uint_fast64_t extF80_to_ui64( extFloat80_t a, uint_fast8_t roundingMode, bool exact ) { union { struct extFloat80M s; extFloat80_t f; } uA; uint_fast16_t uiA64; int_fast32_t exp, shiftCount; bool sign; uint_fast64_t sig, 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 ); sig = uA.s.signif; sigExtra = 0; if ( shiftCount ) { sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftCount ); sig = sig64Extra.v; sigExtra = sig64Extra.extra; } return softfloat_roundPackToUI64( sign, sig, sigExtra, roundingMode, exact ); }
uint_fast64_t f64_to_ui64( float64_t a, int_fast8_t roundingMode, bool exact ) { union ui64_f64 uA; uint_fast64_t uiA; bool sign; int_fast16_t exp; uint_fast64_t sig; int_fast16_t shiftCount; struct uint64_extra sigExtra; uA.f = a; uiA = uA.ui; sign = signF64UI( uiA ); exp = expF64UI( uiA ); sig = fracF64UI( uiA ); if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); shiftCount = 0x433 - exp; if ( shiftCount <= 0 ) { if ( 0x43E < exp ) { softfloat_raiseFlags( softfloat_flag_invalid ); return UINT64_C( 0xFFFFFFFFFFFFFFFF ); } sigExtra.v = sig<<( - shiftCount ); sigExtra.extra = 0; } else { sigExtra = softfloat_shift64ExtraRightJam( sig, 0, shiftCount ); } return softfloat_roundPackToUI64( sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); }
uint_fast64_t f128_to_ui64( float128_t a, uint_fast8_t roundingMode, bool exact ) { union ui128_f128 uA; uint_fast64_t uiA64, uiA0; bool sign; int_fast32_t exp; uint_fast64_t sig64, sig0; int_fast32_t shiftDist; struct uint128 sig128; struct uint64_extra sigExtra; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.ui.v64; uiA0 = uA.ui.v0; sign = signF128UI64( uiA64 ); exp = expF128UI64( uiA64 ); sig64 = fracF128UI64( uiA64 ); sig0 = uiA0; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ shiftDist = 0x402F - exp; if ( shiftDist <= 0 ) { /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ if ( shiftDist < -15 ) { softfloat_raiseFlags( softfloat_flag_invalid ); return (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ sig64 |= UINT64_C( 0x0001000000000000 ); if ( shiftDist ) { sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftDist ); sig64 = sig128.v64; sig0 = sig128.v0; } } else { /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftDist ); sig64 = sigExtra.v; sig0 = sigExtra.extra; } return softfloat_roundPackToUI64( sign, sig64, sig0, roundingMode, exact ); }
uint_fast64_t f64_to_ui64( float64_t a, uint_fast8_t roundingMode, bool exact ) { union ui64_f64 uA; uint_fast64_t uiA; bool sign; int_fast16_t exp; uint_fast64_t sig; int_fast16_t shiftCount; #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; #ifdef SOFTFLOAT_FAST_INT64 if ( shiftCount <= 0 ) { if ( shiftCount < -11 ) { softfloat_raiseFlags( softfloat_flag_invalid ); return UINT64_C( 0xFFFFFFFFFFFFFFFF ); } sigExtra.v = sig<<-shiftCount; sigExtra.extra = 0; } else { sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftCount ); } 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; extSig[indexWord( 3, 2 )] = sig>>32; extSig[indexWord( 3, 1 )] = sig; } else {
uint_fast64_t extF80_to_ui64( extFloat80_t a, uint_fast8_t roundingMode, bool exact ) { union { struct extFloat80M s; extFloat80_t f; } uA; uint_fast16_t uiA64; bool sign; 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; 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 ( shiftDist ) { sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); sig = sig64Extra.v; sigExtra = sig64Extra.extra; } return softfloat_roundPackToUI64( sign, sig, sigExtra, roundingMode, exact ); }
uint_fast64_t f128_to_ui64( float128_t a, uint_fast8_t roundingMode, bool exact ) { union ui128_f128 uA; uint_fast64_t uiA64, uiA0; bool sign; int_fast32_t exp, shiftCount; uint_fast64_t sig64, sig0; 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 ) { softfloat_raiseFlags( softfloat_flag_invalid ); return UINT64_C( 0xFFFFFFFFFFFFFFFF ); } sig64 = fracF128UI64( uiA64 ) | UINT64_C( 0x0001000000000000 ); sig0 = uiA0; if ( shiftCount ) { sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftCount ); sig64 = sig128.v64; sig0 = sig128.v0; } } else { sig64 = fracF128UI64( uiA64 ); sig0 = uiA0; if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftCount ); sig64 = sigExtra.v; sig0 = sigExtra.extra; } return softfloat_roundPackToUI64( sign, sig64, sig0, roundingMode, exact ); }