From 17c501fa0833815975494880c975ef604e063681 Mon Sep 17 00:00:00 2001
From: zilmar <zilmar@pj64-emu.com>
Date: Thu, 24 Oct 2024 13:32:02 +1030
Subject: [PATCH] Core: clean up some code related to CompileStoreMemoryValue,
 like the exit method being an exception

---
 .../Recompiler/x86/x86RecompilerOps.cpp       | 72 ++++++++++++-------
 .../Recompiler/x86/x86RecompilerOps.h         |  4 +-
 2 files changed, 48 insertions(+), 28 deletions(-)

diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp
index 6bc69359a..a9c70e259 100644
--- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp
+++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp
@@ -9767,7 +9767,7 @@ asmjit::x86::Gp CX86RecompilerOps::BaseOffsetAddress(bool UseBaseRegister)
     return AddressReg;
 }
 
-void CX86RecompilerOps::CompileLoadMemoryValue(asmjit::x86::Gp & AddressReg, asmjit::x86::Gp ValueReg, const asmjit::x86::Gp & ValueRegHi, uint8_t ValueSize, bool SignExtend)
+void CX86RecompilerOps::CompileLoadMemoryValue(asmjit::x86::Gp & AddressReg, const asmjit::x86::Gp & ValueReg, const asmjit::x86::Gp & ValueRegHi, uint8_t ValueSize, bool SignExtend)
 {
     bool UnprotectAddressReg = !AddressReg.isValid();
     if (UnprotectAddressReg)
@@ -9916,32 +9916,42 @@ void CX86RecompilerOps::CompileLoadMemoryValue(asmjit::x86::Gp & AddressReg, asm
     else if (ValueSize == 16)
     {
         m_Assembler.xor_(AddressReg, 2);
-        if (!ValueReg.isValid())
+        asmjit::x86::Gp MovReg;
+        if (ValueReg.isValid())
+        {
+            MovReg = ValueReg;
+        }
+        else
         {
             m_RegWorkingSet.Map_GPR_32bit(m_Opcode.rt, SignExtend, -1);
-            ValueReg = m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt);
+            MovReg = m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt);
         }
 
         if (SignExtend)
         {
-            m_Assembler.movsx(ValueReg, asmjit::x86::word_ptr(AddressReg, TempReg));
+            m_Assembler.movsx(MovReg, asmjit::x86::word_ptr(AddressReg, TempReg));
         }
         else
         {
-            m_Assembler.movzx(ValueReg, asmjit::x86::word_ptr(AddressReg, TempReg));
+            m_Assembler.movzx(MovReg, asmjit::x86::word_ptr(AddressReg, TempReg));
         }
     }
     else if (ValueSize == 32)
     {
-        if (!ValueReg.isValid())
-        {
-            m_RegWorkingSet.Map_GPR_32bit(m_Opcode.rt, true, -1);
-            ValueReg = m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt);
-        }
-
+        asmjit::x86::Gp MovReg;
         if (ValueReg.isValid())
         {
-            m_Assembler.mov(ValueReg, asmjit::x86::dword_ptr(AddressReg, TempReg));
+            MovReg = ValueReg;
+        }
+        else
+        {
+            m_RegWorkingSet.Map_GPR_32bit(m_Opcode.rt, true, -1);
+            MovReg = m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt);
+        }
+
+        if (MovReg.isValid())
+        {
+            m_Assembler.mov(MovReg, asmjit::x86::dword_ptr(AddressReg, TempReg));
         }
         else
         {
@@ -9971,7 +9981,7 @@ void CX86RecompilerOps::CompileLoadMemoryValue(asmjit::x86::Gp & AddressReg, asm
     }
 }
 
-void CX86RecompilerOps::CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, asmjit::x86::Gp ValueReg, const asmjit::x86::Gp & ValueRegHi, uint64_t Value, uint8_t ValueSize)
+void CX86RecompilerOps::CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, const asmjit::x86::Gp & ValueReg, const asmjit::x86::Gp & ValueRegHi, uint64_t Value, uint8_t ValueSize)
 {
     asmjit::Label MemoryWriteDone;
 
@@ -10000,18 +10010,25 @@ void CX86RecompilerOps::CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, asmj
         }
     }
 
