Fix Trap Interpreter Functions, add recompiler trap functions

This commit is contained in:
KrimtonZ 2019-12-17 09:08:15 -06:00
parent 0e5c771408
commit 0baf3ef263
9 changed files with 214 additions and 9 deletions

View File

@ -2064,7 +2064,7 @@ void R4300iOp::SPECIAL_TGE()
void R4300iOp::SPECIAL_TGEU()
{
if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].D)
if (_GPR[m_Opcode.rs].UDW >= _GPR[m_Opcode.rt].UDW)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
@ -2080,7 +2080,7 @@ void R4300iOp::SPECIAL_TLT()
void R4300iOp::SPECIAL_TLTU()
{
if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW)
if (_GPR[m_Opcode.rs].UDW < _GPR[m_Opcode.rt].UDW)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
@ -2263,7 +2263,7 @@ void R4300iOp::REGIMM_BGEZAL()
void R4300iOp::REGIMM_TEQI()
{
if (_GPR[m_Opcode.rs].DW == m_Opcode.immediate)
if (_GPR[m_Opcode.rs].DW == (int64_t)((int16_t)m_Opcode.immediate))
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
@ -2271,7 +2271,7 @@ void R4300iOp::REGIMM_TEQI()
void R4300iOp::REGIMM_TGEI()
{
if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate)
if (_GPR[m_Opcode.rs].DW >= (int64_t)((int16_t)m_Opcode.immediate))
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
@ -2279,7 +2279,11 @@ void R4300iOp::REGIMM_TGEI()
void R4300iOp::REGIMM_TGEIU()
{
if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate)
int32_t imm32 = (int16_t)m_Opcode.immediate;
int64_t imm64;
imm64 = imm32;
if (_GPR[m_Opcode.rs].DW >= (uint64_t)imm64)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
@ -2287,7 +2291,7 @@ void R4300iOp::REGIMM_TGEIU()
void R4300iOp::REGIMM_TLTI()
{
if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate)
if (_GPR[m_Opcode.rs].DW < (int64_t)((int16_t)m_Opcode.immediate))
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
@ -2295,7 +2299,11 @@ void R4300iOp::REGIMM_TLTI()
void R4300iOp::REGIMM_TLTIU()
{
if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate)
int32_t imm32 = (int16_t)m_Opcode.immediate;
int64_t imm64;
imm64 = imm32;
if (_GPR[m_Opcode.rs].DW < (uint64_t)imm64)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
@ -2303,7 +2311,7 @@ void R4300iOp::REGIMM_TLTIU()
void R4300iOp::REGIMM_TNEI()
{
if (_GPR[m_Opcode.rs].DW != m_Opcode.immediate)
if (_GPR[m_Opcode.rs].DW != (int64_t)((int16_t)m_Opcode.immediate))
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}

View File

@ -105,6 +105,77 @@ CArmRecompilerOps::CArmRecompilerOps() :
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
void CArmRecompilerOps::Compile_TrapCompare(TRAP_COMPARE CompareType)
{
void *FunctAddress = NULL;
const char *FunctName = NULL;
switch (CompareType)
{
case CompareTypeTEQ:
FunctAddress = (void*)R4300iOp::SPECIAL_TEQ;
FunctName = "R4300iOp::SPECIAL_TEQ";
break;
case CompareTypeTNE:
FunctAddress = (void*)R4300iOp::SPECIAL_TNE;
FunctName = "R4300iOp::SPECIAL_TNE";
break;
case CompareTypeTGE:
FunctAddress = (void*)R4300iOp::SPECIAL_TGE;
FunctName = "R4300iOp::SPECIAL_TGE";
break;
case CompareTypeTGEU:
FunctAddress = (void*)R4300iOp::SPECIAL_TGEU;
FunctName = "R4300iOp::SPECIAL_TGEU";
break;
case CompareTypeTLT:
FunctAddress = (void*)R4300iOp::SPECIAL_TLT;
FunctName = "R4300iOp::SPECIAL_TLT";
break;
case CompareTypeTLTU:
FunctAddress = (void*)R4300iOp::SPECIAL_TLTU;
FunctName = "R4300iOp::SPECIAL_TLTU";
break;
case CompareTypeTEQI:
FunctAddress = (void*)R4300iOp::REGIMM_TEQI;
FunctName = "R4300iOp::REGIMM_TEQI";
break;
case CompareTypeTNEI:
FunctAddress = (void*)R4300iOp::REGIMM_TNEI;
FunctName = "R4300iOp::REGIMM_TNEI";
break;
case CompareTypeTGEI:
FunctAddress = (void*)R4300iOp::REGIMM_TGEI;
FunctName = "R4300iOp::REGIMM_TGEI";
break;
case CompareTypeTGEIU:
FunctAddress = (void*)R4300iOp::REGIMM_TGEIU;
FunctName = "R4300iOp::REGIMM_TGEIU";
break;
case CompareTypeTLTI:
FunctAddress = (void*)R4300iOp::REGIMM_TLTI;
FunctName = "R4300iOp::REGIMM_TLTI";
break;
case CompareTypeTLTIU:
FunctAddress = (void*)R4300iOp::REGIMM_TLTIU;
FunctName = "R4300iOp::REGIMM_TLTIU";
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (FunctName != NULL && FunctAddress != NULL)
{
if (m_Opcode.rs != 0) { WriteBack_GPR(m_Opcode.rs, false); }
if (m_Opcode.rt != 0) { WriteBack_GPR(m_Opcode.rt, false); }
CompileInterpterCall(FunctAddress, FunctName);
}
else
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
}
/************************** Branch functions ************************/
void CArmRecompilerOps::Compile_BranchCompare(BRANCH_COMPARE CompareType)
{

View File

@ -22,6 +22,9 @@ class CArmRecompilerOps :
public:
CArmRecompilerOps();
/*************************** Trap functions *************************/
void Compile_TrapCompare(TRAP_COMPARE CompareType);
/************************** Branch functions ************************/
void Compile_BranchCompare(BRANCH_COMPARE CompareType);
void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link);

View File

@ -475,7 +475,9 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
case R4300i_SPECIAL_DSLL32: case R4300i_SPECIAL_DSRL32: case R4300i_SPECIAL_DSRA32:
case R4300i_SPECIAL_MULT: case R4300i_SPECIAL_MULTU: case R4300i_SPECIAL_DIV:
case R4300i_SPECIAL_DIVU: case R4300i_SPECIAL_DMULT: case R4300i_SPECIAL_DMULTU:
case R4300i_SPECIAL_DDIV: case R4300i_SPECIAL_DDIVU:
case R4300i_SPECIAL_DDIV: case R4300i_SPECIAL_DDIVU: case R4300i_SPECIAL_TEQ:
case R4300i_SPECIAL_TNE: case R4300i_SPECIAL_TGE: case R4300i_SPECIAL_TGEU:
case R4300i_SPECIAL_TLT: case R4300i_SPECIAL_TLTU:
break;
case R4300i_SPECIAL_JALR:
case R4300i_SPECIAL_JR:
@ -556,6 +558,9 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
LikelyBranch = true;
IncludeDelaySlot = true;
break;
case R4300i_REGIMM_TEQI: case R4300i_REGIMM_TNEI: case R4300i_REGIMM_TGEI:
case R4300i_REGIMM_TGEIU: case R4300i_REGIMM_TLTI: case R4300i_REGIMM_TLTIU:
break;
default:
if (Command.Hex == 0x0407000D)
{

View File

@ -583,6 +583,13 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
case R4300i_SPECIAL_DSLL32: m_RecompilerOps->SPECIAL_DSLL32(); break;
case R4300i_SPECIAL_DSRL32: m_RecompilerOps->SPECIAL_DSRL32(); break;
case R4300i_SPECIAL_DSRA32: m_RecompilerOps->SPECIAL_DSRA32(); break;
case R4300i_SPECIAL_TEQ: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTEQ); break;
case R4300i_SPECIAL_TNE: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTNE); break;
case R4300i_SPECIAL_TGE: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGE); break;
case R4300i_SPECIAL_TGEU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGEU); break;
case R4300i_SPECIAL_TLT: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLT); break;
case R4300i_SPECIAL_TLTU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLTU); break;
break;
default:
m_RecompilerOps->UnknownOpcode(); break;
}
@ -596,6 +603,12 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
case R4300i_REGIMM_BGEZL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBGEZ, false); break;
case R4300i_REGIMM_BLTZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLTZ, CRecompilerOps::BranchTypeRs, true); break;
case R4300i_REGIMM_BGEZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGEZ, CRecompilerOps::BranchTypeRs, true); break;
case R4300i_REGIMM_TEQI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTEQI); break;
case R4300i_REGIMM_TNEI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTNEI); break;
case R4300i_REGIMM_TGEI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGEI); break;
case R4300i_REGIMM_TGEIU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGEIU); break;
case R4300i_REGIMM_TLTI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLTI); break;
case R4300i_REGIMM_TLTIU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLTIU); break;
default:
m_RecompilerOps->UnknownOpcode(); break;
}

