|
@@ -3188,3 +3188,175 @@ floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
|
|
invalid:
|
|
invalid:
|
|
roundData->exception |= float_flag_invalid;
|
|
roundData->exception |= float_flag_invalid;
|
|
z.low = floatx80_default_nan_low;
|
|
z.low = floatx80_default_nan_low;
|
|
|
|
+ z.high = floatx80_default_nan_high;
|
|
|
|
+ z.__padding = 0;
|
|
|
|
+ return z;
|
|
|
|
+ }
|
|
|
|
+ if ( aExp == 0 ) {
|
|
|
|
+ if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
|
|
|
|
+ normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
|
|
|
|
+ }
|
|
|
|
+ zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
|
|
|
|
+ zSig0 = estimateSqrt32( aExp, aSig0>>32 );
|
|
|
|
+ zSig0 <<= 31;
|
|
|
|
+ aSig1 = 0;
|
|
|
|
+ shift128Right( aSig0, 0, ( aExp & 1 ) + 2, &aSig0, &aSig1 );
|
|
|
|
+ zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0 ) + zSig0 + 4;
|
|
|
|
+ if ( 0 <= (sbits64) zSig0 ) zSig0 = LIT64( 0xFFFFFFFFFFFFFFFF );
|
|
|
|
+ shortShift128Left( aSig0, aSig1, 2, &aSig0, &aSig1 );
|
|
|
|
+ mul64To128( zSig0, zSig0, &term0, &term1 );
|
|
|
|
+ sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
|
|
|
|
+ while ( (sbits64) rem0 < 0 ) {
|
|
|
|
+ --zSig0;
|
|
|
|
+ shortShift128Left( 0, zSig0, 1, &term0, &term1 );
|
|
|
|
+ term1 |= 1;
|
|
|
|
+ add128( rem0, rem1, term0, term1, &rem0, &rem1 );
|
|
|
|
+ }
|
|
|
|
+ shortShift128Left( rem0, rem1, 63, &shiftedRem0, &shiftedRem1 );
|
|
|
|
+ zSig1 = estimateDiv128To64( shiftedRem0, shiftedRem1, zSig0 );
|
|
|
|
+ if ( (bits64) ( zSig1<<1 ) <= 10 ) {
|
|
|
|
+ if ( zSig1 == 0 ) zSig1 = 1;
|
|
|
|
+ mul64To128( zSig0, zSig1, &term1, &term2 );
|
|
|
|
+ shortShift128Left( term1, term2, 1, &term1, &term2 );
|
|
|
|
+ sub128( rem1, 0, term1, term2, &rem1, &rem2 );
|
|
|
|
+ mul64To128( zSig1, zSig1, &term2, &term3 );
|
|
|
|
+ sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
|
|
|
|
+ while ( (sbits64) rem1 < 0 ) {
|
|
|
|
+ --zSig1;
|
|
|
|
+ shortShift192Left( 0, zSig0, zSig1, 1, &term1, &term2, &term3 );
|
|
|
|
+ term3 |= 1;
|
|
|
|
+ add192(
|
|
|
|
+ rem1, rem2, rem3, term1, term2, term3, &rem1, &rem2, &rem3 );
|
|
|
|
+ }
|
|
|
|
+ zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ roundAndPackFloatx80(
|
|
|
|
+ roundData, 0, zExp, zSig0, zSig1 );
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+-------------------------------------------------------------------------------
|
|
|
|
+Returns 1 if the extended double-precision floating-point value `a' is
|
|
|
|
+equal to the corresponding value `b', and 0 otherwise. The comparison is
|
|
|
|
+performed according to the IEC/IEEE Standard for Binary Floating-point
|
|
|
|
+Arithmetic.
|
|
|
|
+-------------------------------------------------------------------------------
|
|
|
|
+*/
|
|
|
|
+flag floatx80_eq( floatx80 a, floatx80 b )
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
|
|
|
+ && (bits64) ( extractFloatx80Frac( a )<<1 ) )
|
|
|
|
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
|
|
|
+ && (bits64) ( extractFloatx80Frac( b )<<1 ) )
|
|
|
|
+ ) {
|
|
|
|
+ if ( floatx80_is_signaling_nan( a )
|
|
|
|
+ || floatx80_is_signaling_nan( b ) ) {
|
|
|
|
+ float_raise( float_flag_invalid );
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ ( a.low == b.low )
|
|
|
|
+ && ( ( a.high == b.high )
|
|
|
|
+ || ( ( a.low == 0 )
|
|
|
|
+ && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+-------------------------------------------------------------------------------
|
|
|
|
+Returns 1 if the extended double-precision floating-point value `a' is
|
|
|
|
+less than or equal to the corresponding value `b', and 0 otherwise. The
|
|
|
|
+comparison is performed according to the IEC/IEEE Standard for Binary
|
|
|
|
+Floating-point Arithmetic.
|
|
|
|
+-------------------------------------------------------------------------------
|
|
|
|
+*/
|
|
|
|
+flag floatx80_le( floatx80 a, floatx80 b )
|
|
|
|
+{
|
|
|
|
+ flag aSign, bSign;
|
|
|
|
+
|
|
|
|
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
|
|
|
+ && (bits64) ( extractFloatx80Frac( a )<<1 ) )
|
|
|
|
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
|
|
|
+ && (bits64) ( extractFloatx80Frac( b )<<1 ) )
|
|
|
|
+ ) {
|
|
|
|
+ float_raise( float_flag_invalid );
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ aSign = extractFloatx80Sign( a );
|
|
|
|
+ bSign = extractFloatx80Sign( b );
|
|
|
|
+ if ( aSign != bSign ) {
|
|
|
|
+ return
|
|
|
|
+ aSign
|
|
|
|
+ || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
|
|
|
|
+ == 0 );
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ aSign ? le128( b.high, b.low, a.high, a.low )
|
|
|
|
+ : le128( a.high, a.low, b.high, b.low );
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+-------------------------------------------------------------------------------
|
|
|
|
+Returns 1 if the extended double-precision floating-point value `a' is
|
|
|
|
+less than the corresponding value `b', and 0 otherwise. The comparison
|
|
|
|
+is performed according to the IEC/IEEE Standard for Binary Floating-point
|
|
|
|
+Arithmetic.
|
|
|
|
+-------------------------------------------------------------------------------
|
|
|
|
+*/
|
|
|
|
+flag floatx80_lt( floatx80 a, floatx80 b )
|
|
|
|
+{
|
|
|
|
+ flag aSign, bSign;
|
|
|
|
+
|
|
|
|
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
|
|
|
+ && (bits64) ( extractFloatx80Frac( a )<<1 ) )
|
|
|
|
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
|
|
|
+ && (bits64) ( extractFloatx80Frac( b )<<1 ) )
|
|
|
|
+ ) {
|
|
|
|
+ float_raise( float_flag_invalid );
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ aSign = extractFloatx80Sign( a );
|
|
|
|
+ bSign = extractFloatx80Sign( b );
|
|
|
|
+ if ( aSign != bSign ) {
|
|
|
|
+ return
|
|
|
|
+ aSign
|
|
|
|
+ && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
|
|
|
|
+ != 0 );
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ aSign ? lt128( b.high, b.low, a.high, a.low )
|
|
|
|
+ : lt128( a.high, a.low, b.high, b.low );
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+-------------------------------------------------------------------------------
|
|
|
|
+Returns 1 if the extended double-precision floating-point value `a' is equal
|
|
|
|
+to the corresponding value `b', and 0 otherwise. The invalid exception is
|
|
|
|
+raised if either operand is a NaN. Otherwise, the comparison is performed
|
|
|
|
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
|
|
|
|
+-------------------------------------------------------------------------------
|
|
|
|
+*/
|
|
|
|
+flag floatx80_eq_signaling( floatx80 a, floatx80 b )
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
|
|
|
+ && (bits64) ( extractFloatx80Frac( a )<<1 ) )
|
|
|
|
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
|
|
|
+ && (bits64) ( extractFloatx80Frac( b )<<1 ) )
|
|
|
|
+ ) {
|
|
|
|
+ float_raise( float_flag_invalid );
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ ( a.low == b.low )
|
|
|
|
+ && ( ( a.high == b.high )
|
|
|
|
+ || ( ( a.low == 0 )
|
|
|
|
+ && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
|
|
|
|
+ );
|