From 745e4746fce6ec7e231216431478950c5d6763b9 Mon Sep 17 00:00:00 2001 From: GitHubProUser67 <127040195+GitHubProUser67@users.noreply.github.com> Date: Sat, 7 Dec 2024 22:38:10 +0100 Subject: [PATCH] [Soft-Float] - Improves the PS2Float class by using a raw float to speed-up simple calculations. This greatly improves performance while using Soft-Floats. --- pcsx2/FPU.cpp | 25 +++--- pcsx2/PS2Float.cpp | 198 +++++++++++++++++++-------------------------- pcsx2/PS2Float.h | 17 ++-- pcsx2/VUflags.cpp | 4 +- pcsx2/VUops.cpp | 42 +++++----- 5 files changed, 125 insertions(+), 161 deletions(-) diff --git a/pcsx2/FPU.cpp b/pcsx2/FPU.cpp index d4967dc4675c0..96b51f10c5ec0 100644 --- a/pcsx2/FPU.cpp +++ b/pcsx2/FPU.cpp @@ -146,16 +146,13 @@ bool checkDivideByZero(u32& xReg, u32 yDivisorReg, u32 zDividendReg, u32 cFlagsT _ContVal_ |= dividendZero ? cFlagsToSet2 : cFlagsToSet1; - bool IsSigned = yMatrix.Sign ^ zMatrix.Sign; + bool IsSigned = yMatrix.Sign() ^ zMatrix.Sign(); if (dividendZero) xReg = IsSigned ? PS2Float::MIN_FLOATING_POINT_VALUE : PS2Float::MAX_FLOATING_POINT_VALUE; else { - PS2Float zeroRes = PS2Float(0); - - zeroRes.Sign = IsSigned; - xReg = zeroRes.AsUInt32(); + xReg = PS2Float(IsSigned, 0, 0).raw; } return true; @@ -221,28 +218,28 @@ float fpuDouble(u32 f) static __fi u32 fpuAccurateAdd(u32 a, u32 b) { - if (CHECK_FPU_SOFT_ADDSUB) return PS2Float(a).Add(PS2Float(b)).AsUInt32(); + if (CHECK_FPU_SOFT_ADDSUB) return PS2Float(a).Add(PS2Float(b)).raw; return std::bit_cast(fpuDouble(a) + fpuDouble(b)); } static __fi u32 fpuAccurateSub(u32 a, u32 b) { - if (CHECK_FPU_SOFT_ADDSUB) return PS2Float(a).Sub(PS2Float(b)).AsUInt32(); + if (CHECK_FPU_SOFT_ADDSUB) return PS2Float(a).Sub(PS2Float(b)).raw; return std::bit_cast(fpuDouble(a) - fpuDouble(b)); } static __fi u32 fpuAccurateMul(u32 a, u32 b) { - if (CHECK_FPU_SOFT_MULDIV) return PS2Float(a).Mul(PS2Float(b)).AsUInt32(); + if (CHECK_FPU_SOFT_MULDIV) return PS2Float(a).Mul(PS2Float(b)).raw; return std::bit_cast(fpuDouble(a) * fpuDouble(b)); } static __fi u32 fpuAccurateDiv(u32 a, u32 b) { - if (CHECK_FPU_SOFT_MULDIV) return PS2Float(a).Div(PS2Float(b)).AsUInt32(); + if (CHECK_FPU_SOFT_MULDIV) return PS2Float(a).Div(PS2Float(b)).raw; return std::bit_cast(fpuDouble(a) / fpuDouble(b)); } @@ -472,17 +469,17 @@ void RSQRT_S() { if (value.IsDenormalized()) { _ContVal_ |= FPUflagD | FPUflagSD; - _FdValUl_ = value.Sign ? PS2Float::MIN_FLOATING_POINT_VALUE : PS2Float::MAX_FLOATING_POINT_VALUE; + _FdValUl_ = value.Sign() ? PS2Float::MIN_FLOATING_POINT_VALUE : PS2Float::MAX_FLOATING_POINT_VALUE; return; } else if (_FtValUl_ & 0x80000000) // Ft is negative { _ContVal_ |= FPUflagI | FPUflagSI; - _FdValUl_ = PS2Float(_FsValUl_).Rsqrt(PS2Float(value.Abs())).AsUInt32(); + _FdValUl_ = PS2Float(_FsValUl_).Rsqrt(PS2Float(value.Abs())).raw; } else // Ft is positive and not zero { - _FdValUl_ = PS2Float(_FsValUl_).Rsqrt(value).AsUInt32(); + _FdValUl_ = PS2Float(_FsValUl_).Rsqrt(value).raw; } } else @@ -519,10 +516,10 @@ void SQRT_S() { if (_FtValUl_ & 0x80000000) // If Ft is Negative { _ContVal_ |= FPUflagI | FPUflagSI; - _FdValUl_ = PS2Float(value.Abs()).Sqrt().AsUInt32(); + _FdValUl_ = PS2Float(value.Abs()).Sqrt().raw; } else - _FdValUl_ = value.Sqrt().AsUInt32(); // If Ft is Positive + _FdValUl_ = value.Sqrt().raw; // If Ft is Positive } else { diff --git a/pcsx2/PS2Float.cpp b/pcsx2/PS2Float.cpp index 9a9babeabfad7..955759c2e13c2 100644 --- a/pcsx2/PS2Float.cpp +++ b/pcsx2/PS2Float.cpp @@ -74,18 +74,14 @@ u64 PS2Float::MulMantissa(u32 a, u32 b) // Float Processor //**************************************************************** -PS2Float::PS2Float(u32 value) - : Sign((value >> 31) & 1) - , Exponent((u8)(((value >> 23) & 0xFF))) - , Mantissa(value & 0x7FFFFF) -{ -} +PS2Float::PS2Float(u32 value) { raw = value; } PS2Float::PS2Float(bool sign, u8 exponent, u32 mantissa) - : Sign(sign) - , Exponent(exponent) - , Mantissa(mantissa) { + raw = 0; + raw |= (sign ? 1u : 0u) << 31; + raw |= (u32)(exponent << 23); + raw |= mantissa; } PS2Float PS2Float::Max() @@ -108,15 +104,6 @@ PS2Float PS2Float::MinOne() return PS2Float(MIN_ONE); } -u32 PS2Float::AsUInt32() const -{ - u32 result = 0; - result |= (Sign ? 1u : 0u) << 31; - result |= (u32)(Exponent << 23); - result |= Mantissa; - return result; -} - PS2Float PS2Float::Add(PS2Float addend) { if (IsDenormalized() || addend.IsDenormalized()) @@ -125,8 +112,8 @@ PS2Float PS2Float::Add(PS2Float addend) if (IsAbnormal() && addend.IsAbnormal()) return SolveAbnormalAdditionOrSubtractionOperation(*this, addend, true); - u32 a = AsUInt32(); - u32 b = addend.AsUInt32(); + u32 a = raw; + u32 b = addend.raw; //exponent difference s32 exp_diff = ((a >> 23) & 0xFF) - ((b >> 23) & 0xFF); @@ -169,8 +156,8 @@ PS2Float PS2Float::Sub(PS2Float subtrahend) if (IsAbnormal() && subtrahend.IsAbnormal()) return SolveAbnormalAdditionOrSubtractionOperation(*this, subtrahend, false); - u32 a = AsUInt32(); - u32 b = subtrahend.AsUInt32(); + u32 a = raw; + u32 b = subtrahend.raw; //exponent difference s32 exp_diff = ((a >> 23) & 0xFF) - ((b >> 23) & 0xFF); @@ -203,7 +190,7 @@ PS2Float PS2Float::Sub(PS2Float subtrahend) } - return PS2Float(a).DoAdd(Neg(PS2Float(b))); + return PS2Float(a).DoAdd(PS2Float(b).Negate()); } PS2Float PS2Float::Mul(PS2Float mulend) @@ -215,12 +202,7 @@ PS2Float PS2Float::Mul(PS2Float mulend) return SolveAbnormalMultiplicationOrDivisionOperation(*this, mulend, true); if (IsZero() || mulend.IsZero()) - { - PS2Float result = PS2Float(0); - - result.Sign = DetermineMultiplicationDivisionOperationSign(*this, mulend); - return result; - } + return PS2Float(DetermineMultiplicationDivisionOperationSign(*this, mulend), 0, 0); return DoMul(mulend); } @@ -234,12 +216,7 @@ PS2Float PS2Float::Div(PS2Float divend) return SolveAbnormalMultiplicationOrDivisionOperation(*this, divend, false); if (IsZero()) - { - PS2Float result = PS2Float(0); - - result.Sign = DetermineMultiplicationDivisionOperationSign(*this, divend); - return result; - } + return PS2Float(DetermineMultiplicationDivisionOperationSign(*this, divend), 0, 0); else if (divend.IsZero()) return DetermineMultiplicationDivisionOperationSign(*this, divend) ? Min() : Max(); @@ -258,7 +235,7 @@ PS2Float PS2Float::Sqrt() return PS2Float(0); // PS2 only takes positive numbers for SQRT, and convert if necessary. - s32 ix = (s32)(PS2Float(false, Exponent, Mantissa).AsUInt32()); + s32 ix = (s32)PS2Float(false, Exponent(), Mantissa()).raw; /* extract mantissa and unbias exponent */ s32 m = (ix >> 23) - BIAS; @@ -308,39 +285,44 @@ PS2Float PS2Float::Rsqrt(PS2Float other) bool PS2Float::IsDenormalized() { - return Exponent == 0; + return Exponent() == 0; } bool PS2Float::IsAbnormal() { - u32 val = AsUInt32(); + u32 val = raw; return val == MAX_FLOATING_POINT_VALUE || val == MIN_FLOATING_POINT_VALUE || val == POSITIVE_INFINITY_VALUE || val == NEGATIVE_INFINITY_VALUE; } bool PS2Float::IsZero() { - return (Abs()) == 0; + return Abs() == 0; } u32 PS2Float::Abs() { - return (AsUInt32() & MAX_FLOATING_POINT_VALUE); + return (raw & MAX_FLOATING_POINT_VALUE); +} + +PS2Float PS2Float::Negate() +{ + return PS2Float(raw ^ 0x80000000); } PS2Float PS2Float::RoundTowardsZero() { - return PS2Float((u32)(std::trunc((double)(AsUInt32())))); + return PS2Float((u32)std::trunc((double)raw)); } s32 PS2Float::CompareTo(PS2Float other) { - s32 selfTwoComplementVal = (s32)(Abs()); - if (Sign) + s32 selfTwoComplementVal = (s32)Abs(); + if (Sign()) selfTwoComplementVal = -selfTwoComplementVal; - s32 otherTwoComplementVal = (s32)(other.Abs()); - if (other.Sign) + s32 otherTwoComplementVal = (s32)other.Abs(); + if (other.Sign()) otherTwoComplementVal = -otherTwoComplementVal; if (selfTwoComplementVal < otherTwoComplementVal) @@ -353,8 +335,8 @@ s32 PS2Float::CompareTo(PS2Float other) s32 PS2Float::CompareOperand(PS2Float other) { - s32 selfTwoComplementVal = (s32)(Abs()); - s32 otherTwoComplementVal = (s32)(other.Abs()); + s32 selfTwoComplementVal = (s32)Abs(); + s32 otherTwoComplementVal = (s32)other.Abs(); if (selfTwoComplementVal < otherTwoComplementVal) return -1; @@ -366,14 +348,14 @@ s32 PS2Float::CompareOperand(PS2Float other) double PS2Float::ToDouble() { - return std::bit_cast(((u64)Sign << 63) | ((((u64)Exponent - BIAS) + 1023ULL) << 52) | ((u64)Mantissa << 29)); + return std::bit_cast(((u64)Sign() << 63) | ((((u64)Exponent() - BIAS) + 1023ULL) << 52) | ((u64)Mantissa() << 29)); } std::string PS2Float::ToString() { double res = ToDouble(); - u32 value = AsUInt32(); + u32 value = raw; std::ostringstream oss; oss << std::fixed << std::setprecision(6); @@ -409,8 +391,8 @@ PS2Float PS2Float::DoAdd(PS2Float other) { const u8 roundingMultiplier = 6; - u8 selfExponent = Exponent; - s32 resExponent = selfExponent - other.Exponent; + u8 selfExponent = Exponent(); + s32 resExponent = selfExponent - other.Exponent(); if (resExponent < 0) return other.DoAdd(*this); @@ -418,10 +400,10 @@ PS2Float PS2Float::DoAdd(PS2Float other) return *this; // http://graphics.stanford.edu/~seander/bithacks.html#ConditionalNegate - u32 sign1 = (u32)((s32)AsUInt32() >> 31); - s32 selfMantissa = (s32)(((Mantissa | 0x800000) ^ sign1) - sign1); - u32 sign2 = (u32)((s32)other.AsUInt32() >> 31); - s32 otherMantissa = (s32)(((other.Mantissa | 0x800000) ^ sign2) - sign2); + u32 sign1 = (u32)((s32)raw >> 31); + s32 selfMantissa = (s32)(((Mantissa() | 0x800000) ^ sign1) - sign1); + u32 sign2 = (u32)((s32)other.raw >> 31); + s32 otherMantissa = (s32)(((other.Mantissa() | 0x800000) ^ sign2) - sign2); // PS2 multiply by 2 before doing the Math here. s32 man = (selfMantissa << roundingMultiplier) + ((otherMantissa << roundingMultiplier) >> resExponent); @@ -450,11 +432,11 @@ PS2Float PS2Float::DoAdd(PS2Float other) PS2Float PS2Float::DoMul(PS2Float other) { - u8 selfExponent = Exponent; - u8 otherExponent = other.Exponent; - u32 selfMantissa = Mantissa | 0x800000; - u32 otherMantissa = other.Mantissa | 0x800000; - u32 sign = (AsUInt32() ^ other.AsUInt32()) & SIGNMASK; + u8 selfExponent = Exponent(); + u8 otherExponent = other.Exponent(); + u32 selfMantissa = Mantissa() | 0x800000; + u32 otherMantissa = other.Mantissa() | 0x800000; + u32 sign = (raw ^ other.raw) & SIGNMASK; s32 resExponent = selfExponent + otherExponent - 127; u32 resMantissa = (u32)(MulMantissa(selfMantissa, otherMantissa) >> 23); @@ -476,25 +458,22 @@ PS2Float PS2Float::DoMul(PS2Float other) // Rounding can be slightly off: (PS2: 0x3F800000 / 0x3F800001 = 0x3F7FFFFF | SoftFloat/IEEE754: 0x3F800000 / 0x3F800001 = 0x3F7FFFFE). PS2Float PS2Float::DoDiv(PS2Float other) { + bool sign = DetermineMultiplicationDivisionOperationSign(*this, other); + u32 selfMantissa = Mantissa() | 0x800000; + u32 otherMantissa = other.Mantissa() | 0x800000; + s32 resExponent = Exponent() - other.Exponent() + BIAS; u64 selfMantissa64; - u32 selfMantissa = Mantissa | 0x800000; - u32 otherMantissa = other.Mantissa | 0x800000; - s32 resExponent = Exponent - other.Exponent + BIAS; - - PS2Float result = PS2Float(0); - - result.Sign = DetermineMultiplicationDivisionOperationSign(*this, other); if (resExponent > 255) - return result.Sign ? Min() : Max(); + return sign ? Min() : Max(); else if (resExponent <= 0) - return PS2Float(result.Sign, 0, 0); + return PS2Float(sign, 0, 0); if (selfMantissa < otherMantissa) { --resExponent; if (resExponent == 0) - return PS2Float(result.Sign, 0, 0); + return PS2Float(sign, 0, 0); selfMantissa64 = (u64)(selfMantissa) << 31; } else @@ -503,55 +482,55 @@ PS2Float PS2Float::DoDiv(PS2Float other) } u32 resMantissa = (u32)(selfMantissa64 / otherMantissa); + if ((resMantissa & 0x3F) == 0) resMantissa |= ((u64)(otherMantissa)*resMantissa != selfMantissa64) ? 1U : 0; - result.Exponent = (u8)(resExponent); - result.Mantissa = (resMantissa + 0x40U) >> 7; + resMantissa = (resMantissa + 0x40U) >> 7; - if (result.Mantissa > 0) + if (resMantissa > 0) { - s32 leadingBitPosition = PS2Float::GetMostSignificantBitPosition(result.Mantissa); + s32 leadingBitPosition = PS2Float::GetMostSignificantBitPosition(resMantissa); while (leadingBitPosition != IMPLICIT_LEADING_BIT_POS) { if (leadingBitPosition > IMPLICIT_LEADING_BIT_POS) { - result.Mantissa >>= 1; + resMantissa >>= 1; - s32 exp = ((s32)result.Exponent + 1); + s32 exp = resExponent + 1; if (exp > 255) - return result.Sign ? Min() : Max(); + return sign ? Min() : Max(); - result.Exponent = (u8)exp; + resExponent = exp; leadingBitPosition--; } else if (leadingBitPosition < IMPLICIT_LEADING_BIT_POS) { - result.Mantissa <<= 1; + resMantissa <<= 1; - s32 exp = ((s32)result.Exponent - 1); + s32 exp = resExponent - 1; if (exp <= 0) - return PS2Float(result.Sign, 0, 0); + return PS2Float(sign, 0, 0); - result.Exponent = (u8)exp; + resExponent = exp; leadingBitPosition++; } } } - result.Mantissa &= 0x7FFFFF; - return result.RoundTowardsZero(); + resMantissa &= 0x7FFFFF; + return PS2Float(sign, (u8)resExponent, resMantissa).RoundTowardsZero(); } PS2Float PS2Float::SolveAbnormalAdditionOrSubtractionOperation(PS2Float a, PS2Float b, bool add) { - u32 aval = a.AsUInt32(); - u32 bval = b.AsUInt32(); + u32 aval = a.raw; + u32 bval = b.raw; if (aval == MAX_FLOATING_POINT_VALUE && bval == MAX_FLOATING_POINT_VALUE) return add ? Max() : PS2Float(0); @@ -608,8 +587,8 @@ PS2Float PS2Float::SolveAbnormalAdditionOrSubtractionOperation(PS2Float a, PS2Fl PS2Float PS2Float::SolveAbnormalMultiplicationOrDivisionOperation(PS2Float a, PS2Float b, bool mul) { - u32 aval = a.AsUInt32(); - u32 bval = b.AsUInt32(); + u32 aval = a.raw; + u32 bval = b.raw; if (mul) { @@ -711,38 +690,31 @@ PS2Float PS2Float::SolveAbnormalMultiplicationOrDivisionOperation(PS2Float a, PS PS2Float PS2Float::SolveAddSubDenormalizedOperation(PS2Float a, PS2Float b, bool add) { - PS2Float result = PS2Float(0); + bool sign = add ? DetermineAdditionOperationSign(a, b) : DetermineSubtractionOperationSign(a, b); if (a.IsDenormalized() && !b.IsDenormalized()) - result = b; + return PS2Float(sign, b.Exponent(), b.Mantissa()); else if (!a.IsDenormalized() && b.IsDenormalized()) - result = a; + return PS2Float(sign, a.Exponent(), a.Mantissa()); else if (a.IsDenormalized() && b.IsDenormalized()) - { - } + return PS2Float(sign, 0, 0); else Console.Error("Both numbers are not denormalized"); - result.Sign = add ? DetermineAdditionOperationSign(a, b) : DetermineSubtractionOperationSign(a, b); - return result; + return PS2Float(0); } PS2Float PS2Float::SolveMultiplicationDenormalizedOperation(PS2Float a, PS2Float b) { - PS2Float result = PS2Float(0); - - result.Sign = DetermineMultiplicationDivisionOperationSign(a, b); - return result; + return PS2Float(DetermineMultiplicationDivisionOperationSign(a, b), 0, 0); } PS2Float PS2Float::SolveDivisionDenormalizedOperation(PS2Float a, PS2Float b) { bool sign = DetermineMultiplicationDivisionOperationSign(a, b); - PS2Float result = PS2Float(0); if (a.IsDenormalized() && !b.IsDenormalized()) - { - } + return PS2Float(sign, 0, 0); else if (!a.IsDenormalized() && b.IsDenormalized()) return sign ? Min() : Max(); else if (a.IsDenormalized() && b.IsDenormalized()) @@ -750,48 +722,42 @@ PS2Float PS2Float::SolveDivisionDenormalizedOperation(PS2Float a, PS2Float b) else Console.Error("Both numbers are not denormalized"); - result.Sign = sign; - return result; -} - -PS2Float PS2Float::Neg(PS2Float self) -{ - return PS2Float(self.AsUInt32() ^ SIGNMASK); + return PS2Float(0); } bool PS2Float::DetermineMultiplicationDivisionOperationSign(PS2Float a, PS2Float b) { - return a.Sign ^ b.Sign; + return a.Sign() ^ b.Sign(); } bool PS2Float::DetermineAdditionOperationSign(PS2Float a, PS2Float b) { if (a.IsZero() && b.IsZero()) { - if (!a.Sign || !b.Sign) + if (!a.Sign() || !b.Sign()) return false; - else if (a.Sign && b.Sign) + else if (a.Sign() && b.Sign()) return true; else Console.Error("Unhandled addition operation flags"); } - return a.CompareOperand(b) >= 0 ? a.Sign : b.Sign; + return a.CompareOperand(b) >= 0 ? a.Sign() : b.Sign(); } bool PS2Float::DetermineSubtractionOperationSign(PS2Float a, PS2Float b) { if (a.IsZero() && b.IsZero()) { - if (!a.Sign || b.Sign) + if (!a.Sign() || b.Sign()) return false; - else if (a.Sign && !b.Sign) + else if (a.Sign() && !b.Sign()) return true; else Console.Error("Unhandled subtraction operation flags"); } - return a.CompareOperand(b) >= 0 ? a.Sign : !b.Sign; + return a.CompareOperand(b) >= 0 ? a.Sign() : !b.Sign(); } s32 PS2Float::clz(s32 x) diff --git a/pcsx2/PS2Float.h b/pcsx2/PS2Float.h index 341bc10b56c0e..89c0b94969080 100644 --- a/pcsx2/PS2Float.h +++ b/pcsx2/PS2Float.h @@ -26,10 +26,7 @@ class PS2Float static AddResult Add3(u32 a, u32 b, u32 c); public: - bool Sign; - u8 Exponent; - u32 Mantissa; - + static constexpr u8 BIAS = 127; static constexpr u32 SIGNMASK = 0x80000000; static constexpr u32 MAX_FLOATING_POINT_VALUE = 0x7FFFFFFF; @@ -62,6 +59,12 @@ class PS2Float 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24 }; + u32 raw; + + constexpr u32 Mantissa() const { return raw & 0x7FFFFF; } + constexpr u8 Exponent() const { return (raw >> 23) & 0xFF; } + constexpr bool Sign() const { return ((raw >> 31) & 1) != 0; } + PS2Float(u32 value); PS2Float(bool sign, u8 exponent, u32 mantissa); @@ -74,10 +77,6 @@ class PS2Float static PS2Float MinOne(); - static PS2Float Neg(PS2Float self); - - u32 AsUInt32() const; - PS2Float Add(PS2Float addend); PS2Float Sub(PS2Float subtrahend); @@ -98,6 +97,8 @@ class PS2Float u32 Abs(); + PS2Float Negate(); + PS2Float RoundTowardsZero(); s32 CompareTo(PS2Float other); diff --git a/pcsx2/VUflags.cpp b/pcsx2/VUflags.cpp index d3422c2587998..4640fcf4054cc 100644 --- a/pcsx2/VUflags.cpp +++ b/pcsx2/VUflags.cpp @@ -16,8 +16,8 @@ static __ri u32 VU_MAC_UPDATE(int shift, VURegs* VU, u32 f) { PS2Float ps2f = PS2Float(f); - u32 exp = ps2f.Exponent; - u32 s = ps2f.AsUInt32() & PS2Float::SIGNMASK; + u32 exp = ps2f.Exponent(); + u32 s = ps2f.raw & PS2Float::SIGNMASK; if (s) VU->macflag |= 0x0010<(vuDouble(a) + vuDouble(b)); } static __fi u32 vuAccurateSub(VURegs* VU, u32 a, u32 b) { - if (CHECK_VU_SOFT_ADDSUB((VU == &VU1) ? 1 : 0)) return PS2Float(a).Sub(PS2Float(b)).AsUInt32(); + if (CHECK_VU_SOFT_ADDSUB((VU == &VU1) ? 1 : 0)) return PS2Float(a).Sub(PS2Float(b)).raw; return std::bit_cast(vuDouble(a) - vuDouble(b)); } static __fi u32 vuAccurateMul(VURegs* VU, u32 a, u32 b) { - if (CHECK_VU_SOFT_MULDIV((VU == &VU1) ? 1 : 0)) return PS2Float(a).Mul(PS2Float(b)).AsUInt32(); + if (CHECK_VU_SOFT_MULDIV((VU == &VU1) ? 1 : 0)) return PS2Float(a).Mul(PS2Float(b)).raw; return std::bit_cast(vuDouble(a) * vuDouble(b)); } static __fi u32 vuAccurateDiv(VURegs* VU, u32 a, u32 b) { - if (CHECK_VU_SOFT_MULDIV((VU == &VU1) ? 1 : 0)) return PS2Float(a).Div(PS2Float(b)).AsUInt32(); + if (CHECK_VU_SOFT_MULDIV((VU == &VU1) ? 1 : 0)) return PS2Float(a).Div(PS2Float(b)).raw; return std::bit_cast(vuDouble(a) / vuDouble(b)); } @@ -1778,7 +1778,7 @@ static __fi void _vuDIV(VURegs* VU) } else { - VU->q.UL = fs.Div(ft).AsUInt32(); + VU->q.UL = fs.Div(ft).raw; } } else @@ -1819,7 +1819,7 @@ static __fi void _vuSQRT(VURegs* VU) if (ft.ToDouble() < 0.0) VU->statusflag |= 0x10; - VU->q.UL = PS2Float(ft.Abs()).Sqrt().AsUInt32(); + VU->q.UL = PS2Float(ft.Abs()).Sqrt().raw; } else { @@ -1874,11 +1874,11 @@ static __fi void _vuRSQRT(VURegs* VU) } if (CHECK_VU_SOFT_MULDIV((VU == &VU1) ? 1 : 0)) - VU->q.UL = fs.Div(PS2Float(ft.Abs()).Sqrt()).AsUInt32(); + VU->q.UL = fs.Div(PS2Float(ft.Abs()).Sqrt()).raw; else { - float temp = sqrt(fabs(vuDouble(ft.AsUInt32()))); - VU->q.F = vuDouble(fs.AsUInt32()) / temp; + float temp = sqrt(fabs(vuDouble(ft.raw))); + VU->q.F = vuDouble(fs.raw) / temp; VU->q.F = vuDouble(VU->q.UL); } } @@ -2589,12 +2589,12 @@ static __ri void _vuERSADD(VURegs* VU) p = PS2Float::One().Div(p); else { - VU->p.F = 1.0f / vuDouble(p.AsUInt32()); + VU->p.F = 1.0f / vuDouble(p.raw); return; } } - VU->p.UL = p.AsUInt32(); + VU->p.UL = p.raw; } static __ri void _vuELENG(VURegs* VU) @@ -2611,11 +2611,11 @@ static __ri void _vuELENG(VURegs* VU) { value = value.Sqrt(); } - VU->p.UL = value.AsUInt32(); + VU->p.UL = value.raw; } else { - float p = vuDouble(value.AsUInt32()); + float p = vuDouble(value.raw); if (p >= 0) { @@ -2646,16 +2646,16 @@ static __ri void _vuERLENG(VURegs* VU) } else { - VU->p.F = 1.0 / vuDouble(value.AsUInt32()); + VU->p.F = 1.0 / vuDouble(value.raw); return; } } } - VU->p.UL = value.AsUInt32(); + VU->p.UL = value.raw; } else { - float p = vuDouble(value.AsUInt32()); + float p = vuDouble(value.raw); if (p >= 0) { @@ -2731,12 +2731,12 @@ static __ri void _vuERCPR(VURegs* VU) } else { - VU->p.F = 1.0 / vuDouble(p.AsUInt32()); + VU->p.F = 1.0 / vuDouble(p.raw); return; } } - VU->p.UL = p.AsUInt32(); + VU->p.UL = p.raw; } static __ri void _vuESQRT(VURegs* VU) @@ -2750,7 +2750,7 @@ static __ri void _vuESQRT(VURegs* VU) value = value.Sqrt(); } - VU->p.UL = value.AsUInt32(); + VU->p.UL = value.raw; } else { @@ -2778,7 +2778,7 @@ static __ri void _vuERSQRT(VURegs* VU) { if (CHECK_VU_SOFT_MULDIV((VU == &VU1) ? 1 : 0)) { - VU->p.F = 1.0f / vuDouble(value.AsUInt32()); + VU->p.F = 1.0f / vuDouble(value.raw); return; } else @@ -2788,7 +2788,7 @@ static __ri void _vuERSQRT(VURegs* VU) } } - VU->p.UL = value.AsUInt32(); + VU->p.UL = value.raw; } else {