diff options
Diffstat (limited to 'softfloat/s_roundPackToF64.c')
-rw-r--r-- | softfloat/s_roundPackToF64.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/softfloat/s_roundPackToF64.c b/softfloat/s_roundPackToF64.c index e56493e..aaff008 100644 --- a/softfloat/s_roundPackToF64.c +++ b/softfloat/s_roundPackToF64.c @@ -2,9 +2,9 @@ /*============================================================================ This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3a, by John R. Hauser. +Package, Release 3d, by John R. Hauser. -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -50,6 +50,8 @@ float64_t uint_fast64_t uiZ; union ui64_f64 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ roundingMode = softfloat_roundingMode; roundNearEven = (roundingMode == softfloat_round_near_even); roundIncrement = 0x200; @@ -61,13 +63,16 @@ float64_t : 0; } roundBits = sig & 0x3FF; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( 0x7FD <= (uint16_t) exp ) { if ( exp < 0 ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ isTiny = - (softfloat_detectTininess - == softfloat_tininess_beforeRounding) - || (exp < -1) - || (sig + roundIncrement < UINT64_C( 0x8000000000000000 )); + (softfloat_detectTininess == softfloat_tininess_beforeRounding) + || (exp < -1) + || (sig + roundIncrement < UINT64_C( 0x8000000000000000 )); sig = softfloat_shiftRightJam64( sig, -exp ); exp = 0; roundBits = sig & 0x3FF; @@ -78,16 +83,32 @@ float64_t (0x7FD < exp) || (UINT64_C( 0x8000000000000000 ) <= sig + roundIncrement) ) { + /*---------------------------------------------------------------- + *----------------------------------------------------------------*/ softfloat_raiseFlags( softfloat_flag_overflow | softfloat_flag_inexact ); uiZ = packToF64UI( sign, 0x7FF, 0 ) - ! roundIncrement; goto uiZ; } } - if ( roundBits ) softfloat_exceptionFlags |= softfloat_flag_inexact; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ sig = (sig + roundIncrement)>>10; + if ( roundBits ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; +#ifdef SOFTFLOAT_ROUND_ODD + if ( roundingMode == softfloat_round_odd ) { + sig |= 1; + goto packReturn; + } +#endif + } sig &= ~(uint_fast64_t) (! (roundBits ^ 0x200) & roundNearEven); - uiZ = packToF64UI( sign, sig ? exp : 0, sig ); + if ( ! sig ) exp = 0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + packReturn: + uiZ = packToF64UI( sign, exp, sig ); uiZ: uZ.ui = uiZ; return uZ.f; |