Compare commits

..

1 Commits

Author SHA1 Message Date
Summate 1b1699a9af
Merge 6e95cb463b into 5133d47502 2024-03-14 02:43:29 -05:00
5 changed files with 76 additions and 141 deletions

View File

@ -191,7 +191,7 @@ bool CN64Disk::IsValidDiskImage(uint8_t Test[0x20])
// IPL load address
uint32_t ipl_load_addr = (Test[0x1C] << 24) | (Test[0x1D] << 16) | (Test[0x1E] << 8) | Test[0x1F];
if (ipl_load_addr < 0x80000000 || ipl_load_addr >= 0x80800000) return false;
if (ipl_load_addr < 0x80000000 && ipl_load_addr >= 0x80800000) return false;
// Country code
if (*((uint32_t *)&Test[0]) == 0x16D348E8)

View File

@ -8294,6 +8294,9 @@ void CX86RecompilerOps::COP1_S_CMP()
// COP1: D functions
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())
{
COP1_D_Opcode(&CX86Ops::Fadd);
@ -8302,9 +8305,6 @@ void CX86RecompilerOps::COP1_D_ADD()
{
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);
if (m_RegWorkingSet.RegInStack(Reg2, CRegInfo::FPU_Double))
{
@ -8323,6 +8323,9 @@ void CX86RecompilerOps::COP1_D_ADD()
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())
{
COP1_D_Opcode(&CX86Ops::Fsub);
@ -8331,9 +8334,6 @@ void CX86RecompilerOps::COP1_D_SUB()
{
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)
{
m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true);
@ -8364,15 +8364,15 @@ void CX86RecompilerOps::COP1_D_SUB()
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())
{
COP1_D_Opcode(&CX86Ops::Fmul);
}
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();
m_RegWorkingSet.FixRoundModel(CRegInfo::RoundDefault);
@ -8394,15 +8394,15 @@ void CX86RecompilerOps::COP1_D_MUL()
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())
{
COP1_D_Opcode(&CX86Ops::Fdiv);
}
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();
if (m_Opcode.fd == m_Opcode.ft)
@ -8436,7 +8436,21 @@ void CX86RecompilerOps::COP1_D_ABS()
{
if (FpuExceptionInRecompiler())
{
COP1_D_Opcode(&CX86Ops::Fabs);
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.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
{
@ -8448,23 +8462,30 @@ void CX86RecompilerOps::COP1_D_ABS()
void CX86RecompilerOps::COP1_D_NEG()
{
if (FpuExceptionInRecompiler())
{
COP1_D_Opcode(&CX86Ops::Fchs);
}
else
{
CompileCop1Test();
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
m_Assembler.fchs();
}
CompileCop1Test();
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
m_Assembler.fchs();
}
void CX86RecompilerOps::COP1_D_SQRT()
{
if (FpuExceptionInRecompiler())
{
COP1_D_Opcode(&CX86Ops::Fsqrt);
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.PrepareFPTopToBe(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
m_Assembler.fsqrt();
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
{
@ -8478,7 +8499,6 @@ void CX86RecompilerOps::COP1_D_MOV()
{
if (FpuExceptionInRecompiler())
{
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Any) || m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Any))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
@ -8558,23 +8578,16 @@ void CX86RecompilerOps::COP1_D_FLOOR_L()
void CX86RecompilerOps::COP1_D_ROUND_W()
{
if (FpuExceptionInRecompiler())
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
{
COP1_S_CVT(CRegInfo::RoundNearest, CRegInfo::FPU_Double, CRegInfo::FPU_Dword);
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
}
else
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
{
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
{
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
}
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundNearest);
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundNearest);
}
void CX86RecompilerOps::COP1_D_TRUNC_W()
@ -8600,86 +8613,58 @@ void CX86RecompilerOps::COP1_D_TRUNC_W()
void CX86RecompilerOps::COP1_D_CEIL_W()
{
if (FpuExceptionInRecompiler())
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
{
COP1_S_CVT(CRegInfo::RoundUp, CRegInfo::FPU_Double, CRegInfo::FPU_Dword);
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
}
else
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
{
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
{
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
}
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundUp);
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundUp);
}
void CX86RecompilerOps::COP1_D_FLOOR_W()
{
if (FpuExceptionInRecompiler())
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
{
COP1_S_CVT(CRegInfo::RoundDown, CRegInfo::FPU_Double, CRegInfo::FPU_Dword);
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
}
else
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
{
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
{
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
}
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDown);
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDown);
}
void CX86RecompilerOps::COP1_D_CVT_S()
{
if (FpuExceptionInRecompiler())
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword))
{
COP1_S_CVT(CRegInfo::RoundDefault, CRegInfo::FPU_Double, CRegInfo::FPU_FloatLow);
m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true);
}
else
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
{
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword))
{
m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true);
}
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Float, CRegInfo::RoundDefault);
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Float, CRegInfo::RoundDefault);
}
void CX86RecompilerOps::COP1_D_CVT_W()
{
if (FpuExceptionInRecompiler())
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
{
COP1_S_CVT(CRegInfo::RoundDefault, CRegInfo::FPU_Double, CRegInfo::FPU_Dword);
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
}
else
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
{
CompileCop1Test();
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
{
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
}
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDefault);
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDefault);
}
void CX86RecompilerOps::COP1_D_CVT_L()
@ -9153,12 +9138,6 @@ void CX86RecompilerOps::CompileCheckFPUResult64(asmjit::x86::Gp RegPointer)
m_Assembler.mov(RegPointerValue, RegPointer);
RegPointer = RegPointerValue;
}
bool RegPointerProtect = m_RegWorkingSet.GetX86Protected(GetIndexFromX86Reg(RegPointer));
if (!RegPointerProtect)
{
m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(RegPointer), true);
}
asmjit::x86::Gp TempReg2 = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.fnstsw(asmjit::x86::ax);
m_Assembler.and_(asmjit::x86::ax, 0x3D);
@ -9213,11 +9192,6 @@ void CX86RecompilerOps::CompileCheckFPUResult64(asmjit::x86::Gp RegPointer)
CompileExit(m_CompilePC + 4, m_CompilePC + 4, ExitRegSet, ExitReason_Normal, false, &CX86Ops::JmpLabel);
m_Assembler.bind(ValueSame);
m_Assembler.bind(DoNoModify);
if (!RegPointerProtect)
{
m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(RegPointer), false);
}
}
void CX86RecompilerOps::CompileCop1Test()
@ -10898,26 +10872,6 @@ 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 &))
{
CompileInitFpuOperation(CRegInfo::RoundDefault);

View File

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

View File

@ -233,21 +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)
{
fadd(Mem);
}
void CX86Ops::Fchs(void)
{
fchs();
}
void CX86Ops::Fdiv(const asmjit::x86::Mem & Mem)
{
fdiv(Mem);
@ -258,11 +248,6 @@ void CX86Ops::Fmul(const asmjit::x86::Mem & Mem)
fmul(Mem);
}
void CX86Ops::Fsqrt(void)
{
fsqrt();
}
void CX86Ops::Fsub(const asmjit::x86::Mem & Mem)
{
fsub(Mem);

View File

@ -44,12 +44,9 @@ public:
void CompConstToVariable(void * Variable, const char * VariableName, 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 Fabs(void);
void Fadd(const asmjit::x86::Mem & Mem);
void Fchs(void);
void Fdiv(const asmjit::x86::Mem & Mem);
void Fmul(const asmjit::x86::Mem & Mem);
void Fsqrt(void);
void Fsub(const asmjit::x86::Mem & Mem);
void JaeLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JaLabel(const char * LabelName, asmjit::Label & JumpLabel);