-    if (ValueSize == 16)
+    if (ValueSize != 8)
     {
         m_Assembler.MoveX86regToVariable(&m_TempValue32, "TempValue32", AddressReg);
-        m_Assembler.test(AddressReg, 1);
-        m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp());
-        CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_AddressErrorExceptionWrite32, false, &CX86Ops::JneLabel);
-        m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp());
-    }
-    else if (ValueSize == 32)
-    {
-        m_Assembler.MoveX86regToVariable(&m_TempValue32, "TempValue32", AddressReg);
-        m_Assembler.test(AddressReg, 3);
+        if (ValueSize == 16)
+        {
+            m_Assembler.test(AddressReg, 1);
+        }
+        else if (ValueSize == 32)
+        {
+            m_Assembler.test(AddressReg, 3);
+        }
+        else if (ValueSize == 64)
+        {
+            m_Assembler.test(AddressReg, 7);
+        }
+        else
+        {
+            g_Notify->BreakPoint(__FILE__, __LINE__);
+        }
         m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp());
         CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_AddressErrorExceptionWrite32, false, &CX86Ops::JneLabel);
         m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp());
@@ -10081,7 +10098,7 @@ void CX86RecompilerOps::CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, asmj
         }
         m_Assembler.test(asmjit::x86::al, asmjit::x86::al);
         m_RegWorkingSet.AfterCallDirect();
-        CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_NormalNoSysCheck, false, &CX86Ops::JeLabel);
+        CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_Exception, false, &CX86Ops::JeLabel);
         if (m_PipelineStage != PIPELINE_STAGE_NORMAL)
         {
             m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "g_System->m_PipelineStage", PIPELINE_STAGE_NORMAL);
@@ -10108,7 +10125,10 @@ void CX86RecompilerOps::CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, asmj
         }
         m_Assembler.test(asmjit::x86::al, asmjit::x86::al);
         m_RegWorkingSet.AfterCallDirect();
-        CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_NormalNoSysCheck, false, &CX86Ops::JeLabel);
+        m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp());
+        CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_Exception, false, &CX86Ops::JeLabel);
+        m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp());
+
         if (m_PipelineStage != PIPELINE_STAGE_NORMAL)
         {
             m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "g_System->m_PipelineStage", PIPELINE_STAGE_NORMAL);
@@ -10137,7 +10157,7 @@ void CX86RecompilerOps::CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, asmj
         }
         m_Assembler.test(asmjit::x86::al, asmjit::x86::al);
         m_RegWorkingSet.AfterCallDirect();
-        CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_NormalNoSysCheck, false, &CX86Ops::JeLabel);
+        CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_Exception, false, &CX86Ops::JeLabel);
         if (m_PipelineStage != PIPELINE_STAGE_NORMAL)
         {
             m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "g_System->m_PipelineStage", PIPELINE_STAGE_NORMAL);
diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h
index afecd1532..8b7308209 100644
--- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h
+++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h
@@ -268,8 +268,8 @@ private:
     CX86RecompilerOps & operator=(const CX86RecompilerOps &);
 
     asmjit::x86::Gp BaseOffsetAddress(bool UseBaseRegister);
-    void CompileLoadMemoryValue(asmjit::x86::Gp & AddressReg, asmjit::x86::Gp ValueReg, const asmjit::x86::Gp & ValueRegHi, uint8_t ValueSize, bool SignExtend);
-    void CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, asmjit::x86::Gp ValueReg, const asmjit::x86::Gp & ValueRegHi, uint64_t Value, uint8_t ValueSize);
+    void CompileLoadMemoryValue(asmjit::x86::Gp & AddressReg, const asmjit::x86::Gp & ValueReg, const asmjit::x86::Gp & ValueRegHi, uint8_t ValueSize, bool SignExtend);
+    void CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, const asmjit::x86::Gp & ValueReg, const asmjit::x86::Gp & ValueRegHi, uint64_t Value, uint8_t ValueSize);
     void COP1_D_Opcode(void (CX86Ops::*Instruction)(void));
     void COP1_D_Opcode(void (CX86Ops::*Instruction)(const asmjit::x86::Mem &));
     void COP1_S_Opcode(void (CX86Ops::*Instruction)(void));