From a6dab97928e9264d8053b32614fdb70fced00e8d Mon Sep 17 00:00:00 2001 From: Connor McLaughlin <stenzek@gmail.com> Date: Wed, 11 Dec 2019 21:44:26 +1000 Subject: [PATCH] CPU: Simplify GTE register addressing --- src/core/cpu_core.cpp | 20 ++++-- src/core/gte.cpp | 160 +++++++++--------------------------------- src/core/gte.h | 11 +-- src/core/gte_types.h | 2 + 4 files changed, 54 insertions(+), 139 deletions(-) diff --git a/src/core/cpu_core.cpp b/src/core/cpu_core.cpp index 3076f3f85..4653fa0b2 100644 --- a/src/core/cpu_core.cpp +++ b/src/core/cpu_core.cpp @@ -642,6 +642,14 @@ void Core::ExecuteInstruction() } #endif +#if 0 + if (m_current_instruction_pc == 0x8002bf50) + { + TRACE_EXECUTION = true; + __debugbreak(); + } +#endif + #ifdef _DEBUG if (TRACE_EXECUTION) PrintInstruction(inst.bits, m_current_instruction_pc, this); @@ -1219,7 +1227,7 @@ void Core::ExecuteInstruction() if (!ReadMemoryWord(addr, &value)) return; - m_cop2.WriteDataRegister(ZeroExtend32(static_cast<u8>(inst.i.rt.GetValue())), value); + m_cop2.WriteRegister(ZeroExtend32(static_cast<u8>(inst.i.rt.GetValue())), value); } break; @@ -1233,7 +1241,7 @@ void Core::ExecuteInstruction() } const VirtualMemoryAddress addr = ReadReg(inst.i.rs) + inst.i.imm_sext32(); - const u32 value = m_cop2.ReadDataRegister(ZeroExtend32(static_cast<u8>(inst.i.rt.GetValue()))); + const u32 value = m_cop2.ReadRegister(ZeroExtend32(static_cast<u8>(inst.i.rt.GetValue()))); WriteMemoryWord(addr, value); } break; @@ -1317,19 +1325,19 @@ void Core::ExecuteCop2Instruction() switch (inst.cop.CommonOp()) { case CopCommonInstruction::cfcn: - WriteRegDelayed(inst.r.rt, m_cop2.ReadControlRegister(static_cast<u32>(inst.r.rd.GetValue()))); + WriteRegDelayed(inst.r.rt, m_cop2.ReadRegister(static_cast<u32>(inst.r.rd.GetValue()) + 32)); break; case CopCommonInstruction::ctcn: - m_cop2.WriteControlRegister(static_cast<u32>(inst.r.rd.GetValue()), ReadReg(inst.r.rt)); + m_cop2.WriteRegister(static_cast<u32>(inst.r.rd.GetValue()) + 32, ReadReg(inst.r.rt)); break; case CopCommonInstruction::mfcn: - WriteRegDelayed(inst.r.rt, m_cop2.ReadDataRegister(static_cast<u32>(inst.r.rd.GetValue()))); + WriteRegDelayed(inst.r.rt, m_cop2.ReadRegister(static_cast<u32>(inst.r.rd.GetValue()))); break; case CopCommonInstruction::mtcn: - m_cop2.WriteDataRegister(static_cast<u32>(inst.r.rd.GetValue()), ReadReg(inst.r.rt)); + m_cop2.WriteRegister(static_cast<u32>(inst.r.rd.GetValue()), ReadReg(inst.r.rt)); break; case CopCommonInstruction::bcnc: diff --git a/src/core/gte.cpp b/src/core/gte.cpp index 76462fb6e..7f0800f2c 100644 --- a/src/core/gte.cpp +++ b/src/core/gte.cpp @@ -55,19 +55,20 @@ void Core::Reset() bool Core::DoState(StateWrapper& sw) { - sw.DoArray(m_regs.dr32, NUM_DATA_REGS); - sw.DoArray(m_regs.cr32, NUM_CONTROL_REGS); + sw.DoArray(m_regs.r32, NUM_DATA_REGS + NUM_CONTROL_REGS); return !sw.HasError(); } -u32 Core::ReadDataRegister(u32 index) const +u32 Core::ReadRegister(u32 index) const { + DebugAssert(index < countof(m_regs.r32)); + switch (index) { case 15: // SXY3 { // mirror of SXY2 - return m_regs.dr32[14]; + return m_regs.r32[14]; } case 28: // IRGB @@ -80,46 +81,23 @@ u32 Core::ReadDataRegister(u32 index) const return ZeroExtend32(r) | (ZeroExtend32(g) << 5) | (ZeroExtend32(b) << 10); } - case 0: // V0-1 [x,y] - case 1: // V0[z] - case 2: // V1-2 [x,y] - case 3: // V1[z] - case 4: // V2-3 [x,y] - case 5: // V2[z] - case 6: // RGBC - case 7: // OTZ - case 8: // IR0 - case 9: // IR1 - case 10: // IR2 - case 11: // IR3 - case 12: // SXY0 - case 13: // SXY1 - case 14: // SXY2 - case 16: // SZ0 - case 17: // SZ1 - case 18: // SZ2 - case 19: // SZ3 - case 20: // RGB0 - case 21: // RGB1 - case 22: // RGB2 - case 23: // RES1 - case 24: // MAC0 - case 25: // MAC1 - case 26: // MAC2 - case 27: // MAC3 - case 30: // LZCS - case 31: // LZCR - return m_regs.dr32[index]; - default: - Panic("Unknown register"); - return 0; + return m_regs.r32[index]; } } -void Core::WriteDataRegister(u32 index, u32 value) +void Core::WriteRegister(u32 index, u32 value) { - // Log_DebugPrintf("DataReg(%u) <- 0x%08X", index, value); +#if 0 + if (index < 32) + { + Log_DebugPrintf("DataReg(%u) <- 0x%08X", index, value); + } + else + { + Log_DebugPrintf("ControlReg(%u) <- 0x%08X", index, value); + } +#endif switch (index) { @@ -130,9 +108,16 @@ void Core::WriteDataRegister(u32 index, u32 value) case 9: // IR1 case 10: // IR2 case 11: // IR3 + case 36: // RT33 + case 44: // L33 + case 52: // LR33 + case 58: // H - sign-extended on read but zext on use + case 59: // DQA + case 61: // ZSF3 + case 62: // ZSF4 { // sign-extend z component of vector registers - m_regs.dr32[index] = SignExtend32(Truncate16(value)); + m_regs.r32[index] = SignExtend32(Truncate16(value)); } break; @@ -143,16 +128,16 @@ void Core::WriteDataRegister(u32 index, u32 value) case 19: // SZ3 { // zero-extend unsigned values - m_regs.dr32[index] = ZeroExtend32(Truncate16(value)); + m_regs.r32[index] = ZeroExtend32(Truncate16(value)); } break; case 15: // SXY3 { // writing to SXYP pushes to the FIFO - m_regs.dr32[12] = m_regs.dr32[13]; // SXY0 <- SXY1 - m_regs.dr32[13] = m_regs.dr32[14]; // SXY1 <- SXY2 - m_regs.dr32[14] = value; // SXY2 <- SXYP + m_regs.r32[12] = m_regs.r32[13]; // SXY0 <- SXY1 + m_regs.r32[13] = m_regs.r32[14]; // SXY1 <- SXY2 + m_regs.r32[14] = value; // SXY2 <- SXYP } break; @@ -160,9 +145,9 @@ void Core::WriteDataRegister(u32 index, u32 value) { // IRGB register, convert 555 to 16-bit m_regs.IRGB = value & UINT32_C(0x7FFF); - m_regs.dr32[9] = SignExtend32(static_cast<u16>(Truncate16((value & UINT32_C(0x1F)) * UINT32_C(0x80)))); - m_regs.dr32[10] = SignExtend32(static_cast<u16>(Truncate16(((value >> 5) & UINT32_C(0x1F)) * UINT32_C(0x80)))); - m_regs.dr32[11] = SignExtend32(static_cast<u16>(Truncate16(((value >> 10) & UINT32_C(0x1F)) * UINT32_C(0x80)))); + m_regs.r32[9] = SignExtend32(static_cast<u16>(Truncate16((value & UINT32_C(0x1F)) * UINT32_C(0x80)))); + m_regs.r32[10] = SignExtend32(static_cast<u16>(Truncate16(((value >> 5) & UINT32_C(0x1F)) * UINT32_C(0x80)))); + m_regs.r32[11] = SignExtend32(static_cast<u16>(Truncate16(((value >> 10) & UINT32_C(0x1F)) * UINT32_C(0x80)))); } break; @@ -180,94 +165,19 @@ void Core::WriteDataRegister(u32 index, u32 value) } break; - case 0: // V0-1 [x,y] - case 2: // V1-2 [x,y] - case 4: // V2-3 [x,y] - case 6: // RGBC - case 12: // SXY0 - case 13: // SXY1 - case 14: // SXY2 - case 20: // RGB0 - case 21: // RGB1 - case 22: // RGB2 - case 23: // RES1 - case 24: // MAC0 - case 25: // MAC1 - case 26: // MAC2 - case 27: // MAC3 - m_regs.dr32[index] = value; - break; - - default: - Panic("Unknown register"); - break; - } -} - -u32 Core::ReadControlRegister(u32 index) const -{ - return m_regs.cr32[index]; -} - -void Core::WriteControlRegister(u32 index, u32 value) -{ - // Log_DebugPrintf("ControlReg(%u,%u) <- 0x%08X", index, index + 32, value); - - switch (index) - { - case 36 - 32: // RT33 - case 44 - 32: // L33 - case 52 - 32: // LR33 - case 58 - 32: // H - sign-extended on read but zext on use - case 59 - 32: // DQA - case 61 - 32: // ZSF3 - case 62 - 32: // ZSF4 - { - // MSB of the last matrix element is the last element sign-extended - m_regs.cr32[index] = SignExtend32(Truncate16(value)); - } - break; - - case 63 - 32: // FLAG + case 63: // FLAG { m_regs.FLAG.bits = value & UINT32_C(0x7FFFF000); m_regs.FLAG.UpdateError(); } break; - case 32 - 32: // RT11,RT12 - case 33 - 32: // RT13,RT21 - case 34 - 32: // RT22,RT23 - case 35 - 32: // RT31,RT32 - case 37 - 32: // TRX - case 38 - 32: // TRY - case 39 - 32: // TRZ - case 40 - 32: // L11,L12 - case 41 - 32: // L13,L21 - case 42 - 32: // L22,L23 - case 43 - 32: // L31,L32 - case 45 - 32: // RBK - case 46 - 32: // GBK - case 47 - 32: // BBK - case 48 - 32: // LR11,LR12 - case 49 - 32: // LR13,LR21 - case 50 - 32: // LR22,LR23 - case 51 - 32: // LR31,LR32 - case 53 - 32: // RFC - case 54 - 32: // GFC - case 55 - 32: // BFC - case 56 - 32: // OFX - case 57 - 32: // OFY - case 60 - 32: // DQB + default: { // written as-is, 2x16 or 1x32 bits - m_regs.cr32[index] = value; + m_regs.r32[index] = value; } break; - - default: - Panic("Unknown register"); - break; } } diff --git a/src/core/gte.h b/src/core/gte.h index b6d3d9165..319760f60 100644 --- a/src/core/gte.h +++ b/src/core/gte.h @@ -14,14 +14,9 @@ public: void Reset(); bool DoState(StateWrapper& sw); - u32 ReadRegister(u32 index) const { return m_regs.dr32[index]; } - void WriteRegister(u32 index, u32 value) { m_regs.dr32[index] = value; } - - u32 ReadDataRegister(u32 index) const; - void WriteDataRegister(u32 index, u32 value); - - u32 ReadControlRegister(u32 index) const; - void WriteControlRegister(u32 index, u32 value); + // control registers are offset by +32 + u32 ReadRegister(u32 index) const; + void WriteRegister(u32 index, u32 value); void ExecuteInstruction(Instruction inst); diff --git a/src/core/gte_types.h b/src/core/gte_types.h index 16824e92c..7c55138d4 100644 --- a/src/core/gte_types.h +++ b/src/core/gte_types.h @@ -48,6 +48,8 @@ union Regs u32 cr32[NUM_CONTROL_REGS]; }; + u32 r32[NUM_DATA_REGS + NUM_CONTROL_REGS]; + #pragma pack(push, 1) struct {