void f128M_to_extF80M( const float128_t *aPtr, extFloat80_t *zPtr ) { const uint32_t *aWPtr; struct extFloat80M *zSPtr; uint32_t uiA96; bool sign; int32_t exp; struct commonNaN commonNaN; uint32_t sig[4]; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ aWPtr = (const uint32_t *) aPtr; zSPtr = (struct extFloat80M *) zPtr; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uiA96 = aWPtr[indexWordHi( 4 )]; sign = signF128UI96( uiA96 ); exp = expF128UI96( uiA96 ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( exp == 0x7FFF ) { if ( softfloat_isNaNF128M( aWPtr ) ) { softfloat_f128MToCommonNaN( aWPtr, &commonNaN ); softfloat_commonNaNToExtF80M( &commonNaN, zSPtr ); return; } zSPtr->signExp = packToExtF80UI64( sign, 0x7FFF ); zSPtr->signif = UINT64_C( 0x8000000000000000 ); return; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ exp = softfloat_shiftNormSigF128M( aWPtr, 15, sig ); if ( exp == -128 ) { zSPtr->signExp = packToExtF80UI64( sign, 0 ); zSPtr->signif = 0; return; } if ( sig[indexWord( 4, 0 )] ) sig[indexWord( 4, 1 )] |= 1; softfloat_roundPackMToExtF80M( sign, exp, &sig[indexMultiwordHi( 4, 3 )], 80, zSPtr ); }
void softfloat_normRoundPackMToExtF80M( bool sign, int32_t exp, uint32_t *extSigPtr, uint_fast8_t roundingPrecision, struct extFloat80M *zSPtr ) { int_fast16_t shiftCount; uint32_t wordSig; shiftCount = 0; wordSig = extSigPtr[indexWord( 3, 2 )]; if ( ! wordSig ) { shiftCount = 32; wordSig = extSigPtr[indexWord( 3, 1 )]; if ( ! wordSig ) { shiftCount = 64; wordSig = extSigPtr[indexWord( 3, 0 )]; if ( ! wordSig ) { zSPtr->signExp = packToExtF80UI64( sign, 0 ); zSPtr->signif = 0; return; } } } shiftCount += softfloat_countLeadingZeros32( wordSig ); if ( shiftCount ) { exp -= shiftCount; softfloat_shiftLeft96M( extSigPtr, shiftCount, extSigPtr ); } softfloat_roundPackMToExtF80M( sign, exp, extSigPtr, roundingPrecision, zSPtr ); }
void extF80M_mul( const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) { const struct extFloat80M *aSPtr, *bSPtr; struct extFloat80M *zSPtr; uint_fast16_t uiA64; int32_t expA; uint_fast16_t uiB64; int32_t expB; bool signZ; uint_fast16_t exp, uiZ64; uint64_t uiZ0, sigA, sigB; int32_t expZ; uint32_t sigProd[4], *extSigZPtr; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ aSPtr = (const struct extFloat80M *) aPtr; bSPtr = (const struct extFloat80M *) bPtr; zSPtr = (struct extFloat80M *) zPtr; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uiA64 = aSPtr->signExp; expA = expExtF80UI64( uiA64 ); uiB64 = bSPtr->signExp; expB = expExtF80UI64( uiB64 ); signZ = signExtF80UI64( uiA64 ) ^ signExtF80UI64( uiB64 ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { if ( softfloat_tryPropagateNaNExtF80M( aSPtr, bSPtr, zSPtr ) ) return; if ( (! aSPtr->signif && (expA != 0x7FFF)) || (! bSPtr->signif && (expB != 0x7FFF)) ) { softfloat_invalidExtF80M( zSPtr ); return; } uiZ64 = packToExtF80UI64( signZ, 0x7FFF ); uiZ0 = UINT64_C( 0x8000000000000000 ); goto uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( ! expA ) expA = 1; sigA = aSPtr->signif; if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { if ( ! sigA ) goto zero; expA += softfloat_normExtF80SigM( &sigA ); } if ( ! expB ) expB = 1; sigB = bSPtr->signif; if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) { if ( ! sigB ) goto zero; expB += softfloat_normExtF80SigM( &sigB ); } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ expZ = expA + expB - 0x3FFE; softfloat_mul64To128M( sigA, sigB, sigProd ); if ( sigProd[indexWordLo( 4 )] ) sigProd[indexWord( 4, 1 )] |= 1; extSigZPtr = &sigProd[indexMultiwordHi( 4, 3 )]; if ( sigProd[indexWordHi( 4 )] < 0x80000000 ) { --expZ; softfloat_add96M( extSigZPtr, extSigZPtr, extSigZPtr ); } softfloat_roundPackMToExtF80M( signZ, expZ, extSigZPtr, extF80_roundingPrecision, zSPtr ); return; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ zero: uiZ64 = packToExtF80UI64( signZ, 0 ); uiZ0 = 0; uiZ: zSPtr->signExp = uiZ64; zSPtr->signif = uiZ0; }