RSP: Move CompilePC into RspRecompilerCPU

This commit is contained in:
zilmar 2024-09-19 08:31:28 +09:30
parent df9b04bb5b
commit 3340c032c3
6 changed files with 344 additions and 340 deletions

View File

@ -22,7 +22,7 @@
#define X86_RECOMP_VERBOSE
#define BUILD_BRANCHLABELS_VERBOSE
uint32_t CompilePC, JumpTableSize, BlockID = 0;
uint32_t JumpTableSize, BlockID = 0;
uint32_t dwBuffer = MainBuffer;
bool ChangedPC;
@ -43,6 +43,7 @@ p_Recompfunc RSP_Recomp_Sc2[32];
CRSPRecompiler::CRSPRecompiler(CRSPSystem & System) :
m_System(System),
m_RSPRegisterHandler(System.m_RSPRegisterHandler),
m_CompilePC(0),
m_OpCode(System.m_OpCode),
m_NextInstruction(RSPPIPELINE_NORMAL),
m_IMEM(System.m_IMEM)
@ -797,7 +798,7 @@ bool IsJumpLabel(uint32_t PC)
void CRSPRecompiler::CompilerLinkBlocks(void)
{
uint8_t * KnownCode = (uint8_t *)*(JumpTable + (CompilePC >> 2));
uint8_t * KnownCode = (uint8_t *)*(JumpTable + (m_CompilePC >> 2));
CPU_Message("***** Linking block to X86: %08X *****", KnownCode);
m_NextInstruction = RSPPIPELINE_FINISH_BLOCK;
@ -814,11 +815,11 @@ void CRSPRecompiler::CompilerRSPBlock(void)
uint8_t * IMEM_SAVE = (uint8_t *)malloc(0x1000);
const size_t X86BaseAddress = (size_t)RecompPos;
m_NextInstruction = RSPPIPELINE_NORMAL;
CompilePC = *m_System.m_SP_PC_REG;
m_CompilePC = *m_System.m_SP_PC_REG;
memset(&m_CurrentBlock, 0, sizeof(m_CurrentBlock));
m_CurrentBlock.StartPC = CompilePC;
m_CurrentBlock.CurrPC = CompilePC;
m_CurrentBlock.StartPC = m_CompilePC;
m_CurrentBlock.CurrPC = m_CompilePC;
// Align the block to a boundary
if (X86BaseAddress & 7)
@ -846,7 +847,7 @@ void CRSPRecompiler::CompilerRSPBlock(void)
}
// This is for the block about to be compiled
*(JumpTable + (CompilePC >> 2)) = RecompPos;
*(JumpTable + (m_CompilePC >> 2)) = RecompPos;
uint32_t EndPC = 0x1000;
do
@ -854,17 +855,17 @@ void CRSPRecompiler::CompilerRSPBlock(void)
// Reordering is setup to allow us to have loop labels
// so here we see if this is one and put it in the jump table
if (m_NextInstruction == RSPPIPELINE_NORMAL && IsJumpLabel(CompilePC))
if (m_NextInstruction == RSPPIPELINE_NORMAL && IsJumpLabel(m_CompilePC))
{
// Jumps come around twice
if (NULL == *(JumpTable + (CompilePC >> 2)))
if (NULL == *(JumpTable + (m_CompilePC >> 2)))
{
CPU_Message("***** Adding jump table entry for PC: %04X at X86: %08X *****", CompilePC, RecompPos);
CPU_Message("***** Adding jump table entry for PC: %04X at X86: %08X *****", m_CompilePC, RecompPos);
CPU_Message("");
*(JumpTable + (CompilePC >> 2)) = RecompPos;
*(JumpTable + (m_CompilePC >> 2)) = RecompPos;
// Reorder from here to next label or branch
m_CurrentBlock.CurrPC = CompilePC;
m_CurrentBlock.CurrPC = m_CompilePC;
ReOrderSubBlock(&m_CurrentBlock);
}
else if (m_NextInstruction != RSPPIPELINE_DELAY_SLOT_DONE)
@ -883,12 +884,12 @@ void CRSPRecompiler::CompilerRSPBlock(void)
}
#ifdef X86_RECOMP_VERBOSE
if (!IsOpcodeNop(CompilePC))
if (!IsOpcodeNop(m_CompilePC))
{
CPU_Message("X86 Address: %08X", RecompPos);
}
#endif
RSP_LW_IMEM(CompilePC, &m_OpCode.Value);
RSP_LW_IMEM(m_CompilePC, &m_OpCode.Value);
if (m_OpCode.Value == 0xFFFFFFFF)
{
@ -903,34 +904,34 @@ void CRSPRecompiler::CompilerRSPBlock(void)
switch (m_NextInstruction)
{
case RSPPIPELINE_NORMAL:
CompilePC += 4;
m_CompilePC += 4;
break;
case RSPPIPELINE_DO_DELAY_SLOT:
m_NextInstruction = RSPPIPELINE_DELAY_SLOT;
CompilePC += 4;
m_CompilePC += 4;
break;
case RSPPIPELINE_DELAY_SLOT:
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_DONE;
CompilePC = (CompilePC - 4 & 0xFFC);
m_CompilePC = (m_CompilePC - 4 & 0xFFC);
break;
case RSPPIPELINE_DELAY_SLOT_EXIT:
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT_DONE;
CompilePC = (CompilePC - 4 & 0xFFC);
m_CompilePC = (m_CompilePC - 4 & 0xFFC);
break;
case RSPPIPELINE_FINISH_SUB_BLOCK:
m_NextInstruction = RSPPIPELINE_NORMAL;
CompilePC += 8;
if (CompilePC >= 0x1000)
m_CompilePC += 8;
if (m_CompilePC >= 0x1000)
{
m_NextInstruction = RSPPIPELINE_FINISH_BLOCK;
}
else if (NULL == *(JumpTable + (CompilePC >> 2)))
else if (NULL == *(JumpTable + (m_CompilePC >> 2)))
{
// This is for the new block being compiled now
CPU_Message("***** Continuing static SubBlock (jump table entry added for PC: %04X at X86: %08X) *****", CompilePC, RecompPos);
*(JumpTable + (CompilePC >> 2)) = RecompPos;
CPU_Message("***** Continuing static SubBlock (jump table entry added for PC: %04X at X86: %08X) *****", m_CompilePC, RecompPos);
*(JumpTable + (m_CompilePC >> 2)) = RecompPos;
m_CurrentBlock.CurrPC = CompilePC;
m_CurrentBlock.CurrPC = m_CompilePC;
// Reorder from after delay to next label or branch
ReOrderSubBlock(&m_CurrentBlock);
}
@ -943,19 +944,19 @@ void CRSPRecompiler::CompilerRSPBlock(void)
case RSPPIPELINE_FINISH_BLOCK: break;
default:
g_Notify->DisplayError(stdstr_f("RSP main loop\n\nWTF m_NextInstruction = %d", m_NextInstruction).c_str());
CompilePC += 4;
m_CompilePC += 4;
break;
}
if (CompilePC >= EndPC && *m_System.m_SP_PC_REG != 0 && EndPC != *m_System.m_SP_PC_REG)
if (m_CompilePC >= EndPC && *m_System.m_SP_PC_REG != 0 && EndPC != *m_System.m_SP_PC_REG)
{
CompilePC = 0;
m_CompilePC = 0;
EndPC = *m_System.m_SP_PC_REG;
}
} while (m_NextInstruction != RSPPIPELINE_FINISH_BLOCK && (CompilePC < EndPC || m_NextInstruction == RSPPIPELINE_DELAY_SLOT || m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE));
if (CompilePC >= EndPC)
} while (m_NextInstruction != RSPPIPELINE_FINISH_BLOCK && (m_CompilePC < EndPC || m_NextInstruction == RSPPIPELINE_DELAY_SLOT || m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE));
if (m_CompilePC >= EndPC)
{
MoveConstToVariable((CompilePC & 0xFFC), m_System.m_SP_PC_REG, "RSP PC");
MoveConstToVariable((m_CompilePC & 0xFFC), m_System.m_SP_PC_REG, "RSP PC");
Ret();
}
CPU_Message("===== End of recompiled code =====");
@ -1000,7 +1001,7 @@ void CRSPRecompiler::RunCPU(void)
__except (EXCEPTION_EXECUTE_HANDLER)
{
char ErrorMessage[400];
sprintf(ErrorMessage, "Error CompilePC = %08X", CompilePC);
sprintf(ErrorMessage, "Error m_CompilePC = %08X", m_CompilePC);
g_Notify->DisplayError(ErrorMessage);
ClearAllx86Code();
continue;

View File

@ -49,12 +49,13 @@ private:
CRSPSystem & m_System;
RSPRegisterHandlerPlugin *& m_RSPRegisterHandler;
RSPOpcode & m_OpCode;
uint32_t m_CompilePC;
RSP_BLOCK m_CurrentBlock;
RSPPIPELINE_STAGE m_NextInstruction;
uint8_t *& m_IMEM;
};
extern uint32_t CompilePC, JumpTableSize;
extern uint32_t JumpTableSize;
extern bool ChangedPC;
#define CompilerWarning \

