diff options
218 files changed, 11195 insertions, 1068 deletions
diff --git a/softfloat/f128_add.c b/softfloat/f128_add.c new file mode 100644 index 0000000..6568ab6 --- /dev/null +++ b/softfloat/f128_add.c @@ -0,0 +1,78 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float128_t f128_add( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool signA; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + bool signB; +#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) + float128_t + (*magsFuncPtr)( + uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); +#endif + + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + signA = signF128UI64( uiA64 ); + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + signB = signF128UI64( uiB64 ); +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) + if ( signA == signB ) { + return softfloat_addMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); + } else { + return softfloat_subMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); + } +#else + magsFuncPtr = + (signA == signB) ? softfloat_addMagsF128 : softfloat_subMagsF128; + return (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); +#endif + +} + diff --git a/softfloat/f128_classify.c b/softfloat/f128_classify.c new file mode 100755 index 0000000..1092a9b --- /dev/null +++ b/softfloat/f128_classify.c @@ -0,0 +1,37 @@ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast16_t f128_classify( float128_t a ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + + uint_fast16_t infOrNaN = expF128UI64( uiA64 ) == 0x7FFF; + uint_fast16_t subnormalOrZero = expF128UI64( uiA64 ) == 0; + bool sign = signF128UI64( uiA64 ); + bool fracZero = fracF128UI64( uiA64 ) == 0 && uiA0 == 0; + bool isNaN = isNaNF128UI( uiA64, uiA0 ); + bool isSNaN = softfloat_isSigNaNF128UI( uiA64, uiA0 ); + + return + ( sign && infOrNaN && fracZero ) << 0 | + ( sign && !infOrNaN && !subnormalOrZero ) << 1 | + ( sign && subnormalOrZero && !fracZero ) << 2 | + ( sign && subnormalOrZero && fracZero ) << 3 | + ( !sign && infOrNaN && fracZero ) << 7 | + ( !sign && !infOrNaN && !subnormalOrZero ) << 6 | + ( !sign && subnormalOrZero && !fracZero ) << 5 | + ( !sign && subnormalOrZero && fracZero ) << 4 | + ( isNaN && isSNaN ) << 8 | + ( isNaN && !isSNaN ) << 9; +} + diff --git a/softfloat/f128_div.c b/softfloat/f128_div.c new file mode 100644 index 0000000..9384e75 --- /dev/null +++ b/softfloat/f128_div.c @@ -0,0 +1,199 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f128_div( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool signA; + int_fast32_t expA; + struct uint128 sigA; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + bool signB; + int_fast32_t expB; + struct uint128 sigB; + bool signZ; + struct exp32_sig128 normExpSig; + int_fast32_t expZ; + struct uint128 rem; + uint_fast32_t recip32; + int ix; + uint_fast64_t q64; + uint_fast32_t q; + struct uint128 term; + uint_fast32_t qs[3]; + uint_fast64_t sigZExtra; + struct uint128 sigZ, uiZ; + union ui128_f128 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + signA = signF128UI64( uiA64 ); + expA = expF128UI64( uiA64 ); + sigA.v64 = fracF128UI64( uiA64 ); + sigA.v0 = uiA0; + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + signB = signF128UI64( uiB64 ); + expB = expF128UI64( uiB64 ); + sigB.v64 = fracF128UI64( uiB64 ); + sigB.v0 = uiB0; + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x7FFF ) { + if ( sigA.v64 | sigA.v0 ) goto propagateNaN; + if ( expB == 0x7FFF ) { + if ( sigB.v64 | sigB.v0 ) goto propagateNaN; + goto invalid; + } + goto infinity; + } + if ( expB == 0x7FFF ) { + if ( sigB.v64 | sigB.v0 ) goto propagateNaN; + goto zero; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expB ) { + if ( ! (sigB.v64 | sigB.v0) ) { + if ( ! (expA | sigA.v64 | sigA.v0) ) goto invalid; + softfloat_raiseFlags( softfloat_flag_infinite ); + goto infinity; + } + normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + if ( ! expA ) { + if ( ! (sigA.v64 | sigA.v0) ) goto zero; + normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA - expB + 0x3FFE; + sigA.v64 |= UINT64_C( 0x0001000000000000 ); + sigB.v64 |= UINT64_C( 0x0001000000000000 ); + rem = sigA; + if ( softfloat_lt128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 ) ) { + --expZ; + rem = softfloat_add128( sigA.v64, sigA.v0, sigA.v64, sigA.v0 ); + } + recip32 = softfloat_approxRecip32_1( sigB.v64>>17 ); + ix = 3; + for (;;) { + q64 = (uint_fast64_t) (uint32_t) (rem.v64>>19) * recip32; + q = (q64 + 0x80000000)>>32; + --ix; + if ( ix < 0 ) break; + rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); + term = softfloat_mul128By32( sigB.v64, sigB.v0, q ); + rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); + if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { + --q; + rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); + } + qs[ix] = q; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ((q + 1) & 7) < 2 ) { + rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); + term = softfloat_mul128By32( sigB.v64, sigB.v0, q ); + rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); + if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { + --q; + rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); + } else if ( softfloat_le128( sigB.v64, sigB.v0, rem.v64, rem.v0 ) ) { + ++q; + rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); + } + if ( rem.v64 | rem.v0 ) q |= 1; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigZExtra = (uint64_t) ((uint_fast64_t) q<<60); + term = softfloat_shortShiftLeft128( 0, qs[1], 54 ); + sigZ = + softfloat_add128( + (uint_fast64_t) qs[2]<<19, ((uint_fast64_t) qs[0]<<25) + (q>>4), + term.v64, term.v0 + ); + return + softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infinity: + uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 ); + goto uiZ0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + uiZ.v64 = packToF128UI64( signZ, 0, 0 ); + uiZ0: + uiZ.v0 = 0; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f128_eq.c b/softfloat/f128_eq.c new file mode 100644 index 0000000..a0e1ad2 --- /dev/null +++ b/softfloat/f128_eq.c @@ -0,0 +1,73 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +bool f128_eq( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { + if ( + softfloat_isSigNaNF128UI( uiA64, uiA0 ) + || softfloat_isSigNaNF128UI( uiB64, uiB0 ) + ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + } + return false; + } + return + (uiA0 == uiB0) + && ( (uiA64 == uiB64) + || (! uiA0 && ! ((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) + ); + +} + diff --git a/softfloat/f128_eq_signaling.c b/softfloat/f128_eq_signaling.c new file mode 100644 index 0000000..bd37b97 --- /dev/null +++ b/softfloat/f128_eq_signaling.c @@ -0,0 +1,67 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +bool f128_eq_signaling( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return false; + } + return + (uiA0 == uiB0) + && ( (uiA64 == uiB64) + || (! uiA0 && ! ((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) + ); + +} + diff --git a/softfloat/f128_isSignalingNaN.c b/softfloat/f128_isSignalingNaN.c new file mode 100644 index 0000000..fced58e --- /dev/null +++ b/softfloat/f128_isSignalingNaN.c @@ -0,0 +1,51 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +bool f128_isSignalingNaN( float128_t a ) +{ + union ui128_f128 uA; + + uA.f = a; + return softfloat_isSigNaNF128UI( uA.ui.v64, uA.ui.v0 ); + +} + diff --git a/softfloat/f128_le.c b/softfloat/f128_le.c new file mode 100644 index 0000000..9b0aa23 --- /dev/null +++ b/softfloat/f128_le.c @@ -0,0 +1,72 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +bool f128_le( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + bool signA, signB; + + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return false; + } + signA = signF128UI64( uiA64 ); + signB = signF128UI64( uiB64 ); + return + (signA != signB) + ? signA + || ! (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + | uiA0 | uiB0) + : ((uiA64 == uiB64) && (uiA0 == uiB0)) + || (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); + +} + diff --git a/softfloat/f128_le_quiet.c b/softfloat/f128_le_quiet.c new file mode 100644 index 0000000..3b44038 --- /dev/null +++ b/softfloat/f128_le_quiet.c @@ -0,0 +1,78 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +bool f128_le_quiet( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + bool signA, signB; + + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { + if ( + softfloat_isSigNaNF128UI( uiA64, uiA0 ) + || softfloat_isSigNaNF128UI( uiB64, uiB0 ) + ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + } + return false; + } + signA = signF128UI64( uiA64 ); + signB = signF128UI64( uiB64 ); + return + (signA != signB) + ? signA + || ! (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + | uiA0 | uiB0) + : ((uiA64 == uiB64) && (uiA0 == uiB0)) + || (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); + +} + diff --git a/softfloat/f128_lt.c b/softfloat/f128_lt.c new file mode 100644 index 0000000..a28f95b --- /dev/null +++ b/softfloat/f128_lt.c @@ -0,0 +1,72 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +bool f128_lt( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + bool signA, signB; + + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return false; + } + signA = signF128UI64( uiA64 ); + signB = signF128UI64( uiB64 ); + return + (signA != signB) + ? signA + && (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + | uiA0 | uiB0) + : ((uiA64 != uiB64) || (uiA0 != uiB0)) + && (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); + +} + diff --git a/softfloat/f128_lt_quiet.c b/softfloat/f128_lt_quiet.c new file mode 100644 index 0000000..20146ee --- /dev/null +++ b/softfloat/f128_lt_quiet.c @@ -0,0 +1,78 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +bool f128_lt_quiet( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + bool signA, signB; + + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { + if ( + softfloat_isSigNaNF128UI( uiA64, uiA0 ) + || softfloat_isSigNaNF128UI( uiB64, uiB0 ) + ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + } + return false; + } + signA = signF128UI64( uiA64 ); + signB = signF128UI64( uiB64 ); + return + (signA != signB) + ? signA + && (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + | uiA0 | uiB0) + : ((uiA64 != uiB64) || (uiA0 != uiB0)) + && (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); + +} + diff --git a/softfloat/f128_mul.c b/softfloat/f128_mul.c new file mode 100644 index 0000000..1871613 --- /dev/null +++ b/softfloat/f128_mul.c @@ -0,0 +1,163 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f128_mul( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool signA; + int_fast32_t expA; + struct uint128 sigA; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + bool signB; + int_fast32_t expB; + struct uint128 sigB; + bool signZ; + uint_fast64_t magBits; + struct exp32_sig128 normExpSig; + int_fast32_t expZ; + uint64_t sig256Z[4]; + uint_fast64_t sigZExtra; + struct uint128 sigZ; + struct uint128_extra sig128Extra; + struct uint128 uiZ; + union ui128_f128 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + signA = signF128UI64( uiA64 ); + expA = expF128UI64( uiA64 ); + sigA.v64 = fracF128UI64( uiA64 ); + sigA.v0 = uiA0; + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + signB = signF128UI64( uiB64 ); + expB = expF128UI64( uiB64 ); + sigB.v64 = fracF128UI64( uiB64 ); + sigB.v0 = uiB0; + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x7FFF ) { + if ( + (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0)) + ) { + goto propagateNaN; + } + magBits = expB | sigB.v64 | sigB.v0; + goto infArg; + } + if ( expB == 0x7FFF ) { + if ( sigB.v64 | sigB.v0 ) goto propagateNaN; + magBits = expA | sigA.v64 | sigA.v0; + goto infArg; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! (sigA.v64 | sigA.v0) ) goto zero; + normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if ( ! expB ) { + if ( ! (sigB.v64 | sigB.v0) ) goto zero; + normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x4000; + sigA.v64 |= UINT64_C( 0x0001000000000000 ); + sigB = softfloat_shortShiftLeft128( sigB.v64, sigB.v0, 16 ); + softfloat_mul128To256M( sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z ); + sigZExtra = sig256Z[indexWord( 4, 1 )] | (sig256Z[indexWord( 4, 0 )] != 0); + sigZ = + softfloat_add128( + sig256Z[indexWord( 4, 3 )], sig256Z[indexWord( 4, 2 )], + sigA.v64, sigA.v0 + ); + if ( UINT64_C( 0x0002000000000000 ) <= sigZ.v64 ) { + ++expZ; + sig128Extra = + softfloat_shortShiftRightJam128Extra( + sigZ.v64, sigZ.v0, sigZExtra, 1 ); + sigZ = sig128Extra.v; + sigZExtra = sig128Extra.extra; + } + return + softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infArg: + if ( ! magBits ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + goto uiZ; + } + uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 ); + goto uiZ0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + uiZ.v64 = packToF128UI64( signZ, 0, 0 ); + uiZ0: + uiZ.v0 = 0; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f128_mulAdd.c b/softfloat/f128_mulAdd.c new file mode 100644 index 0000000..b2e2142 --- /dev/null +++ b/softfloat/f128_mulAdd.c @@ -0,0 +1,63 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float128_t f128_mulAdd( float128_t a, float128_t b, float128_t c ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + union ui128_f128 uC; + uint_fast64_t uiC64, uiC0; + + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + uC.f = c; + uiC64 = uC.ui.v64; + uiC0 = uC.ui.v0; + return softfloat_mulAddF128( uiA64, uiA0, uiB64, uiB0, uiC64, uiC0, 0 ); + +} + diff --git a/softfloat/f128_rem.c b/softfloat/f128_rem.c new file mode 100644 index 0000000..555d71e --- /dev/null +++ b/softfloat/f128_rem.c @@ -0,0 +1,190 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f128_rem( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool signA; + int_fast32_t expA; + struct uint128 sigA; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + int_fast32_t expB; + struct uint128 sigB; + struct exp32_sig128 normExpSig; + struct uint128 rem; + int_fast32_t expDiff; + uint_fast32_t q, recip32; + uint_fast64_t q64; + struct uint128 term, altRem, meanRem; + bool signRem; + struct uint128 uiZ; + union ui128_f128 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + signA = signF128UI64( uiA64 ); + expA = expF128UI64( uiA64 ); + sigA.v64 = fracF128UI64( uiA64 ); + sigA.v0 = uiA0; + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + expB = expF128UI64( uiB64 ); + sigB.v64 = fracF128UI64( uiB64 ); + sigB.v0 = uiB0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x7FFF ) { + if ( + (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0)) + ) { + goto propagateNaN; + } + goto invalid; + } + if ( expB == 0x7FFF ) { + if ( sigB.v64 | sigB.v0 ) goto propagateNaN; + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expB ) { + if ( ! (sigB.v64 | sigB.v0) ) goto invalid; + normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + if ( ! expA ) { + if ( ! (sigA.v64 | sigA.v0) ) return a; + normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigA.v64 |= UINT64_C( 0x0001000000000000 ); + sigB.v64 |= UINT64_C( 0x0001000000000000 ); + rem = sigA; + expDiff = expA - expB; + if ( expDiff < 1 ) { + if ( expDiff < -1 ) return a; + if ( expDiff ) { + --expB; + sigB = softfloat_add128( sigB.v64, sigB.v0, sigB.v64, sigB.v0 ); + q = 0; + } else { + q = softfloat_le128( sigB.v64, sigB.v0, rem.v64, rem.v0 ); + if ( q ) { + rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); + } + } + } else { + recip32 = softfloat_approxRecip32_1( sigB.v64>>17 ); + expDiff -= 30; + for (;;) { + q64 = (uint_fast64_t) (uint32_t) (rem.v64>>19) * recip32; + if ( expDiff < 0 ) break; + q = (q64 + 0x80000000)>>32; + rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); + term = softfloat_mul128By32( sigB.v64, sigB.v0, q ); + rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); + if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { + rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); + } + expDiff -= 29; + } + /*-------------------------------------------------------------------- + | (`expDiff' cannot be less than -29 here.) + *--------------------------------------------------------------------*/ + q = (uint32_t) (q64>>32)>>(~expDiff & 31); + rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, expDiff + 30 ); + term = softfloat_mul128By32( sigB.v64, sigB.v0, q ); + rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); + if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { + altRem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); + goto selectRem; + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + do { + altRem = rem; + ++q; + rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); + } while ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ); + selectRem: + meanRem = softfloat_add128( rem.v64, rem.v0, altRem.v64, altRem.v0 ); + if ( + (meanRem.v64 & UINT64_C( 0x8000000000000000 )) + || (! (meanRem.v64 | meanRem.v0) && (q & 1)) + ) { + rem = altRem; + } + signRem = signA; + if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { + signRem = ! signRem; + rem = softfloat_sub128( 0, 0, rem.v64, rem.v0 ); + } + return softfloat_normRoundPackToF128( signRem, expB - 1, rem.v64, rem.v0 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f128_roundToInt.c b/softfloat/f128_roundToInt.c new file mode 100644 index 0000000..0f1f07e --- /dev/null +++ b/softfloat/f128_roundToInt.c @@ -0,0 +1,160 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t + f128_roundToInt( float128_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + int_fast32_t exp; + struct uint128 uiZ; + uint_fast64_t lastBitMask, roundBitsMask; + bool roundNearEven; + union ui128_f128 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + exp = expF128UI64( uiA64 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( 0x402F <= exp ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( 0x406F <= exp ) { + if ( (exp == 0x7FFF) && (fracF128UI64( uiA64 ) | uiA0) ) { + uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, 0, 0 ); + goto uiZ; + } + return a; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + lastBitMask = (uint_fast64_t) 2<<(0x406E - exp); + roundBitsMask = lastBitMask - 1; + uiZ.v64 = uiA64; + uiZ.v0 = uiA0; + roundNearEven = (roundingMode == softfloat_round_near_even); + if ( roundNearEven || (roundingMode == softfloat_round_near_maxMag) ) { + if ( exp == 0x402F ) { + if ( UINT64_C( 0x8000000000000000 ) <= uiZ.v0 ) { + ++uiZ.v64; + if ( + roundNearEven + && (uiZ.v0 == UINT64_C( 0x8000000000000000 )) + ) { + uiZ.v64 &= ~1; + } + } + } else { + uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, lastBitMask>>1 ); + if ( roundNearEven && ! (uiZ.v0 & roundBitsMask) ) { + uiZ.v0 &= ~lastBitMask; + } + } + } else if ( + roundingMode + == (signF128UI64( uiZ.v64 ) ? softfloat_round_min + : softfloat_round_max) + ) { + uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, roundBitsMask ); + } + uiZ.v0 &= ~roundBitsMask; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( exp < 0x3FFF ) { + if ( ! ((uiA64 & UINT64_C( 0x7FFFFFFFFFFFFFFF )) | uiA0) ) { + return a; + } + if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; + uiZ.v64 = uiA64 & packToF128UI64( 1, 0, 0 ); + uiZ.v0 = 0; + switch ( roundingMode ) { + case softfloat_round_near_even: + if ( ! (fracF128UI64( uiA64 ) | uiA0) ) break; + case softfloat_round_near_maxMag: + if ( exp == 0x3FFE ) uiZ.v64 |= packToF128UI64( 0, 0x3FFF, 0 ); + break; + case softfloat_round_min: + if ( uiZ.v64 ) uiZ.v64 = packToF128UI64( 1, 0x3FFF, 0 ); + break; + case softfloat_round_max: + if ( ! uiZ.v64 ) uiZ.v64 = packToF128UI64( 0, 0x3FFF, 0 ); + break; + } + goto uiZ; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + uiZ.v64 = uiA64; + uiZ.v0 = 0; + lastBitMask = (uint_fast64_t) 1<<(0x402F - exp); + roundBitsMask = lastBitMask - 1; + if ( roundingMode == softfloat_round_near_maxMag ) { + uiZ.v64 += lastBitMask>>1; + } else if ( roundingMode == softfloat_round_near_even ) { + uiZ.v64 += lastBitMask>>1; + if ( ! ((uiZ.v64 & roundBitsMask) | uiA0) ) { + uiZ.v64 &= ~lastBitMask; + } + } else if ( + roundingMode + == (signF128UI64( uiZ.v64 ) ? softfloat_round_min + : softfloat_round_max) + ) { + uiZ.v64 = (uiZ.v64 | (uiA0 != 0)) + roundBitsMask; + } + uiZ.v64 &= ~roundBitsMask; + } + if ( exact && ((uiZ.v64 != uiA64) || (uiZ.v0 != uiA0)) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f128_sqrt.c b/softfloat/f128_sqrt.c new file mode 100644 index 0000000..5b99694 --- /dev/null +++ b/softfloat/f128_sqrt.c @@ -0,0 +1,201 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f128_sqrt( float128_t a ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool signA; + int_fast32_t expA; + struct uint128 sigA, uiZ; + struct exp32_sig128 normExpSig; + int_fast32_t expZ; + uint_fast32_t sig32A, recipSqrt32, sig32Z; + struct uint128 rem; + uint32_t qs[3]; + uint_fast32_t q; + uint_fast64_t x64, sig64Z; + struct uint128 y, term; + uint_fast64_t sigZExtra; + struct uint128 sigZ; + union ui128_f128 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + signA = signF128UI64( uiA64 ); + expA = expF128UI64( uiA64 ); + sigA.v64 = fracF128UI64( uiA64 ); + sigA.v0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x7FFF ) { + if ( sigA.v64 | sigA.v0 ) { + uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, 0, 0 ); + goto uiZ; + } + if ( ! signA ) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( signA ) { + if ( ! (expA | sigA.v64 | sigA.v0) ) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! (sigA.v64 | sigA.v0) ) return a; + normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + | (`sig32Z' is guaranteed to be a lower bound on the square root of + | `sig32A', which makes `sig32Z' also a lower bound on the square root of + | `sigA'.) + *------------------------------------------------------------------------*/ + expZ = ((expA - 0x3FFF)>>1) + 0x3FFE; + expA &= 1; + sigA.v64 |= UINT64_C( 0x0001000000000000 ); + sig32A = sigA.v64>>17; + recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A ); + sig32Z = ((uint_fast64_t) sig32A * recipSqrt32)>>32; + if ( expA ) { + sig32Z >>= 1; + rem = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 12 ); + } else { + rem = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 13 ); + } + qs[2] = sig32Z; + rem.v64 -= (uint_fast64_t) sig32Z * sig32Z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + q = ((uint32_t) (rem.v64>>2) * (uint_fast64_t) recipSqrt32)>>32; + x64 = (uint_fast64_t) sig32Z<<32; + sig64Z = x64 + ((uint_fast64_t) q<<3); + y = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); + /*------------------------------------------------------------------------ + | (Repeating this loop is a rare occurrence.) + *------------------------------------------------------------------------*/ + for (;;) { + term = softfloat_mul64ByShifted32To128( x64 + sig64Z, q ); + rem = softfloat_sub128( y.v64, y.v0, term.v64, term.v0 ); + if ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ) break; + --q; + sig64Z -= 1<<3; + } + qs[1] = q; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + q = ((rem.v64>>2) * recipSqrt32)>>32; + y = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); + sig64Z <<= 1; + /*------------------------------------------------------------------------ + | (Repeating this loop is a rare occurrence.) + *------------------------------------------------------------------------*/ + for (;;) { + term = softfloat_shortShiftLeft128( 0, sig64Z, 32 ); + term = softfloat_add128( term.v64, term.v0, 0, (uint_fast64_t) q<<6 ); + term = softfloat_mul128By32( term.v64, term.v0, q ); + rem = softfloat_sub128( y.v64, y.v0, term.v64, term.v0 ); + if ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ) break; + --q; + } + qs[0] = q; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + q = (((rem.v64>>2) * recipSqrt32)>>32) + 2; + sigZExtra = (uint64_t) ((uint_fast64_t) q<<59); + term = softfloat_shortShiftLeft128( 0, qs[1], 53 ); + sigZ = + softfloat_add128( + (uint_fast64_t) qs[2]<<18, ((uint_fast64_t) qs[0]<<24) + (q>>5), + term.v64, term.v0 + ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( (q & 0xF) <= 2 ) { + q &= ~3; + sigZExtra = (uint64_t) ((uint_fast64_t) q<<59); + y = softfloat_shortShiftLeft128( sigZ.v64, sigZ.v0, 6 ); + y.v0 |= sigZExtra>>58; + term = softfloat_sub128( y.v64, y.v0, 0, q ); + y = softfloat_mul64ByShifted32To128( term.v0, q ); + term = softfloat_mul64ByShifted32To128( term.v64, q ); + term = softfloat_add128( term.v64, term.v0, 0, y.v64 ); + rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 20 ); + term = softfloat_sub128( term.v64, term.v0, rem.v64, rem.v0 ); + /*-------------------------------------------------------------------- + | The concatenation of `term' and `y.v0' is now the negative remainder + | (3 words altogether). + *--------------------------------------------------------------------*/ + if ( term.v64 & UINT64_C( 0x8000000000000000 ) ) { + sigZExtra |= 1; + } else { + if ( term.v64 | term.v0 | y.v0 ) { + if ( sigZExtra ) { + --sigZExtra; + } else { + sigZ = softfloat_sub128( sigZ.v64, sigZ.v0, 0, 1 ); + sigZExtra = ~0; + } + } + } + } + return softfloat_roundPackToF128( 0, expZ, sigZ.v64, sigZ.v0, sigZExtra ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f128_sub.c b/softfloat/f128_sub.c new file mode 100644 index 0000000..ce2e5ad --- /dev/null +++ b/softfloat/f128_sub.c @@ -0,0 +1,78 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float128_t f128_sub( float128_t a, float128_t b ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool signA; + union ui128_f128 uB; + uint_fast64_t uiB64, uiB0; + bool signB; +#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) + float128_t + (*magsFuncPtr)( + uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); +#endif + + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + signA = signF128UI64( uiA64 ); + uB.f = b; + uiB64 = uB.ui.v64; + uiB0 = uB.ui.v0; + signB = signF128UI64( uiB64 ); +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) + if ( signA == signB ) { + return softfloat_subMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); + } else { + return softfloat_addMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); + } +#else + magsFuncPtr = + (signA == signB) ? softfloat_subMagsF128 : softfloat_addMagsF128; + return (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); +#endif + +} + diff --git a/softfloat/f128_to_f16.c b/softfloat/f128_to_f16.c new file mode 100644 index 0000000..a910c12 --- /dev/null +++ b/softfloat/f128_to_f16.c @@ -0,0 +1,95 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16_t f128_to_f16( float128_t a ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool sign; + int_fast32_t exp; + uint_fast64_t frac64; + struct commonNaN commonNaN; + uint_fast16_t uiZ, frac16; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + sign = signF128UI64( uiA64 ); + exp = expF128UI64( uiA64 ); + frac64 = fracF128UI64( uiA64 ) | (uiA0 != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x7FFF ) { + if ( frac64 ) { + softfloat_f128UIToCommonNaN( uiA64, uiA0, &commonNaN ); + uiZ = softfloat_commonNaNToF16UI( &commonNaN ); + } else { + uiZ = packToF16UI( sign, 0x1F, 0 ); + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac16 = softfloat_shortShiftRightJam64( frac64, 34 ); + if ( ! (exp | frac16) ) { + uiZ = packToF16UI( sign, 0, 0 ); + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp -= 0x3FF1; + if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) { + if ( exp < -0x40 ) exp = -0x40; + } + return softfloat_roundPackToF16( sign, exp, frac16 | 0x4000 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f128_to_f32.c b/softfloat/f128_to_f32.c new file mode 100644 index 0000000..d890d3e --- /dev/null +++ b/softfloat/f128_to_f32.c @@ -0,0 +1,95 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float32_t f128_to_f32( float128_t a ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool sign; + int_fast32_t exp; + uint_fast64_t frac64; + struct commonNaN commonNaN; + uint_fast32_t uiZ, frac32; + union ui32_f32 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + sign = signF128UI64( uiA64 ); + exp = expF128UI64( uiA64 ); + frac64 = fracF128UI64( uiA64 ) | (uiA0 != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x7FFF ) { + if ( frac64 ) { + softfloat_f128UIToCommonNaN( uiA64, uiA0, &commonNaN ); + uiZ = softfloat_commonNaNToF32UI( &commonNaN ); + } else { + uiZ = packToF32UI( sign, 0xFF, 0 ); + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac32 = softfloat_shortShiftRightJam64( frac64, 18 ); + if ( ! (exp | frac32) ) { + uiZ = packToF32UI( sign, 0, 0 ); + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp -= 0x3F81; + if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) { + if ( exp < -0x1000 ) exp = -0x1000; + } + return softfloat_roundPackToF32( sign, exp, frac32 | 0x40000000 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f128_to_f64.c b/softfloat/f128_to_f64.c new file mode 100644 index 0000000..e7aec20 --- /dev/null +++ b/softfloat/f128_to_f64.c @@ -0,0 +1,100 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float64_t f128_to_f64( float128_t a ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool sign; + int_fast32_t exp; + uint_fast64_t frac64, frac0; + struct commonNaN commonNaN; + uint_fast64_t uiZ; + struct uint128 frac128; + union ui64_f64 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + sign = signF128UI64( uiA64 ); + exp = expF128UI64( uiA64 ); + frac64 = fracF128UI64( uiA64 ); + frac0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x7FFF ) { + if ( frac64 | frac0 ) { + softfloat_f128UIToCommonNaN( uiA64, uiA0, &commonNaN ); + uiZ = softfloat_commonNaNToF64UI( &commonNaN ); + } else { + uiZ = packToF64UI( sign, 0x7FF, 0 ); + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac128 = softfloat_shortShiftLeft128( frac64, frac0, 14 ); + frac64 = frac128.v64 | (frac128.v0 != 0); + if ( ! (exp | frac64) ) { + uiZ = packToF64UI( sign, 0, 0 ); + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + exp -= 0x3C01; + if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) { + if ( exp < -0x1000 ) exp = -0x1000; + } + return + softfloat_roundPackToF64( + sign, exp, frac64 | UINT64_C( 0x4000000000000000 ) ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f128_to_i32.c b/softfloat/f128_to_i32.c new file mode 100644 index 0000000..507691c --- /dev/null +++ b/softfloat/f128_to_i32.c @@ -0,0 +1,85 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast32_t f128_to_i32( float128_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool sign; + int_fast32_t exp; + uint_fast64_t sig64, sig0; + int_fast32_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + sign = signF128UI64( uiA64 ); + exp = expF128UI64( uiA64 ); + sig64 = fracF128UI64( uiA64 ); + sig0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ( (exp == 0x7FFF) && (sig64 | sig0) ) { +#if (i32_fromNaN == i32_fromPosOverflow) + sign = 0; +#elif (i32_fromNaN == i32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags( softfloat_flag_invalid ); + return i32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); + sig64 |= (sig0 != 0); + shiftDist = 0x4023 - exp; + if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); + return softfloat_roundToI32( sign, sig64, roundingMode, exact ); + +} + diff --git a/softfloat/f128_to_i32_r_minMag.c b/softfloat/f128_to_i32_r_minMag.c new file mode 100644 index 0000000..fc9f84f --- /dev/null +++ b/softfloat/f128_to_i32_r_minMag.c @@ -0,0 +1,100 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast32_t f128_to_i32_r_minMag( float128_t a, bool exact ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + int_fast32_t exp; + uint_fast64_t sig64; + int_fast32_t shiftDist; + bool sign; + int_fast32_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + exp = expF128UI64( uiA64 ); + sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( 49 <= shiftDist ) { + if ( exact && (exp | sig64) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF128UI64( uiA64 ); + if ( shiftDist < 18 ) { + if ( + sign && (shiftDist == 17) + && (sig64 < UINT64_C( 0x0000000000020000 )) + ) { + if ( exact && sig64 ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return -0x7FFFFFFF - 1; + } + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FFF) && sig64 ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig64 |= UINT64_C( 0x0001000000000000 ); + absZ = sig64>>shiftDist; + if ( + exact && ((uint_fast64_t) (uint_fast32_t) absZ<<shiftDist != sig64) + ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return sign ? -absZ : absZ; + +} + diff --git a/softfloat/f128_to_i64.c b/softfloat/f128_to_i64.c new file mode 100644 index 0000000..2282eaf --- /dev/null +++ b/softfloat/f128_to_i64.c @@ -0,0 +1,95 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t f128_to_i64( float128_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool sign; + int_fast32_t exp; + uint_fast64_t sig64, sig0; + int_fast32_t shiftDist; + struct uint128 sig128; + struct uint64_extra sigExtra; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + sign = signF128UI64( uiA64 ); + exp = expF128UI64( uiA64 ); + sig64 = fracF128UI64( uiA64 ); + sig0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( shiftDist <= 0 ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( shiftDist < -15 ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64 |= UINT64_C( 0x0001000000000000 ); + if ( shiftDist ) { + sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftDist ); + sig64 = sig128.v64; + sig0 = sig128.v0; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); + sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftDist ); + sig64 = sigExtra.v; + sig0 = sigExtra.extra; + } + return softfloat_roundToI64( sign, sig64, sig0, roundingMode, exact ); + +} + diff --git a/softfloat/f128_to_i64_r_minMag.c b/softfloat/f128_to_i64_r_minMag.c new file mode 100644 index 0000000..7e0d63d --- /dev/null +++ b/softfloat/f128_to_i64_r_minMag.c @@ -0,0 +1,113 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t f128_to_i64_r_minMag( float128_t a, bool exact ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool sign; + int_fast32_t exp; + uint_fast64_t sig64, sig0; + int_fast32_t shiftDist; + int_fast8_t negShiftDist; + int_fast64_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + sign = signF128UI64( uiA64 ); + exp = expF128UI64( uiA64 ); + sig64 = fracF128UI64( uiA64 ); + sig0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( shiftDist < 0 ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( shiftDist < -14 ) { + if ( + (uiA64 == UINT64_C( 0xC03E000000000000 )) + && (sig0 < UINT64_C( 0x0002000000000000 )) + ) { + if ( exact && sig0 ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + } + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64 |= UINT64_C( 0x0001000000000000 ); + negShiftDist = -shiftDist; + absZ = sig64<<negShiftDist | sig0>>(shiftDist & 63); + if ( exact && (uint64_t) (sig0<<negShiftDist) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( 49 <= shiftDist ) { + if ( exact && (exp | sig64 | sig0) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64 |= UINT64_C( 0x0001000000000000 ); + absZ = sig64>>shiftDist; + if ( exact && (sig0 || (absZ<<shiftDist != sig64)) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + } + return sign ? -absZ : absZ; + +} + diff --git a/softfloat/f128_to_ui32.c b/softfloat/f128_to_ui32.c new file mode 100644 index 0000000..75e53d9 --- /dev/null +++ b/softfloat/f128_to_ui32.c @@ -0,0 +1,86 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast32_t + f128_to_ui32( float128_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool sign; + int_fast32_t exp; + uint_fast64_t sig64; + int_fast32_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + sign = signF128UI64( uiA64 ); + exp = expF128UI64( uiA64 ); + sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) + if ( (exp == 0x7FFF) && sig64 ) { +#if (ui32_fromNaN == ui32_fromPosOverflow) + sign = 0; +#elif (ui32_fromNaN == ui32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags( softfloat_flag_invalid ); + return ui32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); + shiftDist = 0x4023 - exp; + if ( 0 < shiftDist ) { + sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); + } + return softfloat_roundToUI32( sign, sig64, roundingMode, exact ); + +} + diff --git a/softfloat/f128_to_ui32_r_minMag.c b/softfloat/f128_to_ui32_r_minMag.c new file mode 100644 index 0000000..2097fb8 --- /dev/null +++ b/softfloat/f128_to_ui32_r_minMag.c @@ -0,0 +1,89 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast32_t f128_to_ui32_r_minMag( float128_t a, bool exact ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + int_fast32_t exp; + uint_fast64_t sig64; + int_fast32_t shiftDist; + bool sign; + uint_fast32_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + exp = expF128UI64( uiA64 ); + sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( 49 <= shiftDist ) { + if ( exact && (exp | sig64) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF128UI64( uiA64 ); + if ( sign || (shiftDist < 17) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FFF) && sig64 ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig64 |= UINT64_C( 0x0001000000000000 ); + z = sig64>>shiftDist; + if ( exact && ((uint_fast64_t) z<<shiftDist != sig64) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return z; + +} + diff --git a/softfloat/f128_to_ui64.c b/softfloat/f128_to_ui64.c new file mode 100644 index 0000000..b88d251 --- /dev/null +++ b/softfloat/f128_to_ui64.c @@ -0,0 +1,96 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t + f128_to_ui64( float128_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool sign; + int_fast32_t exp; + uint_fast64_t sig64, sig0; + int_fast32_t shiftDist; + struct uint128 sig128; + struct uint64_extra sigExtra; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + sign = signF128UI64( uiA64 ); + exp = expF128UI64( uiA64 ); + sig64 = fracF128UI64( uiA64 ); + sig0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( shiftDist <= 0 ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( shiftDist < -15 ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64 |= UINT64_C( 0x0001000000000000 ); + if ( shiftDist ) { + sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftDist ); + sig64 = sig128.v64; + sig0 = sig128.v0; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); + sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftDist ); + sig64 = sigExtra.v; + sig0 = sigExtra.extra; + } + return softfloat_roundToUI64( sign, sig64, sig0, roundingMode, exact ); + +} + diff --git a/softfloat/f128_to_ui64_r_minMag.c b/softfloat/f128_to_ui64_r_minMag.c new file mode 100644 index 0000000..fb16320 --- /dev/null +++ b/softfloat/f128_to_ui64_r_minMag.c @@ -0,0 +1,105 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t f128_to_ui64_r_minMag( float128_t a, bool exact ) +{ + union ui128_f128 uA; + uint_fast64_t uiA64, uiA0; + bool sign; + int_fast32_t exp; + uint_fast64_t sig64, sig0; + int_fast32_t shiftDist; + int_fast8_t negShiftDist; + uint_fast64_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA64 = uA.ui.v64; + uiA0 = uA.ui.v0; + sign = signF128UI64( uiA64 ); + exp = expF128UI64( uiA64 ); + sig64 = fracF128UI64( uiA64 ); + sig0 = uiA0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( shiftDist < 0 ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( sign || (shiftDist < -15) ) goto invalid; + sig64 |= UINT64_C( 0x0001000000000000 ); + negShiftDist = -shiftDist; + z = sig64<<negShiftDist | sig0>>(shiftDist & 63); + if ( exact && (uint64_t) (sig0<<negShiftDist) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( 49 <= shiftDist ) { + if ( exact && (exp | sig64 | sig0) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( sign ) goto invalid; + sig64 |= UINT64_C( 0x0001000000000000 ); + z = sig64>>shiftDist; + if ( exact && (sig0 || (z<<shiftDist != sig64)) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + +} + diff --git a/softfloat/f16_add.c b/softfloat/f16_add.c new file mode 100644 index 0000000..eb763d0 --- /dev/null +++ b/softfloat/f16_add.c @@ -0,0 +1,70 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float16_t f16_add( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + union ui16_f16 uB; + uint_fast16_t uiB; +#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1) + float16_t (*magsFuncPtr)( uint_fast16_t, uint_fast16_t ); +#endif + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; +#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) + if ( signF16UI( uiA ^ uiB ) ) { + return softfloat_subMagsF16( uiA, uiB ); + } else { + return softfloat_addMagsF16( uiA, uiB ); + } +#else + magsFuncPtr = + signF16UI( uiA ^ uiB ) ? softfloat_subMagsF16 : softfloat_addMagsF16; + return (*magsFuncPtr)( uiA, uiB ); +#endif + +} + diff --git a/softfloat/f16_div.c b/softfloat/f16_div.c new file mode 100644 index 0000000..71b5c29 --- /dev/null +++ b/softfloat/f16_div.c @@ -0,0 +1,186 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +extern const uint16_t softfloat_approxRecip_1k0s[]; +extern const uint16_t softfloat_approxRecip_1k1s[]; + +float16_t f16_div( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool signA; + int_fast8_t expA; + uint_fast16_t sigA; + union ui16_f16 uB; + uint_fast16_t uiB; + bool signB; + int_fast8_t expB; + uint_fast16_t sigB; + bool signZ; + struct exp8_sig16 normExpSig; + int_fast8_t expZ; +#ifdef SOFTFLOAT_FAST_DIV32TO16 + uint_fast32_t sig32A; + uint_fast16_t sigZ; +#else + int index; + uint16_t r0; + uint_fast16_t sigZ, rem; +#endif + uint_fast16_t uiZ; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + signA = signF16UI( uiA ); + expA = expF16UI( uiA ); + sigA = fracF16UI( uiA ); + uB.f = b; + uiB = uB.ui; + signB = signF16UI( uiB ); + expB = expF16UI( uiB ); + sigB = fracF16UI( uiB ); + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x1F ) { + if ( sigA ) goto propagateNaN; + if ( expB == 0x1F ) { + if ( sigB ) goto propagateNaN; + goto invalid; + } + goto infinity; + } + if ( expB == 0x1F ) { + if ( sigB ) goto propagateNaN; + goto zero; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expB ) { + if ( ! sigB ) { + if ( ! (expA | sigA) ) goto invalid; + softfloat_raiseFlags( softfloat_flag_infinite ); + goto infinity; + } + normExpSig = softfloat_normSubnormalF16Sig( sigB ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + if ( ! expA ) { + if ( ! sigA ) goto zero; + normExpSig = softfloat_normSubnormalF16Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA - expB + 0xE; + sigA |= 0x0400; + sigB |= 0x0400; +#ifdef SOFTFLOAT_FAST_DIV32TO16 + if ( sigA < sigB ) { + --expZ; + sig32A = (uint_fast32_t) sigA<<15; + } else { + sig32A = (uint_fast32_t) sigA<<14; + } + sigZ = sig32A / sigB; + if ( ! (sigZ & 7) ) sigZ |= ((uint_fast32_t) sigB * sigZ != sig32A); +#else + if ( sigA < sigB ) { + --expZ; + sigA <<= 5; + } else { + sigA <<= 4; + } + index = sigB>>6 & 0xF; + r0 = softfloat_approxRecip_1k0s[index] + - (((uint_fast32_t) softfloat_approxRecip_1k1s[index] + * (sigB & 0x3F)) + >>10); + sigZ = ((uint_fast32_t) sigA * r0)>>16; + rem = (sigA<<10) - sigZ * sigB; + sigZ += (rem * (uint_fast32_t) r0)>>26; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + ++sigZ; + if ( ! (sigZ & 7) ) { + sigZ &= ~1; + rem = (sigA<<10) - sigZ * sigB; + if ( rem & 0x8000 ) { + sigZ -= 2; + } else { + if ( rem ) sigZ |= 1; + } + } +#endif + return softfloat_roundPackToF16( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF16UI; + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infinity: + uiZ = packToF16UI( signZ, 0x1F, 0 ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + uiZ = packToF16UI( signZ, 0, 0 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f16_eq.c b/softfloat/f16_eq.c new file mode 100644 index 0000000..37a6099 --- /dev/null +++ b/softfloat/f16_eq.c @@ -0,0 +1,66 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +bool f16_eq( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + union ui16_f16 uB; + uint_fast16_t uiB; + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; + if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { + if ( + softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) + ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + } + return false; + } + return (uiA == uiB) || ! (uint16_t) ((uiA | uiB)<<1); + +} + diff --git a/softfloat/f16_eq_signaling.c b/softfloat/f16_eq_signaling.c new file mode 100644 index 0000000..894f7b5 --- /dev/null +++ b/softfloat/f16_eq_signaling.c @@ -0,0 +1,61 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +bool f16_eq_signaling( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + union ui16_f16 uB; + uint_fast16_t uiB; + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; + if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return false; + } + return (uiA == uiB) || ! (uint16_t) ((uiA | uiB)<<1); + +} + diff --git a/softfloat/f16_isSignalingNaN.c b/softfloat/f16_isSignalingNaN.c new file mode 100644 index 0000000..657805b --- /dev/null +++ b/softfloat/f16_isSignalingNaN.c @@ -0,0 +1,51 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +bool f16_isSignalingNaN( float16_t a ) +{ + union ui16_f16 uA; + + uA.f = a; + return softfloat_isSigNaNF16UI( uA.ui ); + +} + diff --git a/softfloat/f16_le.c b/softfloat/f16_le.c new file mode 100644 index 0000000..37eaf18 --- /dev/null +++ b/softfloat/f16_le.c @@ -0,0 +1,66 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +bool f16_le( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + union ui16_f16 uB; + uint_fast16_t uiB; + bool signA, signB; + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; + if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return false; + } + signA = signF16UI( uiA ); + signB = signF16UI( uiB ); + return + (signA != signB) ? signA || ! (uint16_t) ((uiA | uiB)<<1) + : (uiA == uiB) || (signA ^ (uiA < uiB)); + +} + diff --git a/softfloat/f16_le_quiet.c b/softfloat/f16_le_quiet.c new file mode 100644 index 0000000..8391db7 --- /dev/null +++ b/softfloat/f16_le_quiet.c @@ -0,0 +1,71 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +bool f16_le_quiet( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + union ui16_f16 uB; + uint_fast16_t uiB; + bool signA, signB; + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; + if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { + if ( + softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) + ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + } + return false; + } + signA = signF16UI( uiA ); + signB = signF16UI( uiB ); + return + (signA != signB) ? signA || ! (uint16_t) ((uiA | uiB)<<1) + : (uiA == uiB) || (signA ^ (uiA < uiB)); + +} + diff --git a/softfloat/f16_lt.c b/softfloat/f16_lt.c new file mode 100644 index 0000000..3d3522a --- /dev/null +++ b/softfloat/f16_lt.c @@ -0,0 +1,66 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +bool f16_lt( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + union ui16_f16 uB; + uint_fast16_t uiB; + bool signA, signB; + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; + if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return false; + } + signA = signF16UI( uiA ); + signB = signF16UI( uiB ); + return + (signA != signB) ? signA && ((uint16_t) ((uiA | uiB)<<1) != 0) + : (uiA != uiB) && (signA ^ (uiA < uiB)); + +} + diff --git a/softfloat/f16_lt_quiet.c b/softfloat/f16_lt_quiet.c new file mode 100644 index 0000000..37f762c --- /dev/null +++ b/softfloat/f16_lt_quiet.c @@ -0,0 +1,71 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +bool f16_lt_quiet( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + union ui16_f16 uB; + uint_fast16_t uiB; + bool signA, signB; + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; + if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { + if ( + softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) + ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + } + return false; + } + signA = signF16UI( uiA ); + signB = signF16UI( uiB ); + return + (signA != signB) ? signA && ((uint16_t) ((uiA | uiB)<<1) != 0) + : (uiA != uiB) && (signA ^ (uiA < uiB)); + +} + diff --git a/softfloat/f16_mul.c b/softfloat/f16_mul.c new file mode 100644 index 0000000..255caa7 --- /dev/null +++ b/softfloat/f16_mul.c @@ -0,0 +1,140 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16_t f16_mul( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool signA; + int_fast8_t expA; + uint_fast16_t sigA; + union ui16_f16 uB; + uint_fast16_t uiB; + bool signB; + int_fast8_t expB; + uint_fast16_t sigB; + bool signZ; + uint_fast16_t magBits; + struct exp8_sig16 normExpSig; + int_fast8_t expZ; + uint_fast32_t sig32Z; + uint_fast16_t sigZ, uiZ; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + signA = signF16UI( uiA ); + expA = expF16UI( uiA ); + sigA = fracF16UI( uiA ); + uB.f = b; + uiB = uB.ui; + signB = signF16UI( uiB ); + expB = expF16UI( uiB ); + sigB = fracF16UI( uiB ); + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x1F ) { + if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN; + magBits = expB | sigB; + goto infArg; + } + if ( expB == 0x1F ) { + if ( sigB ) goto propagateNaN; + magBits = expA | sigA; + goto infArg; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! sigA ) goto zero; + normExpSig = softfloat_normSubnormalF16Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if ( ! expB ) { + if ( ! sigB ) goto zero; + normExpSig = softfloat_normSubnormalF16Sig( sigB ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0xF; + sigA = (sigA | 0x0400)<<4; + sigB = (sigB | 0x0400)<<5; + sig32Z = (uint_fast32_t) sigA * sigB; + sigZ = sig32Z>>16; + if ( sig32Z & 0xFFFF ) sigZ |= 1; + if ( sigZ < 0x4000 ) { + --expZ; + sigZ <<= 1; + } + return softfloat_roundPackToF16( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infArg: + if ( ! magBits ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF16UI; + } else { + uiZ = packToF16UI( signZ, 0x1F, 0 ); + } + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + uiZ = packToF16UI( signZ, 0, 0 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f16_mulAdd.c b/softfloat/f16_mulAdd.c new file mode 100644 index 0000000..4026196 --- /dev/null +++ b/softfloat/f16_mulAdd.c @@ -0,0 +1,60 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float16_t f16_mulAdd( float16_t a, float16_t b, float16_t c ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + union ui16_f16 uB; + uint_fast16_t uiB; + union ui16_f16 uC; + uint_fast16_t uiC; + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; + uC.f = c; + uiC = uC.ui; + return softfloat_mulAddF16( uiA, uiB, uiC, 0 ); + +} + diff --git a/softfloat/f16_rem.c b/softfloat/f16_rem.c new file mode 100644 index 0000000..86c319d --- /dev/null +++ b/softfloat/f16_rem.c @@ -0,0 +1,171 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16_t f16_rem( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool signA; + int_fast8_t expA; + uint_fast16_t sigA; + union ui16_f16 uB; + uint_fast16_t uiB; + int_fast8_t expB; + uint_fast16_t sigB; + struct exp8_sig16 normExpSig; + uint16_t rem; + int_fast8_t expDiff; + uint_fast16_t q; + uint32_t recip32, q32; + uint16_t altRem, meanRem; + bool signRem; + uint_fast16_t uiZ; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + signA = signF16UI( uiA ); + expA = expF16UI( uiA ); + sigA = fracF16UI( uiA ); + uB.f = b; + uiB = uB.ui; + expB = expF16UI( uiB ); + sigB = fracF16UI( uiB ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x1F ) { + if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN; + goto invalid; + } + if ( expB == 0x1F ) { + if ( sigB ) goto propagateNaN; + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expB ) { + if ( ! sigB ) goto invalid; + normExpSig = softfloat_normSubnormalF16Sig( sigB ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + if ( ! expA ) { + if ( ! sigA ) return a; + normExpSig = softfloat_normSubnormalF16Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + rem = sigA | 0x0400; + sigB |= 0x0400; + expDiff = expA - expB; + if ( expDiff < 1 ) { + if ( expDiff < -1 ) return a; + sigB <<= 3; + if ( expDiff ) { + rem <<= 2; + q = 0; + } else { + rem <<= 3; + q = (sigB <= rem); + if ( q ) rem -= sigB; + } + } else { + recip32 = softfloat_approxRecip32_1( (uint_fast32_t) sigB<<21 ); + /*-------------------------------------------------------------------- + | Changing the shift of `rem' here requires also changing the initial + | subtraction from `expDiff'. + *--------------------------------------------------------------------*/ + rem <<= 4; + expDiff -= 31; + /*-------------------------------------------------------------------- + | The scale of `sigB' affects how many bits are obtained during each + | cycle of the loop. Currently this is 29 bits per loop iteration, + | which is believed to be the maximum possible. + *--------------------------------------------------------------------*/ + sigB <<= 3; + for (;;) { + q32 = (rem * (uint_fast64_t) recip32)>>16; + if ( expDiff < 0 ) break; + rem = -((uint_fast16_t) q32 * sigB); + expDiff -= 29; + } + /*-------------------------------------------------------------------- + | (`expDiff' cannot be less than -30 here.) + *--------------------------------------------------------------------*/ + q32 >>= ~expDiff & 31; + q = q32; + rem = (rem<<(expDiff + 30)) - q * sigB; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + do { + altRem = rem; + ++q; + rem -= sigB; + } while ( ! (rem & 0x8000) ); + meanRem = rem + altRem; + if ( (meanRem & 0x8000) || (! meanRem && (q & 1)) ) rem = altRem; + signRem = signA; + if ( 0x8000 <= rem ) { + signRem = ! signRem; + rem = -rem; + } + return softfloat_normRoundPackToF16( signRem, expB, rem ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); + goto uiZ; + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF16UI; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f16_roundToInt.c b/softfloat/f16_roundToInt.c new file mode 100644 index 0000000..9bbd47e --- /dev/null +++ b/softfloat/f16_roundToInt.c @@ -0,0 +1,112 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16_t f16_roundToInt( float16_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + int_fast8_t exp; + uint_fast16_t uiZ, lastBitMask, roundBitsMask; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp <= 0xE ) { + if ( ! (uint16_t) (uiA<<1) ) return a; + if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; + uiZ = uiA & packToF16UI( 1, 0, 0 ); + switch ( roundingMode ) { + case softfloat_round_near_even: + if ( ! fracF16UI( uiA ) ) break; + case softfloat_round_near_maxMag: + if ( exp == 0xE ) uiZ |= packToF16UI( 0, 0xF, 0 ); + break; + case softfloat_round_min: + if ( uiZ ) uiZ = packToF16UI( 1, 0xF, 0 ); + break; + case softfloat_round_max: + if ( ! uiZ ) uiZ = packToF16UI( 0, 0xF, 0 ); + break; + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( 0x19 <= exp ) { + if ( (exp == 0x1F) && fracF16UI( uiA ) ) { + uiZ = softfloat_propagateNaNF16UI( uiA, 0 ); + goto uiZ; + } + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ = uiA; + lastBitMask = (uint_fast16_t) 1<<(0x19 - exp); + roundBitsMask = lastBitMask - 1; + if ( roundingMode == softfloat_round_near_maxMag ) { + uiZ += lastBitMask>>1; + } else if ( roundingMode == softfloat_round_near_even ) { + uiZ += lastBitMask>>1; + if ( ! (uiZ & roundBitsMask) ) uiZ &= ~lastBitMask; + } else if ( + roundingMode + == (signF16UI( uiZ ) ? softfloat_round_min : softfloat_round_max) + ) { + uiZ += roundBitsMask; + } + uiZ &= ~roundBitsMask; + if ( exact && (uiZ != uiA) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f16_sqrt.c b/softfloat/f16_sqrt.c new file mode 100644 index 0000000..7ff2923 --- /dev/null +++ b/softfloat/f16_sqrt.c @@ -0,0 +1,136 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +extern const uint16_t softfloat_approxRecipSqrt_1k0s[]; +extern const uint16_t softfloat_approxRecipSqrt_1k1s[]; + +float16_t f16_sqrt( float16_t a ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool signA; + int_fast8_t expA; + uint_fast16_t sigA, uiZ; + struct exp8_sig16 normExpSig; + int_fast8_t expZ; + int index; + uint_fast16_t r0; + uint_fast32_t ESqrR0; + uint16_t sigma0; + uint_fast16_t recipSqrt16, sigZ, shiftedSigZ; + uint16_t negRem; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + signA = signF16UI( uiA ); + expA = expF16UI( uiA ); + sigA = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x1F ) { + if ( sigA ) { + uiZ = softfloat_propagateNaNF16UI( uiA, 0 ); + goto uiZ; + } + if ( ! signA ) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( signA ) { + if ( ! (expA | sigA) ) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! sigA ) return a; + normExpSig = softfloat_normSubnormalF16Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = ((expA - 0xF)>>1) + 0xE; + expA &= 1; + sigA |= 0x0400; + index = (sigA>>6 & 0xE) + expA; + r0 = softfloat_approxRecipSqrt_1k0s[index] + - (((uint_fast32_t) softfloat_approxRecipSqrt_1k1s[index] + * (sigA & 0x7F)) + >>11); + ESqrR0 = ((uint_fast32_t) r0 * r0)>>1; + if ( expA ) ESqrR0 >>= 1; + sigma0 = ~(uint_fast16_t) ((ESqrR0 * sigA)>>16); + recipSqrt16 = r0 + (((uint_fast32_t) r0 * sigma0)>>25); + if ( ! (recipSqrt16 & 0x8000) ) recipSqrt16 = 0x8000; + sigZ = ((uint_fast32_t) (sigA<<5) * recipSqrt16)>>16; + if ( expA ) sigZ >>= 1; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + ++sigZ; + if ( ! (sigZ & 7) ) { + shiftedSigZ = sigZ>>1; + negRem = shiftedSigZ * shiftedSigZ; + sigZ &= ~1; + if ( negRem & 0x8000 ) { + sigZ |= 1; + } else { + if ( negRem ) --sigZ; + } + } + return softfloat_roundPackToF16( 0, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF16UI; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f16_sub.c b/softfloat/f16_sub.c new file mode 100644 index 0000000..811f239 --- /dev/null +++ b/softfloat/f16_sub.c @@ -0,0 +1,70 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float16_t f16_sub( float16_t a, float16_t b ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + union ui16_f16 uB; + uint_fast16_t uiB; +#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1) + float16_t (*magsFuncPtr)( uint_fast16_t, uint_fast16_t ); +#endif + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; +#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) + if ( signF16UI( uiA ^ uiB ) ) { + return softfloat_addMagsF16( uiA, uiB ); + } else { + return softfloat_subMagsF16( uiA, uiB ); + } +#else + magsFuncPtr = + signF16UI( uiA ^ uiB ) ? softfloat_addMagsF16 : softfloat_subMagsF16; + return (*magsFuncPtr)( uiA, uiB ); +#endif + +} + diff --git a/softfloat/f16_to_f128.c b/softfloat/f16_to_f128.c new file mode 100644 index 0000000..961cdaa --- /dev/null +++ b/softfloat/f16_to_f128.c @@ -0,0 +1,96 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f16_to_f128( float16_t a ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool sign; + int_fast8_t exp; + uint_fast16_t frac; + struct commonNaN commonNaN; + struct uint128 uiZ; + struct exp8_sig16 normExpSig; + union ui128_f128 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF16UI( uiA ); + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x1F ) { + if ( frac ) { + softfloat_f16UIToCommonNaN( uiA, &commonNaN ); + uiZ = softfloat_commonNaNToF128UI( &commonNaN ); + } else { + uiZ.v64 = packToF128UI64( sign, 0x7FFF, 0 ); + uiZ.v0 = 0; + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! exp ) { + if ( ! frac ) { + uiZ.v64 = packToF128UI64( sign, 0, 0 ); + uiZ.v0 = 0; + goto uiZ; + } + normExpSig = softfloat_normSubnormalF16Sig( frac ); + exp = normExpSig.exp - 1; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ.v64 = packToF128UI64( sign, exp + 0x3FF0, (uint_fast64_t) frac<<38 ); + uiZ.v0 = 0; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f16_to_f32.c b/softfloat/f16_to_f32.c new file mode 100644 index 0000000..fb8b381 --- /dev/null +++ b/softfloat/f16_to_f32.c @@ -0,0 +1,93 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float32_t f16_to_f32( float16_t a ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool sign; + int_fast8_t exp; + uint_fast16_t frac; + struct commonNaN commonNaN; + uint_fast32_t uiZ; + struct exp8_sig16 normExpSig; + union ui32_f32 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF16UI( uiA ); + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x1F ) { + if ( frac ) { + softfloat_f16UIToCommonNaN( uiA, &commonNaN ); + uiZ = softfloat_commonNaNToF32UI( &commonNaN ); + } else { + uiZ = packToF32UI( sign, 0xFF, 0 ); + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! exp ) { + if ( ! frac ) { + uiZ = packToF32UI( sign, 0, 0 ); + goto uiZ; + } + normExpSig = softfloat_normSubnormalF16Sig( frac ); + exp = normExpSig.exp - 1; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ = packToF32UI( sign, exp + 0x70, (uint_fast32_t) frac<<13 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f16_to_f64.c b/softfloat/f16_to_f64.c new file mode 100644 index 0000000..4ab27ba --- /dev/null +++ b/softfloat/f16_to_f64.c @@ -0,0 +1,93 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float64_t f16_to_f64( float16_t a ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool sign; + int_fast8_t exp; + uint_fast16_t frac; + struct commonNaN commonNaN; + uint_fast64_t uiZ; + struct exp8_sig16 normExpSig; + union ui64_f64 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF16UI( uiA ); + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x1F ) { + if ( frac ) { + softfloat_f16UIToCommonNaN( uiA, &commonNaN ); + uiZ = softfloat_commonNaNToF64UI( &commonNaN ); + } else { + uiZ = packToF64UI( sign, 0x7FF, 0 ); + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! exp ) { + if ( ! frac ) { + uiZ = packToF64UI( sign, 0, 0 ); + goto uiZ; + } + normExpSig = softfloat_normSubnormalF16Sig( frac ); + exp = normExpSig.exp - 1; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ = packToF64UI( sign, exp + 0x3F0, (uint_fast64_t) frac<<42 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f16_to_i32.c b/softfloat/f16_to_i32.c new file mode 100644 index 0000000..24b1984 --- /dev/null +++ b/softfloat/f16_to_i32.c @@ -0,0 +1,87 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast32_t f16_to_i32( float16_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool sign; + int_fast8_t exp; + uint_fast16_t frac; + int_fast32_t sig32; + int_fast8_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF16UI( uiA ); + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x1F ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + frac ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig32 = frac; + if ( exp ) { + sig32 |= 0x0400; + shiftDist = exp - 0x19; + if ( 0 <= shiftDist ) { + sig32 <<= shiftDist; + return sign ? -sig32 : sig32; + } + shiftDist = exp - 0x0D; + if ( 0 < shiftDist ) sig32 <<= shiftDist; + } + return + softfloat_roundToI32( + sign, (uint_fast32_t) sig32, roundingMode, exact ); + +} + diff --git a/softfloat/f16_to_i32_r_minMag.c b/softfloat/f16_to_i32_r_minMag.c new file mode 100644 index 0000000..ebb4965 --- /dev/null +++ b/softfloat/f16_to_i32_r_minMag.c @@ -0,0 +1,88 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast32_t f16_to_i32_r_minMag( float16_t a, bool exact ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + int_fast8_t exp; + uint_fast16_t frac; + int_fast8_t shiftDist; + bool sign; + int_fast32_t alignedSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = exp - 0x0F; + if ( shiftDist < 0 ) { + if ( exact && (exp | frac) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI( uiA ); + if ( exp == 0x1F ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x1F) && frac ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + alignedSig = (int_fast32_t) (frac | 0x0400)<<shiftDist; + if ( exact && (alignedSig & 0x3FF) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + alignedSig >>= 10; + return sign ? -alignedSig : alignedSig; + +} + diff --git a/softfloat/f16_to_i64.c b/softfloat/f16_to_i64.c new file mode 100644 index 0000000..c241745 --- /dev/null +++ b/softfloat/f16_to_i64.c @@ -0,0 +1,87 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t f16_to_i64( float16_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool sign; + int_fast8_t exp; + uint_fast16_t frac; + int_fast32_t sig32; + int_fast8_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF16UI( uiA ); + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x1F ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + frac ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig32 = frac; + if ( exp ) { + sig32 |= 0x0400; + shiftDist = exp - 0x19; + if ( 0 <= shiftDist ) { + sig32 <<= shiftDist; + return sign ? -sig32 : sig32; + } + shiftDist = exp - 0x0D; + if ( 0 < shiftDist ) sig32 <<= shiftDist; + } + return + softfloat_roundToI32( + sign, (uint_fast32_t) sig32, roundingMode, exact ); + +} + diff --git a/softfloat/f16_to_i64_r_minMag.c b/softfloat/f16_to_i64_r_minMag.c new file mode 100644 index 0000000..dc9a8d3 --- /dev/null +++ b/softfloat/f16_to_i64_r_minMag.c @@ -0,0 +1,88 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t f16_to_i64_r_minMag( float16_t a, bool exact ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + int_fast8_t exp; + uint_fast16_t frac; + int_fast8_t shiftDist; + bool sign; + int_fast32_t alignedSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = exp - 0x0F; + if ( shiftDist < 0 ) { + if ( exact && (exp | frac) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI( uiA ); + if ( exp == 0x1F ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x1F) && frac ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + alignedSig = (int_fast32_t) (frac | 0x0400)<<shiftDist; + if ( exact && (alignedSig & 0x3FF) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + alignedSig >>= 10; + return sign ? -alignedSig : alignedSig; + +} + diff --git a/softfloat/f16_to_ui32.c b/softfloat/f16_to_ui32.c new file mode 100644 index 0000000..c99af39 --- /dev/null +++ b/softfloat/f16_to_ui32.c @@ -0,0 +1,84 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast32_t f16_to_ui32( float16_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool sign; + int_fast8_t exp; + uint_fast16_t frac; + uint_fast32_t sig32; + int_fast8_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF16UI( uiA ); + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x1F ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + frac ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig32 = frac; + if ( exp ) { + sig32 |= 0x0400; + shiftDist = exp - 0x19; + if ( (0 <= shiftDist) && ! sign ) { + return sig32<<shiftDist; + } + shiftDist = exp - 0x0D; + if ( 0 < shiftDist ) sig32 <<= shiftDist; + } + return softfloat_roundToUI32( sign, sig32, roundingMode, exact ); + +} + diff --git a/softfloat/f16_to_ui32_r_minMag.c b/softfloat/f16_to_ui32_r_minMag.c new file mode 100644 index 0000000..f63e05a --- /dev/null +++ b/softfloat/f16_to_ui32_r_minMag.c @@ -0,0 +1,87 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast32_t f16_to_ui32_r_minMag( float16_t a, bool exact ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + int_fast8_t exp; + uint_fast16_t frac; + int_fast8_t shiftDist; + bool sign; + uint_fast32_t alignedSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = exp - 0x0F; + if ( shiftDist < 0 ) { + if ( exact && (exp | frac) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI( uiA ); + if ( sign || (exp == 0x1F) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x1F) && frac ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + alignedSig = (uint_fast32_t) (frac | 0x0400)<<shiftDist; + if ( exact && (alignedSig & 0x3FF) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return alignedSig>>10; + +} + diff --git a/softfloat/f16_to_ui64.c b/softfloat/f16_to_ui64.c new file mode 100644 index 0000000..dd260ea --- /dev/null +++ b/softfloat/f16_to_ui64.c @@ -0,0 +1,84 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t f16_to_ui64( float16_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + bool sign; + int_fast8_t exp; + uint_fast16_t frac; + uint_fast32_t sig32; + int_fast8_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF16UI( uiA ); + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x1F ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + frac ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig32 = frac; + if ( exp ) { + sig32 |= 0x0400; + shiftDist = exp - 0x19; + if ( (0 <= shiftDist) && ! sign ) { + return sig32<<shiftDist; + } + shiftDist = exp - 0x0D; + if ( 0 < shiftDist ) sig32 <<= shiftDist; + } + return softfloat_roundToUI32( sign, sig32, roundingMode, exact ); + +} + diff --git a/softfloat/f16_to_ui64_r_minMag.c b/softfloat/f16_to_ui64_r_minMag.c new file mode 100644 index 0000000..a57b422 --- /dev/null +++ b/softfloat/f16_to_ui64_r_minMag.c @@ -0,0 +1,87 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t f16_to_ui64_r_minMag( float16_t a, bool exact ) +{ + union ui16_f16 uA; + uint_fast16_t uiA; + int_fast8_t exp; + uint_fast16_t frac; + int_fast8_t shiftDist; + bool sign; + uint_fast32_t alignedSig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF16UI( uiA ); + frac = fracF16UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = exp - 0x0F; + if ( shiftDist < 0 ) { + if ( exact && (exp | frac) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF16UI( uiA ); + if ( sign || (exp == 0x1F) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x1F) && frac ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + alignedSig = (uint_fast32_t) (frac | 0x0400)<<shiftDist; + if ( exact && (alignedSig & 0x3FF) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return alignedSig>>10; + +} + diff --git a/softfloat/f32_add.c b/softfloat/f32_add.c index 5b5a09e..4a51ecc 100644 --- a/softfloat/f32_add.c +++ b/softfloat/f32_add.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: @@ -44,30 +44,26 @@ float32_t f32_add( float32_t a, float32_t b ) { union ui32_f32 uA; uint_fast32_t uiA; - bool signA; union ui32_f32 uB; uint_fast32_t uiB; - bool signB; #if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1) - float32_t (*magsFuncPtr)( uint_fast32_t, uint_fast32_t, bool ); + float32_t (*magsFuncPtr)( uint_fast32_t, uint_fast32_t ); #endif uA.f = a; uiA = uA.ui; - signA = signF32UI( uiA ); uB.f = b; uiB = uB.ui; - signB = signF32UI( uiB ); #if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) - if ( signA == signB ) { - return softfloat_addMagsF32( uiA, uiB, signA ); + if ( signF32UI( uiA ^ uiB ) ) { + return softfloat_subMagsF32( uiA, uiB ); } else { - return softfloat_subMagsF32( uiA, uiB, signA ); + return softfloat_addMagsF32( uiA, uiB ); } #else magsFuncPtr = - (signA == signB) ? softfloat_addMagsF32 : softfloat_subMagsF32; - return (*magsFuncPtr)( uiA, uiB, signA ); + signF32UI( uiA ^ uiB ) ? softfloat_subMagsF32 : softfloat_addMagsF32; + return (*magsFuncPtr)( uiA, uiB ); #endif } diff --git a/softfloat/f32_classify.c b/softfloat/f32_classify.c index d16aa25..83fad87 100755 --- a/softfloat/f32_classify.c +++ b/softfloat/f32_classify.c @@ -17,17 +17,20 @@ uint_fast16_t f32_classify( float32_t a ) uint_fast16_t infOrNaN = expF32UI( uiA ) == 0xFF; uint_fast16_t subnormalOrZero = expF32UI( uiA ) == 0; bool sign = signF32UI( uiA ); + bool fracZero = fracF32UI( uiA ) == 0; + bool isNaN = isNaNF32UI( uiA ); + bool isSNaN = softfloat_isSigNaNF32UI( uiA ); return - ( sign && infOrNaN && fracF32UI( uiA ) == 0 ) << 0 | - ( sign && !infOrNaN && !subnormalOrZero ) << 1 | - ( sign && subnormalOrZero && fracF32UI( uiA ) ) << 2 | - ( sign && subnormalOrZero && fracF32UI( uiA ) == 0 ) << 3 | - ( !sign && infOrNaN && fracF32UI( uiA ) == 0 ) << 7 | - ( !sign && !infOrNaN && !subnormalOrZero ) << 6 | - ( !sign && subnormalOrZero && fracF32UI( uiA ) ) << 5 | - ( !sign && subnormalOrZero && fracF32UI( uiA ) == 0 ) << 4 | - ( isNaNF32UI( uiA ) && softfloat_isSigNaNF32UI( uiA )) << 8 | - ( isNaNF32UI( uiA ) && !softfloat_isSigNaNF32UI( uiA )) << 9; + ( sign && infOrNaN && fracZero ) << 0 | + ( sign && !infOrNaN && !subnormalOrZero ) << 1 | + ( sign && subnormalOrZero && !fracZero ) << 2 | + ( sign && subnormalOrZero && fracZero ) << 3 | + ( !sign && infOrNaN && fracZero ) << 7 | + ( !sign && !infOrNaN && !subnormalOrZero ) << 6 | + ( !sign && subnormalOrZero && !fracZero ) << 5 | + ( !sign && subnormalOrZero && fracZero ) << 4 | + ( isNaN && isSNaN ) << 8 | + ( isNaN && !isSNaN ) << 9; } diff --git a/softfloat/f32_div.c b/softfloat/f32_div.c index 2321d20..9d10125 100644 --- a/softfloat/f32_div.c +++ b/softfloat/f32_div.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f32_eq.c b/softfloat/f32_eq.c index ee0918f..5f07eee 100644 --- a/softfloat/f32_eq.c +++ b/softfloat/f32_eq.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f32_eq_signaling.c b/softfloat/f32_eq_signaling.c index 52b1dd7..f5fcc82 100644 --- a/softfloat/f32_eq_signaling.c +++ b/softfloat/f32_eq_signaling.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f32_isSignalingNaN.c b/softfloat/f32_isSignalingNaN.c index 479c287..5004a5a 100644 --- a/softfloat/f32_isSignalingNaN.c +++ b/softfloat/f32_isSignalingNaN.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f32_le.c b/softfloat/f32_le.c index fb30c3c..77595fb 100644 --- a/softfloat/f32_le.c +++ b/softfloat/f32_le.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f32_le_quiet.c b/softfloat/f32_le_quiet.c index 3cb6378..1ec9101 100644 --- a/softfloat/f32_le_quiet.c +++ b/softfloat/f32_le_quiet.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f32_lt.c b/softfloat/f32_lt.c index 73af423..9e12843 100644 --- a/softfloat/f32_lt.c +++ b/softfloat/f32_lt.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f32_lt_quiet.c b/softfloat/f32_lt_quiet.c index 0bab973..9f83b81 100644 --- a/softfloat/f32_lt_quiet.c +++ b/softfloat/f32_lt_quiet.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f32_mul.c b/softfloat/f32_mul.c index 941eb39..a2a673f 100644 --- a/softfloat/f32_mul.c +++ b/softfloat/f32_mul.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 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: @@ -60,6 +60,8 @@ float32_t f32_mul( float32_t a, float32_t b ) uint_fast32_t sigZ, uiZ; union ui32_f32 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; signA = signF32UI( uiA ); @@ -71,6 +73,8 @@ float32_t f32_mul( float32_t a, float32_t b ) expB = expF32UI( uiB ); sigB = fracF32UI( uiB ); signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( expA == 0xFF ) { if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN; magBits = expB | sigB; @@ -81,6 +85,8 @@ float32_t f32_mul( float32_t a, float32_t b ) magBits = expA | sigA; goto infArg; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( ! expA ) { if ( ! sigA ) goto zero; normExpSig = softfloat_normSubnormalF32Sig( sigA ); @@ -93,6 +99,8 @@ float32_t f32_mul( float32_t a, float32_t b ) expB = normExpSig.exp; sigB = normExpSig.sig; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ expZ = expA + expB - 0x7F; sigA = (sigA | 0x00800000)<<7; sigB = (sigB | 0x00800000)<<8; @@ -102,9 +110,13 @@ float32_t f32_mul( float32_t a, float32_t b ) sigZ <<= 1; } return softfloat_roundPackToF32( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ infArg: if ( ! magBits ) { softfloat_raiseFlags( softfloat_flag_invalid ); @@ -113,6 +125,8 @@ float32_t f32_mul( float32_t a, float32_t b ) uiZ = packToF32UI( signZ, 0xFF, 0 ); } goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ zero: uiZ = packToF32UI( signZ, 0, 0 ); uiZ: diff --git a/softfloat/f32_mulAdd.c b/softfloat/f32_mulAdd.c index 5bf77fe..e98021b 100644 --- a/softfloat/f32_mulAdd.c +++ b/softfloat/f32_mulAdd.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f32_rem.c b/softfloat/f32_rem.c index b1997ef..771b1b9 100644 --- a/softfloat/f32_rem.c +++ b/softfloat/f32_rem.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f32_roundToInt.c b/softfloat/f32_roundToInt.c index 314747e..0861b84 100644 --- a/softfloat/f32_roundToInt.c +++ b/softfloat/f32_roundToInt.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, 2017 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: @@ -94,10 +94,11 @@ float32_t f32_roundToInt( float32_t a, uint_fast8_t roundingMode, bool exact ) } else if ( roundingMode == softfloat_round_near_even ) { uiZ += lastBitMask>>1; if ( ! (uiZ & roundBitsMask) ) uiZ &= ~lastBitMask; - } else if ( roundingMode != softfloat_round_minMag ) { - if ( signF32UI( uiZ ) ^ (roundingMode == softfloat_round_max) ) { - uiZ += roundBitsMask; - } + } else if ( + roundingMode + == (signF32UI( uiZ ) ? softfloat_round_min : softfloat_round_max) + ) { + uiZ += roundBitsMask; } uiZ &= ~roundBitsMask; if ( exact && (uiZ != uiA) ) { diff --git a/softfloat/f32_sqrt.c b/softfloat/f32_sqrt.c index d0b489c..5ef659e 100644 --- a/softfloat/f32_sqrt.c +++ b/softfloat/f32_sqrt.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: @@ -94,13 +94,13 @@ float32_t f32_sqrt( float32_t a ) ((uint_fast64_t) sigA * softfloat_approxRecipSqrt32_1( expA, sigA )) >>32; if ( expA ) sigZ >>= 1; - sigZ += 2; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ + sigZ += 2; if ( (sigZ & 0x3F) < 2 ) { shiftedSigZ = sigZ>>2; negRem = shiftedSigZ * shiftedSigZ; - sigZ = shiftedSigZ<<2; + sigZ &= ~3; if ( negRem & 0x80000000 ) { sigZ |= 1; } else { diff --git a/softfloat/f32_sub.c b/softfloat/f32_sub.c index eae436c..d830738 100644 --- a/softfloat/f32_sub.c +++ b/softfloat/f32_sub.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: @@ -44,30 +44,26 @@ float32_t f32_sub( float32_t a, float32_t b ) { union ui32_f32 uA; uint_fast32_t uiA; - bool signA; union ui32_f32 uB; uint_fast32_t uiB; - bool signB; #if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1) - float32_t (*magsFuncPtr)( uint_fast32_t, uint_fast32_t, bool ); + float32_t (*magsFuncPtr)( uint_fast32_t, uint_fast32_t ); #endif uA.f = a; uiA = uA.ui; - signA = signF32UI( uiA ); uB.f = b; uiB = uB.ui; - signB = signF32UI( uiB ); #if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) - if ( signA == signB ) { - return softfloat_subMagsF32( uiA, uiB, signA ); + if ( signF32UI( uiA ^ uiB ) ) { + return softfloat_addMagsF32( uiA, uiB ); } else { - return softfloat_addMagsF32( uiA, uiB, signA ); + return softfloat_subMagsF32( uiA, uiB ); } #else magsFuncPtr = - (signA == signB) ? softfloat_subMagsF32 : softfloat_addMagsF32; - return (*magsFuncPtr)( uiA, uiB, signA ); + signF32UI( uiA ^ uiB ) ? softfloat_addMagsF32 : softfloat_subMagsF32; + return (*magsFuncPtr)( uiA, uiB ); #endif } diff --git a/softfloat/f32_to_f128.c b/softfloat/f32_to_f128.c new file mode 100644 index 0000000..bf51926 --- /dev/null +++ b/softfloat/f32_to_f128.c @@ -0,0 +1,96 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f32_to_f128( float32_t a ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + bool sign; + int_fast16_t exp; + uint_fast32_t frac; + struct commonNaN commonNaN; + struct uint128 uiZ; + struct exp16_sig32 normExpSig; + union ui128_f128 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF32UI( uiA ); + exp = expF32UI( uiA ); + frac = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0xFF ) { + if ( frac ) { + softfloat_f32UIToCommonNaN( uiA, &commonNaN ); + uiZ = softfloat_commonNaNToF128UI( &commonNaN ); + } else { + uiZ.v64 = packToF128UI64( sign, 0x7FFF, 0 ); + uiZ.v0 = 0; + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! exp ) { + if ( ! frac ) { + uiZ.v64 = packToF128UI64( sign, 0, 0 ); + uiZ.v0 = 0; + goto uiZ; + } + normExpSig = softfloat_normSubnormalF32Sig( frac ); + exp = normExpSig.exp - 1; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ.v64 = packToF128UI64( sign, exp + 0x3F80, (uint_fast64_t) frac<<25 ); + uiZ.v0 = 0; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f32_to_f16.c b/softfloat/f32_to_f16.c new file mode 100644 index 0000000..7a97158 --- /dev/null +++ b/softfloat/f32_to_f16.c @@ -0,0 +1,88 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16_t f32_to_f16( float32_t a ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + bool sign; + int_fast16_t exp; + uint_fast32_t frac; + struct commonNaN commonNaN; + uint_fast16_t uiZ, frac16; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF32UI( uiA ); + exp = expF32UI( uiA ); + frac = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0xFF ) { + if ( frac ) { + softfloat_f32UIToCommonNaN( uiA, &commonNaN ); + uiZ = softfloat_commonNaNToF16UI( &commonNaN ); + } else { + uiZ = packToF16UI( sign, 0x1F, 0 ); + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac16 = frac>>9 | ((frac & 0x1FF) != 0); + if ( ! (exp | frac16) ) { + uiZ = packToF16UI( sign, 0, 0 ); + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return softfloat_roundPackToF16( sign, exp - 0x71, frac16 | 0x4000 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f32_to_f64.c b/softfloat/f32_to_f64.c index 30b0923..f9e02f2 100644 --- a/softfloat/f32_to_f64.c +++ b/softfloat/f32_to_f64.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 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: @@ -47,19 +47,23 @@ float64_t f32_to_f64( float32_t a ) uint_fast32_t uiA; bool sign; int_fast16_t exp; - uint_fast32_t sig; + uint_fast32_t frac; struct commonNaN commonNaN; uint_fast64_t uiZ; struct exp16_sig32 normExpSig; union ui64_f64 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF32UI( uiA ); exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); + frac = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( exp == 0xFF ) { - if ( sig ) { + if ( frac ) { softfloat_f32UIToCommonNaN( uiA, &commonNaN ); uiZ = softfloat_commonNaNToF64UI( &commonNaN ); } else { @@ -67,16 +71,20 @@ float64_t f32_to_f64( float32_t a ) } goto uiZ; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( ! exp ) { - if ( ! sig ) { + if ( ! frac ) { uiZ = packToF64UI( sign, 0, 0 ); goto uiZ; } - normExpSig = softfloat_normSubnormalF32Sig( sig ); + normExpSig = softfloat_normSubnormalF32Sig( frac ); exp = normExpSig.exp - 1; - sig = normExpSig.sig; + frac = normExpSig.sig; } - uiZ = packToF64UI( sign, exp + 0x380, (uint_fast64_t) sig<<29 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uiZ = packToF64UI( sign, exp + 0x380, (uint_fast64_t) frac<<29 ); uiZ: uZ.ui = uiZ; return uZ.f; diff --git a/softfloat/f32_to_i32.c b/softfloat/f32_to_i32.c index c80649a..c9f2cf9 100644 --- a/softfloat/f32_to_i32.c +++ b/softfloat/f32_to_i32.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, 2015, 2016 The Regents of the University of -California. All rights reserved. +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: @@ -76,9 +76,9 @@ int_fast32_t f32_to_i32( float32_t a, uint_fast8_t roundingMode, bool exact ) *------------------------------------------------------------------------*/ if ( exp ) sig |= 0x00800000; sig64 = (uint_fast64_t) sig<<32; - shiftDist = 0xAF - exp; + shiftDist = 0xAA - exp; if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); - return softfloat_roundPackToI32( sign, sig64, roundingMode, exact ); + return softfloat_roundToI32( sign, sig64, roundingMode, exact ); } diff --git a/softfloat/f32_to_i32_r_minMag.c b/softfloat/f32_to_i32_r_minMag.c index d2e4b92..1a94dcc 100644 --- a/softfloat/f32_to_i32_r_minMag.c +++ b/softfloat/f32_to_i32_r_minMag.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015, 2016 The Regents of the University of California. All rights reserved. diff --git a/softfloat/f32_to_i64.c b/softfloat/f32_to_i64.c index b354f6c..48ab46f 100644 --- a/softfloat/f32_to_i64.c +++ b/softfloat/f32_to_i64.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, 2015, 2016 The Regents of the University of -California. All rights reserved. +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: @@ -83,13 +83,13 @@ int_fast64_t f32_to_i64( float32_t a, uint_fast8_t roundingMode, bool exact ) sig64 = sig64Extra.v; extra = sig64Extra.extra; } - return softfloat_roundPackToI64( sign, sig64, extra, roundingMode, exact ); + return softfloat_roundToI64( sign, sig64, extra, roundingMode, exact ); #else extSig[indexWord( 3, 2 )] = sig<<8; extSig[indexWord( 3, 1 )] = 0; extSig[indexWord( 3, 0 )] = 0; if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); - return softfloat_roundPackMToI64( sign, extSig, roundingMode, exact ); + return softfloat_roundMToI64( sign, extSig, roundingMode, exact ); #endif } diff --git a/softfloat/f32_to_i64_r_minMag.c b/softfloat/f32_to_i64_r_minMag.c index af2b28b..7d336a4 100644 --- a/softfloat/f32_to_i64_r_minMag.c +++ b/softfloat/f32_to_i64_r_minMag.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015, 2016 The Regents of the University of California. All rights reserved. diff --git a/softfloat/f32_to_ui32.c b/softfloat/f32_to_ui32.c index 1979dd5..5ec279b 100644 --- a/softfloat/f32_to_ui32.c +++ b/softfloat/f32_to_ui32.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, 2015, 2016 The Regents of the University of -California. All rights reserved. +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: @@ -76,9 +76,9 @@ uint_fast32_t f32_to_ui32( float32_t a, uint_fast8_t roundingMode, bool exact ) *------------------------------------------------------------------------*/ if ( exp ) sig |= 0x00800000; sig64 = (uint_fast64_t) sig<<32; - shiftDist = 0xAF - exp; + shiftDist = 0xAA - exp; if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); - return softfloat_roundPackToUI32( sign, sig64, roundingMode, exact ); + return softfloat_roundToUI32( sign, sig64, roundingMode, exact ); } diff --git a/softfloat/f32_to_ui32_r_minMag.c b/softfloat/f32_to_ui32_r_minMag.c index 9979b2c..12f7261 100644 --- a/softfloat/f32_to_ui32_r_minMag.c +++ b/softfloat/f32_to_ui32_r_minMag.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015, 2016 The Regents of the University of California. All rights reserved. diff --git a/softfloat/f32_to_ui64.c b/softfloat/f32_to_ui64.c index 6be8537..11c7b4b 100644 --- a/softfloat/f32_to_ui64.c +++ b/softfloat/f32_to_ui64.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, 2015, 2016 The Regents of the University of -California. All rights reserved. +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: @@ -83,14 +83,13 @@ uint_fast64_t f32_to_ui64( float32_t a, uint_fast8_t roundingMode, bool exact ) sig64 = sig64Extra.v; extra = sig64Extra.extra; } - return - softfloat_roundPackToUI64( sign, sig64, extra, roundingMode, exact ); + return softfloat_roundToUI64( sign, sig64, extra, roundingMode, exact ); #else extSig[indexWord( 3, 2 )] = sig<<8; extSig[indexWord( 3, 1 )] = 0; extSig[indexWord( 3, 0 )] = 0; if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); - return softfloat_roundPackMToUI64( sign, extSig, roundingMode, exact ); + return softfloat_roundMToUI64( sign, extSig, roundingMode, exact ); #endif } diff --git a/softfloat/f32_to_ui64_r_minMag.c b/softfloat/f32_to_ui64_r_minMag.c index 0d5fe5b..f96f3e1 100644 --- a/softfloat/f32_to_ui64_r_minMag.c +++ b/softfloat/f32_to_ui64_r_minMag.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015, 2016 The Regents of the University of California. All rights reserved. diff --git a/softfloat/f64_add.c b/softfloat/f64_add.c index 5bbb1b5..e9880dd 100644 --- a/softfloat/f64_add.c +++ b/softfloat/f64_add.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_classify.c b/softfloat/f64_classify.c index 2ec124b..180abde 100755 --- a/softfloat/f64_classify.c +++ b/softfloat/f64_classify.c @@ -17,17 +17,20 @@ uint_fast16_t f64_classify( float64_t a ) uint_fast16_t infOrNaN = expF64UI( uiA ) == 0x7FF; uint_fast16_t subnormalOrZero = expF64UI( uiA ) == 0; bool sign = signF64UI( uiA ); + bool fracZero = fracF64UI( uiA ) == 0; + bool isNaN = isNaNF64UI( uiA ); + bool isSNaN = softfloat_isSigNaNF64UI( uiA ); return - ( sign && infOrNaN && fracF64UI( uiA ) == 0 ) << 0 | - ( sign && !infOrNaN && !subnormalOrZero ) << 1 | - ( sign && subnormalOrZero && fracF64UI( uiA ) ) << 2 | - ( sign && subnormalOrZero && fracF64UI( uiA ) == 0 ) << 3 | - ( !sign && infOrNaN && fracF64UI( uiA ) == 0 ) << 7 | - ( !sign && !infOrNaN && !subnormalOrZero ) << 6 | - ( !sign && subnormalOrZero && fracF64UI( uiA ) ) << 5 | - ( !sign && subnormalOrZero && fracF64UI( uiA ) == 0 ) << 4 | - ( isNaNF64UI( uiA ) && softfloat_isSigNaNF64UI( uiA )) << 8 | - ( isNaNF64UI( uiA ) && !softfloat_isSigNaNF64UI( uiA )) << 9; + ( sign && infOrNaN && fracZero ) << 0 | + ( sign && !infOrNaN && !subnormalOrZero ) << 1 | + ( sign && subnormalOrZero && !fracZero ) << 2 | + ( sign && subnormalOrZero && fracZero ) << 3 | + ( !sign && infOrNaN && fracZero ) << 7 | + ( !sign && !infOrNaN && !subnormalOrZero ) << 6 | + ( !sign && subnormalOrZero && !fracZero ) << 5 | + ( !sign && subnormalOrZero && fracZero ) << 4 | + ( isNaN && isSNaN ) << 8 | + ( isNaN && !isSNaN ) << 9; } diff --git a/softfloat/f64_div.c b/softfloat/f64_div.c index 96523f0..c5a2d4f 100644 --- a/softfloat/f64_div.c +++ b/softfloat/f64_div.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_eq.c b/softfloat/f64_eq.c index 6d69e03..ccb602a 100644 --- a/softfloat/f64_eq.c +++ b/softfloat/f64_eq.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_eq_signaling.c b/softfloat/f64_eq_signaling.c index 2f77bbd..ee5a441 100644 --- a/softfloat/f64_eq_signaling.c +++ b/softfloat/f64_eq_signaling.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_isSignalingNaN.c b/softfloat/f64_isSignalingNaN.c index 2858ded..f55acb4 100644 --- a/softfloat/f64_isSignalingNaN.c +++ b/softfloat/f64_isSignalingNaN.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_le.c b/softfloat/f64_le.c index 7462215..91fc994 100644 --- a/softfloat/f64_le.c +++ b/softfloat/f64_le.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_le_quiet.c b/softfloat/f64_le_quiet.c index 907c5ec..a5d332a 100644 --- a/softfloat/f64_le_quiet.c +++ b/softfloat/f64_le_quiet.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_lt.c b/softfloat/f64_lt.c index 902701f..abf62fd 100644 --- a/softfloat/f64_lt.c +++ b/softfloat/f64_lt.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_lt_quiet.c b/softfloat/f64_lt_quiet.c index 5d20c48..6531f57 100644 --- a/softfloat/f64_lt_quiet.c +++ b/softfloat/f64_lt_quiet.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_mul.c b/softfloat/f64_mul.c index 78c4421..86f6654 100644 --- a/softfloat/f64_mul.c +++ b/softfloat/f64_mul.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_mulAdd.c b/softfloat/f64_mulAdd.c index 37bd999..67fc44d 100644 --- a/softfloat/f64_mulAdd.c +++ b/softfloat/f64_mulAdd.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_rem.c b/softfloat/f64_rem.c index 8ae87fc..e917455 100644 --- a/softfloat/f64_rem.c +++ b/softfloat/f64_rem.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_roundToInt.c b/softfloat/f64_roundToInt.c index 94fe40d..7f81007 100644 --- a/softfloat/f64_roundToInt.c +++ b/softfloat/f64_roundToInt.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, 2017 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: @@ -94,10 +94,11 @@ float64_t f64_roundToInt( float64_t a, uint_fast8_t roundingMode, bool exact ) } else if ( roundingMode == softfloat_round_near_even ) { uiZ += lastBitMask>>1; if ( ! (uiZ & roundBitsMask) ) uiZ &= ~lastBitMask; - } else if ( roundingMode != softfloat_round_minMag ) { - if ( signF64UI( uiZ ) ^ (roundingMode == softfloat_round_max) ) { - uiZ += roundBitsMask; - } + } else if ( + roundingMode + == (signF64UI( uiZ ) ? softfloat_round_min : softfloat_round_max) + ) { + uiZ += roundBitsMask; } uiZ &= ~roundBitsMask; if ( exact && (uiZ != uiA) ) { diff --git a/softfloat/f64_sqrt.c b/softfloat/f64_sqrt.c index b65c150..9a06cfa 100644 --- a/softfloat/f64_sqrt.c +++ b/softfloat/f64_sqrt.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, 2017 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: @@ -109,7 +109,7 @@ float64_t f64_sqrt( float64_t a ) sigZ = ((uint_fast64_t) sig32Z<<32 | 1<<5) + ((uint_fast64_t) q<<3); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - if ( (sigZ & 0x1FF) < 1<<5 ) { + if ( (sigZ & 0x1FF) < 0x22 ) { sigZ &= ~(uint_fast64_t) 0x3F; shiftedSigZ = sigZ>>6; rem = (sigA<<52) - shiftedSigZ * shiftedSigZ; diff --git a/softfloat/f64_sub.c b/softfloat/f64_sub.c index 0169ef8..0e990cd 100644 --- a/softfloat/f64_sub.c +++ b/softfloat/f64_sub.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/f64_to_f128.c b/softfloat/f64_to_f128.c new file mode 100644 index 0000000..92c2d56 --- /dev/null +++ b/softfloat/f64_to_f128.c @@ -0,0 +1,98 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t f64_to_f128( float64_t a ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + bool sign; + int_fast16_t exp; + uint_fast64_t frac; + struct commonNaN commonNaN; + struct uint128 uiZ; + struct exp16_sig64 normExpSig; + struct uint128 frac128; + union ui128_f128 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF64UI( uiA ); + exp = expF64UI( uiA ); + frac = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x7FF ) { + if ( frac ) { + softfloat_f64UIToCommonNaN( uiA, &commonNaN ); + uiZ = softfloat_commonNaNToF128UI( &commonNaN ); + } else { + uiZ.v64 = packToF128UI64( sign, 0x7FFF, 0 ); + uiZ.v0 = 0; + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! exp ) { + if ( ! frac ) { + uiZ.v64 = packToF128UI64( sign, 0, 0 ); + uiZ.v0 = 0; + goto uiZ; + } + normExpSig = softfloat_normSubnormalF64Sig( frac ); + exp = normExpSig.exp - 1; + frac = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac128 = softfloat_shortShiftLeft128( 0, frac, 60 ); + uiZ.v64 = packToF128UI64( sign, exp + 0x3C00, frac128.v64 ); + uiZ.v0 = frac128.v0; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f64_to_f16.c b/softfloat/f64_to_f16.c new file mode 100644 index 0000000..325788c --- /dev/null +++ b/softfloat/f64_to_f16.c @@ -0,0 +1,88 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16_t f64_to_f16( float64_t a ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + bool sign; + int_fast16_t exp; + uint_fast64_t frac; + struct commonNaN commonNaN; + uint_fast16_t uiZ, frac16; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF64UI( uiA ); + exp = expF64UI( uiA ); + frac = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp == 0x7FF ) { + if ( frac ) { + softfloat_f64UIToCommonNaN( uiA, &commonNaN ); + uiZ = softfloat_commonNaNToF16UI( &commonNaN ); + } else { + uiZ = packToF16UI( sign, 0x1F, 0 ); + } + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac16 = softfloat_shortShiftRightJam64( frac, 38 ); + if ( ! (exp | frac16) ) { + uiZ = packToF16UI( sign, 0, 0 ); + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return softfloat_roundPackToF16( sign, exp - 0x3F1, frac16 | 0x4000 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f64_to_f32.c b/softfloat/f64_to_f32.c index c08b964..99b13dd 100644 --- a/softfloat/f64_to_f32.c +++ b/softfloat/f64_to_f32.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 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: @@ -47,18 +47,22 @@ float32_t f64_to_f32( float64_t a ) uint_fast64_t uiA; bool sign; int_fast16_t exp; - uint_fast64_t sig; + uint_fast64_t frac; struct commonNaN commonNaN; - uint_fast32_t uiZ, sig32; + uint_fast32_t uiZ, frac32; union ui32_f32 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); + frac = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( exp == 0x7FF ) { - if ( sig ) { + if ( frac ) { softfloat_f64UIToCommonNaN( uiA, &commonNaN ); uiZ = softfloat_commonNaNToF32UI( &commonNaN ); } else { @@ -66,12 +70,16 @@ float32_t f64_to_f32( float64_t a ) } goto uiZ; } - sig32 = softfloat_shortShiftRightJam64( sig, 22 ); - if ( ! (exp | sig32) ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + frac32 = softfloat_shortShiftRightJam64( frac, 22 ); + if ( ! (exp | frac32) ) { uiZ = packToF32UI( sign, 0, 0 ); goto uiZ; } - return softfloat_roundPackToF32( sign, exp - 0x381, sig32 | 0x40000000 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + return softfloat_roundPackToF32( sign, exp - 0x381, frac32 | 0x40000000 ); uiZ: uZ.ui = uiZ; return uZ.f; diff --git a/softfloat/f64_to_i32.c b/softfloat/f64_to_i32.c index b41aac6..8712c0a 100644 --- a/softfloat/f64_to_i32.c +++ b/softfloat/f64_to_i32.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, 2015, 2016 The Regents of the University of -California. All rights reserved. +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: @@ -74,9 +74,9 @@ int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact ) /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftDist = 0x42C - exp; + shiftDist = 0x427 - exp; if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist ); - return softfloat_roundPackToI32( sign, sig, roundingMode, exact ); + return softfloat_roundToI32( sign, sig, roundingMode, exact ); } diff --git a/softfloat/f64_to_i32_r_minMag.c b/softfloat/f64_to_i32_r_minMag.c index ae3171e..b7e1e03 100644 --- a/softfloat/f64_to_i32_r_minMag.c +++ b/softfloat/f64_to_i32_r_minMag.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015, 2016 The Regents of the University of California. All rights reserved. diff --git a/softfloat/f64_to_i64.c b/softfloat/f64_to_i64.c index 58cb45b..4f48843 100644 --- a/softfloat/f64_to_i64.c +++ b/softfloat/f64_to_i64.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, 2015, 2016 The Regents of the University of -California. All rights reserved. +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: @@ -75,7 +75,7 @@ int_fast64_t f64_to_i64( float64_t a, uint_fast8_t roundingMode, bool exact ) sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); } return - softfloat_roundPackToI64( + softfloat_roundToI64( sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); #else extSig[indexWord( 3, 0 )] = 0; @@ -89,7 +89,7 @@ int_fast64_t f64_to_i64( float64_t a, uint_fast8_t roundingMode, bool exact ) extSig[indexWord( 3, 1 )] = sig; softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); } - return softfloat_roundPackMToI64( sign, extSig, roundingMode, exact ); + return softfloat_roundMToI64( sign, extSig, roundingMode, exact ); #endif /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ diff --git a/softfloat/f64_to_i64_r_minMag.c b/softfloat/f64_to_i64_r_minMag.c index 003e165..3822606 100644 --- a/softfloat/f64_to_i64_r_minMag.c +++ b/softfloat/f64_to_i64_r_minMag.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015, 2016 The Regents of the University of California. All rights reserved. diff --git a/softfloat/f64_to_ui32.c b/softfloat/f64_to_ui32.c index 6027c2f..67e4d05 100644 --- a/softfloat/f64_to_ui32.c +++ b/softfloat/f64_to_ui32.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, 2015, 2016 The Regents of the University of -California. All rights reserved. +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: @@ -74,9 +74,9 @@ uint_fast32_t f64_to_ui32( float64_t a, uint_fast8_t roundingMode, bool exact ) /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftDist = 0x42C - exp; + shiftDist = 0x427 - exp; if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist ); - return softfloat_roundPackToUI32( sign, sig, roundingMode, exact ); + return softfloat_roundToUI32( sign, sig, roundingMode, exact ); } diff --git a/softfloat/f64_to_ui32_r_minMag.c b/softfloat/f64_to_ui32_r_minMag.c index 8d0dc71..11f0b05 100644 --- a/softfloat/f64_to_ui32_r_minMag.c +++ b/softfloat/f64_to_ui32_r_minMag.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015, 2016 The Regents of the University of California. All rights reserved. diff --git a/softfloat/f64_to_ui64.c b/softfloat/f64_to_ui64.c index 636d70c..e92d605 100644 --- a/softfloat/f64_to_ui64.c +++ b/softfloat/f64_to_ui64.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, 2015, 2016 The Regents of the University of -California. All rights reserved. +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: @@ -75,7 +75,7 @@ uint_fast64_t f64_to_ui64( float64_t a, uint_fast8_t roundingMode, bool exact ) sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); } return - softfloat_roundPackToUI64( + softfloat_roundToUI64( sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); #else extSig[indexWord( 3, 0 )] = 0; @@ -89,7 +89,7 @@ uint_fast64_t f64_to_ui64( float64_t a, uint_fast8_t roundingMode, bool exact ) extSig[indexWord( 3, 1 )] = sig; softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); } - return softfloat_roundPackMToUI64( sign, extSig, roundingMode, exact ); + return softfloat_roundMToUI64( sign, extSig, roundingMode, exact ); #endif /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ diff --git a/softfloat/f64_to_ui64_r_minMag.c b/softfloat/f64_to_ui64_r_minMag.c index e54c930..25918c4 100644 --- a/softfloat/f64_to_ui64_r_minMag.c +++ b/softfloat/f64_to_ui64_r_minMag.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015, 2016 The Regents of the University of California. All rights reserved. diff --git a/softfloat/i32_to_f128.c b/softfloat/i32_to_f128.c new file mode 100644 index 0000000..af7268a --- /dev/null +++ b/softfloat/i32_to_f128.c @@ -0,0 +1,64 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float128_t i32_to_f128( int32_t a ) +{ + uint_fast64_t uiZ64; + bool sign; + uint_fast32_t absA; + int_fast8_t shiftDist; + union ui128_f128 uZ; + + uiZ64 = 0; + if ( a ) { + sign = (a < 0); + absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a; + shiftDist = softfloat_countLeadingZeros32( absA ) + 17; + uiZ64 = + packToF128UI64( + sign, 0x402E - shiftDist, (uint_fast64_t) absA<<shiftDist ); + } + uZ.ui.v64 = uiZ64; + uZ.ui.v0 = 0; + return uZ.f; + +} + diff --git a/softfloat/i32_to_f16.c b/softfloat/i32_to_f16.c new file mode 100644 index 0000000..7442972 --- /dev/null +++ b/softfloat/i32_to_f16.c @@ -0,0 +1,71 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float16_t i32_to_f16( int32_t a ) +{ + bool sign; + uint_fast32_t absA; + int_fast8_t shiftDist; + union ui16_f16 u; + uint_fast16_t sig; + + sign = (a < 0); + absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a; + shiftDist = softfloat_countLeadingZeros32( absA ) - 21; + if ( 0 <= shiftDist ) { + u.ui = + a ? packToF16UI( + sign, 0x18 - shiftDist, (uint_fast16_t) absA<<shiftDist ) + : 0; + return u.f; + } else { + shiftDist += 4; + sig = + (shiftDist < 0) + ? absA>>(-shiftDist) + | ((uint32_t) (absA<<(shiftDist & 31)) != 0) + : (uint_fast16_t) absA<<shiftDist; + return softfloat_roundPackToF16( sign, 0x1C - shiftDist, sig ); + } + +} + diff --git a/softfloat/i32_to_f32.c b/softfloat/i32_to_f32.c index bfe8ace..b1aedba 100644 --- a/softfloat/i32_to_f32.c +++ b/softfloat/i32_to_f32.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/i32_to_f64.c b/softfloat/i32_to_f64.c index ac17f78..d3901eb 100644 --- a/softfloat/i32_to_f64.c +++ b/softfloat/i32_to_f64.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: @@ -45,7 +45,7 @@ float64_t i32_to_f64( int32_t a ) uint_fast64_t uiZ; bool sign; uint_fast32_t absA; - int_fast8_t shiftCount; + int_fast8_t shiftDist; union ui64_f64 uZ; if ( ! a ) { @@ -53,10 +53,10 @@ float64_t i32_to_f64( int32_t a ) } else { sign = (a < 0); absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a; - shiftCount = softfloat_countLeadingZeros32( absA ) + 21; + shiftDist = softfloat_countLeadingZeros32( absA ) + 21; uiZ = packToF64UI( - sign, 0x432 - shiftCount, (uint_fast64_t) absA<<shiftCount ); + sign, 0x432 - shiftDist, (uint_fast64_t) absA<<shiftDist ); } uZ.ui = uiZ; return uZ.f; diff --git a/softfloat/i64_to_f128.c b/softfloat/i64_to_f128.c new file mode 100644 index 0000000..8eddbae --- /dev/null +++ b/softfloat/i64_to_f128.c @@ -0,0 +1,72 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float128_t i64_to_f128( int64_t a ) +{ + uint_fast64_t uiZ64, uiZ0; + bool sign; + uint_fast64_t absA; + int_fast8_t shiftDist; + struct uint128 zSig; + union ui128_f128 uZ; + + if ( ! a ) { + uiZ64 = 0; + uiZ0 = 0; + } else { + sign = (a < 0); + absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a; + shiftDist = softfloat_countLeadingZeros64( absA ) + 49; + if ( 64 <= shiftDist ) { + zSig.v64 = absA<<(shiftDist - 64); + zSig.v0 = 0; + } else { + zSig = softfloat_shortShiftLeft128( 0, absA, shiftDist ); + } + uiZ64 = packToF128UI64( sign, 0x406E - shiftDist, zSig.v64 ); + uiZ0 = zSig.v0; + } + uZ.ui.v64 = uiZ64; + uZ.ui.v0 = uiZ0; + return uZ.f; + +} + diff --git a/softfloat/i64_to_f16.c b/softfloat/i64_to_f16.c new file mode 100644 index 0000000..56f0191 --- /dev/null +++ b/softfloat/i64_to_f16.c @@ -0,0 +1,70 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float16_t i64_to_f16( int64_t a ) +{ + bool sign; + uint_fast64_t absA; + int_fast8_t shiftDist; + union ui16_f16 u; + uint_fast16_t sig; + + sign = (a < 0); + absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a; + shiftDist = softfloat_countLeadingZeros64( absA ) - 53; + if ( 0 <= shiftDist ) { + u.ui = + a ? packToF16UI( + sign, 0x18 - shiftDist, (uint_fast16_t) absA<<shiftDist ) + : 0; + return u.f; + } else { + shiftDist += 4; + sig = + (shiftDist < 0) + ? softfloat_shortShiftRightJam64( absA, -shiftDist ) + : (uint_fast16_t) absA<<shiftDist; + return softfloat_roundPackToF16( sign, 0x1C - shiftDist, sig ); + } + +} + diff --git a/softfloat/i64_to_f32.c b/softfloat/i64_to_f32.c index ae68ad9..e8a3494 100644 --- a/softfloat/i64_to_f32.c +++ b/softfloat/i64_to_f32.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: @@ -44,26 +44,26 @@ float32_t i64_to_f32( int64_t a ) { bool sign; uint_fast64_t absA; - int_fast8_t shiftCount; + int_fast8_t shiftDist; union ui32_f32 u; uint_fast32_t sig; sign = (a < 0); absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a; - shiftCount = softfloat_countLeadingZeros64( absA ) - 40; - if ( 0 <= shiftCount ) { + shiftDist = softfloat_countLeadingZeros64( absA ) - 40; + if ( 0 <= shiftDist ) { u.ui = a ? packToF32UI( - sign, 0x95 - shiftCount, (uint_fast32_t) absA<<shiftCount ) + sign, 0x95 - shiftDist, (uint_fast32_t) absA<<shiftDist ) : 0; return u.f; } else { - shiftCount += 7; + shiftDist += 7; sig = - (shiftCount < 0) - ? softfloat_shortShiftRightJam64( absA, -shiftCount ) - : (uint_fast32_t) absA<<shiftCount; - return softfloat_roundPackToF32( sign, 0x9C - shiftCount, sig ); + (shiftDist < 0) + ? softfloat_shortShiftRightJam64( absA, -shiftDist ) + : (uint_fast32_t) absA<<shiftDist; + return softfloat_roundPackToF32( sign, 0x9C - shiftDist, sig ); } } diff --git a/softfloat/i64_to_f64.c b/softfloat/i64_to_f64.c index 952a049..392fef9 100644 --- a/softfloat/i64_to_f64.c +++ b/softfloat/i64_to_f64.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/internals.h b/softfloat/internals.h index cf57bdc..55585e9 100644 --- a/softfloat/internals.h +++ b/softfloat/internals.h @@ -2,10 +2,10 @@ /*============================================================================ This C header 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, 2017 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: @@ -42,6 +42,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "primitives.h" #include "softfloat_types.h" +#ifdef __cplusplus +extern "C" { +#endif + +union ui16_f16 { uint16_t ui; float16_t f; }; union ui32_f32 { uint32_t ui; float32_t f; }; union ui64_f64 { uint64_t ui; float64_t f; }; @@ -57,37 +62,55 @@ enum { /*---------------------------------------------------------------------------- *----------------------------------------------------------------------------*/ -uint_fast32_t - softfloat_roundPackToUI32( bool, uint_fast64_t, uint_fast8_t, bool ); +uint_fast32_t softfloat_roundToUI32( bool, uint_fast64_t, uint_fast8_t, bool ); #ifdef SOFTFLOAT_FAST_INT64 uint_fast64_t - softfloat_roundPackToUI64( + softfloat_roundToUI64( bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool ); #else -uint_fast64_t - softfloat_roundPackMToUI64( bool, uint32_t *, uint_fast8_t, bool ); +uint_fast64_t softfloat_roundMToUI64( bool, uint32_t *, uint_fast8_t, bool ); #endif -int_fast32_t - softfloat_roundPackToI32( bool, uint_fast64_t, uint_fast8_t, bool ); +int_fast32_t softfloat_roundToI32( bool, uint_fast64_t, uint_fast8_t, bool ); #ifdef SOFTFLOAT_FAST_INT64 int_fast64_t - softfloat_roundPackToI64( + softfloat_roundToI64( bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool ); #else -int_fast64_t softfloat_roundPackMToI64( bool, uint32_t *, uint_fast8_t, bool ); +int_fast64_t softfloat_roundMToI64( bool, uint32_t *, uint_fast8_t, bool ); #endif /*---------------------------------------------------------------------------- *----------------------------------------------------------------------------*/ +#define signF16UI( a ) ((bool) ((uint16_t) (a)>>15)) +#define expF16UI( a ) ((int_fast8_t) ((a)>>10) & 0x1F) +#define fracF16UI( a ) ((a) & 0x03FF) +#define packToF16UI( sign, exp, sig ) (((uint16_t) (sign)<<15) + ((uint16_t) (exp)<<10) + (sig)) + +#define isNaNF16UI( a ) (((~(a) & 0x7C00) == 0) && ((a) & 0x03FF)) + +struct exp8_sig16 { int_fast8_t exp; uint_fast16_t sig; }; +struct exp8_sig16 softfloat_normSubnormalF16Sig( uint_fast16_t ); + +float16_t softfloat_roundPackToF16( bool, int_fast16_t, uint_fast16_t ); +float16_t softfloat_normRoundPackToF16( bool, int_fast16_t, uint_fast16_t ); + +float16_t softfloat_addMagsF16( uint_fast16_t, uint_fast16_t ); +float16_t softfloat_subMagsF16( uint_fast16_t, uint_fast16_t ); +float16_t + softfloat_mulAddF16( + uint_fast16_t, uint_fast16_t, uint_fast16_t, uint_fast8_t ); + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ #define signF32UI( a ) ((bool) ((uint32_t) (a)>>31)) #define expF32UI( a ) ((int_fast16_t) ((a)>>23) & 0xFF) #define fracF32UI( a ) ((a) & 0x007FFFFF) #define packToF32UI( sign, exp, sig ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig)) -#define isNaNF32UI( a ) ((((a) & 0x7F800000) == 0x7F800000) && ((a) & 0x007FFFFF)) +#define isNaNF32UI( a ) (((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF)) struct exp16_sig32 { int_fast16_t exp; uint_fast32_t sig; }; struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t ); @@ -95,8 +118,8 @@ struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t ); float32_t softfloat_roundPackToF32( bool, int_fast16_t, uint_fast32_t ); float32_t softfloat_normRoundPackToF32( bool, int_fast16_t, uint_fast32_t ); -float32_t softfloat_addMagsF32( uint_fast32_t, uint_fast32_t, bool ); -float32_t softfloat_subMagsF32( uint_fast32_t, uint_fast32_t, bool ); +float32_t softfloat_addMagsF32( uint_fast32_t, uint_fast32_t ); +float32_t softfloat_subMagsF32( uint_fast32_t, uint_fast32_t ); float32_t softfloat_mulAddF32( uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t ); @@ -108,7 +131,7 @@ float32_t #define fracF64UI( a ) ((a) & UINT64_C( 0x000FFFFFFFFFFFFF )) #define packToF64UI( sign, exp, sig ) ((uint64_t) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<52) + (sig))) -#define isNaNF64UI( a ) ((((a) & UINT64_C( 0x7FF0000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((a) & UINT64_C( 0x000FFFFFFFFFFFFF ))) +#define isNaNF64UI( a ) (((~(a) & UINT64_C( 0x7FF0000000000000 )) == 0) && ((a) & UINT64_C( 0x000FFFFFFFFFFFFF ))) struct exp16_sig64 { int_fast16_t exp; uint_fast64_t sig; }; struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t ); @@ -159,7 +182,7 @@ extFloat80_t #define fracF128UI64( a64 ) ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )) #define packToF128UI64( sign, exp, sig64 ) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<48) + (sig64)) -#define isNaNF128UI( a64, a0 ) ((((a64) & UINT64_C( 0x7FFF000000000000 )) == UINT64_C( 0x7FFF000000000000 )) && (a0 || ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )))) +#define isNaNF128UI( a64, a0 ) (((~(a64) & UINT64_C( 0x7FFF000000000000 )) == 0) && (a0 || ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )))) struct exp32_sig128 { int_fast32_t exp; struct uint128 sig; }; struct exp32_sig128 @@ -255,5 +278,9 @@ void #endif +#ifdef __cplusplus +} +#endif + #endif diff --git a/softfloat/primitives.h b/softfloat/primitives.h index a193555..1acc8a8 100644 --- a/softfloat/primitives.h +++ b/softfloat/primitives.h @@ -2,10 +2,10 @@ /*============================================================================ This C header 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, 2017 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: @@ -37,71 +37,69 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef primitives_h #define primitives_h 1 -#ifdef __cplusplus -extern "C" { -#endif - #include <stdbool.h> #include <stdint.h> #include "primitiveTypes.h" +#ifdef __cplusplus +extern "C" { +#endif + #ifndef softfloat_shortShiftRightJam64 /*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count', which must be in +| Shifts 'a' right by the number of bits given in 'dist', which must be in | the range 1 to 63. If any nonzero bits are shifted off, they are "jammed" | into the least-significant bit of the shifted value by setting the least- | significant bit to 1. This shifted-and-jammed value is returned. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) INLINE - uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t count ) - { return a>>count | ((a & (((uint_fast64_t) 1<<count) - 1)) != 0); } +uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist ) + { return a>>dist | ((a & (((uint_fast64_t) 1<<dist) - 1)) != 0); } #else -uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t count ); +uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist ); #endif #endif #ifndef softfloat_shiftRightJam32 /*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count', which must not +| Shifts 'a' right by the number of bits given in 'dist', which must not | be zero. If any nonzero bits are shifted off, they are "jammed" into the | least-significant bit of the shifted value by setting the least-significant | bit to 1. This shifted-and-jammed value is returned. -| The value of `count' can be arbitrarily large. In particular, if `count' -| is greater than 32, the result will be either 0 or 1, depending on whether -| `a' is zero or nonzero. +| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is +| greater than 32, the result will be either 0 or 1, depending on whether 'a' +| is zero or nonzero. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) -INLINE uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t count ) +INLINE uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist ) { return - (count < 31) ? a>>count | ((uint32_t) (a<<(-count & 31)) != 0) - : (a != 0); + (dist < 31) ? a>>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0); } #else -uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t count ); +uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist ); #endif #endif #ifndef softfloat_shiftRightJam64 /*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count', which must not +| Shifts 'a' right by the number of bits given in 'dist', which must not | be zero. If any nonzero bits are shifted off, they are "jammed" into the | least-significant bit of the shifted value by setting the least-significant | bit to 1. This shifted-and-jammed value is returned. -| The value of `count' can be arbitrarily large. In particular, if `count' -| is greater than 64, the result will be either 0 or 1, depending on whether -| `a' is zero or nonzero. +| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is +| greater than 64, the result will be either 0 or 1, depending on whether 'a' +| is zero or nonzero. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) -INLINE uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t count ) +INLINE uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist ) { return - (count < 63) ? a>>count | ((uint64_t) (a<<(-count & 63)) != 0) - : (a != 0); + (dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0); } #else -uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t count ); +uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist ); #endif #endif @@ -112,10 +110,31 @@ uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t count ); *----------------------------------------------------------------------------*/ extern const uint_least8_t softfloat_countLeadingZeros8[256]; +#ifndef softfloat_countLeadingZeros16 +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| 'a'. If 'a' is zero, 16 is returned. +*----------------------------------------------------------------------------*/ +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) +INLINE uint_fast8_t softfloat_countLeadingZeros16( uint16_t a ) +{ + uint_fast8_t count = 8; + if ( 0x100 <= a ) { + count = 0; + a >>= 8; + } + count += softfloat_countLeadingZeros8[a]; + return count; +} +#else +uint_fast8_t softfloat_countLeadingZeros16( uint16_t a ); +#endif +#endif + #ifndef softfloat_countLeadingZeros32 /*---------------------------------------------------------------------------- | Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 32 is returned. +| 'a'. If 'a' is zero, 32 is returned. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) INLINE uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ) @@ -140,18 +159,21 @@ uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ); #ifndef softfloat_countLeadingZeros64 /*---------------------------------------------------------------------------- | Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 64 is returned. +| 'a'. If 'a' is zero, 64 is returned. *----------------------------------------------------------------------------*/ uint_fast8_t softfloat_countLeadingZeros64( uint64_t a ); #endif +extern const uint16_t softfloat_approxRecip_1k0s[16]; +extern const uint16_t softfloat_approxRecip_1k1s[16]; + #ifndef softfloat_approxRecip32_1 /*---------------------------------------------------------------------------- -| Returns an approximation to the reciprocal of the number represented by `a', -| where `a' is interpreted as an unsigned fixed-point number with one integer -| bit and 31 fraction bits. The `a' input must be "normalized", meaning that +| Returns an approximation to the reciprocal of the number represented by 'a', +| where 'a' is interpreted as an unsigned fixed-point number with one integer +| bit and 31 fraction bits. The 'a' input must be "normalized", meaning that | its most-significant bit (bit 31) must be 1. Thus, if A is the value of -| the fixed-point interpretation of `a', then 1 <= A < 2. The returned value +| the fixed-point interpretation of 'a', then 1 <= A < 2. The returned value | is interpreted as a pure unsigned fraction, having no integer bits and 32 | fraction bits. The approximation returned is never greater than the true | reciprocal 1/A, and it differs from the true reciprocal by at most 2.006 ulp @@ -164,18 +186,21 @@ uint32_t softfloat_approxRecip32_1( uint32_t a ); #endif #endif +extern const uint16_t softfloat_approxRecipSqrt_1k0s[16]; +extern const uint16_t softfloat_approxRecipSqrt_1k1s[16]; + #ifndef softfloat_approxRecipSqrt32_1 /*---------------------------------------------------------------------------- | Returns an approximation to the reciprocal of the square root of the number -| represented by `a', where `a' is interpreted as an unsigned fixed-point +| represented by 'a', where 'a' is interpreted as an unsigned fixed-point | number either with one integer bit and 31 fraction bits or with two integer -| bits and 30 fraction bits. The format of `a' is determined by `oddExpA', -| which must be either 0 or 1. If `oddExpA' is 1, `a' is interpreted as -| having one integer bit, and if `oddExpA' is 0, `a' is interpreted as having -| two integer bits. The `a' input must be "normalized", meaning that its +| bits and 30 fraction bits. The format of 'a' is determined by 'oddExpA', +| which must be either 0 or 1. If 'oddExpA' is 1, 'a' is interpreted as +| having one integer bit, and if 'oddExpA' is 0, 'a' is interpreted as having +| two integer bits. The 'a' input must be "normalized", meaning that its | most-significant bit (bit 31) must be 1. Thus, if A is the value of the -| fixed-point interpretation of `a', it follows that 1 <= A < 2 when `oddExpA' -| is 1, and 2 <= A < 4 when `oddExpA' is 0. +| fixed-point interpretation of 'a', it follows that 1 <= A < 2 when 'oddExpA' +| is 1, and 2 <= A < 4 when 'oddExpA' is 0. | The returned value is interpreted as a pure unsigned fraction, having | no integer bits and 32 fraction bits. The approximation returned is never | greater than the true reciprocal 1/sqrt(A), and it differs from the true @@ -189,19 +214,19 @@ uint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a ); #ifdef SOFTFLOAT_FAST_INT64 /*---------------------------------------------------------------------------- -| The following functions are needed only when `SOFTFLOAT_FAST_INT64' is +| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is | defined. *----------------------------------------------------------------------------*/ #ifndef softfloat_eq128 /*---------------------------------------------------------------------------- -| Returns true if the 128-bit unsigned integer formed by concatenating `a64' -| and `a0' is equal to the 128-bit unsigned integer formed by concatenating -| `b64' and `b0'. +| Returns true if the 128-bit unsigned integer formed by concatenating 'a64' +| and 'a0' is equal to the 128-bit unsigned integer formed by concatenating +| 'b64' and 'b0'. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) INLINE - bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) { return (a64 == b64) && (a0 == b0); } #else bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); @@ -210,13 +235,13 @@ bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); #ifndef softfloat_le128 /*---------------------------------------------------------------------------- -| Returns true if the 128-bit unsigned integer formed by concatenating `a64' -| and `a0' is less than or equal to the 128-bit unsigned integer formed by -| concatenating `b64' and `b0'. +| Returns true if the 128-bit unsigned integer formed by concatenating 'a64' +| and 'a0' is less than or equal to the 128-bit unsigned integer formed by +| concatenating 'b64' and 'b0'. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) INLINE - bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) { return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); } #else bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); @@ -225,13 +250,13 @@ bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); #ifndef softfloat_lt128 /*---------------------------------------------------------------------------- -| Returns true if the 128-bit unsigned integer formed by concatenating `a64' -| and `a0' is less than the 128-bit unsigned integer formed by concatenating -| `b64' and `b0'. +| Returns true if the 128-bit unsigned integer formed by concatenating 'a64' +| and 'a0' is less than the 128-bit unsigned integer formed by concatenating +| 'b64' and 'b0'. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) INLINE - bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) { return (a64 < b64) || ((a64 == b64) && (a0 < b0)); } #else bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); @@ -240,153 +265,153 @@ bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); #ifndef softfloat_shortShiftLeft128 /*---------------------------------------------------------------------------- -| Shifts the 128 bits formed by concatenating `a64' and `a0' left by the -| number of bits given in `count', which must be in the range 1 to 63. +| Shifts the 128 bits formed by concatenating 'a64' and 'a0' left by the +| number of bits given in 'dist', which must be in the range 1 to 63. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) INLINE - struct uint128 - softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t count ) +struct uint128 + softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist ) { struct uint128 z; - z.v64 = a64<<count | a0>>(-count & 63); - z.v0 = a0<<count; + z.v64 = a64<<dist | a0>>(-dist & 63); + z.v0 = a0<<dist; return z; } #else struct uint128 - softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t count ); + softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist ); #endif #endif #ifndef softfloat_shortShiftRight128 /*---------------------------------------------------------------------------- -| Shifts the 128 bits formed by concatenating `a64' and `a0' right by the -| number of bits given in `count', which must be in the range 1 to 63. +| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the +| number of bits given in 'dist', which must be in the range 1 to 63. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) INLINE - struct uint128 - softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t count ) +struct uint128 + softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist ) { struct uint128 z; - z.v64 = a64>>count; - z.v0 = a64<<(-count & 63) | a0>>count; + z.v64 = a64>>dist; + z.v0 = a64<<(-dist & 63) | a0>>dist; return z; } #else struct uint128 - softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t count ); + softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist ); #endif #endif #ifndef softfloat_shortShiftRightJam64Extra /*---------------------------------------------------------------------------- -| This function is the same as `softfloat_shiftRightJam64Extra' (below), -| except that `count' must be in the range 1 to 63. +| This function is the same as 'softfloat_shiftRightJam64Extra' (below), +| except that 'dist' must be in the range 1 to 63. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) INLINE - struct uint64_extra - softfloat_shortShiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast8_t count ) +struct uint64_extra + softfloat_shortShiftRightJam64Extra( + uint64_t a, uint64_t extra, uint_fast8_t dist ) { struct uint64_extra z; - z.v = a>>count; - z.extra = a<<(-count & 63) | (extra != 0); + z.v = a>>dist; + z.extra = a<<(-dist & 63) | (extra != 0); return z; } #else struct uint64_extra softfloat_shortShiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast8_t count ); + uint64_t a, uint64_t extra, uint_fast8_t dist ); #endif #endif #ifndef softfloat_shortShiftRightJam128 /*---------------------------------------------------------------------------- -| Shifts the 128 bits formed by concatenating `a64' and `a0' right by the -| number of bits given in `count', which must be in the range 1 to 63. If any +| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the +| number of bits given in 'dist', which must be in the range 1 to 63. If any | nonzero bits are shifted off, they are "jammed" into the least-significant | bit of the shifted value by setting the least-significant bit to 1. This | shifted-and-jammed value is returned. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) INLINE - struct uint128 - softfloat_shortShiftRightJam128( - uint64_t a64, uint64_t a0, uint_fast8_t count ) +struct uint128 + softfloat_shortShiftRightJam128( + uint64_t a64, uint64_t a0, uint_fast8_t dist ) { - uint_fast8_t negCount = -count; + uint_fast8_t negDist = -dist; struct uint128 z; - z.v64 = a64>>count; + z.v64 = a64>>dist; z.v0 = - a64<<(negCount & 63) | a0>>count - | ((uint64_t) (a0<<(negCount & 63)) != 0); + a64<<(negDist & 63) | a0>>dist + | ((uint64_t) (a0<<(negDist & 63)) != 0); return z; } #else struct uint128 softfloat_shortShiftRightJam128( - uint64_t a64, uint64_t a0, uint_fast8_t count ); + uint64_t a64, uint64_t a0, uint_fast8_t dist ); #endif #endif #ifndef softfloat_shortShiftRightJam128Extra /*---------------------------------------------------------------------------- -| This function is the same as `softfloat_shiftRightJam128Extra' (below), -| except that `count' must be in the range 1 to 63. +| This function is the same as 'softfloat_shiftRightJam128Extra' (below), +| except that 'dist' must be in the range 1 to 63. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) INLINE - struct uint128_extra - softfloat_shortShiftRightJam128Extra( - uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t count ) +struct uint128_extra + softfloat_shortShiftRightJam128Extra( + uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist ) { - uint_fast8_t negCount = -count; + uint_fast8_t negDist = -dist; struct uint128_extra z; - z.v.v64 = a64>>count; - z.v.v0 = a64<<(negCount & 63) | a0>>count; - z.extra = a0<<(negCount & 63) | (extra != 0); + z.v.v64 = a64>>dist; + z.v.v0 = a64<<(negDist & 63) | a0>>dist; + z.extra = a0<<(negDist & 63) | (extra != 0); return z; } #else struct uint128_extra softfloat_shortShiftRightJam128Extra( - uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t count ); + uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist ); #endif #endif #ifndef softfloat_shiftRightJam64Extra /*---------------------------------------------------------------------------- -| Shifts the 128 bits formed by concatenating `a' and `extra' right by 64 -| _plus_ the number of bits given in `count', which must not be zero. This -| shifted value is at most 64 nonzero bits and is returned in the `v' field -| of the `struct uint64_extra' result. The 64-bit `extra' field of the result +| Shifts the 128 bits formed by concatenating 'a' and 'extra' right by 64 +| _plus_ the number of bits given in 'dist', which must not be zero. This +| shifted value is at most 64 nonzero bits and is returned in the 'v' field +| of the 'struct uint64_extra' result. The 64-bit 'extra' field of the result | contains a value formed as follows from the bits that were shifted off: The -| _last_ bit shifted off is the most-significant bit of the `extra' field, and -| the other 63 bits of the `extra' field are all zero if and only if _all_but_ +| _last_ bit shifted off is the most-significant bit of the 'extra' field, and +| the other 63 bits of the 'extra' field are all zero if and only if _all_but_ | _the_last_ bits shifted off were all zero. -| (This function makes more sense if `a' and `extra' are considered to form -| an unsigned fixed-point number with binary point between `a' and `extra'. +| (This function makes more sense if 'a' and 'extra' are considered to form +| an unsigned fixed-point number with binary point between 'a' and 'extra'. | This fixed-point value is shifted right by the number of bits given in -| `count', and the integer part of this shifted value is returned in the `v' +| 'dist', and the integer part of this shifted value is returned in the 'v' | field of the result. The fractional part of the shifted value is modified -| as described above and returned in the `extra' field of the result.) +| as described above and returned in the 'extra' field of the result.) *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (4 <= INLINE_LEVEL) INLINE - struct uint64_extra - softfloat_shiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast32_t count ) +struct uint64_extra + softfloat_shiftRightJam64Extra( + uint64_t a, uint64_t extra, uint_fast32_t dist ) { struct uint64_extra z; - if ( count < 64 ) { - z.v = a>>count; - z.extra = a<<(-count & 63); + if ( dist < 64 ) { + z.v = a>>dist; + z.extra = a<<(-dist & 63); } else { z.v = 0; - z.extra = (count == 64) ? a : (a != 0); + z.extra = (dist == 64) ? a : (a != 0); } z.extra |= (extra != 0); return z; @@ -394,76 +419,76 @@ INLINE #else struct uint64_extra softfloat_shiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast32_t count ); + uint64_t a, uint64_t extra, uint_fast32_t dist ); #endif #endif #ifndef softfloat_shiftRightJam128 /*---------------------------------------------------------------------------- -| Shifts the 128 bits formed by concatenating `a64' and `a0' right by the -| number of bits given in `count', which must not be zero. If any nonzero -| bits are shifted off, they are "jammed" into the least-significant bit of -| the shifted value by setting the least-significant bit to 1. This shifted- -| and-jammed value is returned. -| The value of `count' can be arbitrarily large. In particular, if `count' -| is greater than 128, the result will be either 0 or 1, depending on whether -| the original 128 bits are all zeros. +| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the +| number of bits given in 'dist', which must not be zero. If any nonzero bits +| are shifted off, they are "jammed" into the least-significant bit of the +| shifted value by setting the least-significant bit to 1. This shifted-and- +| jammed value is returned. +| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is +| greater than 128, the result will be either 0 or 1, depending on whether the +| original 128 bits are all zeros. *----------------------------------------------------------------------------*/ struct uint128 - softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t count ); + softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t dist ); #endif #ifndef softfloat_shiftRightJam128Extra /*---------------------------------------------------------------------------- -| Shifts the 192 bits formed by concatenating `a64', `a0', and `extra' right -| by 64 _plus_ the number of bits given in `count', which must not be zero. -| This shifted value is at most 128 nonzero bits and is returned in the `v' -| field of the `struct uint128_extra' result. The 64-bit `extra' field of the +| Shifts the 192 bits formed by concatenating 'a64', 'a0', and 'extra' right +| by 64 _plus_ the number of bits given in 'dist', which must not be zero. +| This shifted value is at most 128 nonzero bits and is returned in the 'v' +| field of the 'struct uint128_extra' result. The 64-bit 'extra' field of the | result contains a value formed as follows from the bits that were shifted -| off: The _last_ bit shifted off is the most-significant bit of the `extra' -| field, and the other 63 bits of the `extra' field are all zero if and only +| off: The _last_ bit shifted off is the most-significant bit of the 'extra' +| field, and the other 63 bits of the 'extra' field are all zero if and only | if _all_but_the_last_ bits shifted off were all zero. -| (This function makes more sense if `a64', `a0', and `extra' are considered -| to form an unsigned fixed-point number with binary point between `a0' and -| `extra'. This fixed-point value is shifted right by the number of bits -| given in `count', and the integer part of this shifted value is returned -| in the `v' field of the result. The fractional part of the shifted value -| is modified as described above and returned in the `extra' field of the +| (This function makes more sense if 'a64', 'a0', and 'extra' are considered +| to form an unsigned fixed-point number with binary point between 'a0' and +| 'extra'. This fixed-point value is shifted right by the number of bits +| given in 'dist', and the integer part of this shifted value is returned +| in the 'v' field of the result. The fractional part of the shifted value +| is modified as described above and returned in the 'extra' field of the | result.) *----------------------------------------------------------------------------*/ struct uint128_extra softfloat_shiftRightJam128Extra( - uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t count ); + uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist ); #endif #ifndef softfloat_shiftRightJam256M /*---------------------------------------------------------------------------- -| Shifts the 256-bit unsigned integer pointed to by `aPtr' right by the number -| of bits given in `count', which must not be zero. If any nonzero bits are +| Shifts the 256-bit unsigned integer pointed to by 'aPtr' right by the number +| of bits given in 'dist', which must not be zero. If any nonzero bits are | shifted off, they are "jammed" into the least-significant bit of the shifted | value by setting the least-significant bit to 1. This shifted-and-jammed -| value is stored at the location pointed to by `zPtr'. Each of `aPtr' and -| `zPtr' points to an array of four 64-bit elements that concatenate in the +| value is stored at the location pointed to by 'zPtr'. Each of 'aPtr' and +| 'zPtr' points to an array of four 64-bit elements that concatenate in the | platform's normal endian order to form a 256-bit integer. -| The value of `count' can be arbitrarily large. In particular, if `count' +| The value of 'dist' can be arbitrarily large. In particular, if 'dist' | is greater than 256, the stored result will be either 0 or 1, depending on | whether the original 256 bits are all zeros. *----------------------------------------------------------------------------*/ void softfloat_shiftRightJam256M( - const uint64_t *aPtr, uint_fast32_t count, uint64_t *zPtr ); + const uint64_t *aPtr, uint_fast32_t dist, uint64_t *zPtr ); #endif #ifndef softfloat_add128 /*---------------------------------------------------------------------------- -| Returns the sum of the 128-bit integer formed by concatenating `a64' and -| `a0' and the 128-bit integer formed by concatenating `b64' and `b0'. The +| Returns the sum of the 128-bit integer formed by concatenating 'a64' and +| 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'. The | addition is modulo 2^128, so any carry out is lost. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) INLINE - struct uint128 - softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +struct uint128 + softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) { struct uint128 z; z.v0 = a0 + b0; @@ -478,9 +503,9 @@ struct uint128 #ifndef softfloat_add256M /*---------------------------------------------------------------------------- -| Adds the two 256-bit integers pointed to by `aPtr' and `bPtr'. The addition +| Adds the two 256-bit integers pointed to by 'aPtr' and 'bPtr'. The addition | is modulo 2^256, so any carry out is lost. The sum is stored at the -| location pointed to by `zPtr'. Each of `aPtr', `bPtr', and `zPtr' points to +| location pointed to by 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to | an array of four 64-bit elements that concatenate in the platform's normal | endian order to form a 256-bit integer. *----------------------------------------------------------------------------*/ @@ -491,14 +516,14 @@ void #ifndef softfloat_sub128 /*---------------------------------------------------------------------------- -| Returns the difference of the 128-bit integer formed by concatenating `a64' -| and `a0' and the 128-bit integer formed by concatenating `b64' and `b0'. +| Returns the difference of the 128-bit integer formed by concatenating 'a64' +| and 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'. | The subtraction is modulo 2^128, so any borrow out (carry out) is lost. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) INLINE - struct uint128 - softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +struct uint128 + softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) { struct uint128 z; z.v0 = a0 - b0; @@ -514,10 +539,10 @@ struct uint128 #ifndef softfloat_sub256M /*---------------------------------------------------------------------------- -| Subtracts the 256-bit integer pointed to by `bPtr' from the 256-bit integer -| pointed to by `aPtr'. The addition is modulo 2^256, so any borrow out +| Subtracts the 256-bit integer pointed to by 'bPtr' from the 256-bit integer +| pointed to by 'aPtr'. The addition is modulo 2^256, so any borrow out | (carry out) is lost. The difference is stored at the location pointed to -| by `zPtr'. Each of `aPtr', `bPtr', and `zPtr' points to an array of four +| by 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to an array of four | 64-bit elements that concatenate in the platform's normal endian order to | form a 256-bit integer. *----------------------------------------------------------------------------*/ @@ -528,7 +553,7 @@ void #ifndef softfloat_mul64ByShifted32To128 /*---------------------------------------------------------------------------- -| Returns the 128-bit product of `a', `b', and 2^32. +| Returns the 128-bit product of 'a', 'b', and 2^32. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) INLINE struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ) @@ -547,20 +572,20 @@ struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ); #ifndef softfloat_mul64To128 /*---------------------------------------------------------------------------- -| Returns the 128-bit product of `a' and `b'. +| Returns the 128-bit product of 'a' and 'b'. *----------------------------------------------------------------------------*/ struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b ); #endif #ifndef softfloat_mul128By32 /*---------------------------------------------------------------------------- -| Returns the product of the 128-bit integer formed by concatenating `a64' and -| `a0', multiplied by `b'. The multiplication is modulo 2^128; any overflow +| Returns the product of the 128-bit integer formed by concatenating 'a64' and +| 'a0', multiplied by 'b'. The multiplication is modulo 2^128; any overflow | bits are discarded. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (4 <= INLINE_LEVEL) INLINE - struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ) +struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ) { struct uint128 z; uint_fast64_t mid; @@ -578,10 +603,10 @@ struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ); #ifndef softfloat_mul128To256M /*---------------------------------------------------------------------------- -| Multiplies the 128-bit unsigned integer formed by concatenating `a64' and -| `a0' by the 128-bit unsigned integer formed by concatenating `b64' and -| `b0'. The 256-bit product is stored at the location pointed to by `zPtr'. -| Argument `zPtr' points to an array of four 64-bit elements that concatenate +| Multiplies the 128-bit unsigned integer formed by concatenating 'a64' and +| 'a0' by the 128-bit unsigned integer formed by concatenating 'b64' and +| 'b0'. The 256-bit product is stored at the location pointed to by 'zPtr'. +| Argument 'zPtr' points to an array of four 64-bit elements that concatenate | in the platform's normal endian order to form a 256-bit integer. *----------------------------------------------------------------------------*/ void @@ -592,17 +617,17 @@ void #else /*---------------------------------------------------------------------------- -| The following functions are needed only when `SOFTFLOAT_FAST_INT64' is not +| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is not | defined. *----------------------------------------------------------------------------*/ #ifndef softfloat_compare96M /*---------------------------------------------------------------------------- -| Compares the two 96-bit unsigned integers pointed to by `aPtr' and `bPtr'. +| Compares the two 96-bit unsigned integers pointed to by 'aPtr' and 'bPtr'. | Returns -1 if the first integer (A) is less than the second (B); returns 0 | if the two integers are equal; and returns +1 if the first integer (A) | is greater than the second (B). (The result is thus the signum of A - B.) -| Each of `aPtr' and `bPtr' points to an array of three 32-bit elements that +| Each of 'aPtr' and 'bPtr' points to an array of three 32-bit elements that | concatenate in the platform's normal endian order to form a 96-bit integer. *----------------------------------------------------------------------------*/ int_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr ); @@ -610,11 +635,11 @@ int_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr ); #ifndef softfloat_compare128M /*---------------------------------------------------------------------------- -| Compares the two 128-bit unsigned integers pointed to by `aPtr' and `bPtr'. +| Compares the two 128-bit unsigned integers pointed to by 'aPtr' and 'bPtr'. | Returns -1 if the first integer (A) is less than the second (B); returns 0 | if the two integers are equal; and returns +1 if the first integer (A) | is greater than the second (B). (The result is thus the signum of A - B.) -| Each of `aPtr' and `bPtr' points to an array of four 32-bit elements that +| Each of 'aPtr' and 'bPtr' points to an array of four 32-bit elements that | concatenate in the platform's normal endian order to form a 128-bit integer. *----------------------------------------------------------------------------*/ int_fast8_t @@ -623,37 +648,37 @@ int_fast8_t #ifndef softfloat_shortShiftLeft64To96M /*---------------------------------------------------------------------------- -| Extends `a' to 96 bits and shifts the value left by the number of bits given -| in `count', which must be in the range 1 to 31. The result is stored at the -| location pointed to by `zPtr'. Argument `zPtr' points to an array of three +| Extends 'a' to 96 bits and shifts the value left by the number of bits given +| in 'dist', which must be in the range 1 to 31. The result is stored at the +| location pointed to by 'zPtr'. Argument 'zPtr' points to an array of three | 32-bit elements that concatenate in the platform's normal endian order to | form a 96-bit integer. *----------------------------------------------------------------------------*/ #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) INLINE - void - softfloat_shortShiftLeft64To96M( - uint64_t a, uint_fast8_t count, uint32_t *zPtr ) +void + softfloat_shortShiftLeft64To96M( + uint64_t a, uint_fast8_t dist, uint32_t *zPtr ) { - zPtr[indexWord( 3, 0 )] = (uint32_t) a<<count; - a >>= 32 - count; + zPtr[indexWord( 3, 0 )] = (uint32_t) a<<dist; + a >>= 32 - dist; zPtr[indexWord( 3, 2 )] = a>>32; zPtr[indexWord( 3, 1 )] = a; } #else void softfloat_shortShiftLeft64To96M( - uint64_t a, uint_fast8_t count, uint32_t *zPtr ); + uint64_t a, uint_fast8_t dist, uint32_t *zPtr ); #endif #endif #ifndef softfloat_shortShiftLeftM /*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by `aPtr' left by the number -| of bits given in `count', where N = `size_words' * 32. The value of `count' +| Shifts the N-bit unsigned integer pointed to by 'aPtr' left by the number +| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' | must be in the range 1 to 31. Any nonzero bits shifted off are lost. The -| shifted N-bit result is stored at the location pointed to by `zPtr'. Each -| of `aPtr' and `zPtr' points to a `size_words'-long array of 32-bit elements +| shifted N-bit result is stored at the location pointed to by 'zPtr'. Each +| of 'aPtr' and 'zPtr' points to a 'size_words'-long array of 32-bit elements | that concatenate in the platform's normal endian order to form an N-bit | integer. *----------------------------------------------------------------------------*/ @@ -661,86 +686,86 @@ void softfloat_shortShiftLeftM( uint_fast8_t size_words, const uint32_t *aPtr, - uint_fast8_t count, + uint_fast8_t dist, uint32_t *zPtr ); #endif #ifndef softfloat_shortShiftLeft96M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shortShiftLeftM' with -| `size_words' = 3 (N = 96). +| This function or macro is the same as 'softfloat_shortShiftLeftM' with +| 'size_words' = 3 (N = 96). *----------------------------------------------------------------------------*/ -#define softfloat_shortShiftLeft96M( aPtr, count, zPtr ) softfloat_shortShiftLeftM( 3, aPtr, count, zPtr ) +#define softfloat_shortShiftLeft96M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 3, aPtr, dist, zPtr ) #endif #ifndef softfloat_shortShiftLeft128M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shortShiftLeftM' with -| `size_words' = 4 (N = 128). +| This function or macro is the same as 'softfloat_shortShiftLeftM' with +| 'size_words' = 4 (N = 128). *----------------------------------------------------------------------------*/ -#define softfloat_shortShiftLeft128M( aPtr, count, zPtr ) softfloat_shortShiftLeftM( 4, aPtr, count, zPtr ) +#define softfloat_shortShiftLeft128M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 4, aPtr, dist, zPtr ) #endif #ifndef softfloat_shortShiftLeft160M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shortShiftLeftM' with -| `size_words' = 5 (N = 160). +| This function or macro is the same as 'softfloat_shortShiftLeftM' with +| 'size_words' = 5 (N = 160). *----------------------------------------------------------------------------*/ -#define softfloat_shortShiftLeft160M( aPtr, count, zPtr ) softfloat_shortShiftLeftM( 5, aPtr, count, zPtr ) +#define softfloat_shortShiftLeft160M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 5, aPtr, dist, zPtr ) #endif #ifndef softfloat_shiftLeftM /*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by `aPtr' left by the number -| of bits given in `count', where N = `size_words' * 32. The value of `count' +| Shifts the N-bit unsigned integer pointed to by 'aPtr' left by the number +| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' | must not be zero. Any nonzero bits shifted off are lost. The shifted -| N-bit result is stored at the location pointed to by `zPtr'. Each of `aPtr' -| and `zPtr' points to a `size_words'-long array of 32-bit elements that +| N-bit result is stored at the location pointed to by 'zPtr'. Each of 'aPtr' +| and 'zPtr' points to a 'size_words'-long array of 32-bit elements that | concatenate in the platform's normal endian order to form an N-bit integer. -| The value of `count' can be arbitrarily large. In particular, if `count' -| is greater than N, the stored result will be 0. +| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is +| greater than N, the stored result will be 0. *----------------------------------------------------------------------------*/ void softfloat_shiftLeftM( uint_fast8_t size_words, const uint32_t *aPtr, - uint32_t count, + uint32_t dist, uint32_t *zPtr ); #endif #ifndef softfloat_shiftLeft96M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shiftLeftM' with -| `size_words' = 3 (N = 96). +| This function or macro is the same as 'softfloat_shiftLeftM' with +| 'size_words' = 3 (N = 96). *----------------------------------------------------------------------------*/ -#define softfloat_shiftLeft96M( aPtr, count, zPtr ) softfloat_shiftLeftM( 3, aPtr, count, zPtr ) +#define softfloat_shiftLeft96M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 3, aPtr, dist, zPtr ) #endif #ifndef softfloat_shiftLeft128M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shiftLeftM' with -| `size_words' = 4 (N = 128). +| This function or macro is the same as 'softfloat_shiftLeftM' with +| 'size_words' = 4 (N = 128). *----------------------------------------------------------------------------*/ -#define softfloat_shiftLeft128M( aPtr, count, zPtr ) softfloat_shiftLeftM( 4, aPtr, count, zPtr ) +#define softfloat_shiftLeft128M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 4, aPtr, dist, zPtr ) #endif #ifndef softfloat_shiftLeft160M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shiftLeftM' with -| `size_words' = 5 (N = 160). +| This function or macro is the same as 'softfloat_shiftLeftM' with +| 'size_words' = 5 (N = 160). *----------------------------------------------------------------------------*/ -#define softfloat_shiftLeft160M( aPtr, count, zPtr ) softfloat_shiftLeftM( 5, aPtr, count, zPtr ) +#define softfloat_shiftLeft160M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 5, aPtr, dist, zPtr ) #endif #ifndef softfloat_shortShiftRightM /*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by `aPtr' right by the number -| of bits given in `count', where N = `size_words' * 32. The value of `count' +| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number +| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' | must be in the range 1 to 31. Any nonzero bits shifted off are lost. The -| shifted N-bit result is stored at the location pointed to by `zPtr'. Each -| of `aPtr' and `zPtr' points to a `size_words'-long array of 32-bit elements +| shifted N-bit result is stored at the location pointed to by 'zPtr'. Each +| of 'aPtr' and 'zPtr' points to a 'size_words'-long array of 32-bit elements | that concatenate in the platform's normal endian order to form an N-bit | integer. *----------------------------------------------------------------------------*/ @@ -748,36 +773,36 @@ void softfloat_shortShiftRightM( uint_fast8_t size_words, const uint32_t *aPtr, - uint_fast8_t count, + uint_fast8_t dist, uint32_t *zPtr ); #endif #ifndef softfloat_shortShiftRight128M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shortShiftRightM' with -| `size_words' = 4 (N = 128). +| This function or macro is the same as 'softfloat_shortShiftRightM' with +| 'size_words' = 4 (N = 128). *----------------------------------------------------------------------------*/ -#define softfloat_shortShiftRight128M( aPtr, count, zPtr ) softfloat_shortShiftRightM( 4, aPtr, count, zPtr ) +#define softfloat_shortShiftRight128M( aPtr, dist, zPtr ) softfloat_shortShiftRightM( 4, aPtr, dist, zPtr ) #endif #ifndef softfloat_shortShiftRight160M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shortShiftRightM' with -| `size_words' = 5 (N = 160). +| This function or macro is the same as 'softfloat_shortShiftRightM' with +| 'size_words' = 5 (N = 160). *----------------------------------------------------------------------------*/ -#define softfloat_shortShiftRight160M( aPtr, count, zPtr ) softfloat_shortShiftRightM( 5, aPtr, count, zPtr ) +#define softfloat_shortShiftRight160M( aPtr, dist, zPtr ) softfloat_shortShiftRightM( 5, aPtr, dist, zPtr ) #endif #ifndef softfloat_shortShiftRightJamM /*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by `aPtr' right by the number -| of bits given in `count', where N = `size_words' * 32. The value of `count' +| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number +| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' | must be in the range 1 to 31. If any nonzero bits are shifted off, they are | "jammed" into the least-significant bit of the shifted value by setting the | least-significant bit to 1. This shifted-and-jammed N-bit result is stored -| at the location pointed to by `zPtr'. Each of `aPtr' and `zPtr' points -| to a `size_words'-long array of 32-bit elements that concatenate in the +| at the location pointed to by 'zPtr'. Each of 'aPtr' and 'zPtr' points +| to a 'size_words'-long array of 32-bit elements that concatenate in the | platform's normal endian order to form an N-bit integer. *----------------------------------------------------------------------------*/ void @@ -787,51 +812,51 @@ void #ifndef softfloat_shortShiftRightJam160M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shortShiftRightJamM' with -| `size_words' = 5 (N = 160). +| This function or macro is the same as 'softfloat_shortShiftRightJamM' with +| 'size_words' = 5 (N = 160). *----------------------------------------------------------------------------*/ -#define softfloat_shortShiftRightJam160M( aPtr, count, zPtr ) softfloat_shortShiftRightJamM( 5, aPtr, count, zPtr ) +#define softfloat_shortShiftRightJam160M( aPtr, dist, zPtr ) softfloat_shortShiftRightJamM( 5, aPtr, dist, zPtr ) #endif #ifndef softfloat_shiftRightM /*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by `aPtr' right by the number -| of bits given in `count', where N = `size_words' * 32. The value of `count' +| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number +| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' | must not be zero. Any nonzero bits shifted off are lost. The shifted -| N-bit result is stored at the location pointed to by `zPtr'. Each of `aPtr' -| and `zPtr' points to a `size_words'-long array of 32-bit elements that +| N-bit result is stored at the location pointed to by 'zPtr'. Each of 'aPtr' +| and 'zPtr' points to a 'size_words'-long array of 32-bit elements that | concatenate in the platform's normal endian order to form an N-bit integer. -| The value of `count' can be arbitrarily large. In particular, if `count' -| is greater than N, the stored result will be 0. +| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is +| greater than N, the stored result will be 0. *----------------------------------------------------------------------------*/ void softfloat_shiftRightM( uint_fast8_t size_words, const uint32_t *aPtr, - uint32_t count, + uint32_t dist, uint32_t *zPtr ); #endif #ifndef softfloat_shiftRight96M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shiftRightM' with -| `size_words' = 3 (N = 96). +| This function or macro is the same as 'softfloat_shiftRightM' with +| 'size_words' = 3 (N = 96). *----------------------------------------------------------------------------*/ -#define softfloat_shiftRight96M( aPtr, count, zPtr ) softfloat_shiftRightM( 3, aPtr, count, zPtr ) +#define softfloat_shiftRight96M( aPtr, dist, zPtr ) softfloat_shiftRightM( 3, aPtr, dist, zPtr ) #endif #ifndef softfloat_shiftRightJamM /*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by `aPtr' right by the number -| of bits given in `count', where N = `size_words' * 32. The value of `count' +| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number +| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' | must not be zero. If any nonzero bits are shifted off, they are "jammed" | into the least-significant bit of the shifted value by setting the least- | significant bit to 1. This shifted-and-jammed N-bit result is stored -| at the location pointed to by `zPtr'. Each of `aPtr' and `zPtr' points -| to a `size_words'-long array of 32-bit elements that concatenate in the +| at the location pointed to by 'zPtr'. Each of 'aPtr' and 'zPtr' points +| to a 'size_words'-long array of 32-bit elements that concatenate in the | platform's normal endian order to form an N-bit integer. -| The value of `count' can be arbitrarily large. In particular, if `count' +| The value of 'dist' can be arbitrarily large. In particular, if 'dist' | is greater than N, the stored result will be either 0 or 1, depending on | whether the original N bits are all zeros. *----------------------------------------------------------------------------*/ @@ -839,41 +864,41 @@ void softfloat_shiftRightJamM( uint_fast8_t size_words, const uint32_t *aPtr, - uint32_t count, + uint32_t dist, uint32_t *zPtr ); #endif #ifndef softfloat_shiftRightJam96M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shiftRightJamM' with -| `size_words' = 3 (N = 96). +| This function or macro is the same as 'softfloat_shiftRightJamM' with +| 'size_words' = 3 (N = 96). *----------------------------------------------------------------------------*/ -#define softfloat_shiftRightJam96M( aPtr, count, zPtr ) softfloat_shiftRightJamM( 3, aPtr, count, zPtr ) +#define softfloat_shiftRightJam96M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 3, aPtr, dist, zPtr ) #endif #ifndef softfloat_shiftRightJam128M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shiftRightJamM' with -| `size_words' = 4 (N = 128). +| This function or macro is the same as 'softfloat_shiftRightJamM' with +| 'size_words' = 4 (N = 128). *----------------------------------------------------------------------------*/ -#define softfloat_shiftRightJam128M( aPtr, count, zPtr ) softfloat_shiftRightJamM( 4, aPtr, count, zPtr ) +#define softfloat_shiftRightJam128M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 4, aPtr, dist, zPtr ) #endif #ifndef softfloat_shiftRightJam160M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_shiftRightJamM' with -| `size_words' = 5 (N = 160). +| This function or macro is the same as 'softfloat_shiftRightJamM' with +| 'size_words' = 5 (N = 160). *----------------------------------------------------------------------------*/ -#define softfloat_shiftRightJam160M( aPtr, count, zPtr ) softfloat_shiftRightJamM( 5, aPtr, count, zPtr ) +#define softfloat_shiftRightJam160M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 5, aPtr, dist, zPtr ) #endif #ifndef softfloat_addM /*---------------------------------------------------------------------------- -| Adds the two N-bit integers pointed to by `aPtr' and `bPtr', where N = -| `size_words' * 32. The addition is modulo 2^N, so any carry out is lost. -| The N-bit sum is stored at the location pointed to by `zPtr'. Each of -| `aPtr', `bPtr', and `zPtr' points to a `size_words'-long array of 32-bit +| Adds the two N-bit integers pointed to by 'aPtr' and 'bPtr', where N = +| 'size_words' * 32. The addition is modulo 2^N, so any carry out is lost. +| The N-bit sum is stored at the location pointed to by 'zPtr'. Each of +| 'aPtr', 'bPtr', and 'zPtr' points to a 'size_words'-long array of 32-bit | elements that concatenate in the platform's normal endian order to form an | N-bit integer. *----------------------------------------------------------------------------*/ @@ -888,7 +913,7 @@ void #ifndef softfloat_add96M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_addM' with `size_words' +| This function or macro is the same as 'softfloat_addM' with 'size_words' | = 3 (N = 96). *----------------------------------------------------------------------------*/ #define softfloat_add96M( aPtr, bPtr, zPtr ) softfloat_addM( 3, aPtr, bPtr, zPtr ) @@ -896,7 +921,7 @@ void #ifndef softfloat_add128M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_addM' with `size_words' +| This function or macro is the same as 'softfloat_addM' with 'size_words' | = 4 (N = 128). *----------------------------------------------------------------------------*/ #define softfloat_add128M( aPtr, bPtr, zPtr ) softfloat_addM( 4, aPtr, bPtr, zPtr ) @@ -904,7 +929,7 @@ void #ifndef softfloat_add160M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_addM' with `size_words' +| This function or macro is the same as 'softfloat_addM' with 'size_words' | = 5 (N = 160). *----------------------------------------------------------------------------*/ #define softfloat_add160M( aPtr, bPtr, zPtr ) softfloat_addM( 5, aPtr, bPtr, zPtr ) @@ -912,11 +937,11 @@ void #ifndef softfloat_addCarryM /*---------------------------------------------------------------------------- -| Adds the two N-bit unsigned integers pointed to by `aPtr' and `bPtr', where -| N = `size_words' * 32, plus `carry', which must be either 0 or 1. The N-bit -| sum (modulo 2^N) is stored at the location pointed to by `zPtr', and any -| carry out is returned as the result. Each of `aPtr', `bPtr', and `zPtr' -| points to a `size_words'-long array of 32-bit elements that concatenate in +| Adds the two N-bit unsigned integers pointed to by 'aPtr' and 'bPtr', where +| N = 'size_words' * 32, plus 'carry', which must be either 0 or 1. The N-bit +| sum (modulo 2^N) is stored at the location pointed to by 'zPtr', and any +| carry out is returned as the result. Each of 'aPtr', 'bPtr', and 'zPtr' +| points to a 'size_words'-long array of 32-bit elements that concatenate in | the platform's normal endian order to form an N-bit integer. *----------------------------------------------------------------------------*/ uint_fast8_t @@ -931,8 +956,8 @@ uint_fast8_t #ifndef softfloat_addComplCarryM /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_addCarryM', except that -| the value of the unsigned integer pointed to by `bPtr' is bit-wise completed +| This function or macro is the same as 'softfloat_addCarryM', except that +| the value of the unsigned integer pointed to by 'bPtr' is bit-wise completed | before the addition. *----------------------------------------------------------------------------*/ uint_fast8_t @@ -947,17 +972,17 @@ uint_fast8_t #ifndef softfloat_addComplCarry96M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_addComplCarryM' with -| `size_words' = 3 (N = 96). +| This function or macro is the same as 'softfloat_addComplCarryM' with +| 'size_words' = 3 (N = 96). *----------------------------------------------------------------------------*/ #define softfloat_addComplCarry96M( aPtr, bPtr, carry, zPtr ) softfloat_addComplCarryM( 3, aPtr, bPtr, carry, zPtr ) #endif #ifndef softfloat_negXM /*---------------------------------------------------------------------------- -| Replaces the N-bit unsigned integer pointed to by `zPtr' by the -| 2s-complement of itself, where N = `size_words' * 32. Argument `zPtr' -| points to a `size_words'-long array of 32-bit elements that concatenate in +| Replaces the N-bit unsigned integer pointed to by 'zPtr' by the +| 2s-complement of itself, where N = 'size_words' * 32. Argument 'zPtr' +| points to a 'size_words'-long array of 32-bit elements that concatenate in | the platform's normal endian order to form an N-bit integer. *----------------------------------------------------------------------------*/ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ); @@ -965,7 +990,7 @@ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ); #ifndef softfloat_negX96M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_negXM' with `size_words' +| This function or macro is the same as 'softfloat_negXM' with 'size_words' | = 3 (N = 96). *----------------------------------------------------------------------------*/ #define softfloat_negX96M( zPtr ) softfloat_negXM( 3, zPtr ) @@ -973,7 +998,7 @@ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ); #ifndef softfloat_negX128M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_negXM' with `size_words' +| This function or macro is the same as 'softfloat_negXM' with 'size_words' | = 4 (N = 128). *----------------------------------------------------------------------------*/ #define softfloat_negX128M( zPtr ) softfloat_negXM( 4, zPtr ) @@ -981,7 +1006,7 @@ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ); #ifndef softfloat_negX160M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_negXM' with `size_words' +| This function or macro is the same as 'softfloat_negXM' with 'size_words' | = 5 (N = 160). *----------------------------------------------------------------------------*/ #define softfloat_negX160M( zPtr ) softfloat_negXM( 5, zPtr ) @@ -989,7 +1014,7 @@ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ); #ifndef softfloat_negX256M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_negXM' with `size_words' +| This function or macro is the same as 'softfloat_negXM' with 'size_words' | = 8 (N = 256). *----------------------------------------------------------------------------*/ #define softfloat_negX256M( zPtr ) softfloat_negXM( 8, zPtr ) @@ -997,9 +1022,9 @@ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ); #ifndef softfloat_sub1XM /*---------------------------------------------------------------------------- -| Subtracts 1 from the N-bit integer pointed to by `zPtr', where N = -| `size_words' * 32. The subtraction is modulo 2^N, so any borrow out (carry -| out) is lost. Argument `zPtr' points to a `size_words'-long array of 32-bit +| Subtracts 1 from the N-bit integer pointed to by 'zPtr', where N = +| 'size_words' * 32. The subtraction is modulo 2^N, so any borrow out (carry +| out) is lost. Argument 'zPtr' points to a 'size_words'-long array of 32-bit | elements that concatenate in the platform's normal endian order to form an | N-bit integer. *----------------------------------------------------------------------------*/ @@ -1008,7 +1033,7 @@ void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr ); #ifndef softfloat_sub1X96M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_sub1XM' with `size_words' +| This function or macro is the same as 'softfloat_sub1XM' with 'size_words' | = 3 (N = 96). *----------------------------------------------------------------------------*/ #define softfloat_sub1X96M( zPtr ) softfloat_sub1XM( 3, zPtr ) @@ -1016,7 +1041,7 @@ void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr ); #ifndef softfloat_sub1X160M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_sub1XM' with `size_words' +| This function or macro is the same as 'softfloat_sub1XM' with 'size_words' | = 5 (N = 160). *----------------------------------------------------------------------------*/ #define softfloat_sub1X160M( zPtr ) softfloat_sub1XM( 5, zPtr ) @@ -1024,10 +1049,10 @@ void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr ); #ifndef softfloat_subM /*---------------------------------------------------------------------------- -| Subtracts the two N-bit integers pointed to by `aPtr' and `bPtr', where N = -| `size_words' * 32. The subtraction is modulo 2^N, so any borrow out (carry +| Subtracts the two N-bit integers pointed to by 'aPtr' and 'bPtr', where N = +| 'size_words' * 32. The subtraction is modulo 2^N, so any borrow out (carry | out) is lost. The N-bit difference is stored at the location pointed to by -| `zPtr'. Each of `aPtr', `bPtr', and `zPtr' points to a `size_words'-long +| 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to a 'size_words'-long | array of 32-bit elements that concatenate in the platform's normal endian | order to form an N-bit integer. *----------------------------------------------------------------------------*/ @@ -1042,7 +1067,7 @@ void #ifndef softfloat_sub96M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_subM' with `size_words' +| This function or macro is the same as 'softfloat_subM' with 'size_words' | = 3 (N = 96). *----------------------------------------------------------------------------*/ #define softfloat_sub96M( aPtr, bPtr, zPtr ) softfloat_subM( 3, aPtr, bPtr, zPtr ) @@ -1050,7 +1075,7 @@ void #ifndef softfloat_sub128M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_subM' with `size_words' +| This function or macro is the same as 'softfloat_subM' with 'size_words' | = 4 (N = 128). *----------------------------------------------------------------------------*/ #define softfloat_sub128M( aPtr, bPtr, zPtr ) softfloat_subM( 4, aPtr, bPtr, zPtr ) @@ -1058,7 +1083,7 @@ void #ifndef softfloat_sub160M /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_subM' with `size_words' +| This function or macro is the same as 'softfloat_subM' with 'size_words' | = 5 (N = 160). *----------------------------------------------------------------------------*/ #define softfloat_sub160M( aPtr, bPtr, zPtr ) softfloat_subM( 5, aPtr, bPtr, zPtr ) @@ -1066,8 +1091,8 @@ void #ifndef softfloat_mul64To128M /*---------------------------------------------------------------------------- -| Multiplies `a' and `b' and stores the 128-bit product at the location -| pointed to by `zPtr'. Argument `zPtr' points to an array of four 32-bit +| Multiplies 'a' and 'b' and stores the 128-bit product at the location +| pointed to by 'zPtr'. Argument 'zPtr' points to an array of four 32-bit | elements that concatenate in the platform's normal endian order to form a | 128-bit integer. *----------------------------------------------------------------------------*/ @@ -1076,11 +1101,11 @@ void softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr ); #ifndef softfloat_mul128MTo256M /*---------------------------------------------------------------------------- -| Multiplies the two 128-bit unsigned integers pointed to by `aPtr' and -| `bPtr', and stores the 256-bit product at the location pointed to by `zPtr'. -| Each of `aPtr' and `bPtr' points to an array of four 32-bit elements that +| Multiplies the two 128-bit unsigned integers pointed to by 'aPtr' and +| 'bPtr', and stores the 256-bit product at the location pointed to by 'zPtr'. +| Each of 'aPtr' and 'bPtr' points to an array of four 32-bit elements that | concatenate in the platform's normal endian order to form a 128-bit integer. -| Argument `zPtr' points to an array of eight 32-bit elements that concatenate +| Argument 'zPtr' points to an array of eight 32-bit elements that concatenate | to form a 256-bit integer. *----------------------------------------------------------------------------*/ void @@ -1090,19 +1115,19 @@ void #ifndef softfloat_remStepMBy32 /*---------------------------------------------------------------------------- -| Performs a "remainder reduction step" as follows: Arguments `remPtr' and -| `bPtr' both point to N-bit unsigned integers, where N = `size_words' * 32. -| Defining R and B as the values of those integers, the expression (R<<`count') +| Performs a "remainder reduction step" as follows: Arguments 'remPtr' and +| 'bPtr' both point to N-bit unsigned integers, where N = 'size_words' * 32. +| Defining R and B as the values of those integers, the expression (R<<'dist') | - B * q is computed modulo 2^N, and the N-bit result is stored at the -| location pointed to by `zPtr'. Each of `remPtr', `bPtr', and `zPtr' points -| to a `size_words'-long array of 32-bit elements that concatenate in the +| location pointed to by 'zPtr'. Each of 'remPtr', 'bPtr', and 'zPtr' points +| to a 'size_words'-long array of 32-bit elements that concatenate in the | platform's normal endian order to form an N-bit integer. *----------------------------------------------------------------------------*/ void softfloat_remStepMBy32( uint_fast8_t size_words, const uint32_t *remPtr, - uint_fast8_t count, + uint_fast8_t dist, const uint32_t *bPtr, uint32_t q, uint32_t *zPtr @@ -1111,26 +1136,26 @@ void #ifndef softfloat_remStep96MBy32 /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_remStepMBy32' with -| `size_words' = 3 (N = 96). +| This function or macro is the same as 'softfloat_remStepMBy32' with +| 'size_words' = 3 (N = 96). *----------------------------------------------------------------------------*/ -#define softfloat_remStep96MBy32( remPtr, count, bPtr, q, zPtr ) softfloat_remStepMBy32( 3, remPtr, count, bPtr, q, zPtr ) +#define softfloat_remStep96MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 3, remPtr, dist, bPtr, q, zPtr ) #endif #ifndef softfloat_remStep128MBy32 /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_remStepMBy32' with -| `size_words' = 4 (N = 128). +| This function or macro is the same as 'softfloat_remStepMBy32' with +| 'size_words' = 4 (N = 128). *----------------------------------------------------------------------------*/ -#define softfloat_remStep128MBy32( remPtr, count, bPtr, q, zPtr ) softfloat_remStepMBy32( 4, remPtr, count, bPtr, q, zPtr ) +#define softfloat_remStep128MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 4, remPtr, dist, bPtr, q, zPtr ) #endif #ifndef softfloat_remStep160MBy32 /*---------------------------------------------------------------------------- -| This function or macro is the same as `softfloat_remStepMBy32' with -| `size_words' = 5 (N = 160). +| This function or macro is the same as 'softfloat_remStepMBy32' with +| 'size_words' = 5 (N = 160). *----------------------------------------------------------------------------*/ -#define softfloat_remStep160MBy32( remPtr, count, bPtr, q, zPtr ) softfloat_remStepMBy32( 5, remPtr, count, bPtr, q, zPtr ) +#define softfloat_remStep160MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 5, remPtr, dist, bPtr, q, zPtr ) #endif #endif diff --git a/softfloat/s_add128.c b/softfloat/s_add128.c index cabbb73..8065656 100644 --- a/softfloat/s_add128.c +++ b/softfloat/s_add128.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. diff --git a/softfloat/s_add256M.c b/softfloat/s_add256M.c new file mode 100644 index 0000000..d07b004 --- /dev/null +++ b/softfloat/s_add256M.c @@ -0,0 +1,65 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_add256M + +void + softfloat_add256M( + const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr ) +{ + unsigned int index; + uint_fast8_t carry; + uint64_t wordA, wordZ; + + index = indexWordLo( 4 ); + carry = 0; + for (;;) { + wordA = aPtr[index]; + wordZ = wordA + bPtr[index] + carry; + zPtr[index] = wordZ; + if ( index == indexWordHi( 4 ) ) break; + if ( wordZ != wordA ) carry = (wordZ < wordA); + index += wordIncr; + } + +} + +#endif + diff --git a/softfloat/s_addCarryM.c b/softfloat/s_addCarryM.c index 0f3c997..fae1db4 100644 --- a/softfloat/s_addCarryM.c +++ b/softfloat/s_addCarryM.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -58,7 +58,7 @@ uint_fast8_t wordA = aPtr[index]; wordZ = wordA + bPtr[index] + carry; zPtr[index] = wordZ; - carry = carry ? (wordZ <= wordA) : (wordZ < wordA); + if ( wordZ != wordA ) carry = (wordZ < wordA); if ( index == lastIndex ) break; index += wordIncr; } diff --git a/softfloat/s_addComplCarryM.c b/softfloat/s_addComplCarryM.c index 6f22273..02f2bce 100644 --- a/softfloat/s_addComplCarryM.c +++ b/softfloat/s_addComplCarryM.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -58,7 +58,7 @@ uint_fast8_t wordA = aPtr[index]; wordZ = wordA + ~bPtr[index] + carry; zPtr[index] = wordZ; - carry = carry ? (wordZ <= wordA) : (wordZ < wordA); + if ( wordZ != wordA ) carry = (wordZ < wordA); if ( index == lastIndex ) break; index += wordIncr; } diff --git a/softfloat/s_addM.c b/softfloat/s_addM.c index f01be48..a06eda6 100644 --- a/softfloat/s_addM.c +++ b/softfloat/s_addM.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -60,7 +60,7 @@ void wordZ = wordA + bPtr[index] + carry; zPtr[index] = wordZ; if ( index == lastIndex ) break; - carry = carry ? (wordZ <= wordA) : (wordZ < wordA); + if ( wordZ != wordA ) carry = (wordZ < wordA); index += wordIncr; } diff --git a/softfloat/s_addMagsF128.c b/softfloat/s_addMagsF128.c new file mode 100644 index 0000000..292f0aa --- /dev/null +++ b/softfloat/s_addMagsF128.c @@ -0,0 +1,154 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" + +float128_t + softfloat_addMagsF128( + uint_fast64_t uiA64, + uint_fast64_t uiA0, + uint_fast64_t uiB64, + uint_fast64_t uiB0, + bool signZ + ) +{ + int_fast32_t expA; + struct uint128 sigA; + int_fast32_t expB; + struct uint128 sigB; + int_fast32_t expDiff; + struct uint128 uiZ, sigZ; + int_fast32_t expZ; + uint_fast64_t sigZExtra; + struct uint128_extra sig128Extra; + union ui128_f128 uZ; + + expA = expF128UI64( uiA64 ); + sigA.v64 = fracF128UI64( uiA64 ); + sigA.v0 = uiA0; + expB = expF128UI64( uiB64 ); + sigB.v64 = fracF128UI64( uiB64 ); + sigB.v0 = uiB0; + expDiff = expA - expB; + if ( ! expDiff ) { + if ( expA == 0x7FFF ) { + if ( sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0 ) goto propagateNaN; + uiZ.v64 = uiA64; + uiZ.v0 = uiA0; + goto uiZ; + } + sigZ = softfloat_add128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 ); + if ( ! expA ) { + uiZ.v64 = packToF128UI64( signZ, 0, sigZ.v64 ); + uiZ.v0 = sigZ.v0; + goto uiZ; + } + expZ = expA; + sigZ.v64 |= UINT64_C( 0x0002000000000000 ); + sigZExtra = 0; + goto shiftRight1; + } + if ( expDiff < 0 ) { + if ( expB == 0x7FFF ) { + if ( sigB.v64 | sigB.v0 ) goto propagateNaN; + uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 ); + uiZ.v0 = 0; + goto uiZ; + } + expZ = expB; + if ( expA ) { + sigA.v64 |= UINT64_C( 0x0001000000000000 ); + } else { + ++expDiff; + sigZExtra = 0; + if ( ! expDiff ) goto newlyAligned; + } + sig128Extra = + softfloat_shiftRightJam128Extra( sigA.v64, sigA.v0, 0, -expDiff ); + sigA = sig128Extra.v; + sigZExtra = sig128Extra.extra; + } else { + if ( expA == 0x7FFF ) { + if ( sigA.v64 | sigA.v0 ) goto propagateNaN; + uiZ.v64 = uiA64; + uiZ.v0 = uiA0; + goto uiZ; + } + expZ = expA; + if ( expB ) { + sigB.v64 |= UINT64_C( 0x0001000000000000 ); + } else { + --expDiff; + sigZExtra = 0; + if ( ! expDiff ) goto newlyAligned; + } + sig128Extra = + softfloat_shiftRightJam128Extra( sigB.v64, sigB.v0, 0, expDiff ); + sigB = sig128Extra.v; + sigZExtra = sig128Extra.extra; + } + newlyAligned: + sigZ = + softfloat_add128( + sigA.v64 | UINT64_C( 0x0001000000000000 ), + sigA.v0, + sigB.v64, + sigB.v0 + ); + --expZ; + if ( sigZ.v64 < UINT64_C( 0x0002000000000000 ) ) goto roundAndPack; + ++expZ; + shiftRight1: + sig128Extra = + softfloat_shortShiftRightJam128Extra( + sigZ.v64, sigZ.v0, sigZExtra, 1 ); + sigZ = sig128Extra.v; + sigZExtra = sig128Extra.extra; + roundAndPack: + return + softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra ); + propagateNaN: + uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/s_addMagsF16.c b/softfloat/s_addMagsF16.c new file mode 100644 index 0000000..4204c1e --- /dev/null +++ b/softfloat/s_addMagsF16.c @@ -0,0 +1,183 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16_t softfloat_addMagsF16( uint_fast16_t uiA, uint_fast16_t uiB ) +{ + int_fast8_t expA; + uint_fast16_t sigA; + int_fast8_t expB; + uint_fast16_t sigB; + int_fast8_t expDiff; + uint_fast16_t uiZ; + bool signZ; + int_fast8_t expZ; + uint_fast16_t sigZ; + uint_fast16_t sigX, sigY; + int_fast8_t shiftDist; + uint_fast32_t sig32Z; + int_fast8_t roundingMode; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expA = expF16UI( uiA ); + sigA = fracF16UI( uiA ); + expB = expF16UI( uiB ); + sigB = fracF16UI( uiB ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if ( ! expDiff ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( ! expA ) { + uiZ = uiA + sigB; + goto uiZ; + } + if ( expA == 0x1F ) { + if ( sigA | sigB ) goto propagateNaN; + uiZ = uiA; + goto uiZ; + } + signZ = signF16UI( uiA ); + expZ = expA; + sigZ = 0x0800 + sigA + sigB; + if ( ! (sigZ & 1) && (expZ < 0x1E) ) { + sigZ >>= 1; + goto pack; + } + sigZ <<= 3; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + signZ = signF16UI( uiA ); + if ( expDiff < 0 ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + if ( expB == 0x1F ) { + if ( sigB ) goto propagateNaN; + uiZ = packToF16UI( signZ, 0x1F, 0 ); + goto uiZ; + } + if ( expDiff <= -13 ) { + uiZ = packToF16UI( signZ, expB, sigB ); + if ( expA | sigA ) goto addEpsilon; + goto uiZ; + } + expZ = expB; + sigX = sigB | 0x0400; + sigY = sigA + (expA ? 0x0400 : sigA); + shiftDist = 19 + expDiff; + } else { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + uiZ = uiA; + if ( expA == 0x1F ) { + if ( sigA ) goto propagateNaN; + goto uiZ; + } + if ( 13 <= expDiff ) { + if ( expB | sigB ) goto addEpsilon; + goto uiZ; + } + expZ = expA; + sigX = sigA | 0x0400; + sigY = sigB + (expB ? 0x0400 : sigB); + shiftDist = 19 - expDiff; + } + sig32Z = + ((uint_fast32_t) sigX<<19) + ((uint_fast32_t) sigY<<shiftDist); + if ( sig32Z < 0x40000000 ) { + --expZ; + sig32Z <<= 1; + } + sigZ = sig32Z>>16; + if ( sig32Z & 0xFFFF ) { + sigZ |= 1; + } else { + if ( ! (sigZ & 0xF) && (expZ < 0x1E) ) { + sigZ >>= 4; + goto pack; + } + } + } + return softfloat_roundPackToF16( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + addEpsilon: + roundingMode = softfloat_roundingMode; + if ( roundingMode != softfloat_round_near_even ) { + if ( + roundingMode + == (signF16UI( uiZ ) ? softfloat_round_min + : softfloat_round_max) + ) { + ++uiZ; + if ( (uint16_t) (uiZ<<1) == 0xF800 ) { + softfloat_raiseFlags( + softfloat_flag_overflow | softfloat_flag_inexact ); + } + } +#ifdef SOFTFLOAT_ROUND_ODD + else if ( roundingMode == softfloat_round_odd ) { + uiZ |= 1; + } +#endif + } + softfloat_exceptionFlags |= softfloat_flag_inexact; + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + pack: + uiZ = packToF16UI( signZ, expZ, sigZ ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/s_addMagsF32.c b/softfloat/s_addMagsF32.c index c1b6b2d..ba64781 100644 --- a/softfloat/s_addMagsF32.c +++ b/softfloat/s_addMagsF32.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: @@ -40,8 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "internals.h" #include "specialize.h" -float32_t - softfloat_addMagsF32( uint_fast32_t uiA, uint_fast32_t uiB, bool signZ ) +float32_t softfloat_addMagsF32( uint_fast32_t uiA, uint_fast32_t uiB ) { int_fast16_t expA; uint_fast32_t sigA; @@ -49,30 +48,46 @@ float32_t uint_fast32_t sigB; int_fast16_t expDiff; uint_fast32_t uiZ; + bool signZ; int_fast16_t expZ; uint_fast32_t sigZ; union ui32_f32 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ expA = expF32UI( uiA ); sigA = fracF32UI( uiA ); expB = expF32UI( uiB ); sigB = fracF32UI( uiB ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ expDiff = expA - expB; - sigA <<= 6; - sigB <<= 6; if ( ! expDiff ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( ! expA ) { + uiZ = uiA + sigB; + goto uiZ; + } if ( expA == 0xFF ) { if ( sigA | sigB ) goto propagateNaN; uiZ = uiA; goto uiZ; } - if ( ! expA ) { - uiZ = packToF32UI( signZ, 0, (uiA + uiB) & 0x7FFFFFFF ); + signZ = signF32UI( uiA ); + expZ = expA; + sigZ = 0x01000000 + sigA + sigB; + if ( ! (sigZ & 1) && (expZ < 0xFE) ) { + uiZ = packToF32UI( signZ, expZ, sigZ>>1 ); goto uiZ; } - expZ = expA; - sigZ = 0x40000000 + sigA + sigB; + sigZ <<= 6; } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + signZ = signF32UI( uiA ); + sigA <<= 6; + sigB <<= 6; if ( expDiff < 0 ) { if ( expB == 0xFF ) { if ( sigB ) goto propagateNaN; @@ -99,6 +114,8 @@ float32_t } } return softfloat_roundPackToF32( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); uiZ: diff --git a/softfloat/s_addMagsF64.c b/softfloat/s_addMagsF64.c index ba67e7c..63e1afe 100644 --- a/softfloat/s_addMagsF64.c +++ b/softfloat/s_addMagsF64.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: @@ -53,28 +53,35 @@ float64_t uint_fast64_t sigZ; union ui64_f64 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ expA = expF64UI( uiA ); sigA = fracF64UI( uiA ); expB = expF64UI( uiB ); sigB = fracF64UI( uiB ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ expDiff = expA - expB; - sigA <<= 9; - sigB <<= 9; if ( ! expDiff ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( ! expA ) { + uiZ = uiA + sigB; + goto uiZ; + } if ( expA == 0x7FF ) { if ( sigA | sigB ) goto propagateNaN; uiZ = uiA; goto uiZ; } - if ( ! expA ) { - uiZ = - packToF64UI( - signZ, 0, (uiA + uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ); - goto uiZ; - } expZ = expA; - sigZ = UINT64_C( 0x4000000000000000 ) + sigA + sigB; + sigZ = UINT64_C( 0x0020000000000000 ) + sigA + sigB; + sigZ <<= 9; } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sigA <<= 9; + sigB <<= 9; if ( expDiff < 0 ) { if ( expB == 0x7FF ) { if ( sigB ) goto propagateNaN; @@ -82,7 +89,11 @@ float64_t goto uiZ; } expZ = expB; - sigA += expA ? UINT64_C( 0x2000000000000000 ) : sigA; + if ( expA ) { + sigA += UINT64_C( 0x2000000000000000 ); + } else { + sigA <<= 1; + } sigA = softfloat_shiftRightJam64( sigA, -expDiff ); } else { if ( expA == 0x7FF ) { @@ -91,7 +102,11 @@ float64_t goto uiZ; } expZ = expA; - sigB += expB ? UINT64_C( 0x2000000000000000 ) : sigB; + if ( expB ) { + sigB += UINT64_C( 0x2000000000000000 ); + } else { + sigB <<= 1; + } sigB = softfloat_shiftRightJam64( sigB, expDiff ); } sigZ = UINT64_C( 0x2000000000000000 ) + sigA + sigB; @@ -101,6 +116,8 @@ float64_t } } return softfloat_roundPackToF64( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); uiZ: diff --git a/softfloat/s_approxRecip32_1.c b/softfloat/s_approxRecip32_1.c index 14ddd95..a06192e 100644 --- a/softfloat/s_approxRecip32_1.c +++ b/softfloat/s_approxRecip32_1.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -39,30 +39,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef softfloat_approxRecip32_1 +extern const uint16_t softfloat_approxRecip_1k0s[16]; +extern const uint16_t softfloat_approxRecip_1k1s[16]; + uint32_t softfloat_approxRecip32_1( uint32_t a ) { int index; - uint16_t eps; - static const uint16_t k0s[] = { - 0xFFC4, 0xF0BE, 0xE363, 0xD76F, 0xCCAD, 0xC2F0, 0xBA16, 0xB201, - 0xAA97, 0xA3C6, 0x9D7A, 0x97A6, 0x923C, 0x8D32, 0x887E, 0x8417 - }; - static const uint16_t k1s[] = { - 0xF0F1, 0xD62C, 0xBFA1, 0xAC77, 0x9C0A, 0x8DDB, 0x8185, 0x76BA, - 0x6D3B, 0x64D4, 0x5D5C, 0x56B1, 0x50B6, 0x4B55, 0x4679, 0x4211 - }; - uint16_t r0; - uint32_t delta0; + uint16_t eps, r0; + uint32_t sigma0; uint_fast32_t r; - uint32_t sqrDelta0; + uint32_t sqrSigma0; index = a>>27 & 0xF; eps = (uint16_t) (a>>11); - r0 = k0s[index] - ((k1s[index] * (uint_fast32_t) eps)>>20); - delta0 = ~(uint_fast32_t) ((r0 * (uint_fast64_t) a)>>7); - r = ((uint_fast32_t) r0<<16) + ((r0 * (uint_fast64_t) delta0)>>24); - sqrDelta0 = ((uint_fast64_t) delta0 * delta0)>>32; - r += ((uint32_t) r * (uint_fast64_t) sqrDelta0)>>48; + r0 = softfloat_approxRecip_1k0s[index] + - ((softfloat_approxRecip_1k1s[index] * (uint_fast32_t) eps)>>20); + sigma0 = ~(uint_fast32_t) ((r0 * (uint_fast64_t) a)>>7); + r = ((uint_fast32_t) r0<<16) + ((r0 * (uint_fast64_t) sigma0)>>24); + sqrSigma0 = ((uint_fast64_t) sigma0 * sigma0)>>32; + r += ((uint32_t) r * (uint_fast64_t) sqrSigma0)>>48; return r; } diff --git a/softfloat/s_approxRecipSqrt32_1.c b/softfloat/s_approxRecipSqrt32_1.c index a318673..2ab71a2 100644 --- a/softfloat/s_approxRecipSqrt32_1.c +++ b/softfloat/s_approxRecipSqrt32_1.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -39,34 +39,30 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef softfloat_approxRecipSqrt32_1 +extern const uint16_t softfloat_approxRecipSqrt_1k0s[]; +extern const uint16_t softfloat_approxRecipSqrt_1k1s[]; + uint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a ) { int index; - uint16_t eps; - static const uint16_t k0s[] = { - 0xB4C9, 0xFFAB, 0xAA7D, 0xF11C, 0xA1C5, 0xE4C7, 0x9A43, 0xDA29, - 0x93B5, 0xD0E5, 0x8DED, 0xC8B7, 0x88C6, 0xC16D, 0x8424, 0xBAE1 - }; - static const uint16_t k1s[] = { - 0xA5A5, 0xEA42, 0x8C21, 0xC62D, 0x788F, 0xAA7F, 0x6928, 0x94B6, - 0x5CC7, 0x8335, 0x52A6, 0x74E2, 0x4A3E, 0x68FE, 0x432B, 0x5EFD - }; - uint16_t r0; + uint16_t eps, r0; uint_fast32_t ESqrR0; - uint32_t delta0; + uint32_t sigma0; uint_fast32_t r; - uint32_t sqrDelta0; + uint32_t sqrSigma0; index = (a>>27 & 0xE) + oddExpA; eps = (uint16_t) (a>>12); - r0 = k0s[index] - ((k1s[index] * (uint_fast32_t) eps)>>20); + r0 = softfloat_approxRecipSqrt_1k0s[index] + - ((softfloat_approxRecipSqrt_1k1s[index] * (uint_fast32_t) eps) + >>20); ESqrR0 = (uint_fast32_t) r0 * r0; if ( ! oddExpA ) ESqrR0 <<= 1; - delta0 = ~(uint_fast32_t) (((uint32_t) ESqrR0 * (uint_fast64_t) a)>>23); - r = ((uint_fast32_t) r0<<16) + ((r0 * (uint_fast64_t) delta0)>>25); - sqrDelta0 = ((uint_fast64_t) delta0 * delta0)>>32; + sigma0 = ~(uint_fast32_t) (((uint32_t) ESqrR0 * (uint_fast64_t) a)>>23); + r = ((uint_fast32_t) r0<<16) + ((r0 * (uint_fast64_t) sigma0)>>25); + sqrSigma0 = ((uint_fast64_t) sigma0 * sigma0)>>32; r += ((uint32_t) ((r>>1) + (r>>3) - ((uint_fast32_t) r0<<14)) - * (uint_fast64_t) sqrDelta0) + * (uint_fast64_t) sqrSigma0) >>48; if ( ! (r & 0x80000000) ) r = 0x80000000; return r; diff --git a/softfloat/s_approxRecipSqrt_1Ks.c b/softfloat/s_approxRecipSqrt_1Ks.c new file mode 100644 index 0000000..a60cf82 --- /dev/null +++ b/softfloat/s_approxRecipSqrt_1Ks.c @@ -0,0 +1,49 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitives.h" + +const uint16_t softfloat_approxRecipSqrt_1k0s[16] = { + 0xB4C9, 0xFFAB, 0xAA7D, 0xF11C, 0xA1C5, 0xE4C7, 0x9A43, 0xDA29, + 0x93B5, 0xD0E5, 0x8DED, 0xC8B7, 0x88C6, 0xC16D, 0x8424, 0xBAE1 +}; +const uint16_t softfloat_approxRecipSqrt_1k1s[16] = { + 0xA5A5, 0xEA42, 0x8C21, 0xC62D, 0x788F, 0xAA7F, 0x6928, 0x94B6, + 0x5CC7, 0x8335, 0x52A6, 0x74E2, 0x4A3E, 0x68FE, 0x432B, 0x5EFD +}; + diff --git a/softfloat/s_approxRecip_1Ks.c b/softfloat/s_approxRecip_1Ks.c new file mode 100644 index 0000000..1108fcb --- /dev/null +++ b/softfloat/s_approxRecip_1Ks.c @@ -0,0 +1,49 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitives.h" + +const uint16_t softfloat_approxRecip_1k0s[16] = { + 0xFFC4, 0xF0BE, 0xE363, 0xD76F, 0xCCAD, 0xC2F0, 0xBA16, 0xB201, + 0xAA97, 0xA3C6, 0x9D7A, 0x97A6, 0x923C, 0x8D32, 0x887E, 0x8417 +}; +const uint16_t softfloat_approxRecip_1k1s[16] = { + 0xF0F1, 0xD62C, 0xBFA1, 0xAC77, 0x9C0A, 0x8DDB, 0x8185, 0x76BA, + 0x6D3B, 0x64D4, 0x5D5C, 0x56B1, 0x50B6, 0x4B55, 0x4679, 0x4211 +}; + diff --git a/softfloat/s_commonNaNToF128UI.c b/softfloat/s_commonNaNToF128UI.c new file mode 100644 index 0000000..9b97f34 --- /dev/null +++ b/softfloat/s_commonNaNToF128UI.c @@ -0,0 +1,56 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include "platform.h" +#include "primitiveTypes.h" + +#define softfloat_commonNaNToF128UI softfloat_commonNaNToF128UI +#include "specialize.h" + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) +{ + struct uint128 uiZ; + + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + return uiZ; + +} + diff --git a/softfloat/s_commonNaNToF16UI.c b/softfloat/s_commonNaNToF16UI.c new file mode 100644 index 0000000..861b269 --- /dev/null +++ b/softfloat/s_commonNaNToF16UI.c @@ -0,0 +1,5 @@ + +/*---------------------------------------------------------------------------- +| This file intentionally contains no code. +*----------------------------------------------------------------------------*/ + diff --git a/softfloat/s_commonNaNToF32UI.c b/softfloat/s_commonNaNToF32UI.c index 8b13789..861b269 100644 --- a/softfloat/s_commonNaNToF32UI.c +++ b/softfloat/s_commonNaNToF32UI.c @@ -1 +1,5 @@ +/*---------------------------------------------------------------------------- +| This file intentionally contains no code. +*----------------------------------------------------------------------------*/ + diff --git a/softfloat/s_commonNaNToF64UI.c b/softfloat/s_commonNaNToF64UI.c index 8b13789..861b269 100644 --- a/softfloat/s_commonNaNToF64UI.c +++ b/softfloat/s_commonNaNToF64UI.c @@ -1 +1,5 @@ +/*---------------------------------------------------------------------------- +| This file intentionally contains no code. +*----------------------------------------------------------------------------*/ + diff --git a/softfloat/s_shortShiftLeftM.c b/softfloat/s_compare128M.c index acb3e29..c2819e2 100644 --- a/softfloat/s_shortShiftLeftM.c +++ b/softfloat/s_compare128M.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. @@ -38,31 +38,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.h" #include "primitiveTypes.h" -#ifndef softfloat_shortShiftLeftM +#ifndef softfloat_compare128M -void - softfloat_shortShiftLeftM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint_fast8_t count, - uint32_t *zPtr - ) +int_fast8_t softfloat_compare128M( const uint32_t *aPtr, const uint32_t *bPtr ) { - uint_fast8_t negCount; unsigned int index, lastIndex; - uint32_t partWordZ, wordA; - - negCount = -count; - index = indexWordHi( size_words ); - lastIndex = indexWordLo( size_words ); - partWordZ = aPtr[index]<<count; - while ( index != lastIndex ) { - wordA = aPtr[index - wordIncr]; - zPtr[index] = partWordZ | wordA>>(negCount & 31); + uint32_t wordA, wordB; + + index = indexWordHi( 4 ); + lastIndex = indexWordLo( 4 ); + for (;;) { + wordA = aPtr[index]; + wordB = bPtr[index]; + if ( wordA != wordB ) return (wordA < wordB) ? -1 : 1; + if ( index == lastIndex ) break; index -= wordIncr; - partWordZ = wordA<<count; } - zPtr[index] = partWordZ; + return 0; } diff --git a/softfloat/s_compare96M.c b/softfloat/s_compare96M.c index 5ec6965..0dc39f5 100644 --- a/softfloat/s_compare96M.c +++ b/softfloat/s_compare96M.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. diff --git a/softfloat/s_countLeadingZeros16.c b/softfloat/s_countLeadingZeros16.c new file mode 100644 index 0000000..950db6c --- /dev/null +++ b/softfloat/s_countLeadingZeros16.c @@ -0,0 +1,60 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" + +#ifndef softfloat_countLeadingZeros16 + +#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16 +#include "primitives.h" + +uint_fast8_t softfloat_countLeadingZeros16( uint16_t a ) +{ + uint_fast8_t count; + + count = 8; + if ( 0x100 <= a ) { + count = 0; + a >>= 8; + } + count += softfloat_countLeadingZeros8[a]; + return count; + +} + +#endif + diff --git a/softfloat/s_countLeadingZeros32.c b/softfloat/s_countLeadingZeros32.c index 4446b47..fbf8ab6 100644 --- a/softfloat/s_countLeadingZeros32.c +++ b/softfloat/s_countLeadingZeros32.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. diff --git a/softfloat/s_countLeadingZeros64.c b/softfloat/s_countLeadingZeros64.c index 505dc0f..0045741 100644 --- a/softfloat/s_countLeadingZeros64.c +++ b/softfloat/s_countLeadingZeros64.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. diff --git a/softfloat/s_countLeadingZeros8.c b/softfloat/s_countLeadingZeros8.c index ed84ffa..1158d01 100644 --- a/softfloat/s_countLeadingZeros8.c +++ b/softfloat/s_countLeadingZeros8.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/s_eq128.c b/softfloat/s_eq128.c new file mode 100644 index 0000000..625ef00 --- /dev/null +++ b/softfloat/s_eq128.c @@ -0,0 +1,51 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" + +#ifndef softfloat_eq128 + +bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +{ + + return (a64 == b64) && (a0 == b0); + +} + +#endif + diff --git a/softfloat/s_f128UIToCommonNaN.c b/softfloat/s_f128UIToCommonNaN.c new file mode 100644 index 0000000..861b269 --- /dev/null +++ b/softfloat/s_f128UIToCommonNaN.c @@ -0,0 +1,5 @@ + +/*---------------------------------------------------------------------------- +| This file intentionally contains no code. +*----------------------------------------------------------------------------*/ + diff --git a/softfloat/s_f16UIToCommonNaN.c b/softfloat/s_f16UIToCommonNaN.c new file mode 100644 index 0000000..861b269 --- /dev/null +++ b/softfloat/s_f16UIToCommonNaN.c @@ -0,0 +1,5 @@ + +/*---------------------------------------------------------------------------- +| This file intentionally contains no code. +*----------------------------------------------------------------------------*/ + diff --git a/softfloat/s_f32UIToCommonNaN.c b/softfloat/s_f32UIToCommonNaN.c index 8b13789..861b269 100644 --- a/softfloat/s_f32UIToCommonNaN.c +++ b/softfloat/s_f32UIToCommonNaN.c @@ -1 +1,5 @@ +/*---------------------------------------------------------------------------- +| This file intentionally contains no code. +*----------------------------------------------------------------------------*/ + diff --git a/softfloat/s_f64UIToCommonNaN.c b/softfloat/s_f64UIToCommonNaN.c index 8b13789..861b269 100644 --- a/softfloat/s_f64UIToCommonNaN.c +++ b/softfloat/s_f64UIToCommonNaN.c @@ -1 +1,5 @@ +/*---------------------------------------------------------------------------- +| This file intentionally contains no code. +*----------------------------------------------------------------------------*/ + diff --git a/softfloat/s_le128.c b/softfloat/s_le128.c new file mode 100644 index 0000000..7261012 --- /dev/null +++ b/softfloat/s_le128.c @@ -0,0 +1,51 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" + +#ifndef softfloat_le128 + +bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +{ + + return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); + +} + +#endif + diff --git a/softfloat/s_lt128.c b/softfloat/s_lt128.c new file mode 100644 index 0000000..0d461c3 --- /dev/null +++ b/softfloat/s_lt128.c @@ -0,0 +1,51 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" + +#ifndef softfloat_lt128 + +bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +{ + + return (a64 < b64) || ((a64 == b64) && (a0 < b0)); + +} + +#endif + diff --git a/softfloat/s_mul128By32.c b/softfloat/s_mul128By32.c new file mode 100644 index 0000000..6e71dd0 --- /dev/null +++ b/softfloat/s_mul128By32.c @@ -0,0 +1,58 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_mul128By32 + +struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ) +{ + struct uint128 z; + uint_fast64_t mid; + uint_fast32_t carry; + + z.v0 = a0 * b; + mid = (uint_fast64_t) (uint32_t) (a0>>32) * b; + carry = (uint32_t) ((uint_fast32_t) (z.v0>>32) - (uint_fast32_t) mid); + z.v64 = a64 * b + (uint_fast32_t) ((mid + carry)>>32); + return z; + +} + +#endif + diff --git a/softfloat/s_mul128MTo256M.c b/softfloat/s_mul128MTo256M.c new file mode 100644 index 0000000..49a1d29 --- /dev/null +++ b/softfloat/s_mul128MTo256M.c @@ -0,0 +1,100 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_mul128MTo256M + +void + softfloat_mul128MTo256M( + const uint32_t *aPtr, const uint32_t *bPtr, uint32_t *zPtr ) +{ + uint32_t *lastZPtr, wordB; + uint64_t dwordProd; + uint32_t wordZ; + uint_fast8_t carry; + + bPtr += indexWordLo( 4 ); + lastZPtr = zPtr + indexMultiwordHi( 8, 5 ); + zPtr += indexMultiwordLo( 8, 5 ); + wordB = *bPtr; + dwordProd = (uint64_t) aPtr[indexWord( 4, 0 )] * wordB; + zPtr[indexWord( 5, 0 )] = dwordProd; + dwordProd = (uint64_t) aPtr[indexWord( 4, 1 )] * wordB + (dwordProd>>32); + zPtr[indexWord( 5, 1 )] = dwordProd; + dwordProd = (uint64_t) aPtr[indexWord( 4, 2 )] * wordB + (dwordProd>>32); + zPtr[indexWord( 5, 2 )] = dwordProd; + dwordProd = (uint64_t) aPtr[indexWord( 4, 3 )] * wordB + (dwordProd>>32); + zPtr[indexWord( 5, 3 )] = dwordProd; + zPtr[indexWord( 5, 4 )] = dwordProd>>32; + do { + bPtr += wordIncr; + zPtr += wordIncr; + wordB = *bPtr; + dwordProd = (uint64_t) aPtr[indexWord( 4, 0 )] * wordB; + wordZ = zPtr[indexWord( 5, 0 )] + (uint32_t) dwordProd; + zPtr[indexWord( 5, 0 )] = wordZ; + carry = (wordZ < (uint32_t) dwordProd); + dwordProd = + (uint64_t) aPtr[indexWord( 4, 1 )] * wordB + (dwordProd>>32); + wordZ = zPtr[indexWord( 5, 1 )] + (uint32_t) dwordProd + carry; + zPtr[indexWord( 5, 1 )] = wordZ; + if ( wordZ != (uint32_t) dwordProd ) { + carry = (wordZ < (uint32_t) dwordProd); + } + dwordProd = + (uint64_t) aPtr[indexWord( 4, 2 )] * wordB + (dwordProd>>32); + wordZ = zPtr[indexWord( 5, 2 )] + (uint32_t) dwordProd + carry; + zPtr[indexWord( 5, 2 )] = wordZ; + if ( wordZ != (uint32_t) dwordProd ) { + carry = (wordZ < (uint32_t) dwordProd); + } + dwordProd = + (uint64_t) aPtr[indexWord( 4, 3 )] * wordB + (dwordProd>>32); + wordZ = zPtr[indexWord( 5, 3 )] + (uint32_t) dwordProd + carry; + zPtr[indexWord( 5, 3 )] = wordZ; + if ( wordZ != (uint32_t) dwordProd ) { + carry = (wordZ < (uint32_t) dwordProd); + } + zPtr[indexWord( 5, 4 )] = (dwordProd>>32) + carry; + } while ( zPtr != lastZPtr ); + +} + +#endif + diff --git a/softfloat/s_mul128To256M.c b/softfloat/s_mul128To256M.c new file mode 100644 index 0000000..fccc2a6 --- /dev/null +++ b/softfloat/s_mul128To256M.c @@ -0,0 +1,71 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" + +#ifndef softfloat_mul128To256M + +#define softfloat_mul128To256M softfloat_mul128To256M +#include "primitives.h" + +void + softfloat_mul128To256M( + uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr ) +{ + struct uint128 p0, p64, p128; + uint_fast64_t z64, z128, z192; + + p0 = softfloat_mul64To128( a0, b0 ); + zPtr[indexWord( 4, 0 )] = p0.v0; + p64 = softfloat_mul64To128( a64, b0 ); + z64 = p64.v0 + p0.v64; + z128 = p64.v64 + (z64 < p64.v0); + p128 = softfloat_mul64To128( a64, b64 ); + z128 += p128.v0; + z192 = p128.v64 + (z128 < p128.v0); + p64 = softfloat_mul64To128( a0, b64 ); + z64 += p64.v0; + zPtr[indexWord( 4, 1 )] = z64; + p64.v64 += (z64 < p64.v0); + z128 += p64.v64; + zPtr[indexWord( 4, 2 )] = z128; + zPtr[indexWord( 4, 3 )] = z192 + (z128 < p64.v64); + +} + +#endif + diff --git a/softfloat/s_mul64ByShifted32To128.c b/softfloat/s_mul64ByShifted32To128.c new file mode 100644 index 0000000..f7e7104 --- /dev/null +++ b/softfloat/s_mul64ByShifted32To128.c @@ -0,0 +1,56 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_mul64ByShifted32To128 + +struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ) +{ + uint_fast64_t mid; + struct uint128 z; + + mid = (uint_fast64_t) (uint32_t) a * b; + z.v0 = mid<<32; + z.v64 = (uint_fast64_t) (uint32_t) (a>>32) * b + (mid>>32); + return z; + +} + +#endif + diff --git a/softfloat/s_mul64To128.c b/softfloat/s_mul64To128.c index 06beec8..6620a20 100644 --- a/softfloat/s_mul64To128.c +++ b/softfloat/s_mul64To128.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. diff --git a/softfloat/s_mul64To128M.c b/softfloat/s_mul64To128M.c new file mode 100644 index 0000000..e3f9a48 --- /dev/null +++ b/softfloat/s_mul64To128M.c @@ -0,0 +1,68 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_mul64To128M + +void softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr ) +{ + uint32_t a32, a0, b32, b0; + uint64_t z0, mid1, z64, mid; + + a32 = a>>32; + a0 = a; + b32 = b>>32; + b0 = b; + z0 = (uint64_t) a0 * b0; + mid1 = (uint64_t) a32 * b0; + mid = mid1 + (uint64_t) a0 * b32; + z64 = (uint64_t) a32 * b32; + z64 += (uint64_t) (mid < mid1)<<32 | mid>>32; + mid <<= 32; + z0 += mid; + zPtr[indexWord( 4, 1 )] = z0>>32; + zPtr[indexWord( 4, 0 )] = z0; + z64 += (z0 < mid); + zPtr[indexWord( 4, 3 )] = z64>>32; + zPtr[indexWord( 4, 2 )] = z64; + +} + +#endif + diff --git a/softfloat/s_mulAddF128.c b/softfloat/s_mulAddF128.c new file mode 100644 index 0000000..877b33d --- /dev/null +++ b/softfloat/s_mulAddF128.c @@ -0,0 +1,350 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t + softfloat_mulAddF128( + uint_fast64_t uiA64, + uint_fast64_t uiA0, + uint_fast64_t uiB64, + uint_fast64_t uiB0, + uint_fast64_t uiC64, + uint_fast64_t uiC0, + uint_fast8_t op + ) +{ + bool signA; + int_fast32_t expA; + struct uint128 sigA; + bool signB; + int_fast32_t expB; + struct uint128 sigB; + bool signC; + int_fast32_t expC; + struct uint128 sigC; + bool signZ; + uint_fast64_t magBits; + struct uint128 uiZ; + struct exp32_sig128 normExpSig; + int_fast32_t expZ; + uint64_t sig256Z[4]; + struct uint128 sigZ; + int_fast32_t shiftDist, expDiff; + struct uint128 x128; + uint64_t sig256C[4]; + static uint64_t zero256[4] = INIT_UINTM4( 0, 0, 0, 0 ); + uint_fast64_t sigZExtra, sig256Z0; + union ui128_f128 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF128UI64( uiA64 ); + expA = expF128UI64( uiA64 ); + sigA.v64 = fracF128UI64( uiA64 ); + sigA.v0 = uiA0; + signB = signF128UI64( uiB64 ); + expB = expF128UI64( uiB64 ); + sigB.v64 = fracF128UI64( uiB64 ); + sigB.v0 = uiB0; + signC = signF128UI64( uiC64 ) ^ (op == softfloat_mulAdd_subC); + expC = expF128UI64( uiC64 ); + sigC.v64 = fracF128UI64( uiC64 ); + sigC.v0 = uiC0; + signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x7FFF ) { + if ( + (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0)) + ) { + goto propagateNaN_ABC; + } + magBits = expB | sigB.v64 | sigB.v0; + goto infProdArg; + } + if ( expB == 0x7FFF ) { + if ( sigB.v64 | sigB.v0 ) goto propagateNaN_ABC; + magBits = expA | sigA.v64 | sigA.v0; + goto infProdArg; + } + if ( expC == 0x7FFF ) { + if ( sigC.v64 | sigC.v0 ) { + uiZ.v64 = 0; + uiZ.v0 = 0; + goto propagateNaN_ZC; + } + uiZ.v64 = uiC64; + uiZ.v0 = uiC0; + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! (sigA.v64 | sigA.v0) ) goto zeroProd; + normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if ( ! expB ) { + if ( ! (sigB.v64 | sigB.v0) ) goto zeroProd; + normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x3FFE; + sigA.v64 |= UINT64_C( 0x0001000000000000 ); + sigB.v64 |= UINT64_C( 0x0001000000000000 ); + sigA = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 8 ); + sigB = softfloat_shortShiftLeft128( sigB.v64, sigB.v0, 15 ); + softfloat_mul128To256M( sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z ); + sigZ.v64 = sig256Z[indexWord( 4, 3 )]; + sigZ.v0 = sig256Z[indexWord( 4, 2 )]; + shiftDist = 0; + if ( ! (sigZ.v64 & UINT64_C( 0x0100000000000000 )) ) { + --expZ; + shiftDist = -1; + } + if ( ! expC ) { + if ( ! (sigC.v64 | sigC.v0) ) { + shiftDist += 8; + goto sigZ; + } + normExpSig = softfloat_normSubnormalF128Sig( sigC.v64, sigC.v0 ); + expC = normExpSig.exp; + sigC = normExpSig.sig; + } + sigC.v64 |= UINT64_C( 0x0001000000000000 ); + sigC = softfloat_shortShiftLeft128( sigC.v64, sigC.v0, 8 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expZ - expC; + if ( expDiff < 0 ) { + expZ = expC; + if ( (signZ == signC) || (expDiff < -1) ) { + shiftDist -= expDiff; + if ( shiftDist ) { + sigZ = + softfloat_shiftRightJam128( sigZ.v64, sigZ.v0, shiftDist ); + } + } else { + if ( ! shiftDist ) { + x128 = + softfloat_shortShiftRight128( + sig256Z[indexWord( 4, 1 )], sig256Z[indexWord( 4, 0 )], + 1 + ); + sig256Z[indexWord( 4, 1 )] = (sigZ.v0<<63) | x128.v64; + sig256Z[indexWord( 4, 0 )] = x128.v0; + sigZ = softfloat_shortShiftRight128( sigZ.v64, sigZ.v0, 1 ); + sig256Z[indexWord( 4, 3 )] = sigZ.v64; + sig256Z[indexWord( 4, 2 )] = sigZ.v0; + } + } + } else { + if ( shiftDist ) softfloat_add256M( sig256Z, sig256Z, sig256Z ); + if ( ! expDiff ) { + sigZ.v64 = sig256Z[indexWord( 4, 3 )]; + sigZ.v0 = sig256Z[indexWord( 4, 2 )]; + } else { + sig256C[indexWord( 4, 3 )] = sigC.v64; + sig256C[indexWord( 4, 2 )] = sigC.v0; + sig256C[indexWord( 4, 1 )] = 0; + sig256C[indexWord( 4, 0 )] = 0; + softfloat_shiftRightJam256M( sig256C, expDiff, sig256C ); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 8; + if ( signZ == signC ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( expDiff <= 0 ) { + sigZ = softfloat_add128( sigC.v64, sigC.v0, sigZ.v64, sigZ.v0 ); + } else { + softfloat_add256M( sig256Z, sig256C, sig256Z ); + sigZ.v64 = sig256Z[indexWord( 4, 3 )]; + sigZ.v0 = sig256Z[indexWord( 4, 2 )]; + } + if ( sigZ.v64 & UINT64_C( 0x0200000000000000 ) ) { + ++expZ; + shiftDist = 9; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( expDiff < 0 ) { + signZ = signC; + if ( expDiff < -1 ) { + sigZ = + softfloat_sub128( sigC.v64, sigC.v0, sigZ.v64, sigZ.v0 ); + sigZExtra = + sig256Z[indexWord( 4, 1 )] | sig256Z[indexWord( 4, 0 )]; + if ( sigZExtra ) { + sigZ = softfloat_sub128( sigZ.v64, sigZ.v0, 0, 1 ); + } + if ( ! (sigZ.v64 & UINT64_C( 0x0100000000000000 )) ) { + --expZ; + shiftDist = 7; + } + goto shiftRightRoundPack; + } else { + sig256C[indexWord( 4, 3 )] = sigC.v64; + sig256C[indexWord( 4, 2 )] = sigC.v0; + sig256C[indexWord( 4, 1 )] = 0; + sig256C[indexWord( 4, 0 )] = 0; + softfloat_sub256M( sig256C, sig256Z, sig256Z ); + } + } else if ( ! expDiff ) { + sigZ = softfloat_sub128( sigZ.v64, sigZ.v0, sigC.v64, sigC.v0 ); + if ( + ! (sigZ.v64 | sigZ.v0) && ! sig256Z[indexWord( 4, 1 )] + && ! sig256Z[indexWord( 4, 0 )] + ) { + goto completeCancellation; + } + sig256Z[indexWord( 4, 3 )] = sigZ.v64; + sig256Z[indexWord( 4, 2 )] = sigZ.v0; + if ( sigZ.v64 & UINT64_C( 0x8000000000000000 ) ) { + signZ = ! signZ; + softfloat_sub256M( zero256, sig256Z, sig256Z ); + } + } else { + softfloat_sub256M( sig256Z, sig256C, sig256Z ); + if ( 1 < expDiff ) { + sigZ.v64 = sig256Z[indexWord( 4, 3 )]; + sigZ.v0 = sig256Z[indexWord( 4, 2 )]; + if ( ! (sigZ.v64 & UINT64_C( 0x0100000000000000 )) ) { + --expZ; + shiftDist = 7; + } + goto sigZ; + } + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sigZ.v64 = sig256Z[indexWord( 4, 3 )]; + sigZ.v0 = sig256Z[indexWord( 4, 2 )]; + sigZExtra = sig256Z[indexWord( 4, 1 )]; + sig256Z0 = sig256Z[indexWord( 4, 0 )]; + if ( sigZ.v64 ) { + if ( sig256Z0 ) sigZExtra |= 1; + } else { + expZ -= 64; + sigZ.v64 = sigZ.v0; + sigZ.v0 = sigZExtra; + sigZExtra = sig256Z0; + if ( ! sigZ.v64 ) { + expZ -= 64; + sigZ.v64 = sigZ.v0; + sigZ.v0 = sigZExtra; + sigZExtra = 0; + if ( ! sigZ.v64 ) { + expZ -= 64; + sigZ.v64 = sigZ.v0; + sigZ.v0 = 0; + } + } + } + shiftDist = softfloat_countLeadingZeros64( sigZ.v64 ); + expZ += 7 - shiftDist; + shiftDist = 15 - shiftDist; + if ( 0 < shiftDist ) goto shiftRightRoundPack; + if ( shiftDist ) { + shiftDist = -shiftDist; + sigZ = softfloat_shortShiftLeft128( sigZ.v64, sigZ.v0, shiftDist ); + x128 = softfloat_shortShiftLeft128( 0, sigZExtra, shiftDist ); + sigZ.v0 |= x128.v64; + sigZExtra = x128.v0; + } + goto roundPack; + } + sigZ: + sigZExtra = sig256Z[indexWord( 4, 1 )] | sig256Z[indexWord( 4, 0 )]; + shiftRightRoundPack: + sigZExtra = (uint64_t) (sigZ.v0<<(64 - shiftDist)) | (sigZExtra != 0); + sigZ = softfloat_shortShiftRight128( sigZ.v64, sigZ.v0, shiftDist ); + roundPack: + return + softfloat_roundPackToF128( + signZ, expZ - 1, sigZ.v64, sigZ.v0, sigZExtra ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN_ABC: + uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); + goto propagateNaN_ZC; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infProdArg: + if ( magBits ) { + uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 ); + uiZ.v0 = 0; + if ( expC != 0x7FFF ) goto uiZ; + if ( sigC.v64 | sigC.v0 ) goto propagateNaN_ZC; + if ( signZ == signC ) goto uiZ; + } + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + propagateNaN_ZC: + uiZ = softfloat_propagateNaNF128UI( uiZ.v64, uiZ.v0, uiC64, uiC0 ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zeroProd: + uiZ.v64 = uiC64; + uiZ.v0 = uiC0; + if ( ! (expC | sigC.v64 | sigC.v0) && (signZ != signC) ) { + completeCancellation: + uiZ.v64 = + packToF128UI64( + (softfloat_roundingMode == softfloat_round_min), 0, 0 ); + uiZ.v0 = 0; + } + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/s_mulAddF16.c b/softfloat/s_mulAddF16.c new file mode 100644 index 0000000..b604007 --- /dev/null +++ b/softfloat/s_mulAddF16.c @@ -0,0 +1,226 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16_t + softfloat_mulAddF16( + uint_fast16_t uiA, uint_fast16_t uiB, uint_fast16_t uiC, uint_fast8_t op ) +{ + bool signA; + int_fast8_t expA; + uint_fast16_t sigA; + bool signB; + int_fast8_t expB; + uint_fast16_t sigB; + bool signC; + int_fast8_t expC; + uint_fast16_t sigC; + bool signProd; + uint_fast16_t magBits, uiZ; + struct exp8_sig16 normExpSig; + int_fast8_t expProd; + uint_fast32_t sigProd; + bool signZ; + int_fast8_t expZ; + uint_fast16_t sigZ; + int_fast8_t expDiff; + uint_fast32_t sig32Z, sig32C; + int_fast8_t shiftDist; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF16UI( uiA ); + expA = expF16UI( uiA ); + sigA = fracF16UI( uiA ); + signB = signF16UI( uiB ); + expB = expF16UI( uiB ); + sigB = fracF16UI( uiB ); + signC = signF16UI( uiC ) ^ (op == softfloat_mulAdd_subC); + expC = expF16UI( uiC ); + sigC = fracF16UI( uiC ); + signProd = signA ^ signB ^ (op == softfloat_mulAdd_subProd); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x1F ) { + if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN_ABC; + magBits = expB | sigB; + goto infProdArg; + } + if ( expB == 0x1F ) { + if ( sigB ) goto propagateNaN_ABC; + magBits = expA | sigA; + goto infProdArg; + } + if ( expC == 0x1F ) { + if ( sigC ) { + uiZ = 0; + goto propagateNaN_ZC; + } + uiZ = uiC; + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! sigA ) goto zeroProd; + normExpSig = softfloat_normSubnormalF16Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if ( ! expB ) { + if ( ! sigB ) goto zeroProd; + normExpSig = softfloat_normSubnormalF16Sig( sigB ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expProd = expA + expB - 0xE; + sigA = (sigA | 0x0400)<<4; + sigB = (sigB | 0x0400)<<4; + sigProd = (uint_fast32_t) sigA * sigB; + if ( sigProd < 0x20000000 ) { + --expProd; + sigProd <<= 1; + } + signZ = signProd; + if ( ! expC ) { + if ( ! sigC ) { + expZ = expProd - 1; + sigZ = sigProd>>15 | ((sigProd & 0x7FFF) != 0); + goto roundPack; + } + normExpSig = softfloat_normSubnormalF16Sig( sigC ); + expC = normExpSig.exp; + sigC = normExpSig.sig; + } + sigC = (sigC | 0x0400)<<3; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expProd - expC; + if ( signProd == signC ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( expDiff <= 0 ) { + expZ = expC; + sigZ = sigC + softfloat_shiftRightJam32( sigProd, 16 - expDiff ); + } else { + expZ = expProd; + sig32Z = + sigProd + + softfloat_shiftRightJam32( + (uint_fast32_t) sigC<<16, expDiff ); + sigZ = sig32Z>>16 | ((sig32Z & 0xFFFF) != 0 ); + } + if ( sigZ < 0x4000 ) { + --expZ; + sigZ <<= 1; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig32C = (uint_fast32_t) sigC<<16; + if ( expDiff < 0 ) { + signZ = signC; + expZ = expC; + sig32Z = sig32C - softfloat_shiftRightJam32( sigProd, -expDiff ); + } else if ( ! expDiff ) { + expZ = expProd; + sig32Z = sigProd - sig32C; + if ( ! sig32Z ) goto completeCancellation; + if ( sig32Z & 0x80000000 ) { + signZ = ! signZ; + sig32Z = -sig32Z; + } + } else { + expZ = expProd; + sig32Z = sigProd - softfloat_shiftRightJam32( sig32C, expDiff ); + } + shiftDist = softfloat_countLeadingZeros32( sig32Z ) - 1; + expZ -= shiftDist; + shiftDist -= 16; + if ( shiftDist < 0 ) { + sigZ = + sig32Z>>(-shiftDist) + | ((uint32_t) (sig32Z<<(shiftDist & 31)) != 0); + } else { + sigZ = (uint_fast16_t) sig32Z<<shiftDist; + } + } + roundPack: + return softfloat_roundPackToF16( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN_ABC: + uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); + goto propagateNaN_ZC; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infProdArg: + if ( magBits ) { + uiZ = packToF16UI( signProd, 0x1F, 0 ); + if ( expC != 0x1F ) goto uiZ; + if ( sigC ) goto propagateNaN_ZC; + if ( signProd == signC ) goto uiZ; + } + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF16UI; + propagateNaN_ZC: + uiZ = softfloat_propagateNaNF16UI( uiZ, uiC ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zeroProd: + uiZ = uiC; + if ( ! (expC | sigC) && (signProd != signC) ) { + completeCancellation: + uiZ = + packToF16UI( + (softfloat_roundingMode == softfloat_round_min), 0, 0 ); + } + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + 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; diff --git a/softfloat/s_mulAddF64.c b/softfloat/s_mulAddF64.c index 9f9ecf5..484ac58 100644 --- a/softfloat/s_mulAddF64.c +++ b/softfloat/s_mulAddF64.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,7 +64,7 @@ float64_t uint_fast64_t sigZ; int_fast16_t expDiff; struct uint128 sig128C; - int_fast8_t shiftCount; + int_fast8_t shiftDist; union ui64_f64 uZ; /*------------------------------------------------------------------------ @@ -177,7 +177,7 @@ float64_t sig128Z.v64 = sig128Z.v64 - sigC; if ( ! (sig128Z.v64 | sig128Z.v0) ) goto completeCancellation; if ( sig128Z.v64 & UINT64_C( 0x8000000000000000 ) ) { - signZ ^= 1; + signZ = ! signZ; sig128Z = softfloat_sub128( 0, 0, sig128Z.v64, sig128Z.v0 ); } } else { @@ -192,14 +192,14 @@ float64_t sig128Z.v64 = sig128Z.v0; sig128Z.v0 = 0; } - shiftCount = softfloat_countLeadingZeros64( sig128Z.v64 ) - 1; - expZ -= shiftCount; - if ( shiftCount < 0 ) { - sigZ = softfloat_shortShiftRightJam64( sig128Z.v64, -shiftCount ); + shiftDist = softfloat_countLeadingZeros64( sig128Z.v64 ) - 1; + expZ -= shiftDist; + if ( shiftDist < 0 ) { + sigZ = softfloat_shortShiftRightJam64( sig128Z.v64, -shiftDist ); } else { sig128Z = softfloat_shortShiftLeft128( - sig128Z.v64, sig128Z.v0, shiftCount ); + sig128Z.v64, sig128Z.v0, shiftDist ); sigZ = sig128Z.v64; } sigZ |= (sig128Z.v0 != 0); @@ -220,7 +220,6 @@ float64_t if ( sigC ) goto propagateNaN_ZC; if ( signZ == signC ) goto uiZ; } - invalid: softfloat_raiseFlags( softfloat_flag_invalid ); uiZ = defaultNaNF64UI; propagateNaN_ZC: @@ -233,7 +232,8 @@ float64_t if ( ! (expC | sigC) && (signZ != signC) ) { completeCancellation: uiZ = - packToF64UI( softfloat_roundingMode == softfloat_round_min, 0, 0 ); + packToF64UI( + (softfloat_roundingMode == softfloat_round_min), 0, 0 ); } uiZ: uZ.ui = uiZ; @@ -262,7 +262,7 @@ float64_t int_fast16_t expZ; uint32_t sig128Z[4]; uint64_t sigZ; - int_fast16_t shiftCount, expDiff; + int_fast16_t shiftDist, expDiff; uint32_t sig128C[4]; union ui64_f64 uZ; @@ -320,14 +320,14 @@ float64_t softfloat_mul64To128M( sigA, sigB, sig128Z ); sigZ = (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 | sig128Z[indexWord( 4, 2 )]; - shiftCount = 0; + shiftDist = 0; if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) { --expZ; - shiftCount = -1; + shiftDist = -1; } if ( ! expC ) { if ( ! sigC ) { - if ( shiftCount ) sigZ <<= 1; + if ( shiftDist ) sigZ <<= 1; goto sigZ; } normExpSig = softfloat_normSubnormalF64Sig( sigC ); @@ -341,17 +341,17 @@ float64_t if ( expDiff < 0 ) { expZ = expC; if ( (signZ == signC) || (expDiff < -1) ) { - shiftCount -= expDiff; - if ( shiftCount) { - sigZ = softfloat_shiftRightJam64( sigZ, shiftCount ); + shiftDist -= expDiff; + if ( shiftDist) { + sigZ = softfloat_shiftRightJam64( sigZ, shiftDist ); } } else { - if ( ! shiftCount ) { + if ( ! shiftDist ) { softfloat_shortShiftRight128M( sig128Z, 1, sig128Z ); } } } else { - if ( shiftCount ) softfloat_add128M( sig128Z, sig128Z, sig128Z ); + if ( shiftDist ) softfloat_add128M( sig128Z, sig128Z, sig128Z ); if ( ! expDiff ) { sigZ = (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 @@ -416,7 +416,7 @@ float64_t sig128Z[indexWord( 4, 3 )] = sigZ>>32; sig128Z[indexWord( 4, 2 )] = sigZ; if ( sigZ & UINT64_C( 0x8000000000000000 ) ) { - signZ ^= 1; + signZ = ! signZ; softfloat_negX128M( sig128Z ); } } else { @@ -434,20 +434,20 @@ float64_t } /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ - shiftCount = 0; + shiftDist = 0; sigZ = (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 | sig128Z[indexWord( 4, 2 )]; if ( ! sigZ ) { - shiftCount = 64; + shiftDist = 64; sigZ = (uint64_t) sig128Z[indexWord( 4, 1 )]<<32 | sig128Z[indexWord( 4, 0 )]; } - shiftCount += softfloat_countLeadingZeros64( sigZ ) - 1; - if ( shiftCount ) { - expZ -= shiftCount; - softfloat_shiftLeft128M( sig128Z, shiftCount, sig128Z ); + shiftDist += softfloat_countLeadingZeros64( sigZ ) - 1; + if ( shiftDist ) { + expZ -= shiftDist; + softfloat_shiftLeft128M( sig128Z, shiftDist, sig128Z ); sigZ = (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 | sig128Z[indexWord( 4, 2 )]; @@ -471,7 +471,6 @@ float64_t if ( sigC ) goto propagateNaN_ZC; if ( signZ == signC ) goto uiZ; } - invalid: softfloat_raiseFlags( softfloat_flag_invalid ); uiZ = defaultNaNF64UI; propagateNaN_ZC: @@ -484,7 +483,8 @@ float64_t if ( ! (expC | sigC) && (signZ != signC) ) { completeCancellation: uiZ = - packToF64UI( softfloat_roundingMode == softfloat_round_min, 0, 0 ); + packToF64UI( + (softfloat_roundingMode == softfloat_round_min), 0, 0 ); } uiZ: uZ.ui = uiZ; diff --git a/softfloat/s_negXM.c b/softfloat/s_negXM.c index 4c80aa9..76f110c 100644 --- a/softfloat/s_negXM.c +++ b/softfloat/s_negXM.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. diff --git a/softfloat/s_normRoundPackToF128.c b/softfloat/s_normRoundPackToF128.c new file mode 100644 index 0000000..148cb2c --- /dev/null +++ b/softfloat/s_normRoundPackToF128.c @@ -0,0 +1,81 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" + +float128_t + softfloat_normRoundPackToF128( + bool sign, int_fast32_t exp, uint_fast64_t sig64, uint_fast64_t sig0 ) +{ + int_fast8_t shiftDist; + struct uint128 sig128; + union ui128_f128 uZ; + uint_fast64_t sigExtra; + struct uint128_extra sig128Extra; + + if ( ! sig64 ) { + exp -= 64; + sig64 = sig0; + sig0 = 0; + } + shiftDist = softfloat_countLeadingZeros64( sig64 ) - 15; + exp -= shiftDist; + if ( 0 <= shiftDist ) { + if ( shiftDist ) { + sig128 = softfloat_shortShiftLeft128( sig64, sig0, shiftDist ); + sig64 = sig128.v64; + sig0 = sig128.v0; + } + if ( (uint32_t) exp < 0x7FFD ) { + uZ.ui.v64 = packToF128UI64( sign, sig64 | sig0 ? exp : 0, sig64 ); + uZ.ui.v0 = sig0; + return uZ.f; + } + sigExtra = 0; + } else { + sig128Extra = + softfloat_shortShiftRightJam128Extra( sig64, sig0, 0, -shiftDist ); + sig64 = sig128Extra.v.v64; + sig0 = sig128Extra.v.v0; + sigExtra = sig128Extra.extra; + } + return softfloat_roundPackToF128( sign, exp, sig64, sig0, sigExtra ); + +} + diff --git a/softfloat/s_normRoundPackToF16.c b/softfloat/s_normRoundPackToF16.c new file mode 100644 index 0000000..6788f2e --- /dev/null +++ b/softfloat/s_normRoundPackToF16.c @@ -0,0 +1,58 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" + +float16_t + softfloat_normRoundPackToF16( bool sign, int_fast16_t exp, uint_fast16_t sig ) +{ + int_fast8_t shiftDist; + union ui16_f16 uZ; + + shiftDist = softfloat_countLeadingZeros16( sig ) - 1; + exp -= shiftDist; + if ( (4 <= shiftDist) && ((unsigned int) exp < 0x1D) ) { + uZ.ui = packToF16UI( sign, sig ? exp : 0, sig<<(shiftDist - 4) ); + return uZ.f; + } else { + return softfloat_roundPackToF16( sign, exp, sig<<shiftDist ); + } + +} + diff --git a/softfloat/s_normRoundPackToF32.c b/softfloat/s_normRoundPackToF32.c index fea073c..14e0811 100644 --- a/softfloat/s_normRoundPackToF32.c +++ b/softfloat/s_normRoundPackToF32.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: @@ -42,16 +42,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float32_t softfloat_normRoundPackToF32( bool sign, int_fast16_t exp, uint_fast32_t sig ) { - int_fast8_t shiftCount; + int_fast8_t shiftDist; union ui32_f32 uZ; - shiftCount = softfloat_countLeadingZeros32( sig ) - 1; - exp -= shiftCount; - if ( (7 <= shiftCount) && ((uint16_t) exp < 0xFD) ) { - uZ.ui = packToF32UI( sign, sig ? exp : 0, sig<<(shiftCount - 7) ); + shiftDist = softfloat_countLeadingZeros32( sig ) - 1; + exp -= shiftDist; + if ( (7 <= shiftDist) && ((unsigned int) exp < 0xFD) ) { + uZ.ui = packToF32UI( sign, sig ? exp : 0, sig<<(shiftDist - 7) ); return uZ.f; } else { - return softfloat_roundPackToF32( sign, exp, sig<<shiftCount ); + return softfloat_roundPackToF32( sign, exp, sig<<shiftDist ); } } diff --git a/softfloat/s_normRoundPackToF64.c b/softfloat/s_normRoundPackToF64.c index dd42fc8..7f5d6a2 100644 --- a/softfloat/s_normRoundPackToF64.c +++ b/softfloat/s_normRoundPackToF64.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: @@ -42,16 +42,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float64_t softfloat_normRoundPackToF64( bool sign, int_fast16_t exp, uint_fast64_t sig ) { - int_fast8_t shiftCount; + int_fast8_t shiftDist; union ui64_f64 uZ; - shiftCount = softfloat_countLeadingZeros64( sig ) - 1; - exp -= shiftCount; - if ( (10 <= shiftCount) && ((uint16_t) exp < 0x7FD) ) { - uZ.ui = packToF64UI( sign, sig ? exp : 0, sig<<(shiftCount - 10) ); + shiftDist = softfloat_countLeadingZeros64( sig ) - 1; + exp -= shiftDist; + if ( (10 <= shiftDist) && ((unsigned int) exp < 0x7FD) ) { + uZ.ui = packToF64UI( sign, sig ? exp : 0, sig<<(shiftDist - 10) ); return uZ.f; } else { - return softfloat_roundPackToF64( sign, exp, sig<<shiftCount ); + return softfloat_roundPackToF64( sign, exp, sig<<shiftDist ); } } diff --git a/softfloat/s_normSubnormalF128Sig.c b/softfloat/s_normSubnormalF128Sig.c new file mode 100644 index 0000000..cf02e10 --- /dev/null +++ b/softfloat/s_normSubnormalF128Sig.c @@ -0,0 +1,65 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "internals.h" + +struct exp32_sig128 + softfloat_normSubnormalF128Sig( uint_fast64_t sig64, uint_fast64_t sig0 ) +{ + int_fast8_t shiftDist; + struct exp32_sig128 z; + + if ( ! sig64 ) { + shiftDist = softfloat_countLeadingZeros64( sig0 ) - 15; + z.exp = -63 - shiftDist; + if ( shiftDist < 0 ) { + z.sig.v64 = sig0>>-shiftDist; + z.sig.v0 = sig0<<(shiftDist & 63); + } else { + z.sig.v64 = sig0<<shiftDist; + z.sig.v0 = 0; + } + } else { + shiftDist = softfloat_countLeadingZeros64( sig64 ) - 15; + z.exp = 1 - shiftDist; + z.sig = softfloat_shortShiftLeft128( sig64, sig0, shiftDist ); + } + return z; + +} + diff --git a/softfloat/s_normSubnormalF16Sig.c b/softfloat/s_normSubnormalF16Sig.c new file mode 100644 index 0000000..e612a9e --- /dev/null +++ b/softfloat/s_normSubnormalF16Sig.c @@ -0,0 +1,52 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "internals.h" + +struct exp8_sig16 softfloat_normSubnormalF16Sig( uint_fast16_t sig ) +{ + int_fast8_t shiftDist; + struct exp8_sig16 z; + + shiftDist = softfloat_countLeadingZeros16( sig ) - 5; + z.exp = 1 - shiftDist; + z.sig = sig<<shiftDist; + return z; + +} + diff --git a/softfloat/s_normSubnormalF32Sig.c b/softfloat/s_normSubnormalF32Sig.c index 3948eb7..e3e8ce4 100644 --- a/softfloat/s_normSubnormalF32Sig.c +++ b/softfloat/s_normSubnormalF32Sig.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: @@ -40,12 +40,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t sig ) { - int_fast8_t shiftCount; + int_fast8_t shiftDist; struct exp16_sig32 z; - shiftCount = softfloat_countLeadingZeros32( sig ) - 8; - z.exp = 1 - shiftCount; - z.sig = sig<<shiftCount; + shiftDist = softfloat_countLeadingZeros32( sig ) - 8; + z.exp = 1 - shiftDist; + z.sig = sig<<shiftDist; return z; } diff --git a/softfloat/s_normSubnormalF64Sig.c b/softfloat/s_normSubnormalF64Sig.c index e9234e9..fddfc32 100644 --- a/softfloat/s_normSubnormalF64Sig.c +++ b/softfloat/s_normSubnormalF64Sig.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: @@ -40,12 +40,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t sig ) { - int_fast8_t shiftCount; + int_fast8_t shiftDist; struct exp16_sig64 z; - shiftCount = softfloat_countLeadingZeros64( sig ) - 11; - z.exp = 1 - shiftCount; - z.sig = sig<<shiftCount; + shiftDist = softfloat_countLeadingZeros64( sig ) - 11; + z.exp = 1 - shiftDist; + z.sig = sig<<shiftDist; return z; } diff --git a/softfloat/s_propagateNaNF128UI.c b/softfloat/s_propagateNaNF128UI.c new file mode 100644 index 0000000..ad7e83b --- /dev/null +++ b/softfloat/s_propagateNaNF128UI.c @@ -0,0 +1,73 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Interpreting the unsigned integer formed from concatenating `uiA64' and +| `uiA0' as a 128-bit floating-point value, and likewise interpreting the +| unsigned integer formed from concatenating `uiB64' and `uiB0' as another +| 128-bit floating-point value, and assuming at least on of these floating- +| point values is a NaN, returns the bit pattern of the combined NaN result. +| If either original floating-point value is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +struct uint128 + softfloat_propagateNaNF128UI( + uint_fast64_t uiA64, + uint_fast64_t uiA0, + uint_fast64_t uiB64, + uint_fast64_t uiB0 + ) +{ + struct uint128 uiZ; + + if ( + softfloat_isSigNaNF128UI( uiA64, uiA0 ) + || softfloat_isSigNaNF128UI( uiB64, uiB0 ) + ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + } + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + return uiZ; + +} + diff --git a/softfloat/s_propagateNaNF16UI.c b/softfloat/s_propagateNaNF16UI.c new file mode 100644 index 0000000..3ecd4c9 --- /dev/null +++ b/softfloat/s_propagateNaNF16UI.c @@ -0,0 +1,58 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Interpreting `uiA' and `uiB' as the bit patterns of two 16-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either `uiA' or `uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint_fast16_t + softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ) +{ + + if ( softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + } + return defaultNaNF16UI; + +} + diff --git a/softfloat/s_propagateNaNF32UI.c b/softfloat/s_propagateNaNF32UI.c index ec709f9..b97fa41 100644 --- a/softfloat/s_propagateNaNF32UI.c +++ b/softfloat/s_propagateNaNF32UI.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. diff --git a/softfloat/s_propagateNaNF64UI.c b/softfloat/s_propagateNaNF64UI.c index 5868225..9c2d359 100644 --- a/softfloat/s_propagateNaNF64UI.c +++ b/softfloat/s_propagateNaNF64UI.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. diff --git a/softfloat/s_remStepMBy32.c b/softfloat/s_remStepMBy32.c index 429d3dc..fe787a4 100644 --- a/softfloat/s_remStepMBy32.c +++ b/softfloat/s_remStepMBy32.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -44,34 +44,33 @@ void softfloat_remStepMBy32( uint_fast8_t size_words, const uint32_t *remPtr, - uint_fast8_t count, + uint_fast8_t dist, const uint32_t *bPtr, uint32_t q, uint32_t *zPtr ) { - uint_fast8_t negCount; unsigned int index, lastIndex; uint64_t dwordProd; uint32_t wordRem, wordShiftedRem, wordProd; - uint_fast8_t borrow; + uint_fast8_t uNegDist, borrow; - negCount = -count; index = indexWordLo( size_words ); lastIndex = indexWordHi( size_words ); dwordProd = (uint64_t) bPtr[index] * q; wordRem = remPtr[index]; - wordShiftedRem = wordRem<<count; + wordShiftedRem = wordRem<<dist; wordProd = dwordProd; zPtr[index] = wordShiftedRem - wordProd; if ( index != lastIndex ) { + uNegDist = -dist; borrow = (wordShiftedRem < wordProd); for (;;) { - wordShiftedRem = wordRem>>(negCount & 31); + wordShiftedRem = wordRem>>(uNegDist & 31); index += wordIncr; dwordProd = (uint64_t) bPtr[index] * q + (dwordProd>>32); wordRem = remPtr[index]; - wordShiftedRem |= wordRem<<count; + wordShiftedRem |= wordRem<<dist; wordProd = dwordProd; zPtr[index] = wordShiftedRem - wordProd - borrow; if ( index == lastIndex ) break; diff --git a/softfloat/s_roundMToI64.c b/softfloat/s_roundMToI64.c new file mode 100644 index 0000000..a73f7f8 --- /dev/null +++ b/softfloat/s_roundMToI64.c @@ -0,0 +1,88 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t + softfloat_roundMToI64( + bool sign, uint32_t *extSigPtr, uint_fast8_t roundingMode, bool exact ) +{ + bool roundNearEven; + uint32_t sigExtra; + bool doIncrement; + uint64_t sig; + union { uint64_t ui; int64_t i; } uZ; + int64_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); + sigExtra = extSigPtr[indexWordLo( 3 )]; + doIncrement = (0x80000000 <= sigExtra); + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + doIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + && sigExtra; + } + sig = + (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32 + | extSigPtr[indexWord( 3, 1 )]; + if ( doIncrement ) { + ++sig; + if ( ! sig ) goto invalid; + if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) sig &= ~1; + } + uZ.ui = sign ? -sig : sig; + z = uZ.i; + if ( z && ((z < 0) ^ sign) ) goto invalid; + if ( exact && sigExtra ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return sign ? i64_fromNegOverflow : i64_fromPosOverflow; + +} + diff --git a/softfloat/s_roundMToUI64.c b/softfloat/s_roundMToUI64.c new file mode 100644 index 0000000..0377c5b --- /dev/null +++ b/softfloat/s_roundMToUI64.c @@ -0,0 +1,84 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t + softfloat_roundMToUI64( + bool sign, uint32_t *extSigPtr, uint_fast8_t roundingMode, bool exact ) +{ + bool roundNearEven; + uint32_t sigExtra; + bool doIncrement; + uint64_t sig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); + sigExtra = extSigPtr[indexWordLo( 3 )]; + doIncrement = (0x80000000 <= sigExtra); + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + doIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + && sigExtra; + } + sig = + (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32 + | extSigPtr[indexWord( 3, 1 )]; + if ( doIncrement ) { + ++sig; + if ( ! sig ) goto invalid; + if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) sig &= ~1; + } + if ( sign && sig ) goto invalid; + if ( exact && sigExtra ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return sig; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + +} + diff --git a/softfloat/s_roundPackToF128.c b/softfloat/s_roundPackToF128.c new file mode 100644 index 0000000..eaaa375 --- /dev/null +++ b/softfloat/s_roundPackToF128.c @@ -0,0 +1,171 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float128_t + softfloat_roundPackToF128( + bool sign, + int_fast32_t exp, + uint_fast64_t sig64, + uint_fast64_t sig0, + uint_fast64_t sigExtra + ) +{ + uint_fast8_t roundingMode; + bool roundNearEven, doIncrement, isTiny; + struct uint128_extra sig128Extra; + uint_fast64_t uiZ64, uiZ0; + struct uint128 sig128; + union ui128_f128 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundingMode = softfloat_roundingMode; + roundNearEven = (roundingMode == softfloat_round_near_even); + doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + doIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + && sigExtra; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( 0x7FFD <= (uint32_t) exp ) { + if ( exp < 0 ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + isTiny = + (softfloat_detectTininess + == softfloat_tininess_beforeRounding) + || (exp < -1) + || ! doIncrement + || softfloat_lt128( + sig64, + sig0, + UINT64_C( 0x0001FFFFFFFFFFFF ), + UINT64_C( 0xFFFFFFFFFFFFFFFF ) + ); + sig128Extra = + softfloat_shiftRightJam128Extra( sig64, sig0, sigExtra, -exp ); + sig64 = sig128Extra.v.v64; + sig0 = sig128Extra.v.v0; + sigExtra = sig128Extra.extra; + exp = 0; + if ( isTiny && sigExtra ) { + softfloat_raiseFlags( softfloat_flag_underflow ); + } + doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); + if ( + ! roundNearEven + && (roundingMode != softfloat_round_near_maxMag) + ) { + doIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + && sigExtra; + } + } else if ( + (0x7FFD < exp) + || ((exp == 0x7FFD) + && softfloat_eq128( + sig64, + sig0, + UINT64_C( 0x0001FFFFFFFFFFFF ), + UINT64_C( 0xFFFFFFFFFFFFFFFF ) + ) + && doIncrement) + ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + softfloat_raiseFlags( + softfloat_flag_overflow | softfloat_flag_inexact ); + if ( + roundNearEven + || (roundingMode == softfloat_round_near_maxMag) + || (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + ) { + uiZ64 = packToF128UI64( sign, 0x7FFF, 0 ); + uiZ0 = 0; + } else { + uiZ64 = + packToF128UI64( + sign, 0x7FFE, UINT64_C( 0x0000FFFFFFFFFFFF ) ); + uiZ0 = UINT64_C( 0xFFFFFFFFFFFFFFFF ); + } + goto uiZ; + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( sigExtra ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; +#ifdef SOFTFLOAT_ROUND_ODD + if ( roundingMode == softfloat_round_odd ) { + sig0 |= 1; + goto packReturn; + } +#endif + } + if ( doIncrement ) { + sig128 = softfloat_add128( sig64, sig0, 0, 1 ); + sig64 = sig128.v64; + sig0 = + sig128.v0 + & ~(uint64_t) + (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + & roundNearEven); + } else { + if ( ! (sig64 | sig0) ) exp = 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + packReturn: + uiZ64 = packToF128UI64( sign, exp, sig64 ); + uiZ0 = sig0; + uiZ: + uZ.ui.v64 = uiZ64; + uZ.ui.v0 = uiZ0; + return uZ.f; + +} + diff --git a/softfloat/s_roundPackToF16.c b/softfloat/s_roundPackToF16.c new file mode 100644 index 0000000..0eaa73a --- /dev/null +++ b/softfloat/s_roundPackToF16.c @@ -0,0 +1,113 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float16_t + softfloat_roundPackToF16( bool sign, int_fast16_t exp, uint_fast16_t sig ) +{ + uint_fast8_t roundingMode; + bool roundNearEven; + uint_fast8_t roundIncrement, roundBits; + bool isTiny; + uint_fast16_t uiZ; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundingMode = softfloat_roundingMode; + roundNearEven = (roundingMode == softfloat_round_near_even); + roundIncrement = 0x8; + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + roundIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + ? 0xF + : 0; + } + roundBits = sig & 0xF; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( 0x1D <= (unsigned int) exp ) { + if ( exp < 0 ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + isTiny = + (softfloat_detectTininess == softfloat_tininess_beforeRounding) + || (exp < -1) || (sig + roundIncrement < 0x8000); + sig = softfloat_shiftRightJam32( sig, -exp ); + exp = 0; + roundBits = sig & 0xF; + if ( isTiny && roundBits ) { + softfloat_raiseFlags( softfloat_flag_underflow ); + } + } else if ( (0x1D < exp) || (0x8000 <= sig + roundIncrement) ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + softfloat_raiseFlags( + softfloat_flag_overflow | softfloat_flag_inexact ); + uiZ = packToF16UI( sign, 0x1F, 0 ) - ! roundIncrement; + goto uiZ; + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig = (sig + roundIncrement)>>4; + if ( roundBits ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; +#ifdef SOFTFLOAT_ROUND_ODD + if ( roundingMode == softfloat_round_odd ) { + sig |= 1; + goto packReturn; + } +#endif + } + sig &= ~(uint_fast16_t) (! (roundBits ^ 8) & roundNearEven); + if ( ! sig ) exp = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + packReturn: + uiZ = packToF16UI( sign, exp, sig ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/s_roundPackToF32.c b/softfloat/s_roundPackToF32.c index 8b44a03..cc34508 100644 --- a/softfloat/s_roundPackToF32.c +++ b/softfloat/s_roundPackToF32.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -50,6 +50,8 @@ float32_t uint_fast32_t uiZ; union ui32_f32 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ roundingMode = softfloat_roundingMode; roundNearEven = (roundingMode == softfloat_round_near_even); roundIncrement = 0x40; @@ -61,13 +63,15 @@ float32_t : 0; } roundBits = sig & 0x7F; - if ( 0xFD <= (uint16_t) exp ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( 0xFD <= (unsigned int) exp ) { if ( exp < 0 ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ isTiny = - (softfloat_detectTininess - == softfloat_tininess_beforeRounding) - || (exp < -1) - || (sig + roundIncrement < 0x80000000); + (softfloat_detectTininess == softfloat_tininess_beforeRounding) + || (exp < -1) || (sig + roundIncrement < 0x80000000); sig = softfloat_shiftRightJam32( sig, -exp ); exp = 0; roundBits = sig & 0x7F; @@ -75,16 +79,32 @@ float32_t softfloat_raiseFlags( softfloat_flag_underflow ); } } else if ( (0xFD < exp) || (0x80000000 <= sig + roundIncrement) ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ softfloat_raiseFlags( softfloat_flag_overflow | softfloat_flag_inexact ); uiZ = packToF32UI( sign, 0xFF, 0 ) - ! roundIncrement; goto uiZ; } } - if ( roundBits ) softfloat_exceptionFlags |= softfloat_flag_inexact; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig = (sig + roundIncrement)>>7; + if ( roundBits ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; +#ifdef SOFTFLOAT_ROUND_ODD + if ( roundingMode == softfloat_round_odd ) { + sig |= 1; + goto packReturn; + } +#endif + } sig &= ~(uint_fast32_t) (! (roundBits ^ 0x40) & roundNearEven); - uiZ = packToF32UI( sign, sig ? exp : 0, sig ); + if ( ! sig ) exp = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + packReturn: + uiZ = packToF32UI( sign, exp, sig ); uiZ: uZ.ui = uiZ; return uZ.f; diff --git a/softfloat/s_roundPackToF64.c b/softfloat/s_roundPackToF64.c index e56493e..aaff008 100644 --- a/softfloat/s_roundPackToF64.c +++ b/softfloat/s_roundPackToF64.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -50,6 +50,8 @@ float64_t uint_fast64_t uiZ; union ui64_f64 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ roundingMode = softfloat_roundingMode; roundNearEven = (roundingMode == softfloat_round_near_even); roundIncrement = 0x200; @@ -61,13 +63,16 @@ float64_t : 0; } roundBits = sig & 0x3FF; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( 0x7FD <= (uint16_t) exp ) { if ( exp < 0 ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ isTiny = - (softfloat_detectTininess - == softfloat_tininess_beforeRounding) - || (exp < -1) - || (sig + roundIncrement < UINT64_C( 0x8000000000000000 )); + (softfloat_detectTininess == softfloat_tininess_beforeRounding) + || (exp < -1) + || (sig + roundIncrement < UINT64_C( 0x8000000000000000 )); sig = softfloat_shiftRightJam64( sig, -exp ); exp = 0; roundBits = sig & 0x3FF; @@ -78,16 +83,32 @@ float64_t (0x7FD < exp) || (UINT64_C( 0x8000000000000000 ) <= sig + roundIncrement) ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ softfloat_raiseFlags( softfloat_flag_overflow | softfloat_flag_inexact ); uiZ = packToF64UI( sign, 0x7FF, 0 ) - ! roundIncrement; goto uiZ; } } - if ( roundBits ) softfloat_exceptionFlags |= softfloat_flag_inexact; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig = (sig + roundIncrement)>>10; + if ( roundBits ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; +#ifdef SOFTFLOAT_ROUND_ODD + if ( roundingMode == softfloat_round_odd ) { + sig |= 1; + goto packReturn; + } +#endif + } sig &= ~(uint_fast64_t) (! (roundBits ^ 0x200) & roundNearEven); - uiZ = packToF64UI( sign, sig ? exp : 0, sig ); + if ( ! sig ) exp = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + packReturn: + uiZ = packToF64UI( sign, exp, sig ); uiZ: uZ.ui = uiZ; return uZ.f; diff --git a/softfloat/s_roundToI32.c b/softfloat/s_roundToI32.c new file mode 100644 index 0000000..20a3ff4 --- /dev/null +++ b/softfloat/s_roundToI32.c @@ -0,0 +1,84 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast32_t + softfloat_roundToI32( + bool sign, uint_fast64_t sig, uint_fast8_t roundingMode, bool exact ) +{ + bool roundNearEven; + uint_fast16_t roundIncrement, roundBits; + uint_fast32_t sig32; + union { uint32_t ui; int32_t i; } uZ; + int_fast32_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); + roundIncrement = 0x800; + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + roundIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + ? 0xFFF + : 0; + } + roundBits = sig & 0xFFF; + sig += roundIncrement; + if ( sig & UINT64_C( 0xFFFFF00000000000 ) ) goto invalid; + sig32 = sig>>12; + sig32 &= ~(uint_fast32_t) (! (roundBits ^ 0x800) & roundNearEven); + uZ.ui = sign ? -sig32 : sig32; + z = uZ.i; + if ( z && ((z < 0) ^ sign) ) goto invalid; + if ( exact && roundBits ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return sign ? i32_fromNegOverflow : i32_fromPosOverflow; + +} + diff --git a/softfloat/s_roundToI64.c b/softfloat/s_roundToI64.c new file mode 100644 index 0000000..fcddbc2 --- /dev/null +++ b/softfloat/s_roundToI64.c @@ -0,0 +1,89 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t + softfloat_roundToI64( + bool sign, + uint_fast64_t sig, + uint_fast64_t sigExtra, + uint_fast8_t roundingMode, + bool exact + ) +{ + bool roundNearEven, doIncrement; + union { uint64_t ui; int64_t i; } uZ; + int_fast64_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); + doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + doIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + && sigExtra; + } + if ( doIncrement ) { + ++sig; + if ( ! sig ) goto invalid; + sig &= + ~(uint_fast64_t) + (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + & roundNearEven); + } + uZ.ui = sign ? -sig : sig; + z = uZ.i; + if ( z && ((z < 0) ^ sign) ) goto invalid; + if ( exact && sigExtra ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return sign ? i64_fromNegOverflow : i64_fromPosOverflow; + +} + diff --git a/softfloat/s_roundToUI32.c b/softfloat/s_roundToUI32.c new file mode 100644 index 0000000..180899b --- /dev/null +++ b/softfloat/s_roundToUI32.c @@ -0,0 +1,80 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast32_t + softfloat_roundToUI32( + bool sign, uint_fast64_t sig, uint_fast8_t roundingMode, bool exact ) +{ + bool roundNearEven; + uint_fast16_t roundIncrement, roundBits; + uint_fast32_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); + roundIncrement = 0x800; + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + roundIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + ? 0xFFF + : 0; + } + roundBits = sig & 0xFFF; + sig += roundIncrement; + if ( sig & UINT64_C( 0xFFFFF00000000000 ) ) goto invalid; + z = sig>>12; + z &= ~(uint_fast32_t) (! (roundBits ^ 0x800) & roundNearEven); + if ( sign && z ) goto invalid; + if ( exact && roundBits ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + +} + diff --git a/softfloat/s_roundToUI64.c b/softfloat/s_roundToUI64.c new file mode 100644 index 0000000..de35b5e --- /dev/null +++ b/softfloat/s_roundToUI64.c @@ -0,0 +1,85 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t + softfloat_roundToUI64( + bool sign, + uint_fast64_t sig, + uint_fast64_t sigExtra, + uint_fast8_t roundingMode, + bool exact + ) +{ + bool roundNearEven, doIncrement; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); + doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + doIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + && sigExtra; + } + if ( doIncrement ) { + ++sig; + if ( ! sig ) goto invalid; + sig &= + ~(uint_fast64_t) + (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + & roundNearEven); + } + if ( sign && sig ) goto invalid; + if ( exact && sigExtra ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return sig; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + +} + diff --git a/softfloat/s_shiftRightJam128.c b/softfloat/s_shiftRightJam128.c index 4e8a88f..8d2b91e 100644 --- a/softfloat/s_shiftRightJam128.c +++ b/softfloat/s_shiftRightJam128.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -41,23 +41,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef softfloat_shiftRightJam128 struct uint128 - softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t count ) + softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t dist ) { - int_fast32_t negCount; + uint_fast8_t u8NegDist; struct uint128 z; - if ( count < 64 ) { - negCount = -count; - z.v64 = a64>>count; + if ( dist < 64 ) { + u8NegDist = -dist; + z.v64 = a64>>dist; z.v0 = - a64<<(negCount & 63) | a0>>count - | ((uint64_t) (a0<<(negCount & 63)) != 0); + a64<<(u8NegDist & 63) | a0>>dist + | ((uint64_t) (a0<<(u8NegDist & 63)) != 0); } else { z.v64 = 0; z.v0 = - (count < 127) - ? a64>>(count & 63) - | (((a64 & (((uint_fast64_t) 1<<(count & 63)) - 1)) | a0) + (dist < 127) + ? a64>>(dist & 63) + | (((a64 & (((uint_fast64_t) 1<<(dist & 63)) - 1)) | a0) != 0) : ((a64 | a0) != 0); } diff --git a/softfloat/s_shiftRightJam128Extra.c b/softfloat/s_shiftRightJam128Extra.c new file mode 100644 index 0000000..4e1293c --- /dev/null +++ b/softfloat/s_shiftRightJam128Extra.c @@ -0,0 +1,77 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shiftRightJam128Extra + +struct uint128_extra + softfloat_shiftRightJam128Extra( + uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist ) +{ + uint_fast8_t u8NegDist; + struct uint128_extra z; + + u8NegDist = -dist; + if ( dist < 64 ) { + z.v.v64 = a64>>dist; + z.v.v0 = a64<<(u8NegDist & 63) | a0>>dist; + z.extra = a0<<(u8NegDist & 63); + } else { + z.v.v64 = 0; + if ( dist == 64 ) { + z.v.v0 = a64; + z.extra = a0; + } else { + extra |= a0; + if ( dist < 128 ) { + z.v.v0 = a64>>(dist & 63); + z.extra = a64<<(u8NegDist & 63); + } else { + z.v.v0 = 0; + z.extra = (dist == 128) ? a64 : (a64 != 0); + } + } + } + z.extra |= (extra != 0); + return z; + +} + +#endif + diff --git a/softfloat/s_shiftRightJam256M.c b/softfloat/s_shiftRightJam256M.c new file mode 100644 index 0000000..04cd1e5 --- /dev/null +++ b/softfloat/s_shiftRightJam256M.c @@ -0,0 +1,126 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shiftRightJam256M + +static + void + softfloat_shortShiftRightJamM( + uint_fast8_t size_words, + const uint64_t *aPtr, + uint_fast8_t dist, + uint64_t *zPtr + ) +{ + uint_fast8_t uNegDist; + unsigned int index, lastIndex; + uint64_t partWordZ, wordA; + + uNegDist = -dist; + index = indexWordLo( size_words ); + lastIndex = indexWordHi( size_words ); + wordA = aPtr[index]; + partWordZ = wordA>>dist; + if ( partWordZ<<dist != wordA ) partWordZ |= 1; + while ( index != lastIndex ) { + wordA = aPtr[index + wordIncr]; + zPtr[index] = wordA<<(uNegDist & 63) | partWordZ; + index += wordIncr; + partWordZ = wordA>>dist; + } + zPtr[index] = partWordZ; + +} + +void + softfloat_shiftRightJam256M( + const uint64_t *aPtr, uint_fast32_t dist, uint64_t *zPtr ) +{ + uint64_t wordJam; + uint_fast32_t wordDist; + uint64_t *ptr; + uint_fast8_t i, innerDist; + + wordJam = 0; + wordDist = dist>>6; + if ( wordDist ) { + if ( 4 < wordDist ) wordDist = 4; + ptr = (uint64_t *) (aPtr + indexMultiwordLo( 4, wordDist )); + i = wordDist; + do { + wordJam = *ptr++; + if ( wordJam ) break; + --i; + } while ( i ); + ptr = zPtr; + } + if ( wordDist < 4 ) { + aPtr += indexMultiwordHiBut( 4, wordDist ); + innerDist = dist & 63; + if ( innerDist ) { + softfloat_shortShiftRightJamM( + 4 - wordDist, + aPtr, + innerDist, + zPtr + indexMultiwordLoBut( 4, wordDist ) + ); + if ( ! wordDist ) goto wordJam; + } else { + aPtr += indexWordLo( 4 - wordDist ); + ptr = zPtr + indexWordLo( 4 ); + for ( i = 4 - wordDist; i; --i ) { + *ptr = *aPtr; + aPtr += wordIncr; + ptr += wordIncr; + } + } + ptr = zPtr + indexMultiwordHi( 4, wordDist ); + } + do { + *ptr++ = 0; + --wordDist; + } while ( wordDist ); + wordJam: + if ( wordJam ) zPtr[indexWordLo( 4 )] |= 1; + +} + +#endif + diff --git a/softfloat/s_shiftRightJam32.c b/softfloat/s_shiftRightJam32.c index e1df875..fbc3aa0 100644 --- a/softfloat/s_shiftRightJam32.c +++ b/softfloat/s_shiftRightJam32.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -39,12 +39,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef softfloat_shiftRightJam32 -uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t count ) +uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist ) { return - (count < 31) ? a>>count | ((uint32_t) (a<<(-count & 31)) != 0) - : (a != 0); + (dist < 31) ? a>>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0); } diff --git a/softfloat/s_shiftRightJam64.c b/softfloat/s_shiftRightJam64.c index 876640d..34edd7b 100644 --- a/softfloat/s_shiftRightJam64.c +++ b/softfloat/s_shiftRightJam64.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -39,12 +39,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef softfloat_shiftRightJam64 -uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t count ) +uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist ) { return - (count < 63) ? a>>count | ((uint64_t) (a<<(-count & 63)) != 0) - : (a != 0); + (dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0); } diff --git a/softfloat/s_shiftRightJam64Extra.c b/softfloat/s_shiftRightJam64Extra.c index df31362..4d78712 100644 --- a/softfloat/s_shiftRightJam64Extra.c +++ b/softfloat/s_shiftRightJam64Extra.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -42,16 +42,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct uint64_extra softfloat_shiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast32_t count ) + uint64_t a, uint64_t extra, uint_fast32_t dist ) { struct uint64_extra z; - if ( count < 64 ) { - z.v = a>>count; - z.extra = a<<(-count & 63); + if ( dist < 64 ) { + z.v = a>>dist; + z.extra = a<<(-dist & 63); } else { z.v = 0; - z.extra = (count == 64) ? a : (a != 0); + z.extra = (dist == 64) ? a : (a != 0); } z.extra |= (extra != 0); return z; diff --git a/softfloat/s_shortShiftLeft128.c b/softfloat/s_shortShiftLeft128.c new file mode 100644 index 0000000..9b7c067 --- /dev/null +++ b/softfloat/s_shortShiftLeft128.c @@ -0,0 +1,55 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shortShiftLeft128 + +struct uint128 + softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist ) +{ + struct uint128 z; + + z.v64 = a64<<dist | a0>>(-dist & 63); + z.v0 = a0<<dist; + return z; + +} + +#endif + diff --git a/softfloat/s_shortShiftLeft64To96M.c b/softfloat/s_shortShiftLeft64To96M.c index 0053913..4caf4b9 100644 --- a/softfloat/s_shortShiftLeft64To96M.c +++ b/softfloat/s_shortShiftLeft64To96M.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -42,11 +42,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. void softfloat_shortShiftLeft64To96M( - uint64_t a, uint_fast8_t count, uint32_t *zPtr ) + uint64_t a, uint_fast8_t dist, uint32_t *zPtr ) { - zPtr[indexWord( 3, 0 )] = (uint32_t) a<<count; - a >>= 32 - count; + zPtr[indexWord( 3, 0 )] = (uint32_t) a<<dist; + a >>= 32 - dist; zPtr[indexWord( 3, 2 )] = a>>32; zPtr[indexWord( 3, 1 )] = a; diff --git a/softfloat/s_shortShiftRight128.c b/softfloat/s_shortShiftRight128.c new file mode 100644 index 0000000..28c39bb --- /dev/null +++ b/softfloat/s_shortShiftRight128.c @@ -0,0 +1,55 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shortShiftRight128 + +struct uint128 + softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist ) +{ + struct uint128 z; + + z.v64 = a64>>dist; + z.v0 = a64<<(-dist & 63) | a0>>dist; + return z; + +} + +#endif + diff --git a/softfloat/s_shortShiftRightExtendM.c b/softfloat/s_shortShiftRightExtendM.c index 513bf02..309188c 100644 --- a/softfloat/s_shortShiftRightExtendM.c +++ b/softfloat/s_shortShiftRightExtendM.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -44,24 +44,24 @@ void softfloat_shortShiftRightExtendM( uint_fast8_t size_words, const uint32_t *aPtr, - uint_fast8_t count, + uint_fast8_t dist, uint32_t *zPtr ) { - uint_fast8_t negCount; + uint_fast8_t uNegDist; unsigned int indexA, lastIndexA; uint32_t partWordZ, wordA; - negCount = -count; + uNegDist = -dist; indexA = indexWordLo( size_words ); lastIndexA = indexWordHi( size_words ); zPtr += indexWordLo( size_words + 1 ); partWordZ = 0; for (;;) { wordA = aPtr[indexA]; - *zPtr = wordA<<(negCount & 31) | partWordZ; + *zPtr = wordA<<(uNegDist & 31) | partWordZ; zPtr += wordIncr; - partWordZ = wordA>>count; + partWordZ = wordA>>dist; if ( indexA == lastIndexA ) break; indexA += wordIncr; } diff --git a/softfloat/s_shortShiftRightJam128.c b/softfloat/s_shortShiftRightJam128.c new file mode 100644 index 0000000..3eb0dd4 --- /dev/null +++ b/softfloat/s_shortShiftRightJam128.c @@ -0,0 +1,60 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shortShiftRightJam128 + +struct uint128 + softfloat_shortShiftRightJam128( + uint64_t a64, uint64_t a0, uint_fast8_t dist ) +{ + uint_fast8_t uNegDist; + struct uint128 z; + + uNegDist = -dist; + z.v64 = a64>>dist; + z.v0 = + a64<<(uNegDist & 63) | a0>>dist + | ((uint64_t) (a0<<(uNegDist & 63)) != 0); + return z; + +} + +#endif + diff --git a/softfloat/s_shortShiftRightJam128Extra.c b/softfloat/s_shortShiftRightJam128Extra.c new file mode 100644 index 0000000..13692a0 --- /dev/null +++ b/softfloat/s_shortShiftRightJam128Extra.c @@ -0,0 +1,59 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shortShiftRightJam128Extra + +struct uint128_extra + softfloat_shortShiftRightJam128Extra( + uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist ) +{ + uint_fast8_t uNegDist; + struct uint128_extra z; + + uNegDist = -dist; + z.v.v64 = a64>>dist; + z.v.v0 = a64<<(uNegDist & 63) | a0>>dist; + z.extra = a0<<(uNegDist & 63) | (extra != 0); + return z; + +} + +#endif + diff --git a/softfloat/s_shortShiftRightJam64.c b/softfloat/s_shortShiftRightJam64.c index 93c6f0a..7e93cd4 100644 --- a/softfloat/s_shortShiftRightJam64.c +++ b/softfloat/s_shortShiftRightJam64.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -39,10 +39,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef softfloat_shortShiftRightJam64 -uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t count ) +uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist ) { - return a>>count | ((a & (((uint_fast64_t) 1<<count) - 1)) != 0); + return a>>dist | ((a & (((uint_fast64_t) 1<<dist) - 1)) != 0); } diff --git a/softfloat/s_shortShiftRightJam64Extra.c b/softfloat/s_shortShiftRightJam64Extra.c index 2ca4d01..25d23f4 100644 --- a/softfloat/s_shortShiftRightJam64Extra.c +++ b/softfloat/s_shortShiftRightJam64Extra.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -42,12 +42,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct uint64_extra softfloat_shortShiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast8_t count ) + uint64_t a, uint64_t extra, uint_fast8_t dist ) { struct uint64_extra z; - z.v = a>>count; - z.extra = a<<(-count & 63) | (extra != 0); + z.v = a>>dist; + z.extra = a<<(-dist & 63) | (extra != 0); return z; } diff --git a/softfloat/s_shortShiftRightM.c b/softfloat/s_shortShiftRightM.c index ec61c25..308ad59 100644 --- a/softfloat/s_shortShiftRightM.c +++ b/softfloat/s_shortShiftRightM.c @@ -2,9 +2,9 @@ /*============================================================================ 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, 2015 The Regents of the University of +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 @@ -44,23 +44,23 @@ void softfloat_shortShiftRightM( uint_fast8_t size_words, const uint32_t *aPtr, - uint_fast8_t count, + uint_fast8_t dist, uint32_t *zPtr ) { - uint_fast8_t negCount; + uint_fast8_t uNegDist; unsigned int index, lastIndex; uint32_t partWordZ, wordA; - negCount = -count; + uNegDist = -dist; index = indexWordLo( size_words ); lastIndex = indexWordHi( size_words ); - partWordZ = aPtr[index]>>count; + partWordZ = aPtr[index]>>dist; while ( index != lastIndex ) { wordA = aPtr[index + wordIncr]; - zPtr[index] = wordA<<(negCount & 31) | partWordZ; + zPtr[index] = wordA<<(uNegDist & 31) | partWordZ; index += wordIncr; - partWordZ = wordA>>count; + partWordZ = wordA>>dist; } zPtr[index] = partWordZ; diff --git a/softfloat/s_sub128.c b/softfloat/s_sub128.c index 7659b40..ed86e10 100644 --- a/softfloat/s_sub128.c +++ b/softfloat/s_sub128.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. diff --git a/softfloat/s_shortShiftRightJamM.c b/softfloat/s_sub1XM.c index 9aeba80..73773e5 100644 --- a/softfloat/s_shortShiftRightJamM.c +++ b/softfloat/s_sub1XM.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. @@ -38,33 +38,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.h" #include "primitiveTypes.h" -#ifndef softfloat_shortShiftRightJamM +#ifndef softfloat_sub1XM -void - softfloat_shortShiftRightJamM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint_fast8_t count, - uint32_t *zPtr - ) +void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr ) { - uint_fast8_t negCount; unsigned int index, lastIndex; - uint32_t partWordZ, wordA; + uint32_t wordA; - negCount = -count; index = indexWordLo( size_words ); lastIndex = indexWordHi( size_words ); - wordA = aPtr[index]; - partWordZ = wordA>>count; - if ( partWordZ<<count != wordA ) partWordZ |= 1; - while ( index != lastIndex ) { - wordA = aPtr[index + wordIncr]; - zPtr[index] = wordA<<(negCount & 31) | partWordZ; + for (;;) { + wordA = zPtr[index]; + zPtr[index] = wordA - 1; + if ( wordA || (index == lastIndex) ) break; index += wordIncr; - partWordZ = wordA>>count; } - zPtr[index] = partWordZ; } diff --git a/softfloat/s_sub256M.c b/softfloat/s_sub256M.c new file mode 100644 index 0000000..c07b45e --- /dev/null +++ b/softfloat/s_sub256M.c @@ -0,0 +1,65 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_sub256M + +void + softfloat_sub256M( + const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr ) +{ + unsigned int index; + uint_fast8_t borrow; + uint64_t wordA, wordB; + + index = indexWordLo( 4 ); + borrow = 0; + for (;;) { + wordA = aPtr[index]; + wordB = bPtr[index]; + zPtr[index] = wordA - wordB - borrow; + if ( index == indexWordHi( 4 ) ) break; + borrow = borrow ? (wordA <= wordB) : (wordA < wordB); + index += wordIncr; + } + +} + +#endif + diff --git a/softfloat/s_subM.c b/softfloat/s_subM.c index df984d0..003f699 100644 --- a/softfloat/s_subM.c +++ b/softfloat/s_subM.c @@ -2,7 +2,7 @@ /*============================================================================ 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, 2015 The Regents of the University of California. All rights reserved. diff --git a/softfloat/s_subMagsF128.c b/softfloat/s_subMagsF128.c new file mode 100644 index 0000000..c4264d5 --- /dev/null +++ b/softfloat/s_subMagsF128.c @@ -0,0 +1,139 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float128_t + softfloat_subMagsF128( + uint_fast64_t uiA64, + uint_fast64_t uiA0, + uint_fast64_t uiB64, + uint_fast64_t uiB0, + bool signZ + ) +{ + int_fast32_t expA; + struct uint128 sigA; + int_fast32_t expB; + struct uint128 sigB, sigZ; + int_fast32_t expDiff, expZ; + struct uint128 uiZ; + union ui128_f128 uZ; + + expA = expF128UI64( uiA64 ); + sigA.v64 = fracF128UI64( uiA64 ); + sigA.v0 = uiA0; + expB = expF128UI64( uiB64 ); + sigB.v64 = fracF128UI64( uiB64 ); + sigB.v0 = uiB0; + sigA = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 4 ); + sigB = softfloat_shortShiftLeft128( sigB.v64, sigB.v0, 4 ); + expDiff = expA - expB; + if ( 0 < expDiff ) goto expABigger; + if ( expDiff < 0 ) goto expBBigger; + if ( expA == 0x7FFF ) { + if ( sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0 ) goto propagateNaN; + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + goto uiZ; + } + expZ = expA; + if ( ! expZ ) expZ = 1; + if ( sigB.v64 < sigA.v64 ) goto aBigger; + if ( sigA.v64 < sigB.v64 ) goto bBigger; + if ( sigB.v0 < sigA.v0 ) goto aBigger; + if ( sigA.v0 < sigB.v0 ) goto bBigger; + uiZ.v64 = + packToF128UI64( + (softfloat_roundingMode == softfloat_round_min), 0, 0 ); + uiZ.v0 = 0; + goto uiZ; + expBBigger: + if ( expB == 0x7FFF ) { + if ( sigB.v64 | sigB.v0 ) goto propagateNaN; + uiZ.v64 = packToF128UI64( signZ ^ 1, 0x7FFF, 0 ); + uiZ.v0 = 0; + goto uiZ; + } + if ( expA ) { + sigA.v64 |= UINT64_C( 0x0010000000000000 ); + } else { + ++expDiff; + if ( ! expDiff ) goto newlyAlignedBBigger; + } + sigA = softfloat_shiftRightJam128( sigA.v64, sigA.v0, -expDiff ); + newlyAlignedBBigger: + expZ = expB; + sigB.v64 |= UINT64_C( 0x0010000000000000 ); + bBigger: + signZ = ! signZ; + sigZ = softfloat_sub128( sigB.v64, sigB.v0, sigA.v64, sigA.v0 ); + goto normRoundPack; + expABigger: + if ( expA == 0x7FFF ) { + if ( sigA.v64 | sigA.v0 ) goto propagateNaN; + uiZ.v64 = uiA64; + uiZ.v0 = uiA0; + goto uiZ; + } + if ( expB ) { + sigB.v64 |= UINT64_C( 0x0010000000000000 ); + } else { + --expDiff; + if ( ! expDiff ) goto newlyAlignedABigger; + } + sigB = softfloat_shiftRightJam128( sigB.v64, sigB.v0, expDiff ); + newlyAlignedABigger: + expZ = expA; + sigA.v64 |= UINT64_C( 0x0010000000000000 ); + aBigger: + sigZ = softfloat_sub128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 ); + normRoundPack: + return softfloat_normRoundPackToF128( signZ, expZ - 5, sigZ.v64, sigZ.v0 ); + propagateNaN: + uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/s_subMagsF16.c b/softfloat/s_subMagsF16.c new file mode 100644 index 0000000..5ec579e --- /dev/null +++ b/softfloat/s_subMagsF16.c @@ -0,0 +1,187 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdbool.h> +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float16_t softfloat_subMagsF16( uint_fast16_t uiA, uint_fast16_t uiB ) +{ + int_fast8_t expA; + uint_fast16_t sigA; + int_fast8_t expB; + uint_fast16_t sigB; + int_fast8_t expDiff; + uint_fast16_t uiZ; + int_fast16_t sigDiff; + bool signZ; + int_fast8_t shiftDist, expZ; + uint_fast16_t sigZ, sigX, sigY; + uint_fast32_t sig32Z; + int_fast8_t roundingMode; + union ui16_f16 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expA = expF16UI( uiA ); + sigA = fracF16UI( uiA ); + expB = expF16UI( uiB ); + sigB = fracF16UI( uiB ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if ( ! expDiff ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( expA == 0x1F ) { + if ( sigA | sigB ) goto propagateNaN; + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF16UI; + goto uiZ; + } + sigDiff = sigA - sigB; + if ( ! sigDiff ) { + uiZ = + packToF16UI( + (softfloat_roundingMode == softfloat_round_min), 0, 0 ); + goto uiZ; + } + if ( expA ) --expA; + signZ = signF16UI( uiA ); + if ( sigDiff < 0 ) { + signZ = ! signZ; + sigDiff = -sigDiff; + } + shiftDist = softfloat_countLeadingZeros16( sigDiff ) - 5; + expZ = expA - shiftDist; + if ( expZ < 0 ) { + shiftDist = expA; + expZ = 0; + } + sigZ = sigDiff<<shiftDist; + goto pack; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + signZ = signF16UI( uiA ); + if ( expDiff < 0 ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + signZ = ! signZ; + if ( expB == 0x1F ) { + if ( sigB ) goto propagateNaN; + uiZ = packToF16UI( signZ, 0x1F, 0 ); + goto uiZ; + } + if ( expDiff <= -13 ) { + uiZ = packToF16UI( signZ, expB, sigB ); + if ( expA | sigA ) goto subEpsilon; + goto uiZ; + } + expZ = expA + 19; + sigX = sigB | 0x0400; + sigY = sigA + (expA ? 0x0400 : sigA); + expDiff = -expDiff; + } else { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + uiZ = uiA; + if ( expA == 0x1F ) { + if ( sigA ) goto propagateNaN; + goto uiZ; + } + if ( 13 <= expDiff ) { + if ( expB | sigB ) goto subEpsilon; + goto uiZ; + } + expZ = expB + 19; + sigX = sigA | 0x0400; + sigY = sigB + (expB ? 0x0400 : sigB); + } + sig32Z = ((uint_fast32_t) sigX<<expDiff) - sigY; + shiftDist = softfloat_countLeadingZeros32( sig32Z ) - 1; + sig32Z <<= shiftDist; + expZ -= shiftDist; + sigZ = sig32Z>>16; + if ( sig32Z & 0xFFFF ) { + sigZ |= 1; + } else { + if ( ! (sigZ & 0xF) && ((unsigned int) expZ < 0x1E) ) { + sigZ >>= 4; + goto pack; + } + } + return softfloat_roundPackToF16( signZ, expZ, sigZ ); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + subEpsilon: + roundingMode = softfloat_roundingMode; + if ( roundingMode != softfloat_round_near_even ) { + if ( + (roundingMode == softfloat_round_minMag) + || (roundingMode + == (signF16UI( uiZ ) ? softfloat_round_max + : softfloat_round_min)) + ) { + --uiZ; + } +#ifdef SOFTFLOAT_ROUND_ODD + else if ( roundingMode == softfloat_round_odd ) { + uiZ = (uiZ - 1) | 1; + } +#endif + } + softfloat_exceptionFlags |= softfloat_flag_inexact; + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + pack: + uiZ = packToF16UI( signZ, expZ, sigZ ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/s_subMagsF32.c b/softfloat/s_subMagsF32.c index ba5ac9a..86e89f2 100644 --- a/softfloat/s_subMagsF32.c +++ b/softfloat/s_subMagsF32.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: @@ -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: diff --git a/softfloat/s_subMagsF64.c b/softfloat/s_subMagsF64.c index e499d98..5ef9ea4 100644 --- a/softfloat/s_subMagsF64.c +++ b/softfloat/s_subMagsF64.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: @@ -50,61 +50,87 @@ float64_t uint_fast64_t sigB; int_fast16_t expDiff; uint_fast64_t uiZ; + int_fast64_t sigDiff; + int_fast8_t shiftDist; int_fast16_t expZ; uint_fast64_t sigZ; union ui64_f64 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ expA = expF64UI( uiA ); sigA = fracF64UI( uiA ); expB = expF64UI( uiB ); sigB = fracF64UI( uiB ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ expDiff = expA - expB; - sigA <<= 10; - sigB <<= 10; - if ( 0 < expDiff ) goto expABigger; - if ( expDiff < 0 ) goto expBBigger; - if ( expA == 0x7FF ) { - if ( sigA | sigB ) goto propagateNaN; - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; + if ( ! expDiff ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( expA == 0x7FF ) { + if ( sigA | sigB ) goto propagateNaN; + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF64UI; + goto uiZ; + } + sigDiff = sigA - sigB; + if ( ! sigDiff ) { + uiZ = + packToF64UI( + (softfloat_roundingMode == softfloat_round_min), 0, 0 ); + goto uiZ; + } + if ( expA ) --expA; + if ( sigDiff < 0 ) { + signZ = ! signZ; + sigDiff = -sigDiff; + } + shiftDist = softfloat_countLeadingZeros64( sigDiff ) - 11; + expZ = expA - shiftDist; + if ( expZ < 0 ) { + shiftDist = expA; + expZ = 0; + } + uiZ = packToF64UI( signZ, expZ, sigDiff<<shiftDist ); goto uiZ; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sigA <<= 10; + sigB <<= 10; + if ( expDiff < 0 ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + signZ = ! signZ; + if ( expB == 0x7FF ) { + if ( sigB ) goto propagateNaN; + uiZ = packToF64UI( signZ, 0x7FF, 0 ); + goto uiZ; + } + sigA += expA ? UINT64_C( 0x4000000000000000 ) : sigA; + sigA = softfloat_shiftRightJam64( sigA, -expDiff ); + sigB |= UINT64_C( 0x4000000000000000 ); + expZ = expB; + sigZ = sigB - sigA; + } else { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ + if ( expA == 0x7FF ) { + if ( sigA ) goto propagateNaN; + uiZ = uiA; + goto uiZ; + } + sigB += expB ? UINT64_C( 0x4000000000000000 ) : sigB; + sigB = softfloat_shiftRightJam64( sigB, expDiff ); + sigA |= UINT64_C( 0x4000000000000000 ); + expZ = expA; + sigZ = sigA - sigB; + } + return softfloat_normRoundPackToF64( signZ, expZ - 1, sigZ ); } - if ( ! expA ) { - expA = 1; - expB = 1; - } - if ( sigB < sigA ) goto aBigger; - if ( sigA < sigB ) goto bBigger; - uiZ = packToF64UI( softfloat_roundingMode == softfloat_round_min, 0, 0 ); - goto uiZ; - expBBigger: - if ( expB == 0x7FF ) { - if ( sigB ) goto propagateNaN; - uiZ = packToF64UI( signZ ^ 1, 0x7FF, 0 ); - goto uiZ; - } - sigA += expA ? UINT64_C( 0x4000000000000000 ) : sigA; - sigA = softfloat_shiftRightJam64( sigA, -expDiff ); - sigB |= UINT64_C( 0x4000000000000000 ); - bBigger: - signZ ^= 1; - expZ = expB; - sigZ = sigB - sigA; - goto normRoundPack; - expABigger: - if ( expA == 0x7FF ) { - if ( sigA ) goto propagateNaN; - uiZ = uiA; - goto uiZ; - } - sigB += expB ? UINT64_C( 0x4000000000000000 ) : sigB; - sigB = softfloat_shiftRightJam64( sigB, expDiff ); - sigA |= UINT64_C( 0x4000000000000000 ); - aBigger: - expZ = expA; - sigZ = sigA - sigB; - normRoundPack: - return softfloat_normRoundPackToF64( signZ, expZ - 1, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); uiZ: diff --git a/softfloat/softfloat.h b/softfloat/softfloat.h index 45ff0cf..b277281 100644 --- a/softfloat/softfloat.h +++ b/softfloat/softfloat.h @@ -2,10 +2,10 @@ /*============================================================================ This C header 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, 2017 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: @@ -46,40 +46,45 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef softfloat_h #define softfloat_h 1 -#ifdef __cplusplus -extern "C" { -#endif - #include <stdbool.h> #include <stdint.h> - #include "softfloat_types.h" +#ifndef THREAD_LOCAL +#define THREAD_LOCAL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + /*---------------------------------------------------------------------------- | Software floating-point underflow tininess-detection mode. *----------------------------------------------------------------------------*/ -extern uint_fast8_t softfloat_detectTininess; +extern THREAD_LOCAL uint_fast8_t softfloat_detectTininess; enum { softfloat_tininess_beforeRounding = 0, softfloat_tininess_afterRounding = 1 }; /*---------------------------------------------------------------------------- -| Software floating-point rounding mode. +| Software floating-point rounding mode. (Mode "odd" is supported only if +| SoftFloat is compiled with macro 'SOFTFLOAT_ROUND_ODD' defined.) *----------------------------------------------------------------------------*/ -extern uint_fast8_t softfloat_roundingMode; +extern THREAD_LOCAL uint_fast8_t softfloat_roundingMode; enum { softfloat_round_near_even = 0, softfloat_round_minMag = 1, softfloat_round_min = 2, softfloat_round_max = 3, - softfloat_round_near_maxMag = 4 + softfloat_round_near_maxMag = 4, + softfloat_round_odd = 5 }; /*---------------------------------------------------------------------------- | Software floating-point exception flags. *----------------------------------------------------------------------------*/ -extern uint_fast8_t softfloat_exceptionFlags; +extern THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags; enum { softfloat_flag_inexact = 1, softfloat_flag_underflow = 2, @@ -96,6 +101,7 @@ void softfloat_raiseFlags( uint_fast8_t ); /*---------------------------------------------------------------------------- | Integer-to-floating-point conversion routines. *----------------------------------------------------------------------------*/ +float16_t ui32_to_f16( uint32_t ); float32_t ui32_to_f32( uint32_t ); float64_t ui32_to_f64( uint32_t ); #ifdef SOFTFLOAT_FAST_INT64 @@ -104,6 +110,7 @@ float128_t ui32_to_f128( uint32_t ); #endif void ui32_to_extF80M( uint32_t, extFloat80_t * ); void ui32_to_f128M( uint32_t, float128_t * ); +float16_t ui64_to_f16( uint64_t ); float32_t ui64_to_f32( uint64_t ); float64_t ui64_to_f64( uint64_t ); #ifdef SOFTFLOAT_FAST_INT64 @@ -112,6 +119,7 @@ float128_t ui64_to_f128( uint64_t ); #endif void ui64_to_extF80M( uint64_t, extFloat80_t * ); void ui64_to_f128M( uint64_t, float128_t * ); +float16_t i32_to_f16( int32_t ); float32_t i32_to_f32( int32_t ); float64_t i32_to_f64( int32_t ); #ifdef SOFTFLOAT_FAST_INT64 @@ -120,6 +128,7 @@ float128_t i32_to_f128( int32_t ); #endif void i32_to_extF80M( int32_t, extFloat80_t * ); void i32_to_f128M( int32_t, float128_t * ); +float16_t i64_to_f16( int64_t ); float32_t i64_to_f32( int64_t ); float64_t i64_to_f64( int64_t ); #ifdef SOFTFLOAT_FAST_INT64 @@ -130,6 +139,41 @@ void i64_to_extF80M( int64_t, extFloat80_t * ); void i64_to_f128M( int64_t, float128_t * ); /*---------------------------------------------------------------------------- +| 16-bit (half-precision) floating-point operations. +*----------------------------------------------------------------------------*/ +uint_fast32_t f16_to_ui32( float16_t, uint_fast8_t, bool ); +uint_fast64_t f16_to_ui64( float16_t, uint_fast8_t, bool ); +int_fast32_t f16_to_i32( float16_t, uint_fast8_t, bool ); +int_fast64_t f16_to_i64( float16_t, uint_fast8_t, bool ); +uint_fast32_t f16_to_ui32_r_minMag( float16_t, bool ); +uint_fast64_t f16_to_ui64_r_minMag( float16_t, bool ); +int_fast32_t f16_to_i32_r_minMag( float16_t, bool ); +int_fast64_t f16_to_i64_r_minMag( float16_t, bool ); +float32_t f16_to_f32( float16_t ); +float64_t f16_to_f64( float16_t ); +#ifdef SOFTFLOAT_FAST_INT64 +extFloat80_t f16_to_extF80( float16_t ); +float128_t f16_to_f128( float16_t ); +#endif +void f16_to_extF80M( float16_t, extFloat80_t * ); +void f16_to_f128M( float16_t, float128_t * ); +float16_t f16_roundToInt( float16_t, uint_fast8_t, bool ); +float16_t f16_add( float16_t, float16_t ); +float16_t f16_sub( float16_t, float16_t ); +float16_t f16_mul( float16_t, float16_t ); +float16_t f16_mulAdd( float16_t, float16_t, float16_t ); +float16_t f16_div( float16_t, float16_t ); +float16_t f16_rem( float16_t, float16_t ); +float16_t f16_sqrt( float16_t ); +bool f16_eq( float16_t, float16_t ); +bool f16_le( float16_t, float16_t ); +bool f16_lt( float16_t, float16_t ); +bool f16_eq_signaling( float16_t, float16_t ); +bool f16_le_quiet( float16_t, float16_t ); +bool f16_lt_quiet( float16_t, float16_t ); +bool f16_isSignalingNaN( float16_t ); + +/*---------------------------------------------------------------------------- | 32-bit (single-precision) floating-point operations. *----------------------------------------------------------------------------*/ uint_fast32_t f32_to_ui32( float32_t, uint_fast8_t, bool ); @@ -140,6 +184,7 @@ uint_fast32_t f32_to_ui32_r_minMag( float32_t, bool ); uint_fast64_t f32_to_ui64_r_minMag( float32_t, bool ); int_fast32_t f32_to_i32_r_minMag( float32_t, bool ); int_fast64_t f32_to_i64_r_minMag( float32_t, bool ); +float16_t f32_to_f16( float32_t ); float64_t f32_to_f64( float32_t ); #ifdef SOFTFLOAT_FAST_INT64 extFloat80_t f32_to_extF80( float32_t ); @@ -175,6 +220,7 @@ uint_fast32_t f64_to_ui32_r_minMag( float64_t, bool ); uint_fast64_t f64_to_ui64_r_minMag( float64_t, bool ); int_fast32_t f64_to_i32_r_minMag( float64_t, bool ); int_fast64_t f64_to_i64_r_minMag( float64_t, bool ); +float16_t f64_to_f16( float64_t ); float32_t f64_to_f32( float64_t ); #ifdef SOFTFLOAT_FAST_INT64 extFloat80_t f64_to_extF80( float64_t ); @@ -203,7 +249,7 @@ uint_fast16_t f64_classify( float64_t ); | Rounding precision for 80-bit extended double-precision floating-point. | Valid values are 32, 64, and 80. *----------------------------------------------------------------------------*/ -extern uint_fast8_t extF80_roundingPrecision; +extern THREAD_LOCAL uint_fast8_t extF80_roundingPrecision; /*---------------------------------------------------------------------------- | 80-bit extended double-precision floating-point operations. @@ -217,6 +263,7 @@ uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t, bool ); uint_fast64_t extF80_to_ui64_r_minMag( extFloat80_t, bool ); int_fast32_t extF80_to_i32_r_minMag( extFloat80_t, bool ); int_fast64_t extF80_to_i64_r_minMag( extFloat80_t, bool ); +float16_t extF80_to_f16( extFloat80_t ); float32_t extF80_to_f32( extFloat80_t ); float64_t extF80_to_f64( extFloat80_t ); float128_t extF80_to_f128( extFloat80_t ); @@ -243,6 +290,7 @@ uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *, bool ); uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *, bool ); int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *, bool ); int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *, bool ); +float16_t extF80M_to_f16( const extFloat80_t * ); float32_t extF80M_to_f32( const extFloat80_t * ); float64_t extF80M_to_f64( const extFloat80_t * ); void extF80M_to_f128M( const extFloat80_t *, float128_t * ); @@ -275,6 +323,7 @@ uint_fast32_t f128_to_ui32_r_minMag( float128_t, bool ); uint_fast64_t f128_to_ui64_r_minMag( float128_t, bool ); int_fast32_t f128_to_i32_r_minMag( float128_t, bool ); int_fast64_t f128_to_i64_r_minMag( float128_t, bool ); +float16_t f128_to_f16( float128_t ); float32_t f128_to_f32( float128_t ); float64_t f128_to_f64( float128_t ); extFloat80_t f128_to_extF80( float128_t ); @@ -293,6 +342,7 @@ bool f128_eq_signaling( float128_t, float128_t ); bool f128_le_quiet( float128_t, float128_t ); bool f128_lt_quiet( float128_t, float128_t ); bool f128_isSignalingNaN( float128_t ); +uint_fast16_t f128_classify( float128_t ); #endif uint_fast32_t f128M_to_ui32( const float128_t *, uint_fast8_t, bool ); uint_fast64_t f128M_to_ui64( const float128_t *, uint_fast8_t, bool ); @@ -302,6 +352,7 @@ uint_fast32_t f128M_to_ui32_r_minMag( const float128_t *, bool ); uint_fast64_t f128M_to_ui64_r_minMag( const float128_t *, bool ); int_fast32_t f128M_to_i32_r_minMag( const float128_t *, bool ); int_fast64_t f128M_to_i64_r_minMag( const float128_t *, bool ); +float16_t f128M_to_f16( const float128_t * ); float32_t f128M_to_f32( const float128_t * ); float64_t f128M_to_f64( const float128_t * ); void f128M_to_extF80M( const float128_t *, extFloat80_t * ); diff --git a/softfloat/softfloat.mk.in b/softfloat/softfloat.mk.in index e373df1..77c1357 100644 --- a/softfloat/softfloat.mk.in +++ b/softfloat/softfloat.mk.in @@ -9,116 +9,220 @@ softfloat_hdrs = \ specialize.h \ softfloat_c_srcs = \ - f32_add.c \ - f32_classify.c \ - f32_div.c \ - f32_eq.c \ - f32_eq_signaling.c \ - f32_isSignalingNaN.c \ - f32_le.c \ - f32_le_quiet.c \ - f32_lt.c \ - f32_lt_quiet.c \ - f32_mulAdd.c \ - f32_mul.c \ - f32_rem.c \ - f32_roundToInt.c \ - f32_sqrt.c \ - f32_sub.c \ - f32_to_f64.c \ - f32_to_i32.c \ - f32_to_i32_r_minMag.c \ - f32_to_i64.c \ - f32_to_i64_r_minMag.c \ - f32_to_ui32.c \ - f32_to_ui32_r_minMag.c \ - f32_to_ui64.c \ - f32_to_ui64_r_minMag.c \ - f64_add.c \ - f64_classify.c \ - f64_div.c \ - f64_eq.c \ - f64_eq_signaling.c \ - f64_isSignalingNaN.c \ - f64_le.c \ - f64_le_quiet.c \ - f64_lt.c \ - f64_lt_quiet.c \ - f64_mulAdd.c \ - f64_mul.c \ - f64_rem.c \ - f64_roundToInt.c \ - f64_sqrt.c \ - f64_sub.c \ - f64_to_f32.c \ - f64_to_i32.c \ - f64_to_i32_r_minMag.c \ - f64_to_i64.c \ - f64_to_i64_r_minMag.c \ - f64_to_ui32.c \ - f64_to_ui32_r_minMag.c \ - f64_to_ui64.c \ - f64_to_ui64_r_minMag.c \ - i32_to_f32.c \ - i32_to_f64.c \ - i64_to_f32.c \ - i64_to_f64.c \ - s_add128.c \ - s_addCarryM.c \ - s_addComplCarryM.c \ - s_addMagsF32.c \ - s_addMagsF64.c \ - s_addM.c \ - s_approxRecip32_1.c \ - s_approxRecipSqrt32_1.c \ - s_commonNaNToF32UI.c \ - s_commonNaNToF64UI.c \ - s_compare96M.c \ - s_countLeadingZeros32.c \ - s_countLeadingZeros64.c \ - s_countLeadingZeros8.c \ - s_f32UIToCommonNaN.c \ - s_f64UIToCommonNaN.c \ - s_mul64To128.c \ - s_mulAddF32.c \ - s_mulAddF64.c \ - s_negXM.c \ - s_normRoundPackToF32.c \ - s_normRoundPackToF64.c \ - s_normSubnormalF32Sig.c \ - s_normSubnormalF64Sig.c \ - softfloat_raiseFlags.c \ - softfloat_state.c \ - s_propagateNaNF32UI.c \ - s_propagateNaNF64UI.c \ - s_remStepMBy32.c \ - s_roundPackMToI64.c \ - s_roundPackMToUI64.c \ - s_roundPackToF32.c \ - s_roundPackToF64.c \ - s_roundPackToI32.c \ - s_roundPackToI64.c \ - s_roundPackToUI32.c \ - s_roundPackToUI64.c \ - s_shiftRightJam128.c \ - s_shiftRightJam32.c \ - s_shiftRightJam64.c \ - s_shiftRightJam64Extra.c \ - s_shortShiftLeft64To96M.c \ - s_shortShiftLeftM.c \ - s_shortShiftRightExtendM.c \ - s_shortShiftRightJam64.c \ - s_shortShiftRightJam64Extra.c \ - s_shortShiftRightJamM.c \ - s_shortShiftRightM.c \ - s_sub128.c \ - s_subMagsF32.c \ - s_subMagsF64.c \ - s_subM.c \ - ui32_to_f32.c \ - ui32_to_f64.c \ - ui64_to_f32.c \ - ui64_to_f64.c \ + f128_add.c \ + f128_classify.c \ + f128_div.c \ + f128_eq.c \ + f128_eq_signaling.c \ + f128_isSignalingNaN.c \ + f128_le.c \ + f128_le_quiet.c \ + f128_lt.c \ + f128_lt_quiet.c \ + f128_mulAdd.c \ + f128_mul.c \ + f128_rem.c \ + f128_roundToInt.c \ + f128_sqrt.c \ + f128_sub.c \ + f128_to_f16.c \ + f128_to_f32.c \ + f128_to_f64.c \ + f128_to_i32.c \ + f128_to_i32_r_minMag.c \ + f128_to_i64.c \ + f128_to_i64_r_minMag.c \ + f128_to_ui32.c \ + f128_to_ui32_r_minMag.c \ + f128_to_ui64.c \ + f128_to_ui64_r_minMag.c \ + f16_add.c \ + f16_div.c \ + f16_eq.c \ + f16_eq_signaling.c \ + f16_isSignalingNaN.c \ + f16_le.c \ + f16_le_quiet.c \ + f16_lt.c \ + f16_lt_quiet.c \ + f16_mulAdd.c \ + f16_mul.c \ + f16_rem.c \ + f16_roundToInt.c \ + f16_sqrt.c \ + f16_sub.c \ + f16_to_f128.c \ + f16_to_f32.c \ + f16_to_f64.c \ + f16_to_i32.c \ + f16_to_i32_r_minMag.c \ + f16_to_i64.c \ + f16_to_i64_r_minMag.c \ + f16_to_ui32.c \ + f16_to_ui32_r_minMag.c \ + f16_to_ui64.c \ + f16_to_ui64_r_minMag.c \ + f32_add.c \ + f32_classify.c \ + f32_div.c \ + f32_eq.c \ + f32_eq_signaling.c \ + f32_isSignalingNaN.c \ + f32_le.c \ + f32_le_quiet.c \ + f32_lt.c \ + f32_lt_quiet.c \ + f32_mulAdd.c \ + f32_mul.c \ + f32_rem.c \ + f32_roundToInt.c \ + f32_sqrt.c \ + f32_sub.c \ + f32_to_f128.c \ + f32_to_f16.c \ + f32_to_f64.c \ + f32_to_i32.c \ + f32_to_i32_r_minMag.c \ + f32_to_i64.c \ + f32_to_i64_r_minMag.c \ + f32_to_ui32.c \ + f32_to_ui32_r_minMag.c \ + f32_to_ui64.c \ + f32_to_ui64_r_minMag.c \ + f64_add.c \ + f64_classify.c \ + f64_div.c \ + f64_eq.c \ + f64_eq_signaling.c \ + f64_isSignalingNaN.c \ + f64_le.c \ + f64_le_quiet.c \ + f64_lt.c \ + f64_lt_quiet.c \ + f64_mulAdd.c \ + f64_mul.c \ + f64_rem.c \ + f64_roundToInt.c \ + f64_sqrt.c \ + f64_sub.c \ + f64_to_f128.c \ + f64_to_f16.c \ + f64_to_f32.c \ + f64_to_i32.c \ + f64_to_i32_r_minMag.c \ + f64_to_i64.c \ + f64_to_i64_r_minMag.c \ + f64_to_ui32.c \ + f64_to_ui32_r_minMag.c \ + f64_to_ui64.c \ + f64_to_ui64_r_minMag.c \ + i32_to_f128.c \ + i32_to_f16.c \ + i32_to_f32.c \ + i32_to_f64.c \ + i64_to_f128.c \ + i64_to_f16.c \ + i64_to_f32.c \ + i64_to_f64.c \ + s_add128.c \ + s_add256M.c \ + s_addCarryM.c \ + s_addComplCarryM.c \ + s_addMagsF128.c \ + s_addMagsF16.c \ + s_addMagsF32.c \ + s_addMagsF64.c \ + s_addM.c \ + s_approxRecip_1Ks.c \ + s_approxRecip32_1.c \ + s_approxRecipSqrt_1Ks.c \ + s_approxRecipSqrt32_1.c \ + s_commonNaNToF32UI.c \ + s_commonNaNToF64UI.c \ + s_compare128M.c \ + s_compare96M.c \ + s_countLeadingZeros16.c \ + s_countLeadingZeros32.c \ + s_countLeadingZeros64.c \ + s_countLeadingZeros8.c \ + s_eq128.c \ + s_f32UIToCommonNaN.c \ + s_f64UIToCommonNaN.c \ + s_le128.c \ + s_lt128.c \ + s_mul128By32.c \ + s_mul128MTo256M.c \ + s_mul128To256M.c \ + s_mul64ByShifted32To128.c \ + s_mul64To128.c \ + s_mul64To128M.c \ + s_mulAddF128.c \ + s_mulAddF16.c \ + s_mulAddF32.c \ + s_mulAddF64.c \ + s_negXM.c \ + s_normRoundPackToF128.c \ + s_normRoundPackToF16.c \ + s_normRoundPackToF32.c \ + s_normRoundPackToF64.c \ + s_normSubnormalF128Sig.c \ + s_normSubnormalF16Sig.c \ + s_normSubnormalF32Sig.c \ + s_normSubnormalF64Sig.c \ + softfloat_raiseFlags.c \ + softfloat_state.c \ + s_propagateNaNF16UI.c \ + s_propagateNaNF32UI.c \ + s_propagateNaNF64UI.c \ + s_propagateNaNF128UI.c \ + s_remStepMBy32.c \ + s_roundMToI64.c \ + s_roundMToUI64.c \ + s_roundPackMToI64.c \ + s_roundPackMToUI64.c \ + s_roundPackToF128.c \ + s_roundPackToF16.c \ + s_roundPackToF32.c \ + s_roundPackToF64.c \ + s_roundPackToI32.c \ + s_roundPackToI64.c \ + s_roundPackToUI32.c \ + s_roundPackToUI64.c \ + s_roundToI32.c \ + s_roundToI64.c \ + s_roundToUI32.c \ + s_roundToUI64.c \ + s_shiftRightJam128.c \ + s_shiftRightJam128Extra.c \ + s_shiftRightJam256M.c \ + s_shiftRightJam32.c \ + s_shiftRightJam64.c \ + s_shiftRightJam64Extra.c \ + s_shortShiftLeft128.c \ + s_shortShiftLeft64To96M.c \ + s_shortShiftRight128.c \ + s_shortShiftRightExtendM.c \ + s_shortShiftRightJam128.c \ + s_shortShiftRightJam128Extra.c \ + s_shortShiftRightJam64.c \ + s_shortShiftRightJam64Extra.c \ + s_shortShiftRightM.c \ + s_sub128.c \ + s_sub1XM.c \ + s_sub256M.c \ + s_subMagsF128.c \ + s_subMagsF16.c \ + s_subMagsF32.c \ + s_subMagsF64.c \ + s_subM.c \ + ui32_to_f128.c \ + ui32_to_f16.c \ + ui32_to_f32.c \ + ui32_to_f64.c \ + ui64_to_f128.c \ + ui64_to_f16.c \ + ui64_to_f32.c \ + ui64_to_f64.c \ softfloat_test_srcs = diff --git a/softfloat/softfloat_raiseFlags.c b/softfloat/softfloat_raiseFlags.c index 7b5ba25..f2c25ad 100644 --- a/softfloat/softfloat_raiseFlags.c +++ b/softfloat/softfloat_raiseFlags.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/softfloat_state.c b/softfloat/softfloat_state.c index d93087d..a105e6f 100644 --- a/softfloat/softfloat_state.c +++ b/softfloat/softfloat_state.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: @@ -40,9 +40,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "specialize.h" #include "softfloat.h" -uint_fast8_t softfloat_roundingMode = softfloat_round_near_even; -uint_fast8_t softfloat_detectTininess = init_detectTininess; -uint_fast8_t softfloat_exceptionFlags = 0; +#ifndef THREAD_LOCAL +#define THREAD_LOCAL +#endif -uint_fast8_t extF80_roundingPrecision = 80; +THREAD_LOCAL uint_fast8_t softfloat_roundingMode = softfloat_round_near_even; +THREAD_LOCAL uint_fast8_t softfloat_detectTininess = init_detectTininess; +THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags = 0; + +THREAD_LOCAL uint_fast8_t extF80_roundingPrecision = 80; diff --git a/softfloat/softfloat_types.h b/softfloat/softfloat_types.h index c7b67ae..af1888f 100644 --- a/softfloat/softfloat_types.h +++ b/softfloat/softfloat_types.h @@ -2,10 +2,10 @@ /*============================================================================ This C header 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, 2017 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: @@ -40,21 +40,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> /*---------------------------------------------------------------------------- -| Types used to pass 32-bit, 64-bit, and 128-bit floating-point arguments and -| results to/from functions. These types must be exactly 32 bits, 64 bits, -| and 128 bits in size, respectively. Where a platform has "native" support -| for IEEE-Standard floating-point formats, the types below may, if desired, -| be defined as aliases for the native types (typically `float' and `double', -| and possibly `long double'). +| Types used to pass 16-bit, 32-bit, 64-bit, and 128-bit floating-point +| arguments and results to/from functions. These types must be exactly +| 16 bits, 32 bits, 64 bits, and 128 bits in size, respectively. Where a +| platform has "native" support for IEEE-Standard floating-point formats, +| the types below may, if desired, be defined as aliases for the native types +| (typically 'float' and 'double', and possibly 'long double'). *----------------------------------------------------------------------------*/ +typedef struct { uint16_t v; } float16_t; typedef struct { uint32_t v; } float32_t; typedef struct { uint64_t v; } float64_t; typedef struct { uint64_t v[2]; } float128_t; /*---------------------------------------------------------------------------- | The format of an 80-bit extended floating-point number in memory. This -| structure must contain a 16-bit field named `signExp' and a 64-bit field -| named `signif'. +| structure must contain a 16-bit field named 'signExp' and a 64-bit field +| named 'signif'. *----------------------------------------------------------------------------*/ #ifdef LITTLEENDIAN struct extFloat80M { uint64_t signif; uint16_t signExp; }; @@ -65,12 +66,12 @@ struct extFloat80M { uint16_t signExp; uint64_t signif; }; /*---------------------------------------------------------------------------- | The type used to pass 80-bit extended floating-point arguments and | results to/from functions. This type must have size identical to -| `struct extFloat80M'. Type `extFloat80_t' can be defined as an alias for -| `struct extFloat80M'. Alternatively, if a platform has "native" support +| 'struct extFloat80M'. Type 'extFloat80_t' can be defined as an alias for +| 'struct extFloat80M'. Alternatively, if a platform has "native" support | for IEEE-Standard 80-bit extended floating-point, it may be possible, -| if desired, to define `extFloat80_t' as an alias for the native type -| (presumably either `long double' or a nonstandard compiler-intrinsic type). -| In that case, the `signif' and `signExp' fields of `struct extFloat80M' +| if desired, to define 'extFloat80_t' as an alias for the native type +| (presumably either 'long double' or a nonstandard compiler-intrinsic type). +| In that case, the 'signif' and 'signExp' fields of 'struct extFloat80M' | must align exactly with the locations in memory of the sign, exponent, and | significand of the native type. *----------------------------------------------------------------------------*/ diff --git a/softfloat/specialize.h b/softfloat/specialize.h index 6975f39..629d518 100644 --- a/softfloat/specialize.h +++ b/softfloat/specialize.h @@ -2,7 +2,7 @@ /*============================================================================ This C header 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, 2015, 2016 The Regents of the University of California. All rights reserved. @@ -42,13 +42,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "primitiveTypes.h" #include "softfloat.h" +#ifdef __cplusplus +extern "C" { +#endif + /*---------------------------------------------------------------------------- | Default value for `softfloat_detectTininess'. *----------------------------------------------------------------------------*/ #define init_detectTininess softfloat_tininess_afterRounding /*---------------------------------------------------------------------------- -| The values to return on conversions to 32-bit integer format that raise an +| The values to return on conversions to 32-bit integer formats that raise an | invalid exception. *----------------------------------------------------------------------------*/ #define ui32_fromPosOverflow 0xFFFFFFFF @@ -59,7 +63,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define i32_fromNaN 0x7FFFFFFF /*---------------------------------------------------------------------------- -| The values to return on conversions to 64-bit integer format that raise an +| The values to return on conversions to 64-bit integer formats that raise an | invalid exception. *----------------------------------------------------------------------------*/ #define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) @@ -76,6 +80,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct commonNaN { char _unused; }; /*---------------------------------------------------------------------------- +| The bit pattern for a default generated 16-bit floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNF16UI 0x7E00 + +/*---------------------------------------------------------------------------- +| Returns true when 16-bit unsigned integer `uiA' has the bit pattern of a +| 16-bit floating-point signaling NaN. +| Note: This macro evaluates its argument more than once. +*----------------------------------------------------------------------------*/ +#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) + +/*---------------------------------------------------------------------------- +| Assuming `uiA' has the bit pattern of a 16-bit floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +#define softfloat_f16UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x0200) ) softfloat_raiseFlags( softfloat_flag_invalid ) + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into a 16-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +#define softfloat_commonNaNToF16UI( aPtr ) ((uint_fast16_t) defaultNaNF16UI) + +/*---------------------------------------------------------------------------- +| Interpreting `uiA' and `uiB' as the bit patterns of two 16-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either `uiA' or `uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint_fast16_t + softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ); + +/*---------------------------------------------------------------------------- | The bit pattern for a default generated 32-bit floating-point NaN. *----------------------------------------------------------------------------*/ #define defaultNaNF32UI 0x7FC00000 @@ -182,7 +221,7 @@ uint_fast64_t *----------------------------------------------------------------------------*/ #if defined INLINE && ! defined softfloat_commonNaNToExtF80UI INLINE - struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ) +struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ) { struct uint128 uiZ; uiZ.v64 = defaultNaNExtF80UI64; @@ -239,7 +278,7 @@ struct uint128 *----------------------------------------------------------------------------*/ #if defined INLINE && ! defined softfloat_commonNaNToF128UI INLINE - struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) +struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) { struct uint128 uiZ; uiZ.v64 = defaultNaNF128UI64; @@ -289,9 +328,9 @@ struct uint128 *----------------------------------------------------------------------------*/ #if defined INLINE && ! defined softfloat_commonNaNToExtF80M INLINE - void - softfloat_commonNaNToExtF80M( - const struct commonNaN *aPtr, struct extFloat80M *zSPtr ) +void + softfloat_commonNaNToExtF80M( + const struct commonNaN *aPtr, struct extFloat80M *zSPtr ) { zSPtr->signExp = defaultNaNExtF80UI64; zSPtr->signif = defaultNaNExtF80UI0; @@ -318,10 +357,10 @@ void /*---------------------------------------------------------------------------- | The bit pattern for a default generated 128-bit floating-point NaN. *----------------------------------------------------------------------------*/ -#define defaultNaNF128UI96 0xFFFFFFFF -#define defaultNaNF128UI64 0xFFFFFFFF -#define defaultNaNF128UI32 0xFFFFFFFF -#define defaultNaNF128UI0 0xFFFFFFFF +#define defaultNaNF128UI96 0x7FFF8000 +#define defaultNaNF128UI64 0 +#define defaultNaNF128UI32 0 +#define defaultNaNF128UI0 0 /*---------------------------------------------------------------------------- | Assuming the 128-bit floating-point value pointed to by `aWPtr' is a NaN, @@ -341,8 +380,8 @@ void *----------------------------------------------------------------------------*/ #if defined INLINE && ! defined softfloat_commonNaNToF128M INLINE - void - softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ) +void + softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ) { zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96; zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64; @@ -368,5 +407,9 @@ void #endif +#ifdef __cplusplus +} +#endif + #endif diff --git a/softfloat/ui32_to_f128.c b/softfloat/ui32_to_f128.c new file mode 100644 index 0000000..78d3eb6 --- /dev/null +++ b/softfloat/ui32_to_f128.c @@ -0,0 +1,60 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float128_t ui32_to_f128( uint32_t a ) +{ + uint_fast64_t uiZ64; + int_fast8_t shiftDist; + union ui128_f128 uZ; + + uiZ64 = 0; + if ( a ) { + shiftDist = softfloat_countLeadingZeros32( a ) + 17; + uiZ64 = + packToF128UI64( + 0, 0x402E - shiftDist, (uint_fast64_t) a<<shiftDist ); + } + uZ.ui.v64 = uiZ64; + uZ.ui.v0 = 0; + return uZ.f; + +} + diff --git a/softfloat/ui32_to_f16.c b/softfloat/ui32_to_f16.c new file mode 100644 index 0000000..09dcc8c --- /dev/null +++ b/softfloat/ui32_to_f16.c @@ -0,0 +1,65 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float16_t ui32_to_f16( uint32_t a ) +{ + int_fast8_t shiftDist; + union ui16_f16 u; + uint_fast16_t sig; + + shiftDist = softfloat_countLeadingZeros32( a ) - 21; + if ( 0 <= shiftDist ) { + u.ui = + a ? packToF16UI( + 0, 0x18 - shiftDist, (uint_fast16_t) a<<shiftDist ) + : 0; + return u.f; + } else { + shiftDist += 4; + sig = + (shiftDist < 0) + ? a>>(-shiftDist) | ((uint32_t) (a<<(shiftDist & 31)) != 0) + : (uint_fast16_t) a<<shiftDist; + return softfloat_roundPackToF16( 0, 0x1C - shiftDist, sig ); + } + +} + diff --git a/softfloat/ui32_to_f32.c b/softfloat/ui32_to_f32.c index ae98fb7..7e5ece6 100644 --- a/softfloat/ui32_to_f32.c +++ b/softfloat/ui32_to_f32.c @@ -2,7 +2,7 @@ /*============================================================================ 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. diff --git a/softfloat/ui32_to_f64.c b/softfloat/ui32_to_f64.c index 6b72fa5..5e5f843 100644 --- a/softfloat/ui32_to_f64.c +++ b/softfloat/ui32_to_f64.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: @@ -42,16 +42,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float64_t ui32_to_f64( uint32_t a ) { uint_fast64_t uiZ; - int_fast8_t shiftCount; + int_fast8_t shiftDist; union ui64_f64 uZ; if ( ! a ) { uiZ = 0; } else { - shiftCount = softfloat_countLeadingZeros32( a ) + 21; + shiftDist = softfloat_countLeadingZeros32( a ) + 21; uiZ = - packToF64UI( - 0, 0x432 - shiftCount, (uint_fast64_t) a<<shiftCount ); + packToF64UI( 0, 0x432 - shiftDist, (uint_fast64_t) a<<shiftDist ); } uZ.ui = uiZ; return uZ.f; diff --git a/softfloat/ui64_to_f128.c b/softfloat/ui64_to_f128.c new file mode 100644 index 0000000..0124bc5 --- /dev/null +++ b/softfloat/ui64_to_f128.c @@ -0,0 +1,68 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float128_t ui64_to_f128( uint64_t a ) +{ + uint_fast64_t uiZ64, uiZ0; + int_fast8_t shiftDist; + struct uint128 zSig; + union ui128_f128 uZ; + + if ( ! a ) { + uiZ64 = 0; + uiZ0 = 0; + } else { + shiftDist = softfloat_countLeadingZeros64( a ) + 49; + if ( 64 <= shiftDist ) { + zSig.v64 = a<<(shiftDist - 64); + zSig.v0 = 0; + } else { + zSig = softfloat_shortShiftLeft128( 0, a, shiftDist ); + } + uiZ64 = packToF128UI64( 0, 0x406E - shiftDist, zSig.v64 ); + uiZ0 = zSig.v0; + } + uZ.ui.v64 = uiZ64; + uZ.ui.v0 = uiZ0; + return uZ.f; + +} + diff --git a/softfloat/ui64_to_f16.c b/softfloat/ui64_to_f16.c new file mode 100644 index 0000000..ecca02b --- /dev/null +++ b/softfloat/ui64_to_f16.c @@ -0,0 +1,64 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3d, by John R. Hauser. + +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: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include <stdint.h> +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float16_t ui64_to_f16( uint64_t a ) +{ + int_fast8_t shiftDist; + union ui16_f16 u; + uint_fast16_t sig; + + shiftDist = softfloat_countLeadingZeros64( a ) - 53; + if ( 0 <= shiftDist ) { + u.ui = + a ? packToF16UI( + 0, 0x18 - shiftDist, (uint_fast16_t) a<<shiftDist ) + : 0; + return u.f; + } else { + shiftDist += 4; + sig = + (shiftDist < 0) ? softfloat_shortShiftRightJam64( a, -shiftDist ) + : (uint_fast16_t) a<<shiftDist; + return softfloat_roundPackToF16( 0, 0x1C - shiftDist, sig ); + } + +} + diff --git a/softfloat/ui64_to_f32.c b/softfloat/ui64_to_f32.c index d67c6f9..2d946c2 100644 --- a/softfloat/ui64_to_f32.c +++ b/softfloat/ui64_to_f32.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: @@ -41,23 +41,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float32_t ui64_to_f32( uint64_t a ) { - int_fast8_t shiftCount; + int_fast8_t shiftDist; union ui32_f32 u; uint_fast32_t sig; - shiftCount = softfloat_countLeadingZeros64( a ) - 40; - if ( 0 <= shiftCount ) { + shiftDist = softfloat_countLeadingZeros64( a ) - 40; + if ( 0 <= shiftDist ) { u.ui = a ? packToF32UI( - 0, 0x95 - shiftCount, (uint_fast32_t) a<<shiftCount ) + 0, 0x95 - shiftDist, (uint_fast32_t) a<<shiftDist ) : 0; return u.f; } else { - shiftCount += 7; + shiftDist += 7; sig = - (shiftCount < 0) ? softfloat_shortShiftRightJam64( a, -shiftCount ) - : (uint_fast32_t) a<<shiftCount; - return softfloat_roundPackToF32( 0, 0x9C - shiftCount, sig ); + (shiftDist < 0) ? softfloat_shortShiftRightJam64( a, -shiftDist ) + : (uint_fast32_t) a<<shiftDist; + return softfloat_roundPackToF32( 0, 0x9C - shiftDist, sig ); } } diff --git a/softfloat/ui64_to_f64.c b/softfloat/ui64_to_f64.c index fcaa682..57102a7 100644 --- a/softfloat/ui64_to_f64.c +++ b/softfloat/ui64_to_f64.c @@ -2,7 +2,7 @@ /*============================================================================ 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. |