--- /dev/null
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include "platform.h"\r
+#include "primitives.h"\r
+#include "internals.h"\r
+#include "specialize.h"\r
+#include "softfloat.h"\r
+\r
+float64_t f64_sqrt( float64_t a )\r
+{\r
+ union ui64_f64 uA;\r
+ uint_fast64_t uiA;\r
+ bool signA;\r
+ int_fast16_t expA;\r
+ uint_fast64_t sigA, uiZ;\r
+ struct exp16_sig64 normExpSig;\r
+ int_fast16_t expZ;\r
+ uint_fast32_t sigZ32;\r
+ uint_fast64_t sigZ;\r
+ struct uint128 term, rem;\r
+ union ui64_f64 uZ;\r
+\r
+ uA.f = a;\r
+ uiA = uA.ui;\r
+ signA = signF64UI( uiA );\r
+ expA = expF64UI( uiA );\r
+ sigA = fracF64UI( uiA );\r
+ if ( expA == 0x7FF ) {\r
+ if ( sigA ) {\r
+ uiZ = softfloat_propagateNaNF64UI( uiA, 0 );\r
+ goto uiZ;\r
+ }\r
+ if ( ! signA ) return a;\r
+ goto invalid;\r
+ }\r
+ if ( signA ) {\r
+ if ( ! ( expA | sigA ) ) return a;\r
+ goto invalid;\r
+ }\r
+ if ( ! expA ) {\r
+ if ( ! sigA ) return a;\r
+ normExpSig = softfloat_normSubnormalF64Sig( sigA );\r
+ expA = normExpSig.exp;\r
+ sigA = normExpSig.sig;\r
+ }\r
+ expZ = ( ( expA - 0x3FF )>>1 ) + 0x3FE;\r
+ sigA |= UINT64_C( 0x0010000000000000 );\r
+ sigZ32 = softfloat_estimateSqrt32( expA, sigA>>21 );\r
+ sigA <<= 9 - ( expA & 1 );\r
+ sigZ =\r
+ softfloat_estimateDiv128To64( sigA, 0, (uint_fast64_t) sigZ32<<32 )\r
+ + ( (uint_fast64_t) sigZ32<<30 );\r
+ if ( ( sigZ & 0x1FF ) <= 5 ) {\r
+ term = softfloat_mul64To128( sigZ, sigZ );\r
+ rem = softfloat_sub128( sigA, 0, term.v64, term.v0 );\r
+ while ( UINT64_C( 0x8000000000000000 ) <= rem.v64 ) {\r
+ --sigZ;\r
+ rem =\r
+ softfloat_add128(\r
+ rem.v64, rem.v0, sigZ>>63, (uint64_t) ( sigZ<<1 ) );\r
+ }\r
+ sigZ |= ( ( rem.v64 | rem.v0 ) != 0 );\r
+ }\r
+ return softfloat_roundPackToF64( 0, expZ, sigZ );\r
+ invalid:\r
+ softfloat_raiseFlags( softfloat_flag_invalid );\r
+ uiZ = defaultNaNF64UI;\r
+ uiZ:\r
+ uZ.ui = uiZ;\r
+ return uZ.f;\r
+\r
+}\r
+\r