make VU jumps relative: pass instruction relative location CMIPSInstructionFactory

This commit is contained in:
Mahmood - Zer0xFF 2022-10-18 20:01:20 +01:00 committed by Jean-Philip Desjardins
parent 6f0ab037d9
commit 2f4f10e91c
16 changed files with 53 additions and 42 deletions

View file

@ -206,7 +206,7 @@ void CBasicBlock::CompileRange(CMipsJitter* jitter)
m_context.m_pArch->CompileInstruction( m_context.m_pArch->CompileInstruction(
address, address,
jitter, jitter,
&m_context); &m_context, address - m_begin);
//Sanity check //Sanity check
assert(jitter->IsStackEmpty()); assert(jitter->IsStackEmpty());
} }
@ -275,7 +275,9 @@ void CBasicBlock::CompileEpilog(CMipsJitter* jitter)
} }
jitter->Else(); jitter->Else();
{ {
jitter->PushCst(m_end + 4); jitter->PushRel(offsetof(CMIPS, m_State.nPC));
jitter->PushCst(m_end - m_begin + 4);
jitter->Add();
jitter->PullRel(offsetof(CMIPS, m_State.nPC)); jitter->PullRel(offsetof(CMIPS, m_State.nPC));
#if !defined(AOT_BUILD_CACHE) && !defined(__EMSCRIPTEN__) #if !defined(AOT_BUILD_CACHE) && !defined(__EMSCRIPTEN__)

View file

@ -24,9 +24,9 @@ CCOP_FPU::CCOP_FPU(MIPS_REGSIZE regSize)
SetupReflectionTables(); SetupReflectionTables();
} }
void CCOP_FPU::CompileInstruction(uint32 address, CMipsJitter* codeGen, CMIPS* ctx) void CCOP_FPU::CompileInstruction(uint32 address, CMipsJitter* codeGen, CMIPS* ctx, uint32 instrPosition)
{ {
SetupQuickVariables(address, codeGen, ctx); SetupQuickVariables(address, codeGen, ctx, instrPosition);
m_ft = static_cast<uint8>((m_nOpcode >> 16) & 0x1F); m_ft = static_cast<uint8>((m_nOpcode >> 16) & 0x1F);
m_fs = static_cast<uint8>((m_nOpcode >> 11) & 0x1F); m_fs = static_cast<uint8>((m_nOpcode >> 11) & 0x1F);

View file

@ -7,7 +7,7 @@ class CCOP_FPU : public CMIPSCoprocessor
{ {
public: public:
CCOP_FPU(MIPS_REGSIZE); CCOP_FPU(MIPS_REGSIZE);
void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override; void CompileInstruction(uint32, CMipsJitter*, CMIPS*, uint32) override;
void GetInstruction(uint32, char*) override; void GetInstruction(uint32, char*) override;
void GetArguments(uint32, uint32, char*) override; void GetArguments(uint32, uint32, char*) override;
uint32 GetEffectiveAddress(uint32, uint32) override; uint32 GetEffectiveAddress(uint32, uint32) override;

View file

@ -52,9 +52,9 @@ CCOP_SCU::CCOP_SCU(MIPS_REGSIZE nRegSize)
SetupReflectionTables(); SetupReflectionTables();
} }
void CCOP_SCU::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx) void CCOP_SCU::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx, uint32 instrPosition)
{ {
SetupQuickVariables(nAddress, codeGen, pCtx); SetupQuickVariables(nAddress, codeGen, pCtx, instrPosition);
m_nRT = (uint8)((m_nOpcode >> 16) & 0x1F); m_nRT = (uint8)((m_nOpcode >> 16) & 0x1F);
m_nRD = (uint8)((m_nOpcode >> 11) & 0x1F); m_nRD = (uint8)((m_nOpcode >> 11) & 0x1F);

View file

@ -62,7 +62,7 @@ public:
static_assert(sizeof(PCCR) == 4, "PCCR must be 4 bytes long."); static_assert(sizeof(PCCR) == 4, "PCCR must be 4 bytes long.");
CCOP_SCU(MIPS_REGSIZE); CCOP_SCU(MIPS_REGSIZE);
virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override; virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*, uint32) override;
virtual void GetInstruction(uint32, char*) override; virtual void GetInstruction(uint32, char*) override;
virtual void GetArguments(uint32, uint32, char*) override; virtual void GetArguments(uint32, uint32, char*) override;
virtual uint32 GetEffectiveAddress(uint32, uint32) override; virtual uint32 GetEffectiveAddress(uint32, uint32) override;

View file

@ -225,9 +225,9 @@ void CMA_MIPSIV::SetupInstructionTables()
} }
} }
void CMA_MIPSIV::CompileInstruction(uint32 address, CMipsJitter* codeGen, CMIPS* ctx) void CMA_MIPSIV::CompileInstruction(uint32 address, CMipsJitter* codeGen, CMIPS* ctx, uint32 instrPosition)
{ {
SetupQuickVariables(address, codeGen, ctx); SetupQuickVariables(address, codeGen, ctx, instrPosition);
m_nRS = (uint8)((m_nOpcode >> 21) & 0x1F); m_nRS = (uint8)((m_nOpcode >> 21) & 0x1F);
m_nRT = (uint8)((m_nOpcode >> 16) & 0x1F); m_nRT = (uint8)((m_nOpcode >> 16) & 0x1F);
@ -435,7 +435,7 @@ void CMA_MIPSIV::COP0()
{ {
if(m_pCtx->m_pCOP[0] != NULL) if(m_pCtx->m_pCOP[0] != NULL)
{ {
m_pCtx->m_pCOP[0]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx); m_pCtx->m_pCOP[0]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, m_instrPosition);
} }
else else
{ {
@ -448,7 +448,7 @@ void CMA_MIPSIV::COP1()
{ {
if(m_pCtx->m_pCOP[1] != NULL) if(m_pCtx->m_pCOP[1] != NULL)
{ {
m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx); m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, m_instrPosition);
} }
else else
{ {
@ -461,7 +461,7 @@ void CMA_MIPSIV::COP2()
{ {
if(m_pCtx->m_pCOP[2] != NULL) if(m_pCtx->m_pCOP[2] != NULL)
{ {
m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx); m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, m_instrPosition);
} }
else else
{ {
@ -706,7 +706,7 @@ void CMA_MIPSIV::LWC1()
{ {
if(m_pCtx->m_pCOP[1] != NULL) if(m_pCtx->m_pCOP[1] != NULL)
{ {
m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx); m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, m_instrPosition);
} }
else else
{ {
@ -725,7 +725,7 @@ void CMA_MIPSIV::LDC2()
{ {
if(m_pCtx->m_pCOP[2] != NULL) if(m_pCtx->m_pCOP[2] != NULL)
{ {
m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx); m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, m_instrPosition);
} }
else else
{ {
@ -769,7 +769,7 @@ void CMA_MIPSIV::SWC1()
{ {
if(m_pCtx->m_pCOP[1] != NULL) if(m_pCtx->m_pCOP[1] != NULL)
{ {
m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx); m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, m_instrPosition);
} }
else else
{ {
@ -782,7 +782,7 @@ void CMA_MIPSIV::SDC2()
{ {
if(m_pCtx->m_pCOP[2] != NULL) if(m_pCtx->m_pCOP[2] != NULL)
{ {
m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx); m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, m_instrPosition);
} }
else else
{ {

View file

@ -9,7 +9,7 @@ class CMA_MIPSIV : public CMIPSArchitecture
public: public:
CMA_MIPSIV(MIPS_REGSIZE); CMA_MIPSIV(MIPS_REGSIZE);
virtual ~CMA_MIPSIV() = default; virtual ~CMA_MIPSIV() = default;
void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override; void CompileInstruction(uint32, CMipsJitter*, CMIPS*, uint32) override;
void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int) override; void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int) override;
void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int) override; void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int) override;
MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32) override; MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32) override;

View file

@ -11,11 +11,12 @@ CMIPSInstructionFactory::CMIPSInstructionFactory(MIPS_REGSIZE nRegSize)
{ {
} }
void CMIPSInstructionFactory::SetupQuickVariables(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx) void CMIPSInstructionFactory::SetupQuickVariables(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx, uint32 instrPosition)
{ {
m_pCtx = pCtx; m_pCtx = pCtx;
m_codeGen = codeGen; m_codeGen = codeGen;
m_nAddress = nAddress; m_nAddress = nAddress;
m_instrPosition = instrPosition;
m_nOpcode = m_pCtx->m_pMemoryMap->GetInstruction(m_nAddress); m_nOpcode = m_pCtx->m_pMemoryMap->GetInstruction(m_nAddress);
} }

View file

@ -23,7 +23,7 @@ class CMIPSInstructionFactory
public: public:
CMIPSInstructionFactory(MIPS_REGSIZE); CMIPSInstructionFactory(MIPS_REGSIZE);
virtual ~CMIPSInstructionFactory() = default; virtual ~CMIPSInstructionFactory() = default;
virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*) = 0; virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*, uint32) = 0;
void Illegal(); void Illegal();
protected: protected:
@ -36,11 +36,12 @@ protected:
void Branch(Jitter::CONDITION); void Branch(Jitter::CONDITION);
void BranchLikely(Jitter::CONDITION); void BranchLikely(Jitter::CONDITION);
void SetupQuickVariables(uint32, CMipsJitter*, CMIPS*); void SetupQuickVariables(uint32, CMipsJitter*, CMIPS*, uint32);
CMipsJitter* m_codeGen = nullptr; CMipsJitter* m_codeGen = nullptr;
CMIPS* m_pCtx = nullptr; CMIPS* m_pCtx = nullptr;
uint32 m_nOpcode = 0; uint32 m_nOpcode = 0;
uint32 m_nAddress = 0; uint32 m_nAddress = 0;
uint32 m_instrPosition = 0;
MIPS_REGSIZE m_regSize; MIPS_REGSIZE m_regSize;
}; };

View file

@ -30,9 +30,9 @@ CCOP_VU::CCOP_VU(MIPS_REGSIZE nRegSize)
SetupReflectionTables(); SetupReflectionTables();
} }
void CCOP_VU::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx) void CCOP_VU::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx, uint32 instrPosition)
{ {
SetupQuickVariables(nAddress, codeGen, pCtx); SetupQuickVariables(nAddress, codeGen, pCtx, instrPosition);
m_nDest = (uint8)((m_nOpcode >> 21) & 0x0F); m_nDest = (uint8)((m_nOpcode >> 21) & 0x0F);

View file

@ -9,7 +9,7 @@ class CCOP_VU : public CMIPSCoprocessor
public: public:
CCOP_VU(MIPS_REGSIZE); CCOP_VU(MIPS_REGSIZE);
void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override; void CompileInstruction(uint32, CMipsJitter*, CMIPS*, uint32) override;
void GetInstruction(uint32, char*) override; void GetInstruction(uint32, char*) override;
void GetArguments(uint32, uint32, char*) override; void GetArguments(uint32, uint32, char*) override;
uint32 GetEffectiveAddress(uint32, uint32) override; uint32 GetEffectiveAddress(uint32, uint32) override;

View file

@ -8,17 +8,17 @@ CMA_VU::CMA_VU(uint32 vuMemAddressMask)
SetupReflectionTables(); SetupReflectionTables();
} }
void CMA_VU::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx) void CMA_VU::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx, uint32 instrPosition)
{ {
SetupQuickVariables(nAddress, codeGen, pCtx); SetupQuickVariables(nAddress, codeGen, pCtx, instrPosition);
if(nAddress & 0x04) if(nAddress & 0x04)
{ {
m_Upper.CompileInstruction(nAddress, codeGen, pCtx); m_Upper.CompileInstruction(nAddress, codeGen, pCtx, instrPosition);
} }
else else
{ {
m_Lower.CompileInstruction(nAddress, codeGen, pCtx); m_Lower.CompileInstruction(nAddress, codeGen, pCtx, instrPosition);
} }
} }

