diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h index 98c245b3ca..686557461f 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h @@ -296,10 +296,10 @@ private: bool HandleFunctionHooking(u32 address); // flag helper - static void Helper_UpdateCR0(u32 value); + static void Helper_UpdateCR0(PowerPC::PowerPCState& ppc_state, u32 value); template - static void Helper_IntCompare(UGeckoInstruction inst, T a, T b); + static void Helper_IntCompare(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, T a, T b); static void Helper_FloatCompareOrdered(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, double a, double b); static void Helper_FloatCompareUnordered(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp index b5bc42d234..006110a4e2 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -11,14 +11,14 @@ #include "Core/PowerPC/Interpreter/ExceptionUtils.h" #include "Core/PowerPC/PowerPC.h" -void Interpreter::Helper_UpdateCR0(u32 value) +void Interpreter::Helper_UpdateCR0(PowerPC::PowerPCState& ppc_state, u32 value) { const s64 sign_extended = s64{s32(value)}; u64 cr_val = u64(sign_extended); cr_val = (cr_val & ~(1ULL << PowerPC::CR_EMU_SO_BIT)) | - (u64{PowerPC::ppcState.GetXER_SO()} << PowerPC::CR_EMU_SO_BIT); + (u64{ppc_state.GetXER_SO()} << PowerPC::CR_EMU_SO_BIT); - PowerPC::ppcState.cr.fields[0] = cr_val; + ppc_state.cr.fields[0] = cr_val; } u32 Interpreter::Helper_Carry(u32 value1, u32 value2) @@ -28,49 +28,56 @@ u32 Interpreter::Helper_Carry(u32 value1, u32 value2) void Interpreter::addi(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; if (inst.RA) - PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_16); + ppc_state.gpr[inst.RD] = ppc_state.gpr[inst.RA] + u32(inst.SIMM_16); else - PowerPC::ppcState.gpr[inst.RD] = u32(inst.SIMM_16); + ppc_state.gpr[inst.RD] = u32(inst.SIMM_16); } void Interpreter::addic(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; const u32 imm = u32(s32{inst.SIMM_16}); - PowerPC::ppcState.gpr[inst.RD] = a + imm; - PowerPC::ppcState.SetCarry(Helper_Carry(a, imm)); + ppc_state.gpr[inst.RD] = a + imm; + ppc_state.SetCarry(Helper_Carry(a, imm)); } void Interpreter::addic_rc(Interpreter& interpreter, UGeckoInstruction inst) { addic(interpreter, inst); - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); + auto& ppc_state = interpreter.m_ppc_state; + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RD]); } void Interpreter::addis(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; if (inst.RA) - PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_16 << 16); + ppc_state.gpr[inst.RD] = ppc_state.gpr[inst.RA] + u32(inst.SIMM_16 << 16); else - PowerPC::ppcState.gpr[inst.RD] = u32(inst.SIMM_16 << 16); + ppc_state.gpr[inst.RD] = u32(inst.SIMM_16 << 16); } void Interpreter::andi_rc(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & inst.UIMM; - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] & inst.UIMM; + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::andis_rc(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & (u32{inst.UIMM} << 16); - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] & (u32{inst.UIMM} << 16); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } template -void Interpreter::Helper_IntCompare(UGeckoInstruction inst, T a, T b) +void Interpreter::Helper_IntCompare(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, T a, + T b) { u32 cr_field; @@ -81,52 +88,59 @@ void Interpreter::Helper_IntCompare(UGeckoInstruction inst, T a, T b) else cr_field = PowerPC::CR_EQ; - if (PowerPC::ppcState.GetXER_SO()) + if (ppc_state.GetXER_SO()) cr_field |= PowerPC::CR_SO; - PowerPC::ppcState.cr.SetField(inst.CRFD, cr_field); + ppc_state.cr.SetField(inst.CRFD, cr_field); } void Interpreter::cmpi(Interpreter& interpreter, UGeckoInstruction inst) { - const s32 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); + auto& ppc_state = interpreter.m_ppc_state; + const s32 a = static_cast(ppc_state.gpr[inst.RA]); const s32 b = inst.SIMM_16; - Helper_IntCompare(inst, a, b); + Helper_IntCompare(ppc_state, inst, a, b); } void Interpreter::cmpli(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; const u32 b = inst.UIMM; - Helper_IntCompare(inst, a, b); + Helper_IntCompare(ppc_state, inst, a, b); } void Interpreter::mulli(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RD] = u32(s32(PowerPC::ppcState.gpr[inst.RA]) * inst.SIMM_16); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RD] = u32(s32(ppc_state.gpr[inst.RA]) * inst.SIMM_16); } void Interpreter::ori(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] | inst.UIMM; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] | inst.UIMM; } void Interpreter::oris(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] | (u32{inst.UIMM} << 16); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] | (u32{inst.UIMM} << 16); } void Interpreter::subfic(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; const s32 immediate = inst.SIMM_16; - PowerPC::ppcState.gpr[inst.RD] = u32(immediate - s32(PowerPC::ppcState.gpr[inst.RA])); - PowerPC::ppcState.SetCarry((PowerPC::ppcState.gpr[inst.RA] == 0) || - (Helper_Carry(0 - PowerPC::ppcState.gpr[inst.RA], u32(immediate)))); + ppc_state.gpr[inst.RD] = u32(immediate - s32(ppc_state.gpr[inst.RA])); + ppc_state.SetCarry((ppc_state.gpr[inst.RA] == 0) || + (Helper_Carry(0 - ppc_state.gpr[inst.RA], u32(immediate)))); } void Interpreter::twi(Interpreter& interpreter, UGeckoInstruction inst) { - const s32 a = s32(PowerPC::ppcState.gpr[inst.RA]); + auto& ppc_state = interpreter.m_ppc_state; + const s32 a = s32(ppc_state.gpr[inst.RA]); const s32 b = inst.SIMM_16; const u32 TO = inst.TO; @@ -143,207 +157,222 @@ void Interpreter::twi(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::xori(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] ^ inst.UIMM; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] ^ inst.UIMM; } void Interpreter::xoris(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] ^ (u32{inst.UIMM} << 16); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] ^ (u32{inst.UIMM} << 16); } void Interpreter::rlwimix(Interpreter& interpreter, UGeckoInstruction inst) { const u32 mask = MakeRotationMask(inst.MB, inst.ME); - PowerPC::ppcState.gpr[inst.RA] = (PowerPC::ppcState.gpr[inst.RA] & ~mask) | - (std::rotl(PowerPC::ppcState.gpr[inst.RS], inst.SH) & mask); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = + (ppc_state.gpr[inst.RA] & ~mask) | (std::rotl(ppc_state.gpr[inst.RS], inst.SH) & mask); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::rlwinmx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 mask = MakeRotationMask(inst.MB, inst.ME); - PowerPC::ppcState.gpr[inst.RA] = std::rotl(PowerPC::ppcState.gpr[inst.RS], inst.SH) & mask; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = std::rotl(ppc_state.gpr[inst.RS], inst.SH) & mask; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::rlwnmx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 mask = MakeRotationMask(inst.MB, inst.ME); - PowerPC::ppcState.gpr[inst.RA] = - std::rotl(PowerPC::ppcState.gpr[inst.RS], PowerPC::ppcState.gpr[inst.RB] & 0x1F) & mask; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = std::rotl(ppc_state.gpr[inst.RS], ppc_state.gpr[inst.RB] & 0x1F) & mask; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::andx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] & ppc_state.gpr[inst.RB]; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::andcx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & ~PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] & ~ppc_state.gpr[inst.RB]; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::cmp(Interpreter& interpreter, UGeckoInstruction inst) { - const s32 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); - const s32 b = static_cast(PowerPC::ppcState.gpr[inst.RB]); - Helper_IntCompare(inst, a, b); + auto& ppc_state = interpreter.m_ppc_state; + const s32 a = static_cast(ppc_state.gpr[inst.RA]); + const s32 b = static_cast(ppc_state.gpr[inst.RB]); + Helper_IntCompare(ppc_state, inst, a, b); } void Interpreter::cmpl(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; - Helper_IntCompare(inst, a, b); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; + Helper_IntCompare(ppc_state, inst, a, b); } void Interpreter::cntlzwx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = u32(std::countl_zero(PowerPC::ppcState.gpr[inst.RS])); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = u32(std::countl_zero(ppc_state.gpr[inst.RS])); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::eqvx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = - ~(PowerPC::ppcState.gpr[inst.RS] ^ PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ~(ppc_state.gpr[inst.RS] ^ ppc_state.gpr[inst.RB]); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::extsbx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = u32(s32(s8(PowerPC::ppcState.gpr[inst.RS]))); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = u32(s32(s8(ppc_state.gpr[inst.RS]))); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::extshx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = u32(s32(s16(PowerPC::ppcState.gpr[inst.RS]))); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = u32(s32(s16(ppc_state.gpr[inst.RS]))); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::nandx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = - ~(PowerPC::ppcState.gpr[inst.RS] & PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ~(ppc_state.gpr[inst.RS] & ppc_state.gpr[inst.RB]); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::norx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = - ~(PowerPC::ppcState.gpr[inst.RS] | PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ~(ppc_state.gpr[inst.RS] | ppc_state.gpr[inst.RB]); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::orx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] | PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] | ppc_state.gpr[inst.RB]; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::orcx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = - PowerPC::ppcState.gpr[inst.RS] | (~PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] | (~ppc_state.gpr[inst.RB]); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::slwx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 amount = PowerPC::ppcState.gpr[inst.RB]; - PowerPC::ppcState.gpr[inst.RA] = - (amount & 0x20) != 0 ? 0 : PowerPC::ppcState.gpr[inst.RS] << (amount & 0x1f); + auto& ppc_state = interpreter.m_ppc_state; + const u32 amount = ppc_state.gpr[inst.RB]; + ppc_state.gpr[inst.RA] = (amount & 0x20) != 0 ? 0 : ppc_state.gpr[inst.RS] << (amount & 0x1f); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::srawx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 rb = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 rb = ppc_state.gpr[inst.RB]; if ((rb & 0x20) != 0) { - if ((PowerPC::ppcState.gpr[inst.RS] & 0x80000000) != 0) + if ((ppc_state.gpr[inst.RS] & 0x80000000) != 0) { - PowerPC::ppcState.gpr[inst.RA] = 0xFFFFFFFF; - PowerPC::ppcState.SetCarry(1); + ppc_state.gpr[inst.RA] = 0xFFFFFFFF; + ppc_state.SetCarry(1); } else { - PowerPC::ppcState.gpr[inst.RA] = 0x00000000; - PowerPC::ppcState.SetCarry(0); + ppc_state.gpr[inst.RA] = 0x00000000; + ppc_state.SetCarry(0); } } else { const u32 amount = rb & 0x1f; - const s32 rrs = s32(PowerPC::ppcState.gpr[inst.RS]); - PowerPC::ppcState.gpr[inst.RA] = u32(rrs >> amount); + const s32 rrs = s32(ppc_state.gpr[inst.RS]); + ppc_state.gpr[inst.RA] = u32(rrs >> amount); - PowerPC::ppcState.SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0); + ppc_state.SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0); } if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::srawix(Interpreter& interpreter, UGeckoInstruction inst) { const u32 amount = inst.SH; - const s32 rrs = s32(PowerPC::ppcState.gpr[inst.RS]); + auto& ppc_state = interpreter.m_ppc_state; + const s32 rrs = s32(ppc_state.gpr[inst.RS]); - PowerPC::ppcState.gpr[inst.RA] = u32(rrs >> amount); - PowerPC::ppcState.SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0); + ppc_state.gpr[inst.RA] = u32(rrs >> amount); + ppc_state.SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::srwx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 amount = PowerPC::ppcState.gpr[inst.RB]; - PowerPC::ppcState.gpr[inst.RA] = - (amount & 0x20) != 0 ? 0 : (PowerPC::ppcState.gpr[inst.RS] >> (amount & 0x1f)); + auto& ppc_state = interpreter.m_ppc_state; + const u32 amount = ppc_state.gpr[inst.RB]; + ppc_state.gpr[inst.RA] = (amount & 0x20) != 0 ? 0 : (ppc_state.gpr[inst.RS] >> (amount & 0x1f)); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::tw(Interpreter& interpreter, UGeckoInstruction inst) { - const s32 a = s32(PowerPC::ppcState.gpr[inst.RA]); - const s32 b = s32(PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + const s32 a = s32(ppc_state.gpr[inst.RA]); + const s32 b = s32(ppc_state.gpr[inst.RB]); const u32 TO = inst.TO; DEBUG_LOG_FMT(POWERPC, "tw rA {:x} rB {:x} TO {:x}", a, b, TO); @@ -359,10 +388,11 @@ void Interpreter::tw(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::xorx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] ^ PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] ^ ppc_state.gpr[inst.RB]; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } static bool HasAddOverflowed(u32 x, u32 y, u32 result) @@ -374,263 +404,279 @@ static bool HasAddOverflowed(u32 x, u32 y, u32 result) void Interpreter::addx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const u32 result = a + b; - PowerPC::ppcState.gpr[inst.RD] = result; + ppc_state.gpr[inst.RD] = result; if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::addcx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const u32 result = a + b; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, b)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, b)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::addex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 carry = PowerPC::ppcState.GetCarry(); - const u32 a = PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 carry = ppc_state.GetCarry(); + const u32 a = ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const u32 result = a + b + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry))); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry))); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::addmex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 carry = PowerPC::ppcState.GetCarry(); - const u32 a = PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 carry = ppc_state.GetCarry(); + const u32 a = ppc_state.gpr[inst.RA]; const u32 b = 0xFFFFFFFF; const u32 result = a + b + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, carry - 1)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, carry - 1)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::addzex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 carry = PowerPC::ppcState.GetCarry(); - const u32 a = PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 carry = ppc_state.GetCarry(); + const u32 a = ppc_state.gpr[inst.RA]; const u32 result = a + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, carry)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, carry)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, 0, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, 0, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::divwx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto a = s32(PowerPC::ppcState.gpr[inst.RA]); - const auto b = s32(PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + const auto a = s32(ppc_state.gpr[inst.RA]); + const auto b = s32(ppc_state.gpr[inst.RB]); const bool overflow = b == 0 || (static_cast(a) == 0x80000000 && b == -1); if (overflow) { if (a < 0) - PowerPC::ppcState.gpr[inst.RD] = UINT32_MAX; + ppc_state.gpr[inst.RD] = UINT32_MAX; else - PowerPC::ppcState.gpr[inst.RD] = 0; + ppc_state.gpr[inst.RD] = 0; } else { - PowerPC::ppcState.gpr[inst.RD] = static_cast(a / b); + ppc_state.gpr[inst.RD] = static_cast(a / b); } if (inst.OE) - PowerPC::ppcState.SetXER_OV(overflow); + ppc_state.SetXER_OV(overflow); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RD]); } void Interpreter::divwux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const bool overflow = b == 0; if (overflow) { - PowerPC::ppcState.gpr[inst.RD] = 0; + ppc_state.gpr[inst.RD] = 0; } else { - PowerPC::ppcState.gpr[inst.RD] = a / b; + ppc_state.gpr[inst.RD] = a / b; } if (inst.OE) - PowerPC::ppcState.SetXER_OV(overflow); + ppc_state.SetXER_OV(overflow); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RD]); } void Interpreter::mulhwx(Interpreter& interpreter, UGeckoInstruction inst) { - const s64 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); - const s64 b = static_cast(PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + const s64 a = static_cast(ppc_state.gpr[inst.RA]); + const s64 b = static_cast(ppc_state.gpr[inst.RB]); const u32 d = static_cast((a * b) >> 32); - PowerPC::ppcState.gpr[inst.RD] = d; + ppc_state.gpr[inst.RD] = d; if (inst.Rc) - Helper_UpdateCR0(d); + Helper_UpdateCR0(ppc_state, d); } void Interpreter::mulhwux(Interpreter& interpreter, UGeckoInstruction inst) { - const u64 a = PowerPC::ppcState.gpr[inst.RA]; - const u64 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u64 a = ppc_state.gpr[inst.RA]; + const u64 b = ppc_state.gpr[inst.RB]; const u32 d = static_cast((a * b) >> 32); - PowerPC::ppcState.gpr[inst.RD] = d; + ppc_state.gpr[inst.RD] = d; if (inst.Rc) - Helper_UpdateCR0(d); + Helper_UpdateCR0(ppc_state, d); } void Interpreter::mullwx(Interpreter& interpreter, UGeckoInstruction inst) { - const s64 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); - const s64 b = static_cast(PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + const s64 a = static_cast(ppc_state.gpr[inst.RA]); + const s64 b = static_cast(ppc_state.gpr[inst.RB]); const s64 result = a * b; - PowerPC::ppcState.gpr[inst.RD] = static_cast(result); + ppc_state.gpr[inst.RD] = static_cast(result); if (inst.OE) - PowerPC::ppcState.SetXER_OV(result < -0x80000000LL || result > 0x7FFFFFFFLL); + ppc_state.SetXER_OV(result < -0x80000000LL || result > 0x7FFFFFFFLL); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RD]); } void Interpreter::negx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; - PowerPC::ppcState.gpr[inst.RD] = (~a) + 1; + ppc_state.gpr[inst.RD] = (~a) + 1; if (inst.OE) - PowerPC::ppcState.SetXER_OV(a == 0x80000000); + ppc_state.SetXER_OV(a == 0x80000000); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RD]); } void Interpreter::subfx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ~ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const u32 result = a + b + 1; - PowerPC::ppcState.gpr[inst.RD] = result; + ppc_state.gpr[inst.RD] = result; if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::subfcx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ~ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const u32 result = a + b + 1; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(a == 0xFFFFFFFF || Helper_Carry(b, a + 1)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(a == 0xFFFFFFFF || Helper_Carry(b, a + 1)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::subfex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; - const u32 carry = PowerPC::ppcState.GetCarry(); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ~ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; + const u32 carry = ppc_state.GetCarry(); const u32 result = a + b + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, b) || Helper_Carry(a + b, carry)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, b) || Helper_Carry(a + b, carry)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } // sub from minus one void Interpreter::subfmex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ~ppc_state.gpr[inst.RA]; const u32 b = 0xFFFFFFFF; - const u32 carry = PowerPC::ppcState.GetCarry(); + const u32 carry = ppc_state.GetCarry(); const u32 result = a + b + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, carry - 1)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, carry - 1)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } // sub from zero void Interpreter::subfzex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; - const u32 carry = PowerPC::ppcState.GetCarry(); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ~ppc_state.gpr[inst.RA]; + const u32 carry = ppc_state.GetCarry(); const u32 result = a + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, carry)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, carry)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, 0, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, 0, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); }