CPU: Simplify GTE register addressing

This commit is contained in:
Connor McLaughlin 2019-12-11 21:44:26 +10:00
parent 4e7d420a06
commit a6dab97928
4 changed files with 54 additions and 139 deletions

View File

@ -642,6 +642,14 @@ void Core::ExecuteInstruction()
} }
#endif #endif
#if 0
if (m_current_instruction_pc == 0x8002bf50)
{
TRACE_EXECUTION = true;
__debugbreak();
}
#endif
#ifdef _DEBUG #ifdef _DEBUG
if (TRACE_EXECUTION) if (TRACE_EXECUTION)
PrintInstruction(inst.bits, m_current_instruction_pc, this); PrintInstruction(inst.bits, m_current_instruction_pc, this);
@ -1219,7 +1227,7 @@ void Core::ExecuteInstruction()
if (!ReadMemoryWord(addr, &value)) if (!ReadMemoryWord(addr, &value))
return; 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; break;
@ -1233,7 +1241,7 @@ void Core::ExecuteInstruction()
} }
const VirtualMemoryAddress addr = ReadReg(inst.i.rs) + inst.i.imm_sext32(); 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); WriteMemoryWord(addr, value);
} }
break; break;
@ -1317,19 +1325,19 @@ void Core::ExecuteCop2Instruction()
switch (inst.cop.CommonOp()) switch (inst.cop.CommonOp())
{ {
case CopCommonInstruction::cfcn: 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; break;
case CopCommonInstruction::ctcn: 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; break;
case CopCommonInstruction::mfcn: 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; break;
case CopCommonInstruction::mtcn: 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; break;
case CopCommonInstruction::bcnc: case CopCommonInstruction::bcnc:

View File

@ -55,19 +55,20 @@ void Core::Reset()
bool Core::DoState(StateWrapper& sw) bool Core::DoState(StateWrapper& sw)
{ {
sw.DoArray(m_regs.dr32, NUM_DATA_REGS); sw.DoArray(m_regs.r32, NUM_DATA_REGS + NUM_CONTROL_REGS);
sw.DoArray(m_regs.cr32, NUM_CONTROL_REGS);
return !sw.HasError(); return !sw.HasError();
} }
u32 Core::ReadDataRegister(u32 index) const u32 Core::ReadRegister(u32 index) const
{ {
DebugAssert(index < countof(m_regs.r32));
switch (index) switch (index)
{ {
case 15: // SXY3 case 15: // SXY3
{ {
// mirror of SXY2 // mirror of SXY2
return m_regs.dr32[14]; return m_regs.r32[14];
} }
case 28: // IRGB case 28: // IRGB
@ -80,46 +81,23 @@ u32 Core::ReadDataRegister(u32 index) const
return ZeroExtend32(r) | (ZeroExtend32(g) << 5) | (ZeroExtend32(b) << 10); 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: default:
Panic("Unknown register"); return m_regs.r32[index];
return 0;
} }
} }
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) switch (index)
{ {
@ -130,9 +108,16 @@ void Core::WriteDataRegister(u32 index, u32 value)
case 9: // IR1 case 9: // IR1
case 10: // IR2 case 10: // IR2
case 11: // IR3 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 // sign-extend z component of vector registers
m_regs.dr32[index] = SignExtend32(Truncate16(value)); m_regs.r32[index] = SignExtend32(Truncate16(value));
} }
break; break;
@ -143,16 +128,16 @@ void Core::WriteDataRegister(u32 index, u32 value)
case 19: // SZ3 case 19: // SZ3
{ {
// zero-extend unsigned values // zero-extend unsigned values
m_regs.dr32[index] = ZeroExtend32(Truncate16(value)); m_regs.r32[index] = ZeroExtend32(Truncate16(value));
} }
break; break;
case 15: // SXY3 case 15: // SXY3
{ {
// writing to SXYP pushes to the FIFO // writing to SXYP pushes to the FIFO
m_regs.dr32[12] = m_regs.dr32[13]; // SXY0 <- SXY1 m_regs.r32[12] = m_regs.r32[13]; // SXY0 <- SXY1
m_regs.dr32[13] = m_regs.dr32[14]; // SXY1 <- SXY2 m_regs.r32[13] = m_regs.r32[14]; // SXY1 <- SXY2
m_regs.dr32[14] = value; // SXY2 <- SXYP m_regs.r32[14] = value; // SXY2 <- SXYP
} }
break; break;
@ -160,9 +145,9 @@ void Core::WriteDataRegister(u32 index, u32 value)
{ {
// IRGB register, convert 555 to 16-bit // IRGB register, convert 555 to 16-bit
m_regs.IRGB = value & UINT32_C(0x7FFF); 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.r32[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.r32[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[11] = SignExtend32(static_cast<u16>(Truncate16(((value >> 10) & UINT32_C(0x1F)) * UINT32_C(0x80))));
} }
break; break;
@ -180,94 +165,19 @@ void Core::WriteDataRegister(u32 index, u32 value)
} }
break; break;
case 0: // V0-1 [x,y] case 63: // FLAG
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
{ {
m_regs.FLAG.bits = value & UINT32_C(0x7FFFF000); m_regs.FLAG.bits = value & UINT32_C(0x7FFFF000);
m_regs.FLAG.UpdateError(); m_regs.FLAG.UpdateError();
} }
break; break;
case 32 - 32: // RT11,RT12 default:
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
{ {
// written as-is, 2x16 or 1x32 bits // written as-is, 2x16 or 1x32 bits
m_regs.cr32[index] = value; m_regs.r32[index] = value;
} }
break; break;
default:
Panic("Unknown register");
break;
} }
} }

View File

@ -14,14 +14,9 @@ public:
void Reset(); void Reset();
bool DoState(StateWrapper& sw); bool DoState(StateWrapper& sw);
u32 ReadRegister(u32 index) const { return m_regs.dr32[index]; } // control registers are offset by +32
void WriteRegister(u32 index, u32 value) { m_regs.dr32[index] = value; } u32 ReadRegister(u32 index) const;
void WriteRegister(u32 index, u32 value);
u32 ReadDataRegister(u32 index) const;
void WriteDataRegister(u32 index, u32 value);
u32 ReadControlRegister(u32 index) const;
void WriteControlRegister(u32 index, u32 value);
void ExecuteInstruction(Instruction inst); void ExecuteInstruction(Instruction inst);

View File

@ -48,6 +48,8 @@ union Regs
u32 cr32[NUM_CONTROL_REGS]; u32 cr32[NUM_CONTROL_REGS];
}; };
u32 r32[NUM_DATA_REGS + NUM_CONTROL_REGS];
#pragma pack(push, 1) #pragma pack(push, 1)
struct struct
{ {