File diff suppressed because it is too large Load Diff

View File

@ -219,6 +219,7 @@ private:
CRSPRecompiler & m_Recompiler;
RSPPIPELINE_STAGE & m_NextInstruction;
RSPOpcode & m_OpCode;
uint32_t & m_CompilePC;
UWORD32 * m_GPR;
UDWORD * m_ACCUM;
UWORD32 * m_Flags;

View File

@ -553,7 +553,7 @@ bool CRSPRecompilerOps::Check_Section_000(void)
uint32_t i;
RSPOpcode op0, op1;
RSP_LW_IMEM(CompilePC + 0x00, &op0.Value);
RSP_LW_IMEM(m_CompilePC + 0x00, &op0.Value);
// Example: (Mario audio microcode)
// 0x574 VMUDN $v30, $v3, $v23
@ -567,7 +567,7 @@ bool CRSPRecompilerOps::Check_Section_000(void)
for (i = 0; i < 0x20; i++)
{
RSP_LW_IMEM(CompilePC + 0x04 + (i * 4), &op1.Value);
RSP_LW_IMEM(m_CompilePC + 0x04 + (i * 4), &op1.Value);
if (!(op1.op == RSP_CP2 && (op1.rs & 0x10) != 0 && op1.funct == RSP_VECTOR_VMADN))
{
@ -591,7 +591,7 @@ bool CRSPRecompilerOps::Check_Section_000(void)
}
// TODO: check destination and flushes
if (true == WriteToAccum(7, CompilePC + 0x4 + (Section_000_VMADN * 4) - 0x4))
if (true == WriteToAccum(7, m_CompilePC + 0x4 + (Section_000_VMADN * 4) - 0x4))
{
return false;
}
@ -608,26 +608,26 @@ void CRSPRecompilerOps::Compile_Section_000(void)
RSPOpcode vmudn, vmadn = {0};
uint32_t i;
RSP_LW_IMEM(CompilePC + 0x00, &vmudn.Value);
RSP_LW_IMEM(m_CompilePC + 0x00, &vmudn.Value);
CPU_Message("Compiling: %X to ..., RSP optimization $000", CompilePC);
CPU_Message(" %X %s", CompilePC + 0x00, RSPInstruction(CompilePC + 0x00, vmudn.Value).NameAndParam().c_str());
CPU_Message("Compiling: %X to ..., RSP optimization $000", m_CompilePC);
CPU_Message(" %X %s", m_CompilePC + 0x00, RSPInstruction(m_CompilePC + 0x00, vmudn.Value).NameAndParam().c_str());
for (i = 0; i < Section_000_VMADN; i++)
{
RSP_LW_IMEM(CompilePC + 0x04 + (i * 4), &vmadn.Value);
CPU_Message(" %X %s", CompilePC + 0x04 + (i * 4), RSPInstruction(CompilePC + 0x04 + (i * 4), vmadn.Value).NameAndParam().c_str());
RSP_LW_IMEM(m_CompilePC + 0x04 + (i * 4), &vmadn.Value);
CPU_Message(" %X %s", m_CompilePC + 0x04 + (i * 4), RSPInstruction(m_CompilePC + 0x04 + (i * 4), vmadn.Value).NameAndParam().c_str());
}
RSP_Sections_VMUDN(vmudn, Low16BitAccum);
CompilePC += 4;
m_CompilePC += 4;
for (i = 0; i < Section_000_VMADN; i++)
{
RSP_LW_IMEM(CompilePC, &vmadn.Value);
CompilePC += 4;
RSP_LW_IMEM(m_CompilePC, &vmadn.Value);
m_CompilePC += 4;
RSP_Sections_VMADN(vmadn, Low16BitAccum);
if (WriteToVectorDest(vmadn.sa, CompilePC - 4) == true)
if (WriteToVectorDest(vmadn.sa, m_CompilePC - 4) == true)
{
sprintf(Reg, "m_Vect[%i].HW[0]", vmadn.sa);
MmxMoveQwordRegToVariable(x86_MM0, &m_Vect[vmadn.sa].s16(0), Reg);
@ -651,7 +651,7 @@ bool CRSPRecompilerOps::Check_Section_001(void)
uint32_t i;
RSPOpcode op0, op1;
RSP_LW_IMEM(CompilePC + 0x00, &op0.Value);
RSP_LW_IMEM(m_CompilePC + 0x00, &op0.Value);
// Example: (Mario audio microcode)
// 0xCC0 VMULF $v28, $v28, $v10 [6]
@ -665,7 +665,7 @@ bool CRSPRecompilerOps::Check_Section_001(void)
for (i = 0; i < 0x20; i++)
{
RSP_LW_IMEM(CompilePC + 0x04 + (i * 4), &op1.Value);
RSP_LW_IMEM(m_CompilePC + 0x04 + (i * 4), &op1.Value);
if (!(op1.op == RSP_CP2 && (op1.rs & 0x10) != 0 && op1.funct == RSP_VECTOR_VMACF))
{
@ -694,7 +694,7 @@ bool CRSPRecompilerOps::Check_Section_001(void)
}
// Destinations are checked elsewhere, this is fine
if (true == WriteToAccum(7, CompilePC + 0x4 + (Section_001_VMACF * 4) - 0x4))
if (true == WriteToAccum(7, m_CompilePC + 0x4 + (Section_001_VMACF * 4) - 0x4))
{
return false;
}
@ -708,35 +708,35 @@ void CRSPRecompilerOps::Compile_Section_001(void)
char Reg[256];
RSPOpcode vmulf, vmacf;
RSP_LW_IMEM(CompilePC + 0x00, &vmulf.Value);
RSP_LW_IMEM(m_CompilePC + 0x00, &vmulf.Value);
CPU_Message("Compiling: %X to ..., RSP optimization $001", CompilePC);
CPU_Message(" %X %s", CompilePC + 0x00, RSPInstruction(CompilePC + 0x00, vmulf.Value).NameAndParam().c_str());
CPU_Message("Compiling: %X to ..., RSP optimization $001", m_CompilePC);
CPU_Message(" %X %s", m_CompilePC + 0x00, RSPInstruction(m_CompilePC + 0x00, vmulf.Value).NameAndParam().c_str());
for (i = 0; i < Section_001_VMACF; i++)
{
RSP_LW_IMEM(CompilePC + 0x04 + (i * 4), &vmacf.Value);
CPU_Message(" %X %s", CompilePC + 0x04 + (i * 4), RSPInstruction(CompilePC + 0x04 + (i * 4), vmacf.Value).NameAndParam().c_str());
RSP_LW_IMEM(m_CompilePC + 0x04 + (i * 4), &vmacf.Value);
CPU_Message(" %X %s", m_CompilePC + 0x04 + (i * 4), RSPInstruction(m_CompilePC + 0x04 + (i * 4), vmacf.Value).NameAndParam().c_str());
}
RSP_Sections_VMULF(vmulf, Middle16BitAccum);
if (WriteToVectorDest(vmulf.sa, CompilePC) == true)
if (WriteToVectorDest(vmulf.sa, m_CompilePC) == true)
{
sprintf(Reg, "m_Vect[%i].HW[0]", vmulf.sa);
MmxMoveQwordRegToVariable(x86_MM0, &m_Vect[vmulf.sa].s16(0), Reg);
sprintf(Reg, "m_Vect[%i].HW[4]", vmulf.sa);
MmxMoveQwordRegToVariable(x86_MM1, &m_Vect[vmulf.sa].s16(4), Reg);
}
CompilePC += 4;
m_CompilePC += 4;
for (i = 0; i < Section_001_VMACF; i++)
{
RSP_LW_IMEM(CompilePC, &vmacf.Value);
CompilePC += 4;
RSP_LW_IMEM(m_CompilePC, &vmacf.Value);
m_CompilePC += 4;
RSP_Sections_VMACF(vmacf, Middle16BitAccum);
if (WriteToVectorDest(vmacf.sa, CompilePC - 4) == true)
if (WriteToVectorDest(vmacf.sa, m_CompilePC - 4) == true)
{
sprintf(Reg, "m_Vect[%i].HW[0]", vmacf.sa);
MmxMoveQwordRegToVariable(x86_MM0, &m_Vect[vmacf.sa].s16(0), Reg);
@ -755,7 +755,7 @@ bool CRSPRecompilerOps::Check_Section_002(void)
for (Count = 0; Count < 0x0C; Count++)
{
RSP_LW_IMEM(CompilePC + (Count * 0x04), &op[Count].Value);
RSP_LW_IMEM(m_CompilePC + (Count * 0x04), &op[Count].Value);
}
/*
@ -812,7 +812,7 @@ bool CRSPRecompilerOps::Check_Section_002(void)
return false;
}
if (true == WriteToAccum(7, CompilePC + 0x2C))
if (true == WriteToAccum(7, m_CompilePC + 0x2C))
return false;
return true;
@ -827,11 +827,11 @@ void CRSPRecompilerOps::Compile_Section_002(void)
RSPOpcode vmudh, vsaw;
CPU_Message("Compiling: %X to ..., RSP optimization $002", CompilePC);
CPU_Message("Compiling: %X to ..., RSP optimization $002", m_CompilePC);
for (Count = 0; Count < 0xC; Count++)
{
RSP_LW_IMEM(CompilePC + (Count * 0x04), &op[Count].Value);
CPU_Message(" %X %s", CompilePC + (Count * 0x04), RSPInstruction(CompilePC + (Count * 0x04), op[Count].Value).NameAndParam().c_str());
RSP_LW_IMEM(m_CompilePC + (Count * 0x04), &op[Count].Value);
CPU_Message(" %X %s", m_CompilePC + (Count * 0x04), RSPInstruction(m_CompilePC + (Count * 0x04), op[Count].Value).NameAndParam().c_str());
}
vmudh = op[0];
@ -859,7 +859,7 @@ void CRSPRecompilerOps::Compile_Section_002(void)
MmxEmptyMultimediaState();
CompilePC += 12 * sizeof(RSPOpcode);
m_CompilePC += 12 * sizeof(RSPOpcode);
}
bool CRSPRecompilerOps::Check_Section_003(void)
@ -869,7 +869,7 @@ bool CRSPRecompilerOps::Check_Section_003(void)
for (Count = 0; Count < 4; Count++)
{
RSP_LW_IMEM(CompilePC + (Count * 0x04), &op[Count].Value);
RSP_LW_IMEM(m_CompilePC + (Count * 0x04), &op[Count].Value);
}
// Example: (Zelda audio microcode)
@ -880,7 +880,7 @@ bool CRSPRecompilerOps::Check_Section_003(void)
if (op[0].Value == 0x4BF7FDC5 && op[1].Value == 0x4BF6FDCF && op[2].Value == 0x4B92CD8D && op[3].Value == 0x4B1EFDCE)
{
if (true == WriteToAccum(7, CompilePC + 0xc))
if (true == WriteToAccum(7, m_CompilePC + 0xc))
return false;
return true;
@ -937,10 +937,10 @@ void CRSPRecompilerOps::resampler_hle()
void CRSPRecompilerOps::Compile_Section_003(void)
{
CPU_Message("Compiling: %X to ..., RSP optimization $003", CompilePC);
CPU_Message("Compiling: %X to ..., RSP optimization $003", m_CompilePC);
MoveConstToX86reg((uint32_t)this, x86_ECX);
Call_Direct(AddressOf(&CRSPRecompilerOps::resampler_hle), "Resampler_HLE");
CompilePC += 4 * sizeof(RSPOpcode);
m_CompilePC += 4 * sizeof(RSPOpcode);
}
bool CRSPRecompilerOps::RSP_DoSections(void)

View File

@ -3333,6 +3333,28 @@ void XorX86RegToVariable(void * Variable, const char * VariableName, int x86reg)
PUTDSTPTR(RecompPos, Variable);
}
void x86_SetBranch8b(void * JumpByte, void * Destination)
{
// Calculate 32-bit relative offset
size_t n = (uint8_t *)Destination - ((uint8_t *)JumpByte + 1);
intptr_t signed_n = (intptr_t)n;
// Check limits, no pun intended
if (signed_n > +128 || signed_n < -127)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
else
{
*(uint8_t *)(JumpByte) = (uint8_t)(n & 0xFF);
}
}
void x86_SetBranch32b(void * JumpByte, void * Destination)
{
*(uint32_t *)(JumpByte) = (uint32_t)((uint8_t *)Destination - (uint8_t *)((uint32_t *)JumpByte + 1));
}
void * GetAddressOf_(int value, ...)
{
void * Address;