[sim] added SoftFloat-3 source
[riscv-isa-sim.git] / softfloat / SoftFloat-3 / source / f32_mul.c
diff --git a/softfloat/SoftFloat-3/source/f32_mul.c b/softfloat/SoftFloat-3/source/f32_mul.c
new file mode 100755 (executable)
index 0000000..d49c1dd
--- /dev/null
@@ -0,0 +1,89 @@
+\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
+float32_t f32_mul( float32_t a, float32_t b )\r
+{\r
+    union ui32_f32 uA;\r
+    uint_fast32_t uiA;\r
+    bool signA;\r
+    int_fast16_t expA;\r
+    uint_fast32_t sigA;\r
+    union ui32_f32 uB;\r
+    uint_fast32_t uiB;\r
+    bool signB;\r
+    int_fast16_t expB;\r
+    uint_fast32_t sigB;\r
+    bool signZ;\r
+    uint_fast32_t magBits;\r
+    struct exp16_sig32 normExpSig;\r
+    int_fast16_t expZ;\r
+    uint_fast32_t sigZ, uiZ;\r
+    union ui32_f32 uZ;\r
+\r
+    uA.f = a;\r
+    uiA = uA.ui;\r
+    signA = signF32UI( uiA );\r
+    expA = expF32UI( uiA );\r
+    sigA = fracF32UI( uiA );\r
+    uB.f = b;\r
+    uiB = uB.ui;\r
+    signB = signF32UI( uiB );\r
+    expB = expF32UI( uiB );\r
+    sigB = fracF32UI( uiB );\r
+    signZ = signA ^ signB;\r
+    if ( expA == 0xFF ) {\r
+        if ( sigA || ( ( expB == 0xFF ) && sigB ) ) goto propagateNaN;\r
+        magBits = expB | sigB;\r
+        goto infArg;\r
+    }\r
+    if ( expB == 0xFF ) {\r
+        if ( sigB ) goto propagateNaN;\r
+        magBits = expA | sigA;\r
+        goto infArg;\r
+    }\r
+    if ( ! expA ) {\r
+        if ( ! sigA ) goto zero;\r
+        normExpSig = softfloat_normSubnormalF32Sig( sigA );\r
+        expA = normExpSig.exp;\r
+        sigA = normExpSig.sig;\r
+    }\r
+    if ( ! expB ) {\r
+        if ( ! sigB ) goto zero;\r
+        normExpSig = softfloat_normSubnormalF32Sig( sigB );\r
+        expB = normExpSig.exp;\r
+        sigB = normExpSig.sig;\r
+    }\r
+    expZ = expA + expB - 0x7F;\r
+    sigA = ( sigA | 0x00800000 )<<7;\r
+    sigB = ( sigB | 0x00800000 )<<8;\r
+    sigZ = softfloat_shortShift64RightJam( (uint_fast64_t) sigA * sigB, 32 );\r
+    if ( sigZ < 0x40000000 ) {\r
+        --expZ;\r
+        sigZ <<= 1;\r
+    }\r
+    return softfloat_roundPackToF32( signZ, expZ, sigZ );\r
+ propagateNaN:\r
+    uiZ = softfloat_propagateNaNF32UI( uiA, uiB );\r
+    goto uiZ;\r
+ infArg:\r
+    if ( ! magBits ) {\r
+        softfloat_raiseFlags( softfloat_flag_invalid );\r
+        uiZ = defaultNaNF32UI;\r
+    } else {\r
+        uiZ = packToF32UI( signZ, 0xFF, 0 );\r
+    }\r
+    goto uiZ;\r
+ zero:\r
+    uiZ = packToF32UI( signZ, 0, 0 );\r
+ uiZ:\r
+    uZ.ui = uiZ;\r
+    return uZ.f;\r
+\r
+}\r
+\r