uint_fast64_t f32_to_ui64( float32_t a, uint_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 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 ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ shiftDist = 0xBE - exp; if ( shiftDist < 0 ) { softfloat_raiseFlags( softfloat_flag_invalid ); 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 ( shiftDist ) { sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftDist ); sig64 = sig64Extra.v; extra = sig64Extra.extra; } return softfloat_roundToUI64( sign, sig64, extra, roundingMode, exact ); #else extSig[indexWord( 3, 2 )] = sig<<8; extSig[indexWord( 3, 1 )] = 0; extSig[indexWord( 3, 0 )] = 0; if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); return softfloat_roundMToUI64( sign, extSig, roundingMode, exact ); #endif }
uint_fast64_t f128M_to_ui64( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) { const uint32_t *aWPtr; uint32_t uiA96; bool sign; int32_t exp; uint32_t sig96; int32_t shiftDist; uint32_t sig[4]; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ aWPtr = (const uint32_t *) aPtr; uiA96 = aWPtr[indexWordHi( 4 )]; 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, shiftDist, sig ); return softfloat_roundMToUI64( sign, sig + indexMultiwordLo( 4, 3 ), roundingMode, exact ); }
uint_fast64_t extF80M_to_ui64( const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) { const struct extFloat80M *aSPtr; uint_fast16_t uiA64; bool sign; int32_t exp; uint64_t sig; int32_t shiftDist; uint32_t extSig[3]; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ aSPtr = (const struct extFloat80M *) aPtr; uiA64 = aSPtr->signExp; sign = signExtF80UI64( uiA64 ); exp = expExtF80UI64( uiA64 ); sig = aSPtr->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; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ extSig[indexWord( 3, 2 )] = sig>>32; extSig[indexWord( 3, 1 )] = sig; extSig[indexWord( 3, 0 )] = 0; if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); return softfloat_roundMToUI64( sign, extSig, roundingMode, exact ); }