@samitouri / QOSamiQemu / commits / 512f5147c8

fpu: Export floatN_minmax

Allow target access to routines using the minmax flags. Make the existing min/max wrappers inline. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Richard Henderson committed May 16, 2026 at 15:13 UTC 512f5147c8722c2caf730d1b5a09dbf36b03da57
3 files changed +62 -89
fpu/softfloat-parts.c.inc
+4 -4
@@ -1469,7 +1469,7 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
1469 * if one operand is a QNaN, and the other
1470 * operand is numerical, then return numerical argument.
1471 */
1472 - if ((flags & (minmax_isnum | minmax_isnumber))
1472 + if ((flags & (float_minmax_isnum | float_minmax_isnumber))
1473 && !(ab_mask & float_cmask_snan)
1474 && (ab_mask & ~float_cmask_qnan)) {
1475 record_denormals_used(ab_mask, s);
@@ -1487,7 +1487,7 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
1487 * but unless both operands are NaNs,
1488 * the SNaN is otherwise ignored and not converted to a QNaN.
1489 */
1490 - if ((flags & minmax_isnumber)
1490 + if ((flags & float_minmax_isnumber)
1491 && (ab_mask & float_cmask_snan)
1492 && (ab_mask & ~float_cmask_anynan)) {
1493 float_raise(float_flag_invalid, s);
@@ -1542,7 +1542,7 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
1542 * Take the sign into account.
1543 * For ismag, only do this if the magnitudes are equal.
1544 */
1545 - if (!(flags & minmax_ismag) || cmp == 0) {
1545 + if (!(flags & float_minmax_ismag) || cmp == 0) {
1546 if (a->sign != b->sign) {
1547 /* For differing signs, the negative operand is less. */
1548 cmp = a->sign ? -1 : 1;
@@ -1552,7 +1552,7 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
1552 }
1553 }
1554
1555 - if (flags & minmax_ismin) {
1555 + if (flags & float_minmax_ismin) {
1556 cmp = -cmp;
1557 }
1558 return cmp < 0 ? b : a;
fpu/softfloat.c
+5 -45
@@ -397,21 +397,6 @@ float64_gen2(float64 xa, float64 xb, float_status *s,
397 return soft(ua.s, ub.s, s);
398 }
399
400 -/* Flags for parts_minmax. */
401 -enum {
402 - /* Set for minimum; clear for maximum. */
403 - minmax_ismin = 1,
404 - /* Set for the IEEE 754-2008 minNum() and maxNum() operations. */
405 - minmax_isnum = 2,
406 - /* Set for the IEEE 754-2008 minNumMag() and minNumMag() operations. */
407 - minmax_ismag = 4,
408 - /*
409 - * Set for the IEEE 754-2019 minimumNumber() and maximumNumber()
410 - * operations.
411 - */
412 - minmax_isnumber = 8,
413 -};
414 -
400 /* Simple helpers for checking if, or what kind of, NaN we have */
401 static inline __attribute__((unused)) bool is_nan(FloatClass c)
402 {
@@ -4076,7 +4061,7 @@ float128 uint128_to_float128(Int128 a, float_status *status)
4061 * Minimum and maximum
4062 */
4063
4079 -static float16 float16_minmax(float16 a, float16 b, float_status *s, int flags)
4064 +float16 float16_minmax(float16 a, float16 b, float_status *s, int flags)
4065 {
4066 FloatParts64 pa = float16_unpack_canonical(a, s);
4067 FloatParts64 pb = float16_unpack_canonical(b, s);
@@ -4085,8 +4070,7 @@ static float16 float16_minmax(float16 a, float16 b, float_status *s, int flags)
4070 return float16_round_pack_canonical(pr, s);
4071 }
4072
4088 -static bfloat16 bfloat16_minmax(bfloat16 a, bfloat16 b,
4089 - float_status *s, int flags)
4073 +bfloat16 bfloat16_minmax(bfloat16 a, bfloat16 b, float_status *s, int flags)
4074 {
4075 FloatParts64 pa = bfloat16_unpack_canonical(a, s);
4076 FloatParts64 pb = bfloat16_unpack_canonical(b, s);
@@ -4095,7 +4079,7 @@ static bfloat16 bfloat16_minmax(bfloat16 a, bfloat16 b,
4079 return bfloat16_round_pack_canonical(pr, s);
4080 }
4081
4098 -static float32 float32_minmax(float32 a, float32 b, float_status *s, int flags)
4082 +float32 float32_minmax(float32 a, float32 b, float_status *s, int flags)
4083 {
4084 FloatParts64 pa = float32_unpack_canonical(a, s);
4085 FloatParts64 pb = float32_unpack_canonical(b, s);
@@ -4104,7 +4088,7 @@ static float32 float32_minmax(float32 a, float32 b, float_status *s, int flags)
4088 return float32_round_pack_canonical(pr, s);
4089 }
4090
4107 -static float64 float64_minmax(float64 a, float64 b, float_status *s, int flags)
4091 +float64 float64_minmax(float64 a, float64 b, float_status *s, int flags)
4092 {
4093 FloatParts64 pa = float64_unpack_canonical(a, s);
4094 FloatParts64 pb = float64_unpack_canonical(b, s);
@@ -4113,8 +4097,7 @@ static float64 float64_minmax(float64 a, float64 b, float_status *s, int flags)
4097 return float64_round_pack_canonical(pr, s);
4098 }
4099
4116 -static float128 float128_minmax(float128 a, float128 b,
4117 - float_status *s, int flags)
4100 +float128 float128_minmax(float128 a, float128 b, float_status *s, int flags)
4101 {
4102 FloatParts128 pa = float128_unpack_canonical(a, s);
4103 FloatParts128 pb = float128_unpack_canonical(b, s);
@@ -4123,29 +4106,6 @@ static float128 float128_minmax(float128 a, float128 b,
4106 return float128_round_pack_canonical(pr, s);
4107 }
4108
4126 -#define MINMAX_1(type, name, flags) \
4127 - type type##_##name(type a, type b, float_status *s) \
4128 - { return type##_minmax(a, b, s, flags); }
4129 -
4130 -#define MINMAX_2(type) \
4131 - MINMAX_1(type, max, 0) \
4132 - MINMAX_1(type, maxnum, minmax_isnum) \
4133 - MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \
4134 - MINMAX_1(type, maximum_number, minmax_isnumber) \
4135 - MINMAX_1(type, min, minmax_ismin) \
4136 - MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \
4137 - MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag) \
4138 - MINMAX_1(type, minimum_number, minmax_ismin | minmax_isnumber) \
4139 -
4140 -MINMAX_2(float16)
4141 -MINMAX_2(bfloat16)
4142 -MINMAX_2(float32)
4143 -MINMAX_2(float64)
4144 -MINMAX_2(float128)
4145 -
4146 -#undef MINMAX_1
4147 -#undef MINMAX_2
4148 -
4109 /*
4110 * Floating point compare
4111 */
include/fpu/softfloat.h
+53 -40
@@ -132,6 +132,25 @@ enum {
132 float_muladd_suppress_add_product_zero = 8,
133 };
134
135 +/*----------------------------------------------------------------------------
136 +| Options to indicate which negations to perform in float*_minmax()
137 +*----------------------------------------------------------------------------*/
138 +
139 +/* Flags for parts_minmax. */
140 +enum {
141 + /* Set for minimum; clear for maximum. */
142 + float_minmax_ismin = 1,
143 + /* Set for the IEEE 754-2008 minNum() and maxNum() operations. */
144 + float_minmax_isnum = 2,
145 + /* Set for the IEEE 754-2008 minNumMag() and minNumMag() operations. */
146 + float_minmax_ismag = 4,
147 + /*
148 + * Set for the IEEE 754-2019 minimumNumber() and maximumNumber()
149 + * operations.
150 + */
151 + float_minmax_isnumber = 8,
152 +};
153 +
154 /*----------------------------------------------------------------------------
155 | Software IEC/IEEE integer-to-floating-point conversion routines.
156 *----------------------------------------------------------------------------*/
@@ -258,14 +277,7 @@ float16 float16_muladd_scalbn(float16, float16, float16,
277 int, int, float_status *status);
278 float16 float16_div(float16, float16, float_status *status);
279 float16 float16_scalbn(float16, int, float_status *status);
261 -float16 float16_min(float16, float16, float_status *status);
262 -float16 float16_max(float16, float16, float_status *status);
263 -float16 float16_minnum(float16, float16, float_status *status);
264 -float16 float16_maxnum(float16, float16, float_status *status);
265 -float16 float16_minnummag(float16, float16, float_status *status);
266 -float16 float16_maxnummag(float16, float16, float_status *status);
267 -float16 float16_minimum_number(float16, float16, float_status *status);
268 -float16 float16_maximum_number(float16, float16, float_status *status);
280 +float16 float16_minmax(float16, float16, float_status *status, int flags);
281 float16 float16_sqrt(float16, float_status *status);
282 FloatRelation float16_compare(float16, float16, float_status *status);
283 FloatRelation float16_compare_quiet(float16, float16, float_status *status);
@@ -451,14 +463,7 @@ bfloat16 bfloat16_div(bfloat16, bfloat16, float_status *status);
463 bfloat16 bfloat16_muladd(bfloat16, bfloat16, bfloat16, int,
464 float_status *status);
465 float16 bfloat16_scalbn(bfloat16, int, float_status *status);
454 -bfloat16 bfloat16_min(bfloat16, bfloat16, float_status *status);
455 -bfloat16 bfloat16_max(bfloat16, bfloat16, float_status *status);
456 -bfloat16 bfloat16_minnum(bfloat16, bfloat16, float_status *status);
457 -bfloat16 bfloat16_maxnum(bfloat16, bfloat16, float_status *status);
458 -bfloat16 bfloat16_minnummag(bfloat16, bfloat16, float_status *status);
459 -bfloat16 bfloat16_maxnummag(bfloat16, bfloat16, float_status *status);
460 -bfloat16 bfloat16_minimum_number(bfloat16, bfloat16, float_status *status);
461 -bfloat16 bfloat16_maximum_number(bfloat16, bfloat16, float_status *status);
466 +bfloat16 bfloat16_minmax(bfloat16, bfloat16, float_status *status, int flags);
467 bfloat16 bfloat16_sqrt(bfloat16, float_status *status);
468 FloatRelation bfloat16_compare(bfloat16, bfloat16, float_status *status);
469 FloatRelation bfloat16_compare_quiet(bfloat16, bfloat16, float_status *status);
@@ -622,14 +627,7 @@ float32 float32_exp2(float32, float_status *status);
627 float32 float32_log2(float32, float_status *status);
628 FloatRelation float32_compare(float32, float32, float_status *status);
629 FloatRelation float32_compare_quiet(float32, float32, float_status *status);
625 -float32 float32_min(float32, float32, float_status *status);
626 -float32 float32_max(float32, float32, float_status *status);
627 -float32 float32_minnum(float32, float32, float_status *status);
628 -float32 float32_maxnum(float32, float32, float_status *status);
629 -float32 float32_minnummag(float32, float32, float_status *status);
630 -float32 float32_maxnummag(float32, float32, float_status *status);
631 -float32 float32_minimum_number(float32, float32, float_status *status);
632 -float32 float32_maximum_number(float32, float32, float_status *status);
630 +float32 float32_minmax(float32, float32, float_status *status, int flags);
631 bool float32_is_quiet_nan(float32, float_status *status);
632 bool float32_is_signaling_nan(float32, float_status *status);
633 float32 float32_silence_nan(float32, float_status *status);
@@ -818,14 +816,7 @@ float64 float64_sqrt(float64, float_status *status);
816 float64 float64_log2(float64, float_status *status);
817 FloatRelation float64_compare(float64, float64, float_status *status);
818 FloatRelation float64_compare_quiet(float64, float64, float_status *status);
821 -float64 float64_min(float64, float64, float_status *status);
822 -float64 float64_max(float64, float64, float_status *status);
823 -float64 float64_minnum(float64, float64, float_status *status);
824 -float64 float64_maxnum(float64, float64, float_status *status);
825 -float64 float64_minnummag(float64, float64, float_status *status);
826 -float64 float64_maxnummag(float64, float64, float_status *status);
827 -float64 float64_minimum_number(float64, float64, float_status *status);
828 -float64 float64_maximum_number(float64, float64, float_status *status);
819 +float64 float64_minmax(float64, float64, float_status *status, int flags);
820 bool float64_is_quiet_nan(float64 a, float_status *status);
821 bool float64_is_signaling_nan(float64, float_status *status);
822 float64 float64_silence_nan(float64, float_status *status);
@@ -1279,14 +1270,7 @@ float128 float128_rem(float128, float128, float_status *status);
1270 float128 float128_sqrt(float128, float_status *status);
1271 FloatRelation float128_compare(float128, float128, float_status *status);
1272 FloatRelation float128_compare_quiet(float128, float128, float_status *status);
1282 -float128 float128_min(float128, float128, float_status *status);
1283 -float128 float128_max(float128, float128, float_status *status);
1284 -float128 float128_minnum(float128, float128, float_status *status);
1285 -float128 float128_maxnum(float128, float128, float_status *status);
1286 -float128 float128_minnummag(float128, float128, float_status *status);
1287 -float128 float128_maxnummag(float128, float128, float_status *status);
1288 -float128 float128_minimum_number(float128, float128, float_status *status);
1289 -float128 float128_maximum_number(float128, float128, float_status *status);
1273 +float128 float128_minmax(float128, float128, float_status *status, int flags);
1274 bool float128_is_quiet_nan(float128, float_status *status);
1275 bool float128_is_signaling_nan(float128, float_status *status);
1276 float128 float128_silence_nan(float128, float_status *status);
@@ -1388,4 +1372,33 @@ static inline bool float128_unordered_quiet(float128 a, float128 b,
1372 *----------------------------------------------------------------------------*/
1373 float128 float128_default_nan(float_status *status);
1374
1375 +/*----------------------------------------------------------------------------
1376 +| Minumum and maximum functions.
1377 +*----------------------------------------------------------------------------*/
1378 +
1379 +#define MINMAX_1(type, name, flags) \
1380 + static inline type type##_##name(type a, type b, float_status *s) \
1381 + { return type##_minmax(a, b, s, flags); }
1382 +
1383 +#define MINMAX_2(type) \
1384 + MINMAX_1(type, max, 0) \
1385 + MINMAX_1(type, maxnum, float_minmax_isnum) \
1386 + MINMAX_1(type, maxnummag, float_minmax_isnum | float_minmax_ismag) \
1387 + MINMAX_1(type, maximum_number, float_minmax_isnumber) \
1388 + MINMAX_1(type, min, float_minmax_ismin) \
1389 + MINMAX_1(type, minnum, float_minmax_ismin | float_minmax_isnum) \
1390 + MINMAX_1(type, minnummag, \
1391 + float_minmax_ismin | float_minmax_isnum | float_minmax_ismag) \
1392 + MINMAX_1(type, minimum_number, \
1393 + float_minmax_ismin | float_minmax_isnumber)
1394 +
1395 +MINMAX_2(float16)
1396 +MINMAX_2(bfloat16)
1397 +MINMAX_2(float32)
1398 +MINMAX_2(float64)
1399 +MINMAX_2(float128)
1400 +
1401 +#undef MINMAX_1
1402 +#undef MINMAX_2
1403 +
1404 #endif /* SOFTFLOAT_H */