[sim] made softfloat files C instead of C++
[riscv-isa-sim.git] / softfloat / f64_sqrt.c
diff --git a/softfloat/f64_sqrt.c b/softfloat/f64_sqrt.c
new file mode 100755 (executable)
index 0000000..cd91010
--- /dev/null
@@ -0,0 +1,74 @@
+\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