diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 0bc60a890..d70241b6f 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -250,13 +250,13 @@ R4300iOp::Func * R4300iOp::BuildInterpreter() Jump_Special[45] = SPECIAL_DADDU; Jump_Special[46] = SPECIAL_DSUB; Jump_Special[47] = SPECIAL_DSUBU; - Jump_Special[48] = UnknownOpcode; - Jump_Special[49] = UnknownOpcode; - Jump_Special[50] = UnknownOpcode; - Jump_Special[51] = UnknownOpcode; + Jump_Special[48] = SPECIAL_TGE; + Jump_Special[49] = SPECIAL_TGEU; + Jump_Special[50] = SPECIAL_TLT; + Jump_Special[51] = SPECIAL_TLTU; Jump_Special[52] = SPECIAL_TEQ; Jump_Special[53] = UnknownOpcode; - Jump_Special[54] = UnknownOpcode; + Jump_Special[54] = SPECIAL_TNE; Jump_Special[55] = UnknownOpcode; Jump_Special[56] = SPECIAL_DSLL; Jump_Special[57] = UnknownOpcode; @@ -275,13 +275,13 @@ R4300iOp::Func * R4300iOp::BuildInterpreter() Jump_Regimm[5] = UnknownOpcode; Jump_Regimm[6] = UnknownOpcode; Jump_Regimm[7] = UnknownOpcode; - Jump_Regimm[8] = UnknownOpcode; - Jump_Regimm[9] = UnknownOpcode; - Jump_Regimm[10] = UnknownOpcode; - Jump_Regimm[11] = UnknownOpcode; - Jump_Regimm[12] = UnknownOpcode; + Jump_Regimm[8] = REGIMM_TGEI; + Jump_Regimm[9] = REGIMM_TGEIU; + Jump_Regimm[10] = REGIMM_TLTI; + Jump_Regimm[11] = REGIMM_TLTIU; + Jump_Regimm[12] = REGIMM_TEQI; Jump_Regimm[13] = UnknownOpcode; - Jump_Regimm[14] = UnknownOpcode; + Jump_Regimm[14] = REGIMM_TNEI; Jump_Regimm[15] = UnknownOpcode; Jump_Regimm[16] = REGIMM_BLTZAL; Jump_Regimm[17] = REGIMM_BGEZAL; @@ -2048,9 +2048,49 @@ void R4300iOp::SPECIAL_DSUBU() void R4300iOp::SPECIAL_TEQ() { - if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW) { - g_Notify->DisplayError("Should trap this ???"); + g_Reg->DoTrapException(m_NextInstruction == JUMP); + } +} + +void R4300iOp::SPECIAL_TGE() +{ + if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + } +} + +void R4300iOp::SPECIAL_TGEU() +{ + if (_GPR[m_Opcode.rs].UDW >= _GPR[m_Opcode.rt].UDW) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + } +} + +void R4300iOp::SPECIAL_TLT() +{ + if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + } +} + +void R4300iOp::SPECIAL_TLTU() +{ + if (_GPR[m_Opcode.rs].UDW < _GPR[m_Opcode.rt].UDW) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + } +} + +void R4300iOp::SPECIAL_TNE() +{ + if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); } } @@ -2220,6 +2260,63 @@ void R4300iOp::REGIMM_BGEZAL() } _GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8); } + +void R4300iOp::REGIMM_TEQI() +{ + if (_GPR[m_Opcode.rs].DW == (int64_t)((int16_t)m_Opcode.immediate)) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + } +} + +void R4300iOp::REGIMM_TGEI() +{ + if (_GPR[m_Opcode.rs].DW >= (int64_t)((int16_t)m_Opcode.immediate)) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + } +} + +void R4300iOp::REGIMM_TGEIU() +{ + 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); + } +} + +void R4300iOp::REGIMM_TLTI() +{ + if (_GPR[m_Opcode.rs].DW < (int64_t)((int16_t)m_Opcode.immediate)) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + } +} + +void R4300iOp::REGIMM_TLTIU() +{ + 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); + } +} + +void R4300iOp::REGIMM_TNEI() +{ + if (_GPR[m_Opcode.rs].DW != (int64_t)((int16_t)m_Opcode.immediate)) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + } +} + /************************** COP0 functions **************************/ void R4300iOp::COP0_MF() { diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h index 273d574bd..80fffa594 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h @@ -110,7 +110,12 @@ public: static void SPECIAL_DADDU(); static void SPECIAL_DSUB(); static void SPECIAL_DSUBU(); + static void SPECIAL_TGE(); + static void SPECIAL_TGEU(); + static void SPECIAL_TLT(); + static void SPECIAL_TLTU(); static void SPECIAL_TEQ(); + static void SPECIAL_TNE(); static void SPECIAL_DSLL(); static void SPECIAL_DSRL(); static void SPECIAL_DSRA(); @@ -125,6 +130,12 @@ public: static void REGIMM_BGEZL(); static void REGIMM_BLTZAL(); static void REGIMM_BGEZAL(); + static void REGIMM_TEQI(); + static void REGIMM_TGEI(); + static void REGIMM_TGEIU(); + static void REGIMM_TLTI(); + static void REGIMM_TLTIU(); + static void REGIMM_TNEI(); /************************** COP0 functions **************************/ static void COP0_MF(); diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp index 53b2dc4ac..70cd0949b 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp @@ -155,13 +155,13 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter() Jump_Special[45] = R4300iOp::SPECIAL_DADDU; Jump_Special[46] = R4300iOp::SPECIAL_DSUB; Jump_Special[47] = R4300iOp::SPECIAL_DSUBU; - Jump_Special[48] = R4300iOp::UnknownOpcode; - Jump_Special[49] = R4300iOp::UnknownOpcode; - Jump_Special[50] = R4300iOp::UnknownOpcode; - Jump_Special[51] = R4300iOp::UnknownOpcode; + Jump_Special[48] = R4300iOp::SPECIAL_TGE; + Jump_Special[49] = R4300iOp::SPECIAL_TGEU; + Jump_Special[50] = R4300iOp::SPECIAL_TLT; + Jump_Special[51] = R4300iOp::SPECIAL_TLTU; Jump_Special[52] = R4300iOp::SPECIAL_TEQ; Jump_Special[53] = R4300iOp::UnknownOpcode; - Jump_Special[54] = R4300iOp::UnknownOpcode; + Jump_Special[54] = R4300iOp::SPECIAL_TNE; Jump_Special[55] = R4300iOp::UnknownOpcode; Jump_Special[56] = R4300iOp::SPECIAL_DSLL; Jump_Special[57] = R4300iOp::UnknownOpcode; @@ -180,13 +180,13 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter() Jump_Regimm[5] = R4300iOp::UnknownOpcode; Jump_Regimm[6] = R4300iOp::UnknownOpcode; Jump_Regimm[7] = R4300iOp::UnknownOpcode; - Jump_Regimm[8] = R4300iOp::UnknownOpcode; - Jump_Regimm[9] = R4300iOp::UnknownOpcode; - Jump_Regimm[10] = R4300iOp::UnknownOpcode; - Jump_Regimm[11] = R4300iOp::UnknownOpcode; - Jump_Regimm[12] = R4300iOp::UnknownOpcode; + Jump_Regimm[8] = R4300iOp::REGIMM_TGEI; + Jump_Regimm[9] = R4300iOp::REGIMM_TGEIU; + Jump_Regimm[10] = R4300iOp::REGIMM_TLTI; + Jump_Regimm[11] = R4300iOp::REGIMM_TLTIU; + Jump_Regimm[12] = R4300iOp::REGIMM_TEQI; Jump_Regimm[13] = R4300iOp::UnknownOpcode; - Jump_Regimm[14] = R4300iOp::UnknownOpcode; + Jump_Regimm[14] = R4300iOp::REGIMM_TNEI; Jump_Regimm[15] = R4300iOp::UnknownOpcode; Jump_Regimm[16] = REGIMM_BLTZAL; Jump_Regimm[17] = REGIMM_BGEZAL; diff --git a/Source/Project64-core/N64System/Mips/RegisterClass.cpp b/Source/Project64-core/N64System/Mips/RegisterClass.cpp index ed175a744..28a994844 100644 --- a/Source/Project64-core/N64System/Mips/RegisterClass.cpp +++ b/Source/Project64-core/N64System/Mips/RegisterClass.cpp @@ -438,6 +438,22 @@ void CRegisters::DoBreakException(bool DelaySlot) m_PROGRAM_COUNTER = 0x80000180; } +void CRegisters::DoTrapException(bool DelaySlot) +{ + CAUSE_REGISTER = EXC_TRAP; + if (DelaySlot) + { + EPC_REGISTER = m_PROGRAM_COUNTER - 4; + CAUSE_REGISTER |= CAUSE_BD; + } + else + { + EPC_REGISTER = m_PROGRAM_COUNTER; + } + m_PROGRAM_COUNTER = 0x80000180; + +} + void CRegisters::DoCopUnusableException(bool DelaySlot, int Coprocessor) { if (HaveDebugger()) diff --git a/Source/Project64-core/N64System/Mips/RegisterClass.h b/Source/Project64-core/N64System/Mips/RegisterClass.h index ef6dd0345..ae266cd06 100644 --- a/Source/Project64-core/N64System/Mips/RegisterClass.h +++ b/Source/Project64-core/N64System/Mips/RegisterClass.h @@ -631,6 +631,7 @@ public: void CheckInterrupts (); void DoAddressError ( bool DelaySlot, uint32_t BadVaddr, bool FromRead ); void DoBreakException ( bool DelaySlot ); + void DoTrapException ( bool DelaySlot ); void DoCopUnusableException ( bool DelaySlot, int32_t Coprocessor ); bool DoIntrException ( bool DelaySlot ); void DoTLBReadMiss ( bool DelaySlot, uint32_t BadVaddr ); diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp index 7feada20b..b9dc356f9 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp @@ -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) { diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h index ab1aeb4c6..e0dd38ac4 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h @@ -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); diff --git a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp index 7d0911f76..9babef77f 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp @@ -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) { diff --git a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp index b47186f34..082f6b0df 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp @@ -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; } diff --git a/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp b/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp index d25a4d5fa..1193c575b 100644 --- a/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp +++ b/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp @@ -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; diff --git a/Source/Project64-core/N64System/Recompiler/RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/RecompilerOps.h index 392a74858..d126f80f0 100644 --- a/Source/Project64-core/N64System/Recompiler/RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/RecompilerOps.h @@ -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; diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index d5bedb821..9a0ee3605 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -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) { diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h index 8111de5f9..49f1711b9 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h @@ -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);