int_fast64_t f32_to_i64( float32_t a, int_fast8_t roundingMode, bool exact ) { union ui32_f32 uA; uint_fast32_t uiA; bool sign; int_fast16_t exp; uint_fast32_t sig; int_fast16_t shiftCount; uint_fast64_t sig64, extra; struct uint64_extra sig64Extra; 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 ); if ( ! sign || ( ( exp == 0xFF ) && sig ) ) { return INT64_C( 0x7FFFFFFFFFFFFFFF ); } return - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; } if ( exp ) sig |= 0x00800000; sig64 = (uint_fast64_t) sig<<40; extra = 0; if ( shiftCount ) { sig64Extra = softfloat_shift64ExtraRightJam( sig64, 0, shiftCount ); sig64 = sig64Extra.v; extra = sig64Extra.extra; } return softfloat_roundPackToI64( sign, sig64, extra, roundingMode, exact ); }
int_fast64_t f64_to_i64( 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 ! sign || ((exp == 0x7FF) && (sig != UINT64_C( 0x0010000000000000 ))) ? INT64_C( 0x7FFFFFFFFFFFFFFF ) : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; } sigExtra.v = sig<<-shiftCount; sigExtra.extra = 0; } else { sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftCount ); } 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; extSig[indexWord( 3, 2 )] = sig>>32; extSig[indexWord( 3, 1 )] = sig; } else {
int_fast64_t f128_to_i64( float128_t a, uint_fast8_t roundingMode, bool exact ) { union ui128_f128 uA; uint_fast64_t uiA64, uiA0; bool sign; int_fast32_t exp; uint_fast64_t sig64, sig0; int_fast32_t shiftDist; struct uint128 sig128; struct uint64_extra sigExtra; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uA.f = a; uiA64 = uA.ui.v64; uiA0 = uA.ui.v0; sign = signF128UI64( uiA64 ); exp = expF128UI64( uiA64 ); sig64 = fracF128UI64( uiA64 ); sig0 = uiA0; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ shiftDist = 0x402F - exp; if ( shiftDist <= 0 ) { /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ if ( shiftDist < -15 ) { softfloat_raiseFlags( softfloat_flag_invalid ); return (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ sig64 |= UINT64_C( 0x0001000000000000 ); if ( shiftDist ) { sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftDist ); sig64 = sig128.v64; sig0 = sig128.v0; } } else { /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftDist ); sig64 = sigExtra.v; sig0 = sigExtra.extra; } return softfloat_roundPackToI64( sign, sig64, sig0, roundingMode, exact ); }
int_fast64_t extF80_to_i64( 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 ) { /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ if ( shiftDist ) { softfloat_raiseFlags( softfloat_flag_invalid ); return (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ? i64_fromNaN : sign ? i64_fromNegOverflow : i64_fromPosOverflow; } /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ sigExtra = 0; } else { /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); sig = sig64Extra.v; sigExtra = sig64Extra.extra; } return softfloat_roundPackToI64( sign, sig, sigExtra, roundingMode, exact ); }
int_fast64_t f128_to_i64( float128_t a, uint_fast8_t roundingMode, bool exact ) { union ui128_f128 uA; uint_fast64_t uiA64, uiA0; bool sign; int_fast32_t exp; uint_fast64_t sig64, sig0; int_fast32_t shiftCount; 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; shiftCount = 0x402F - exp; if ( shiftCount <= 0 ) { if ( shiftCount < -15 ) { softfloat_raiseFlags( softfloat_flag_invalid ); return ! sign || ((exp == 0x7FFF) && (sig64 | sig0)) ? INT64_C( 0x7FFFFFFFFFFFFFFF ) : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; } sig64 |= UINT64_C( 0x0001000000000000 ); if ( shiftCount ) { sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftCount ); sig64 = sig128.v64; sig0 = sig128.v0; } } else { if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftCount ); sig64 = sigExtra.v; sig0 = sigExtra.extra; } return softfloat_roundPackToI64( sign, sig64, sig0, roundingMode, exact ); }
int_fast64_t extF80_to_i64( 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 shiftCount; 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 ) { softfloat_raiseFlags( softfloat_flag_invalid ); return ! sign || ((exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) ? INT64_C( 0x7FFFFFFFFFFFFFFF ) : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; } sigExtra = 0; } else { sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftCount ); sig = sig64Extra.v; sigExtra = sig64Extra.extra; } return softfloat_roundPackToI64( sign, sig, sigExtra, roundingMode, exact ); }
int_fast64_t f64_to_i64( 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 ! sign || ( ( exp == 0x7FF ) && ( sig != UINT64_C( 0x0010000000000000 ) ) ) ? INT64_C( 0x7FFFFFFFFFFFFFFF ) : - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; } sigExtra.v = sig<<( - shiftCount ); sigExtra.extra = 0; } else { sigExtra = softfloat_shift64ExtraRightJam( sig, 0, shiftCount ); } return softfloat_roundPackToI64( sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); }