diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index d1c03420fc..ff3bd8c4f8 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -18,7 +18,8 @@ #include "Core/PowerPC/GDBStub.h" #endif -namespace { +namespace +{ u32 last_pc; } @@ -32,11 +33,11 @@ Interpreter::_interpreterInstruction Interpreter::m_opTable31[1024]; Interpreter::_interpreterInstruction Interpreter::m_opTable59[32]; Interpreter::_interpreterInstruction Interpreter::m_opTable63[1024]; -void Interpreter::RunTable4(UGeckoInstruction _inst) {m_opTable4 [_inst.SUBOP10](_inst);} -void Interpreter::RunTable19(UGeckoInstruction _inst) {m_opTable19[_inst.SUBOP10](_inst);} -void Interpreter::RunTable31(UGeckoInstruction _inst) {m_opTable31[_inst.SUBOP10](_inst);} -void Interpreter::RunTable59(UGeckoInstruction _inst) {m_opTable59[_inst.SUBOP5 ](_inst);} -void Interpreter::RunTable63(UGeckoInstruction _inst) {m_opTable63[_inst.SUBOP10](_inst);} +void Interpreter::RunTable4(UGeckoInstruction _inst) { m_opTable4 [_inst.SUBOP10](_inst); } +void Interpreter::RunTable19(UGeckoInstruction _inst) { m_opTable19[_inst.SUBOP10](_inst); } +void Interpreter::RunTable31(UGeckoInstruction _inst) { m_opTable31[_inst.SUBOP10](_inst); } +void Interpreter::RunTable59(UGeckoInstruction _inst) { m_opTable59[_inst.SUBOP5 ](_inst); } +void Interpreter::RunTable63(UGeckoInstruction _inst) { m_opTable63[_inst.SUBOP10](_inst); } void Interpreter::Init() { @@ -116,8 +117,8 @@ int Interpreter::SingleStepInner(void) if (function == 0) { #ifdef USE_GDBSTUB - if (gdb_active() && gdb_bp_x(PC)) { - + if (gdb_active() && gdb_bp_x(PC)) + { Host_UpdateDisasmDialog(); gdb_signal(SIGTRAP); @@ -260,8 +261,10 @@ void Interpreter::Run() { // Write space if (j > 0) + { if (PCVec.at(j) != PCVec.at(j-1) + 4) NOTICE_LOG(POWERPC, ""); + } NOTICE_LOG(POWERPC, "PC: 0x%08x", PCVec.at(j)); } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp index b64ee65c71..33c653c191 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -9,6 +9,7 @@ void Interpreter::bx(UGeckoInstruction _inst) { if (_inst.LK) LR = PC + 4; + if (_inst.AA) NPC = SignExt26(_inst.LI << 2); else @@ -41,11 +42,13 @@ void Interpreter::bcx(UGeckoInstruction _inst) { if (_inst.LK) LR = PC + 4; + if (_inst.AA) NPC = SignExt16(_inst.BD << 2); else NPC = PC + SignExt16(_inst.BD << 2); } + m_EndBlock = true; } @@ -61,6 +64,7 @@ void Interpreter::bcctrx(UGeckoInstruction _inst) if (_inst.LK_3) LR = PC + 4; } + m_EndBlock = true; } @@ -78,6 +82,7 @@ void Interpreter::bclrx(UGeckoInstruction _inst) if (_inst.LK_3) LR = PC + 4; } + m_EndBlock = true; } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h index a506fc33bc..b98cad295e 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h @@ -43,7 +43,8 @@ const u64 PPC_NAN_U64 = 0x7ff8000000000000ull; const double PPC_NAN = *(double* const)&PPC_NAN_U64; // the 4 less-significand bits in FPSCR[FPRF] -enum FPCC { +enum FPCC +{ FL = 8, // < FG = 4, // > FE = 2, // = @@ -264,6 +265,7 @@ inline u64 ConvertToDouble(u32 _x) frac <<= 1; exp -= 1; } while ((frac & 0x00800000) == 0); + return ((x & 0x80000000) << 32) | (exp << 52) | ((frac & 0x007fffff) << 29); } else // QNaN, SNaN or Zero @@ -303,6 +305,7 @@ inline double ApproximateReciprocal(double val) double valf; s64 vali; }; + valf = val; s64 mantissa = vali & ((1LL << 52) - 1); s64 sign = vali & (1ULL << 63); @@ -312,6 +315,7 @@ inline double ApproximateReciprocal(double val) if (mantissa == 0 && exponent == 0) return sign ? -std::numeric_limits::infinity() : std::numeric_limits::infinity(); + // Special case NaN-ish numbers if (exponent == (0x7FFLL << 52)) { @@ -319,10 +323,12 @@ inline double ApproximateReciprocal(double val) return sign ? -0.0 : 0.0; return 0.0 + valf; } + // Special case small inputs if (exponent < (895LL << 52)) return sign ? -std::numeric_limits::max() : std::numeric_limits::max(); + // Special case large inputs if (exponent >= (1149LL << 52)) return sign ? -0.0f : 0.0f; @@ -379,10 +385,13 @@ inline double ApproximateReciprocalSquareRoot(double val) { if (sign) return std::numeric_limits::quiet_NaN(); + return 0.0; } + return 0.0 + valf; } + // Negative numbers return NaN if (sign) return std::numeric_limits::quiet_NaN(); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp index 906c1e297c..d3df8716f5 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp @@ -87,6 +87,7 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction _inst, double f SetFPException(FPSCR_VXSNAN); } } + FPSCR.FPRF = compareResult; SetCRField(_inst.CRFD, compareResult); } @@ -106,6 +107,7 @@ void Interpreter::fctiwx(UGeckoInstruction _inst) { const double b = rPS0(_inst.FB); u32 value; + if (b > (double)0x7fffffff) { value = 0x7fffffff; @@ -129,7 +131,11 @@ void Interpreter::fctiwx(UGeckoInstruction _inst) { double t = b + 0.5; i = (s32)t; - if (t - i < 0 || (t - i == 0 && b > 0)) i--; + + if (t - i < 0 || (t - i == 0 && b > 0)) + { + i--; + } break; } case 1: // zero @@ -137,11 +143,17 @@ void Interpreter::fctiwx(UGeckoInstruction _inst) break; case 2: // +inf i = (s32)b; - if (b - i > 0) i++; + if (b - i > 0) + { + i++; + } break; case 3: // -inf i = (s32)b; - if (b - i < 0) i--; + if (b - i < 0) + { + i--; + } break; } value = (u32)i; @@ -157,6 +169,7 @@ void Interpreter::fctiwx(UGeckoInstruction _inst) FPSCR.FR = fabs(di) > fabs(b); } } + // based on HW tests // FPRF is not affected riPS0(_inst.FD) = 0xfff8000000000000ull | value; @@ -171,6 +184,7 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst) { const double b = rPS0(_inst.FB); u32 value; + if (b > (double)0x7fffffff) { value = 0x7fffffff; @@ -201,6 +215,7 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst) } value = (u32)i; } + // based on HW tests // FPRF is not affected riPS0(_inst.FD) = 0xfff8000000000000ull | value; @@ -213,36 +228,46 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst) void Interpreter::fmrx(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB); + // This is a binary instruction. Does not alter FPSCR - if (_inst.Rc) Helper_UpdateCR1(); + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fabsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = fabs(rPS0(_inst.FB)); + // This is a binary instruction. Does not alter FPSCR - if (_inst.Rc) Helper_UpdateCR1(); + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fnabsx(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63); + // This is a binary instruction. Does not alter FPSCR - if (_inst.Rc) Helper_UpdateCR1(); + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fnegx(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63); + // This is a binary instruction. Does not alter FPSCR - if (_inst.Rc) Helper_UpdateCR1(); + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fselx(UGeckoInstruction _inst) { rPS0(_inst.FD) = (rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB); + // This is a binary instruction. Does not alter FPSCR - if (_inst.Rc) Helper_UpdateCR1(); + if (_inst.Rc) + Helper_UpdateCR1(); } // !!! warning !!! @@ -266,7 +291,9 @@ void Interpreter::fmulx(UGeckoInstruction _inst) FPSCR.FI = 0; // are these flags important? FPSCR.FR = 0; UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fmulsx(UGeckoInstruction _inst) { @@ -276,7 +303,9 @@ void Interpreter::fmulsx(UGeckoInstruction _inst) FPSCR.FI = 0; FPSCR.FR = 0; UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fmaddx(UGeckoInstruction _inst) @@ -284,7 +313,9 @@ void Interpreter::fmaddx(UGeckoInstruction _inst) double result = ForceDouble(NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) )); rPS0(_inst.FD) = result; UpdateFPRF(result); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fmaddsx(UGeckoInstruction _inst) @@ -294,7 +325,9 @@ void Interpreter::fmaddsx(UGeckoInstruction _inst) FPSCR.FI = d_value != rPS0(_inst.FD); FPSCR.FR = 0; UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } @@ -302,21 +335,32 @@ void Interpreter::faddx(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceDouble(NI_add(rPS0(_inst.FA), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::faddsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fdivx(UGeckoInstruction _inst) { double a = rPS0(_inst.FA); double b = rPS0(_inst.FB); - if (a != a) rPS0(_inst.FD) = a; - else if (b != b) rPS0(_inst.FD) = b; + + if (a != a) + { + rPS0(_inst.FD) = a; + } + else if (b != b) + { + rPS0(_inst.FD) = b; + } else { rPS0(_inst.FD) = ForceDouble(a / b); @@ -339,16 +383,25 @@ void Interpreter::fdivx(UGeckoInstruction _inst) } } UpdateFPRF(rPS0(_inst.FD)); + // FR,FI,OX,UX??? - if (_inst.Rc) Helper_UpdateCR1(); + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fdivsx(UGeckoInstruction _inst) { double a = rPS0(_inst.FA); double b = rPS0(_inst.FB); double res; - if (a != a) res = a; - else if (b != b) res = b; + + if (a != a) + { + res = a; + } + else if (b != b) + { + res = b; + } else { res = ForceSingle(a / b); @@ -370,9 +423,12 @@ void Interpreter::fdivsx(UGeckoInstruction _inst) } } } + rPS0(_inst.FD) = rPS1(_inst.FD) = res; UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } // Single precision only. @@ -380,17 +436,22 @@ void Interpreter::fresx(UGeckoInstruction _inst) { double b = rPS0(_inst.FB); rPS0(_inst.FD) = rPS1(_inst.FD) = ApproximateReciprocal(b); + if (b == 0.0) { SetFPException(FPSCR_ZX); } + UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::frsqrtex(UGeckoInstruction _inst) { double b = rPS0(_inst.FB); + if (b < 0.0) { SetFPException(FPSCR_VXSQRT); @@ -399,45 +460,59 @@ void Interpreter::frsqrtex(UGeckoInstruction _inst) { SetFPException(FPSCR_ZX); } + rPS0(_inst.FD) = ApproximateReciprocalSquareRoot(b); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fmsubx(UGeckoInstruction _inst) { - rPS0(_inst.FD) = ForceDouble(NI_msub( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) )); + rPS0(_inst.FD) = ForceDouble(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fmsubsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS1(_inst.FD) = - ForceSingle( NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) )); + ForceSingle(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fnmaddx(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceDouble(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } + void Interpreter::fnmaddsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fnmsubx(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceDouble(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } // fnmsubsx does not handle QNAN properly - see NI_msub @@ -446,21 +521,27 @@ void Interpreter::fnmsubsx(UGeckoInstruction _inst) rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fsubx(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceDouble(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fsubsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::fsqrtx(UGeckoInstruction _inst) @@ -468,10 +549,15 @@ void Interpreter::fsqrtx(UGeckoInstruction _inst) // GEKKO is not supposed to support this instruction. // PanicAlert("fsqrtx"); double b = rPS0(_inst.FB); - if (b < 0.0) { + + if (b < 0.0) + { FPSCR.VXSQRT = 1; } + rPS0(_inst.FD) = sqrt(b); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp index 0fa0f8f4a8..bac0ac1a18 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -95,10 +95,17 @@ void Interpreter::cmpli(UGeckoInstruction _inst) u32 a = m_GPR[_inst.RA]; u32 b = _inst.UIMM; int f; - if (a < b) f = 0x8; - else if (a > b) f = 0x4; - else f = 0x2; //equals - if (GetXER_SO()) f |= 0x1; + + if (a < b) + f = 0x8; + else if (a > b) + f = 0x4; + else + f = 0x2; //equals + + if (GetXER_SO()) + f |= 0x1; + SetCRField(_inst.CRFD, f); } @@ -170,14 +177,18 @@ void Interpreter::rlwimix(UGeckoInstruction _inst) { u32 mask = Helper_Mask(_inst.MB,_inst.ME); m_GPR[_inst.RA] = (m_GPR[_inst.RA] & ~mask) | (_rotl(m_GPR[_inst.RS],_inst.SH) & mask); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::rlwinmx(UGeckoInstruction _inst) { u32 mask = Helper_Mask(_inst.MB,_inst.ME); m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS],_inst.SH) & mask; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::rlwnmx(UGeckoInstruction _inst) @@ -185,21 +196,24 @@ void Interpreter::rlwnmx(UGeckoInstruction _inst) u32 mask = Helper_Mask(_inst.MB,_inst.ME); m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS], m_GPR[_inst.RB] & 0x1F) & mask; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::andx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] & m_GPR[_inst.RB]; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::andcx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] & ~m_GPR[_inst.RB]; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::cmp(UGeckoInstruction _inst) @@ -207,10 +221,16 @@ void Interpreter::cmp(UGeckoInstruction _inst) s32 a = (s32)m_GPR[_inst.RA]; s32 b = (s32)m_GPR[_inst.RB]; int fTemp = 0x8; // a < b - // if (a < b) fTemp = 0x8; else - if (a > b) fTemp = 0x4; - else if (a == b) fTemp = 0x2; - if (GetXER_SO()) PanicAlert("cmp getting overflow flag"); // fTemp |= 0x1 + + // if (a < b) fTemp = 0x8; else + if (a > b) + fTemp = 0x4; + else if (a == b) + fTemp = 0x2; + + if (GetXER_SO()) + PanicAlert("cmp getting overflow flag"); // fTemp |= 0x1 + SetCRField(_inst.CRFD, fTemp); } @@ -221,9 +241,14 @@ void Interpreter::cmpl(UGeckoInstruction _inst) u32 fTemp = 0x8; // a < b // if (a < b) fTemp = 0x8;else - if (a > b) fTemp = 0x4; - else if (a == b) fTemp = 0x2; - if (GetXER_SO()) PanicAlert("cmpl getting overflow flag"); // fTemp |= 0x1; + if (a > b) + fTemp = 0x4; + else if (a == b) + fTemp = 0x2; + + if (GetXER_SO()) + PanicAlert("cmpl getting overflow flag"); // fTemp |= 0x1; + SetCRField(_inst.CRFD, fTemp); } @@ -231,61 +256,74 @@ void Interpreter::cntlzwx(UGeckoInstruction _inst) { u32 val = m_GPR[_inst.RS]; u32 mask = 0x80000000; + int i = 0; for (; i < 32; i++, mask >>= 1) + { if (val & mask) break; + } + m_GPR[_inst.RA] = i; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::eqvx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] ^ m_GPR[_inst.RB]); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::extsbx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = (u32)(s32)(s8)m_GPR[_inst.RS]; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::extshx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = (u32)(s32)(s16)m_GPR[_inst.RS]; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::nandx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] & m_GPR[_inst.RB]); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::norx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] | m_GPR[_inst.RB]); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::orx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] | m_GPR[_inst.RB]; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::orcx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] | (~m_GPR[_inst.RB]); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::slwx(UGeckoInstruction _inst) @@ -293,12 +331,14 @@ void Interpreter::slwx(UGeckoInstruction _inst) u32 amount = m_GPR[_inst.RB]; m_GPR[_inst.RA] = (amount & 0x20) ? 0 : m_GPR[_inst.RS] << amount; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::srawx(UGeckoInstruction _inst) { int rb = m_GPR[_inst.RB]; + if (rb & 0x20) { if (m_GPR[_inst.RS] & 0x80000000) @@ -330,7 +370,8 @@ void Interpreter::srawx(UGeckoInstruction _inst) } } - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::srawix(UGeckoInstruction _inst) @@ -353,7 +394,8 @@ void Interpreter::srawix(UGeckoInstruction _inst) m_GPR[_inst.RA] = m_GPR[_inst.RS]; } - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::srwx(UGeckoInstruction _inst) @@ -361,7 +403,8 @@ void Interpreter::srwx(UGeckoInstruction _inst) u32 amount = m_GPR[_inst.RB]; m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> (amount & 0x1f)); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::tw(UGeckoInstruction _inst) @@ -388,15 +431,19 @@ void Interpreter::xorx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] ^ m_GPR[_inst.RB]; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RA]); } void Interpreter::addx(UGeckoInstruction _inst) { m_GPR[_inst.RD] = m_GPR[_inst.RA] + m_GPR[_inst.RB]; - if (_inst.OE) PanicAlert("OE: addx"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: addx"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::addcx(UGeckoInstruction _inst) @@ -406,8 +453,11 @@ void Interpreter::addcx(UGeckoInstruction _inst) m_GPR[_inst.RD] = a + b; SetCarry(Helper_Carry(a,b)); - if (_inst.OE) PanicAlert("OE: addcx"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: addcx"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::addex(UGeckoInstruction _inst) @@ -418,8 +468,11 @@ void Interpreter::addex(UGeckoInstruction _inst) m_GPR[_inst.RD] = a + b + carry; SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry))); - if (_inst.OE) PanicAlert("OE: addex"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: addex"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::addmex(UGeckoInstruction _inst) @@ -429,8 +482,11 @@ void Interpreter::addmex(UGeckoInstruction _inst) m_GPR[_inst.RD] = a + carry - 1; SetCarry(Helper_Carry(a, carry - 1)); - if (_inst.OE) PanicAlert("OE: addmex"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: addmex"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::addzex(UGeckoInstruction _inst) @@ -440,28 +496,38 @@ void Interpreter::addzex(UGeckoInstruction _inst) m_GPR[_inst.RD] = a + carry; SetCarry(Helper_Carry(a, carry)); - if (_inst.OE) PanicAlert("OE: addzex"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: addzex"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::divwx(UGeckoInstruction _inst) { s32 a = m_GPR[_inst.RA]; s32 b = m_GPR[_inst.RB]; + if (b == 0 || ((u32)a == 0x80000000 && b == -1)) { if (_inst.OE) + { // should set OV PanicAlert("OE: divwx"); + } + if (((u32)a & 0x80000000) && b == 0) m_GPR[_inst.RD] = -1; else m_GPR[_inst.RD] = 0; } else + { m_GPR[_inst.RD] = (u32)(a / b); + } - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } @@ -473,14 +539,20 @@ void Interpreter::divwux(UGeckoInstruction _inst) if (b == 0) { if (_inst.OE) + { // should set OV PanicAlert("OE: divwux"); + } + m_GPR[_inst.RD] = 0; } else + { m_GPR[_inst.RD] = a / b; + } - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::mulhwx(UGeckoInstruction _inst) @@ -489,7 +561,9 @@ void Interpreter::mulhwx(UGeckoInstruction _inst) u32 b = m_GPR[_inst.RB]; u32 d = (u32)((u64)(((s64)(s32)a * (s64)(s32)b) ) >> 32); // This can be done better. Not in plain C/C++ though. m_GPR[_inst.RD] = d; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::mulhwux(UGeckoInstruction _inst) @@ -498,7 +572,9 @@ void Interpreter::mulhwux(UGeckoInstruction _inst) u32 b = m_GPR[_inst.RB]; u32 d = (u32)(((u64)a * (u64)b) >> 32); m_GPR[_inst.RD] = d; - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::mullwx(UGeckoInstruction _inst) @@ -508,26 +584,36 @@ void Interpreter::mullwx(UGeckoInstruction _inst) u32 d = (u32)((s32)a * (s32)b); m_GPR[_inst.RD] = d; - if (_inst.OE) PanicAlert("OE: mullwx"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: mullwx"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::negx(UGeckoInstruction _inst) { m_GPR[_inst.RD] = (~m_GPR[_inst.RA]) + 1; + if (m_GPR[_inst.RD] == 0x80000000) { - if (_inst.OE) PanicAlert("OE: negx"); + if (_inst.OE) + PanicAlert("OE: negx"); } - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::subfx(UGeckoInstruction _inst) { m_GPR[_inst.RD] = m_GPR[_inst.RB] - m_GPR[_inst.RA]; - if (_inst.OE) PanicAlert("OE: subfx"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: subfx"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::subfcx(UGeckoInstruction _inst) @@ -537,8 +623,11 @@ void Interpreter::subfcx(UGeckoInstruction _inst) m_GPR[_inst.RD] = b - a; SetCarry(a == 0 || Helper_Carry(b, 0-a)); - if (_inst.OE) PanicAlert("OE: subfcx"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: subfcx"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } void Interpreter::subfex(UGeckoInstruction _inst) @@ -549,8 +638,11 @@ void Interpreter::subfex(UGeckoInstruction _inst) m_GPR[_inst.RD] = (~a) + b + carry; SetCarry(Helper_Carry(~a, b) || Helper_Carry((~a) + b, carry)); - if (_inst.OE) PanicAlert("OE: subfex"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: subfex"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } // sub from minus one @@ -561,8 +653,11 @@ void Interpreter::subfmex(UGeckoInstruction _inst) m_GPR[_inst.RD] = (~a) + carry - 1; SetCarry(Helper_Carry(~a, carry - 1)); - if (_inst.OE) PanicAlert("OE: subfmex"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: subfmex"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } // sub from zero @@ -573,6 +668,9 @@ void Interpreter::subfzex(UGeckoInstruction _inst) m_GPR[_inst.RD] = (~a) + carry; SetCarry(Helper_Carry(~a, carry)); - if (_inst.OE) PanicAlert("OE: subfzex"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); + if (_inst.OE) + PanicAlert("OE: subfzex"); + + if (_inst.Rc) + Helper_UpdateCR0(m_GPR[_inst.RD]); } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp index fcaa010f35..199b3661f3 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -788,9 +788,12 @@ void Interpreter::stwcxd(UGeckoInstruction _inst) { // Stores Word Conditional indeXed u32 uAddress; - if (g_bReserve) { + if (g_bReserve) + { uAddress = Helper_Get_EA_X(_inst); - if (uAddress == g_reserveAddr) { + + if (uAddress == g_reserveAddr) + { Memory::Write_U32(m_GPR[_inst.RS], uAddress); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp index 1539981655..7e506fbccd 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp @@ -142,13 +142,15 @@ void Interpreter::psq_l(UGeckoInstruction _inst) (m_GPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12; int c = 4; - if ((ldType == QUANTIZE_U8) || (ldType == QUANTIZE_S8)) c = 0x1; - if ((ldType == QUANTIZE_U16) || (ldType == QUANTIZE_S16)) c = 0x2; + if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8) + c = 0x1; + else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16) + c = 0x2; if (_inst.W == 0) { - float ps0 = Helper_Dequantize(EA, ldType, ldScale); - float ps1 = Helper_Dequantize(EA+c, ldType, ldScale); + float ps0 = Helper_Dequantize(EA, ldType, ldScale); + float ps1 = Helper_Dequantize(EA + c, ldType, ldScale); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { return; @@ -158,7 +160,7 @@ void Interpreter::psq_l(UGeckoInstruction _inst) } else { - float ps0 = Helper_Dequantize(EA, ldType, ldScale); + float ps0 = Helper_Dequantize(EA, ldType, ldScale); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { return; @@ -176,13 +178,15 @@ void Interpreter::psq_lu(UGeckoInstruction _inst) const u32 EA = m_GPR[_inst.RA] + _inst.SIMM_12; int c = 4; - if ((ldType == 4) || (ldType == 6)) c = 0x1; - if ((ldType == 5) || (ldType == 7)) c = 0x2; + if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8) + c = 0x1; + else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16) + c = 0x2; if (_inst.W == 0) { - float ps0 = Helper_Dequantize( EA, ldType, ldScale ); - float ps1 = Helper_Dequantize( EA+c, ldType, ldScale ); + float ps0 = Helper_Dequantize(EA, ldType, ldScale); + float ps1 = Helper_Dequantize(EA + c, ldType, ldScale); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { return; @@ -192,7 +196,7 @@ void Interpreter::psq_lu(UGeckoInstruction _inst) } else { - float ps0 = Helper_Dequantize( EA, ldType, ldScale ); + float ps0 = Helper_Dequantize(EA, ldType, ldScale); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { return; @@ -212,17 +216,19 @@ void Interpreter::psq_st(UGeckoInstruction _inst) (m_GPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12; int c = 4; - if ((stType == 4) || (stType == 6)) c = 0x1; - if ((stType == 5) || (stType == 7)) c = 0x2; + if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8) + c = 0x1; + else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16) + c = 0x2; if (_inst.W == 0) { - Helper_Quantize( EA, rPS0(_inst.RS), stType, stScale ); - Helper_Quantize( EA+c, rPS1(_inst.RS), stType, stScale ); + Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); + Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale); } else { - Helper_Quantize( EA, rPS0(_inst.RS), stType, stScale ); + Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); } } @@ -234,17 +240,19 @@ void Interpreter::psq_stu(UGeckoInstruction _inst) const u32 EA = m_GPR[_inst.RA] + _inst.SIMM_12; int c = 4; - if ((stType == 4) || (stType == 6)) c = 0x1; - if ((stType == 5) || (stType == 7)) c = 0x2; + if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8) + c = 0x1; + else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16) + c = 0x2; if (_inst.W == 0) { - Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); - Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale); + Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); + Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale); } else { - Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); + Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); } if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { @@ -261,13 +269,15 @@ void Interpreter::psq_lx(UGeckoInstruction _inst) const u32 EA = _inst.RA ? (m_GPR[_inst.RA] + m_GPR[_inst.RB]) : m_GPR[_inst.RB]; int c = 4; - if ((ldType == 4) || (ldType == 6)) c = 0x1; - if ((ldType == 5) || (ldType == 7)) c = 0x2; + if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8) + c = 0x1; + else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16) + c = 0x2; if (_inst.Wx == 0) { - float ps0 = Helper_Dequantize( EA, ldType, ldScale ); - float ps1 = Helper_Dequantize( EA+c, ldType, ldScale ); + float ps0 = Helper_Dequantize(EA, ldType, ldScale); + float ps1 = Helper_Dequantize(EA + c, ldType, ldScale); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { @@ -279,7 +289,7 @@ void Interpreter::psq_lx(UGeckoInstruction _inst) } else { - float ps0 = Helper_Dequantize( EA, ldType, ldScale ); + float ps0 = Helper_Dequantize(EA, ldType, ldScale); float ps1 = 1.0f; if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) @@ -300,17 +310,19 @@ void Interpreter::psq_stx(UGeckoInstruction _inst) const u32 EA = _inst.RA ? (m_GPR[_inst.RA] + m_GPR[_inst.RB]) : m_GPR[_inst.RB]; int c = 4; - if ((stType == 4) || (stType == 6)) c = 0x1; - if ((stType == 5) || (stType == 7)) c = 0x2; + if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8) + c = 0x1; + else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16) + c = 0x2; if (_inst.Wx == 0) { - Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); - Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale); + Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); + Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale); } else { - Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); + Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); } } @@ -322,13 +334,15 @@ void Interpreter::psq_lux(UGeckoInstruction _inst) const u32 EA = m_GPR[_inst.RA] + m_GPR[_inst.RB]; int c = 4; - if ((ldType == 4) || (ldType == 6)) c = 0x1; - if ((ldType == 5) || (ldType == 7)) c = 0x2; + if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8) + c = 0x1; + else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16) + c = 0x2; if (_inst.Wx == 0) { - float ps0 = Helper_Dequantize( EA, ldType, ldScale ); - float ps1 = Helper_Dequantize( EA+c, ldType, ldScale ); + float ps0 = Helper_Dequantize(EA, ldType, ldScale); + float ps1 = Helper_Dequantize(EA + c, ldType, ldScale); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { return; @@ -338,7 +352,7 @@ void Interpreter::psq_lux(UGeckoInstruction _inst) } else { - float ps0 = Helper_Dequantize( EA, ldType, ldScale ); + float ps0 = Helper_Dequantize(EA, ldType, ldScale); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { return; @@ -357,17 +371,19 @@ void Interpreter::psq_stux(UGeckoInstruction _inst) const u32 EA = m_GPR[_inst.RA] + m_GPR[_inst.RB]; int c = 4; - if ((stType == 4) || (stType == 6)) c = 0x1; - if ((stType == 5) || (stType == 7)) c = 0x2; + if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8) + c = 0x1; + else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16) + c = 0x2; if (_inst.Wx == 0) { - Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); - Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale); + Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); + Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale); } else { - Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); + Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale); } if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp index 2a0bcec6d9..bf47c351dc 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp @@ -15,35 +15,45 @@ void Interpreter::ps_sel(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS0(_inst.FA) >= -0.0 ? rPS0(_inst.FC) : rPS0(_inst.FB); rPS1(_inst.FD) = rPS1(_inst.FA) >= -0.0 ? rPS1(_inst.FC) : rPS1(_inst.FB); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_neg(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63); riPS1(_inst.FD) = riPS1(_inst.FB) ^ (1ULL << 63); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_mr(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS0(_inst.FB); rPS1(_inst.FD) = rPS1(_inst.FB); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_nabs(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63); riPS1(_inst.FD) = riPS1(_inst.FB) | (1ULL << 63); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_abs(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB) &~ (1ULL << 63); riPS1(_inst.FD) = riPS1(_inst.FB) &~ (1ULL << 63); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } // These are just moves, double is OK. @@ -53,7 +63,9 @@ void Interpreter::ps_merge00(UGeckoInstruction _inst) double p1 = rPS0(_inst.FB); rPS0(_inst.FD) = p0; rPS1(_inst.FD) = p1; - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_merge01(UGeckoInstruction _inst) @@ -62,7 +74,9 @@ void Interpreter::ps_merge01(UGeckoInstruction _inst) double p1 = rPS1(_inst.FB); rPS0(_inst.FD) = p0; rPS1(_inst.FD) = p1; - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_merge10(UGeckoInstruction _inst) @@ -71,7 +85,9 @@ void Interpreter::ps_merge10(UGeckoInstruction _inst) double p1 = rPS0(_inst.FB); rPS0(_inst.FD) = p0; rPS1(_inst.FD) = p1; - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_merge11(UGeckoInstruction _inst) @@ -80,7 +96,9 @@ void Interpreter::ps_merge11(UGeckoInstruction _inst) double p1 = rPS1(_inst.FB); rPS0(_inst.FD) = p0; rPS1(_inst.FD) = p1; - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } // From here on, the real deal. @@ -94,8 +112,14 @@ void Interpreter::ps_div(UGeckoInstruction _inst) double b = rPS0(_inst.FB); double &res = rPS0(_inst.FD); - if (a != a) res = a; - else if (b != b) res = b; + if (a != a) + { + res = a; + } + else if (b != b) + { + res = b; + } else { if (b == 0.0) @@ -132,8 +156,14 @@ void Interpreter::ps_div(UGeckoInstruction _inst) double b = rPS1(_inst.FB); double &res = rPS1(_inst.FD); - if (a != a) res = a; - else if (b != b) res = b; + if (a != a) + { + res = a; + } + else if (b != b) + { + res = b; + } else { if (b == 0.0) @@ -166,7 +196,9 @@ void Interpreter::ps_div(UGeckoInstruction _inst) SetFPException(ex_mask); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_res(UGeckoInstruction _inst) @@ -174,14 +206,18 @@ void Interpreter::ps_res(UGeckoInstruction _inst) // this code is based on the real hardware tests double a = rPS0(_inst.FB); double b = rPS1(_inst.FB); + if (a == 0.0 || b == 0.0) { SetFPException(FPSCR_ZX); } + rPS0(_inst.FD) = ApproximateReciprocal(a); rPS1(_inst.FD) = ApproximateReciprocal(b); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_rsqrte(UGeckoInstruction _inst) @@ -200,7 +236,9 @@ void Interpreter::ps_rsqrte(UGeckoInstruction _inst) rPS1(_inst.FD) = ForceSingle(ApproximateReciprocalSquareRoot(rPS1(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } @@ -209,7 +247,9 @@ void Interpreter::ps_sub(UGeckoInstruction _inst) rPS0(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB))); rPS1(_inst.FD) = ForceSingle(NI_sub(rPS1(_inst.FA), rPS1(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_add(UGeckoInstruction _inst) @@ -217,7 +257,9 @@ void Interpreter::ps_add(UGeckoInstruction _inst) rPS0(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB))); rPS1(_inst.FD) = ForceSingle(NI_add(rPS1(_inst.FA), rPS1(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_mul(UGeckoInstruction _inst) @@ -225,7 +267,9 @@ void Interpreter::ps_mul(UGeckoInstruction _inst) rPS0(_inst.FD) = ForceSingle(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC))); rPS1(_inst.FD) = ForceSingle(NI_mul(rPS1(_inst.FA), rPS1(_inst.FC))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } @@ -234,7 +278,9 @@ void Interpreter::ps_msub(UGeckoInstruction _inst) rPS0(_inst.FD) = ForceSingle(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); rPS1(_inst.FD) = ForceSingle(NI_msub(rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_madd(UGeckoInstruction _inst) @@ -242,7 +288,9 @@ void Interpreter::ps_madd(UGeckoInstruction _inst) rPS0(_inst.FD) = ForceSingle(NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); rPS1(_inst.FD) = ForceSingle(NI_madd(rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_nmsub(UGeckoInstruction _inst) @@ -250,7 +298,9 @@ void Interpreter::ps_nmsub(UGeckoInstruction _inst) rPS0(_inst.FD) = ForceSingle( -NI_msub( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ) ); rPS1(_inst.FD) = ForceSingle( -NI_msub( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) ); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_nmadd(UGeckoInstruction _inst) @@ -258,7 +308,9 @@ void Interpreter::ps_nmadd(UGeckoInstruction _inst) rPS0(_inst.FD) = ForceSingle( -NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ) ); rPS1(_inst.FD) = ForceSingle( -NI_madd( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) ); UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_sum0(UGeckoInstruction _inst) @@ -268,7 +320,9 @@ void Interpreter::ps_sum0(UGeckoInstruction _inst) rPS0(_inst.FD) = p0; rPS1(_inst.FD) = p1; UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_sum1(UGeckoInstruction _inst) @@ -278,7 +332,9 @@ void Interpreter::ps_sum1(UGeckoInstruction _inst) rPS0(_inst.FD) = p0; rPS1(_inst.FD) = p1; UpdateFPRF(rPS1(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_muls0(UGeckoInstruction _inst) @@ -288,7 +344,9 @@ void Interpreter::ps_muls0(UGeckoInstruction _inst) rPS0(_inst.FD) = p0; rPS1(_inst.FD) = p1; UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_muls1(UGeckoInstruction _inst) @@ -298,7 +356,9 @@ void Interpreter::ps_muls1(UGeckoInstruction _inst) rPS0(_inst.FD) = p0; rPS1(_inst.FD) = p1; UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_madds0(UGeckoInstruction _inst) @@ -308,7 +368,9 @@ void Interpreter::ps_madds0(UGeckoInstruction _inst) rPS0(_inst.FD) = p0; rPS1(_inst.FD) = p1; UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_madds1(UGeckoInstruction _inst) @@ -318,7 +380,9 @@ void Interpreter::ps_madds1(UGeckoInstruction _inst) rPS0(_inst.FD) = p0; rPS1(_inst.FD) = p1; UpdateFPRF(rPS0(_inst.FD)); - if (_inst.Rc) Helper_UpdateCR1(); + + if (_inst.Rc) + Helper_UpdateCR1(); } void Interpreter::ps_cmpu0(UGeckoInstruction _inst) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 933d50a608..466871399a 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -54,7 +54,8 @@ void Interpreter::mtfsb0x(UGeckoInstruction _inst) FPSCR.Hex &= ~b; FPSCRtoFPUSettings(FPSCR); - if (_inst.Rc) PanicAlert("mtfsb0x: inst_.Rc"); + if (_inst.Rc) + PanicAlert("mtfsb0x: inst_.Rc"); } void Interpreter::mtfsb1x(UGeckoInstruction _inst) @@ -67,7 +68,8 @@ void Interpreter::mtfsb1x(UGeckoInstruction _inst) FPSCR.Hex |= b; FPSCRtoFPUSettings(FPSCR); - if (_inst.Rc) PanicAlert("mtfsb1x: inst_.Rc"); + if (_inst.Rc) + PanicAlert("mtfsb1x: inst_.Rc"); } void Interpreter::mtfsfix(UGeckoInstruction _inst) @@ -83,7 +85,8 @@ void Interpreter::mtfsfix(UGeckoInstruction _inst) FPSCRtoFPUSettings(FPSCR); - if (_inst.Rc) PanicAlert("mtfsfix: inst_.Rc"); + if (_inst.Rc) + PanicAlert("mtfsfix: inst_.Rc"); } void Interpreter::mtfsfx(UGeckoInstruction _inst) @@ -103,7 +106,8 @@ void Interpreter::mtfsfx(UGeckoInstruction _inst) FPSCR.Hex = (FPSCR.Hex & ~m) | ((u32)(riPS0(_inst.FB)) & m); FPSCRtoFPUSettings(FPSCR); - if (_inst.Rc) PanicAlert("mtfsfx: inst_.Rc"); + if (_inst.Rc) + PanicAlert("mtfsfx: inst_.Rc"); } void Interpreter::mcrxr(UGeckoInstruction _inst) @@ -129,10 +133,12 @@ void Interpreter::mtcrf(UGeckoInstruction _inst) { //TODO: use lookup table? probably not worth it u32 mask = 0; - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 8; i++) + { if (crm & (1 << i)) mask |= 0xF << (i*4); } + SetCR((GetCR() & ~mask) | (m_GPR[_inst.RS] & mask)); } } @@ -165,7 +171,8 @@ void Interpreter::mtmsr(UGeckoInstruction _inst) // Segment registers. MMU control. -static void SetSR(int index, u32 value) { +static void SetSR(int index, u32 value) +{ DEBUG_LOG(POWERPC, "%08x: MMU: Segment register %i set to %08x", PowerPC::ppcState.pc, index, value); PowerPC::ppcState.sr[index] = value; } @@ -406,7 +413,8 @@ void Interpreter::mcrfs(UGeckoInstruction _inst) UpdateFPSCR(); u32 fpflags = ((FPSCR.Hex >> (4 * (7 - _inst.CRFS))) & 0xF); - switch (_inst.CRFS) { + switch (_inst.CRFS) + { case 0: FPSCR.FX = 0; FPSCR.OX = 0; @@ -443,5 +451,7 @@ void Interpreter::mffsx(UGeckoInstruction _inst) UpdateFPSCR(); riPS0(_inst.FD) = (u64)FPSCR.Hex; - if (_inst.Rc) PanicAlert("mffsx: inst_.Rc"); + + if (_inst.Rc) + PanicAlert("mffsx: inst_.Rc"); } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Tables.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Tables.cpp index 7f5118dae0..0422462e98 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Tables.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Tables.cpp @@ -488,7 +488,9 @@ void InitTables() m_allInstructions[m_numInstructions++] = &tpl.opinfo; for (auto& tpl : table63_2) m_allInstructions[m_numInstructions++] = &tpl.opinfo; - if (m_numInstructions >= 512) { + + if (m_numInstructions >= 512) + { PanicAlert("m_allInstructions underdimensioned"); }