Skip to content

Commit

Permalink
[Soft-Float] - Code review Part1.
Browse files Browse the repository at this point in the history
Applies some recommendations from the review.

The next batch will come later.
  • Loading branch information
GitHubProUser67 committed Nov 23, 2024
1 parent b0b65fa commit 9b6327c
Show file tree
Hide file tree
Showing 4 changed files with 429 additions and 506 deletions.
104 changes: 46 additions & 58 deletions pcsx2/FPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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;
Expand All @@ -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();
}
Expand All @@ -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_)));
}
Expand All @@ -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);
}
Expand Down
32 changes: 0 additions & 32 deletions pcsx2/Ps2Float.cpp → pcsx2/PS2Float.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
//****************************************************************
Expand Down Expand Up @@ -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};
60 changes: 39 additions & 21 deletions pcsx2/Ps2Float.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 const s8 msb[256];
static const s32 debruijn32[64];
static const s32 normalizeAmounts[];
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 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);

Expand All @@ -56,7 +74,7 @@ class PS2Float

static PS2Float MinOne();

static PS2Float Neg(PS2Float self);
static PS2Float Neg(PS2Float self);

u32 AsUInt32() const;

Expand Down
Loading

0 comments on commit 9b6327c

Please sign in to comment.