diff options
| author | Ian Rogers <irogers@google.com> | 2014-07-09 15:26:09 +0000 |
|---|---|---|
| committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-07-09 14:50:30 +0000 |
| commit | 32710dd4a0232149002a5ae7bde1c640cdffd564 (patch) | |
| tree | 13181f80be3ed025276afb1dee9763fb5c3affdf | |
| parent | 62f28f943e2da2873c7a09096c292f01a21c6478 (diff) | |
| parent | eb24baec056dbe5871f1bc64b793eb2e69907866 (diff) | |
| download | art-32710dd4a0232149002a5ae7bde1c640cdffd564.tar.gz art-32710dd4a0232149002a5ae7bde1c640cdffd564.tar.bz2 art-32710dd4a0232149002a5ae7bde1c640cdffd564.zip | |
Merge "x86_64: enable Peek and Poke intrinsics"
| -rwxr-xr-x | compiler/dex/quick/x86/int_x86.cc | 95 | ||||
| -rw-r--r-- | test/082-inline-execute/src/Main.java | 140 |
2 files changed, 189 insertions, 46 deletions
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index cf29e52bb8..b416a7b548 100755 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -761,54 +761,59 @@ bool X86Mir2Lir::GenInlinedMinMax(CallInfo* info, bool is_min, bool is_long) { } bool X86Mir2Lir::GenInlinedPeek(CallInfo* info, OpSize size) { - return false; -// Turned off until tests available in Art. -// -// RegLocation rl_src_address = info->args[0]; // long address -// RegLocation rl_address; -// if (!cu_->target64) { -// rl_src_address = NarrowRegLoc(rl_src_address); // ignore high half in info->args[0] -// rl_address = LoadValue(rl_src_address, kCoreReg); -// } else { -// rl_address = LoadValueWide(rl_src_address, kCoreReg); -// } -// RegLocation rl_dest = size == k64 ? InlineTargetWide(info) : InlineTarget(info); -// RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); -// // Unaligned access is allowed on x86. -// LoadBaseDisp(rl_address.reg, 0, rl_result.reg, size, kNotVolatile); -// if (size == k64) { -// StoreValueWide(rl_dest, rl_result); -// } else { -// DCHECK(size == kSignedByte || size == kSignedHalf || size == k32); -// StoreValue(rl_dest, rl_result); -// } -// return true; + RegLocation rl_src_address = info->args[0]; // long address + RegLocation rl_address; + if (!cu_->target64) { + rl_src_address = NarrowRegLoc(rl_src_address); // ignore high half in info->args[0] + rl_address = LoadValue(rl_src_address, kCoreReg); + } else { + rl_address = LoadValueWide(rl_src_address, kCoreReg); + } + RegLocation rl_dest = size == k64 ? InlineTargetWide(info) : InlineTarget(info); + RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); + // Unaligned access is allowed on x86. + LoadBaseDisp(rl_address.reg, 0, rl_result.reg, size, kNotVolatile); + if (size == k64) { + StoreValueWide(rl_dest, rl_result); + } else { + DCHECK(size == kSignedByte || size == kSignedHalf || size == k32); + StoreValue(rl_dest, rl_result); + } + return true; } bool X86Mir2Lir::GenInlinedPoke(CallInfo* info, OpSize size) { - return false; -// Turned off until tests available in Art. -// -// RegLocation rl_src_address = info->args[0]; // long address -// RegLocation rl_address; -// if (!cu_->target64) { -// rl_src_address = NarrowRegLoc(rl_src_address); // ignore high half in info->args[0] -// rl_address = LoadValue(rl_src_address, kCoreReg); -// } else { -// rl_address = LoadValueWide(rl_src_address, kCoreReg); -// } -// RegLocation rl_src_value = info->args[2]; // [size] value -// if (size == k64) { -// // Unaligned access is allowed on x86. -// RegLocation rl_value = LoadValueWide(rl_src_value, kCoreReg); -// StoreBaseDisp(rl_address.reg, 0, rl_value.reg, size, kNotVolatile); -// } else { -// DCHECK(size == kSignedByte || size == kSignedHalf || size == k32); -// // Unaligned access is allowed on x86. -// RegLocation rl_value = LoadValue(rl_src_value, kCoreReg); -// StoreBaseDisp(rl_address.reg, 0, rl_value.reg, size, kNotVolatile); -// } -// return true; + RegLocation rl_src_address = info->args[0]; // long address + RegLocation rl_address; + if (!cu_->target64) { + rl_src_address = NarrowRegLoc(rl_src_address); // ignore high half in info->args[0] + rl_address = LoadValue(rl_src_address, kCoreReg); + } else { + rl_address = LoadValueWide(rl_src_address, kCoreReg); + } + RegLocation rl_src_value = info->args[2]; // [size] value + RegLocation rl_value; + if (size == k64) { + // Unaligned access is allowed on x86. + rl_value = LoadValueWide(rl_src_value, kCoreReg); + } else { + DCHECK(size == kSignedByte || size == kSignedHalf || size == k32); + // In 32-bit mode the only EAX..EDX registers can be used with Mov8MR. + if (!cu_->target64 && size == kSignedByte) { + rl_src_value = UpdateLocTyped(rl_src_value, kCoreReg); + if (rl_src_value.location == kLocPhysReg && !IsByteRegister(rl_src_value.reg)) { + RegStorage temp = AllocateByteRegister(); + OpRegCopy(temp, rl_src_value.reg); + rl_value.reg = temp; + } else { + rl_value = LoadValue(rl_src_value, kCoreReg); + } + } else { + rl_value = LoadValue(rl_src_value, kCoreReg); + } + } + StoreBaseDisp(rl_address.reg, 0, rl_value.reg, size, kNotVolatile); + return true; } void X86Mir2Lir::OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale, int offset) { diff --git a/test/082-inline-execute/src/Main.java b/test/082-inline-execute/src/Main.java index 3b11879e08..2e1c6d9a76 100644 --- a/test/082-inline-execute/src/Main.java +++ b/test/082-inline-execute/src/Main.java @@ -15,9 +15,11 @@ */ import junit.framework.Assert; +import java.util.Arrays; +import java.lang.reflect.Method; public class Main { - public static void main(String args[]) { + public static void main(String args[]) throws Exception { test_Double_doubleToRawLongBits(); test_Double_longBitsToDouble(); test_Float_floatToRawIntBits(); @@ -50,6 +52,15 @@ public class Main { test_String_isEmpty(); test_String_length(); test_Thread_currentThread(); + initSupportMethodsForPeekPoke(); + test_Memory_peekByte(); + test_Memory_peekShort(); + test_Memory_peekInt(); + test_Memory_peekLong(); + test_Memory_pokeByte(); + test_Memory_pokeShort(); + test_Memory_pokeInt(); + test_Memory_pokeLong(); } /* @@ -510,4 +521,131 @@ public class Main { Assert.assertEquals(Long.reverse(Long.MIN_VALUE), 1L); } + static Object runtime; + static Method address_of; + static Method peek_byte; + static Method peek_short; + static Method peek_int; + static Method peek_long; + static Method poke_byte; + static Method poke_short; + static Method poke_int; + static Method poke_long; + + public static void initSupportMethodsForPeekPoke() throws Exception { + Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime"); + Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime"); + runtime = get_runtime.invoke(null); + address_of = vm_runtime.getDeclaredMethod("addressOf", Object.class); + + Class<?> io_memory = Class.forName("libcore.io.Memory"); + peek_byte = io_memory.getDeclaredMethod("peekByte", Long.TYPE); + peek_int = io_memory.getDeclaredMethod("peekInt", Long.TYPE, Boolean.TYPE); + peek_short = io_memory.getDeclaredMethod("peekShort", Long.TYPE, Boolean.TYPE); + peek_long = io_memory.getDeclaredMethod("peekLong", Long.TYPE, Boolean.TYPE); + poke_byte = io_memory.getDeclaredMethod("pokeByte", Long.TYPE, Byte.TYPE); + poke_short = io_memory.getDeclaredMethod("pokeShort", Long.TYPE, Short.TYPE, Boolean.TYPE); + poke_int = io_memory.getDeclaredMethod("pokeInt", Long.TYPE, Integer.TYPE, Boolean.TYPE); + poke_long = io_memory.getDeclaredMethod("pokeLong", Long.TYPE, Long.TYPE, Boolean.TYPE); + } + + public static void test_Memory_peekByte() throws Exception { + byte[] b = new byte [2]; + b[0] = 0x12; + b[1] = 0x11; + long address = (long)address_of.invoke(runtime, b); + Assert.assertEquals((byte)peek_byte.invoke(null, address), 0x12); + Assert.assertEquals((byte)peek_byte.invoke(null, address + 1), 0x11); + } + + public static void test_Memory_peekShort() throws Exception { + byte[] b = new byte [3]; + b[0] = 0x13; + b[1] = 0x12; + b[2] = 0x11; + long address = (long)address_of.invoke(runtime, b); + Assert.assertEquals((short)peek_short.invoke(null, address, false), 0x1213); // Aligned read + Assert.assertEquals((short)peek_short.invoke(null, address + 1, false), 0x1112); // Unaligned read + } + + public static void test_Memory_peekInt() throws Exception { + byte[] b = new byte [5]; + b[0] = 0x15; + b[1] = 0x14; + b[2] = 0x13; + b[3] = 0x12; + b[4] = 0x11; + long address = (long)address_of.invoke(runtime, b); + Assert.assertEquals((int)peek_int.invoke(null, address, false), 0x12131415); + Assert.assertEquals((int)peek_int.invoke(null, address + 1, false), 0x11121314); + } + + public static void test_Memory_peekLong() throws Exception { + byte[] b = new byte [9]; + b[0] = 0x19; + b[1] = 0x18; + b[2] = 0x17; + b[3] = 0x16; + b[4] = 0x15; + b[5] = 0x14; + b[6] = 0x13; + b[7] = 0x12; + b[8] = 0x11; + long address = (long)address_of.invoke(runtime, b); + Assert.assertEquals((long)peek_long.invoke(null, address, false), 0x1213141516171819L); + Assert.assertEquals((long)peek_long.invoke(null, address + 1, false), 0x1112131415161718L); + } + + public static void test_Memory_pokeByte() throws Exception { + byte[] r = {0x11, 0x12}; + byte[] b = new byte [2]; + long address = (long)address_of.invoke(runtime, b); + poke_byte.invoke(null, address, (byte)0x11); + poke_byte.invoke(null, address + 1, (byte)0x12); + Assert.assertTrue(Arrays.equals(r, b)); + } + + public static void test_Memory_pokeShort() throws Exception { + byte[] ra = {0x12, 0x11, 0x13}; + byte[] ru = {0x12, 0x22, 0x21}; + byte[] b = new byte [3]; + long address = (long)address_of.invoke(runtime, b); + + // Aligned write + b[2] = 0x13; + poke_short.invoke(null, address, (short)0x1112, false); + Assert.assertTrue(Arrays.equals(ra, b)); + + // Unaligned write + poke_short.invoke(null, address + 1, (short)0x2122, false); + Assert.assertTrue(Arrays.equals(ru, b)); + } + + public static void test_Memory_pokeInt() throws Exception { + byte[] ra = {0x14, 0x13, 0x12, 0x11, 0x15}; + byte[] ru = {0x14, 0x24, 0x23, 0x22, 0x21}; + byte[] b = new byte [5]; + long address = (long)address_of.invoke(runtime, b); + + b[4] = 0x15; + poke_int.invoke(null, address, (int)0x11121314, false); + Assert.assertTrue(Arrays.equals(ra, b)); + + poke_int.invoke(null, address + 1, (int)0x21222324, false); + Assert.assertTrue(Arrays.equals(ru, b)); + } + + public static void test_Memory_pokeLong() throws Exception { + byte[] ra = {0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x19}; + byte[] ru = {0x18, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21}; + byte[] b = new byte [9]; + long address = (long)address_of.invoke(runtime, b); + + b[8] = 0x19; + poke_long.invoke(null, address, (long)0x1112131415161718L, false); + Assert.assertTrue(Arrays.equals(ra, b)); + + poke_long.invoke(null, address + 1, (long)0x2122232425262728L, false); + Assert.assertTrue(Arrays.equals(ru, b)); + } } |
