diff options
Diffstat (limited to 'fpu')
-rw-r--r-- | fpu/softfloat-parts.c.inc | 25 | ||||
-rw-r--r-- | fpu/softfloat.c | 19 |
2 files changed, 36 insertions, 8 deletions
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index dddee92d6e..41d4b17e41 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1219,14 +1219,35 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b, if (unlikely(ab_mask & float_cmask_anynan)) { /* - * For minnum/maxnum, if one operand is a QNaN, and the other + * For minNum/maxNum (IEEE 754-2008) + * or minimumNumber/maximumNumber (IEEE 754-2019), + * if one operand is a QNaN, and the other * operand is numerical, then return numerical argument. */ - if ((flags & minmax_isnum) + if ((flags & (minmax_isnum | minmax_isnumber)) && !(ab_mask & float_cmask_snan) && (ab_mask & ~float_cmask_qnan)) { return is_nan(a->cls) ? b : a; } + + /* + * In IEEE 754-2019, minNum, maxNum, minNumMag and maxNumMag + * are removed and replaced with minimum, minimumNumber, maximum + * and maximumNumber. + * minimumNumber/maximumNumber behavior for SNaN is changed to: + * If both operands are NaNs, a QNaN is returned. + * If either operand is a SNaN, + * an invalid operation exception is signaled, + * but unless both operands are NaNs, + * the SNaN is otherwise ignored and not converted to a QNaN. + */ + if ((flags & minmax_isnumber) + && (ab_mask & float_cmask_snan) + && (ab_mask & ~float_cmask_anynan)) { + float_raise(float_flag_invalid, s); + return is_nan(a->cls) ? b : a; + } + return parts_pick_nan(a, b, s); } diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6e769f990c..9a28720d82 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -436,6 +436,11 @@ enum { minmax_isnum = 2, /* Set for the IEEE 754-2008 minNumMag() and minNumMag() operations. */ minmax_ismag = 4, + /* + * Set for the IEEE 754-2019 minimumNumber() and maximumNumber() + * operations. + */ + minmax_isnumber = 8, }; /* Simple helpers for checking if, or what kind of, NaN we have */ @@ -3927,12 +3932,14 @@ static float128 float128_minmax(float128 a, float128 b, { return type##_minmax(a, b, s, flags); } #define MINMAX_2(type) \ - MINMAX_1(type, max, 0) \ - MINMAX_1(type, maxnum, minmax_isnum) \ - MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \ - MINMAX_1(type, min, minmax_ismin) \ - MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \ - MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag) + MINMAX_1(type, max, 0) \ + MINMAX_1(type, maxnum, minmax_isnum) \ + MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \ + MINMAX_1(type, maximum_number, minmax_isnumber) \ + MINMAX_1(type, min, minmax_ismin) \ + MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \ + MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag) \ + MINMAX_1(type, minimum_number, minmax_ismin | minmax_isnumber) \ MINMAX_2(float16) MINMAX_2(bfloat16) |