diff options
author | Andrew Waterman <andrew@sifive.com> | 2017-09-24 20:25:34 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2017-09-24 20:25:34 -0700 |
commit | bd85811c35ea38180d27440507fc222d585ef780 (patch) | |
tree | 214c6b615d7775f73da5ff9a94bd4a0a2772f9cf /softfloat/s_mulAddF32.c | |
parent | b86f2a51f522f020ad0d90f598f4c501f41da232 (diff) | |
download | riscv-isa-sim-bd85811c35ea38180d27440507fc222d585ef780.zip riscv-isa-sim-bd85811c35ea38180d27440507fc222d585ef780.tar.gz riscv-isa-sim-bd85811c35ea38180d27440507fc222d585ef780.tar.bz2 |
Update SoftFloat
Diffstat (limited to 'softfloat/s_mulAddF32.c')
-rw-r--r-- | softfloat/s_mulAddF32.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/softfloat/s_mulAddF32.c b/softfloat/s_mulAddF32.c index 7b0ac6f..d163ea0 100644 --- a/softfloat/s_mulAddF32.c +++ b/softfloat/s_mulAddF32.c @@ -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: @@ -64,9 +64,11 @@ float32_t uint_fast32_t sigZ; int_fast16_t expDiff; uint_fast64_t sig64Z, sig64C; - int_fast8_t shiftCount; + int_fast8_t shiftDist; union ui32_f32 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ signA = signF32UI( uiA ); expA = expF32UI( uiA ); sigA = fracF32UI( uiA ); @@ -77,6 +79,8 @@ float32_t expC = expF32UI( uiC ); sigC = fracF32UI( uiC ); signProd = signA ^ signB ^ (op == softfloat_mulAdd_subProd); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( expA == 0xFF ) { if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN_ABC; magBits = expB | sigB; @@ -95,6 +99,8 @@ float32_t uiZ = uiC; goto uiZ; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( ! expA ) { if ( ! sigA ) goto zeroProd; normExpSig = softfloat_normSubnormalF32Sig( sigA ); @@ -107,6 +113,8 @@ float32_t expB = normExpSig.exp; sigB = normExpSig.sig; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ expProd = expA + expB - 0x7E; sigA = (sigA | 0x00800000)<<7; sigB = (sigB | 0x00800000)<<7; @@ -127,8 +135,12 @@ float32_t sigC = normExpSig.sig; } sigC = (sigC | 0x00800000)<<6; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ expDiff = expProd - expC; if ( signProd == signC ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ if ( expDiff <= 0 ) { expZ = expC; sigZ = sigC + softfloat_shiftRightJam64( sigProd, 32 - expDiff ); @@ -145,6 +157,8 @@ float32_t sigZ <<= 1; } } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ sig64C = (uint_fast64_t) sigC<<32; if ( expDiff < 0 ) { signZ = signC; @@ -155,27 +169,31 @@ float32_t sig64Z = sigProd - sig64C; if ( ! sig64Z ) goto completeCancellation; if ( sig64Z & UINT64_C( 0x8000000000000000 ) ) { - signZ ^= 1; + signZ = ! signZ; sig64Z = -sig64Z; } } else { expZ = expProd; sig64Z = sigProd - softfloat_shiftRightJam64( sig64C, expDiff ); } - shiftCount = softfloat_countLeadingZeros64( sig64Z ) - 1; - expZ -= shiftCount; - shiftCount -= 32; - if ( shiftCount < 0 ) { - sigZ = softfloat_shortShiftRightJam64( sig64Z, -shiftCount ); + shiftDist = softfloat_countLeadingZeros64( sig64Z ) - 1; + expZ -= shiftDist; + shiftDist -= 32; + if ( shiftDist < 0 ) { + sigZ = softfloat_shortShiftRightJam64( sig64Z, -shiftDist ); } else { - sigZ = (uint_fast32_t) sig64Z<<shiftCount; + sigZ = (uint_fast32_t) sig64Z<<shiftDist; } } roundPack: return softfloat_roundPackToF32( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ propagateNaN_ABC: uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); goto propagateNaN_ZC; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ infProdArg: if ( magBits ) { uiZ = packToF32UI( signProd, 0xFF, 0 ); @@ -183,18 +201,20 @@ float32_t if ( sigC ) goto propagateNaN_ZC; if ( signProd == signC ) goto uiZ; } - invalid: softfloat_raiseFlags( softfloat_flag_invalid ); uiZ = defaultNaNF32UI; propagateNaN_ZC: uiZ = softfloat_propagateNaNF32UI( uiZ, uiC ); goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ zeroProd: uiZ = uiC; if ( ! (expC | sigC) && (signProd != signC) ) { completeCancellation: uiZ = - packToF32UI( softfloat_roundingMode == softfloat_round_min, 0, 0 ); + packToF32UI( + (softfloat_roundingMode == softfloat_round_min), 0, 0 ); } uiZ: uZ.ui = uiZ; |