/*---------------------------------------------------------------------------- | 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 )]; }
void test_az_f128( void trueFunction( const float128_t *, float128_t * ), void subjFunction( const float128_t *, float128_t * ) ) { int count; float128_t trueZ; uint_fast8_t trueFlags; float128_t subjZ; uint_fast8_t subjFlags; genCases_f128_a_init(); genCases_writeTestsTotal( testLoops_forever ); verCases_errorCount = 0; verCases_tenThousandsCount = 0; count = 10000; while ( ! genCases_done || testLoops_forever ) { genCases_f128_a_next(); *testLoops_trueFlagsPtr = 0; trueFunction( &genCases_f128_a, &trueZ ); trueFlags = *testLoops_trueFlagsPtr; testLoops_subjFlagsFunction(); subjFunction( &genCases_f128_a, &subjZ ); subjFlags = testLoops_subjFlagsFunction(); --count; if ( ! count ) { verCases_perTenThousand(); count = 10000; } if ( ! f128M_same( &trueZ, &subjZ ) || (trueFlags != subjFlags) ) { if ( ! verCases_checkNaNs && f128M_isSignalingNaN( &genCases_f128_a ) ) { trueFlags |= softfloat_flag_invalid; } if ( verCases_checkNaNs || ! f128M_isNaN( &trueZ ) || ! f128M_isNaN( &subjZ ) || f128M_isSignalingNaN( &subjZ ) || (trueFlags != subjFlags) ) { ++verCases_errorCount; verCases_writeErrorFound( 10000 - count ); writeCase_a_f128M( &genCases_f128_a, " " ); writeCase_z_f128M( &trueZ, trueFlags, &subjZ, subjFlags ); if ( verCases_errorCount == verCases_maxErrorCount ) break; } } } verCases_writeTestsPerformed( 10000 - count ); }
void test_a_f128_z_ui32_rx( uint_fast32_t trueFunction( const float128_t *, uint_fast8_t, bool ), uint_fast32_t subjFunction( const float128_t *, uint_fast8_t, bool ), uint_fast8_t roundingMode, bool exact ) { int count; uint_fast32_t trueZ; uint_fast8_t trueFlags; uint_fast32_t subjZ; uint_fast8_t subjFlags; genCases_f128_a_init(); genCases_writeTestsTotal( testLoops_forever ); verCases_errorCount = 0; verCases_tenThousandsCount = 0; count = 10000; while ( ! genCases_done || testLoops_forever ) { genCases_f128_a_next(); *testLoops_trueFlagsPtr = 0; trueZ = trueFunction( &genCases_f128_a, roundingMode, exact ); trueFlags = *testLoops_trueFlagsPtr; testLoops_subjFlagsFunction(); subjZ = subjFunction( &genCases_f128_a, roundingMode, exact ); subjFlags = testLoops_subjFlagsFunction(); --count; if ( ! count ) { verCases_perTenThousand(); count = 10000; } if ( (trueZ != subjZ) || (trueFlags != subjFlags) ) { if ( ! verCases_checkNaNs && f128M_isSignalingNaN( &genCases_f128_a ) ) { trueFlags |= softfloat_flag_invalid; } if ( (trueZ != 0xFFFFFFFF) || (subjZ != 0xFFFFFFFF) || (trueFlags != softfloat_flag_invalid) || (subjFlags != softfloat_flag_invalid) ) { ++verCases_errorCount; verCases_writeErrorFound( 10000 - count ); writeCase_a_f128M( &genCases_f128_a, " " ); writeCase_z_ui32( trueZ, trueFlags, subjZ, subjFlags ); if ( verCases_errorCount == verCases_maxErrorCount ) break; } } } verCases_writeTestsPerformed( 10000 - count ); }
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; }
/*---------------------------------------------------------------------------- | Assuming the 128-bit floating-point value pointed to by `aWPtr' is a NaN, | converts this NaN to the common NaN form, and stores the resulting common | NaN at the location pointed to by `zPtr'. If the NaN is a signaling NaN, | the invalid exception is raised. Argument `aWPtr' 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_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr ) { if ( f128M_isSignalingNaN( (const float128_t *) aWPtr ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); } zPtr->sign = aWPtr[indexWordHi( 4 )]>>31; softfloat_shortShiftLeft128M( aWPtr, 16, (uint32_t *) &zPtr->v0 ); }
/*---------------------------------------------------------------------------- | 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 )]; }