MCPcopy Create free account
hub / github.com/BlitterStudio/amiberry / floatx80_sqrt

Function floatx80_sqrt

src/softfloat/softfloat.cpp:3090–3152  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3088*----------------------------------------------------------------------------*/
3089
3090floatx80 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 }

Callers 3

fp_sqrtFunction · 0.85
floatx80_acosFunction · 0.85
floatx80_asinFunction · 0.85

Calls 15

float_raiseFunction · 0.85
floatx80_default_nanFunction · 0.85
extractFloatx80FracFunction · 0.85
extractFloatx80ExpFunction · 0.85
extractFloatx80SignFunction · 0.85
inf_clear_intbitFunction · 0.85
packFloatx80Function · 0.85
estimateSqrt32Function · 0.85
shift128RightFunction · 0.85

Tested by

no test coverage detected