void extF80M_to_f128M( const extFloat80_t *aPtr, float128_t *zPtr ) { const struct extFloat80M *aSPtr; uint32_t *zWPtr; uint_fast16_t uiA64; bool sign; int32_t exp; uint64_t sig; struct commonNaN commonNaN; uint32_t uiZ96; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ aSPtr = (const struct extFloat80M *) aPtr; zWPtr = (uint32_t *) zPtr; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uiA64 = aSPtr->signExp; sign = signExtF80UI64( uiA64 ); exp = expExtF80UI64( uiA64 ); sig = aSPtr->signif; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ zWPtr[indexWord( 4, 0 )] = 0; if ( exp == 0x7FFF ) { if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { softfloat_extF80MToCommonNaN( aSPtr, &commonNaN ); softfloat_commonNaNToF128M( &commonNaN, zWPtr ); return; } uiZ96 = packToF128UI96( sign, 0x7FFF, 0 ); goto uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( exp ) --exp; if ( ! (sig & UINT64_C( 0x8000000000000000 )) ) { if ( ! sig ) { uiZ96 = packToF128UI96( sign, 0, 0 ); goto uiZ; } exp += softfloat_normExtF80SigM( &sig ); } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ zWPtr[indexWord( 4, 1 )] = (uint32_t) sig<<17; sig >>= 15; zWPtr[indexWord( 4, 2 )] = sig; if ( exp < 0 ) { zWPtr[indexWordHi( 4 )] = sig>>32; softfloat_shiftRight96M( &zWPtr[indexMultiwordHi( 4, 3 )], -exp, &zWPtr[indexMultiwordHi( 4, 3 )] ); exp = 0; sig = (uint64_t) zWPtr[indexWordHi( 4 )]<<32; }
float32_t extF80M_to_f32( const extFloat80_t *aPtr ) { const struct extFloat80M *aSPtr; uint_fast16_t uiA64; bool sign; int32_t exp; uint64_t sig; struct commonNaN commonNaN; uint32_t uiZ, sig32; union ui32_f32 uZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ aSPtr = (const struct extFloat80M *) aPtr; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uiA64 = aSPtr->signExp; sign = signExtF80UI64( uiA64 ); exp = expExtF80UI64( uiA64 ); sig = aSPtr->signif; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( exp == 0x7FFF ) { if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { softfloat_extF80MToCommonNaN( aSPtr, &commonNaN ); uiZ = softfloat_commonNaNToF32UI( &commonNaN ); } else { uiZ = packToF32UI( sign, 0xFF, 0 ); } goto uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( ! (sig & UINT64_C( 0x8000000000000000 )) ) { if ( ! sig ) { uiZ = packToF32UI( sign, 0, 0 ); goto uiZ; } exp += softfloat_normExtF80SigM( &sig ); } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ sig32 = softfloat_shortShiftRightJam64( sig, 33 ); exp -= 0x3F81; if ( sizeof (int_fast16_t) < sizeof (int32_t) ) { if ( exp < -0x1000 ) exp = -0x1000; } return softfloat_roundPackToF32( sign, exp, sig32 ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uiZ: uZ.ui = uiZ; return uZ.f; }
int softfloat_compareNonnormExtF80M( const struct extFloat80M *aSPtr, const struct extFloat80M *bSPtr ) { uint_fast16_t uiA64, uiB64; uint64_t sigA; bool signB; uint64_t sigB; int32_t expA, expB; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uiA64 = aSPtr->signExp; uiB64 = bSPtr->signExp; sigA = aSPtr->signif; signB = signExtF80UI64( uiB64 ); sigB = bSPtr->signif; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( (uiA64 ^ uiB64) & 0x8000 ) { if ( ! (sigA | sigB) ) return 0; goto resultFromSignB; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ expA = expExtF80UI64( uiA64 ); expB = expExtF80UI64( uiB64 ); if ( expA == 0x7FFF ) { if (expB == 0x7FFF) return 0; signB = ! signB; goto resultFromSignB; } if ( expB == 0x7FFF ) { goto resultFromSignB; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( ! expA ) expA = 1; if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { if ( sigA ) { expA += softfloat_normExtF80SigM( &sigA ); } else { expA = -128; } } if ( ! expB ) expB = 1; if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) { if ( sigB ) { expB += softfloat_normExtF80SigM( &sigB ); } else { expB = -128; } } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( signB ) { if ( expA < expB ) return 1; if ( (expB < expA) || (sigB < sigA) ) return -1; } else { if ( expB < expA ) return 1; if ( (expA < expB) || (sigA < sigB) ) return -1; } return (sigA != sigB); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ resultFromSignB: return signB ? 1 : -1; }
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; }