View file

@ -12,7 +12,7 @@ class CMA_VU : public CMIPSArchitecture
public: public:
CMA_VU(uint32); CMA_VU(uint32);
void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override; void CompileInstruction(uint32, CMipsJitter*, CMIPS*, uint32) override;
void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int) override; void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int) override;
void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int) override; void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int) override;
MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32) override; MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32) override;
@ -30,7 +30,7 @@ private:
CUpper(); CUpper();
void SetupReflectionTables(); void SetupReflectionTables();
void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override; void CompileInstruction(uint32, CMipsJitter*, CMIPS*, uint32) override;
void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int); void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int);
void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int); void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int);
VUShared::OPERANDSET GetAffectedOperands(CMIPS*, uint32, uint32); VUShared::OPERANDSET GetAffectedOperands(CMIPS*, uint32, uint32);
@ -177,7 +177,7 @@ private:
CLower(uint32); CLower(uint32);
void SetupReflectionTables(); void SetupReflectionTables();
void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override; void CompileInstruction(uint32, CMipsJitter*, CMIPS*, uint32) override;
void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int); void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int);
void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int); void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int);
MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32); MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32);

View file

@ -24,9 +24,9 @@ CMA_VU::CLower::CLower(uint32 vuMemAddressMask)
{ {
} }
void CMA_VU::CLower::CompileInstruction(uint32 address, CMipsJitter* codeGen, CMIPS* context) void CMA_VU::CLower::CompileInstruction(uint32 address, CMipsJitter* codeGen, CMIPS* context, uint32 instrPosition)
{ {
SetupQuickVariables(address, codeGen, context); SetupQuickVariables(address, codeGen, context, instrPosition);
if(IsLOI(context, address)) if(IsLOI(context, address))
{ {
@ -65,8 +65,9 @@ void CMA_VU::CLower::SetBranchAddress(bool nCondition, int32 nOffset)
m_codeGen->PushCst(0); m_codeGen->PushCst(0);
m_codeGen->BeginIf(nCondition ? Jitter::CONDITION_NE : Jitter::CONDITION_EQ); m_codeGen->BeginIf(nCondition ? Jitter::CONDITION_NE : Jitter::CONDITION_EQ);
{ {
const uint32 maxIAddr = 0x3FFF; m_codeGen->PushRel(offsetof(CMIPS, m_State.nPC));
m_codeGen->PushCst((m_nAddress + nOffset + 4) & maxIAddr); m_codeGen->PushCst(m_instrPosition + nOffset + 4);
m_codeGen->Add();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr)); m_codeGen->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr));
} }
m_codeGen->EndIf(); m_codeGen->EndIf();
@ -382,7 +383,10 @@ void CMA_VU::CLower::B()
void CMA_VU::CLower::BAL() void CMA_VU::CLower::BAL()
{ {
//Save PC //Save PC
m_codeGen->PushCst((m_nAddress + 0x10) / 0x8); m_codeGen->PushRel(offsetof(CMIPS, m_State.nPC));
m_codeGen->PushCst(m_instrPosition + 0x10);
m_codeGen->Add();
m_codeGen->Sra(3);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT])); m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
m_codeGen->PushCst(1); m_codeGen->PushCst(1);
@ -411,7 +415,10 @@ void CMA_VU::CLower::JALR()
m_codeGen->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr)); m_codeGen->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr));
//Save PC //Save PC
m_codeGen->PushCst((m_nAddress + 0x10) / 0x8); m_codeGen->PushRel(offsetof(CMIPS, m_State.nPC));
m_codeGen->PushCst(m_instrPosition + 0x10);
m_codeGen->Add();
m_codeGen->Sra(3);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT])); m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
} }

