qemu/fpu/softfloat-specialize.h
/*----------------------------------------------------------------------------
| Select which NaN to propagate for a two-input operation.
| IEEE754 doesn't specify all the details of this, so the
| algorithm is target-specific.
| The routine is passed various bits of information about the
| two NaNs and should return 0 to select NaN a and 1 for NaN b.
| Note that signalling NaNs are always squashed to quiet NaNs
| by the caller, by calling floatXX_silence_nan() before
| returning them.
|
| aIsLargerSignificand is only valid if both a and b are NaNs
| of some kind, and is true if a has the larger significand,
| or if both a and b have the same significand but a is
| positive but b is negative. It is only needed for the x87
| tie-break rule.
*----------------------------------------------------------------------------*/
| Select which NaN to propagate for a two-input operation.
| IEEE754 doesn't specify all the details of this, so the
| algorithm is target-specific.
| The routine is passed various bits of information about the
| two NaNs and should return 0 to select NaN a and 1 for NaN b.
| Note that signalling NaNs are always squashed to quiet NaNs
| by the caller, by calling floatXX_silence_nan() before
| returning them.
| Select which NaN to propagate for a two - input operation . | IEEE754 doesn ' t specify all the details of this so the | algorithm is target - specific . | The routine is passed various bits of information about the | two NaNs and should return 0 to select NaN a and 1 for NaN b . | Note that signalling NaNs are always squashed to quiet NaNs | by the caller by calling floatXX_silence_nan () before | returning them .
static int pickNaN(FloatClass a_cls, FloatClass b_cls,
                   flag aIsLargerSignificand)
{
#if defined(TARGET_ARM) || defined(TARGET_MIPS) || defined(TARGET_HPPA)
    if (is_snan(a_cls)) {
        return 0;
    } else if (is_snan(b_cls)) {
        return 1;
    } else if (is_qnan(a_cls)) {
        return 0;
    } else {
        return 1;
    }
#elif defined(TARGET_PPC) || defined(TARGET_XTENSA) || defined(TARGET_M68K)
    if (is_nan(a_cls)) {
        return 0;
    } else {
        return 1;
    }
#else
    if (is_snan(a_cls)) {
        if (is_snan(b_cls)) {
            return aIsLargerSignificand ? 0 : 1;
        }
        return is_qnan(b_cls) ? 1 : 0;
    } else if (is_qnan(a_cls)) {
        if (is_snan(b_cls) || !is_qnan(b_cls)) {
            return 0;
        } else {
            return aIsLargerSignificand ? 0 : 1;
        }
    } else {
        return 1;
    }
#endif
}
static int pickNaN ( FloatClass a_cls , FloatClass b_cls , flag aIsLargerSignificand ) { #if defined ( TARGET_ARM ) || defined ( TARGET_MIPS ) || defined ( TARGET_HPPA ) if ( is_snan ( a_cls ) ) { return 0 ; } else if ( is_snan ( b_cls ) ) { return 1 ; } else if ( is_qnan ( a_cls ) ) { return 0 ; } else { return 1 ; } #elif defined ( TARGET_PPC ) || defined ( TARGET_XTENSA ) || defined ( TARGET_M68K ) if ( is_nan ( a_cls ) ) { return 0 ; } else { return 1 ; } #else if ( is_snan ( a_cls ) ) { if ( is_snan ( b_cls ) ) { return aIsLargerSignificand ? 0 : 1 ; } return is_qnan ( b_cls ) ? 1 : 0 ; } else if ( is_qnan ( a_cls ) ) { if ( is_snan ( b_cls ) || ! is_qnan ( b_cls ) ) { return 0 ; } else { return aIsLargerSignificand ? 0 : 1 ; } } else { return 1 ; } #endif }
| Select which NaN to propagate for a two-input operation.
| Select which NaN to propagate for a two - input operation .
/* ARM mandated NaN propagation rules (see FPProcessNaNs()), take
     * the first of:
     *  1. A if it is signaling
     *  2. B if it is signaling
     *  3. A (quiet)
     *  4. B (quiet)
     * A signaling NaN is always quietened before returning it.
     */ /* According to MIPS specifications, if one of the two operands is
     * a sNaN, a new qNaN has to be generated. This is done in
     * floatXX_silence_nan(). For qNaN inputs the specifications
     * says: "When possible, this QNaN result is one of the operand QNaN
     * values." In practice it seems that most implementations choose
     * the first operand if both operands are qNaN. In short this gives
     * the following rules:
     *  1. A if it is signaling
     *  2. B if it is signaling
     *  3. A (quiet)
     *  4. B (quiet)
     * A signaling NaN is always silenced before returning it.
     */ /* PowerPC propagation rules:
     *  1. A if it sNaN or qNaN
     *  2. B if it sNaN or qNaN
     * A signaling NaN is always silenced before returning it.
     */ /* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
     * 3.4 FLOATING-POINT INSTRUCTION DETAILS
     * If either operand, but not both operands, of an operation is a
     * nonsignaling NaN, then that NaN is returned as the result. If both
     * operands are nonsignaling NaNs, then the destination operand
     * nonsignaling NaN is returned as the result.
     * If either operand to an operation is a signaling NaN (SNaN), then the
     * SNaN bit is set in the FPSR EXC byte. If the SNaN exception enable bit
     * is set in the FPCR ENABLE byte, then the exception is taken and the
     * destination is not modified. If the SNaN exception enable bit is not
     * set, setting the SNaN bit in the operand to a one converts the SNaN to
     * a nonsignaling NaN. The operation then continues as described in the
     * preceding paragraph for nonsignaling NaNs.
     */ /* This implements x87 NaN propagation rules:
     * SNaN + QNaN => return the QNaN
     * two SNaNs => return the one with the larger significand, silenced
     * two QNaNs => return the one with the larger significand
     * SNaN and a non-NaN => return the SNaN, silenced
     * QNaN and a non-NaN => return the QNaN
     *
     * If we get down to comparing significands and they are the same,
     * return the NaN with the positive sign bit (if any).
     */