From b9be612ac5daa0557241975101665fca7a608052 Mon Sep 17 00:00:00 2001 From: KrimtonZ Date: Mon, 16 Dec 2019 14:15:26 -0600 Subject: [PATCH 1/2] 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/2] 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); } }