bool f64_lt_quiet( float64_t a, float64_t b ) { union ui64_f64 uA; uint_fast64_t uiA; union ui64_f64 uB; uint_fast64_t uiB; bool signA, signB; uA.f = a; uiA = uA.ui; uB.f = b; uiB = uB.ui; if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { if ( softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); } return false; } signA = signF64UI( uiA ); signB = signF64UI( uiB ); return (signA != signB) ? signA && ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) : (uiA != uiB) && (signA ^ (uiA < uiB)); }
/*---------------------------------------------------------------------------- | Interpreting `uiA' and `uiB' as the bit patterns of two 64-bit floating- | point values, at least one of which is a NaN, returns the bit pattern of | the combined NaN result. If either `uiA' or `uiB' has the pattern of a | signaling NaN, the invalid exception is raised. *----------------------------------------------------------------------------*/ uint_fast64_t softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ) { bool isSigNaNA, isSigNaNB; uint_fast64_t uiNonsigA, uiNonsigB, uiMagA, uiMagB; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ isSigNaNA = softfloat_isSigNaNF64UI( uiA ); isSigNaNB = softfloat_isSigNaNF64UI( uiB ); /*------------------------------------------------------------------------ | Make NaNs non-signaling. *------------------------------------------------------------------------*/ uiNonsigA = uiA | UINT64_C( 0x0008000000000000 ); uiNonsigB = uiB | UINT64_C( 0x0008000000000000 ); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( isSigNaNA | isSigNaNB ) { softfloat_raiseFlags( softfloat_flag_invalid ); if ( isSigNaNA ) { if ( isSigNaNB ) goto returnLargerMag; return isNaNF64UI( uiB ) ? uiNonsigB : uiNonsigA; } else { return isNaNF64UI( uiA ) ? uiNonsigA : uiNonsigB; } } returnLargerMag: uiMagA = uiNonsigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ); uiMagB = uiNonsigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ); if ( uiMagA < uiMagB ) return uiNonsigB; if ( uiMagB < uiMagA ) return uiNonsigA; return (uiNonsigA < uiNonsigB) ? uiNonsigA : uiNonsigB; }
bool f64_eq_signaling( float64_t a, float64_t b ) { union ui64_f64 uA; uint_fast64_t uiA; union ui64_f64 uB; uint_fast64_t uiB; uA.f = a; uiA = uA.ui; uB.f = b; uiB = uB.ui; if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return false; } return (uiA == uiB) || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )); }
/*---------------------------------------------------------------------------- | Interpreting `uiA' and `uiB' as the bit patterns of two 64-bit floating- | point values, at least one of which is a NaN, returns the bit pattern of | the combined NaN result. If either `uiA' or `uiB' has the pattern of a | signaling NaN, the invalid exception is raised. *----------------------------------------------------------------------------*/ uint_fast64_t softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ) { bool isSigNaNA; isSigNaNA = softfloat_isSigNaNF64UI( uiA ); if ( isSigNaNA || softfloat_isSigNaNF64UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); if ( isSigNaNA ) return uiA | UINT64_C( 0x0008000000000000 ); } return (isNaNF64UI( uiA ) ? uiA : uiB) | UINT64_C( 0x0008000000000000 ); }
uint_fast16_t f64_classify( float64_t a ) { union ui64_f64 uA; uint_fast64_t uiA; uA.f = a; uiA = uA.ui; uint_fast16_t infOrNaN = expF64UI( uiA ) == 0x7FF; uint_fast16_t subnormalOrZero = expF64UI( uiA ) == 0; bool sign = signF64UI( uiA ); return ( sign && infOrNaN && fracF64UI( uiA ) == 0 ) << 0 | ( sign && !infOrNaN && !subnormalOrZero ) << 1 | ( sign && subnormalOrZero && fracF64UI( uiA ) ) << 2 | ( sign && subnormalOrZero && fracF64UI( uiA ) == 0 ) << 3 | ( !sign && infOrNaN && fracF64UI( uiA ) == 0 ) << 7 | ( !sign && !infOrNaN && !subnormalOrZero ) << 6 | ( !sign && subnormalOrZero && fracF64UI( uiA ) ) << 5 | ( !sign && subnormalOrZero && fracF64UI( uiA ) == 0 ) << 4 | ( isNaNF64UI( uiA ) && softfloat_isSigNaNF64UI( uiA )) << 8 | ( isNaNF64UI( uiA ) && !softfloat_isSigNaNF64UI( uiA )) << 9; }
uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) { frs1 = isNaNF64UI(frs2) || f64_lt_quiet(frs2, frs1) ? frs1 : frs2; set_fp_exceptions; return frs1; }