Skip to content

Commit

Permalink
softfloat: Add flag specific to signaling nans
Browse files Browse the repository at this point in the history
PowerPC has this flag, and it's easier to compute it here
than after the fact.

Signed-off-by: Richard Henderson <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Cédric Le Goater <[email protected]>
  • Loading branch information
rth7680 authored and legoater committed Dec 17, 2021
1 parent 81254b0 commit e706d44
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 7 deletions.
18 changes: 12 additions & 6 deletions fpu/softfloat-parts.c.inc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
{
switch (a->cls) {
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) {
parts_default_nan(a, s);
} else {
Expand All @@ -40,7 +40,7 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
float_status *s)
{
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) {
Expand Down Expand Up @@ -68,7 +68,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
int which;

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,
Expand Down Expand Up @@ -1049,8 +1049,10 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode,

switch (p->cls) {
case float_class_snan:
flags |= float_flag_invalid_snan;
/* fall through */
case float_class_qnan:
flags = float_flag_invalid;
flags |= float_flag_invalid;
r = max;
break;

Expand Down Expand Up @@ -1114,8 +1116,10 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,

switch (p->cls) {
case float_class_snan:
flags |= float_flag_invalid_snan;
/* fall through */
case float_class_qnan:
flags = float_flag_invalid;
flags |= float_flag_invalid;
r = max;
break;

Expand Down Expand Up @@ -1341,7 +1345,9 @@ static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b,
}

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);
}
return float_relation_unordered;
Expand Down
4 changes: 3 additions & 1 deletion fpu/softfloat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
switch (a->cls) {
case float_class_qnan:
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
* and return a zero with the sign of the input NaN.
Expand Down
1 change: 1 addition & 0 deletions include/fpu/softfloat-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ enum {
float_flag_invalid_zdz = 0x0400, /* 0 / 0 */
float_flag_invalid_sqrt = 0x0800, /* sqrt(-x) */
float_flag_invalid_cvti = 0x1000, /* non-nan to integer */
float_flag_invalid_snan = 0x2000, /* any operand was snan */
};

/*
Expand Down

0 comments on commit e706d44

Please sign in to comment.