From 0baf3ef263e16e8d5d4efc1e9f206f6fc2aa8321 Mon Sep 17 00:00:00 2001 From: KrimtonZ Date: Tue, 17 Dec 2019 09:08:15 -0600 Subject: [PATCH] Fix Trap Interpreter Functions, add recompiler trap functions --- .../N64System/Interpreter/InterpreterOps.cpp | 24 ++++-- .../Recompiler/Arm/ArmRecompilerOps.cpp | 71 +++++++++++++++++ .../Recompiler/Arm/ArmRecompilerOps.h | 3 + .../N64System/Recompiler/CodeBlock.cpp | 7 +- .../N64System/Recompiler/CodeSection.cpp | 13 ++++ .../N64System/Recompiler/LoopAnalysis.cpp | 6 ++ .../N64System/Recompiler/RecompilerOps.h | 18 +++++ .../Recompiler/x86/x86RecompilerOps.cpp | 78 +++++++++++++++++++ .../Recompiler/x86/x86RecompilerOps.h | 3 + 9 files changed, 214 insertions(+), 9 deletions(-) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 020e2c0de..d70241b6f 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -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); } 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);