From b9be612ac5daa0557241975101665fca7a608052 Mon Sep 17 00:00:00 2001 From: KrimtonZ Date: Mon, 16 Dec 2019 14:15:26 -0600 Subject: [PATCH 1/3] add remaining trap instructions, properly implement traps for the interpreter core --- .../N64System/Interpreter/InterpreterOps.cpp | 137 ++++++++++++++++-- .../N64System/Interpreter/InterpreterOps.h | 11 ++ .../Interpreter/InterpreterOps32.cpp | 22 +-- .../N64System/Mips/RegisterClass.cpp | 16 ++ .../N64System/Mips/RegisterClass.h | 1 + 5 files changed, 164 insertions(+), 23 deletions(-) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 0bc60a890..b920bd947 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; @@ -2050,7 +2050,59 @@ void R4300iOp::SPECIAL_TEQ() { if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW && HaveDebugger()) { - g_Notify->DisplayError("Should trap this ???"); + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::SPECIAL_TGE() +{ + if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::SPECIAL_TGEU() +{ + if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::SPECIAL_TLT() +{ + if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::SPECIAL_TLTU() +{ + if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::SPECIAL_TNE() +{ + if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); } } @@ -2220,6 +2272,67 @@ void R4300iOp::REGIMM_BGEZAL() } _GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8); } + +void R4300iOp::REGIMM_TEQI() +{ + if (_GPR[m_Opcode.rs].DW == m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::REGIMM_TGEI() +{ + if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::REGIMM_TGEIU() +{ + if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::REGIMM_TLTI() +{ + if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::REGIMM_TLTIU() +{ + if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::REGIMM_TNEI() +{ + if (_GPR[m_Opcode.rs].DW != m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + /************************** 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 ); From 0e5c7714084f26c3712c384d7ea1f096feee6f14 Mon Sep 17 00:00:00 2001 From: KrimtonZ Date: Mon, 16 Dec 2019 14:59:40 -0600 Subject: [PATCH 2/3] remove HaveDebugger requirement, remove redundant code --- .../N64System/Interpreter/InterpreterOps.cpp | 48 +++++-------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index b920bd947..020e2c0de 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -2048,61 +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_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::SPECIAL_TGE() { - if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::SPECIAL_TGEU() { - if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].D) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::SPECIAL_TLT() { - if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::SPECIAL_TLTU() { - if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::SPECIAL_TNE() { - if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } @@ -2275,61 +2263,49 @@ void R4300iOp::REGIMM_BGEZAL() void R4300iOp::REGIMM_TEQI() { - if (_GPR[m_Opcode.rs].DW == m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW == m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::REGIMM_TGEI() { - if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::REGIMM_TGEIU() { - if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::REGIMM_TLTI() { - if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::REGIMM_TLTIU() { - if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::REGIMM_TNEI() { - if (_GPR[m_Opcode.rs].DW != m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW != m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } From 0baf3ef263e16e8d5d4efc1e9f206f6fc2aa8321 Mon Sep 17 00:00:00 2001 From: KrimtonZ Date: Tue, 17 Dec 2019 09:08:15 -0600 Subject: [PATCH 3/3] 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);