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

View File

@ -11,16 +11,6 @@
#include "PS2Float.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
//****************************************************************
@ -829,25 +819,3 @@ s32 PS2Float::GetMostSignificantBitPosition(u32 value)
}
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
{
struct BoothRecode
{
struct BoothRecode
{
u32 data;
u32 negate;
};
};
struct AddResult
{
struct AddResult
{
u32 lo;
u32 hi;
};
};
static u64 MulMantissa(u32 a, u32 b);
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:
bool Sign;
u8 Exponent;
u32 Mantissa;
static const u8 BIAS;
static const u32 SIGNMASK;
static const u32 MAX_FLOATING_POINT_VALUE;
static const u32 MIN_FLOATING_POINT_VALUE;
static const u32 POSITIVE_INFINITY_VALUE;
static const u32 NEGATIVE_INFINITY_VALUE;
static const u32 ONE;
static const u32 MIN_ONE;
static const int IMPLICIT_LEADING_BIT_POS;
static constexpr u8 BIAS = 127;
static constexpr u32 SIGNMASK = 0x80000000;
static constexpr u32 MAX_FLOATING_POINT_VALUE = 0x7FFFFFFF;
static constexpr u32 MIN_FLOATING_POINT_VALUE = 0xFFFFFFFF;
static constexpr u32 POSITIVE_INFINITY_VALUE = 0x7F800000;
static constexpr u32 NEGATIVE_INFINITY_VALUE = 0xFF800000;
static constexpr u32 ONE = 0x3F800000;
static constexpr u32 MIN_ONE = 0xBF800000;
static constexpr int IMPLICIT_LEADING_BIT_POS = 23;
static const s8 msb[256];
static const s32 debruijn32[64];
static const s32 normalizeAmounts[];
static constexpr s8 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
};
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);
@ -56,7 +74,7 @@ public:
static PS2Float MinOne();
static PS2Float Neg(PS2Float self);
static PS2Float Neg(PS2Float self);
u32 AsUInt32() const;

File diff suppressed because it is too large Load Diff