diff --git a/pcsx2/FPU.cpp b/pcsx2/FPU.cpp index dc823fd532..c6662c37af 100644 --- a/pcsx2/FPU.cpp +++ b/pcsx2/FPU.cpp @@ -74,23 +74,28 @@ //**************************************************************** // If we have an infinity value, then Overflow has occured. -#define checkOverflow(xReg, cFlagsToSet, shouldReturn) { \ - if ( ( xReg & ~0x80000000 ) == PosInfinity ) { \ - /*Console.Warning( "FPU OVERFLOW!: Changing to +/-Fmax!!!!!!!!!!!!\n" );*/ \ - xReg = ( xReg & 0x80000000 ) | posFmax; \ - _ContVal_ |= cFlagsToSet; \ - if ( shouldReturn ) { return; } \ - } \ +bool checkOverflow(u32& xReg, u32 cFlagsToSet) +{ + if ( (xReg & ~0x80000000) == PosInfinity ) { + /*Console.Warning( "FPU OVERFLOW!: Changing to +/-Fmax!!!!!!!!!!!!\n" );*/ + xReg = (xReg & 0x80000000) | posFmax; + _ContVal_ |= (cFlagsToSet); + return true; + } + + return false; } // If we have a denormal value, then Underflow has occured. -#define checkUnderflow(xReg, cFlagsToSet, shouldReturn) { \ - if ( ( ( xReg & 0x7F800000 ) == 0 ) && ( ( xReg & 0x007FFFFF ) != 0 ) ) { \ - /*Console.Warning( "FPU UNDERFLOW!: Changing to +/-0!!!!!!!!!!!!\n" );*/ \ - xReg &= 0x80000000; \ - _ContVal_ |= cFlagsToSet; \ - if ( shouldReturn ) { return; } \ - } \ +bool checkUnderflow(u32& xReg, u32 cFlagsToSet) { + if ( ( (xReg & 0x7F800000) == 0 ) && ( (xReg & 0x007FFFFF) != 0 ) ) { + /*Console.Warning( "FPU UNDERFLOW!: Changing to +/-0!!!!!!!!!!!!\n" );*/ + xReg &= 0x80000000; + _ContVal_ |= (cFlagsToSet); + return true; + } + + return false; } /* Checks if Divide by Zero will occur. (z/y = x) @@ -98,12 +103,15 @@ cFlagsToSet2 = Flags to set if (z == 0) ( Denormals are counted as "0" ) */ -#define checkDivideByZero(xReg, yDivisorReg, zDividendReg, cFlagsToSet1, cFlagsToSet2, shouldReturn) { \ - if ( ( yDivisorReg & 0x7F800000 ) == 0 ) { \ - _ContVal_ |= ( ( zDividendReg & 0x7F800000 ) == 0 ) ? cFlagsToSet2 : cFlagsToSet1; \ - xReg = ( ( yDivisorReg ^ zDividendReg ) & 0x80000000 ) | posFmax; \ - if ( shouldReturn ) { return; } \ - } \ +bool checkDivideByZero(u32& xReg, u32 yDivisorReg, u32 zDividendReg, u32 cFlagsToSet1, u32 cFlagsToSet2) { + + if ( (yDivisorReg & 0x7F800000) == 0 ) { + _ContVal_ |= ( (zDividendReg & 0x7F800000) == 0 ) ? cFlagsToSet2 : cFlagsToSet1; + xReg = ( (yDivisorReg ^ zDividendReg) & 0x80000000 ) | posFmax; + return true; + } + + return false; } /* Clears the "Cause Flags" of the Control/Status Reg @@ -180,14 +188,14 @@ void ABS_S() { void ADD_S() { _FdValf_ = fpuDouble( _FsValUl_ ) + fpuDouble( _FtValUl_ ); - checkOverflow( _FdValUl_, FPUflagO | FPUflagSO, 1 ); - checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU, 1 ); + if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return; + checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU); } void ADDA_S() { _FAValf_ = fpuDouble( _FsValUl_ ) + fpuDouble( _FtValUl_ ); - checkOverflow( _FAValUl_, FPUflagO | FPUflagSO, 1 ); - checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU, 1 ); + if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return; + checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU); } void BC1F() { @@ -248,10 +256,10 @@ void CVT_W() { } void DIV_S() { - checkDivideByZero( _FdValUl_, _FtValUl_, _FsValUl_, FPUflagD | FPUflagSD, FPUflagI | FPUflagSI, 1 ); + if (checkDivideByZero( _FdValUl_, _FtValUl_, _FsValUl_, FPUflagD | FPUflagSD, FPUflagI | FPUflagSI)) return; _FdValf_ = fpuDouble( _FsValUl_ ) / fpuDouble( _FtValUl_ ); - checkOverflow( _FdValUl_, 0, 1); - checkUnderflow( _FdValUl_, 0, 1 ); + if (checkOverflow( _FdValUl_, 0)) return; + checkUnderflow( _FdValUl_, 0); } /* The Instruction Set manual has an overly complicated way of @@ -262,14 +270,14 @@ void MADD_S() { FPRreg temp; temp.f = fpuDouble( _FsValUl_ ) * fpuDouble( _FtValUl_ ); _FdValf_ = fpuDouble( _FAValUl_ ) + fpuDouble( temp.UL ); - checkOverflow( _FdValUl_, FPUflagO | FPUflagSO, 1 ); - checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU, 1 ); + if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return; + checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU); } void MADDA_S() { _FAValf_ += fpuDouble( _FsValUl_ ) * fpuDouble( _FtValUl_ ); - checkOverflow( _FAValUl_, FPUflagO | FPUflagSO, 1 ); - checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU, 1 ); + if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return; + checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU); } void MAX_S() { @@ -295,14 +303,14 @@ void MSUB_S() { FPRreg temp; temp.f = fpuDouble( _FsValUl_ ) * fpuDouble( _FtValUl_ ); _FdValf_ = fpuDouble( _FAValUl_ ) - fpuDouble( temp.UL ); - checkOverflow( _FdValUl_, FPUflagO | FPUflagSO, 1 ); - checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU, 1 ); + if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return; + checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU); } void MSUBA_S() { _FAValf_ -= fpuDouble( _FsValUl_ ) * fpuDouble( _FtValUl_ ); - checkOverflow( _FAValUl_, FPUflagO | FPUflagSO, 1 ); - checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU, 1 ); + if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return; + checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU); } void MTC1() { @@ -311,14 +319,14 @@ void MTC1() { void MUL_S() { _FdValf_ = fpuDouble( _FsValUl_ ) * fpuDouble( _FtValUl_ ); - checkOverflow( _FdValUl_, FPUflagO | FPUflagSO, 1 ); - checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU, 1 ); + if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return; + checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU); } void MULA_S() { _FAValf_ = fpuDouble( _FsValUl_ ) * fpuDouble( _FtValUl_ ); - checkOverflow( _FAValUl_, FPUflagO | FPUflagSO, 1 ); - checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU, 1 ); + if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return; + checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU); } void NEG_S() { @@ -340,8 +348,8 @@ void RSQRT_S() { } else { _FdValf_ = fpuDouble( _FsValUl_ ) / sqrt( fpuDouble( _FtValUl_ ) ); } // Ft is positive and not zero - checkOverflow( _FdValUl_, 0, 1 ); - checkUnderflow( _FdValUl_, 0, 1 ); + if (checkOverflow( _FdValUl_, 0)) return; + checkUnderflow( _FdValUl_, 0); } void SQRT_S() { @@ -357,14 +365,14 @@ void SQRT_S() { void SUB_S() { _FdValf_ = fpuDouble( _FsValUl_ ) - fpuDouble( _FtValUl_ ); - checkOverflow( _FdValUl_, FPUflagO | FPUflagSO, 1 ); - checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU, 1 ); + if (checkOverflow( _FdValUl_, FPUflagO | FPUflagSO)) return; + checkUnderflow( _FdValUl_, FPUflagU | FPUflagSU); } void SUBA_S() { _FAValf_ = fpuDouble( _FsValUl_ ) - fpuDouble( _FtValUl_ ); - checkOverflow( _FAValUl_, FPUflagO | FPUflagSO, 1 ); - checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU, 1 ); + if (checkOverflow( _FAValUl_, FPUflagO | FPUflagSO)) return; + checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU); } } // End Namespace COP1