Core: create a function to handle .d recompiler opcodes that use fd and fs

This commit is contained in:
zilmar 2024-03-21 17:13:16 +10:30
parent 5133d47502
commit ece5e30a80
4 changed files with 40 additions and 27 deletions

View File

@ -8294,9 +8294,6 @@ void CX86RecompilerOps::COP1_S_CMP()
// COP1: D functions // COP1: D functions
void CX86RecompilerOps::COP1_D_ADD() void CX86RecompilerOps::COP1_D_ADD()
{ {
uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs;
uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft;
if (FpuExceptionInRecompiler()) if (FpuExceptionInRecompiler())
{ {
COP1_D_Opcode(&CX86Ops::Fadd); COP1_D_Opcode(&CX86Ops::Fadd);
@ -8305,6 +8302,9 @@ void CX86RecompilerOps::COP1_D_ADD()
{ {
CompileCop1Test(); CompileCop1Test();
uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs;
uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft;
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double);
if (m_RegWorkingSet.RegInStack(Reg2, CRegInfo::FPU_Double)) if (m_RegWorkingSet.RegInStack(Reg2, CRegInfo::FPU_Double))
{ {
@ -8323,9 +8323,6 @@ void CX86RecompilerOps::COP1_D_ADD()
void CX86RecompilerOps::COP1_D_SUB() void CX86RecompilerOps::COP1_D_SUB()
{ {
uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs;
uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft;
if (FpuExceptionInRecompiler()) if (FpuExceptionInRecompiler())
{ {
COP1_D_Opcode(&CX86Ops::Fsub); COP1_D_Opcode(&CX86Ops::Fsub);
@ -8334,6 +8331,9 @@ void CX86RecompilerOps::COP1_D_SUB()
{ {
CompileCop1Test(); CompileCop1Test();
uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs;
uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft;
if (m_Opcode.fd == m_Opcode.ft) if (m_Opcode.fd == m_Opcode.ft)
{ {
m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true); m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true);
@ -8364,15 +8364,15 @@ void CX86RecompilerOps::COP1_D_SUB()
void CX86RecompilerOps::COP1_D_MUL() void CX86RecompilerOps::COP1_D_MUL()
{ {
uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs;
uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft;
if (FpuExceptionInRecompiler()) if (FpuExceptionInRecompiler())
{ {
COP1_D_Opcode(&CX86Ops::Fmul); COP1_D_Opcode(&CX86Ops::Fmul);
} }
else else
{ {
uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs;
uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft;
CompileCop1Test(); CompileCop1Test();
m_RegWorkingSet.FixRoundModel(CRegInfo::RoundDefault); m_RegWorkingSet.FixRoundModel(CRegInfo::RoundDefault);
@ -8394,15 +8394,15 @@ void CX86RecompilerOps::COP1_D_MUL()
void CX86RecompilerOps::COP1_D_DIV() void CX86RecompilerOps::COP1_D_DIV()
{ {
uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs;
uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft;
if (FpuExceptionInRecompiler()) if (FpuExceptionInRecompiler())
{ {
COP1_D_Opcode(&CX86Ops::Fdiv); COP1_D_Opcode(&CX86Ops::Fdiv);
} }
else else
{ {
uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs;
uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft;
CompileCop1Test(); CompileCop1Test();
if (m_Opcode.fd == m_Opcode.ft) if (m_Opcode.fd == m_Opcode.ft)
@ -8436,21 +8436,7 @@ void CX86RecompilerOps::COP1_D_ABS()
{ {
if (FpuExceptionInRecompiler()) if (FpuExceptionInRecompiler())
{ {
CompileInitFpuOperation(CRegInfo::RoundDefault); COP1_D_Opcode(&CX86Ops::Fabs);
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Any) ||
m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Any))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
asmjit::x86::Gp TempReg = m_RegWorkingSet.FPRValuePointer(m_Opcode.fs, CRegInfo::FPU_Double);
CompileCheckFPUInput(TempReg, FpuOpSize_64bit);
m_RegWorkingSet.PrepareFPTopToBe(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
m_Assembler.fabs();
m_Assembler.mov(TempReg, (uint64_t)&m_TempValue64);
m_Assembler.fpuStoreQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), TempReg, false);
CompileCheckFPUResult64(TempReg);
m_RegWorkingSet.SetFPTopAs(m_Opcode.fd);
} }
else else
{ {
@ -10872,6 +10858,26 @@ void CX86RecompilerOps::CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, asmj
} }
} }
void CX86RecompilerOps::COP1_D_Opcode(void (CX86Ops::*Instruction)(void))
{
CompileInitFpuOperation(CRegInfo::RoundDefault);
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Any) ||
m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Any))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
asmjit::x86::Gp TempReg = m_RegWorkingSet.FPRValuePointer(m_Opcode.fs, CRegInfo::FPU_Double);
CompileCheckFPUInput(TempReg, FpuOpSize_64bit);
m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(TempReg), false);
m_RegWorkingSet.PrepareFPTopToBe(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
(m_Assembler.*Instruction)();
m_Assembler.mov(TempReg, (uint64_t)&m_TempValue64);
m_Assembler.fpuStoreQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), TempReg, false);
CompileCheckFPUResult64(TempReg);
m_RegWorkingSet.SetFPTopAs(m_Opcode.fd);
}
void CX86RecompilerOps::COP1_D_Opcode(void (CX86Ops::*Instruction)(const asmjit::x86::Mem &)) void CX86RecompilerOps::COP1_D_Opcode(void (CX86Ops::*Instruction)(const asmjit::x86::Mem &))
{ {
CompileInitFpuOperation(CRegInfo::RoundDefault); CompileInitFpuOperation(CRegInfo::RoundDefault);

View File

@ -270,6 +270,7 @@ private:
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, 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, 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_D_Opcode(void (CX86Ops::*Instruction)(const asmjit::x86::Mem &));
void SB_Const(uint32_t Value, uint32_t Addr); void SB_Const(uint32_t Value, uint32_t Addr);

View File

@ -233,6 +233,11 @@ void CX86Ops::CompX86regToVariable(const asmjit::x86::Gp & Reg, void * Variable,
} }
} }
void CX86Ops::Fabs(void)
{
fabs();
}
void CX86Ops::Fadd(const asmjit::x86::Mem & Mem) void CX86Ops::Fadd(const asmjit::x86::Mem & Mem)
{ {
fadd(Mem); fadd(Mem);

View File

@ -44,6 +44,7 @@ public:
void CompConstToVariable(void * Variable, const char * VariableName, uint32_t Const); void CompConstToVariable(void * Variable, const char * VariableName, uint32_t Const);
void CompConstToX86reg(const asmjit::x86::Gp & Reg, uint32_t Const); void CompConstToX86reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void CompX86regToVariable(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void CompX86regToVariable(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void Fabs(void);
void Fadd(const asmjit::x86::Mem & Mem); void Fadd(const asmjit::x86::Mem & Mem);
void Fdiv(const asmjit::x86::Mem & Mem); void Fdiv(const asmjit::x86::Mem & Mem);
void Fmul(const asmjit::x86::Mem & Mem); void Fmul(const asmjit::x86::Mem & Mem);