fpu: Introduce record_denormals_used
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Richard Henderson committed
Apr 26, 2026 at 08:56 UTC
333a9d621fba94a0678c9bed7612edd15a3081e5
2 files changed
+22
-35
fpu/softfloat-parts.c.inc
+14
-35
@@ -534,9 +534,8 @@ static FloatPartsN *partsN(addsub)(FloatPartsN *a, FloatPartsN *b,
534
* For addition and subtraction, we will consume an
535
* input denormal unless the other input is a NaN.
536
*/
537
- if ((ab_mask & (float_cmask_denormal | float_cmask_anynan)) ==
538
- float_cmask_denormal) {
539
- float_raise(float_flag_input_denormal_used, s);
537
+ if (!(ab_mask & float_cmask_anynan)) {
538
+ record_denormals_used(ab_mask, s);
539
}
540
541
if (a->sign != b_sign) {
@@ -623,9 +622,7 @@ static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b,
622
if (likely(cmask_is_only_normals(ab_mask))) {
623
FloatPartsW tmp;
624
626
- if (ab_mask & float_cmask_denormal) {
627
- float_raise(float_flag_input_denormal_used, s);
628
- }
625
+ record_denormals_used(ab_mask, s);
626
627
fracN(mulw)(&tmp, a, b);
628
fracN(truncjam)(a, &tmp);
@@ -653,9 +650,7 @@ static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b,
650
}
651
652
/* Multiply by 0 or Inf */
656
- if (ab_mask & float_cmask_denormal) {
657
- float_raise(float_flag_input_denormal_used, s);
658
- }
653
+ record_denormals_used(ab_mask, s);
654
655
if (ab_mask & float_cmask_inf) {
656
a->cls = float_class_inf;
@@ -784,9 +779,7 @@ static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
779
* this matches the set of cases where we consumed a
780
* denormal input.
781
*/
787
- if (abc_mask & float_cmask_denormal) {
788
- float_raise(float_flag_input_denormal_used, s);
789
- }
782
+ record_denormals_used(abc_mask, s);
783
return a;
784
785
return_sub_zero:
@@ -819,9 +812,7 @@ FloatPartsN partsN(div)(const FloatPartsN *a, const FloatPartsN *b,
812
r.exp -= b->exp;
813
814
if (likely(cmask_is_only_normals(ab_mask))) {
822
- if (ab_mask & float_cmask_denormal) {
823
- float_raise(float_flag_input_denormal_used, s);
824
- }
815
+ record_denormals_used(ab_mask, s);
816
r.exp -= fracN(div)(&r, b);
817
return r;
818
}
@@ -841,8 +832,8 @@ FloatPartsN partsN(div)(const FloatPartsN *a, const FloatPartsN *b,
832
return partsN(pick_nan)(a, b, s);
833
}
834
844
- if ((ab_mask & float_cmask_denormal) && b->cls != float_class_zero) {
845
- float_raise(float_flag_input_denormal_used, s);
835
+ if (b->cls != float_class_zero) {
836
+ record_denormals_used(ab_mask, s);
837
}
838
839
/* Inf / X */
@@ -877,9 +868,7 @@ static FloatPartsN *partsN(modrem)(FloatPartsN *a, FloatPartsN *b,
868
int ab_mask = float_cmask(a->cls) | float_cmask(b->cls);
869
870
if (likely(cmask_is_only_normals(ab_mask))) {
880
- if (ab_mask & float_cmask_denormal) {
881
- float_raise(float_flag_input_denormal_used, s);
882
- }
871
+ record_denormals_used(ab_mask, s);
872
fracN(modrem)(a, b, mod_quot);
873
return a;
874
}
@@ -901,9 +890,7 @@ static FloatPartsN *partsN(modrem)(FloatPartsN *a, FloatPartsN *b,
890
return a;
891
}
892
904
- if (ab_mask & float_cmask_denormal) {
905
- float_raise(float_flag_input_denormal_used, s);
906
- }
893
+ record_denormals_used(ab_mask, s);
894
895
/* N % Inf; 0 % N */
896
g_assert(b->cls == float_class_inf || a->cls == float_class_zero);
@@ -1493,9 +1480,7 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
1480
if ((flags & (minmax_isnum | minmax_isnumber))
1481
&& !(ab_mask & float_cmask_snan)
1482
&& (ab_mask & ~float_cmask_qnan)) {
1496
- if (ab_mask & float_cmask_denormal) {
1497
- float_raise(float_flag_input_denormal_used, s);
1498
- }
1483
+ record_denormals_used(ab_mask, s);
1484
return is_nan(a->cls) ? b : a;
1485
}
1486
@@ -1521,9 +1506,7 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
1506
return a;
1507
}
1508
1524
- if (ab_mask & float_cmask_denormal) {
1525
- float_raise(float_flag_input_denormal_used, s);
1526
- }
1509
+ record_denormals_used(ab_mask, s);
1510
1511
a_exp = a->exp;
1512
b_exp = b->exp;
@@ -1594,9 +1577,7 @@ static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b,
1577
if (likely(cmask_is_only_normals(ab_mask))) {
1578
FloatRelation cmp;
1579
1597
- if (ab_mask & float_cmask_denormal) {
1598
- float_raise(float_flag_input_denormal_used, s);
1599
- }
1580
+ record_denormals_used(ab_mask, s);
1581
1582
if (a->sign != b->sign) {
1583
goto a_sign;
@@ -1623,9 +1604,7 @@ static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b,
1604
return float_relation_unordered;
1605
}
1606
1626
- if (ab_mask & float_cmask_denormal) {
1627
- float_raise(float_flag_input_denormal_used, s);
1628
- }
1607
+ record_denormals_used(ab_mask, s);
1608
1609
if (ab_mask & float_cmask_zero) {
1610
if (ab_mask == float_cmask_zero) {
fpu/softfloat.c
+8
@@ -442,6 +442,14 @@ static inline bool is_anynorm(FloatClass c)
442
return float_cmask(c) & float_cmask_anynorm;
443
}
444
445
+/* Record when denormals have been used. */
446
+static void record_denormals_used(int mask, float_status *s)
447
+{
448
+ if (unlikely(mask & float_cmask_denormal)) {
449
+ float_raise(float_flag_input_denormal_used, s);
450
+ }
451
+}
452
+
453
/* FloatParts256 is entirely internal, for parts128_mul* */
454
typedef struct {
455
FloatClass cls;