Core: clean up some code related to CompileStoreMemoryValue, like the exit method being an exception

This commit is contained in:
zilmar 2024-10-24 13:32:02 +10:30
parent a8c8e751fc
commit 17c501fa08
2 changed files with 48 additions and 28 deletions

View File

@ -9767,7 +9767,7 @@ asmjit::x86::Gp CX86RecompilerOps::BaseOffsetAddress(bool UseBaseRegister)
return AddressReg; 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(); bool UnprotectAddressReg = !AddressReg.isValid();
if (UnprotectAddressReg) if (UnprotectAddressReg)
@ -9916,32 +9916,42 @@ void CX86RecompilerOps::CompileLoadMemoryValue(asmjit::x86::Gp & AddressReg, asm
else if (ValueSize == 16) else if (ValueSize == 16)
{ {
m_Assembler.xor_(AddressReg, 2); 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); 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) if (SignExtend)
{ {
m_Assembler.movsx(ValueReg, asmjit::x86::word_ptr(AddressReg, TempReg)); m_Assembler.movsx(MovReg, asmjit::x86::word_ptr(AddressReg, TempReg));
} }
else 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) else if (ValueSize == 32)
{ {
if (!ValueReg.isValid()) asmjit::x86::Gp MovReg;
{
m_RegWorkingSet.Map_GPR_32bit(m_Opcode.rt, true, -1);
ValueReg = m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt);
}
if (ValueReg.isValid()) 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 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; 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.MoveX86regToVariable(&m_TempValue32, "TempValue32", AddressReg);
m_Assembler.test(AddressReg, 1); if (ValueSize == 16)
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); {
CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_AddressErrorExceptionWrite32, false, &CX86Ops::JneLabel); m_Assembler.test(AddressReg, 1);
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); }
} else if (ValueSize == 32)
else if (ValueSize == 32) {
{ m_Assembler.test(AddressReg, 3);
m_Assembler.MoveX86regToVariable(&m_TempValue32, "TempValue32", AddressReg); }
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()); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp());
CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_AddressErrorExceptionWrite32, false, &CX86Ops::JneLabel); CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_AddressErrorExceptionWrite32, false, &CX86Ops::JneLabel);
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); 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_Assembler.test(asmjit::x86::al, asmjit::x86::al);
m_RegWorkingSet.AfterCallDirect(); 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) if (m_PipelineStage != PIPELINE_STAGE_NORMAL)
{ {
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "g_System->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_Assembler.test(asmjit::x86::al, asmjit::x86::al);
m_RegWorkingSet.AfterCallDirect(); 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) if (m_PipelineStage != PIPELINE_STAGE_NORMAL)
{ {
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "g_System->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_Assembler.test(asmjit::x86::al, asmjit::x86::al);
m_RegWorkingSet.AfterCallDirect(); 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) if (m_PipelineStage != PIPELINE_STAGE_NORMAL)
{ {
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "g_System->m_PipelineStage", PIPELINE_STAGE_NORMAL); m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "g_System->m_PipelineStage", PIPELINE_STAGE_NORMAL);

View File

@ -268,8 +268,8 @@ private:
CX86RecompilerOps & operator=(const CX86RecompilerOps &); CX86RecompilerOps & operator=(const CX86RecompilerOps &);
asmjit::x86::Gp BaseOffsetAddress(bool UseBaseRegister); 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 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, asmjit::x86::Gp ValueReg, const asmjit::x86::Gp & ValueRegHi, uint64_t Value, uint8_t ValueSize); 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)(void));
void COP1_D_Opcode(void (CX86Ops::*Instruction)(const asmjit::x86::Mem &)); void COP1_D_Opcode(void (CX86Ops::*Instruction)(const asmjit::x86::Mem &));
void COP1_S_Opcode(void (CX86Ops::*Instruction)(void)); void COP1_S_Opcode(void (CX86Ops::*Instruction)(void));