View file

@ -17,9 +17,9 @@ CMA_VU::CUpper::CUpper()
{ {
} }
void CMA_VU::CUpper::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx) void CMA_VU::CUpper::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx, uint32 instrPositon)
{ {
SetupQuickVariables(nAddress, codeGen, pCtx); SetupQuickVariables(nAddress, codeGen, pCtx, instrPositon);
m_nDest = (uint8)((m_nOpcode >> 21) & 0x000F); m_nDest = (uint8)((m_nOpcode >> 21) & 0x000F);
m_nFT = (uint8)((m_nOpcode >> 16) & 0x001F); m_nFT = (uint8)((m_nOpcode >> 16) & 0x001F);

View file

@ -121,7 +121,7 @@ void CVuBasicBlock::CompileRange(CMipsJitter* jitter)
uint32 compileHints = hints[instructionIndex]; uint32 compileHints = hints[instructionIndex];
arch->SetRelativePipeTime(relativePipeTime, compileHints); arch->SetRelativePipeTime(relativePipeTime, compileHints);
arch->CompileInstruction(addressHi, jitter, &m_context); arch->CompileInstruction(addressHi, jitter, &m_context, addressHi - m_begin);
if(savedReg != 0) if(savedReg != 0)
{ {
@ -149,7 +149,7 @@ void CVuBasicBlock::CompileRange(CMipsJitter* jitter)
clearPendingXgKick(); clearPendingXgKick();
} }
arch->CompileInstruction(addressLo, jitter, &m_context); arch->CompileInstruction(addressLo, jitter, &m_context, addressLo - m_begin);
if(address == integerBranchDelayInfo.useRegAddress) if(address == integerBranchDelayInfo.useRegAddress)
{ {
@ -194,7 +194,7 @@ void CVuBasicBlock::CompileRange(CMipsJitter* jitter)
//We need to compile the instruction at the branch target because it will be executed //We need to compile the instruction at the branch target because it will be executed
//before the branch is taken //before the branch is taken
uint32 branchTgtAddress = branchOpcodeAddr + VUShared::GetBranch(branchOpcodeLo & 0x7FF) + 8; uint32 branchTgtAddress = branchOpcodeAddr + VUShared::GetBranch(branchOpcodeLo & 0x7FF) + 8;
arch->CompileInstruction(branchTgtAddress, jitter, &m_context); arch->CompileInstruction(branchTgtAddress, jitter, &m_context, address - m_begin);
} }
} }