|
@@ -3118,3 +3118,73 @@ floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
|
|
|
q = ( bSig <= aSig0 );
|
|
|
if ( q ) aSig0 -= bSig;
|
|
|
expDiff -= 64;
|
|
|
+ while ( 0 < expDiff ) {
|
|
|
+ q = estimateDiv128To64( aSig0, aSig1, bSig );
|
|
|
+ q = ( 2 < q ) ? q - 2 : 0;
|
|
|
+ mul64To128( bSig, q, &term0, &term1 );
|
|
|
+ sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
|
|
|
+ shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
|
|
|
+ expDiff -= 62;
|
|
|
+ }
|
|
|
+ expDiff += 64;
|
|
|
+ if ( 0 < expDiff ) {
|
|
|
+ q = estimateDiv128To64( aSig0, aSig1, bSig );
|
|
|
+ q = ( 2 < q ) ? q - 2 : 0;
|
|
|
+ q >>= 64 - expDiff;
|
|
|
+ mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
|
|
|
+ sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
|
|
|
+ shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
|
|
|
+ while ( le128( term0, term1, aSig0, aSig1 ) ) {
|
|
|
+ ++q;
|
|
|
+ sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ term1 = 0;
|
|
|
+ term0 = bSig;
|
|
|
+ }
|
|
|
+ sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
|
|
|
+ if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
|
|
|
+ || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
|
|
|
+ && ( q & 1 ) )
|
|
|
+ ) {
|
|
|
+ aSig0 = alternateASig0;
|
|
|
+ aSig1 = alternateASig1;
|
|
|
+ zSign = ! zSign;
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+ normalizeRoundAndPackFloatx80(
|
|
|
+ roundData, zSign, bExp + expDiff, aSig0, aSig1 );
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+-------------------------------------------------------------------------------
|
|
|
+Returns the square root of the extended double-precision floating-point
|
|
|
+value `a'. The operation is performed according to the IEC/IEEE Standard
|
|
|
+for Binary Floating-point Arithmetic.
|
|
|
+-------------------------------------------------------------------------------
|
|
|
+*/
|
|
|
+floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
|
|
|
+{
|
|
|
+ flag aSign;
|
|
|
+ int32 aExp, zExp;
|
|
|
+ bits64 aSig0, aSig1, zSig0, zSig1;
|
|
|
+ bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
|
|
|
+ bits64 shiftedRem0, shiftedRem1;
|
|
|
+ floatx80 z;
|
|
|
+
|
|
|
+ aSig0 = extractFloatx80Frac( a );
|
|
|
+ aExp = extractFloatx80Exp( a );
|
|
|
+ aSign = extractFloatx80Sign( a );
|
|
|
+ if ( aExp == 0x7FFF ) {
|
|
|
+ if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a );
|
|
|
+ if ( ! aSign ) return a;
|
|
|
+ goto invalid;
|
|
|
+ }
|
|
|
+ if ( aSign ) {
|
|
|
+ if ( ( aExp | aSig0 ) == 0 ) return a;
|
|
|
+ invalid:
|
|
|
+ roundData->exception |= float_flag_invalid;
|
|
|
+ z.low = floatx80_default_nan_low;
|