Set impebreak.
[riscv-isa-sim.git] / softfloat / s_subMagsF32.c
index ba5ac9aae6ed907c6dd031b61e0ec8428e9ff01e..86e89f2ec3a852929a87d2b755257034a5dff648 100644 (file)
@@ -2,10 +2,10 @@
 /*============================================================================
 
 This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
-Package, Release 3a, by John R. Hauser.
+Package, Release 3d, by John R. Hauser.
 
-Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
-All rights reserved.
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California.  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
@@ -41,8 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "specialize.h"
 #include "softfloat.h"
 
-float32_t
- softfloat_subMagsF32( uint_fast32_t uiA, uint_fast32_t uiB, bool signZ )
+float32_t softfloat_subMagsF32( uint_fast32_t uiA, uint_fast32_t uiB )
 {
     int_fast16_t expA;
     uint_fast32_t sigA;
@@ -50,61 +49,90 @@ float32_t
     uint_fast32_t sigB;
     int_fast16_t expDiff;
     uint_fast32_t uiZ;
+    int_fast32_t sigDiff;
+    bool signZ;
+    int_fast8_t shiftDist;
     int_fast16_t expZ;
-    uint_fast32_t sigZ;
+    uint_fast32_t sigX, sigY;
     union ui32_f32 uZ;
 
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
     expA = expF32UI( uiA );
     sigA = fracF32UI( uiA );
     expB = expF32UI( uiB );
     sigB = fracF32UI( uiB );
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
     expDiff = expA - expB;
-    sigA <<= 7;
-    sigB <<= 7;
-    if ( 0 < expDiff ) goto expABigger;
-    if ( expDiff < 0 ) goto expBBigger;
-    if ( expA == 0xFF ) {
-        if ( sigA | sigB ) goto propagateNaN;
-        softfloat_raiseFlags( softfloat_flag_invalid );
-        uiZ = defaultNaNF32UI;
+    if ( ! expDiff ) {
+        /*--------------------------------------------------------------------
+        *--------------------------------------------------------------------*/
+        if ( expA == 0xFF ) {
+            if ( sigA | sigB ) goto propagateNaN;
+            softfloat_raiseFlags( softfloat_flag_invalid );
+            uiZ = defaultNaNF32UI;
+            goto uiZ;
+        }
+        sigDiff = sigA - sigB;
+        if ( ! sigDiff ) {
+            uiZ =
+                packToF32UI(
+                    (softfloat_roundingMode == softfloat_round_min), 0, 0 );
+            goto uiZ;
+        }
+        if ( expA ) --expA;
+        signZ = signF32UI( uiA );
+        if ( sigDiff < 0 ) {
+            signZ = ! signZ;
+            sigDiff = -sigDiff;
+        }
+        shiftDist = softfloat_countLeadingZeros32( sigDiff ) - 8;
+        expZ = expA - shiftDist;
+        if ( expZ < 0 ) {
+            shiftDist = expA;
+            expZ = 0;
+        }
+        uiZ = packToF32UI( signZ, expZ, sigDiff<<shiftDist );
         goto uiZ;
+    } else {
+        /*--------------------------------------------------------------------
+        *--------------------------------------------------------------------*/
+        signZ = signF32UI( uiA );
+        sigA <<= 7;
+        sigB <<= 7;
+        if ( expDiff < 0 ) {
+            /*----------------------------------------------------------------
+            *----------------------------------------------------------------*/
+            signZ = ! signZ;
+            if ( expB == 0xFF ) {
+                if ( sigB ) goto propagateNaN;
+                uiZ = packToF32UI( signZ, 0xFF, 0 );
+                goto uiZ;
+            }
+            expZ = expB - 1;
+            sigX = sigB | 0x40000000;
+            sigY = sigA + (expA ? 0x40000000 : sigA);
+            expDiff = -expDiff;
+        } else {
+            /*----------------------------------------------------------------
+            *----------------------------------------------------------------*/
+            if ( expA == 0xFF ) {
+                if ( sigA ) goto propagateNaN;
+                uiZ = uiA;
+                goto uiZ;
+            }
+            expZ = expA - 1;
+            sigX = sigA | 0x40000000;
+            sigY = sigB + (expB ? 0x40000000 : sigB);
+        }
+        return
+            softfloat_normRoundPackToF32(
+                signZ, expZ, sigX - softfloat_shiftRightJam32( sigY, expDiff )
+            );
     }
-    if ( ! expA ) {
-        expA = 1;
-        expB = 1;
-    }
-    if ( sigB < sigA ) goto aBigger;
-    if ( sigA < sigB ) goto bBigger;
-    uiZ = packToF32UI( softfloat_roundingMode == softfloat_round_min, 0, 0 );
-    goto uiZ;
- expBBigger:
-    if ( expB == 0xFF ) {
-        if ( sigB ) goto propagateNaN;
-        uiZ = packToF32UI( signZ ^ 1, 0xFF, 0 );
-        goto uiZ;
-    }
-    sigA += expA ? 0x40000000 : sigA;
-    sigA = softfloat_shiftRightJam32( sigA, -expDiff );
-    sigB |= 0x40000000;
- bBigger:
-    signZ ^= 1;
-    expZ = expB;
-    sigZ = sigB - sigA;
-    goto normRoundPack;
- expABigger:
-    if ( expA == 0xFF ) {
-        if ( sigA ) goto propagateNaN;
-        uiZ = uiA;
-        goto uiZ;
-    }
-    sigB += expB ? 0x40000000 : sigB;
-    sigB = softfloat_shiftRightJam32( sigB, expDiff );
-    sigA |= 0x40000000;
- aBigger:
-    expZ = expA;
-    sigZ = sigA - sigB;
- normRoundPack:
-    return softfloat_normRoundPackToF32( signZ, expZ - 1, sigZ );
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
  propagateNaN:
     uiZ = softfloat_propagateNaNF32UI( uiA, uiB );
  uiZ: