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.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
fpu/softfloat.c | 84 +++++++++++++++++++++++++++++++++------
fpu/softfloat-parts.c.inc | 79 ------------------------------------
2 files changed, 72 insertions(+), 91 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 869b592cd0..0b2638c34b 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -779,16 +779,6 @@ static float128 QEMU_FLATTEN float128_pack_raw(const FloatParts128 *p)
FloatParts128 *: parts128_##NAME, \
FloatParts256 *: parts256_##NAME)
-static int64_t parts64_float_to_sint_modulo(FloatParts64 *p,
- FloatRoundMode rmode,
- int bitsm1, float_status *s);
-static int64_t parts128_float_to_sint_modulo(FloatParts128 *p,
- FloatRoundMode rmode,
- int bitsm1, float_status *s);
-
-#define parts_float_to_sint_modulo(P, R, M, S) \
- PARTS_GENERIC_64_128(float_to_sint_modulo, P)(P, R, M, S)
-
static void parts64_sint_to_float(FloatParts64 *p, int64_t a,
int scale, float_status *s);
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)
return bfloat16_to_int64_scalbn(a, float_round_to_zero, 0, s);
}
+/*
+ * Like partsN(float_to_sint), except do not saturate the result.
+ * Instead, return the rounded unbounded precision two's compliment result,
+ * modulo 2**(bitsm1 + 1).
+ */
+static int64_t parts64_float_to_sint_modulo(FloatParts64 *p,
+ FloatRoundMode rmode,
+ int bitsm1, float_status *s)
+{
+ int flags = 0;
+ uint64_t r;
+ bool overflow = false;
+
+ switch (p->cls) {
+ case float_class_snan:
+ flags |= float_flag_invalid_snan;
+ /* fall through */
+ case float_class_qnan:
+ flags |= float_flag_invalid;
+ r = 0;
+ break;
+
+ case float_class_inf:
+ overflow = true;
+ r = 0;
+ break;
+
+ case float_class_zero:
+ return 0;
+
+ case float_class_normal:
+ case float_class_denormal:
+ /* TODO: 64 - 2 is frac_size for rounding; could use input fmt. */
+ if (parts64_round_to_int_normal(p, rmode, 0, 64 - 2)) {
+ flags = float_flag_inexact;
+ }
+
+ if (p->exp <= DECOMPOSED_BINARY_POINT) {
+ r = p->frac >> (DECOMPOSED_BINARY_POINT - p->exp);
+ if (p->exp < bitsm1) {
+ /* Result in range. */
+ } else if (p->exp == bitsm1) {
+ /* The only in-range value is INT_MIN. */
+ overflow = !p->sign || p->frac != DECOMPOSED_IMPLICIT_BIT;
+ } else {
+ overflow = true;
+ }
+ } else {
+ /* Overflow, but there might still be bits to return. */
+ int shl = p->exp - DECOMPOSED_BINARY_POINT;
+ r = (shl < 64 ? p->frac << shl : 0);
+ overflow = true;
+ }
+
+ if (p->sign) {
+ r = -r;
+ }
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
+
+ if (overflow) {
+ flags = float_flag_invalid | float_flag_invalid_cvti;
+ }
+ float_raise(flags, s);
+ return r;
+}
+
int32_t float64_to_int32_modulo(float64 a, FloatRoundMode rmode,
float_status *s)
{
FloatParts64 p;
float64_unpack_canonical(&p, a, s);
- return parts_float_to_sint_modulo(&p, rmode, 31, s);
+ return parts64_float_to_sint_modulo(&p, rmode, 31, s);
}
int64_t float64_to_int64_modulo(float64 a, FloatRoundMode rmode,
@@ -3573,7 +3633,7 @@ int64_t float64_to_int64_modulo(float64 a, FloatRoundMode rmode,
FloatParts64 p;
float64_unpack_canonical(&p, a, s);
- return parts_float_to_sint_modulo(&p, rmode, 63, s);
+ return parts64_float_to_sint_modulo(&p, rmode, 63, s);
}
/*
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 9b719ac5cf..d8eb9f5b78 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -1415,85 +1415,6 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
return r;
}
-/*
- * Like partsN(float_to_sint), except do not saturate the result.
- * Instead, return the rounded unbounded precision two's compliment result,
- * modulo 2**(bitsm1 + 1).
- */
-static int64_t partsN(float_to_sint_modulo)(FloatPartsN *p,
- FloatRoundMode rmode,
- int bitsm1, float_status *s)
-{
- int flags = 0;
- uint64_t r;
- bool overflow = false;
-
- switch (p->cls) {
- case float_class_snan:
- flags |= float_flag_invalid_snan;
- /* fall through */
- case float_class_qnan:
- flags |= float_flag_invalid;
- r = 0;
- break;
-
- case float_class_inf:
- overflow = true;
- r = 0;
- break;
-
- case float_class_zero:
- return 0;
-
- case float_class_normal:
- case float_class_denormal:
- /* TODO: N - 2 is frac_size for rounding; could use input fmt. */
- if (partsN(round_to_int_normal)(p, rmode, 0, N - 2)) {
- flags = float_flag_inexact;
- }
-
- if (p->exp <= DECOMPOSED_BINARY_POINT) {
- /*
- * Because we rounded to integral, and exp < 64,
- * we know frac_low is zero.
- */
- r = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp);
- if (p->exp < bitsm1) {
- /* Result in range. */
- } else if (p->exp == bitsm1) {
- /* The only in-range value is INT_MIN. */
- overflow = !p->sign || p->frac_hi != DECOMPOSED_IMPLICIT_BIT;
- } else {
- overflow = true;
- }
- } else {
- /* Overflow, but there might still be bits to return. */
- int shl = p->exp - DECOMPOSED_BINARY_POINT;
- if (shl < N) {
- frac_shl(p, shl);
- r = p->frac_hi;
- } else {
- r = 0;
- }
- overflow = true;
- }
-
- if (p->sign) {
- r = -r;
- }
- break;
-
- default:
- g_assert_not_reached();
- }
-
- if (overflow) {
- flags = float_flag_invalid | float_flag_invalid_cvti;
- }
- float_raise(flags, s);
- return r;
-}
-
/*
* Integer to float conversions
*
--
2.43.0