From d35d2e6abe8e3c80715460bba6e4305087f4b416 Mon Sep 17 00:00:00 2001 From: zilmar Date: Mon, 5 Dec 2022 12:23:09 +1030 Subject: [PATCH] Core: Move ReadsGPR, WritesGPR, ReadsHI(), ReadsLO(), WritesHI(), WritesLO() out of OpInfo and into R4300iInstruction --- .../N64System/Mips/R4300iInstruction.cpp | 344 +++++++----------- .../N64System/Mips/R4300iInstruction.h | 6 + .../Debugger/Debugger-RegisterTabs.cpp | 16 +- .../UserInterface/Debugger/Debugger.cpp | 11 +- .../Project64/UserInterface/Debugger/OpInfo.h | 136 ------- 5 files changed, 153 insertions(+), 360 deletions(-) diff --git a/Source/Project64-core/N64System/Mips/R4300iInstruction.cpp b/Source/Project64-core/N64System/Mips/R4300iInstruction.cpp index 7e8b9f43c..930ecc56c 100644 --- a/Source/Project64-core/N64System/Mips/R4300iInstruction.cpp +++ b/Source/Project64-core/N64System/Mips/R4300iInstruction.cpp @@ -82,49 +82,8 @@ bool R4300iInstruction::DelaySlotEffectsCompare(uint32_t DelayInstruction) const { R4300iInstruction DelaySlot(m_Address + 4, DelayInstruction); - uint32_t Reg1 = 0, Reg2 = 0; - switch (m_Instruction.op) + if (m_Instruction.op == R4300i_CP1) { - case R4300i_SPECIAL: - switch (m_Instruction.funct) - { - case R4300i_SPECIAL_JR: - case R4300i_SPECIAL_JALR: - Reg1 = m_Instruction.rs; - break; - default: - return false; - } - break; - case R4300i_REGIMM: - switch (m_Instruction.rt) - { - case R4300i_REGIMM_BLTZ: - case R4300i_REGIMM_BGEZ: - case R4300i_REGIMM_BLTZL: - case R4300i_REGIMM_BGEZL: - case R4300i_REGIMM_BLTZAL: - case R4300i_REGIMM_BGEZAL: - Reg1 = m_Instruction.rs; - break; - default: - return false; - } - break; - case R4300i_BEQ: - case R4300i_BNE: - case R4300i_BEQL: - case R4300i_BNEL: - Reg1 = m_Instruction.rs; - Reg2 = m_Instruction.rt; - break; - case R4300i_BLEZ: - case R4300i_BGTZ: - case R4300i_BLEZL: - case R4300i_BGTZL: - Reg1 = m_Instruction.rs; - break; - case R4300i_CP1: if (m_Instruction.fmt == R4300i_COP1_BC) { if (DelaySlot.m_Instruction.op == R4300i_CP1) @@ -137,190 +96,151 @@ bool R4300iInstruction::DelaySlotEffectsCompare(uint32_t DelayInstruction) const } } return false; - break; - default: - return false; + } + uint32_t WriteReg = 0, ReadReg1 = 0, ReadReg2 = 0; + ReadsGPR(ReadReg1, ReadReg2); + DelaySlot.WritesGPR(WriteReg); + if (WriteReg != 0 && (WriteReg == ReadReg1 || WriteReg == ReadReg2)) + { + return true; + } + return false; +} + + +void R4300iInstruction::ReadsGPR(uint32_t & Reg1, uint32_t & Reg2) const +{ + uint32_t op = m_Instruction.op; + + if (op == R4300i_SPECIAL) + { + uint32_t fn = m_Instruction.funct; + + if (fn >= R4300i_SPECIAL_SLLV && fn <= R4300i_SPECIAL_SRAV || fn >= R4300i_SPECIAL_DSLLV && fn <= R4300i_SPECIAL_DSRAV || fn >= R4300i_SPECIAL_MULT && fn <= R4300i_SPECIAL_TNE) + { + Reg1 = m_Instruction.rs; + Reg2 = m_Instruction.rt; + return; + } + + if (fn == R4300i_SPECIAL_MTLO || fn == R4300i_SPECIAL_MTHI || fn == R4300i_SPECIAL_JR || fn == R4300i_SPECIAL_JALR) + { + Reg1 = m_Instruction.rs; + Reg2 = 0; + return; + } + + if (fn >= R4300i_SPECIAL_SLL && fn <= R4300i_SPECIAL_SRA || fn >= R4300i_SPECIAL_DSLL && fn <= R4300i_SPECIAL_DSRA32) + { + Reg1 = m_Instruction.rt; + Reg2 = 0; + return; + } + + Reg1 = 0; + Reg2 = 0; + return; } - switch (DelaySlot.m_Instruction.op) + if (op >= R4300i_SB && op <= R4300i_SWR || op == R4300i_SC || op == R4300i_SD || op == R4300i_BEQ || op == R4300i_BEQL || op == R4300i_BNE || op == R4300i_BNEL) { - case R4300i_SPECIAL: - switch (DelaySlot.m_Instruction.funct) + Reg1 = m_Instruction.rs; + Reg2 = m_Instruction.rt; + return; + } + + if (op >= R4300i_BLEZL && op <= R4300i_LWU || op >= R4300i_BLEZ && op <= R4300i_XORI || op >= R4300i_CACHE && op <= R4300i_LD || op >= R4300i_SWC1 && op <= R4300i_SDC2 || op == R4300i_REGIMM) + { + Reg1 = m_Instruction.rs; + Reg2 = 0; + return; + } + + if (op == R4300i_CP0 && m_Instruction.fmt == R4300i_COP0_MT) + { + Reg1 = m_Instruction.rt; + Reg2 = 0; + return; + } + + if (op == R4300i_CP1) + { + if (m_Instruction.fmt == R4300i_COP1_MT || m_Instruction.fmt == R4300i_COP1_DMT || m_Instruction.fmt == R4300i_COP1_CT) { - case R4300i_SPECIAL_SLL: - case R4300i_SPECIAL_SRL: - case R4300i_SPECIAL_SRA: - case R4300i_SPECIAL_SLLV: - case R4300i_SPECIAL_SRLV: - case R4300i_SPECIAL_SRAV: - case R4300i_SPECIAL_MFHI: - case R4300i_SPECIAL_MTHI: - case R4300i_SPECIAL_MFLO: - case R4300i_SPECIAL_MTLO: - case R4300i_SPECIAL_DSLLV: - case R4300i_SPECIAL_DSRLV: - case R4300i_SPECIAL_DSRAV: - case R4300i_SPECIAL_ADD: - case R4300i_SPECIAL_ADDU: - case R4300i_SPECIAL_SUB: - case R4300i_SPECIAL_SUBU: - case R4300i_SPECIAL_AND: - case R4300i_SPECIAL_OR: - case R4300i_SPECIAL_XOR: - case R4300i_SPECIAL_NOR: - case R4300i_SPECIAL_SLT: - case R4300i_SPECIAL_SLTU: - case R4300i_SPECIAL_DADD: - case R4300i_SPECIAL_DADDU: - case R4300i_SPECIAL_DSUB: - case R4300i_SPECIAL_DSUBU: - case R4300i_SPECIAL_DSLL: - case R4300i_SPECIAL_DSRL: - case R4300i_SPECIAL_DSRA: - case R4300i_SPECIAL_DSLL32: - case R4300i_SPECIAL_DSRL32: - case R4300i_SPECIAL_DSRA32: - if (DelaySlot.m_Instruction.rd == 0) - { - return false; - } - if (DelaySlot.m_Instruction.rd == Reg1 || DelaySlot.m_Instruction.rd == Reg2) - { - return true; - } - break; - 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: - break; - default: - if (CDebugSettings::HaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?", DelaySlot.Name(), m_Address).c_str()); - } - return true; + Reg1 = m_Instruction.rt; + Reg2 = 0; + return; } - break; - case R4300i_CP0: - switch (DelaySlot.m_Instruction.rs) + } + + Reg1 = 0; + Reg2 = 0; +} + +void R4300iInstruction::WritesGPR(uint32_t & nReg) const +{ + uint32_t op = m_Instruction.op; + if (op == R4300i_SPECIAL) + { + uint32_t fn = m_Instruction.funct; + if (fn >= R4300i_SPECIAL_SLL && fn <= R4300i_SPECIAL_SRAV || fn >= R4300i_SPECIAL_DSLLV && fn <= R4300i_SPECIAL_DSRAV || fn >= R4300i_SPECIAL_DIVU && fn <= R4300i_SPECIAL_DSUBU || fn >= R4300i_SPECIAL_DSLL && fn <= R4300i_SPECIAL_DSRA32 || fn == R4300i_SPECIAL_JALR || fn == R4300i_SPECIAL_MFLO || fn == R4300i_SPECIAL_MFHI) { - case R4300i_COP0_MT: break; - case R4300i_COP0_MF: - if (DelaySlot.m_Instruction.rt == 0) - { - return false; - } - if (DelaySlot.m_Instruction.rt == Reg1 || DelaySlot.m_Instruction.rt == Reg2) - { - return true; - } - break; - default: - if ((DelaySlot.m_Instruction.rs & 0x10) != 0) - { - switch (DelaySlot.m_Instruction.funct) - { - case R4300i_COP0_CO_TLBR: break; - case R4300i_COP0_CO_TLBWI: break; - case R4300i_COP0_CO_TLBWR: break; - case R4300i_COP0_CO_TLBP: break; - default: - if (CDebugSettings::HaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?\n6", DelaySlot.Name(), m_Address).c_str()); - } - return true; - } - } - else - { - if (CDebugSettings::HaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?\n7", DelaySlot.Name(), m_Address).c_str()); - } - return true; - } + nReg = m_Instruction.rd; + return; } - break; - case R4300i_CP1: - switch (DelaySlot.m_Instruction.fmt) + } + else if (op == R4300i_REGIMM) + { + if (op >= R4300i_REGIMM_BLTZAL && op <= R4300i_REGIMM_BGEZALL) { - case R4300i_COP1_MF: - if (DelaySlot.m_Instruction.rt == 0) - { - return false; - } - if (DelaySlot.m_Instruction.rt == Reg1 || DelaySlot.m_Instruction.rt == Reg2) - { - return true; - } - break; - case R4300i_COP1_CF: break; - case R4300i_COP1_MT: break; - case R4300i_COP1_CT: break; - case R4300i_COP1_S: break; - case R4300i_COP1_D: break; - case R4300i_COP1_W: break; - case R4300i_COP1_L: break; - default: - if (CDebugSettings::HaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?", DelaySlot.Name(), m_Address).c_str()); - } - return true; + nReg = 31; // RA + return; } - break; - case R4300i_ANDI: - case R4300i_ORI: - case R4300i_XORI: - case R4300i_LUI: - case R4300i_ADDI: - case R4300i_ADDIU: - case R4300i_SLTI: - case R4300i_SLTIU: - case R4300i_DADDI: - case R4300i_DADDIU: - case R4300i_LB: - case R4300i_LH: - case R4300i_LW: - case R4300i_LWL: - case R4300i_LWR: - case R4300i_LDL: - case R4300i_LDR: - case R4300i_LBU: - case R4300i_LHU: - case R4300i_LD: - case R4300i_LWC1: - case R4300i_LDC1: - if (DelaySlot.m_Instruction.rt == 0) - { - return false; - } - if (DelaySlot.m_Instruction.rt == Reg1 || DelaySlot.m_Instruction.rt == Reg2) + } + else if (op >= R4300i_DADDI && op <= R4300i_LWU || op >= R4300i_ADDI && op <= R4300i_LUI || op == R4300i_LL || op == R4300i_LD || (op == R4300i_CP0 && m_Instruction.fmt == R4300i_COP0_MF) || (op == R4300i_CP1 && m_Instruction.fmt == R4300i_COP1_MF) || (op == R4300i_CP1 && m_Instruction.fmt == R4300i_COP1_CF)) + { + nReg = m_Instruction.rt; + return; + } + + if (op == R4300i_JAL) + { + nReg = 31; // RA + return; + } + nReg = 0; +} + +bool R4300iInstruction::ReadsHI() const +{ + return (m_Instruction.op == R4300i_SPECIAL && m_Instruction.funct == R4300i_SPECIAL_MFHI); +} + +bool R4300iInstruction::ReadsLO() const +{ + return (m_Instruction.op == R4300i_SPECIAL && m_Instruction.funct == R4300i_SPECIAL_MFLO); +} + +bool R4300iInstruction::WritesHI() const +{ + if (m_Instruction.op == R4300i_SPECIAL) + { + if (m_Instruction.funct == R4300i_SPECIAL_MTHI || m_Instruction.funct >= R4300i_SPECIAL_MULT && m_Instruction.funct <= R4300i_SPECIAL_DDIVU) { return true; } - break; - case R4300i_CACHE: break; - case R4300i_SB: break; - case R4300i_SH: break; - case R4300i_SW: break; - case R4300i_SWR: break; - case R4300i_SWL: break; - case R4300i_SWC1: break; - case R4300i_SDC1: break; - case R4300i_SD: break; - default: - if (CDebugSettings::HaveDebugger()) + } + return false; +} + +bool R4300iInstruction::WritesLO() const +{ + if (m_Instruction.op == R4300i_SPECIAL) + { + if (m_Instruction.funct == R4300i_SPECIAL_MTLO || m_Instruction.funct >= R4300i_SPECIAL_MULT && m_Instruction.funct <= R4300i_SPECIAL_DDIVU) { - g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?", DelaySlot.Name(), m_Address).c_str()); + return true; } - return true; } return false; } diff --git a/Source/Project64-core/N64System/Mips/R4300iInstruction.h b/Source/Project64-core/N64System/Mips/R4300iInstruction.h index 4ab3cd10f..d7e546e2d 100644 --- a/Source/Project64-core/N64System/Mips/R4300iInstruction.h +++ b/Source/Project64-core/N64System/Mips/R4300iInstruction.h @@ -13,6 +13,12 @@ public: bool HasDelaySlot(void) const; bool DelaySlotEffectsCompare(uint32_t DelayInstruction) const; + void ReadsGPR(uint32_t & Reg1, uint32_t & Reg2) const; + void WritesGPR(uint32_t & nReg) const; + bool ReadsHI() const; + bool ReadsLO() const; + bool WritesHI() const; + bool WritesLO() const; private: R4300iInstruction(void); diff --git a/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp b/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp index 30a879cc3..b8a537fb2 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" +#include #include "Debugger-RegisterTabs.h" #include "OpInfo.h" @@ -483,8 +484,9 @@ INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, L HWND hWnd = (HWND)lParam; WORD ctrlId = (WORD)::GetWindowLong(hWnd, GWL_ID); - COpInfo opInfo; - m_Debugger->DebugLoad_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Value); + uint32_t Instruction; + m_Debugger->DebugLoad_VAddr(g_Reg->m_PROGRAM_COUNTER, Instruction); + R4300iInstruction opInfo(g_Reg->m_PROGRAM_COUNTER, Instruction); bool bOpReads = false; bool bOpWrites = false; @@ -508,13 +510,13 @@ INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, L return (LRESULT)GetStockObject(DC_BRUSH); } - int nRegRead1, nRegRead2, nRegWrite; + uint32_t nRegRead1, nRegRead2, nRegWrite; - opInfo.ReadsGPR(&nRegRead1, &nRegRead2); - opInfo.WritesGPR(&nRegWrite); + opInfo.ReadsGPR(nRegRead1, nRegRead2); + opInfo.WritesGPR(nRegWrite); - bOpReads = (nReg == nRegRead1) || (nReg == nRegRead2); - bOpWrites = (nReg == nRegWrite); + bOpReads = ((uint32_t)nReg == nRegRead1) || ((uint32_t)nReg == nRegRead2); + bOpWrites = ((uint32_t)nReg == nRegWrite); } if (bOpReads && bOpWrites) diff --git a/Source/Project64/UserInterface/Debugger/Debugger.cpp b/Source/Project64/UserInterface/Debugger/Debugger.cpp index 5baa9062a..17bf63258 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" +#include #include "DebuggerUI.h" #include "CPULog.h" @@ -638,12 +639,12 @@ void CDebuggerUI::CPUStepStarted() if (m_Breakpoints->HaveRegBP()) { - COpInfo opInfo(R4300iOp::m_Opcode); + R4300iInstruction opInfo(g_Reg->m_PROGRAM_COUNTER, R4300iOp::m_Opcode.Value); if (m_Breakpoints->HaveAnyGPRWriteBP()) { - int nReg = 0; - opInfo.WritesGPR(&nReg); + uint32_t nReg = 0; + opInfo.WritesGPR(nReg); if (nReg != 0 && m_Breakpoints->HaveGPRWriteBP(nReg)) { @@ -653,8 +654,8 @@ void CDebuggerUI::CPUStepStarted() if (m_Breakpoints->HaveAnyGPRReadBP()) { - int nReg1 = 0, nReg2 = 0; - opInfo.ReadsGPR(&nReg1, &nReg2); + uint32_t nReg1 = 0, nReg2 = 0; + opInfo.ReadsGPR(nReg1, nReg2); if ((nReg1 != 0 && m_Breakpoints->HaveGPRReadBP(nReg1)) || (nReg2 != 0 && m_Breakpoints->HaveGPRReadBP(nReg2))) { diff --git a/Source/Project64/UserInterface/Debugger/OpInfo.h b/Source/Project64/UserInterface/Debugger/OpInfo.h index 9a33f5ddb..e216a48dd 100644 --- a/Source/Project64/UserInterface/Debugger/OpInfo.h +++ b/Source/Project64/UserInterface/Debugger/OpInfo.h @@ -170,142 +170,6 @@ public: return (short)m_OpCode.immediate > 0; } - void ReadsGPR(int * nReg1, int * nReg2) - { - uint32_t op = m_OpCode.op; - - if (op == R4300i_SPECIAL) - { - uint32_t fn = m_OpCode.funct; - - if (fn >= R4300i_SPECIAL_SLLV && fn <= R4300i_SPECIAL_SRAV || fn >= R4300i_SPECIAL_DSLLV && fn <= R4300i_SPECIAL_DSRAV || fn >= R4300i_SPECIAL_MULT && fn <= R4300i_SPECIAL_TNE) - { - *nReg1 = m_OpCode.rs; - *nReg2 = m_OpCode.rt; - return; - } - - if (fn == R4300i_SPECIAL_MTLO || fn == R4300i_SPECIAL_MTHI || fn == R4300i_SPECIAL_JR || fn == R4300i_SPECIAL_JALR) - { - *nReg1 = m_OpCode.rs; - *nReg2 = 0; - return; - } - - if (fn >= R4300i_SPECIAL_SLL && fn <= R4300i_SPECIAL_SRA || fn >= R4300i_SPECIAL_DSLL && fn <= R4300i_SPECIAL_DSRA32) - { - *nReg1 = m_OpCode.rt; - *nReg2 = 0; - return; - } - - *nReg1 = 0; - *nReg2 = 0; - return; - } - - if (op >= R4300i_SB && op <= R4300i_SWR || op == R4300i_SC || op == R4300i_SD || op == R4300i_BEQ || op == R4300i_BEQL || op == R4300i_BNE || op == R4300i_BNEL) - { - *nReg1 = m_OpCode.rs; - *nReg2 = m_OpCode.rt; - return; - } - - if (op >= R4300i_BLEZL && op <= R4300i_LWU || op >= R4300i_BLEZ && op <= R4300i_XORI || op >= R4300i_CACHE && op <= R4300i_LD || op >= R4300i_SWC1 && op <= R4300i_SDC2 || op == R4300i_REGIMM) - { - *nReg1 = m_OpCode.rs; - *nReg2 = 0; - return; - } - - if (op == R4300i_CP0 && m_OpCode.fmt == R4300i_COP0_MT) - { - *nReg1 = m_OpCode.rt; - *nReg2 = 0; - return; - } - - if (op == R4300i_CP1) - { - if (m_OpCode.fmt == R4300i_COP1_MT || m_OpCode.fmt == R4300i_COP1_DMT || m_OpCode.fmt == R4300i_COP1_CT) - { - *nReg1 = m_OpCode.rt; - *nReg2 = 0; - return; - } - } - - *nReg1 = 0; - *nReg2 = 0; - } - - inline void WritesGPR(int * nReg) - { - uint32_t op = m_OpCode.op; - - if (op == R4300i_SPECIAL) - { - uint32_t fn = m_OpCode.funct; - - if (fn >= R4300i_SPECIAL_SLL && fn <= R4300i_SPECIAL_SRAV || fn >= R4300i_SPECIAL_DSLLV && fn <= R4300i_SPECIAL_DSRAV || fn >= R4300i_SPECIAL_DIVU && fn <= R4300i_SPECIAL_DSUBU || fn >= R4300i_SPECIAL_DSLL && fn <= R4300i_SPECIAL_DSRA32 || fn == R4300i_SPECIAL_JALR || fn == R4300i_SPECIAL_MFLO || fn == R4300i_SPECIAL_MFHI) - { - *nReg = m_OpCode.rd; - return; - } - - *nReg = 0; - return; - } - - if (op >= R4300i_DADDI && op <= R4300i_LWU || op >= R4300i_ADDI && op <= R4300i_LUI || op == R4300i_LL || op == R4300i_LD || (op == R4300i_CP0 && m_OpCode.fmt == R4300i_COP0_MF) || (op == R4300i_CP1 && m_OpCode.fmt == R4300i_COP1_MF) || (op == R4300i_CP1 && m_OpCode.fmt == R4300i_COP1_CF)) - { - *nReg = m_OpCode.rt; - return; - } - - if (op == R4300i_JAL) - { - *nReg = 31; // RA - return; - } - - *nReg = 0; - } - - inline bool ReadsHI() - { - return (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MFHI); - } - - inline bool ReadsLO() - { - return (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MFLO); - } - - inline bool WritesHI() - { - if (m_OpCode.op == R4300i_SPECIAL) - { - if (m_OpCode.funct == R4300i_SPECIAL_MTHI || m_OpCode.funct >= R4300i_SPECIAL_MULT && m_OpCode.funct <= R4300i_SPECIAL_DDIVU) - { - return true; - } - } - return false; - } - - inline bool WritesLO() - { - if (m_OpCode.op == R4300i_SPECIAL) - { - if (m_OpCode.funct == R4300i_SPECIAL_MTLO || m_OpCode.funct >= R4300i_SPECIAL_MULT && m_OpCode.funct <= R4300i_SPECIAL_DDIVU) - { - return true; - } - } - return false; - } - inline uint32_t GetLoadStoreAddress() { return g_Reg->m_GPR[m_OpCode.base].UW[0] + (int16_t)m_OpCode.offset;