bool f32_le_quiet( float32_t a, float32_t b ) { union ui32_f32 uA; uint_fast32_t uiA; union ui32_f32 uB; uint_fast32_t uiB; bool signA, signB; uA.f = a; uiA = uA.ui; uB.f = b; uiB = uB.ui; if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { if ( softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); } return false; } signA = signF32UI( uiA ); signB = signF32UI( uiB ); return (signA != signB) ? signA || ! (uint32_t) ((uiA | uiB)<<1) : (uiA == uiB) || (signA ^ (uiA < uiB)); }
/*---------------------------------------------------------------------------- | Interpreting `uiA' and `uiB' as the bit patterns of two 32-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_fast32_t softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ) { bool isSigNaNA, isSigNaNB; uint_fast32_t uiNonsigA, uiNonsigB, uiMagA, uiMagB; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ isSigNaNA = softfloat_isSigNaNF32UI( uiA ); isSigNaNB = softfloat_isSigNaNF32UI( uiB ); /*------------------------------------------------------------------------ | Make NaNs non-signaling. *------------------------------------------------------------------------*/ uiNonsigA = uiA | 0x00400000; uiNonsigB = uiB | 0x00400000; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( isSigNaNA | isSigNaNB ) { softfloat_raiseFlags( softfloat_flag_invalid ); if ( isSigNaNA ) { if ( isSigNaNB ) goto returnLargerMag; return isNaNF32UI( uiB ) ? uiNonsigB : uiNonsigA; } else { return isNaNF32UI( uiA ) ? uiNonsigA : uiNonsigB; } } returnLargerMag: uiMagA = uiNonsigA & 0x7FFFFFFF; uiMagB = uiNonsigB & 0x7FFFFFFF; if ( uiMagA < uiMagB ) return uiNonsigB; if ( uiMagB < uiMagA ) return uiNonsigA; return (uiNonsigA < uiNonsigB) ? uiNonsigA : uiNonsigB; }
bool f32_eq_signaling( float32_t a, float32_t b ) { union ui32_f32 uA; uint_fast32_t uiA; union ui32_f32 uB; uint_fast32_t uiB; uA.f = a; uiA = uA.ui; uB.f = b; uiB = uB.ui; if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return false; } return (uiA == uiB) || ! (uint32_t) ((uiA | uiB)<<1); }
/*---------------------------------------------------------------------------- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-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_fast32_t softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ) { bool isSigNaNA; isSigNaNA = softfloat_isSigNaNF32UI( uiA ); if ( isSigNaNA || softfloat_isSigNaNF32UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return (isSigNaNA ? uiA : uiB) | 0x00400000; } return isNaNF32UI( uiA ) ? uiA : uiB; }
uint_fast32_t softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ) { bool isNaNA, isSigNaNA, isNaNB, isSigNaNB; uint_fast32_t uiMagA, uiMagB; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ isNaNA = isNaNF32UI( uiA ); isSigNaNA = softfloat_isSigNaNF32UI( uiA ); isNaNB = isNaNF32UI( uiB ); isSigNaNB = softfloat_isSigNaNF32UI( uiB ); /*------------------------------------------------------------------------ | Make NaNs non-signaling. *------------------------------------------------------------------------*/ uiA |= 0x00400000; uiB |= 0x00400000; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( isSigNaNA | isSigNaNB ) { softfloat_raiseFlags( softfloat_flag_invalid ); } if ( isSigNaNA ) { if ( isSigNaNB ) goto returnLargerSignificand; return isNaNB ? uiB : uiA; } else if ( isNaNA ) { if ( isSigNaNB || ! isNaNB ) return uiA; returnLargerSignificand: uiMagA = uiA<<1; uiMagB = uiB<<1; if ( uiMagA < uiMagB ) return uiB; if ( uiMagB < uiMagA ) return uiA; return ( uiA < uiB ) ? uiA : uiB; } else { return uiB; } }
uint64_t helper_fmax_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2) { frs1 = isNaNF32UI(frs2) || f32_lt_quiet(frs2, frs1) ? frs1 : frs2; set_fp_exceptions; return frs1; }