From 7ea521b8bf68ed42a1c2ea4e6c6e82302075d87e Mon Sep 17 00:00:00 2001
From: MerryMage <MerryMage@users.noreply.github.com>
Date: Tue, 16 Jun 2020 13:32:50 +0100
Subject: [PATCH] a32_emit_x64: Change ExclusiveWriteMemory64 to require a
 single U64 argument

---
 src/backend/x64/a32_emit_x64.cpp | 13 +------------
 src/frontend/A32/ir_emitter.cpp  |  4 ++--
 src/frontend/ir/opcodes.inc      |  2 +-
 3 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/src/backend/x64/a32_emit_x64.cpp b/src/backend/x64/a32_emit_x64.cpp
index 2e329ef7..debd83e3 100644
--- a/src/backend/x64/a32_emit_x64.cpp
+++ b/src/backend/x64/a32_emit_x64.cpp
@@ -1063,14 +1063,8 @@ void A32EmitX64::EmitA32WriteMemory64(A32EmitContext& ctx, IR::Inst* inst) {
 
 template <size_t bitsize, auto callback>
 void A32EmitX64::ExclusiveWriteMemory(A32EmitContext& ctx, IR::Inst* inst) {
-    const bool prepend_high_word = bitsize == 64;
-
     auto args = ctx.reg_alloc.GetArgumentInfo(inst);
-    if (prepend_high_word) {
-        ctx.reg_alloc.HostCall(nullptr, {}, args[0], args[1], args[2]);
-    } else {
-        ctx.reg_alloc.HostCall(nullptr, {}, args[0], args[1]);
-    }
+    ctx.reg_alloc.HostCall(nullptr, {}, args[0], args[1]);
     const Xbyak::Reg32 passed = ctx.reg_alloc.ScratchGpr().cvt32();
     const Xbyak::Reg32 tmp = code.ABI_RETURN.cvt32(); // Use one of the unused HostCall registers.
 
@@ -1084,11 +1078,6 @@ void A32EmitX64::ExclusiveWriteMemory(A32EmitContext& ctx, IR::Inst* inst) {
     code.test(tmp, A32JitState::RESERVATION_GRANULE_MASK);
     code.jne(end);
     code.mov(code.byte[r15 + offsetof(A32JitState, exclusive_state)], u8(0));
-    if (prepend_high_word) {
-        code.mov(code.ABI_PARAM3.cvt32(), code.ABI_PARAM3.cvt32()); // zero extend to 64-bits
-        code.shl(code.ABI_PARAM4, 32);
-        code.or_(code.ABI_PARAM3, code.ABI_PARAM4);
-    }
     Devirtualize<callback>(config.callbacks).EmitCall(code);
     code.xor_(passed, passed);
     code.L(end);
diff --git a/src/frontend/A32/ir_emitter.cpp b/src/frontend/A32/ir_emitter.cpp
index cc753889..58d23be4 100644
--- a/src/frontend/A32/ir_emitter.cpp
+++ b/src/frontend/A32/ir_emitter.cpp
@@ -297,9 +297,9 @@ IR::U32 IREmitter::ExclusiveWriteMemory64(const IR::U32& vaddr, const IR::U32& v
     if (current_location.EFlag()) {
         const auto vlo = ByteReverseWord(value_lo);
         const auto vhi = ByteReverseWord(value_hi);
-        return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory64, vaddr, vlo, vhi);
+        return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory64, vaddr, Pack2x32To1x64(vlo, vhi));
     } else {
-        return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory64, vaddr, value_lo, value_hi);
+        return Inst<IR::U32>(Opcode::A32ExclusiveWriteMemory64, vaddr, Pack2x32To1x64(value_lo, value_hi));
     }
 }
 
diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc
index f601c891..1e36bdfc 100644
--- a/src/frontend/ir/opcodes.inc
+++ b/src/frontend/ir/opcodes.inc
@@ -653,7 +653,7 @@ A32OPC(WriteMemory64,                                       Void,           U32,
 A32OPC(ExclusiveWriteMemory8,                               U32,            U32,            U8                                              )
 A32OPC(ExclusiveWriteMemory16,                              U32,            U32,            U16                                             )
 A32OPC(ExclusiveWriteMemory32,                              U32,            U32,            U32                                             )
-A32OPC(ExclusiveWriteMemory64,                              U32,            U32,            U32,            U32                             )
+A32OPC(ExclusiveWriteMemory64,                              U32,            U32,            U64                                             )
 
 // A64 Memory access
 A64OPC(ClearExclusive,                                      Void,                                                                           )