mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-06 21:40:05 +00:00
Interpreter: Avoid ppcState global (Interpreter_Branch.cpp).
This commit is contained in:
parent
68ab623764
commit
d4ca591e02
@ -14,15 +14,17 @@
|
|||||||
|
|
||||||
void Interpreter::bx(Interpreter& interpreter, UGeckoInstruction inst)
|
void Interpreter::bx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
auto& ppc_state = interpreter.m_ppc_state;
|
||||||
|
|
||||||
if (inst.LK)
|
if (inst.LK)
|
||||||
LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4;
|
LR(ppc_state) = ppc_state.pc + 4;
|
||||||
|
|
||||||
const auto address = u32(SignExt26(inst.LI << 2));
|
const auto address = u32(SignExt26(inst.LI << 2));
|
||||||
|
|
||||||
if (inst.AA)
|
if (inst.AA)
|
||||||
PowerPC::ppcState.npc = address;
|
ppc_state.npc = address;
|
||||||
else
|
else
|
||||||
PowerPC::ppcState.npc = PowerPC::ppcState.pc + address;
|
ppc_state.npc = ppc_state.pc + address;
|
||||||
|
|
||||||
interpreter.m_end_block = true;
|
interpreter.m_end_block = true;
|
||||||
}
|
}
|
||||||
@ -30,28 +32,29 @@ void Interpreter::bx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||||||
// bcx - ugly, straight from PPC manual equations :)
|
// bcx - ugly, straight from PPC manual equations :)
|
||||||
void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst)
|
void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
auto& ppc_state = interpreter.m_ppc_state;
|
||||||
|
|
||||||
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||||
CTR(PowerPC::ppcState)--;
|
CTR(ppc_state)--;
|
||||||
|
|
||||||
const bool true_false = ((inst.BO >> 3) & 1) != 0;
|
const bool true_false = ((inst.BO >> 3) & 1) != 0;
|
||||||
const bool only_counter_check = ((inst.BO >> 4) & 1) != 0;
|
const bool only_counter_check = ((inst.BO >> 4) & 1) != 0;
|
||||||
const bool only_condition_check = ((inst.BO >> 2) & 1) != 0;
|
const bool only_condition_check = ((inst.BO >> 2) & 1) != 0;
|
||||||
const u32 ctr_check = ((CTR(PowerPC::ppcState) != 0) ^ (inst.BO >> 1)) & 1;
|
const u32 ctr_check = ((CTR(ppc_state) != 0) ^ (inst.BO >> 1)) & 1;
|
||||||
const bool counter = only_condition_check || ctr_check != 0;
|
const bool counter = only_condition_check || ctr_check != 0;
|
||||||
const bool condition =
|
const bool condition = only_counter_check || (ppc_state.cr.GetBit(inst.BI) == u32(true_false));
|
||||||
only_counter_check || (PowerPC::ppcState.cr.GetBit(inst.BI) == u32(true_false));
|
|
||||||
|
|
||||||
if (counter && condition)
|
if (counter && condition)
|
||||||
{
|
{
|
||||||
if (inst.LK)
|
if (inst.LK)
|
||||||
LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4;
|
LR(ppc_state) = ppc_state.pc + 4;
|
||||||
|
|
||||||
const auto address = u32(SignExt16(s16(inst.BD << 2)));
|
const auto address = u32(SignExt16(s16(inst.BD << 2)));
|
||||||
|
|
||||||
if (inst.AA)
|
if (inst.AA)
|
||||||
PowerPC::ppcState.npc = address;
|
ppc_state.npc = address;
|
||||||
else
|
else
|
||||||
PowerPC::ppcState.npc = PowerPC::ppcState.pc + address;
|
ppc_state.npc = ppc_state.pc + address;
|
||||||
}
|
}
|
||||||
|
|
||||||
interpreter.m_end_block = true;
|
interpreter.m_end_block = true;
|
||||||
@ -59,17 +62,19 @@ void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||||||
|
|
||||||
void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst)
|
void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
auto& ppc_state = interpreter.m_ppc_state;
|
||||||
|
|
||||||
DEBUG_ASSERT_MSG(POWERPC, (inst.BO_2 & BO_DONT_DECREMENT_FLAG) != 0,
|
DEBUG_ASSERT_MSG(POWERPC, (inst.BO_2 & BO_DONT_DECREMENT_FLAG) != 0,
|
||||||
"bcctrx with decrement and test CTR option is invalid!");
|
"bcctrx with decrement and test CTR option is invalid!");
|
||||||
|
|
||||||
const u32 condition =
|
const u32 condition =
|
||||||
((inst.BO_2 >> 4) | (PowerPC::ppcState.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
|
((inst.BO_2 >> 4) | (ppc_state.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
|
||||||
|
|
||||||
if (condition != 0)
|
if (condition != 0)
|
||||||
{
|
{
|
||||||
PowerPC::ppcState.npc = CTR(PowerPC::ppcState) & (~3);
|
ppc_state.npc = CTR(ppc_state) & (~3);
|
||||||
if (inst.LK_3)
|
if (inst.LK_3)
|
||||||
LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4;
|
LR(ppc_state) = ppc_state.pc + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
interpreter.m_end_block = true;
|
interpreter.m_end_block = true;
|
||||||
@ -77,18 +82,20 @@ void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||||||
|
|
||||||
void Interpreter::bclrx(Interpreter& interpreter, UGeckoInstruction inst)
|
void Interpreter::bclrx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
|
auto& ppc_state = interpreter.m_ppc_state;
|
||||||
CTR(PowerPC::ppcState)--;
|
|
||||||
|
|
||||||
const u32 counter = ((inst.BO_2 >> 2) | ((CTR(PowerPC::ppcState) != 0) ^ (inst.BO_2 >> 1))) & 1;
|
if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
|
||||||
|
CTR(ppc_state)--;
|
||||||
|
|
||||||
|
const u32 counter = ((inst.BO_2 >> 2) | ((CTR(ppc_state) != 0) ^ (inst.BO_2 >> 1))) & 1;
|
||||||
const u32 condition =
|
const u32 condition =
|
||||||
((inst.BO_2 >> 4) | (PowerPC::ppcState.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
|
((inst.BO_2 >> 4) | (ppc_state.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
|
||||||
|
|
||||||
if ((counter & condition) != 0)
|
if ((counter & condition) != 0)
|
||||||
{
|
{
|
||||||
PowerPC::ppcState.npc = LR(PowerPC::ppcState) & (~3);
|
ppc_state.npc = LR(ppc_state) & (~3);
|
||||||
if (inst.LK_3)
|
if (inst.LK_3)
|
||||||
LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4;
|
LR(ppc_state) = ppc_state.pc + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
interpreter.m_end_block = true;
|
interpreter.m_end_block = true;
|
||||||
@ -99,14 +106,16 @@ void Interpreter::HLEFunction(Interpreter& interpreter, UGeckoInstruction inst)
|
|||||||
interpreter.m_end_block = true;
|
interpreter.m_end_block = true;
|
||||||
|
|
||||||
ASSERT(Core::IsCPUThread());
|
ASSERT(Core::IsCPUThread());
|
||||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
Core::CPUThreadGuard guard(interpreter.m_system);
|
||||||
|
|
||||||
HLE::Execute(guard, PowerPC::ppcState.pc, inst.hex);
|
HLE::Execute(guard, interpreter.m_ppc_state.pc, inst.hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst)
|
void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (PowerPC::ppcState.msr.PR)
|
auto& ppc_state = interpreter.m_ppc_state;
|
||||||
|
|
||||||
|
if (ppc_state.msr.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
return;
|
||||||
@ -115,17 +124,16 @@ void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst)
|
|||||||
// Restore saved bits from SRR1 to MSR.
|
// Restore saved bits from SRR1 to MSR.
|
||||||
// Gecko/Broadway can save more bits than explicitly defined in ppc spec
|
// Gecko/Broadway can save more bits than explicitly defined in ppc spec
|
||||||
const u32 mask = 0x87C0FFFF;
|
const u32 mask = 0x87C0FFFF;
|
||||||
PowerPC::ppcState.msr.Hex =
|
ppc_state.msr.Hex = (ppc_state.msr.Hex & ~mask) | (SRR1(ppc_state) & mask);
|
||||||
(PowerPC::ppcState.msr.Hex & ~mask) | (SRR1(PowerPC::ppcState) & mask);
|
|
||||||
// MSR[13] is set to 0.
|
// MSR[13] is set to 0.
|
||||||
PowerPC::ppcState.msr.Hex &= 0xFFFBFFFF;
|
ppc_state.msr.Hex &= 0xFFFBFFFF;
|
||||||
// Here we should check if there are pending exceptions, and if their corresponding enable bits
|
// Here we should check if there are pending exceptions, and if their corresponding enable bits
|
||||||
// are set
|
// are set
|
||||||
// if above is true, we'd do:
|
// if above is true, we'd do:
|
||||||
// PowerPC::CheckExceptions();
|
// PowerPC::CheckExceptions();
|
||||||
// else
|
// else
|
||||||
// set NPC to saved offset and resume
|
// set NPC to saved offset and resume
|
||||||
PowerPC::ppcState.npc = SRR0(PowerPC::ppcState);
|
ppc_state.npc = SRR0(ppc_state);
|
||||||
interpreter.m_end_block = true;
|
interpreter.m_end_block = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +142,9 @@ void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst)
|
|||||||
// We do it anyway, though :P
|
// We do it anyway, though :P
|
||||||
void Interpreter::sc(Interpreter& interpreter, UGeckoInstruction inst)
|
void Interpreter::sc(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL;
|
auto& ppc_state = interpreter.m_ppc_state;
|
||||||
|
|
||||||
|
ppc_state.Exceptions |= EXCEPTION_SYSCALL;
|
||||||
PowerPC::CheckExceptions();
|
PowerPC::CheckExceptions();
|
||||||
interpreter.m_end_block = true;
|
interpreter.m_end_block = true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user