View File

@ -238,6 +238,9 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
case R4300i_SPECIAL_DSLL32: SPECIAL_DSLL32(); break;
case R4300i_SPECIAL_DSRL32: SPECIAL_DSRL32(); break;
case R4300i_SPECIAL_DSRA32: SPECIAL_DSRA32(); break;
case R4300i_SPECIAL_TEQ: case R4300i_SPECIAL_TNE: case R4300i_SPECIAL_TGE:
case R4300i_SPECIAL_TGEU: case R4300i_SPECIAL_TLT: case R4300i_SPECIAL_TLTU:
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
#ifdef legacycode
@ -252,6 +255,9 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
case R4300i_REGIMM:
switch (m_Command.rt)
{
case R4300i_REGIMM_TEQI: case R4300i_REGIMM_TNEI: case R4300i_REGIMM_TGEI:
case R4300i_REGIMM_TGEIU: case R4300i_REGIMM_TLTI: case R4300i_REGIMM_TLTIU:
break;
case R4300i_REGIMM_BLTZ:
case R4300i_REGIMM_BGEZ:
m_NextInstruction = DELAY_SLOT;

View File

@ -35,6 +35,24 @@ public:
CompareTypeCOP1BCF,
CompareTypeCOP1BCT,
};
enum TRAP_COMPARE
{
CompareTypeTEQ,
CompareTypeTNE,
CompareTypeTGE,
CompareTypeTGEU,
CompareTypeTLT,
CompareTypeTLTU,
CompareTypeTEQI,
CompareTypeTNEI,
CompareTypeTGEI,
CompareTypeTGEIU,
CompareTypeTLTI,
CompareTypeTLTIU,
};
/*************************** Trap functions *************************/
virtual void Compile_TrapCompare(TRAP_COMPARE CompareType) = 0;
/************************** Branch functions ************************/
virtual void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link) = 0;

