[Project64] Change branch to use enum instead of callback

This commit is contained in:
zilmar 2016-06-30 19:11:46 +10:00
parent 451b803439
commit 78b6f9cc66
3 changed files with 87 additions and 51 deletions

View File

@ -960,20 +960,20 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
case R4300i_REGIMM:
switch (m_Opcode.rt)
{
case R4300i_REGIMM_BLTZ:Compile_Branch(BLTZ_Compare, BranchTypeRs, false); break;
case R4300i_REGIMM_BGEZ:Compile_Branch(BGEZ_Compare, BranchTypeRs, false); break;
case R4300i_REGIMM_BLTZL:Compile_BranchLikely(BLTZ_Compare, false); break;
case R4300i_REGIMM_BGEZL:Compile_BranchLikely(BGEZ_Compare, false); break;
case R4300i_REGIMM_BLTZAL:Compile_Branch(BLTZ_Compare, BranchTypeRs, true); break;
case R4300i_REGIMM_BGEZAL:Compile_Branch(BGEZ_Compare, BranchTypeRs, true); break;
case R4300i_REGIMM_BLTZ:Compile_Branch(CRecompilerOps::CompareTypeBLTZ, BranchTypeRs, false); break;
case R4300i_REGIMM_BGEZ:Compile_Branch(CRecompilerOps::CompareTypeBGEZ, BranchTypeRs, false); break;
case R4300i_REGIMM_BLTZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBLTZ, false); break;
case R4300i_REGIMM_BGEZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBGEZ, false); break;
case R4300i_REGIMM_BLTZAL:Compile_Branch(CRecompilerOps::CompareTypeBLTZ, BranchTypeRs, true); break;
case R4300i_REGIMM_BGEZAL:Compile_Branch(CRecompilerOps::CompareTypeBGEZ, BranchTypeRs, true); break;
default:
UnknownOpcode(); break;
}
break;
case R4300i_BEQ: Compile_Branch(BEQ_Compare, BranchTypeRsRt, false); break;
case R4300i_BNE: Compile_Branch(BNE_Compare, BranchTypeRsRt, false); break;
case R4300i_BGTZ:Compile_Branch(BGTZ_Compare, BranchTypeRs, false); break;
case R4300i_BLEZ:Compile_Branch(BLEZ_Compare, BranchTypeRs, false); break;
case R4300i_BEQ: Compile_Branch(CRecompilerOps::CompareTypeBEQ, BranchTypeRsRt, false); break;
case R4300i_BNE: Compile_Branch(CRecompilerOps::CompareTypeBNE, BranchTypeRsRt, false); break;
case R4300i_BGTZ:Compile_Branch(CRecompilerOps::CompareTypeBGTZ, BranchTypeRs, false); break;
case R4300i_BLEZ:Compile_Branch(CRecompilerOps::CompareTypeBLEZ, BranchTypeRs, false); break;
case R4300i_J: J(); break;
case R4300i_JAL: JAL(); break;
case R4300i_ADDI: ADDI(); break;
@ -1020,10 +1020,10 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
case R4300i_COP1_BC:
switch (m_Opcode.ft)
{
case R4300i_COP1_BC_BCF: Compile_Branch(COP1_BCF_Compare, BranchTypeCop1, false); break;
case R4300i_COP1_BC_BCT: Compile_Branch(COP1_BCT_Compare, BranchTypeCop1, false); break;
case R4300i_COP1_BC_BCFL: Compile_BranchLikely(COP1_BCF_Compare, false); break;
case R4300i_COP1_BC_BCTL: Compile_BranchLikely(COP1_BCT_Compare, false); break;
case R4300i_COP1_BC_BCF: Compile_Branch(CRecompilerOps::CompareTypeCOP1BCF, BranchTypeCop1, false); break;
case R4300i_COP1_BC_BCT: Compile_Branch(CRecompilerOps::CompareTypeCOP1BCT, BranchTypeCop1, false); break;
case R4300i_COP1_BC_BCFL: Compile_BranchLikely(CRecompilerOps::CompareTypeCOP1BCF, false); break;
case R4300i_COP1_BC_BCTL: Compile_BranchLikely(CRecompilerOps::CompareTypeCOP1BCT, false); break;
default:
UnknownOpcode(); break;
}
@ -1120,10 +1120,10 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
UnknownOpcode(); break;
}
break;
case R4300i_BEQL: Compile_BranchLikely(BEQ_Compare, false); break;
case R4300i_BNEL: Compile_BranchLikely(BNE_Compare, false); break;
case R4300i_BGTZL:Compile_BranchLikely(BGTZ_Compare, false); break;
case R4300i_BLEZL:Compile_BranchLikely(BLEZ_Compare, false); break;
case R4300i_BEQL: Compile_BranchLikely(CRecompilerOps::CompareTypeBEQ, false); break;
case R4300i_BNEL: Compile_BranchLikely(CRecompilerOps::CompareTypeBNE, false); break;
case R4300i_BGTZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBGTZ, false); break;
case R4300i_BLEZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBLEZ, false); break;
case R4300i_DADDIU: DADDIU(); break;
case R4300i_LDL: LDL(); break;
case R4300i_LDR: LDR(); break;

View File

@ -106,7 +106,24 @@ void CRecompilerOps::CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg)
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
/************************** Branch functions ************************/
void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc, BRANCH_TYPE BranchType, bool Link)
void CRecompilerOps::Compile_BranchCompare(BRANCH_COMPARE CompareType)
{
switch (CompareType)
{
case CompareTypeBEQ: BEQ_Compare(); break;
case CompareTypeBNE: BNE_Compare(); break;
case CompareTypeBLTZ: BLTZ_Compare(); break;
case CompareTypeBLEZ: BLEZ_Compare(); break;
case CompareTypeBGTZ: BGTZ_Compare(); break;
case CompareTypeBGEZ: BGEZ_Compare(); break;
case CompareTypeCOP1BCF: COP1_BCF_Compare(); break;
case CompareTypeCOP1BCT: COP1_BCT_Compare(); break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
}
void CRecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link)
{
static CRegInfo RegBeforeDelay;
static bool EffectDelaySlot;
@ -114,7 +131,10 @@ void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc,
if (m_NextInstruction == NORMAL)
{
CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC));
if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT)
{
m_Section->CompileCop1Test();
}
if (m_CompilePC + ((int16_t)m_Opcode.offset << 2) + 4 == m_CompilePC + 8)
{
return;
@ -127,25 +147,25 @@ void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc,
case BranchTypeRs: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0); break;
case BranchTypeRsRt: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, m_Opcode.rt); break;
case BranchTypeCop1:
{
OPCODE Command;
if (!g_MMU->LW_VAddr(m_CompilePC + 4, Command.Hex))
{
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
}
OPCODE Command;
EffectDelaySlot = false;
if (Command.op == R4300i_CP1)
{
if ((Command.fmt == R4300i_COP1_S && (Command.funct & 0x30) == 0x30) ||
(Command.fmt == R4300i_COP1_D && (Command.funct & 0x30) == 0x30))
if (!g_MMU->LW_VAddr(m_CompilePC + 4, Command.Hex))
{
EffectDelaySlot = true;
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
}
EffectDelaySlot = false;
if (Command.op == R4300i_CP1)
{
if ((Command.fmt == R4300i_COP1_S && (Command.funct & 0x30) == 0x30) ||
(Command.fmt == R4300i_COP1_D && (Command.funct & 0x30) == 0x30))
{
EffectDelaySlot = true;
}
}
}
}
break;
break;
default:
if (bHaveDebugger()) { g_Notify->DisplayError("Unknown branch type"); }
}
@ -211,7 +231,7 @@ void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc,
}
if (m_Section->m_Jump.TargetPC != m_Section->m_Cont.TargetPC)
{
CompareFunc();
Compile_BranchCompare(CompareType);
}
if (!m_Section->m_Jump.FallThrough && !m_Section->m_Cont.FallThrough)
{
@ -381,7 +401,7 @@ void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc,
{
if (m_Section->m_Jump.TargetPC != m_Section->m_Cont.TargetPC)
{
CompareFunc();
Compile_BranchCompare(CompareType);
ResetX86Protection();
m_Section->m_Cont.RegSet = m_RegWorkingSet;
m_Section->m_Jump.RegSet = m_RegWorkingSet;
@ -418,12 +438,16 @@ void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc,
}
}
void CRecompilerOps::Compile_BranchLikely(BranchFunction CompareFunc, bool Link)
void CRecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link)
{
if (m_NextInstruction == NORMAL)
{
CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC));
if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT)
{
m_Section->CompileCop1Test();;
}
if (!g_System->bLinkBlocks() || (m_CompilePC & 0xFFC) == 0xFFC)
{
m_Section->m_Jump.JumpPC = m_CompilePC;
@ -479,7 +503,7 @@ void CRecompilerOps::Compile_BranchLikely(BranchFunction CompareFunc, bool Link)
m_RegWorkingSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN);
}
CompareFunc();
Compile_BranchCompare(CompareType);
ResetX86Protection();
m_Section->m_Cont.RegSet = m_RegWorkingSet;

View File

@ -31,22 +31,34 @@ class CRecompilerOps :
public:
enum BRANCH_TYPE
{
BranchTypeCop1, BranchTypeRs, BranchTypeRsRt
BranchTypeCop1,
BranchTypeRs,
BranchTypeRsRt
};
enum BRANCH_COMPARE
{
CompareTypeBEQ,
CompareTypeBNE,
CompareTypeBLTZ,
CompareTypeBLEZ,
CompareTypeBGTZ,
CompareTypeBGEZ,
CompareTypeCOP1BCF,
CompareTypeCOP1BCT,
};
typedef void ( * BranchFunction )();
/************************** Branch functions ************************/
void Compile_Branch ( BranchFunction CompareFunc, BRANCH_TYPE BranchType, bool Link);
void Compile_BranchLikely ( BranchFunction CompareFunc, bool Link);
static void BNE_Compare();
static void BEQ_Compare();
static void BGTZ_Compare();
static void BLEZ_Compare();
static void BLTZ_Compare();
static void BGEZ_Compare();
static void COP1_BCF_Compare();
static void COP1_BCT_Compare();
void Compile_BranchCompare(BRANCH_COMPARE CompareType);
void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link);
void Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link);
void BNE_Compare();
void BEQ_Compare();
void BGTZ_Compare();
void BLEZ_Compare();
void BLTZ_Compare();
void BGEZ_Compare();
void COP1_BCF_Compare();
void COP1_BCT_Compare();
/************************* OpCode functions *************************/
static void J ();