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'.)
This commit is contained in:
John Hauser 2016-02-22 15:51:12 -08:00
parent 9dc9d10297
commit 45fdcf1c65
57 changed files with 1285 additions and 707 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 ) {
softfloat_raiseFlags( softfloat_flag_invalid );
return UINT64_C( 0xFFFFFFFFFFFFFFFF );
}
sign = signF128UI96( uiA96 );
exp = expF128UI96( uiA96 );
sig96 = fracF128UI96( uiA96 );
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
shiftDist = 0x404F - exp;
if ( shiftDist < 17 ) {
softfloat_raiseFlags( softfloat_flag_invalid );
return
(exp == 0x7FFF)
&& (sig96
|| (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )]
| aWPtr[indexWord( 4, 0 )]))
? ui64_fromNaN
: sign ? ui64_fromNegOverflow : ui64_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_roundPackMToUI64(
signF128UI96( uiA96 ),
sig + indexMultiwordLo( 4, 3 ),
roundingMode,
exact
);
sign, sig + indexMultiwordLo( 4, 3 ), roundingMode, exact );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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 );
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -2,10 +2,10 @@
/*============================================================================
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
Package, Release 3a, by John R. Hauser.
Package, Release 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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}