View File

@ -361,6 +361,84 @@ void CX86RecompilerOps::CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg)
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
/*************************** Trap functions *************************/
void CX86RecompilerOps::Compile_TrapCompare(TRAP_COMPARE CompareType)
{
void *FunctAddress = NULL;
const char *FunctName = NULL;
switch (CompareType)
{
case CompareTypeTEQ:
FunctAddress = (void*)R4300iOp::SPECIAL_TEQ;
FunctName = "R4300iOp::SPECIAL_TEQ";
break;
case CompareTypeTNE:
FunctAddress = (void*)R4300iOp::SPECIAL_TNE;
FunctName = "R4300iOp::SPECIAL_TNE";
break;
case CompareTypeTGE:
FunctAddress = (void*)R4300iOp::SPECIAL_TGE;
FunctName = "R4300iOp::SPECIAL_TGE";
break;
case CompareTypeTGEU:
FunctAddress = (void*)R4300iOp::SPECIAL_TGEU;
FunctName = "R4300iOp::SPECIAL_TGEU";
break;
case CompareTypeTLT:
FunctAddress = (void*)R4300iOp::SPECIAL_TLT;
FunctName = "R4300iOp::SPECIAL_TLT";
break;
case CompareTypeTLTU:
FunctAddress = (void*)R4300iOp::SPECIAL_TLTU;
FunctName = "R4300iOp::SPECIAL_TLTU";
break;
case CompareTypeTEQI:
FunctAddress = (void*)R4300iOp::REGIMM_TEQI;
FunctName = "R4300iOp::REGIMM_TEQI";
break;
case CompareTypeTNEI:
FunctAddress = (void*)R4300iOp::REGIMM_TNEI;
FunctName = "R4300iOp::REGIMM_TNEI";
break;
case CompareTypeTGEI:
FunctAddress = (void*)R4300iOp::REGIMM_TGEI;
FunctName = "R4300iOp::REGIMM_TGEI";
break;
case CompareTypeTGEIU:
FunctAddress = (void*)R4300iOp::REGIMM_TGEIU;
FunctName = "R4300iOp::REGIMM_TGEIU";
break;
case CompareTypeTLTI:
FunctAddress = (void*)R4300iOp::REGIMM_TLTI;
FunctName = "R4300iOp::REGIMM_TLTI";
break;
case CompareTypeTLTIU:
FunctAddress = (void*)R4300iOp::REGIMM_TLTIU;
FunctName = "R4300iOp::REGIMM_TLTIU";
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (FunctName != NULL && FunctAddress != NULL)
{
if (IsMapped(m_Opcode.rs)) {
UnMap_GPR(m_Opcode.rs, true);
}
if (IsMapped(m_Opcode.rt)) {
UnMap_GPR(m_Opcode.rt, true);
}
m_RegWorkingSet.BeforeCallDirect();
MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex");
Call_Direct(FunctAddress, FunctName);
m_RegWorkingSet.AfterCallDirect();
}
else
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
}
/************************** Branch functions ************************/
void CX86RecompilerOps::Compile_BranchCompare(BRANCH_COMPARE CompareType)
{

View File

@ -33,6 +33,9 @@ class CX86RecompilerOps :
protected CRecompilerSettings
{
public:
/*************************** Trap functions *************************/
void Compile_TrapCompare(TRAP_COMPARE CompareType);
/************************** Branch functions ************************/
void Compile_BranchCompare(BRANCH_COMPARE CompareType);
void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link);