@@ -204,6 +204,25 @@ INLINE flag extractFloat32Sign( float32 a )
}
/*----------------------------------------------------------------------------
+| Unpacks the fractional, exponent, and sign bits of the single-precision
+| floating-point value `a' into the locations pointed to by `aSigPtr',
+| `aExpPtr', and `aSignPtr', respectively.
+-----------------------------------------------------------------------------*/
+
+INLINE void
+ unpackFloat32( float32 a, bits32 *aSigPtr, int16 *aExpPtr, flag *aSignPtr STATUS_PARAM )
+{
+ *aSigPtr = extractFloat32Frac( a );
+ *aExpPtr = extractFloat32Exp( a );
+ *aSignPtr = extractFloat32Sign( a );
+
+ if ( STATUS(flush_inputs_to_zero) && *aExpPtr == 0 ) {
+ *aSigPtr = 0;
+ float_raise( float_flag_input_denormal STATUS_VAR);
+ }
+}
+
+/*----------------------------------------------------------------------------
| Normalizes the subnormal single-precision floating-point value represented
| by the denormalized significand `aSig'. The normalized exponent and
| significand are stored at the locations pointed to by `zExpPtr' and
@@ -296,7 +315,7 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_P
return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
}
if ( zExp < 0 ) {
- if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 );
+ if ( STATUS(flush_outputs_to_zero) ) return packFloat32( zSign, 0, 0 );
isTiny =
( STATUS(float_detect_tininess) == float_tininess_before_rounding )
|| ( zExp < -1 )
@@ -368,6 +387,25 @@ INLINE flag extractFloat64Sign( float64 a )
}
/*----------------------------------------------------------------------------
+| Unpacks the fractional, exponent, and sign bits of the double-precision
+| floating-point value `a' into the locations pointed to by `aSigPtr',
+| `aExpPtr', and `aSignPtr', respectively.
+-----------------------------------------------------------------------------*/
+
+INLINE void
+ unpackFloat64( float64 a, bits64 *aSigPtr, int16 *aExpPtr, flag *aSignPtr STATUS_PARAM )
+{
+ *aSigPtr = extractFloat64Frac( a );
+ *aExpPtr = extractFloat64Exp( a );
+ *aSignPtr = extractFloat64Sign( a );
+
+ if ( STATUS(flush_inputs_to_zero) && *aExpPtr == 0 ) {
+ *aSigPtr = 0;
+ float_raise( float_flag_input_denormal STATUS_VAR);
+ }
+}
+
+/*----------------------------------------------------------------------------
| Normalizes the subnormal double-precision floating-point value represented
| by the denormalized significand `aSig'. The normalized exponent and
| significand are stored at the locations pointed to by `zExpPtr' and
@@ -460,7 +498,7 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_P
return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
}
if ( zExp < 0 ) {
- if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );
+ if ( STATUS(flush_outputs_to_zero) ) return packFloat64( zSign, 0, 0 );
isTiny =
( STATUS(float_detect_tininess) == float_tininess_before_rounding )
|| ( zExp < -1 )
@@ -537,6 +575,25 @@ INLINE flag extractFloatx80Sign( floatx80 a )
}
/*----------------------------------------------------------------------------
+| Unpacks the fractional, exponent, and sign bits of the extended
+| double-precision floating-point value `a' into the locations pointed to by
+| `aSigPtr', `aExpPtr', and `aSignPtr', respectively.
+-----------------------------------------------------------------------------*/
+
+INLINE void
+ unpackFloatx80( floatx80 a, bits64 *aSigPtr, int32 *aExpPtr, flag *aSignPtr STATUS_PARAM )
+{
+ *aSigPtr = extractFloatx80Frac( a );
+ *aExpPtr = extractFloatx80Exp( a );
+ *aSignPtr = extractFloatx80Sign( a );
+
+ if ( STATUS(flush_inputs_to_zero) && *aExpPtr == 0 ) {
+ *aSigPtr = 0;
+ float_raise( float_flag_input_denormal STATUS_VAR);
+ }
+}
+
+/*----------------------------------------------------------------------------
| Normalizes the subnormal extended double-precision floating-point value
| represented by the denormalized significand `aSig'. The normalized exponent
| and significand are stored at the locations pointed to by `zExpPtr' and
@@ -639,7 +696,7 @@ static floatx80
goto overflow;
}
if ( zExp <= 0 ) {
- if ( STATUS(flush_to_zero) ) return packFloatx80( zSign, 0, 0 );
+ if ( STATUS(flush_outputs_to_zero) ) return packFloatx80( zSign, 0, 0 );
isTiny =
( STATUS(float_detect_tininess) == float_tininess_before_rounding )
|| ( zExp < 0 )
@@ -834,6 +891,30 @@ INLINE flag extractFloat128Sign( float128 a )
}
/*----------------------------------------------------------------------------
+| Unpacks the least-significant 64 fraction, the most-significant 48 fraction,
+| exponent, and sign bits of the quadruple-precision floating-point value `a'
+| into the locations pointed to by `aSig1Ptr', `aSig0Ptr', `aExpPtr', and
+| `aSignPtr', respectively.
+-----------------------------------------------------------------------------*/
+
+INLINE void
+ unpackFloat128(
+ float128 a, bits64 *aSig1Ptr, bits64 *aSig0Ptr,
+ int32 *aExpPtr, flag *aSignPtr STATUS_PARAM )
+{
+ *aSig1Ptr = extractFloat128Frac1( a );
+ *aSig0Ptr = extractFloat128Frac0( a );
+ *aExpPtr = extractFloat128Exp( a );
+ *aSignPtr = extractFloat128Sign( a );
+
+ if ( STATUS(flush_inputs_to_zero) && *aExpPtr == 0 ) {
+ *aSig1Ptr = 0;
+ *aSig0Ptr = 0;
+ float_raise( float_flag_input_denormal STATUS_VAR);
+ }
+}
+
+/*----------------------------------------------------------------------------
| Normalizes the subnormal quadruple-precision floating-point value
| represented by the denormalized significand formed by the concatenation of
| `aSig0' and `aSig1'. The normalized exponent is stored at the location
@@ -970,7 +1051,7 @@ static float128
return packFloat128( zSign, 0x7FFF, 0, 0 );
}
if ( zExp < 0 ) {
- if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
+ if ( STATUS(flush_outputs_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
isTiny =
( STATUS(float_detect_tininess) == float_tininess_before_rounding )
|| ( zExp < -1 )
@@ -1298,9 +1379,7 @@ int32 float32_to_int32( float32 a STATUS_PARAM )
bits32 aSig;
bits64 aSig64;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
if ( ( aExp == 0xFF ) && aSig ) aSign = 0;
if ( aExp ) aSig |= 0x00800000;
shiftCount = 0xAF - aExp;
@@ -1328,9 +1407,7 @@ int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM )
bits32 aSig;
int32 z;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
shiftCount = aExp - 0x9E;
if ( 0 <= shiftCount ) {
if ( float32_val(a) != 0xCF000000 ) {
@@ -1370,9 +1447,7 @@ int64 float32_to_int64( float32 a STATUS_PARAM )
bits32 aSig;
bits64 aSig64, aSigExtra;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
shiftCount = 0xBE - aExp;
if ( shiftCount < 0 ) {
float_raise( float_flag_invalid STATUS_VAR);
@@ -1407,9 +1482,7 @@ int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM )
bits64 aSig64;
int64 z;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
shiftCount = aExp - 0xBE;
if ( 0 <= shiftCount ) {
if ( float32_val(a) != 0xDF000000 ) {
@@ -1448,9 +1521,7 @@ float64 float32_to_float64( float32 a STATUS_PARAM )
int16 aExp;
bits32 aSig;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
if ( aExp == 0xFF ) {
if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ));
return packFloat64( aSign, 0x7FF, 0 );
@@ -1479,9 +1550,7 @@ floatx80 float32_to_floatx80( float32 a STATUS_PARAM )
int16 aExp;
bits32 aSig;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
if ( aExp == 0xFF ) {
if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) );
return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
@@ -1512,9 +1581,7 @@ float128 float32_to_float128( float32 a STATUS_PARAM )
int16 aExp;
bits32 aSig;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
if ( aExp == 0xFF ) {
if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) );
return packFloat128( aSign, 0x7FFF, 0, 0 );
@@ -1602,11 +1669,10 @@ static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
int16 aExp, bExp, zExp;
bits32 aSig, bSig, zSig;
int16 expDiff;
+ flag dummySign;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
+ unpackFloat32( a, &aSig, &aExp, &dummySign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &dummySign STATUS_VAR);
expDiff = aExp - bExp;
aSig <<= 6;
bSig <<= 6;
@@ -1644,7 +1710,7 @@ static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
return a;
}
if ( aExp == 0 ) {
- if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 );
+ if ( STATUS(flush_outputs_to_zero) ) return packFloat32( zSign, 0, 0 );
return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
}
zSig = 0x40000000 + aSig + bSig;
@@ -1676,11 +1742,10 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
int16 aExp, bExp, zExp;
bits32 aSig, bSig, zSig;
int16 expDiff;
+ flag dummySign;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
+ unpackFloat32( a, &aSig, &aExp, &dummySign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &dummySign STATUS_VAR);
expDiff = aExp - bExp;
aSig <<= 7;
bSig <<= 7;
@@ -1794,12 +1859,8 @@ float32 float32_mul( float32 a, float32 b STATUS_PARAM )
bits64 zSig64;
bits32 zSig;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- bSign = extractFloat32Sign( b );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &bSign STATUS_VAR);
zSign = aSign ^ bSign;
if ( aExp == 0xFF ) {
if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
@@ -1852,12 +1913,8 @@ float32 float32_div( float32 a, float32 b STATUS_PARAM )
int16 aExp, bExp, zExp;
bits32 aSig, bSig, zSig;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- bSign = extractFloat32Sign( b );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &bSign STATUS_VAR);
zSign = aSign ^ bSign;
if ( aExp == 0xFF ) {
if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
@@ -1918,11 +1975,8 @@ float32 float32_rem( float32 a, float32 b STATUS_PARAM )
bits32 alternateASig;
sbits32 sigMean;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &zSign STATUS_VAR);
if ( aExp == 0xFF ) {
if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
return propagateFloat32NaN( a, b STATUS_VAR );
@@ -2014,9 +2068,7 @@ float32 float32_sqrt( float32 a STATUS_PARAM )
bits32 aSig, zSig;
bits64 rem, term;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
if ( aExp == 0xFF ) {
if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
if ( ! aSign ) return a;
@@ -2066,9 +2118,7 @@ float32 float32_log2( float32 a STATUS_PARAM )
int16 aExp;
bits32 aSig, zSig, i;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloat32( 1, 0xFF, 0 );
@@ -2110,9 +2160,14 @@ float32 float32_log2( float32 a STATUS_PARAM )
int float32_eq( float32 a, float32 b STATUS_PARAM )
{
+ flag aSign, bSign;
+ int16 aExp, bExp;
+ bits32 aSig, bSig;
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &bSign STATUS_VAR);
+ if ( ( ( aExp == 0xFF ) && aSig )
+ || ( ( bExp == 0xFF ) && bSig )
) {
if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid STATUS_VAR);
@@ -2134,16 +2189,18 @@ int float32_eq( float32 a, float32 b STATUS_PARAM )
int float32_le( float32 a, float32 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits32 aSig, bSig;
bits32 av, bv;
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &bSign STATUS_VAR);
+ if ( ( ( aExp == 0xFF ) && aSig )
+ || ( ( bExp == 0xFF ) && bSig )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
av = float32_val(a);
bv = float32_val(b);
if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 );
@@ -2160,16 +2217,18 @@ int float32_le( float32 a, float32 b STATUS_PARAM )
int float32_lt( float32 a, float32 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits32 aSig, bSig;
bits32 av, bv;
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &bSign STATUS_VAR);
+ if ( ( ( aExp == 0xFF ) && aSig )
+ || ( ( bExp == 0xFF ) && bSig )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
av = float32_val(a);
bv = float32_val(b);
if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 );
@@ -2186,10 +2245,15 @@ int float32_lt( float32 a, float32 b STATUS_PARAM )
int float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
{
+ flag aSign, bSign;
+ int16 aExp, bExp;
+ bits32 aSig, bSig;
bits32 av, bv;
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &bSign STATUS_VAR);
+ if ( ( ( aExp == 0xFF ) && aSig )
+ || ( ( bExp == 0xFF ) && bSig )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
@@ -2210,18 +2274,20 @@ int float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
int float32_le_quiet( float32 a, float32 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits32 aSig, bSig;
bits32 av, bv;
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &bSign STATUS_VAR);
+ if ( ( ( aExp == 0xFF ) && aSig )
+ || ( ( bExp == 0xFF ) && bSig )
) {
if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid STATUS_VAR);
}
return 0;
}
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
av = float32_val(a);
bv = float32_val(b);
if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 );
@@ -2239,18 +2305,20 @@ int float32_le_quiet( float32 a, float32 b STATUS_PARAM )
int float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits32 aSig, bSig;
bits32 av, bv;
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
+ unpackFloat32( b, &bSig, &bExp, &bSign STATUS_VAR);
+ if ( ( ( aExp == 0xFF ) && aSig )
+ || ( ( bExp == 0xFF ) && bSig )
) {
if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid STATUS_VAR);
}
return 0;
}
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
av = float32_val(a);
bv = float32_val(b);
if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 );
@@ -2274,9 +2342,7 @@ int32 float64_to_int32( float64 a STATUS_PARAM )
int16 aExp, shiftCount;
bits64 aSig;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
shiftCount = 0x42C - aExp;
@@ -2302,9 +2368,7 @@ int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
bits64 aSig, savedASig;
int32 z;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( 0x41E < aExp ) {
if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
goto invalid;
@@ -2347,9 +2411,7 @@ int64 float64_to_int64( float64 a STATUS_PARAM )
int16 aExp, shiftCount;
bits64 aSig, aSigExtra;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
shiftCount = 0x433 - aExp;
if ( shiftCount <= 0 ) {
@@ -2390,9 +2452,7 @@ int64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM )
bits64 aSig;
int64 z;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
shiftCount = aExp - 0x433;
if ( 0 <= shiftCount ) {
@@ -2439,9 +2499,7 @@ float32 float64_to_float32( float64 a STATUS_PARAM )
bits64 aSig;
bits32 zSig;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FF ) {
if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) );
return packFloat32( aSign, 0xFF, 0 );
@@ -2516,9 +2574,7 @@ bits16 float32_to_float16( float32 a, flag ieee STATUS_PARAM)
bits32 increment;
int8 roundingMode;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
if ( aExp == 0xFF ) {
if (aSig) {
/* Make sure correct exceptions are raised. */
@@ -2609,9 +2665,7 @@ floatx80 float64_to_floatx80( float64 a STATUS_PARAM )
int16 aExp;
bits64 aSig;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FF ) {
if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) );
return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
@@ -2643,9 +2697,7 @@ float128 float64_to_float128( float64 a STATUS_PARAM )
int16 aExp;
bits64 aSig, zSig0, zSig1;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FF ) {
if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) );
return packFloat128( aSign, 0x7FFF, 0, 0 );
@@ -2747,11 +2799,10 @@ static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
int16 aExp, bExp, zExp;
bits64 aSig, bSig, zSig;
int16 expDiff;
+ flag dummySign;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
+ unpackFloat64( a, &aSig, &aExp, &dummySign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &dummySign STATUS_VAR );
expDiff = aExp - bExp;
aSig <<= 9;
bSig <<= 9;
@@ -2789,7 +2840,7 @@ static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
return a;
}
if ( aExp == 0 ) {
- if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );
+ if ( STATUS(flush_outputs_to_zero) ) return packFloat64( zSign, 0, 0 );
return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
}
zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
@@ -2821,11 +2872,10 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
int16 aExp, bExp, zExp;
bits64 aSig, bSig, zSig;
int16 expDiff;
+ flag dummySign;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
+ unpackFloat64( a, &aSig, &aExp, &dummySign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &dummySign STATUS_VAR );
expDiff = aExp - bExp;
aSig <<= 10;
bSig <<= 10;
@@ -2937,12 +2987,8 @@ float64 float64_mul( float64 a, float64 b STATUS_PARAM )
int16 aExp, bExp, zExp;
bits64 aSig, bSig, zSig0, zSig1;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- bSign = extractFloat64Sign( b );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &bSign STATUS_VAR );
zSign = aSign ^ bSign;
if ( aExp == 0x7FF ) {
if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
@@ -2997,12 +3043,8 @@ float64 float64_div( float64 a, float64 b STATUS_PARAM )
bits64 rem0, rem1;
bits64 term0, term1;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- bSign = extractFloat64Sign( b );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &bSign STATUS_VAR );
zSign = aSign ^ bSign;
if ( aExp == 0x7FF ) {
if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
@@ -3067,11 +3109,8 @@ float64 float64_rem( float64 a, float64 b STATUS_PARAM )
bits64 q, alternateASig;
sbits64 sigMean;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &zSign STATUS_VAR );
if ( aExp == 0x7FF ) {
if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
return propagateFloat64NaN( a, b STATUS_VAR );
@@ -3150,9 +3189,7 @@ float64 float64_sqrt( float64 a STATUS_PARAM )
bits64 aSig, zSig, doubleZSig;
bits64 rem0, rem1, term0, term1;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FF ) {
if ( aSig ) return propagateFloat64NaN( a, a STATUS_VAR );
if ( ! aSign ) return a;
@@ -3199,9 +3236,7 @@ float64 float64_log2( float64 a STATUS_PARAM )
int16 aExp;
bits64 aSig, aSig0, aSig1, zSig, i;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloat64( 1, 0x7FF, 0 );
@@ -3242,10 +3277,15 @@ float64 float64_log2( float64 a STATUS_PARAM )
int float64_eq( float64 a, float64 b STATUS_PARAM )
{
+ flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
bits64 av, bv;
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FF ) && aSig )
+ || ( ( bExp == 0x7FF ) && bSig )
) {
if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid STATUS_VAR);
@@ -3268,16 +3308,18 @@ int float64_eq( float64 a, float64 b STATUS_PARAM )
int float64_le( float64 a, float64 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
bits64 av, bv;
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FF ) && aSig )
+ || ( ( bExp == 0x7FF ) && bSig )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
av = float64_val(a);
bv = float64_val(b);
if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 );
@@ -3294,16 +3336,18 @@ int float64_le( float64 a, float64 b STATUS_PARAM )
int float64_lt( float64 a, float64 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
bits64 av, bv;
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FF ) && aSig )
+ || ( ( bExp == 0x7FF ) && bSig )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
av = float64_val(a);
bv = float64_val(b);
if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 );
@@ -3320,10 +3364,15 @@ int float64_lt( float64 a, float64 b STATUS_PARAM )
int float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
{
+ flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
bits64 av, bv;
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FF ) && aSig )
+ || ( ( bExp == 0x7FF ) && bSig )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
@@ -3344,18 +3393,20 @@ int float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
int float64_le_quiet( float64 a, float64 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
bits64 av, bv;
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FF ) && aSig )
+ || ( ( bExp == 0x7FF ) && bSig )
) {
if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid STATUS_VAR);
}
return 0;
}
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
av = float64_val(a);
bv = float64_val(b);
if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 );
@@ -3373,18 +3424,20 @@ int float64_le_quiet( float64 a, float64 b STATUS_PARAM )
int float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
bits64 av, bv;
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloat64( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FF ) && aSig )
+ || ( ( bExp == 0x7FF ) && bSig )
) {
if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid STATUS_VAR);
}
return 0;
}
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
av = float64_val(a);
bv = float64_val(b);
if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 );
@@ -3410,9 +3463,7 @@ int32 floatx80_to_int32( floatx80 a STATUS_PARAM )
int32 aExp, shiftCount;
bits64 aSig;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
shiftCount = 0x4037 - aExp;
if ( shiftCount <= 0 ) shiftCount = 1;
@@ -3438,9 +3489,7 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
bits64 aSig, savedASig;
int32 z;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( 0x401E < aExp ) {
if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
goto invalid;
@@ -3482,9 +3531,7 @@ int64 floatx80_to_int64( floatx80 a STATUS_PARAM )
int32 aExp, shiftCount;
bits64 aSig, aSigExtra;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
shiftCount = 0x403E - aExp;
if ( shiftCount <= 0 ) {
if ( shiftCount ) {
@@ -3523,9 +3570,7 @@ int64 floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM )
bits64 aSig;
int64 z;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
shiftCount = aExp - 0x403E;
if ( 0 <= shiftCount ) {
aSig &= LIT64( 0x7FFFFFFFFFFFFFFF );
@@ -3563,9 +3608,7 @@ float32 floatx80_to_float32( floatx80 a STATUS_PARAM )
int32 aExp;
bits64 aSig;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig<<1 ) ) {
return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) );
@@ -3591,9 +3634,7 @@ float64 floatx80_to_float64( floatx80 a STATUS_PARAM )
int32 aExp;
bits64 aSig, zSig;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig<<1 ) ) {
return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) );
@@ -3621,9 +3662,7 @@ float128 floatx80_to_float128( floatx80 a STATUS_PARAM )
int16 aExp;
bits64 aSig, zSig0, zSig1;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) {
return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) );
}
@@ -3720,11 +3759,10 @@ static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM
int32 aExp, bExp, zExp;
bits64 aSig, bSig, zSig0, zSig1;
int32 expDiff;
+ flag dummySign;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
+ unpackFloatx80( a, &aSig, &aExp, &dummySign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &dummySign STATUS_VAR );
expDiff = aExp - bExp;
if ( 0 < expDiff ) {
if ( aExp == 0x7FFF ) {
@@ -3787,11 +3825,10 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM
bits64 aSig, bSig, zSig0, zSig1;
int32 expDiff;
floatx80 z;
+ flag dummySign;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
+ unpackFloatx80( a, &aSig, &aExp, &dummySign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &dummySign STATUS_VAR );
expDiff = aExp - bExp;
if ( 0 < expDiff ) goto aExpBigger;
if ( expDiff < 0 ) goto bExpBigger;
@@ -3896,12 +3933,8 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM )
bits64 aSig, bSig, zSig0, zSig1;
floatx80 z;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- bSign = extractFloatx80Sign( b );
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &bSign STATUS_VAR );
zSign = aSign ^ bSign;
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig<<1 )
@@ -3956,12 +3989,8 @@ floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM )
bits64 rem0, rem1, rem2, term0, term1, term2;
floatx80 z;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- bSign = extractFloatx80Sign( b );
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &bSign STATUS_VAR );
zSign = aSign ^ bSign;
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
@@ -4036,11 +4065,8 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
bits64 q, term0, term1, alternateASig0, alternateASig1;
floatx80 z;
- aSig0 = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
+ unpackFloatx80( a, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &zSign STATUS_VAR );
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig0<<1 )
|| ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
@@ -4132,9 +4158,7 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
floatx80 z;
- aSig0 = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
+ unpackFloatx80( a, &aSig0, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a STATUS_VAR );
if ( ! aSign ) return a;
@@ -4197,11 +4221,16 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
{
+ flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && (bits64) ( aSig<<1 ) )
+ || ( ( bExp == 0x7FFF )
+ && (bits64) ( bSig<<1 ) )
) {
if ( floatx80_is_signaling_nan( a )
|| floatx80_is_signaling_nan( b ) ) {
@@ -4228,17 +4257,19 @@ int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && (bits64) ( aSig<<1 ) )
+ || ( ( bExp == 0x7FFF )
+ && (bits64) ( bSig<<1 ) )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
if ( aSign != bSign ) {
return
aSign
@@ -4261,17 +4292,19 @@ int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && (bits64) ( aSig<<1 ) )
+ || ( ( bExp == 0x7FFF )
+ && (bits64) ( bSig<<1 ) )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
if ( aSign != bSign ) {
return
aSign
@@ -4293,11 +4326,16 @@ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM )
{
+ flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && (bits64) ( aSig<<1 ) )
+ || ( ( bExp == 0x7FFF )
+ && (bits64) ( bSig<<1 ) )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
@@ -4321,11 +4359,15 @@ int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM )
int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && (bits64) ( aSig<<1 ) )
+ || ( ( bExp == 0x7FFF )
+ && (bits64) ( bSig<<1 ) )
) {
if ( floatx80_is_signaling_nan( a )
|| floatx80_is_signaling_nan( b ) ) {
@@ -4333,8 +4375,6 @@ int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
}
return 0;
}
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
if ( aSign != bSign ) {
return
aSign
@@ -4357,11 +4397,15 @@ int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
{
flag aSign, bSign;
+ int16 aExp, bExp;
+ bits64 aSig, bSig;
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
+ unpackFloatx80( b, &bSig, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && (bits64) ( aSig<<1 ) )
+ || ( ( bExp == 0x7FFF )
+ && (bits64) ( bSig<<1 ) )
) {
if ( floatx80_is_signaling_nan( a )
|| floatx80_is_signaling_nan( b ) ) {
@@ -4369,8 +4413,6 @@ int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
}
return 0;
}
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
if ( aSign != bSign ) {
return
aSign
@@ -4403,10 +4445,7 @@ int32 float128_to_int32( float128 a STATUS_PARAM )
int32 aExp, shiftCount;
bits64 aSig0, aSig1;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
aSig0 |= ( aSig1 != 0 );
@@ -4433,10 +4472,7 @@ int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
bits64 aSig0, aSig1, savedASig;
int32 z;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
aSig0 |= ( aSig1 != 0 );
if ( 0x401E < aExp ) {
if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
@@ -4480,10 +4516,7 @@ int64 float128_to_int64( float128 a STATUS_PARAM )
int32 aExp, shiftCount;
bits64 aSig0, aSig1;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
shiftCount = 0x402F - aExp;
if ( shiftCount <= 0 ) {
@@ -4524,10 +4557,7 @@ int64 float128_to_int64_round_to_zero( float128 a STATUS_PARAM )
bits64 aSig0, aSig1;
int64 z;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
shiftCount = aExp - 0x402F;
if ( 0 < shiftCount ) {
@@ -4582,10 +4612,7 @@ float32 float128_to_float32( float128 a STATUS_PARAM )
bits64 aSig0, aSig1;
bits32 zSig;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) {
return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) );
@@ -4616,10 +4643,7 @@ float64 float128_to_float64( float128 a STATUS_PARAM )
int32 aExp;
bits64 aSig0, aSig1;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) {
return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) );
@@ -4651,10 +4675,7 @@ floatx80 float128_to_floatx80( float128 a STATUS_PARAM )
int32 aExp;
bits64 aSig0, aSig1;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) {
return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) );
@@ -4791,13 +4812,10 @@ static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM
int32 aExp, bExp, zExp;
bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
int32 expDiff;
+ flag dummySign;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &dummySign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &dummySign STATUS_VAR );
expDiff = aExp - bExp;
if ( 0 < expDiff ) {
if ( aExp == 0x7FFF ) {
@@ -4838,7 +4856,7 @@ static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM
}
add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
if ( aExp == 0 ) {
- if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
+ if ( STATUS(flush_outputs_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
return packFloat128( zSign, 0, zSig0, zSig1 );
}
zSig2 = 0;
@@ -4873,13 +4891,10 @@ static float128 subFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM
bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
int32 expDiff;
float128 z;
+ flag dummySign;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &dummySign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &dummySign STATUS_VAR );
expDiff = aExp - bExp;
shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
@@ -4998,14 +5013,8 @@ float128 float128_mul( float128 a, float128 b STATUS_PARAM )
bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
float128 z;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- bSign = extractFloat128Sign( b );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &bSign STATUS_VAR );
zSign = aSign ^ bSign;
if ( aExp == 0x7FFF ) {
if ( ( aSig0 | aSig1 )
@@ -5063,14 +5072,8 @@ float128 float128_div( float128 a, float128 b STATUS_PARAM )
bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
float128 z;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- bSign = extractFloat128Sign( b );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &bSign STATUS_VAR );
zSign = aSign ^ bSign;
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
@@ -5148,13 +5151,8 @@ float128 float128_rem( float128 a, float128 b STATUS_PARAM )
sbits64 sigMean0;
float128 z;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &zSign STATUS_VAR );
if ( aExp == 0x7FFF ) {
if ( ( aSig0 | aSig1 )
|| ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
@@ -5256,10 +5254,7 @@ float128 float128_sqrt( float128 a STATUS_PARAM )
bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
float128 z;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a STATUS_VAR );
if ( ! aSign ) return a;
@@ -5319,11 +5314,16 @@ float128 float128_sqrt( float128 a STATUS_PARAM )
int float128_eq( float128 a, float128 b STATUS_PARAM )
{
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+ flag aSign, bSign;
+ int32 aExp, bExp;
+ bits64 aSig0, aSig1, bSig0, bSig1;
+
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && ( aSig0 | aSig1 ) )
+ || ( ( bExp == 0x7FFF )
+ && ( bSig0 | bSig1 ) )
) {
if ( float128_is_signaling_nan( a )
|| float128_is_signaling_nan( b ) ) {
@@ -5350,17 +5350,19 @@ int float128_eq( float128 a, float128 b STATUS_PARAM )
int float128_le( float128 a, float128 b STATUS_PARAM )
{
flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+ int32 aExp, bExp;
+ bits64 aSig0, aSig1, bSig0, bSig1;
+
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && ( aSig0 | aSig1 ) )
+ || ( ( bExp == 0x7FFF )
+ && ( bSig0 | bSig1 ) )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
if ( aSign != bSign ) {
return
aSign
@@ -5382,17 +5384,19 @@ int float128_le( float128 a, float128 b STATUS_PARAM )
int float128_lt( float128 a, float128 b STATUS_PARAM )
{
flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+ int32 aExp, bExp;
+ bits64 aSig0, aSig1, bSig0, bSig1;
+
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && ( aSig0 | aSig1 ) )
+ || ( ( bExp == 0x7FFF )
+ && ( bSig0 | bSig1 ) )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
}
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
if ( aSign != bSign ) {
return
aSign
@@ -5414,11 +5418,16 @@ int float128_lt( float128 a, float128 b STATUS_PARAM )
int float128_eq_signaling( float128 a, float128 b STATUS_PARAM )
{
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+ flag aSign, bSign;
+ int32 aExp, bExp;
+ bits64 aSig0, aSig1, bSig0, bSig1;
+
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && ( aSig0 | aSig1 ) )
+ || ( ( bExp == 0x7FFF )
+ && ( bSig0 | bSig1 ) )
) {
float_raise( float_flag_invalid STATUS_VAR);
return 0;
@@ -5442,11 +5451,15 @@ int float128_eq_signaling( float128 a, float128 b STATUS_PARAM )
int float128_le_quiet( float128 a, float128 b STATUS_PARAM )
{
flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+ int32 aExp, bExp;
+ bits64 aSig0, aSig1, bSig0, bSig1;
+
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && ( aSig0 | aSig1 ) )
+ || ( ( bExp == 0x7FFF )
+ && ( bSig0 | bSig1 ) )
) {
if ( float128_is_signaling_nan( a )
|| float128_is_signaling_nan( b ) ) {
@@ -5454,8 +5467,6 @@ int float128_le_quiet( float128 a, float128 b STATUS_PARAM )
}
return 0;
}
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
if ( aSign != bSign ) {
return
aSign
@@ -5478,11 +5489,15 @@ int float128_le_quiet( float128 a, float128 b STATUS_PARAM )
int float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
{
flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+ int32 aExp, bExp;
+ bits64 aSig0, aSig1, bSig0, bSig1;
+
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && ( aSig0 | aSig1 ) )
+ || ( ( bExp == 0x7FFF )
+ && ( bSig0 | bSig1 ) )
) {
if ( float128_is_signaling_nan( a )
|| float128_is_signaling_nan( b ) ) {
@@ -5490,8 +5505,6 @@ int float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
}
return 0;
}
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
if ( aSign != bSign ) {
return
aSign
@@ -5617,12 +5630,14 @@ INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \
int is_quiet STATUS_PARAM ) \
{ \
flag aSign, bSign; \
+ int16 aExp, bExp; \
+ bits ## s aSig, bSig; \
bits ## s av, bv; \
\
- if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) && \
- extractFloat ## s ## Frac( a ) ) || \
- ( ( extractFloat ## s ## Exp( b ) == nan_exp ) && \
- extractFloat ## s ## Frac( b ) )) { \
+ unpackFloat ## s ( a, &aSig, &aExp, &aSign ); \
+ unpackFloat ## s ( b, &bSig, &bExp, &bSign ); \
+ if (( ( aExp == nan_exp ) && aSig ) || \
+ ( ( bExp == nan_exp ) && bSig )) { \
if (!is_quiet || \
float ## s ## _is_signaling_nan( a ) || \
float ## s ## _is_signaling_nan( b ) ) { \
@@ -5630,8 +5645,6 @@ INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \
} \
return float_relation_unordered; \
} \
- aSign = extractFloat ## s ## Sign( a ); \
- bSign = extractFloat ## s ## Sign( b ); \
av = float ## s ## _val(a); \
bv = float ## s ## _val(b); \
if ( aSign != bSign ) { \
@@ -5667,11 +5680,16 @@ INLINE int float128_compare_internal( float128 a, float128 b,
int is_quiet STATUS_PARAM )
{
flag aSign, bSign;
-
- if (( ( extractFloat128Exp( a ) == 0x7fff ) &&
- ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) ||
- ( ( extractFloat128Exp( b ) == 0x7fff ) &&
- ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) {
+ int32 aExp, bExp;
+ bits64 aSig0, aSig1, bSig0, bSig1;
+
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
+ unpackFloat128( b, &bSig1, &bSig0, &bExp, &bSign STATUS_VAR );
+ if ( ( ( aExp == 0x7FFF )
+ && ( aSig0 | aSig1 ) )
+ || ( ( bExp == 0x7FFF )
+ && ( bSig0 | bSig1 ) )
+ ) {
if (!is_quiet ||
float128_is_signaling_nan( a ) ||
float128_is_signaling_nan( b ) ) {
@@ -5679,8 +5697,6 @@ INLINE int float128_compare_internal( float128 a, float128 b,
}
return float_relation_unordered;
}
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
if ( aSign != bSign ) {
if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0 ) {
/* zero case */
@@ -5714,9 +5730,7 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
int16 aExp;
bits32 aSig;
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
+ unpackFloat32( a, &aSig, &aExp, &aSign STATUS_VAR);
if ( aExp == 0xFF ) {
return a;
@@ -5737,9 +5751,7 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
int16 aExp;
bits64 aSig;
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
+ unpackFloat64( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FF ) {
return a;
@@ -5761,9 +5773,7 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
int16 aExp;
bits64 aSig;
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
+ unpackFloatx80( a, &aSig, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FF ) {
return a;
@@ -5784,10 +5794,7 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM )
int32 aExp;
bits64 aSig0, aSig1;
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
+ unpackFloat128( a, &aSig1, &aSig0, &aExp, &aSign STATUS_VAR );
if ( aExp == 0x7FFF ) {
return a;
}
@@ -180,7 +180,9 @@ enum {
float_flag_divbyzero = 4,
float_flag_overflow = 8,
float_flag_underflow = 16,
- float_flag_inexact = 32
+ float_flag_inexact = 32,
+ /* Not strictly an IEEE flag, but implemented on several architectures. */
+ float_flag_input_denormal = 64
};
typedef struct float_status {
@@ -190,15 +192,20 @@ typedef struct float_status {
#ifdef FLOATX80
signed char floatx80_rounding_precision;
#endif
- flag flush_to_zero;
+ flag flush_inputs_to_zero;
+ flag flush_outputs_to_zero;
flag default_nan_mode;
} float_status;
void set_float_rounding_mode(int val STATUS_PARAM);
void set_float_exception_flags(int val STATUS_PARAM);
-INLINE void set_flush_to_zero(flag val STATUS_PARAM)
+INLINE void set_flush_inputs_to_zero(flag val STATUS_PARAM)
{
- STATUS(flush_to_zero) = val;
+ STATUS(flush_inputs_to_zero) = val;
+}
+INLINE void set_flush_outputs_to_zero(flag val STATUS_PARAM)
+{
+ STATUS(flush_outputs_to_zero) = val;
}
INLINE void set_default_nan_mode(flag val STATUS_PARAM)
{
@@ -2209,6 +2209,8 @@ static inline int vfp_exceptbits_from_host(int host_bits)
target_bits |= 8;
if (host_bits & float_flag_inexact)
target_bits |= 0x10;
+ if (host_bits & float_flag_input_denormal)
+ target_bits |= 0x80;
return target_bits;
}
@@ -2240,6 +2242,8 @@ static inline int vfp_exceptbits_to_host(int target_bits)
host_bits |= float_flag_underflow;
if (target_bits & 0x10)
host_bits |= float_flag_inexact;
+ if (target_bits & 0x80)
+ host_bits |= float_flag_input_denormal;
return host_bits;
}
@@ -2272,8 +2276,11 @@ void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
}
set_float_rounding_mode(i, &env->vfp.fp_status);
}
- if (changed & (1 << 24))
- set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
+ if (changed & (1 << 24)) {
+ i = (val & (1 << 24)) != 0;
+ set_flush_inputs_to_zero(i, &env->vfp.fp_status);
+ set_flush_outputs_to_zero(i, &env->vfp.fp_status);
+ }
if (changed & (1 << 25))
set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status);
@@ -1897,8 +1897,14 @@ static unsigned int ieee_rm[] = {
#define RESTORE_ROUNDING_MODE \
set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], &env->active_fpu.fp_status)
+/* FIXME: On most MIPS Technologies chips, there are other flags that interact with
+ FS in interesting ways. */
#define RESTORE_FLUSH_MODE \
- set_flush_to_zero((env->active_fpu.fcr31 & (1 << 24)) != 0, &env->active_fpu.fp_status);
+ do { \
+ int flag = (env->active_fpu.fcr31 & (1 << 24)) != 0; \
+ set_flush_inputs_to_zero(flag, &env->active_fpu.fp_status); \
+ set_flush_outputs_to_zero(flag, &env->active_fpu.fp_status); \
+ } while (0);
target_ulong helper_cfc1 (uint32_t reg)
{
@@ -2060,7 +2060,7 @@ void helper_mtvscr (ppc_avr_t *r)
#else
env->vscr = r->u32[0];
#endif
- set_flush_to_zero(vscr_nj, &env->vec_status);
+ set_flush_outputs_to_zero(vscr_nj, &env->vec_status);
}
void helper_vaddcuw (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
@@ -507,7 +507,7 @@ static inline void vscr_init (CPUPPCState *env, uint32_t val)
env->vscr = val;
/* Altivec always uses round-to-nearest */
set_float_rounding_mode(float_round_nearest_even, &env->vec_status);
- set_flush_to_zero(vscr_nj, &env->vec_status);
+ set_flush_outputs_to_zero(vscr_nj, &env->vec_status);
}
#if defined(CONFIG_USER_ONLY)