bool f128M_eq_signaling( const float128_t *aPtr, const float128_t *bPtr ) { const uint32_t *aWPtr, *bWPtr; uint32_t wordA, wordB, uiA96, uiB96; bool possibleOppositeZeros; uint32_t mashWord; aWPtr = (const uint32_t *) aPtr; bWPtr = (const uint32_t *) bPtr; if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return false; } wordA = aWPtr[indexWord( 4, 2 )]; wordB = bWPtr[indexWord( 4, 2 )]; if ( wordA != wordB ) return false; uiA96 = aWPtr[indexWordHi( 4 )]; uiB96 = bWPtr[indexWordHi( 4 )]; possibleOppositeZeros = false; if ( uiA96 != uiB96 ) { possibleOppositeZeros = (((uiA96 | uiB96) & 0x7FFFFFFF) == 0); if ( ! possibleOppositeZeros ) return false; } mashWord = wordA | wordB; wordA = aWPtr[indexWord( 4, 1 )]; wordB = bWPtr[indexWord( 4, 1 )]; if ( wordA != wordB ) return false; mashWord |= wordA | wordB; wordA = aWPtr[indexWord( 4, 0 )]; wordB = bWPtr[indexWord( 4, 0 )]; return (wordA == wordB) && (! possibleOppositeZeros || ((mashWord | wordA | wordB) == 0)); }
/*---------------------------------------------------------------------------- | Assuming at least one of the two 128-bit floating-point values pointed to by | `aWPtr' and `bWPtr' is a NaN, stores the combined NaN result at the location | pointed to by `zWPtr'. If either original floating-point value is a | signaling NaN, the invalid exception is raised. Each of `aWPtr', `bWPtr', | and `zWPtr' points to an array of four 32-bit elements that concatenate in | the platform's normal endian order to form a 128-bit floating-point value. *----------------------------------------------------------------------------*/ void softfloat_propagateNaNF128M( const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ) { bool isSigNaNA; const uint32_t *ptr; bool isSigNaNB; uint32_t uiA96, uiB96, wordMagA, wordMagB; isSigNaNA = f128M_isSignalingNaN( (const float128_t *) aWPtr ); ptr = aWPtr; if ( ! bWPtr ) { if ( isSigNaNA ) softfloat_raiseFlags( softfloat_flag_invalid ); goto copy; } isSigNaNB = f128M_isSignalingNaN( (const float128_t *) bWPtr ); if ( isSigNaNA | isSigNaNB ) { softfloat_raiseFlags( softfloat_flag_invalid ); if ( isSigNaNA ) { if ( isSigNaNB ) goto returnLargerUIMag; if ( softfloat_isNaNF128M( bWPtr ) ) goto copyB; goto copy; } else { if ( softfloat_isNaNF128M( aWPtr ) ) goto copy; goto copyB; } } returnLargerUIMag: uiA96 = aWPtr[indexWordHi( 4 )]; uiB96 = bWPtr[indexWordHi( 4 )]; wordMagA = uiA96 & 0x7FFFFFFF; wordMagB = uiB96 & 0x7FFFFFFF; if ( wordMagA < wordMagB ) goto copyB; if ( wordMagB < wordMagA ) goto copy; wordMagA = aWPtr[indexWord( 4, 2 )]; wordMagB = bWPtr[indexWord( 4, 2 )]; if ( wordMagA < wordMagB ) goto copyB; if ( wordMagB < wordMagA ) goto copy; wordMagA = aWPtr[indexWord( 4, 1 )]; wordMagB = bWPtr[indexWord( 4, 1 )]; if ( wordMagA < wordMagB ) goto copyB; if ( wordMagB < wordMagA ) goto copy; wordMagA = aWPtr[indexWord( 4, 0 )]; wordMagB = bWPtr[indexWord( 4, 0 )]; if ( wordMagA < wordMagB ) goto copyB; if ( wordMagB < wordMagA ) goto copy; if ( uiA96 < uiB96 ) goto copy; copyB: ptr = bWPtr; copy: zWPtr[indexWordHi( 4 )] = ptr[indexWordHi( 4 )] | 0x00008000; zWPtr[indexWord( 4, 2 )] = ptr[indexWord( 4, 2 )]; zWPtr[indexWord( 4, 1 )] = ptr[indexWord( 4, 1 )]; zWPtr[indexWord( 4, 0 )] = ptr[indexWord( 4, 0 )]; }
bool softfloat_tryPropagateNaNF128M( const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ) { if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) { softfloat_propagateNaNF128M( aWPtr, bWPtr, zWPtr ); return true; } return false; }
bool f128M_eq( const float128_t *aPtr, const float128_t *bPtr ) { const uint32_t *aWPtr, *bWPtr; uint32_t wordA, wordB, uiA96, uiB96; bool possibleOppositeZeros; uint32_t mashWord; aWPtr = (const uint32_t *) aPtr; bWPtr = (const uint32_t *) bPtr; wordA = aWPtr[indexWord( 4, 2 )]; wordB = bWPtr[indexWord( 4, 2 )]; if ( wordA != wordB ) goto false_checkSigNaNs; uiA96 = aWPtr[indexWordHi( 4 )]; uiB96 = bWPtr[indexWordHi( 4 )]; possibleOppositeZeros = false; if ( uiA96 != uiB96 ) { possibleOppositeZeros = (((uiA96 | uiB96) & 0x7FFFFFFF) == 0); if ( ! possibleOppositeZeros ) goto false_checkSigNaNs; } mashWord = wordA | wordB; wordA = aWPtr[indexWord( 4, 1 )]; wordB = bWPtr[indexWord( 4, 1 )]; if ( wordA != wordB ) goto false_checkSigNaNs; mashWord |= wordA | wordB; wordA = aWPtr[indexWord( 4, 0 )]; wordB = bWPtr[indexWord( 4, 0 )]; if ( wordA != wordB ) goto false_checkSigNaNs; if ( possibleOppositeZeros && ((mashWord | wordA | wordB) != 0) ) { goto false_checkSigNaNs; } if ( ! softfloat_isNaNF128M( aWPtr ) && ! softfloat_isNaNF128M( bWPtr ) ) { return true; } false_checkSigNaNs: if ( f128M_isSignalingNaN( (const float128_t *) aWPtr ) || f128M_isSignalingNaN( (const float128_t *) bWPtr ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); } return false; }
bool f128M_lt( const float128_t *aPtr, const float128_t *bPtr ) { const uint32_t *aWPtr, *bWPtr; uint32_t uiA96, uiB96; bool signA, signB; uint32_t wordA, wordB; aWPtr = (const uint32_t *) aPtr; bWPtr = (const uint32_t *) bPtr; if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return false; } uiA96 = aWPtr[indexWordHi( 4 )]; uiB96 = bWPtr[indexWordHi( 4 )]; signA = signF128UI96( uiA96 ); signB = signF128UI96( uiB96 ); if ( signA != signB ) { if ( signB ) return false; if ( (uiA96 | uiB96) & 0x7FFFFFFF ) return true; wordA = aWPtr[indexWord( 4, 2 )]; wordB = bWPtr[indexWord( 4, 2 )]; if ( wordA | wordB ) return true; wordA = aWPtr[indexWord( 4, 1 )]; wordB = bWPtr[indexWord( 4, 1 )]; if ( wordA | wordB ) return true; wordA = aWPtr[indexWord( 4, 0 )]; wordB = bWPtr[indexWord( 4, 0 )]; return ((wordA | wordB) != 0); } if ( signA ) { aWPtr = (const uint32_t *) bPtr; bWPtr = (const uint32_t *) aPtr; } return (softfloat_compare128M( aWPtr, bWPtr ) < 0); }
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 ); }
/*---------------------------------------------------------------------------- | Assuming at least one of the two 128-bit floating-point values pointed to by | `aWPtr' and `bWPtr' is a NaN, stores the combined NaN result at the location | pointed to by `zWPtr'. If either original floating-point value is a | signaling NaN, the invalid exception is raised. Each of `aWPtr', `bWPtr', | and `zWPtr' points to an array of four 32-bit elements that concatenate in | the platform's normal endian order to form a 128-bit floating-point value. *----------------------------------------------------------------------------*/ void softfloat_propagateNaNF128M( const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ) { bool isSigNaNA; const uint32_t *ptr; ptr = aWPtr; isSigNaNA = f128M_isSignalingNaN( (const float128_t *) aWPtr ); if ( isSigNaNA || (bWPtr && f128M_isSignalingNaN( (const float128_t *) bWPtr )) ) { softfloat_raiseFlags( softfloat_flag_invalid ); if ( isSigNaNA ) goto copy; } if ( ! softfloat_isNaNF128M( aWPtr ) ) ptr = bWPtr; copy: zWPtr[indexWordHi( 4 )] = ptr[indexWordHi( 4 )] | 0x00008000; zWPtr[indexWord( 4, 2 )] = ptr[indexWord( 4, 2 )]; zWPtr[indexWord( 4, 1 )] = ptr[indexWord( 4, 1 )]; zWPtr[indexWord( 4, 0 )] = ptr[indexWord( 4, 0 )]; }