diff options
author | John Hauser <jhauser@eecs.berkeley.edu> | 2016-02-22 15:51:12 -0800 |
---|---|---|
committer | John Hauser <jhauser@eecs.berkeley.edu> | 2016-02-22 15:51:12 -0800 |
commit | 45fdcf1c6583e4af380b147ac568f5aa721b7ba8 (patch) | |
tree | 844650fe6e692766e725deaed8149125895cbc4b /source | |
parent | 9dc9d10297e1d43e10188b5b19e2b697216fba2b (diff) | |
download | berkeley-softfloat-3-45fdcf1c6583e4af380b147ac568f5aa721b7ba8.zip berkeley-softfloat-3-45fdcf1c6583e4af380b147ac568f5aa721b7ba8.tar.gz berkeley-softfloat-3-45fdcf1c6583e4af380b147ac568f5aa721b7ba8.tar.bz2 |
Added the ability to specify the result values delivered when conversions
from floating-point to an integer format raise an invalid exception.
For the provided specializations (8086 and RISC-V), changed the result
of converting a negative floating-point value to an unsigned integer
format to now be zero. (Also renamed `shiftCount' inside functions to
`shiftDist'.)
Diffstat (limited to 'source')
57 files changed, 1285 insertions, 707 deletions
diff --git a/source/8086-SSE/specialize.h b/source/8086-SSE/specialize.h index eec6311..8a71e46 100644 --- a/source/8086-SSE/specialize.h +++ b/source/8086-SSE/specialize.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 3a+, 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,7 +44,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /*---------------------------------------------------------------------------- | Default value for `softfloat_detectTininess'. *----------------------------------------------------------------------------*/ -#define init_detectTininess softfloat_tininess_afterRounding; +#define init_detectTininess softfloat_tininess_afterRounding + +/*---------------------------------------------------------------------------- +| The values to return on conversions to 32-bit integer format that raise an +| invalid exception. +*----------------------------------------------------------------------------*/ +#define ui32_fromPosOverflow 0xFFFFFFFF +#define ui32_fromNegOverflow 0 +#define ui32_fromNaN 0xFFFFFFFF +#define i32_fromPosOverflow 0x7FFFFFFF +#define i32_fromNegOverflow (-0x7FFFFFFF - 1) +#define i32_fromNaN 0x7FFFFFFF + +/*---------------------------------------------------------------------------- +| The values to return on conversions to 64-bit integer format that raise an +| invalid exception. +*----------------------------------------------------------------------------*/ +#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) +#define ui64_fromNegOverflow 0 +#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF ) +#define i64_fromPosOverflow UINT64_C( 0x7FFFFFFFFFFFFFFF ) +#define i64_fromNegOverflow (-UINT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) +#define i64_fromNaN UINT64_C( 0x7FFFFFFFFFFFFFFF ) /*---------------------------------------------------------------------------- | "Common NaN" structure, used to transfer NaN representations from one format diff --git a/source/8086/specialize.h b/source/8086/specialize.h index eec6311..8a71e46 100644 --- a/source/8086/specialize.h +++ b/source/8086/specialize.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 3a+, 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,7 +44,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /*---------------------------------------------------------------------------- | Default value for `softfloat_detectTininess'. *----------------------------------------------------------------------------*/ -#define init_detectTininess softfloat_tininess_afterRounding; +#define init_detectTininess softfloat_tininess_afterRounding + +/*---------------------------------------------------------------------------- +| The values to return on conversions to 32-bit integer format that raise an +| invalid exception. +*----------------------------------------------------------------------------*/ +#define ui32_fromPosOverflow 0xFFFFFFFF +#define ui32_fromNegOverflow 0 +#define ui32_fromNaN 0xFFFFFFFF +#define i32_fromPosOverflow 0x7FFFFFFF +#define i32_fromNegOverflow (-0x7FFFFFFF - 1) +#define i32_fromNaN 0x7FFFFFFF + +/*---------------------------------------------------------------------------- +| The values to return on conversions to 64-bit integer format that raise an +| invalid exception. +*----------------------------------------------------------------------------*/ +#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) +#define ui64_fromNegOverflow 0 +#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF ) +#define i64_fromPosOverflow UINT64_C( 0x7FFFFFFFFFFFFFFF ) +#define i64_fromNegOverflow (-UINT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) +#define i64_fromNaN UINT64_C( 0x7FFFFFFFFFFFFFFF ) /*---------------------------------------------------------------------------- | "Common NaN" structure, used to transfer NaN representations from one format diff --git a/source/RISCV/specialize.h b/source/RISCV/specialize.h index 972425d..6975f39 100644 --- a/source/RISCV/specialize.h +++ b/source/RISCV/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 3a+, by John R. Hauser. Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of California. All rights reserved. @@ -45,7 +45,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /*---------------------------------------------------------------------------- | Default value for `softfloat_detectTininess'. *----------------------------------------------------------------------------*/ -#define init_detectTininess softfloat_tininess_afterRounding; +#define init_detectTininess softfloat_tininess_afterRounding + +/*---------------------------------------------------------------------------- +| The values to return on conversions to 32-bit integer format that raise an +| invalid exception. +*----------------------------------------------------------------------------*/ +#define ui32_fromPosOverflow 0xFFFFFFFF +#define ui32_fromNegOverflow 0 +#define ui32_fromNaN 0xFFFFFFFF +#define i32_fromPosOverflow 0x7FFFFFFF +#define i32_fromNegOverflow (-0x7FFFFFFF - 1) +#define i32_fromNaN 0x7FFFFFFF + +/*---------------------------------------------------------------------------- +| The values to return on conversions to 64-bit integer format that raise an +| invalid exception. +*----------------------------------------------------------------------------*/ +#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) +#define ui64_fromNegOverflow 0 +#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF ) +#define i64_fromPosOverflow UINT64_C( 0x7FFFFFFFFFFFFFFF ) +#define i64_fromNegOverflow (-UINT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) +#define i64_fromNaN UINT64_C( 0x7FFFFFFFFFFFFFFF ) /*---------------------------------------------------------------------------- | "Common NaN" structure, used to transfer NaN representations from one format diff --git a/source/extF80M_to_i32.c b/source/extF80M_to_i32.c index ce3ae22..97ccb3e 100644 --- a/source/extF80M_to_i32.c +++ b/source/extF80M_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -62,7 +63,7 @@ int_fast32_t bool sign; int32_t exp; uint64_t sig; - int32_t shiftCount; + int32_t shiftDist; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -73,24 +74,25 @@ int_fast32_t sig = aSPtr->signif; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - if ( (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) sign = 0; - shiftCount = 0x4037 - exp; - if ( shiftCount <= 0 ) { + shiftDist = 0x4037 - exp; + if ( shiftDist <= 0 ) { if ( sig>>32 ) goto invalid; - if ( -32 < shiftCount ) { - sig <<= -shiftCount; + if ( -32 < shiftDist ) { + sig <<= -shiftDist; } else { if ( (uint32_t) sig ) goto invalid; } } else { - sig = softfloat_shiftRightJam64( sig, shiftCount ); + sig = softfloat_shiftRightJam64( sig, shiftDist ); } return softfloat_roundPackToI32( sign, sig, roundingMode, exact ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return sign ? -0x7FFFFFFF - 1 : 0x7FFFFFFF; + return + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; } diff --git a/source/extF80M_to_i32_r_minMag.c b/source/extF80M_to_i32_r_minMag.c index bc1b637..33ae48f 100644 --- a/source/extF80M_to_i32_r_minMag.c +++ b/source/extF80M_to_i32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -57,8 +58,8 @@ int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *aPtr, bool exact ) uint_fast16_t uiA64; int32_t exp; uint64_t sig; - int32_t shiftCount; - bool raiseInexact; + int32_t shiftDist; + bool sign, raiseInexact; int32_t z; uint64_t shiftedSig; uint32_t absZ; @@ -73,27 +74,28 @@ int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *aPtr, bool exact ) /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( ! sig && (exp != 0x7FFF) ) return 0; - shiftCount = 0x403E - exp; - if ( 64 <= shiftCount ) { + shiftDist = 0x403E - exp; + if ( 64 <= shiftDist ) { raiseInexact = exact; z = 0; } else { + sign = signExtF80UI64( uiA64 ); raiseInexact = false; - if ( shiftCount < 0 ) { - if ( sig>>32 || (shiftCount <= -31) ) goto invalid; - shiftedSig = (uint64_t) (uint32_t) sig<<-shiftCount; + if ( shiftDist < 0 ) { + if ( sig>>32 || (shiftDist <= -31) ) goto invalid; + shiftedSig = (uint64_t) (uint32_t) sig<<-shiftDist; if ( shiftedSig>>32 ) goto invalid; absZ = shiftedSig; } else { shiftedSig = sig; - if ( shiftCount ) shiftedSig >>= shiftCount; + if ( shiftDist ) shiftedSig >>= shiftDist; if ( shiftedSig>>32 ) goto invalid; absZ = shiftedSig; - if ( exact && shiftCount ) { - raiseInexact = ((uint64_t) absZ<<shiftCount != sig); + if ( exact && shiftDist ) { + raiseInexact = ((uint64_t) absZ<<shiftDist != sig); } } - if ( signExtF80UI64( uiA64 ) ) { + if ( sign ) { if ( 0x80000000 < absZ ) goto invalid; u.ui = -absZ; z = u.i; @@ -109,10 +111,8 @@ int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *aPtr, bool exact ) invalid: softfloat_raiseFlags( softfloat_flag_invalid ); return - ! signExtF80UI64( uiA64 ) - || ((exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - ? 0x7FFFFFFF - : -0x7FFFFFFF - 1; + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; } diff --git a/source/extF80M_to_i64.c b/source/extF80M_to_i64.c index da89c03..4149b6e 100644 --- a/source/extF80M_to_i64.c +++ b/source/extF80M_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -62,7 +63,7 @@ int_fast64_t bool sign; int32_t exp; uint64_t sig; - int32_t shiftCount; + int32_t shiftDist; uint32_t extSig[3]; /*------------------------------------------------------------------------ @@ -74,19 +75,20 @@ int_fast64_t sig = aSPtr->signif; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - shiftCount = 0x403E - exp; - if ( shiftCount < 0 ) { + shiftDist = 0x403E - exp; + if ( shiftDist < 0 ) { softfloat_raiseFlags( softfloat_flag_invalid ); return - ! sign - || ((exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - ? INT64_C( 0x7FFFFFFFFFFFFFFF ) - : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ extSig[indexWord( 3, 2 )] = sig>>32; extSig[indexWord( 3, 1 )] = sig; extSig[indexWord( 3, 0 )] = 0; - if ( shiftCount ) softfloat_shiftRightJam96M( extSig, shiftCount, extSig ); + if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); return softfloat_roundPackMToI64( sign, extSig, roundingMode, exact ); } diff --git a/source/extF80M_to_i64_r_minMag.c b/source/extF80M_to_i64_r_minMag.c index dcf4922..6abbd78 100644 --- a/source/extF80M_to_i64_r_minMag.c +++ b/source/extF80M_to_i64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -57,8 +58,8 @@ int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *aPtr, bool exact ) uint_fast16_t uiA64; int32_t exp; uint64_t sig; - int32_t shiftCount; - bool raiseInexact; + int32_t shiftDist; + bool sign, raiseInexact; int64_t z; uint64_t absZ; union { uint64_t ui; int64_t i; } u; @@ -72,25 +73,24 @@ int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *aPtr, bool exact ) /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( ! sig && (exp != 0x7FFF) ) return 0; - shiftCount = 0x403E - exp; - if ( 64 <= shiftCount ) { + shiftDist = 0x403E - exp; + if ( 64 <= shiftDist ) { raiseInexact = exact; z = 0; } else { + sign = signExtF80UI64( uiA64 ); raiseInexact = false; - if ( shiftCount < 0 ) { - if ( shiftCount <= -63 ) goto invalid; - shiftCount = -shiftCount; - absZ = sig<<shiftCount; - if ( absZ>>shiftCount != sig ) goto invalid; + if ( shiftDist < 0 ) { + if ( shiftDist <= -63 ) goto invalid; + shiftDist = -shiftDist; + absZ = sig<<shiftDist; + if ( absZ>>shiftDist != sig ) goto invalid; } else { absZ = sig; - if ( shiftCount ) absZ >>= shiftCount; - if ( exact && shiftCount ) { - raiseInexact = (absZ<<shiftCount != sig); - } + if ( shiftDist ) absZ >>= shiftDist; + if ( exact && shiftDist ) raiseInexact = (absZ<<shiftDist != sig); } - if ( signExtF80UI64( uiA64 ) ) { + if ( sign ) { if ( UINT64_C( 0x8000000000000000 ) < absZ ) goto invalid; u.ui = -absZ; z = u.i; @@ -106,10 +106,8 @@ int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *aPtr, bool exact ) invalid: softfloat_raiseFlags( softfloat_flag_invalid ); return - ! signExtF80UI64( uiA64 ) - || ((exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - ? UINT64_C( 0x7FFFFFFFFFFFFFFF ) - : -UINT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } diff --git a/source/extF80M_to_ui32.c b/source/extF80M_to_ui32.c index a76f203..294a205 100644 --- a/source/extF80M_to_ui32.c +++ b/source/extF80M_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -62,7 +63,7 @@ uint_fast32_t bool sign; int32_t exp; uint64_t sig; - int32_t shiftCount; + int32_t shiftDist; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -73,23 +74,26 @@ uint_fast32_t sig = aSPtr->signif; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - shiftCount = 0x4037 - exp; - if ( shiftCount <= 0 ) { + shiftDist = 0x4037 - exp; + if ( shiftDist <= 0 ) { if ( sig>>32 ) goto invalid; - if ( -32 < shiftCount ) { - sig <<= -shiftCount; + if ( -32 < shiftDist ) { + sig <<= -shiftDist; } else { if ( (uint32_t) sig ) goto invalid; } } else { - sig = softfloat_shiftRightJam64( sig, shiftCount ); + sig = softfloat_shiftRightJam64( sig, shiftDist ); } return softfloat_roundPackToUI32( sign, sig, roundingMode, exact ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return 0xFFFFFFFF; + return + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; } diff --git a/source/extF80M_to_ui32_r_minMag.c b/source/extF80M_to_ui32_r_minMag.c index e30c6d8..300f05d 100644 --- a/source/extF80M_to_ui32_r_minMag.c +++ b/source/extF80M_to_ui32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -57,7 +58,7 @@ uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *aPtr, bool exact ) uint_fast16_t uiA64; int32_t exp; uint64_t sig; - int32_t shiftCount; + int32_t shiftDist; bool sign; uint64_t shiftedSig; uint32_t z; @@ -71,24 +72,26 @@ uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *aPtr, bool exact ) /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( ! sig && (exp != 0x7FFF) ) return 0; - shiftCount = 0x403E - exp; - if ( 64 <= shiftCount ) { + shiftDist = 0x403E - exp; + if ( 64 <= shiftDist ) { if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; return 0; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sign = signExtF80UI64( uiA64 ); - if ( shiftCount < 0 ) { - if ( sign || sig>>32 || (shiftCount <= -31) ) goto invalid; - shiftedSig = (uint64_t) (uint32_t) sig<<-shiftCount; + if ( shiftDist < 0 ) { + if ( sign || sig>>32 || (shiftDist <= -31) ) goto invalid; + shiftedSig = (uint64_t) (uint32_t) sig<<-shiftDist; if ( shiftedSig>>32 ) goto invalid; z = shiftedSig; } else { shiftedSig = sig; - if ( shiftCount ) shiftedSig >>= shiftCount; + if ( shiftDist ) shiftedSig >>= shiftDist; if ( shiftedSig>>32 ) goto invalid; z = shiftedSig; if ( sign && z ) goto invalid; - if ( exact && shiftCount && ((uint64_t) z<<shiftCount != sig) ) { + if ( exact && shiftDist && ((uint64_t) z<<shiftDist != sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } } @@ -97,7 +100,10 @@ uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *aPtr, bool exact ) *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return 0xFFFFFFFF; + return + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; } diff --git a/source/extF80M_to_ui64.c b/source/extF80M_to_ui64.c index 8e16db1..86ea0f5 100644 --- a/source/extF80M_to_ui64.c +++ b/source/extF80M_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -59,29 +60,35 @@ uint_fast64_t { const struct extFloat80M *aSPtr; uint_fast16_t uiA64; - int32_t exp, shiftCount; bool sign; + int32_t exp; uint64_t sig; + int32_t shiftDist; uint32_t extSig[3]; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ aSPtr = (const struct extFloat80M *) aPtr; uiA64 = aSPtr->signExp; - exp = expExtF80UI64( uiA64 ); + sign = signExtF80UI64( uiA64 ); + exp = expExtF80UI64( uiA64 ); + sig = aSPtr->signif; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - shiftCount = 0x403E - exp; - if ( shiftCount < 0 ) { + shiftDist = 0x403E - exp; + if ( shiftDist < 0 ) { softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } - sign = signExtF80UI64( uiA64 ); - sig = aSPtr->signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ extSig[indexWord( 3, 2 )] = sig>>32; extSig[indexWord( 3, 1 )] = sig; extSig[indexWord( 3, 0 )] = 0; - if ( shiftCount ) softfloat_shiftRightJam96M( extSig, shiftCount, extSig ); + if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); return softfloat_roundPackMToUI64( sign, extSig, roundingMode, exact ); } diff --git a/source/extF80M_to_ui64_r_minMag.c b/source/extF80M_to_ui64_r_minMag.c index fdabd24..2b1b04e 100644 --- a/source/extF80M_to_ui64_r_minMag.c +++ b/source/extF80M_to_ui64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -57,7 +58,7 @@ uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *aPtr, bool exact ) uint_fast16_t uiA64; int32_t exp; uint64_t sig; - int32_t shiftCount; + int32_t shiftDist; bool sign; uint64_t z; @@ -70,22 +71,24 @@ uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *aPtr, bool exact ) /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( ! sig && (exp != 0x7FFF) ) return 0; - shiftCount = 0x403E - exp; - if ( 64 <= shiftCount ) { + shiftDist = 0x403E - exp; + if ( 64 <= shiftDist ) { if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; return 0; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sign = signExtF80UI64( uiA64 ); - if ( shiftCount < 0 ) { - if ( sign || (shiftCount <= -63) ) goto invalid; - shiftCount = -shiftCount; - z = sig<<shiftCount; - if ( z>>shiftCount != sig ) goto invalid; + if ( shiftDist < 0 ) { + if ( sign || (shiftDist <= -63) ) goto invalid; + shiftDist = -shiftDist; + z = sig<<shiftDist; + if ( z>>shiftDist != sig ) goto invalid; } else { z = sig; - if ( shiftCount ) z >>= shiftCount; + if ( shiftDist ) z >>= shiftDist; if ( sign && z ) goto invalid; - if ( exact && shiftCount && (z<<shiftCount != sig) ) { + if ( exact && shiftDist && (z<<shiftDist != sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } } @@ -94,7 +97,10 @@ uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *aPtr, bool exact ) *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } diff --git a/source/extF80_to_i32.c b/source/extF80_to_i32.c index 64826e7..2e58c0a 100644 --- a/source/extF80_to_i32.c +++ b/source/extF80_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast32_t @@ -48,17 +49,34 @@ int_fast32_t bool sign; int_fast32_t exp; uint_fast64_t sig; - int_fast32_t shiftCount; + int_fast32_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.s.signExp; sign = signExtF80UI64( uiA64 ); exp = expExtF80UI64( uiA64 ); sig = uA.s.signif; - if ( (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) sign = 0; - shiftCount = 0x4037 - exp; - if ( shiftCount <= 0 ) shiftCount = 1; - sig = softfloat_shiftRightJam64( sig, shiftCount ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ( (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) { +#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 + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x4037 - exp; + if ( shiftDist <= 0 ) shiftDist = 1; + sig = softfloat_shiftRightJam64( sig, shiftDist ); return softfloat_roundPackToI32( sign, sig, roundingMode, exact ); } diff --git a/source/extF80_to_i32_r_minMag.c b/source/extF80_to_i32_r_minMag.c index 1d0238d..0f591a4 100644 --- a/source/extF80_to_i32_r_minMag.c +++ b/source/extF80_to_i32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast32_t extF80_to_i32_r_minMag( extFloat80_t a, bool exact ) @@ -46,23 +47,29 @@ int_fast32_t extF80_to_i32_r_minMag( extFloat80_t a, bool exact ) uint_fast16_t uiA64; int_fast32_t exp; uint_fast64_t sig; - int_fast32_t shiftCount; + int_fast32_t shiftDist; bool sign; int_fast32_t absZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.s.signExp; exp = expExtF80UI64( uiA64 ); sig = uA.s.signif; - shiftCount = 0x403E - exp; - if ( 64 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if ( 64 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sign = signExtF80UI64( uiA64 ); - if ( shiftCount < 33 ) { + if ( shiftDist < 33 ) { if ( (uiA64 == packToExtF80UI64( 1, 0x401E )) && (sig < UINT64_C( 0x8000000100000000 )) @@ -70,21 +77,18 @@ int_fast32_t extF80_to_i32_r_minMag( extFloat80_t a, bool exact ) if ( exact && (sig & UINT64_C( 0x00000000FFFFFFFF )) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } - } else { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( - ! sign - || ((exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - ) { - return 0x7FFFFFFF; - } + return -0x7FFFFFFF - 1; } - return -0x7FFFFFFF - 1; + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; } - absZ = sig>>shiftCount; - if ( - exact && ((uint_fast64_t) (uint_fast32_t) absZ<<shiftCount != sig) - ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + absZ = sig>>shiftDist; + if ( exact && ((uint_fast64_t) (uint_fast32_t) absZ<<shiftDist != sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return sign ? -absZ : absZ; diff --git a/source/extF80_to_i64.c b/source/extF80_to_i64.c index 9571b5d..98815cf 100644 --- a/source/extF80_to_i64.c +++ b/source/extF80_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast64_t @@ -48,28 +49,37 @@ int_fast64_t bool sign; int_fast32_t exp; uint_fast64_t sig; - int_fast32_t shiftCount; + int_fast32_t shiftDist; uint_fast64_t sigExtra; struct uint64_extra sig64Extra; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.s.signExp; sign = signExtF80UI64( uiA64 ); exp = expExtF80UI64( uiA64 ); sig = uA.s.signif; - shiftCount = 0x403E - exp; - if ( shiftCount <= 0 ) { - if ( shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if ( shiftDist <= 0 ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( shiftDist ) { softfloat_raiseFlags( softfloat_flag_invalid ); return - ! sign - || ((exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - ? INT64_C( 0x7FFFFFFFFFFFFFFF ) - : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ sigExtra = 0; } else { - sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftCount ); + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); sig = sig64Extra.v; sigExtra = sig64Extra.extra; } diff --git a/source/extF80_to_i64_r_minMag.c b/source/extF80_to_i64_r_minMag.c index feeaedf..208ce86 100644 --- a/source/extF80_to_i64_r_minMag.c +++ b/source/extF80_to_i64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast64_t extF80_to_i64_r_minMag( extFloat80_t a, bool exact ) @@ -46,39 +47,45 @@ int_fast64_t extF80_to_i64_r_minMag( extFloat80_t a, bool exact ) uint_fast16_t uiA64; int_fast32_t exp; uint_fast64_t sig; - int_fast32_t shiftCount; + int_fast32_t shiftDist; bool sign; int_fast64_t absZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.s.signExp; exp = expExtF80UI64( uiA64 ); sig = uA.s.signif; - shiftCount = 0x403E - exp; - if ( 64 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if ( 64 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sign = signExtF80UI64( uiA64 ); - if ( shiftCount <= 0 ) { + if ( shiftDist <= 0 ) { if ( - (uiA64 != packToExtF80UI64( 1, 0x403E )) - || (sig != UINT64_C( 0x8000000000000000 )) + (uiA64 == packToExtF80UI64( 1, 0x403E )) + && (sig == UINT64_C( 0x8000000000000000 )) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( - ! sign - || ((exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - ) { - return INT64_C( 0x7FFFFFFFFFFFFFFF ); - } + return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; } - return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } - absZ = sig>>shiftCount; - if ( exact && (uint64_t) (sig<<(-shiftCount & 63)) ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + absZ = sig>>shiftDist; + if ( exact && (uint64_t) (sig<<(-shiftDist & 63)) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return sign ? -absZ : absZ; diff --git a/source/extF80_to_ui32.c b/source/extF80_to_ui32.c index 5a1aeae..2717342 100644 --- a/source/extF80_to_ui32.c +++ b/source/extF80_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast32_t @@ -48,16 +49,34 @@ uint_fast32_t bool sign; int_fast32_t exp; uint_fast64_t sig; - int_fast32_t shiftCount; + int_fast32_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.s.signExp; sign = signExtF80UI64( uiA64 ); exp = expExtF80UI64( uiA64 ); sig = uA.s.signif; - shiftCount = 0x4037 - exp; - if ( shiftCount <= 0 ) shiftCount = 1; - sig = softfloat_shiftRightJam64( sig, shiftCount ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) + if ( (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) { +#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 + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x4037 - exp; + if ( shiftDist <= 0 ) shiftDist = 1; + sig = softfloat_shiftRightJam64( sig, shiftDist ); return softfloat_roundPackToUI32( sign, sig, roundingMode, exact ); } diff --git a/source/extF80_to_ui32_r_minMag.c b/source/extF80_to_ui32_r_minMag.c index 13f706b..3c8c737 100644 --- a/source/extF80_to_ui32_r_minMag.c +++ b/source/extF80_to_ui32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t a, bool exact ) @@ -46,26 +47,39 @@ uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t a, bool exact ) uint_fast16_t uiA64; int_fast32_t exp; uint_fast64_t sig; - int_fast32_t shiftCount; + int_fast32_t shiftDist; + bool sign; uint_fast32_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.s.signExp; exp = expExtF80UI64( uiA64 ); sig = uA.s.signif; - shiftCount = 0x403E - exp; - if ( 64 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if ( 64 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } - if ( signExtF80UI64( uiA64 ) || (shiftCount < 32) ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signExtF80UI64( uiA64 ); + if ( sign || (shiftDist < 32) ) { softfloat_raiseFlags( softfloat_flag_invalid ); - return 0xFFFFFFFF; + return + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; } - z = sig>>shiftCount; - if ( exact && ((uint_fast64_t) z<<shiftCount != sig) ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + z = sig>>shiftDist; + if ( exact && ((uint_fast64_t) z<<shiftDist != sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; diff --git a/source/extF80_to_ui64.c b/source/extF80_to_ui64.c index dc27d4e..449b81b 100644 --- a/source/extF80_to_ui64.c +++ b/source/extF80_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast64_t @@ -45,24 +46,35 @@ uint_fast64_t { union { struct extFloat80M s; extFloat80_t f; } uA; uint_fast16_t uiA64; - int_fast32_t exp, shiftCount; bool sign; - uint_fast64_t sig, sigExtra; + int_fast32_t exp; + uint_fast64_t sig; + int_fast32_t shiftDist; + uint_fast64_t sigExtra; struct uint64_extra sig64Extra; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.s.signExp; - exp = expExtF80UI64( uiA64 ); - shiftCount = 0x403E - exp; - if ( shiftCount < 0 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); - } sign = signExtF80UI64( uiA64 ); + exp = expExtF80UI64( uiA64 ); sig = uA.s.signif; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if ( shiftDist < 0 ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sigExtra = 0; - if ( shiftCount ) { - sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftCount ); + if ( shiftDist ) { + sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); sig = sig64Extra.v; sigExtra = sig64Extra.extra; } diff --git a/source/extF80_to_ui64_r_minMag.c b/source/extF80_to_ui64_r_minMag.c index 4edc1a7..a52e407 100644 --- a/source/extF80_to_ui64_r_minMag.c +++ b/source/extF80_to_ui64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast64_t extF80_to_ui64_r_minMag( extFloat80_t a, bool exact ) @@ -46,26 +47,39 @@ uint_fast64_t extF80_to_ui64_r_minMag( extFloat80_t a, bool exact ) uint_fast16_t uiA64; int_fast32_t exp; uint_fast64_t sig; - int_fast32_t shiftCount; + int_fast32_t shiftDist; + bool sign; uint_fast64_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.s.signExp; exp = expExtF80UI64( uiA64 ); sig = uA.s.signif; - shiftCount = 0x403E - exp; - if ( 64 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if ( 64 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } - if ( signExtF80UI64( uiA64 ) || (shiftCount < 0) ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signExtF80UI64( uiA64 ); + if ( sign || (shiftDist < 0) ) { softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return + (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } - z = sig>>shiftCount; - if ( exact && (z<<shiftCount != sig) ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + z = sig>>shiftDist; + if ( exact && (z<<shiftDist != sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; diff --git a/source/f128M_to_i32.c b/source/f128M_to_i32.c index 3f4541e..dcf83a4 100644 --- a/source/f128M_to_i32.c +++ b/source/f128M_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -60,25 +61,35 @@ int_fast32_t bool sign; int32_t exp; uint64_t sig64; - bool notZeroSig0; - int32_t shiftCount; + int32_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ aWPtr = (const uint32_t *) aPtr; uiA96 = aWPtr[indexWordHi( 4 )]; sign = signF128UI96( uiA96 ); exp = expF128UI96( uiA96 ); sig64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )]; - notZeroSig0 = false; - if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) { - sig64 |= 1; - notZeroSig0 = true; + if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) sig64 |= 1; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ( (exp == 0x7FFF) && sig64 ) { +#if (i32_fromNaN == i32_fromPosOverflow) + sign = 0; +#elif (i32_fromNaN == i32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags( softfloat_flag_invalid ); + return i32_fromNaN; +#endif } - if ( (exp == 0x7FFF) && (notZeroSig0 || sig64) ) sign = 0; +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); - shiftCount = 0x4028 - exp; - if ( 0 < shiftCount ) { - sig64 = softfloat_shiftRightJam64( sig64, shiftCount ); - } + shiftDist = 0x4028 - exp; + if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); return softfloat_roundPackToI32( sign, sig64, roundingMode, exact ); } diff --git a/source/f128M_to_i32_r_minMag.c b/source/f128M_to_i32_r_minMag.c index c9e36cf..44c94ec 100644 --- a/source/f128M_to_i32_r_minMag.c +++ b/source/f128M_to_i32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -58,36 +59,46 @@ int_fast32_t f128M_to_i32_r_minMag( const float128_t *aPtr, bool exact ) bool sign; int32_t exp; uint64_t sig64; - int32_t shiftCount; + int32_t shiftDist; uint32_t absZ, uiZ; union { uint32_t ui; int32_t i; } uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ aWPtr = (const uint32_t *) aPtr; uiA96 = aWPtr[indexWordHi( 4 )]; sign = signF128UI96( uiA96 ); exp = expF128UI96( uiA96 ); sig64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )]; if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) sig64 |= 1; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( exp < 0x3FFF ) { if ( exact && (exp | sig64) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( 0x401F <= exp ) goto invalid; - shiftCount = 0x402F - exp; + shiftDist = 0x402F - exp; sig64 |= UINT64_C( 0x0001000000000000 ); - absZ = sig64>>shiftCount; + absZ = sig64>>shiftDist; uiZ = sign ? -absZ : absZ; if ( uiZ>>31 != sign ) goto invalid; - if ( exact && ((uint64_t) absZ<<shiftCount != sig64) ) { + if ( exact && ((uint64_t) absZ<<shiftDist != sig64) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } uZ.ui = uiZ; return uZ.i; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return sign ? -0x7FFFFFFF - 1 : 0x7FFFFFFF; + return + (exp == 0x7FFF) && sig64 ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; } diff --git a/source/f128M_to_i64.c b/source/f128M_to_i64.c index c04c2ec..766bf33 100644 --- a/source/f128M_to_i64.c +++ b/source/f128M_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -57,37 +58,40 @@ int_fast64_t { const uint32_t *aWPtr; uint32_t uiA96; - int32_t exp; bool sign; + int32_t exp; uint32_t sig96; - int32_t shiftCount; + int32_t shiftDist; uint32_t sig[4]; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ aWPtr = (const uint32_t *) aPtr; uiA96 = aWPtr[indexWordHi( 4 )]; - exp = expF128UI96( uiA96 ); sign = signF128UI96( uiA96 ); + exp = expF128UI96( uiA96 ); sig96 = fracF128UI96( uiA96 ); - shiftCount = 0x404F - exp; - if ( shiftCount < 17 ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x404F - exp; + if ( shiftDist < 17 ) { softfloat_raiseFlags( softfloat_flag_invalid ); return - ! sign - || ((exp == 0x7FFF) - && (sig96 - || ( aWPtr[indexWord( 4, 2 )] - | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )] - ))) - ? INT64_C( 0x7FFFFFFFFFFFFFFF ) - : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + (exp == 0x7FFF) + && (sig96 + || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] + | aWPtr[indexWord( 4, 0 )])) + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( exp ) sig96 |= 0x00010000; sig[indexWord( 4, 3 )] = sig96; sig[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; sig[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; sig[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - softfloat_shiftRightJam128M( sig, shiftCount, sig ); + softfloat_shiftRightJam128M( sig, shiftDist, sig ); return softfloat_roundPackMToI64( sign, sig + indexMultiwordLo( 4, 3 ), roundingMode, exact ); diff --git a/source/f128M_to_i64_r_minMag.c b/source/f128M_to_i64_r_minMag.c index 2cb2626..07e6fa7 100644 --- a/source/f128M_to_i64_r_minMag.c +++ b/source/f128M_to_i64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -56,25 +57,31 @@ int_fast64_t f128M_to_i64_r_minMag( const float128_t *aPtr, bool exact ) const uint32_t *aWPtr; uint32_t uiA96; bool sign; - int32_t exp, shiftCount; - uint32_t sig96, sig[4]; + int32_t exp; + uint32_t sig96; + int32_t shiftDist; + uint32_t sig[4]; uint64_t uiZ; union { uint64_t ui; int64_t i; } uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ aWPtr = (const uint32_t *) aPtr; uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - shiftCount = 0x403E - exp; - if ( shiftCount < 0 ) goto invalid; + sign = signF128UI96( uiA96 ); + exp = expF128UI96( uiA96 ); + sig96 = fracF128UI96( uiA96 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if ( shiftDist < 0 ) goto invalid; if ( exact ) { - sig96 = fracF128UI96( uiA96 ); if ( exp ) sig96 |= 0x00010000; sig[indexWord( 4, 3 )] = sig96; sig[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; sig[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; sig[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - softfloat_shiftRightJam128M( sig, shiftCount + 17, sig ); + softfloat_shiftRightJam128M( sig, shiftDist + 17, sig ); uiZ = (uint64_t) sig[indexWord( 4, 2 )]<<32 | sig[indexWord( 4, 1 )]; if ( uiZ>>63 && (! sign || (uiZ != UINT64_C( 0x8000000000000000 ))) ) { goto invalid; @@ -83,14 +90,14 @@ int_fast64_t f128M_to_i64_r_minMag( const float128_t *aPtr, bool exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; } } else { - if ( 64 <= shiftCount ) return 0; + if ( 64 <= shiftDist ) return 0; uiZ = - (uint64_t) fracF128UI96( uiA96 )<<47 + (uint64_t) sig96<<47 | (uint64_t) aWPtr[indexWord( 4, 2 )]<<15 | aWPtr[indexWord( 4, 1 )]>>17; - if ( shiftCount ) { + if ( shiftDist ) { uiZ |= UINT64_C( 0x8000000000000000 ); - uiZ >>= shiftCount; + uiZ >>= shiftDist; } else { if ( uiZ || ! sign ) goto invalid; uiZ |= UINT64_C( 0x8000000000000000 ); @@ -99,12 +106,17 @@ int_fast64_t f128M_to_i64_r_minMag( const float128_t *aPtr, bool exact ) if ( sign ) uiZ = -uiZ; uZ.ui = uiZ; return uZ.i; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); return - sign && ! softfloat_isNaNF128M( aWPtr ) - ? -UINT64_C( 0x7FFFFFFFFFFFFFFF ) - 1 - : UINT64_C( 0x7FFFFFFFFFFFFFFF ); + (exp == 0x7FFF) + && (sig96 + || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] + | aWPtr[indexWord( 4, 0 )])) + ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } diff --git a/source/f128M_to_ui32.c b/source/f128M_to_ui32.c index 9262fb5..86161be 100644 --- a/source/f128M_to_ui32.c +++ b/source/f128M_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -57,23 +58,39 @@ uint_fast32_t { const uint32_t *aWPtr; uint32_t uiA96; + bool sign; int32_t exp; uint64_t sig64; - int32_t shiftCount; + int32_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ aWPtr = (const uint32_t *) aPtr; uiA96 = aWPtr[indexWordHi( 4 )]; - exp = expF128UI96( uiA96 ); + sign = signF128UI96( uiA96 ); + exp = expF128UI96( uiA96 ); sig64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )]; - if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) sig64 |= 1; - shiftCount = 0x4028 - exp; - if ( 0 < shiftCount ) { - sig64 = softfloat_shiftRightJam64( sig64, shiftCount ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#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 } - return - softfloat_roundPackToUI32( - signF128UI96( uiA96 ), sig64, roundingMode, exact ); +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); + shiftDist = 0x4028 - exp; + if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); + return softfloat_roundPackToUI32( sign, sig64, roundingMode, exact ); } diff --git a/source/f128M_to_ui32_r_minMag.c b/source/f128M_to_ui32_r_minMag.c index e01a736..03c4d3f 100644 --- a/source/f128M_to_ui32_r_minMag.c +++ b/source/f128M_to_ui32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -57,28 +58,40 @@ uint_fast32_t f128M_to_ui32_r_minMag( const float128_t *aPtr, bool exact ) uint32_t uiA96; int32_t exp; uint64_t sig64; - int32_t shiftCount; + int32_t shiftDist; + bool sign; uint32_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ aWPtr = (const uint32_t *) aPtr; uiA96 = aWPtr[indexWordHi( 4 )]; exp = expF128UI96( uiA96 ); sig64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )]; if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) sig64 |= 1; - shiftCount = 0x402F - exp; - if ( 49 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( 49 <= shiftDist ) { if ( exact && (exp | sig64) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } - if ( signF128UI96( uiA96 ) || (shiftCount < 17) ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF128UI96( uiA96 ); + if ( sign || (shiftDist < 17) ) { softfloat_raiseFlags( softfloat_flag_invalid ); - return 0xFFFFFFFF; + return + (exp == 0x7FFF) && sig64 ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig64 |= UINT64_C( 0x0001000000000000 ); - z = sig64>>shiftCount; - if ( exact && ((uint64_t) z<<shiftCount != sig64) ) { + z = sig64>>shiftDist; + if ( exact && ((uint64_t) z<<shiftDist != sig64) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; diff --git a/source/f128M_to_ui64.c b/source/f128M_to_ui64.c index 5876be3..73f8e78 100644 --- a/source/f128M_to_ui64.c +++ b/source/f128M_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -57,31 +58,43 @@ uint_fast64_t { const uint32_t *aWPtr; uint32_t uiA96; - int32_t exp, shiftCount; - uint32_t sig96, sig[4]; - + bool sign; + int32_t exp; + uint32_t sig96; + int32_t shiftDist; + uint32_t sig[4]; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ aWPtr = (const uint32_t *) aPtr; uiA96 = aWPtr[indexWordHi( 4 )]; - exp = expF128UI96( uiA96 ); - shiftCount = 0x404F - exp; - if ( shiftCount < 17 ) { + sign = signF128UI96( uiA96 ); + exp = expF128UI96( uiA96 ); + sig96 = fracF128UI96( uiA96 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x404F - exp; + if ( shiftDist < 17 ) { softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return + (exp == 0x7FFF) + && (sig96 + || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] + | aWPtr[indexWord( 4, 0 )])) + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } - sig96 = fracF128UI96( uiA96 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( exp ) sig96 |= 0x00010000; sig[indexWord( 4, 3 )] = sig96; sig[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; sig[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; sig[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - softfloat_shiftRightJam128M( sig, shiftCount, sig ); + softfloat_shiftRightJam128M( sig, shiftDist, sig ); return softfloat_roundPackMToUI64( - signF128UI96( uiA96 ), - sig + indexMultiwordLo( 4, 3 ), - roundingMode, - exact - ); + sign, sig + indexMultiwordLo( 4, 3 ), roundingMode, exact ); } diff --git a/source/f128M_to_ui64_r_minMag.c b/source/f128M_to_ui64_r_minMag.c index 1c4f3ec..6a5357b 100644 --- a/source/f128M_to_ui64_r_minMag.c +++ b/source/f128M_to_ui64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" #ifdef SOFTFLOAT_FAST_INT64 @@ -55,41 +56,57 @@ uint_fast64_t f128M_to_ui64_r_minMag( const float128_t *aPtr, bool exact ) { const uint32_t *aWPtr; uint32_t uiA96; - int32_t exp, shiftCount; - uint32_t sig96, sig[4]; + bool sign; + int32_t exp; + uint32_t sig96; + int32_t shiftDist; + uint32_t sig[4]; uint64_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ aWPtr = (const uint32_t *) aPtr; uiA96 = aWPtr[indexWordHi( 4 )]; - exp = expF128UI96( uiA96 ); - shiftCount = 0x403E - exp; - if ( shiftCount < 0 ) goto invalid; + sign = signF128UI96( uiA96 ); + exp = expF128UI96( uiA96 ); + sig96 = fracF128UI96( uiA96 ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x403E - exp; + if ( shiftDist < 0 ) goto invalid; if ( exact ) { - sig96 = fracF128UI96( uiA96 ); if ( exp ) sig96 |= 0x00010000; sig[indexWord( 4, 3 )] = sig96; sig[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; sig[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; sig[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - softfloat_shiftRightJam128M( sig, shiftCount + 17, sig ); + softfloat_shiftRightJam128M( sig, shiftDist + 17, sig ); z = (uint64_t) sig[indexWord( 4, 2 )]<<32 | sig[indexWord( 4, 1 )]; - if ( signF128UI96( uiA96 ) && z ) goto invalid; + if ( sign && z ) goto invalid; if ( sig[indexWordLo( 4 )] ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } } else { - if ( 64 <= shiftCount ) return 0; - if ( signF128UI96( uiA96 ) ) goto invalid; + if ( 64 <= shiftDist ) return 0; + if ( sign ) goto invalid; z = UINT64_C( 0x8000000000000000 ) - | (uint64_t) fracF128UI96( uiA96 )<<47 + | (uint64_t) sig96<<47 | (uint64_t) aWPtr[indexWord( 4, 2 )]<<15 | aWPtr[indexWord( 4, 1 )]>>17; - z >>= shiftCount; + z >>= shiftDist; } return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return + (exp == 0x7FFF) + && (sig96 + || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] + | aWPtr[indexWord( 4, 0 )])) + ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } diff --git a/source/f128_to_i32.c b/source/f128_to_i32.c index d956bac..c5fa25d 100644 --- a/source/f128_to_i32.c +++ b/source/f128_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 ) @@ -47,8 +48,10 @@ int_fast32_t f128_to_i32( float128_t a, uint_fast8_t roundingMode, bool exact ) bool sign; int_fast32_t exp; uint_fast64_t sig64, sig0; - int_fast32_t shiftCount; + int_fast32_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.ui.v64; uiA0 = uA.ui.v0; @@ -56,13 +59,26 @@ int_fast32_t f128_to_i32( float128_t a, uint_fast8_t roundingMode, bool exact ) exp = expF128UI64( uiA64 ); sig64 = fracF128UI64( uiA64 ); sig0 = uiA0; - if ( (exp == 0x7FFF) && (sig64 | sig0) ) sign = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#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); - shiftCount = 0x4028 - exp; - if ( 0 < shiftCount ) { - sig64 = softfloat_shiftRightJam64( sig64, shiftCount ); - } + shiftDist = 0x4028 - exp; + if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); return softfloat_roundPackToI32( sign, sig64, roundingMode, exact ); } diff --git a/source/f128_to_i32_r_minMag.c b/source/f128_to_i32_r_minMag.c index 4c12c83..4106245 100644 --- a/source/f128_to_i32_r_minMag.c +++ b/source/f128_to_i32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 ) @@ -46,41 +47,50 @@ int_fast32_t f128_to_i32_r_minMag( float128_t a, bool exact ) uint_fast64_t uiA64, uiA0; int_fast32_t exp; uint_fast64_t sig64; - int_fast32_t shiftCount; + 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); - shiftCount = 0x402F - exp; - if ( 49 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( 49 <= shiftDist ) { if ( exact && (exp | sig64) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sign = signF128UI64( uiA64 ); - if ( shiftCount < 18 ) { + if ( shiftDist < 18 ) { if ( - sign && (shiftCount == 17) + sign && (shiftDist == 17) && (sig64 < UINT64_C( 0x0000000000020000 )) ) { if ( exact && sig64 ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } - } else { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ((exp == 0x7FFF) && sig64) ) return 0x7FFFFFFF; + return -0x7FFFFFFF - 1; } - 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>>shiftCount; + absZ = sig64>>shiftDist; if ( - exact && ((uint_fast64_t) (uint_fast32_t) absZ<<shiftCount != sig64) + exact && ((uint_fast64_t) (uint_fast32_t) absZ<<shiftDist != sig64) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } diff --git a/source/f128_to_i64.c b/source/f128_to_i64.c index 272fa2a..85471f5 100644 --- a/source/f128_to_i64.c +++ b/source/f128_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 ) @@ -47,10 +48,12 @@ int_fast64_t f128_to_i64( float128_t a, uint_fast8_t roundingMode, bool exact ) bool sign; int_fast32_t exp; uint_fast64_t sig64, sig0; - int_fast32_t shiftCount; + int_fast32_t shiftDist; struct uint128 sig128; struct uint64_extra sigExtra; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.ui.v64; uiA0 = uA.ui.v0; @@ -58,24 +61,31 @@ int_fast64_t f128_to_i64( float128_t a, uint_fast8_t roundingMode, bool exact ) exp = expF128UI64( uiA64 ); sig64 = fracF128UI64( uiA64 ); sig0 = uiA0; - shiftCount = 0x402F - exp; - if ( shiftCount <= 0 ) { - if ( shiftCount < -15 ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( shiftDist <= 0 ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( shiftDist < -15 ) { softfloat_raiseFlags( softfloat_flag_invalid ); return - ! sign || ((exp == 0x7FFF) && (sig64 | sig0)) - ? INT64_C( 0x7FFFFFFFFFFFFFFF ) - : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ sig64 |= UINT64_C( 0x0001000000000000 ); - if ( shiftCount ) { - sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftCount ); + 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, shiftCount ); + sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftDist ); sig64 = sigExtra.v; sig0 = sigExtra.extra; } diff --git a/source/f128_to_i64_r_minMag.c b/source/f128_to_i64_r_minMag.c index 54c1569..d3061a9 100644 --- a/source/f128_to_i64_r_minMag.c +++ b/source/f128_to_i64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 ) @@ -47,10 +48,12 @@ int_fast64_t f128_to_i64_r_minMag( float128_t a, bool exact ) bool sign; int_fast32_t exp; uint_fast64_t sig64, sig0; - int_fast32_t shiftCount; - int_fast16_t negShiftCount; + int_fast32_t shiftDist; + int_fast8_t negShiftDist; int_fast64_t absZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.ui.v64; uiA0 = uA.ui.v0; @@ -58,9 +61,13 @@ int_fast64_t f128_to_i64_r_minMag( float128_t a, bool exact ) exp = expF128UI64( uiA64 ); sig64 = fracF128UI64( uiA64 ); sig0 = uiA0; - shiftCount = 0x402F - exp; - if ( shiftCount < 0 ) { - if ( shiftCount < -14 ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( shiftDist < 0 ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( shiftDist < -14 ) { if ( (uiA64 == UINT64_C( 0xC03E000000000000 )) && (sig0 < UINT64_C( 0x0002000000000000 )) @@ -68,30 +75,35 @@ int_fast64_t f128_to_i64_r_minMag( float128_t a, bool exact ) if ( exact && sig0 ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } - } else { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ((exp == 0x7FFF) && (sig64 | sig0)) ) { - return UINT64_C( 0x7FFFFFFFFFFFFFFF ); - } + return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; } - 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 ); - negShiftCount = -shiftCount; - absZ = sig64<<negShiftCount | sig0>>(shiftCount & 63); - if ( exact && (uint64_t) (sig0<<negShiftCount) ) { + negShiftDist = -shiftDist; + absZ = sig64<<negShiftDist | sig0>>(shiftDist & 63); + if ( exact && (uint64_t) (sig0<<negShiftDist) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } } else { - if ( 49 <= shiftCount ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( 49 <= shiftDist ) { if ( exact && (exp | sig64 | sig0) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ sig64 |= UINT64_C( 0x0001000000000000 ); - absZ = sig64>>shiftCount; - if ( exact && (sig0 || (absZ<<shiftCount != sig64)) ) { + absZ = sig64>>shiftDist; + if ( exact && (sig0 || (absZ<<shiftDist != sig64)) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } } diff --git a/source/f128_to_ui32.c b/source/f128_to_ui32.c index f1a2528..7e1f4c8 100644 --- a/source/f128_to_ui32.c +++ b/source/f128_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast32_t @@ -47,21 +48,37 @@ uint_fast32_t uint_fast64_t uiA64, uiA0; bool sign; int_fast32_t exp; - uint_fast64_t sig64, sig0; - int_fast32_t shiftCount; + 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 ); - sig0 = uiA0; + 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 ); - sig64 |= (sig0 != 0); - shiftCount = 0x4028 - exp; - if ( 0 < shiftCount ) { - sig64 = softfloat_shiftRightJam64( sig64, shiftCount ); + shiftDist = 0x4028 - exp; + if ( 0 < shiftDist ) { + sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); } return softfloat_roundPackToUI32( sign, sig64, roundingMode, exact ); diff --git a/source/f128_to_ui32_r_minMag.c b/source/f128_to_ui32_r_minMag.c index fab7902..5e45bb6 100644 --- a/source/f128_to_ui32_r_minMag.c +++ b/source/f128_to_ui32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 ) @@ -46,28 +47,40 @@ uint_fast32_t f128_to_ui32_r_minMag( float128_t a, bool exact ) uint_fast64_t uiA64, uiA0; int_fast32_t exp; uint_fast64_t sig64; - int_fast32_t shiftCount; + 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); - shiftCount = 0x402F - exp; - if ( 49 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x402F - exp; + if ( 49 <= shiftDist ) { if ( exact && (exp | sig64) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } - if ( signF128UI64( uiA64 ) || (shiftCount < 17) ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF128UI64( uiA64 ); + if ( sign || (shiftDist < 17) ) { softfloat_raiseFlags( softfloat_flag_invalid ); - return 0xFFFFFFFF; + return + (exp == 0x7FFF) && sig64 ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig64 |= UINT64_C( 0x0001000000000000 ); - z = sig64>>shiftCount; - if ( exact && ((uint_fast64_t) z<<shiftCount != sig64) ) { + z = sig64>>shiftDist; + if ( exact && ((uint_fast64_t) z<<shiftDist != sig64) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; diff --git a/source/f128_to_ui64.c b/source/f128_to_ui64.c index bc7cd45..e394c22 100644 --- a/source/f128_to_ui64.c +++ b/source/f128_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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast64_t @@ -46,34 +47,46 @@ uint_fast64_t union ui128_f128 uA; uint_fast64_t uiA64, uiA0; bool sign; - int_fast32_t exp, shiftCount; + 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 ); - shiftCount = 0x402F - exp; - if ( shiftCount <= 0 ) { - if ( shiftCount < -15 ) { + 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 UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return + (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } - sig64 = fracF128UI64( uiA64 ) | UINT64_C( 0x0001000000000000 ); - sig0 = uiA0; - if ( shiftCount ) { - sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftCount ); + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig64 |= UINT64_C( 0x0001000000000000 ); + if ( shiftDist ) { + sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftDist ); sig64 = sig128.v64; sig0 = sig128.v0; } } else { - sig64 = fracF128UI64( uiA64 ); - sig0 = uiA0; + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); - sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftCount ); + sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftDist ); sig64 = sigExtra.v; sig0 = sigExtra.extra; } diff --git a/source/f128_to_ui64_r_minMag.c b/source/f128_to_ui64_r_minMag.c index 070d7f9..6bd0144 100644 --- a/source/f128_to_ui64_r_minMag.c +++ b/source/f128_to_ui64_r_minMag.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 3a+, 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: @@ -38,51 +38,68 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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; - int_fast32_t exp, shiftCount; + bool sign; + int_fast32_t exp; uint_fast64_t sig64, sig0; - int_fast16_t negShiftCount; + int_fast32_t shiftDist; + int_fast8_t negShiftDist; uint_fast64_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.ui.v64; uiA0 = uA.ui.v0; - exp = expF128UI64( uiA64 ); - shiftCount = 0x402F - exp; - if ( shiftCount < 0 ) { - if ( signF128UI64( uiA64 ) || (shiftCount < -15) ) goto invalid; - sig64 = fracF128UI64( uiA64 ) | UINT64_C( 0x0001000000000000 ); - sig0 = uiA0; - negShiftCount = -shiftCount; - z = sig64<<negShiftCount | sig0>>(shiftCount & 63); - if ( exact && (uint64_t) (sig0<<negShiftCount) ) { + 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 { - sig64 = fracF128UI64( uiA64 ); - sig0 = uiA0; - if ( 49 <= shiftCount ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( 49 <= shiftDist ) { if ( exact && (exp | sig64 | sig0) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } - if ( signF128UI64( uiA64 ) ) goto invalid; + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( sign ) goto invalid; sig64 |= UINT64_C( 0x0001000000000000 ); - z = sig64>>shiftCount; - if ( exact && (sig0 || (z<<shiftCount != sig64)) ) { + z = sig64>>shiftDist; + if ( exact && (sig0 || (z<<shiftDist != sig64)) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } } return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return + (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } diff --git a/source/f32_to_i32.c b/source/f32_to_i32.c index 733fce0..c80649a 100644 --- a/source/f32_to_i32.c +++ b/source/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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast32_t f32_to_i32( float32_t a, uint_fast8_t roundingMode, bool exact ) @@ -48,20 +49,35 @@ int_fast32_t f32_to_i32( float32_t a, uint_fast8_t roundingMode, bool exact ) int_fast16_t exp; uint_fast32_t sig; uint_fast64_t sig64; - int_fast16_t shiftCount; + int_fast16_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF32UI( uiA ); exp = expF32UI( uiA ); sig = fracF32UI( uiA ); - if ( (exp == 0xFF) && sig ) sign = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ( (exp == 0xFF) && sig ) { +#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 ) sig |= 0x00800000; sig64 = (uint_fast64_t) sig<<32; - shiftCount = 0xAF - exp; - if ( 0 < shiftCount ) { - sig64 = softfloat_shiftRightJam64( sig64, shiftCount ); - } + shiftDist = 0xAF - exp; + if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); return softfloat_roundPackToI32( sign, sig64, roundingMode, exact ); } diff --git a/source/f32_to_i32_r_minMag.c b/source/f32_to_i32_r_minMag.c index e27b064..d2e4b92 100644 --- a/source/f32_to_i32_r_minMag.c +++ b/source/f32_to_i32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast32_t f32_to_i32_r_minMag( float32_t a, bool exact ) @@ -46,32 +47,40 @@ int_fast32_t f32_to_i32_r_minMag( float32_t a, bool exact ) uint_fast32_t uiA; int_fast16_t exp; uint_fast32_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; bool sign; int_fast32_t absZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; exp = expF32UI( uiA ); sig = fracF32UI( uiA ); - shiftCount = 0x9E - exp; - if ( 32 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x9E - exp; + if ( 32 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sign = signF32UI( uiA ); - if ( shiftCount <= 0 ) { - if ( uiA != packToF32UI( 1, 0x9E, 0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ((exp == 0xFF) && sig) ) return 0x7FFFFFFF; - } - return -0x7FFFFFFF - 1; + if ( shiftDist <= 0 ) { + if ( uiA == packToF32UI( 1, 0x9E, 0 ) ) return -0x7FFFFFFF - 1; + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0xFF) && sig ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig = (sig | 0x00800000)<<8; - absZ = sig>>shiftCount; - if ( exact && ((uint_fast32_t) absZ<<shiftCount != sig) ) { + absZ = sig>>shiftDist; + if ( exact && ((uint_fast32_t) absZ<<shiftDist != sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return sign ? -absZ : absZ; diff --git a/source/f32_to_i64.c b/source/f32_to_i64.c index fbdbffb..b354f6c 100644 --- a/source/f32_to_i64.c +++ b/source/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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast64_t f32_to_i64( float32_t a, uint_fast8_t roundingMode, bool exact ) @@ -47,7 +48,7 @@ int_fast64_t f32_to_i64( float32_t a, uint_fast8_t roundingMode, bool exact ) bool sign; int_fast16_t exp; uint_fast32_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; #ifdef SOFTFLOAT_FAST_INT64 uint_fast64_t sig64, extra; struct uint64_extra sig64Extra; @@ -55,25 +56,30 @@ int_fast64_t f32_to_i64( float32_t a, uint_fast8_t roundingMode, bool exact ) uint32_t extSig[3]; #endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF32UI( uiA ); exp = expF32UI( uiA ); sig = fracF32UI( uiA ); - shiftCount = 0xBE - exp; - if ( shiftCount < 0 ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if ( shiftDist < 0 ) { softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ((exp == 0xFF) && sig) ) { - return INT64_C( 0x7FFFFFFFFFFFFFFF ); - } - return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + return + (exp == 0xFF) && sig ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( exp ) sig |= 0x00800000; #ifdef SOFTFLOAT_FAST_INT64 sig64 = (uint_fast64_t) sig<<40; extra = 0; - if ( shiftCount ) { - sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftCount ); + if ( shiftDist ) { + sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftDist ); sig64 = sig64Extra.v; extra = sig64Extra.extra; } @@ -82,7 +88,7 @@ int_fast64_t f32_to_i64( float32_t a, uint_fast8_t roundingMode, bool exact ) extSig[indexWord( 3, 2 )] = sig<<8; extSig[indexWord( 3, 1 )] = 0; extSig[indexWord( 3, 0 )] = 0; - if ( shiftCount ) softfloat_shiftRightJam96M( extSig, shiftCount, extSig ); + if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); return softfloat_roundPackMToI64( sign, extSig, roundingMode, exact ); #endif diff --git a/source/f32_to_i64_r_minMag.c b/source/f32_to_i64_r_minMag.c index f4875f3..af2b28b 100644 --- a/source/f32_to_i64_r_minMag.c +++ b/source/f32_to_i64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast64_t f32_to_i64_r_minMag( float32_t a, bool exact ) @@ -46,37 +47,45 @@ int_fast64_t f32_to_i64_r_minMag( float32_t a, bool exact ) uint_fast32_t uiA; int_fast16_t exp; uint_fast32_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; bool sign; uint_fast64_t sig64; int_fast64_t absZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; exp = expF32UI( uiA ); sig = fracF32UI( uiA ); - shiftCount = 0xBE - exp; - if ( 64 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if ( 64 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sign = signF32UI( uiA ); - if ( shiftCount <= 0 ) { - if ( uiA != packToF32UI( 1, 0xBE, 0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ((exp == 0xFF) && sig) ) { - return INT64_C( 0x7FFFFFFFFFFFFFFF ); - } + if ( shiftDist <= 0 ) { + if ( uiA == packToF32UI( 1, 0xBE, 0 ) ) { + return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; } - return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0xFF) && sig ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig |= 0x00800000; sig64 = (uint_fast64_t) sig<<40; - absZ = sig64>>shiftCount; - shiftCount = 40 - shiftCount; - if ( exact && (shiftCount < 0) && (uint32_t) (sig<<(shiftCount & 31)) ) { + absZ = sig64>>shiftDist; + shiftDist = 40 - shiftDist; + if ( exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31)) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return sign ? -absZ : absZ; diff --git a/source/f32_to_ui32.c b/source/f32_to_ui32.c index a0acbd1..1979dd5 100644 --- a/source/f32_to_ui32.c +++ b/source/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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast32_t f32_to_ui32( float32_t a, uint_fast8_t roundingMode, bool exact ) @@ -48,19 +49,35 @@ uint_fast32_t f32_to_ui32( float32_t a, uint_fast8_t roundingMode, bool exact ) int_fast16_t exp; uint_fast32_t sig; uint_fast64_t sig64; - int_fast16_t shiftCount; + int_fast16_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF32UI( uiA ); exp = expF32UI( uiA ); sig = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) + if ( (exp == 0xFF) && sig ) { +#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 ) sig |= 0x00800000; sig64 = (uint_fast64_t) sig<<32; - shiftCount = 0xAF - exp; - if ( 0 < shiftCount ) { - sig64 = softfloat_shiftRightJam64( sig64, shiftCount ); - } + shiftDist = 0xAF - exp; + if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); return softfloat_roundPackToUI32( sign, sig64, roundingMode, exact ); } diff --git a/source/f32_to_ui32_r_minMag.c b/source/f32_to_ui32_r_minMag.c index d262755..9979b2c 100644 --- a/source/f32_to_ui32_r_minMag.c +++ b/source/f32_to_ui32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast32_t f32_to_ui32_r_minMag( float32_t a, bool exact ) @@ -46,30 +47,42 @@ uint_fast32_t f32_to_ui32_r_minMag( float32_t a, bool exact ) uint_fast32_t uiA; int_fast16_t exp; uint_fast32_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; + bool sign; uint_fast32_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; exp = expF32UI( uiA ); sig = fracF32UI( uiA ); - shiftCount = 0x9E - exp; - if ( 32 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x9E - exp; + if ( 32 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } - if ( signF32UI( uiA ) || (shiftCount < 0) ) goto invalid; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI( uiA ); + if ( sign || (shiftDist < 0) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0xFF) && sig ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig = (sig | 0x00800000)<<8; - z = sig>>shiftCount; - if ( exact && (z<<shiftCount != sig) ) { + z = sig>>shiftDist; + if ( exact && (z<<shiftDist != sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return 0xFFFFFFFF; } diff --git a/source/f32_to_ui64.c b/source/f32_to_ui64.c index a715e03..6be8537 100644 --- a/source/f32_to_ui64.c +++ b/source/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 3a+, 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: @@ -38,10 +38,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" -#ifdef SOFTFLOAT_FAST_INT64 - uint_fast64_t f32_to_ui64( float32_t a, uint_fast8_t roundingMode, bool exact ) { union ui32_f32 uA; @@ -49,63 +48,50 @@ uint_fast64_t f32_to_ui64( float32_t a, uint_fast8_t roundingMode, bool exact ) bool sign; int_fast16_t exp; uint_fast32_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; +#ifdef SOFTFLOAT_FAST_INT64 uint_fast64_t sig64, extra; struct uint64_extra sig64Extra; +#else + uint32_t extSig[3]; +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF32UI( uiA ); exp = expF32UI( uiA ); sig = fracF32UI( uiA ); - shiftCount = 0xBE - exp; - if ( shiftCount < 0 ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if ( shiftDist < 0 ) { softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return + (exp == 0xFF) && sig ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( exp ) sig |= 0x00800000; +#ifdef SOFTFLOAT_FAST_INT64 sig64 = (uint_fast64_t) sig<<40; extra = 0; - if ( shiftCount ) { - sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftCount ); + if ( shiftDist ) { + sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftDist ); sig64 = sig64Extra.v; extra = sig64Extra.extra; } return softfloat_roundPackToUI64( sign, sig64, extra, roundingMode, exact ); - -} - #else - -uint_fast64_t f32_to_ui64( float32_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui32_f32 uA; - uint32_t uiA; - bool sign; - int_fast16_t exp; - uint32_t sig; - int_fast16_t shiftCount; - uint32_t extSig[3]; - - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - shiftCount = 0xBE - exp; - if ( shiftCount < 0 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); - } - if ( exp ) sig |= 0x00800000; extSig[indexWord( 3, 2 )] = sig<<8; extSig[indexWord( 3, 1 )] = 0; extSig[indexWord( 3, 0 )] = 0; - if ( shiftCount ) softfloat_shiftRightJam96M( extSig, shiftCount, extSig ); + if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); return softfloat_roundPackMToUI64( sign, extSig, roundingMode, exact ); +#endif } -#endif - diff --git a/source/f32_to_ui64_r_minMag.c b/source/f32_to_ui64_r_minMag.c index c5fc11a..0d5fe5b 100644 --- a/source/f32_to_ui64_r_minMag.c +++ b/source/f32_to_ui64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast64_t f32_to_ui64_r_minMag( float32_t a, bool exact ) @@ -46,32 +47,44 @@ uint_fast64_t f32_to_ui64_r_minMag( float32_t a, bool exact ) uint_fast32_t uiA; int_fast16_t exp; uint_fast32_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; + bool sign; uint_fast64_t sig64, z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; exp = expF32UI( uiA ); sig = fracF32UI( uiA ); - shiftCount = 0xBE - exp; - if ( 64 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if ( 64 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } - if ( signF32UI( uiA ) || (shiftCount < 0) ) goto invalid; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI( uiA ); + if ( sign || (shiftDist < 0) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0xFF) && sig ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig |= 0x00800000; sig64 = (uint_fast64_t) sig<<40; - z = sig64>>shiftCount; - shiftCount = 40 - shiftCount; - if ( exact && (shiftCount < 0) && (uint32_t) (sig<<(shiftCount & 31)) ) { + z = sig64>>shiftDist; + shiftDist = 40 - shiftDist; + if ( exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31)) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); } diff --git a/source/f64_to_i32.c b/source/f64_to_i32.c index f51d37b..b41aac6 100644 --- a/source/f64_to_i32.c +++ b/source/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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact ) @@ -47,17 +48,34 @@ int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact ) bool sign; int_fast16_t exp; uint_fast64_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); - if ( (exp == 0x7FF) && sig ) sign = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ( (exp == 0x7FF) && sig ) { +#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 ) sig |= UINT64_C( 0x0010000000000000 ); - shiftCount = 0x42C - exp; - if ( 0 < shiftCount ) sig = softfloat_shiftRightJam64( sig, shiftCount ); + shiftDist = 0x42C - exp; + if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist ); return softfloat_roundPackToI32( sign, sig, roundingMode, exact ); } diff --git a/source/f64_to_i32_r_minMag.c b/source/f64_to_i32_r_minMag.c index 3030ba6..ae3171e 100644 --- a/source/f64_to_i32_r_minMag.c +++ b/source/f64_to_i32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast32_t f64_to_i32_r_minMag( float64_t a, bool exact ) @@ -46,38 +47,47 @@ int_fast32_t f64_to_i32_r_minMag( float64_t a, bool exact ) uint_fast64_t uiA; int_fast16_t exp; uint_fast64_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; bool sign; int_fast32_t absZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; exp = expF64UI( uiA ); sig = fracF64UI( uiA ); - shiftCount = 0x433 - exp; - if ( 53 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if ( 53 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sign = signF64UI( uiA ); - if ( shiftCount < 22 ) { + if ( shiftDist < 22 ) { if ( sign && (exp == 0x41E) && (sig < UINT64_C( 0x0000000000200000 )) ) { if ( exact && sig ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } - } else { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ((exp == 0x7FF) && sig) ) return 0x7FFFFFFF; + return -0x7FFFFFFF - 1; } - return -0x7FFFFFFF - 1; + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FF) && sig ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig |= UINT64_C( 0x0010000000000000 ); - absZ = sig>>shiftCount; - if ( exact && ((uint_fast64_t) (uint_fast32_t) absZ<<shiftCount != sig) ) { + absZ = sig>>shiftDist; + if ( exact && ((uint_fast64_t) (uint_fast32_t) absZ<<shiftDist != sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return sign ? -absZ : absZ; diff --git a/source/f64_to_i64.c b/source/f64_to_i64.c index 3d93ea6..58cb45b 100644 --- a/source/f64_to_i64.c +++ b/source/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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast64_t f64_to_i64( float64_t a, uint_fast8_t roundingMode, bool exact ) @@ -47,61 +48,56 @@ int_fast64_t f64_to_i64( float64_t a, uint_fast8_t roundingMode, bool exact ) bool sign; int_fast16_t exp; uint_fast64_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; #ifdef SOFTFLOAT_FAST_INT64 struct uint64_extra sigExtra; #else uint32_t extSig[3]; #endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftCount = 0x433 - exp; + shiftDist = 0x433 - exp; #ifdef SOFTFLOAT_FAST_INT64 - if ( shiftCount <= 0 ) { - if ( shiftCount < -11 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - ! sign - || ((exp == 0x7FF) - && (sig != UINT64_C( 0x0010000000000000 ))) - ? INT64_C( 0x7FFFFFFFFFFFFFFF ) - : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; - } - sigExtra.v = sig<<-shiftCount; + if ( shiftDist <= 0 ) { + if ( shiftDist < -11 ) goto invalid; + sigExtra.v = sig<<-shiftDist; sigExtra.extra = 0; } else { - sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftCount ); + sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); } return softfloat_roundPackToI64( sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); #else extSig[indexWord( 3, 0 )] = 0; - if ( shiftCount <= 0 ) { - if ( shiftCount < -11 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - ! sign - || ((exp == 0x7FF) - && (sig != UINT64_C( 0x0010000000000000 ))) - ? INT64_C( 0x7FFFFFFFFFFFFFFF ) - : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; - } - sig <<= -shiftCount; + if ( shiftDist <= 0 ) { + if ( shiftDist < -11 ) goto invalid; + sig <<= -shiftDist; extSig[indexWord( 3, 2 )] = sig>>32; extSig[indexWord( 3, 1 )] = sig; } else { extSig[indexWord( 3, 2 )] = sig>>32; extSig[indexWord( 3, 1 )] = sig; - softfloat_shiftRightJam96M( extSig, shiftCount, extSig ); + softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); } return softfloat_roundPackMToI64( sign, extSig, roundingMode, exact ); #endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FF) && fracF64UI( uiA ) ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } diff --git a/source/f64_to_i64_r_minMag.c b/source/f64_to_i64_r_minMag.c index d906659..003e165 100644 --- a/source/f64_to_i64_r_minMag.c +++ b/source/f64_to_i64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast64_t f64_to_i64_r_minMag( float64_t a, bool exact ) @@ -47,37 +48,49 @@ int_fast64_t f64_to_i64_r_minMag( float64_t a, bool exact ) bool sign; int_fast16_t exp; uint_fast64_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; int_fast64_t absZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); - shiftCount = 0x433 - exp; - if ( shiftCount <= 0 ) { - if ( shiftCount < -10 ) { - if ( uiA != packToF64UI( 1, 0x43E, 0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ((exp == 0x7FF) && sig) ) { - return INT64_C( 0x7FFFFFFFFFFFFFFF ); - } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if ( shiftDist <= 0 ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( shiftDist < -10 ) { + if ( uiA == packToF64UI( 1, 0x43E, 0 ) ) { + return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; } - return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FF) && sig ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ sig |= UINT64_C( 0x0010000000000000 ); - absZ = sig<<-shiftCount; + absZ = sig<<-shiftDist; } else { - if ( 53 <= shiftCount ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( 53 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ sig |= UINT64_C( 0x0010000000000000 ); - absZ = sig>>shiftCount; - if ( exact && (absZ<<shiftCount != sig) ) { + absZ = sig>>shiftDist; + if ( exact && (absZ<<shiftDist != sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } } diff --git a/source/f64_to_ui32.c b/source/f64_to_ui32.c index 55394f3..6027c2f 100644 --- a/source/f64_to_ui32.c +++ b/source/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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast32_t f64_to_ui32( float64_t a, uint_fast8_t roundingMode, bool exact ) @@ -47,16 +48,34 @@ uint_fast32_t f64_to_ui32( float64_t a, uint_fast8_t roundingMode, bool exact ) bool sign; int_fast16_t exp; uint_fast64_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) + if ( (exp == 0x7FF) && sig ) { +#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 ) sig |= UINT64_C( 0x0010000000000000 ); - shiftCount = 0x42C - exp; - if ( 0 < shiftCount ) sig = softfloat_shiftRightJam64( sig, shiftCount ); + shiftDist = 0x42C - exp; + if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist ); return softfloat_roundPackToUI32( sign, sig, roundingMode, exact ); } diff --git a/source/f64_to_ui32_r_minMag.c b/source/f64_to_ui32_r_minMag.c index 4ceb3de..8d0dc71 100644 --- a/source/f64_to_ui32_r_minMag.c +++ b/source/f64_to_ui32_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast32_t f64_to_ui32_r_minMag( float64_t a, bool exact ) @@ -46,27 +47,39 @@ uint_fast32_t f64_to_ui32_r_minMag( float64_t a, bool exact ) uint_fast64_t uiA; int_fast16_t exp; uint_fast64_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; + bool sign; uint_fast32_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; exp = expF64UI( uiA ); sig = fracF64UI( uiA ); - shiftCount = 0x433 - exp; - if ( 53 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if ( 53 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } - if ( signF64UI( uiA ) || (shiftCount < 21) ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI( uiA ); + if ( sign || (shiftDist < 21) ) { softfloat_raiseFlags( softfloat_flag_invalid ); - return 0xFFFFFFFF; + return + (exp == 0x7FF) && sig ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig |= UINT64_C( 0x0010000000000000 ); - z = sig>>shiftCount; - if ( exact && ((uint_fast64_t) z<<shiftCount != sig) ) { + z = sig>>shiftDist; + if ( exact && ((uint_fast64_t) z<<shiftDist != sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; diff --git a/source/f64_to_ui64.c b/source/f64_to_ui64.c index 89a9096..636d70c 100644 --- a/source/f64_to_ui64.c +++ b/source/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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast64_t f64_to_ui64( float64_t a, uint_fast8_t roundingMode, bool exact ) @@ -47,51 +48,56 @@ uint_fast64_t f64_to_ui64( float64_t a, uint_fast8_t roundingMode, bool exact ) bool sign; int_fast16_t exp; uint_fast64_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; #ifdef SOFTFLOAT_FAST_INT64 struct uint64_extra sigExtra; #else uint32_t extSig[3]; #endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftCount = 0x433 - exp; + shiftDist = 0x433 - exp; #ifdef SOFTFLOAT_FAST_INT64 - if ( shiftCount <= 0 ) { - if ( shiftCount < -11 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); - } - sigExtra.v = sig<<-shiftCount; + if ( shiftDist <= 0 ) { + if ( shiftDist < -11 ) goto invalid; + sigExtra.v = sig<<-shiftDist; sigExtra.extra = 0; } else { - sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftCount ); + sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); } return softfloat_roundPackToUI64( sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); #else extSig[indexWord( 3, 0 )] = 0; - if ( shiftCount <= 0 ) { - if ( shiftCount < -11 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); - } - sig <<= -shiftCount; + if ( shiftDist <= 0 ) { + if ( shiftDist < -11 ) goto invalid; + sig <<= -shiftDist; extSig[indexWord( 3, 2 )] = sig>>32; extSig[indexWord( 3, 1 )] = sig; } else { extSig[indexWord( 3, 2 )] = sig>>32; extSig[indexWord( 3, 1 )] = sig; - softfloat_shiftRightJam96M( extSig, shiftCount, extSig ); + softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); } return softfloat_roundPackMToUI64( sign, extSig, roundingMode, exact ); #endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FF) && fracF64UI( uiA ) ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } diff --git a/source/f64_to_ui64_r_minMag.c b/source/f64_to_ui64_r_minMag.c index 5eb62c9..e54c930 100644 --- a/source/f64_to_ui64_r_minMag.c +++ b/source/f64_to_ui64_r_minMag.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast64_t f64_to_ui64_r_minMag( float64_t a, bool exact ) @@ -46,35 +47,47 @@ uint_fast64_t f64_to_ui64_r_minMag( float64_t a, bool exact ) uint_fast64_t uiA; int_fast16_t exp; uint_fast64_t sig; - int_fast16_t shiftCount; + int_fast16_t shiftDist; + bool sign; uint_fast64_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; exp = expF64UI( uiA ); sig = fracF64UI( uiA ); - shiftCount = 0x433 - exp; - if ( 53 <= shiftCount ) { + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if ( 53 <= shiftDist ) { if ( exact && (exp | sig) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return 0; } - if ( signF64UI( uiA ) ) goto invalid; - if ( shiftCount <= 0 ) { - if ( shiftCount < -11 ) goto invalid; - z = (sig | UINT64_C( 0x0010000000000000 ))<<-shiftCount; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI( uiA ); + if ( sign ) goto invalid; + if ( shiftDist <= 0 ) { + if ( shiftDist < -11 ) goto invalid; + z = (sig | UINT64_C( 0x0010000000000000 ))<<-shiftDist; } else { sig |= UINT64_C( 0x0010000000000000 ); - z = sig>>shiftCount; - if ( exact && (uint64_t) (sig<<(-shiftCount & 63)) ) { + z = sig>>shiftDist; + if ( exact && (uint64_t) (sig<<(-shiftDist & 63)) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } } return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return + (exp == 0x7FF) && sig ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } diff --git a/source/s_roundPackMToI64.c b/source/s_roundPackMToI64.c index 1af0580..4d5efbb 100644 --- a/source/s_roundPackMToI64.c +++ b/source/s_roundPackMToI64.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast64_t @@ -51,6 +52,8 @@ int_fast64_t union { uint64_t ui; int64_t i; } uZ; int64_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ roundNearEven = (roundingMode == softfloat_round_near_even); sigExtra = extSigPtr[indexWordLo( 3 )]; doIncrement = (0x80000000 <= sigExtra); @@ -75,11 +78,11 @@ int_fast64_t softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return - sign ? -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1 - : INT64_C( 0x7FFFFFFFFFFFFFFF ); + return sign ? i64_fromNegOverflow : i64_fromPosOverflow; } diff --git a/source/s_roundPackMToUI64.c b/source/s_roundPackMToUI64.c index 0a57437..1a64fdf 100644 --- a/source/s_roundPackMToUI64.c +++ b/source/s_roundPackMToUI64.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 3a+, 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: @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast64_t @@ -49,6 +50,8 @@ uint_fast64_t bool doIncrement; uint64_t sig; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ roundNearEven = (roundingMode == softfloat_round_near_even); sigExtra = extSigPtr[indexWordLo( 3 )]; doIncrement = (0x80000000 <= sigExtra); @@ -71,9 +74,11 @@ uint_fast64_t softfloat_exceptionFlags |= softfloat_flag_inexact; } return sig; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } diff --git a/source/s_roundPackToI32.c b/source/s_roundPackToI32.c index dc27cf8..3ece8f0 100644 --- a/source/s_roundPackToI32.c +++ b/source/s_roundPackToI32.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 3a+, 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 @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast32_t @@ -50,6 +51,8 @@ int_fast32_t union { uint32_t ui; int32_t i; } uZ; int_fast32_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ roundNearEven = (roundingMode == softfloat_round_near_even); roundIncrement = 0x40; if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { @@ -71,9 +74,11 @@ int_fast32_t softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return sign ? -0x7FFFFFFF - 1 : 0x7FFFFFFF; + return sign ? i32_fromNegOverflow : i32_fromPosOverflow; } diff --git a/source/s_roundPackToI64.c b/source/s_roundPackToI64.c index 2cc8319..ebef7f3 100644 --- a/source/s_roundPackToI64.c +++ b/source/s_roundPackToI64.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 3a+, 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 @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast64_t @@ -53,6 +54,8 @@ int_fast64_t 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) ) { @@ -76,11 +79,11 @@ int_fast64_t softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return - sign ? -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1 - : INT64_C( 0x7FFFFFFFFFFFFFFF ); + return sign ? i64_fromNegOverflow : i64_fromPosOverflow; } diff --git a/source/s_roundPackToUI32.c b/source/s_roundPackToUI32.c index 1ffa76a..f0021fe 100644 --- a/source/s_roundPackToUI32.c +++ b/source/s_roundPackToUI32.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 3a+, 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 @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast32_t @@ -48,6 +49,8 @@ uint_fast32_t uint_fast8_t roundIncrement, roundBits; uint_fast32_t z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ roundNearEven = (roundingMode == softfloat_round_near_even); roundIncrement = 0x40; if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { @@ -67,9 +70,11 @@ uint_fast32_t softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return 0xFFFFFFFF; + return sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; } diff --git a/source/s_roundPackToUI64.c b/source/s_roundPackToUI64.c index 069bdfb..fada184 100644 --- a/source/s_roundPackToUI64.c +++ b/source/s_roundPackToUI64.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 3a+, 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 @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdint.h> #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast64_t @@ -51,6 +52,8 @@ uint_fast64_t { bool roundNearEven, doIncrement; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ roundNearEven = (roundingMode == softfloat_round_near_even); doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { @@ -72,9 +75,11 @@ uint_fast64_t softfloat_exceptionFlags |= softfloat_flag_inexact; } return sig; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } |