@samitouri / QOSamiQemu / commits / a5fa1381ad

fpu: Drop parts_float_to_sint_modulo

Use parts64_float_to_sint_modulo at each call site. That leaves parts128_float_to_sint_modulo unused, so move the whole function back to softfloat.c and specialize for FloatParts64. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Richard Henderson committed Apr 26, 2026 at 20:16 UTC a5fa1381ad2b669352f25584cb507da00df5165e
2 files changed +72 -91
fpu/softfloat-parts.c.inc
-79
@@ -1415,85 +1415,6 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
1415 return r;
1416 }
1417
1418 -/*
1419 - * Like partsN(float_to_sint), except do not saturate the result.
1420 - * Instead, return the rounded unbounded precision two's compliment result,
1421 - * modulo 2**(bitsm1 + 1).
1422 - */
1423 -static int64_t partsN(float_to_sint_modulo)(FloatPartsN *p,
1424 - FloatRoundMode rmode,
1425 - int bitsm1, float_status *s)
1426 -{
1427 - int flags = 0;
1428 - uint64_t r;
1429 - bool overflow = false;
1430 -
1431 - switch (p->cls) {
1432 - case float_class_snan:
1433 - flags |= float_flag_invalid_snan;
1434 - /* fall through */
1435 - case float_class_qnan:
1436 - flags |= float_flag_invalid;
1437 - r = 0;
1438 - break;
1439 -
1440 - case float_class_inf:
1441 - overflow = true;
1442 - r = 0;
1443 - break;
1444 -
1445 - case float_class_zero:
1446 - return 0;
1447 -
1448 - case float_class_normal:
1449 - case float_class_denormal:
1450 - /* TODO: N - 2 is frac_size for rounding; could use input fmt. */
1451 - if (partsN(round_to_int_normal)(p, rmode, 0, N - 2)) {
1452 - flags = float_flag_inexact;
1453 - }
1454 -
1455 - if (p->exp <= DECOMPOSED_BINARY_POINT) {
1456 - /*
1457 - * Because we rounded to integral, and exp < 64,
1458 - * we know frac_low is zero.
1459 - */
1460 - r = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp);
1461 - if (p->exp < bitsm1) {
1462 - /* Result in range. */
1463 - } else if (p->exp == bitsm1) {
1464 - /* The only in-range value is INT_MIN. */
1465 - overflow = !p->sign || p->frac_hi != DECOMPOSED_IMPLICIT_BIT;
1466 - } else {
1467 - overflow = true;
1468 - }
1469 - } else {
1470 - /* Overflow, but there might still be bits to return. */
1471 - int shl = p->exp - DECOMPOSED_BINARY_POINT;
1472 - if (shl < N) {
1473 - frac_shl(p, shl);
1474 - r = p->frac_hi;
1475 - } else {
1476 - r = 0;
1477 - }
1478 - overflow = true;
1479 - }
1480 -
1481 - if (p->sign) {
1482 - r = -r;
1483 - }
1484 - break;
1485 -
1486 - default:
1487 - g_assert_not_reached();
1488 - }
1489 -
1490 - if (overflow) {
1491 - flags = float_flag_invalid | float_flag_invalid_cvti;
1492 - }
1493 - float_raise(flags, s);
1494 - return r;
1495 -}
1496 -
1418 /*
1419 * Integer to float conversions
1420 *
fpu/softfloat.c
+72 -12
@@ -779,16 +779,6 @@ static float128 QEMU_FLATTEN float128_pack_raw(const FloatParts128 *p)
779 FloatParts128 *: parts128_##NAME, \
780 FloatParts256 *: parts256_##NAME)
781
782 -static int64_t parts64_float_to_sint_modulo(FloatParts64 *p,
783 - FloatRoundMode rmode,
784 - int bitsm1, float_status *s);
785 -static int64_t parts128_float_to_sint_modulo(FloatParts128 *p,
786 - FloatRoundMode rmode,
787 - int bitsm1, float_status *s);
788 -
789 -#define parts_float_to_sint_modulo(P, R, M, S) \
790 - PARTS_GENERIC_64_128(float_to_sint_modulo, P)(P, R, M, S)
791 -
782 static void parts64_sint_to_float(FloatParts64 *p, int64_t a,
783 int scale, float_status *s);
784 static void parts128_sint_to_float(FloatParts128 *p, int64_t a,
@@ -3558,13 +3548,83 @@ int64_t bfloat16_to_int64_round_to_zero(bfloat16 a, float_status *s)
3548 return bfloat16_to_int64_scalbn(a, float_round_to_zero, 0, s);
3549 }
3550
3551 +/*
3552 + * Like partsN(float_to_sint), except do not saturate the result.
3553 + * Instead, return the rounded unbounded precision two's compliment result,
3554 + * modulo 2**(bitsm1 + 1).
3555 + */
3556 +static int64_t parts64_float_to_sint_modulo(FloatParts64 *p,
3557 + FloatRoundMode rmode,
3558 + int bitsm1, float_status *s)
3559 +{
3560 + int flags = 0;
3561 + uint64_t r;
3562 + bool overflow = false;
3563 +
3564 + switch (p->cls) {
3565 + case float_class_snan:
3566 + flags |= float_flag_invalid_snan;
3567 + /* fall through */
3568 + case float_class_qnan:
3569 + flags |= float_flag_invalid;
3570 + r = 0;
3571 + break;
3572 +
3573 + case float_class_inf:
3574 + overflow = true;
3575 + r = 0;
3576 + break;
3577 +
3578 + case float_class_zero:
3579 + return 0;
3580 +
3581 + case float_class_normal:
3582 + case float_class_denormal:
3583 + /* TODO: 64 - 2 is frac_size for rounding; could use input fmt. */
3584 + if (parts64_round_to_int_normal(p, rmode, 0, 64 - 2)) {
3585 + flags = float_flag_inexact;
3586 + }
3587 +
3588 + if (p->exp <= DECOMPOSED_BINARY_POINT) {
3589 + r = p->frac >> (DECOMPOSED_BINARY_POINT - p->exp);
3590 + if (p->exp < bitsm1) {
3591 + /* Result in range. */
3592 + } else if (p->exp == bitsm1) {
3593 + /* The only in-range value is INT_MIN. */
3594 + overflow = !p->sign || p->frac != DECOMPOSED_IMPLICIT_BIT;
3595 + } else {
3596 + overflow = true;
3597 + }
3598 + } else {
3599 + /* Overflow, but there might still be bits to return. */
3600 + int shl = p->exp - DECOMPOSED_BINARY_POINT;
3601 + r = (shl < 64 ? p->frac << shl : 0);
3602 + overflow = true;
3603 + }
3604 +
3605 + if (p->sign) {
3606 + r = -r;
3607 + }
3608 + break;
3609 +
3610 + default:
3611 + g_assert_not_reached();
3612 + }
3613 +
3614 + if (overflow) {
3615 + flags = float_flag_invalid | float_flag_invalid_cvti;
3616 + }
3617 + float_raise(flags, s);
3618 + return r;
3619 +}
3620 +
3621 int32_t float64_to_int32_modulo(float64 a, FloatRoundMode rmode,
3622 float_status *s)
3623 {
3624 FloatParts64 p;
3625
3626 float64_unpack_canonical(&p, a, s);
3567 - return parts_float_to_sint_modulo(&p, rmode, 31, s);
3627 + return parts64_float_to_sint_modulo(&p, rmode, 31, s);
3628 }
3629
3630 int64_t float64_to_int64_modulo(float64 a, FloatRoundMode rmode,
@@ -3573,7 +3633,7 @@ int64_t float64_to_int64_modulo(float64 a, FloatRoundMode rmode,
3633 FloatParts64 p;
3634
3635 float64_unpack_canonical(&p, a, s);
3576 - return parts_float_to_sint_modulo(&p, rmode, 63, s);
3636 + return parts64_float_to_sint_modulo(&p, rmode, 63, s);
3637 }
3638
3639 /*