From bdee924494068ebe10630c268755b77db549198c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 28 Jan 2014 23:51:40 -0800 Subject: [PATCH] Various fixes. --- .../backend/x64/lowering/lowering_sequences.cc | 16 ++++++++++++---- src/alloy/backend/x64/lowering/op_utils.inl | 8 +++++--- src/alloy/backend/x64/x64_code_cache.cc | 2 +- src/alloy/backend/x64/x64_emitter.cc | 5 +++-- src/alloy/frontend/ppc/ppc_emit_memory.cc | 3 ++- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/alloy/backend/x64/lowering/lowering_sequences.cc b/src/alloy/backend/x64/lowering/lowering_sequences.cc index 9393c2da9..ec5be7d6f 100644 --- a/src/alloy/backend/x64/lowering/lowering_sequences.cc +++ b/src/alloy/backend/x64/lowering/lowering_sequences.cc @@ -189,7 +189,7 @@ void IssueCall(X64Emitter& e, FunctionInfo* symbol_info, uint32_t flags) { } if (flags & CALL_TAIL) { // TODO(benvanik): adjust stack? - e.add(e.rsp, 0x40); + e.add(e.rsp, 72); e.jmp(e.rax); } else { e.call(e.rax); @@ -210,7 +210,7 @@ void IssueCallIndirect(X64Emitter& e, Value* target, uint32_t flags) { e.mov(e.rdx, e.qword[e.rcx + 8]); // membase if (flags & CALL_TAIL) { // TODO(benvanik): adjust stack? - e.add(e.rsp, 0x40); + e.add(e.rsp, 72); e.jmp(e.rax); } else { e.call(e.rax); @@ -2844,8 +2844,16 @@ table->AddSequence(OPCODE_COMPARE_EXCHANGE, [](X64Emitter& e, Instr*& i) { }); table->AddSequence(OPCODE_ATOMIC_EXCHANGE, [](X64Emitter& e, Instr*& i) { - if (IsIntType(i->dest->type)) { - UNIMPLEMENTED_SEQ(); + if (i->dest->type == INT32_TYPE) { + // dest = old_value = InterlockedExchange(src1 = address, src2 = new_value); + Reg32 dest, src2; + Reg64 src1; + e.BeginOp(i->dest, dest, REG_DEST, + i->src1.value, src1, 0, + i->src2.value, src2, 0); + e.mov(dest, src2); + e.xchg(e.dword[src1], dest); + e.EndOp(dest, src1, src2); } else { ASSERT_INVALID_TYPE(); } diff --git a/src/alloy/backend/x64/lowering/op_utils.inl b/src/alloy/backend/x64/lowering/op_utils.inl index 35b707780..52bf39d7d 100644 --- a/src/alloy/backend/x64/lowering/op_utils.inl +++ b/src/alloy/backend/x64/lowering/op_utils.inl @@ -17,6 +17,8 @@ namespace { #define LIKE_REG(dest, like) Reg(dest.getIdx(), dest.getKind(), like.getBit(), false) #define NAX_LIKE(like) Reg(e.rax.getIdx(), e.rax.getKind(), like.getBit(), false) +#define STASH_OFFSET 48 + // If we are running with tracing on we have to store the EFLAGS in the stack, // otherwise our calls out to C to print will clear it before DID_CARRY/etc // can get the value. @@ -24,7 +26,7 @@ namespace { void LoadEflags(X64Emitter& e) { #if STORE_EFLAGS - e.mov(e.eax, e.dword[e.rsp + 40]); + e.mov(e.eax, e.dword[e.rsp + STASH_OFFSET]); e.push(e.ax); e.popf(); #else @@ -34,7 +36,7 @@ void LoadEflags(X64Emitter& e) { void StoreEflags(X64Emitter& e) { #if STORE_EFLAGS e.pushf(); - e.pop(e.word[e.rsp + 40]); + e.pop(e.word[e.rsp + STASH_OFFSET]); #else // EFLAGS should have CA set? // (so long as we don't fuck with it) @@ -43,7 +45,7 @@ void StoreEflags(X64Emitter& e) { Address Stash(X64Emitter& e, const Xmm& r) { // TODO(benvanik): ensure aligned. - auto addr = e.ptr[e.rsp + 48]; + auto addr = e.ptr[e.rsp + STASH_OFFSET]; e.movups(addr, r); return addr; } diff --git a/src/alloy/backend/x64/x64_code_cache.cc b/src/alloy/backend/x64/x64_code_cache.cc index 7bbf91f2a..c7a456830 100644 --- a/src/alloy/backend/x64/x64_code_cache.cc +++ b/src/alloy/backend/x64/x64_code_cache.cc @@ -216,7 +216,7 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size) { // TODO(benvanik): take as parameters? bool has_prolog = true; uint8_t prolog_size = 4; - uint8_t stack_bytes = 64; + uint8_t stack_bytes = 72; // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx UNWIND_INFO* unwind_info = (UNWIND_INFO*)(buffer + unwind_info_offset); diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 59fcfb36a..fc5dce840 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -132,7 +132,7 @@ int X64Emitter::Emit(HIRBuilder* builder) { // X64CodeCache, which dynamically generates exception information. // Adding or changing anything here must be matched! const bool emit_prolog = true; - const size_t stack_size = 64; + const size_t stack_size = 72; if (emit_prolog) { mov(qword[rsp + 8], rcx); sub(rsp, stack_size); @@ -238,7 +238,8 @@ void X64Emitter::EvictStaleRegisters() { // Register is live, not active. Check and see if we get rid of it. auto v = reg_state_.reg_values[n]; - if (v->last_use->ordinal < current_ordinal) { + if (!v->last_use || + v->last_use->ordinal < current_ordinal) { reg_state_.reg_values[n] = NULL; v->reg = -1; continue; diff --git a/src/alloy/frontend/ppc/ppc_emit_memory.cc b/src/alloy/frontend/ppc/ppc_emit_memory.cc index ab810f6b2..738090abf 100644 --- a/src/alloy/frontend/ppc/ppc_emit_memory.cc +++ b/src/alloy/frontend/ppc/ppc_emit_memory.cc @@ -891,7 +891,8 @@ XEEMITTER(stfiwx, 0x7C0007AE, X )(PPCHIRBuilder& f, InstrData& i) { // EA <- b + (RB) // MEM(EA, 4) <- (FRS)[32:63] Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); - f.Store(ea, f.ByteSwap(f.Cast(f.LoadFPR(i.X.RT), INT32_TYPE))); + f.Store(ea, f.ByteSwap( + f.Truncate(f.Cast(f.LoadFPR(i.X.RT), INT64_TYPE), INT32_TYPE))); return 0; }