From df5d86e78c2c21b059c869fda05d374e85c42bb4 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 30 May 2014 22:29:08 -0700 Subject: [PATCH] Tweaking load/store. Nasty. --- src/alloy/backend/x64/x64_sequences.cc | 68 +++++++++++++++----------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 9de06e58f..438e1d2d9 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -1529,9 +1529,10 @@ void DynamicRegisterStore(void* raw_context, uint32_t address, uint64_t value) { } } template -void EmitLoadCheck(X64Emitter& e, const RegExp& addr, DEST_REG& dest) { +void EmitLoadCheck(X64Emitter& e, const I64<>& addr_value, DEST_REG& dest) { // rax = reserved // if (address >> 24 == 0x7F) call register load handler; + auto addr = ComputeMemoryAddress(e, addr_value); e.lea(e.r8d, e.ptr[addr]); e.shr(e.r8d, 24); e.cmp(e.r8b, 0x7F); @@ -1550,13 +1551,23 @@ void EmitLoadCheck(X64Emitter& e, const RegExp& addr, DEST_REG& dest) { if (DEST_REG::key_type == KEY_TYPE_V_I32) { e.mov(dest, e.dword[addr]); } + if (IsTracingData()) { + e.mov(e.r8, dest); + e.lea(e.rdx, e.ptr[addr]); + if (DEST_REG::key_type == KEY_TYPE_V_I32) { + e.CallNative(TraceMemoryLoadI32); + } else if (DEST_REG::key_type == KEY_TYPE_V_I64) { + e.CallNative(TraceMemoryLoadI64); + } + } e.L(skip_load); e.outLocalLabel(); } template -void EmitStoreCheck(X64Emitter& e, const RegExp& addr, SRC_REG& src) { +void EmitStoreCheck(X64Emitter& e, const I64<>& addr_value, SRC_REG& src) { // rax = reserved // if (address >> 24 == 0x7F) call register store handler; + auto addr = ComputeMemoryAddress(e, addr_value); e.lea(e.r8d, e.ptr[addr]); e.shr(e.r8d, 24); e.cmp(e.r8b, 0x7F); @@ -1567,11 +1578,18 @@ void EmitStoreCheck(X64Emitter& e, const RegExp& addr, SRC_REG& src) { e.lea(e.rdx, e.ptr[addr]); if (SRC_REG::key_type == KEY_TYPE_V_I32) { if (src.is_constant) { - e.mov(e.r8d, XESWAP32(src.constant())); + e.mov(e.r8d, XESWAP32(static_cast(src.constant()))); } else { e.mov(e.r8d, src); e.bswap(e.r8d); } + } else if (SRC_REG::key_type == KEY_TYPE_V_I64) { + if (src.is_constant) { + e.mov(e.r8, XESWAP64(static_cast(src.constant()))); + } else { + e.mov(e.r8, src); + e.bswap(e.r8); + } } e.CallNative(DynamicRegisterStore); e.jmp(skip_load); @@ -1582,6 +1600,21 @@ void EmitStoreCheck(X64Emitter& e, const RegExp& addr, SRC_REG& src) { } else { e.mov(e.dword[addr], src); } + } else if (SRC_REG::key_type == KEY_TYPE_V_I64) { + if (src.is_constant) { + e.MovMem64(addr, src.constant()); + } else { + e.mov(e.qword[addr], src); + } + } + if (IsTracingData()) { + e.mov(e.r8, e.qword[addr]); + e.lea(e.rdx, e.ptr[addr]); + if (SRC_REG::key_type == KEY_TYPE_V_I32) { + e.CallNative(TraceMemoryStoreI32); + } else if (SRC_REG::key_type == KEY_TYPE_V_I64) { + e.CallNative(TraceMemoryStoreI64); + } } e.L(skip_load); e.outLocalLabel(); @@ -1619,13 +1652,7 @@ EMITTER(LOAD_I32, MATCH(I, I64<>>)) { if (CheckLoadAccessCallback(e, i)) { return; } - auto addr = ComputeMemoryAddress(e, i.src1); - EmitLoadCheck(e, addr, i.dest); - if (IsTracingData()) { - e.mov(e.r8, i.dest); - e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryLoadI32); - } + EmitLoadCheck(e, i.src1, i.dest); } }; EMITTER(LOAD_I64, MATCH(I, I64<>>)) { @@ -1772,13 +1799,7 @@ EMITTER(STORE_I32, MATCH(I, I32<>>)) { if (CheckStoreAccessCallback(e, i)) { return; } - auto addr = ComputeMemoryAddress(e, i.src1); - EmitStoreCheck(e, addr, i.src2); - if (IsTracingData()) { - e.mov(e.r8, e.dword[addr]); - e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryStoreI32); - } + EmitStoreCheck(e, i.src1, i.src2); } }; EMITTER(STORE_I64, MATCH(I, I64<>>)) { @@ -1786,17 +1807,7 @@ EMITTER(STORE_I64, MATCH(I, I64<>>)) { if (CheckStoreAccessCallback(e, i)) { return; } - auto addr = ComputeMemoryAddress(e, i.src1); - if (i.src2.is_constant) { - e.MovMem64(addr, i.src2.constant()); - } else { - e.mov(e.qword[addr], i.src2); - } - if (IsTracingData()) { - e.mov(e.r8, e.qword[addr]); - e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryStoreI64); - } + EmitStoreCheck(e, i.src1, i.src2); } }; EMITTER(STORE_F32, MATCH(I, F32<>>)) { @@ -1940,6 +1951,7 @@ EMITTER_OPCODE_TABLE( // ============================================================================ // OPCODE_SELECT // ============================================================================ +// dest = src1 ? src2 : src3 EMITTER(SELECT_I8, MATCH(I, I8<>, I8<>, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { e.test(i.src1, i.src1);