[Soft-Float] - Code review Part1.

Applies some recommendations from the review.

The next batch will come later.
This commit is contained in:
GitHubProUser67 2024-11-23 15:35:44 +01:00
parent b0b65fa248
commit 8bc2ed9282
5 changed files with 429 additions and 506 deletions

View File

@ -33,7 +33,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>-447</y> <y>-447</y>
<width>793</width> <width>790</width>
<height>1283</height> <height>1283</height>
</rect> </rect>
</property> </property>

View File

@ -219,36 +219,32 @@ float fpuDouble(u32 f)
} }
} }
static __fi u32 fpuAccurateAddSub(u32 a, u32 b, bool issub) static __fi u32 fpuAccurateAdd(u32 a, u32 b)
{ {
if (CHECK_FPU_SOFT_ADDSUB) if (CHECK_FPU_SOFT_ADDSUB) return PS2Float(a).Add(PS2Float(b)).AsUInt32();
{
if (issub) return std::bit_cast<u32>(fpuDouble(a) + fpuDouble(b));
return PS2Float(a).Sub(PS2Float(b)).AsUInt32();
else
return PS2Float(a).Add(PS2Float(b)).AsUInt32();
}
if (issub)
return std::bit_cast<u32>(fpuDouble(a) - fpuDouble(b));
else
return std::bit_cast<u32>(fpuDouble(a) + fpuDouble(b));
} }
static __fi u32 fpuAccurateMulDiv(u32 a, u32 b, bool isdiv) static __fi u32 fpuAccurateSub(u32 a, u32 b)
{ {
if (CHECK_FPU_SOFT_MULDIV) if (CHECK_FPU_SOFT_ADDSUB) return PS2Float(a).Sub(PS2Float(b)).AsUInt32();
{
if (isdiv)
return PS2Float(a).Div(PS2Float(b)).AsUInt32();
else
return PS2Float(a).Mul(PS2Float(b)).AsUInt32();
}
if (isdiv) return std::bit_cast<u32>(fpuDouble(a) - fpuDouble(b));
return std::bit_cast<u32>(fpuDouble(a) / fpuDouble(b)); }
else
return std::bit_cast<u32>(fpuDouble(a) * fpuDouble(b)); static __fi u32 fpuAccurateMul(u32 a, u32 b)
{
if (CHECK_FPU_SOFT_MULDIV) return PS2Float(a).Mul(PS2Float(b)).AsUInt32();
return std::bit_cast<u32>(fpuDouble(a) * fpuDouble(b));
}
static __fi u32 fpuAccurateDiv(u32 a, u32 b)
{
if (CHECK_FPU_SOFT_MULDIV) return PS2Float(a).Div(PS2Float(b)).AsUInt32();
return std::bit_cast<u32>(fpuDouble(a) / fpuDouble(b));
} }
static __fi s32 double_to_int(double value) static __fi s32 double_to_int(double value)
@ -304,13 +300,13 @@ void ABS_S() {
} }
void ADD_S() { void ADD_S() {
_FdValUl_ = fpuAccurateAddSub(_FsValUl_, _FtValUl_, 0); _FdValUl_ = fpuAccurateAdd(_FsValUl_, _FtValUl_);
if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return; if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return;
checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU); checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU);
} }
void ADDA_S() { void ADDA_S() {
_FAValUl_ = fpuAccurateAddSub(_FsValUl_, _FtValUl_, 0); _FAValUl_ = fpuAccurateAdd(_FsValUl_, _FtValUl_);
if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return; if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return;
checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU); checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU);
} }
@ -392,7 +388,7 @@ void CVT_W() {
void DIV_S() { void DIV_S() {
if (checkDivideByZero( _FdValUl_, _FtValUl_, _FsValUl_, FPUflagD | FPUflagSD, FPUflagI | FPUflagSI)) return; if (checkDivideByZero( _FdValUl_, _FtValUl_, _FsValUl_, FPUflagD | FPUflagSD, FPUflagI | FPUflagSI)) return;
_FdValUl_ = fpuAccurateMulDiv(_FsValUl_, _FtValUl_, 1); _FdValUl_ = fpuAccurateDiv(_FsValUl_, _FtValUl_);
if (checkOverflow( _FdValUl_, 0)) return; if (checkOverflow( _FdValUl_, 0)) return;
checkUnderflow( _FdValUl_, 0); checkUnderflow( _FdValUl_, 0);
} }
@ -402,17 +398,13 @@ void DIV_S() {
method provides a similar outcome and is faster. (cottonvibes) method provides a similar outcome and is faster. (cottonvibes)
*/ */
void MADD_S() { void MADD_S() {
FPRreg temp; _FdValUl_ = fpuAccurateAdd(_FAValUl_, fpuAccurateMul(_FsValUl_, _FtValUl_));
temp.UL = fpuAccurateMulDiv(_FsValUl_, _FtValUl_, 0);
_FdValUl_ = fpuAccurateAddSub(_FAValUl_, temp.UL, 0);
if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return; if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return;
checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU); checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU);
} }
void MADDA_S() { void MADDA_S() {
FPRreg temp; _FAValUl_ = fpuAccurateAdd(_FAValUl_, fpuAccurateMul(_FsValUl_, _FtValUl_));
temp.UL = fpuAccurateMulDiv(_FsValUl_, _FtValUl_, 0);
_FAValUl_ = fpuAccurateAddSub(_FAValUl_, temp.UL, 0);
if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return; if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return;
checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU); checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU);
} }
@ -437,17 +429,13 @@ void MOV_S() {
} }
void MSUB_S() { void MSUB_S() {
FPRreg temp; _FdValUl_ = fpuAccurateSub(_FAValUl_, fpuAccurateMul(_FsValUl_, _FtValUl_));
temp.UL = fpuAccurateMulDiv(_FsValUl_, _FtValUl_, 0);
_FdValUl_ = fpuAccurateAddSub(_FAValUl_, temp.UL, 1);
if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return; if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return;
checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU); checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU);
} }
void MSUBA_S() { void MSUBA_S() {
FPRreg temp; _FAValUl_ = fpuAccurateSub(_FAValUl_, fpuAccurateMul(_FsValUl_, _FtValUl_));
temp.UL = fpuAccurateMulDiv(_FsValUl_, _FtValUl_, 0);
_FAValUl_ = fpuAccurateAddSub(_FAValUl_, temp.UL, 1);
if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return; if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return;
checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU); checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU);
} }
@ -457,13 +445,13 @@ void MTC1() {
} }
void MUL_S() { void MUL_S() {
_FdValUl_ = fpuAccurateMulDiv(_FsValUl_, _FtValUl_, 0); _FdValUl_ = fpuAccurateMul(_FsValUl_, _FtValUl_);
if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return; if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return;
checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU); checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU);
} }
void MULA_S() { void MULA_S() {
_FAValUl_ = fpuAccurateMulDiv(_FsValUl_, _FtValUl_, 0); _FAValUl_ = fpuAccurateMul(_FsValUl_, _FtValUl_);
if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return; if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return;
checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU); checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU);
} }
@ -487,34 +475,34 @@ void RSQRT_S() {
_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; return;
} }
else if (_FtValUl_ & 0x80000000) else if (_FtValUl_ & 0x80000000) // Ft is negative
{ // Ft is negative {
_ContVal_ |= FPUflagI | FPUflagSI; _ContVal_ |= FPUflagI | FPUflagSI;
_FdValUl_ = PS2Float(_FsValUl_).Rsqrt(PS2Float(value.Abs())).AsUInt32(); _FdValUl_ = PS2Float(_FsValUl_).Rsqrt(PS2Float(value.Abs())).AsUInt32();
} }
else else // Ft is positive and not zero
{ {
_FdValUl_ = PS2Float(_FsValUl_).Rsqrt(value).AsUInt32(); _FdValUl_ = PS2Float(_FsValUl_).Rsqrt(value).AsUInt32();
} // Ft is positive and not zero }
} }
else else
{ {
if ((_FtValUl_ & 0x7F800000) == 0) if ((_FtValUl_ & 0x7F800000) == 0) // Ft is zero (Denormals are Zero)
{ // Ft is zero (Denormals are Zero) {
_ContVal_ |= FPUflagD | FPUflagSD; _ContVal_ |= FPUflagD | FPUflagSD;
_FdValUl_ = (_FtValUl_ & 0x80000000) | posFmax; _FdValUl_ = (_FtValUl_ & 0x80000000) | posFmax;
return; return;
} }
else if (_FtValUl_ & 0x80000000) else if (_FtValUl_ & 0x80000000) // Ft is negative
{ // Ft is negative {
_ContVal_ |= FPUflagI | FPUflagSI; _ContVal_ |= FPUflagI | FPUflagSI;
temp.f = sqrt(fabs(fpuDouble(_FtValUl_))); temp.f = sqrt(fabs(fpuDouble(_FtValUl_)));
_FdValf_ = fpuDouble(_FsValUl_) / fpuDouble(temp.UL); _FdValf_ = fpuDouble(_FsValUl_) / fpuDouble(temp.UL);
} }
else else // Ft is positive and not zero
{ {
_FdValf_ = fpuDouble(_FsValUl_) / sqrt(fpuDouble(_FtValUl_)); _FdValf_ = fpuDouble(_FsValUl_) / sqrt(fpuDouble(_FtValUl_));
} // Ft is positive and not zero }
} }
if (checkOverflow( _FdValUl_, 0)) return; if (checkOverflow( _FdValUl_, 0)) return;
@ -528,8 +516,8 @@ void SQRT_S() {
{ {
PS2Float value = PS2Float(_FtValUl_); PS2Float value = PS2Float(_FtValUl_);
if (_FtValUl_ & 0x80000000) if (_FtValUl_ & 0x80000000) // If Ft is Negative
{ // If Ft is Negative {
_ContVal_ |= FPUflagI | FPUflagSI; _ContVal_ |= FPUflagI | FPUflagSI;
_FdValUl_ = PS2Float(value.Abs()).Sqrt().AsUInt32(); _FdValUl_ = PS2Float(value.Abs()).Sqrt().AsUInt32();
} }
@ -540,8 +528,8 @@ void SQRT_S() {
{ {
if ((_FtValUl_ & 0x7F800000) == 0) // If Ft = +/-0 if ((_FtValUl_ & 0x7F800000) == 0) // If Ft = +/-0
_FdValUl_ = _FtValUl_ & 0x80000000; // result is 0 _FdValUl_ = _FtValUl_ & 0x80000000; // result is 0
else if (_FtValUl_ & 0x80000000) else if (_FtValUl_ & 0x80000000) // If Ft is Negative
{ // If Ft is Negative {
_ContVal_ |= FPUflagI | FPUflagSI; _ContVal_ |= FPUflagI | FPUflagSI;
_FdValf_ = sqrt(fabs(fpuDouble(_FtValUl_))); _FdValf_ = sqrt(fabs(fpuDouble(_FtValUl_)));
} }
@ -551,13 +539,13 @@ void SQRT_S() {
} }
void SUB_S() { void SUB_S() {
_FdValUl_ = fpuAccurateAddSub(_FsValUl_, _FtValUl_, 1); _FdValUl_ = fpuAccurateSub(_FsValUl_, _FtValUl_);
if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return; if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return;
checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU); checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU);
} }
void SUBA_S() { void SUBA_S() {
_FAValUl_ = fpuAccurateAddSub(_FsValUl_, _FtValUl_, 1); _FAValUl_ = fpuAccurateSub(_FsValUl_, _FtValUl_);
if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return; if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return;
checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU); checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU);
} }

