| 3088 | *----------------------------------------------------------------------------*/ |
| 3089 | |
| 3090 | floatx80 floatx80_sqrt(floatx80 a, float_status *status) |
| 3091 | { |
| 3092 | flag aSign; |
| 3093 | int32_t aExp, zExp; |
| 3094 | uint64_t aSig0, aSig1, zSig0, zSig1, doubleZSig0; |
| 3095 | uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3; |
| 3096 | |
| 3097 | if (floatx80_invalid_encoding(a)) { |
| 3098 | float_raise(float_flag_invalid, status); |
| 3099 | return floatx80_default_nan(status); |
| 3100 | } |
| 3101 | aSig0 = extractFloatx80Frac( a ); |
| 3102 | aExp = extractFloatx80Exp( a ); |
| 3103 | aSign = extractFloatx80Sign( a ); |
| 3104 | if ( aExp == 0x7FFF ) { |
| 3105 | if ((uint64_t)(aSig0 << 1)) |
| 3106 | return propagateFloatx80NaNOneArg(a, status); |
| 3107 | if (!aSign) return inf_clear_intbit(status) ? packFloatx80(aSign, aExp, 0) : a; |
| 3108 | goto invalid; |
| 3109 | } |
| 3110 | if ( aSign ) { |
| 3111 | if ( ( aExp | aSig0 ) == 0 ) return a; |
| 3112 | invalid: |
| 3113 | float_raise(float_flag_invalid, status); |
| 3114 | return floatx80_default_nan(status); |
| 3115 | } |
| 3116 | if ( aExp == 0 ) { |
| 3117 | if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 ); |
| 3118 | normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); |
| 3119 | } |
| 3120 | zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; |
| 3121 | zSig0 = estimateSqrt32( aExp, aSig0>>32 ); |
| 3122 | shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 ); |
| 3123 | zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); |
| 3124 | doubleZSig0 = zSig0<<1; |
| 3125 | mul64To128( zSig0, zSig0, &term0, &term1 ); |
| 3126 | sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); |
| 3127 | while ( (int64_t) rem0 < 0 ) { |
| 3128 | --zSig0; |
| 3129 | doubleZSig0 -= 2; |
| 3130 | add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); |
| 3131 | } |
| 3132 | zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); |
| 3133 | if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) { |
| 3134 | if ( zSig1 == 0 ) zSig1 = 1; |
| 3135 | mul64To128( doubleZSig0, zSig1, &term1, &term2 ); |
| 3136 | sub128( rem1, 0, term1, term2, &rem1, &rem2 ); |
| 3137 | mul64To128( zSig1, zSig1, &term2, &term3 ); |
| 3138 | sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); |
| 3139 | while ( (int64_t) rem1 < 0 ) { |
| 3140 | --zSig1; |
| 3141 | shortShift128Left( 0, zSig1, 1, &term2, &term3 ); |
| 3142 | term3 |= 1; |
| 3143 | term2 |= doubleZSig0; |
| 3144 | add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); |
| 3145 | } |
| 3146 | zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); |
| 3147 | } |
no test coverage detected