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 */