summaryrefslogtreecommitdiffstats
path: root/fpu
diff options
context:
space:
mode:
Diffstat (limited to 'fpu')
-rw-r--r--fpu/softfloat-parts.c.inc25
-rw-r--r--fpu/softfloat.c19
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)