@samitouri / QOSamiQemu / commits / 333a9d621f

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;