mirror of https://github.com/PCSX2/pcsx2.git
[Soft-Float] - Code review Part1.
Applies some recommendations from the review. The next batch will come later.
This commit is contained in:
parent
b0b65fa248
commit
8bc2ed9282
|
@ -33,7 +33,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>-447</y>
|
||||
<width>793</width>
|
||||
<width>790</width>
|
||||
<height>1283</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
|
104
pcsx2/FPU.cpp
104
pcsx2/FPU.cpp
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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};
|
|
@ -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;
|
||||
|
739
pcsx2/VUops.cpp
739
pcsx2/VUops.cpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue