mirror of https://github.com/PCSX2/pcsx2.git
FPU: replace check* macros by functions
v2: remove useless return after function call
This commit is contained in:
parent
9648e25018
commit
d39f17bda3
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue