|
@@ -352,102 +352,6 @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-/*----------------------------------------------------------------------------
|
|
|
|
-| 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.
|
|
|
|
-*----------------------------------------------------------------------------*/
|
|
|
|
-
|
|
|
|
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
|
|
|
|
- bool aIsLargerSignificand, float_status *status)
|
|
|
|
-{
|
|
|
|
- /*
|
|
|
|
- * We guarantee not to require the target to tell us how to
|
|
|
|
- * pick a NaN if we're always returning the default NaN.
|
|
|
|
- * But if we're not in default-NaN mode then the target must
|
|
|
|
- * specify via set_float_2nan_prop_rule().
|
|
|
|
- */
|
|
|
|
- assert(!status->default_nan_mode);
|
|
|
|
-
|
|
|
|
- switch (status->float_2nan_prop_rule) {
|
|
|
|
- case float_2nan_prop_s_ab:
|
|
|
|
- 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;
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case float_2nan_prop_s_ba:
|
|
|
|
- if (is_snan(b_cls)) {
|
|
|
|
- return 1;
|
|
|
|
- } else if (is_snan(a_cls)) {
|
|
|
|
- return 0;
|
|
|
|
- } else if (is_qnan(b_cls)) {
|
|
|
|
- return 1;
|
|
|
|
- } else {
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case float_2nan_prop_ab:
|
|
|
|
- if (is_nan(a_cls)) {
|
|
|
|
- return 0;
|
|
|
|
- } else {
|
|
|
|
- return 1;
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case float_2nan_prop_ba:
|
|
|
|
- if (is_nan(b_cls)) {
|
|
|
|
- return 1;
|
|
|
|
- } else {
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case float_2nan_prop_x87:
|
|
|
|
- /*
|
|
|
|
- * 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).
|
|
|
|
- */
|
|
|
|
- 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;
|
|
|
|
- }
|
|
|
|
- default:
|
|
|
|
- g_assert_not_reached();
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*----------------------------------------------------------------------------
|
|
/*----------------------------------------------------------------------------
|
|
| Returns 1 if the double-precision floating-point value `a' is a quiet
|
|
| Returns 1 if the double-precision floating-point value `a' is a quiet
|
|
| NaN; otherwise returns 0.
|
|
| NaN; otherwise returns 0.
|