@@ -1227,6 +1227,25 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
&& (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_isnum | minmax_snan_noprop))
+ && (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);
}
@@ -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() maximumNumber() operations,
+ * without sNaN propagation.
+ */
+ minmax_snan_noprop = 8,
};
/* Simple helpers for checking if, or what kind of, NaN we have */
@@ -3927,11 +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, max, 0) \
+ MINMAX_1(type, maxnum, minmax_isnum) \
+ MINMAX_1(type, maxnum_noprop, minmax_isnum | minmax_snan_noprop) \
+ 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, minnum_noprop, minmax_ismin | minmax_isnum | \
+ minmax_snan_noprop) \
MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag)
MINMAX_2(float16)
@@ -241,6 +241,8 @@ float16 float16_min(float16, float16, float_status *status);
float16 float16_max(float16, float16, float_status *status);
float16 float16_minnum(float16, float16, float_status *status);
float16 float16_maxnum(float16, float16, float_status *status);
+float16 float16_minnum_noprop(float16, float16, float_status *status);
+float16 float16_maxnum_noprop(float16, float16, float_status *status);
float16 float16_minnummag(float16, float16, float_status *status);
float16 float16_maxnummag(float16, float16, float_status *status);
float16 float16_sqrt(float16, float_status *status);
@@ -420,6 +422,8 @@ bfloat16 bfloat16_min(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_max(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_minnum(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_maxnum(bfloat16, bfloat16, float_status *status);
+bfloat16 bfloat16_minnum_noprop(bfloat16, bfloat16, float_status *status);
+bfloat16 bfloat16_maxnum_noprop(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_minnummag(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_maxnummag(bfloat16, bfloat16, float_status *status);
bfloat16 bfloat16_sqrt(bfloat16, float_status *status);
@@ -587,6 +591,8 @@ float32 float32_min(float32, float32, float_status *status);
float32 float32_max(float32, float32, float_status *status);
float32 float32_minnum(float32, float32, float_status *status);
float32 float32_maxnum(float32, float32, float_status *status);
+float32 float32_minnum_noprop(float32, float32, float_status *status);
+float32 float32_maxnum_noprop(float32, float32, float_status *status);
float32 float32_minnummag(float32, float32, float_status *status);
float32 float32_maxnummag(float32, float32, float_status *status);
bool float32_is_quiet_nan(float32, float_status *status);
@@ -776,6 +782,8 @@ float64 float64_min(float64, float64, float_status *status);
float64 float64_max(float64, float64, float_status *status);
float64 float64_minnum(float64, float64, float_status *status);
float64 float64_maxnum(float64, float64, float_status *status);
+float64 float64_minnum_noprop(float64, float64, float_status *status);
+float64 float64_maxnum_noprop(float64, float64, float_status *status);
float64 float64_minnummag(float64, float64, float_status *status);
float64 float64_maxnummag(float64, float64, float_status *status);
bool float64_is_quiet_nan(float64 a, float_status *status);
@@ -1208,6 +1216,8 @@ float128 float128_min(float128, float128, float_status *status);
float128 float128_max(float128, float128, float_status *status);
float128 float128_minnum(float128, float128, float_status *status);
float128 float128_maxnum(float128, float128, float_status *status);
+float128 float128_minnum_noprop(float128, float128, float_status *status);
+float128 float128_maxnum_noprop(float128, float128, float_status *status);
float128 float128_minnummag(float128, float128, float_status *status);
float128 float128_maxnummag(float128, float128, float_status *status);
bool float128_is_quiet_nan(float128, float_status *status);