softfloat: Add flag specific to signaling nans

PowerPC has this flag, and it's easier to compute it here
than after the fact.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20211119160502.17432-8-richard.henderson@linaro.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
Richard Henderson 2021-12-17 17:57:14 +01:00 committed by Cédric Le Goater
parent 81254b02eb
commit e706d4455b
3 changed files with 16 additions and 7 deletions

View File

@ -19,7 +19,7 @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
{ {
switch (a->cls) { switch (a->cls) {
case float_class_snan: case float_class_snan:
float_raise(float_flag_invalid, s); float_raise(float_flag_invalid | float_flag_invalid_snan, s);
if (s->default_nan_mode) { if (s->default_nan_mode) {
parts_default_nan(a, s); parts_default_nan(a, s);
} else { } else {
@ -40,7 +40,7 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
float_status *s) float_status *s)
{ {
if (is_snan(a->cls) || is_snan(b->cls)) { if (is_snan(a->cls) || is_snan(b->cls)) {
float_raise(float_flag_invalid, s); float_raise(float_flag_invalid | float_flag_invalid_snan, s);
} }
if (s->default_nan_mode) { if (s->default_nan_mode) {
@ -68,7 +68,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
int which; int which;
if (unlikely(abc_mask & float_cmask_snan)) { if (unlikely(abc_mask & float_cmask_snan)) {
float_raise(float_flag_invalid, s); float_raise(float_flag_invalid | float_flag_invalid_snan, s);
} }
which = pickNaNMulAdd(a->cls, b->cls, c->cls, which = pickNaNMulAdd(a->cls, b->cls, c->cls,
@ -1049,8 +1049,10 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode,
switch (p->cls) { switch (p->cls) {
case float_class_snan: case float_class_snan:
flags |= float_flag_invalid_snan;
/* fall through */
case float_class_qnan: case float_class_qnan:
flags = float_flag_invalid; flags |= float_flag_invalid;
r = max; r = max;
break; break;
@ -1114,8 +1116,10 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
switch (p->cls) { switch (p->cls) {
case float_class_snan: case float_class_snan:
flags |= float_flag_invalid_snan;
/* fall through */
case float_class_qnan: case float_class_qnan:
flags = float_flag_invalid; flags |= float_flag_invalid;
r = max; r = max;
break; break;
@ -1341,7 +1345,9 @@ static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b,
} }
if (unlikely(ab_mask & float_cmask_anynan)) { if (unlikely(ab_mask & float_cmask_anynan)) {
if (!is_quiet || (ab_mask & float_cmask_snan)) { if (ab_mask & float_cmask_snan) {
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
} else if (!is_quiet) {
float_raise(float_flag_invalid, s); float_raise(float_flag_invalid, s);
} }
return float_relation_unordered; return float_relation_unordered;

View File

@ -2543,8 +2543,10 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
static void parts_float_to_ahp(FloatParts64 *a, float_status *s) static void parts_float_to_ahp(FloatParts64 *a, float_status *s)
{ {
switch (a->cls) { switch (a->cls) {
case float_class_qnan:
case float_class_snan: case float_class_snan:
float_raise(float_flag_invalid_snan, s);
/* fall through */
case float_class_qnan:
/* /*
* There is no NaN in the destination format. Raise Invalid * There is no NaN in the destination format. Raise Invalid
* and return a zero with the sign of the input NaN. * and return a zero with the sign of the input NaN.

View File

@ -158,6 +158,7 @@ enum {
float_flag_invalid_zdz = 0x0400, /* 0 / 0 */ float_flag_invalid_zdz = 0x0400, /* 0 / 0 */
float_flag_invalid_sqrt = 0x0800, /* sqrt(-x) */ float_flag_invalid_sqrt = 0x0800, /* sqrt(-x) */
float_flag_invalid_cvti = 0x1000, /* non-nan to integer */ float_flag_invalid_cvti = 0x1000, /* non-nan to integer */
float_flag_invalid_snan = 0x2000, /* any operand was snan */
}; };
/* /*