/*---------------------------------------------------------------------------- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-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_fast16_t softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ) { bool isSigNaNA, isSigNaNB; uint_fast16_t uiNonsigA, uiNonsigB, uiMagA, uiMagB; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ isSigNaNA = softfloat_isSigNaNF16UI( uiA ); isSigNaNB = softfloat_isSigNaNF16UI( uiB ); /*------------------------------------------------------------------------ | Make NaNs non-signaling. *------------------------------------------------------------------------*/ uiNonsigA = uiA | 0x0200; uiNonsigB = uiB | 0x0200; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( isSigNaNA | isSigNaNB ) { softfloat_raiseFlags( softfloat_flag_invalid ); if ( isSigNaNA ) { if ( isSigNaNB ) goto returnLargerMag; return isNaNF16UI( uiB ) ? uiNonsigB : uiNonsigA; } else { return isNaNF16UI( uiA ) ? uiNonsigA : uiNonsigB; } } returnLargerMag: uiMagA = uiA & 0x7FFF; uiMagB = uiB & 0x7FFF; if ( uiMagA < uiMagB ) return uiNonsigB; if ( uiMagB < uiMagA ) return uiNonsigA; return (uiNonsigA < uiNonsigB) ? uiNonsigA : uiNonsigB; }
bool f16_le_quiet( float16_t a, float16_t b ) { union ui16_f16 uA; uint_fast16_t uiA; union ui16_f16 uB; uint_fast16_t uiB; bool signA, signB; uA.f = a; uiA = uA.ui; uB.f = b; uiB = uB.ui; if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { if ( softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); } return false; } signA = signF16UI( uiA ); signB = signF16UI( uiB ); return (signA != signB) ? signA || ! (uint16_t) ((uiA | uiB)<<1) : (uiA == uiB) || (signA ^ (uiA < uiB)); }
/*---------------------------------------------------------------------------- | Interpreting `uiA' and `uiB' as the bit patterns of two 16-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_fast16_t softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ) { if ( softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); } return defaultNaNF16UI; }
/*---------------------------------------------------------------------------- | Interpreting `uiA' and `uiB' as the bit patterns of two 16-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_fast16_t softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ) { bool isSigNaNA; isSigNaNA = softfloat_isSigNaNF16UI( uiA ); if ( isSigNaNA || softfloat_isSigNaNF16UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); if ( isSigNaNA ) return uiA | 0x0200; } return (isNaNF16UI( uiA ) ? uiA : uiB) | 0x0200; }
bool f16_isSignalingNaN( float16_t a ) { union ui16_f16 uA; uA.f = a; return softfloat_isSigNaNF16UI( uA.ui ); }