View File

@ -11,16 +11,6 @@
#include "PS2Float.h" #include "PS2Float.h"
#include "Common.h" #include "Common.h"
const u8 PS2Float::BIAS = 127;
const u32 PS2Float::SIGNMASK = 0x80000000;
const u32 PS2Float::MAX_FLOATING_POINT_VALUE = 0x7FFFFFFF;
const u32 PS2Float::MIN_FLOATING_POINT_VALUE = 0xFFFFFFFF;
const u32 PS2Float::POSITIVE_INFINITY_VALUE = 0x7F800000;
const u32 PS2Float::NEGATIVE_INFINITY_VALUE = 0xFF800000;
const u32 PS2Float::ONE = 0x3F800000;
const u32 PS2Float::MIN_ONE = 0xBF800000;
const s32 PS2Float::IMPLICIT_LEADING_BIT_POS = 23;
//**************************************************************** //****************************************************************
// Booth Multiplier // Booth Multiplier
//**************************************************************** //****************************************************************
@ -829,25 +819,3 @@ s32 PS2Float::GetMostSignificantBitPosition(u32 value)
} }
return -1; return -1;
} }
const s8 PS2Float::msb[256] =
{
-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
const s32 PS2Float::debruijn32[64] =
{
32, 8, 17, -1, -1, 14, -1, -1, -1, 20, -1, -1, -1, 28, -1, 18,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 26, 25, 24,
4, 11, 23, 31, 3, 7, 10, 16, 22, 30, -1, -1, 2, 6, 13, 9,
-1, 15, -1, 21, -1, 29, 19, -1, -1, -1, -1, -1, 1, 27, 5, 12};
const s32 PS2Float::normalizeAmounts[] =
{
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};

View File

@ -7,42 +7,60 @@
class PS2Float class PS2Float
{ {
struct BoothRecode struct BoothRecode
{ {
u32 data; u32 data;
u32 negate; u32 negate;
}; };
struct AddResult struct AddResult
{ {
u32 lo; u32 lo;
u32 hi; u32 hi;
}; };
static u64 MulMantissa(u32 a, u32 b); static u64 MulMantissa(u32 a, u32 b);
static BoothRecode Booth(u32 a, u32 b, u32 bit); static BoothRecode Booth(u32 a, u32 b, u32 bit);
static AddResult Add3(u32 a, u32 b, u32 c); static AddResult Add3(u32 a, u32 b, u32 c);
public: public:
bool Sign; bool Sign;
u8 Exponent; u8 Exponent;
u32 Mantissa; u32 Mantissa;
static const u8 BIAS; static constexpr u8 BIAS = 127;
static const u32 SIGNMASK; static constexpr u32 SIGNMASK = 0x80000000;
static const u32 MAX_FLOATING_POINT_VALUE; static constexpr u32 MAX_FLOATING_POINT_VALUE = 0x7FFFFFFF;
static const u32 MIN_FLOATING_POINT_VALUE; static constexpr u32 MIN_FLOATING_POINT_VALUE = 0xFFFFFFFF;
static const u32 POSITIVE_INFINITY_VALUE; static constexpr u32 POSITIVE_INFINITY_VALUE = 0x7F800000;
static const u32 NEGATIVE_INFINITY_VALUE; static constexpr u32 NEGATIVE_INFINITY_VALUE = 0xFF800000;
static const u32 ONE; static constexpr u32 ONE = 0x3F800000;
static const u32 MIN_ONE; static constexpr u32 MIN_ONE = 0xBF800000;
static const int IMPLICIT_LEADING_BIT_POS; static constexpr int IMPLICIT_LEADING_BIT_POS = 23;
static const s8 msb[256]; static constexpr s8 msb[256] = {
static const s32 debruijn32[64]; -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
static const s32 normalizeAmounts[]; 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
};
static constexpr s32 debruijn32[64] = {
32, 8, 17, -1, -1, 14, -1, -1, -1, 20, -1, -1, -1, 28, -1, 18,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 26, 25, 24,
4, 11, 23, 31, 3, 7, 10, 16, 22, 30, -1, -1, 2, 6, 13, 9,
-1, 15, -1, 21, -1, 29, 19, -1, -1, -1, -1, -1, 1, 27, 5, 12
};
static constexpr s32 normalizeAmounts[] = {
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
};
PS2Float(u32 value); PS2Float(u32 value);
@ -56,7 +74,7 @@ public:
static PS2Float MinOne(); static PS2Float MinOne();
static PS2Float Neg(PS2Float self); static PS2Float Neg(PS2Float self);
u32 AsUInt32() const; u32 AsUInt32() const;

File diff suppressed because it is too large Load Diff