[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 07/29] softfloat: Move scalbn_decomposed to softfloat-parts.c.inc
From: |
Richard Henderson |
Subject: |
[PULL 07/29] softfloat: Move scalbn_decomposed to softfloat-parts.c.inc |
Date: |
Thu, 3 Jun 2021 14:41:09 -0700 |
Rename to parts$N_scalbn.
Reimplement float128_scalbn with FloatParts128.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
fpu/softfloat.c | 103 +++++++++++++-------------------------
fpu/softfloat-parts.c.inc | 21 ++++++++
2 files changed, 55 insertions(+), 69 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6f1bbbe6cf..666b5a25d6 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -890,6 +890,12 @@ static int parts128_compare(FloatParts128 *a,
FloatParts128 *b,
#define parts_compare(A, B, S, Q) \
PARTS_GENERIC_64_128(compare, A)(A, B, S, Q)
+static void parts64_scalbn(FloatParts64 *a, int n, float_status *s);
+static void parts128_scalbn(FloatParts128 *a, int n, float_status *s);
+
+#define parts_scalbn(A, N, S) \
+ PARTS_GENERIC_64_128(scalbn, A)(A, N, S)
+
/*
* Helper functions for softfloat-parts.c.inc, per-size operations.
*/
@@ -3529,58 +3535,53 @@ FloatRelation float128_compare_quiet(float128 a,
float128 b, float_status *s)
return float128_do_compare(a, b, s, true);
}
-/* Multiply A by 2 raised to the power N. */
-static FloatParts64 scalbn_decomposed(FloatParts64 a, int n, float_status *s)
-{
- if (unlikely(is_nan(a.cls))) {
- parts_return_nan(&a, s);
- }
- if (a.cls == float_class_normal) {
- /* The largest float type (even though not supported by FloatParts64)
- * is float128, which has a 15 bit exponent. Bounding N to 16 bits
- * still allows rounding to infinity, without allowing overflow
- * within the int32_t that backs FloatParts64.exp.
- */
- n = MIN(MAX(n, -0x10000), 0x10000);
- a.exp += n;
- }
- return a;
-}
+/*
+ * Scale by 2**N
+ */
float16 float16_scalbn(float16 a, int n, float_status *status)
{
- FloatParts64 pa, pr;
+ FloatParts64 p;
- float16_unpack_canonical(&pa, a, status);
- pr = scalbn_decomposed(pa, n, status);
- return float16_round_pack_canonical(&pr, status);
+ float16_unpack_canonical(&p, a, status);
+ parts_scalbn(&p, n, status);
+ return float16_round_pack_canonical(&p, status);
}
float32 float32_scalbn(float32 a, int n, float_status *status)
{
- FloatParts64 pa, pr;
+ FloatParts64 p;
- float32_unpack_canonical(&pa, a, status);
- pr = scalbn_decomposed(pa, n, status);
- return float32_round_pack_canonical(&pr, status);
+ float32_unpack_canonical(&p, a, status);
+ parts_scalbn(&p, n, status);
+ return float32_round_pack_canonical(&p, status);
}
float64 float64_scalbn(float64 a, int n, float_status *status)
{
- FloatParts64 pa, pr;
+ FloatParts64 p;
- float64_unpack_canonical(&pa, a, status);
- pr = scalbn_decomposed(pa, n, status);
- return float64_round_pack_canonical(&pr, status);
+ float64_unpack_canonical(&p, a, status);
+ parts_scalbn(&p, n, status);
+ return float64_round_pack_canonical(&p, status);
}
bfloat16 bfloat16_scalbn(bfloat16 a, int n, float_status *status)
{
- FloatParts64 pa, pr;
+ FloatParts64 p;
- bfloat16_unpack_canonical(&pa, a, status);
- pr = scalbn_decomposed(pa, n, status);
- return bfloat16_round_pack_canonical(&pr, status);
+ bfloat16_unpack_canonical(&p, a, status);
+ parts_scalbn(&p, n, status);
+ return bfloat16_round_pack_canonical(&p, status);
+}
+
+float128 float128_scalbn(float128 a, int n, float_status *status)
+{
+ FloatParts128 p;
+
+ float128_unpack_canonical(&p, a, status);
+ parts_scalbn(&p, n, status);
+ return float128_round_pack_canonical(&p, status);
}
/*
@@ -6638,42 +6639,6 @@ floatx80 floatx80_scalbn(floatx80 a, int n, float_status
*status)
aSign, aExp, aSig, 0, status);
}
-float128 float128_scalbn(float128 a, int n, float_status *status)
-{
- bool aSign;
- int32_t aExp;
- uint64_t aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) {
- return propagateFloat128NaN(a, a, status);
- }
- return a;
- }
- if (aExp != 0) {
- aSig0 |= UINT64_C(0x0001000000000000);
- } else if (aSig0 == 0 && aSig1 == 0) {
- return a;
- } else {
- aExp++;
- }
-
- if (n > 0x10000) {
- n = 0x10000;
- } else if (n < -0x10000) {
- n = -0x10000;
- }
-
- aExp += n - 1;
- return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1
- , status);
-
-}
-
static void __attribute__((constructor)) softfloat_init(void)
{
union_float64 ua, ub, uc, ur;
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 3dacb5b4f0..bf935c4fc2 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -1075,3 +1075,24 @@ static FloatRelation partsN(compare)(FloatPartsN *a,
FloatPartsN *b,
b_sign:
return b->sign ? float_relation_greater : float_relation_less;
}
+
+/*
+ * Multiply A by 2 raised to the power N.
+ */
+static void partsN(scalbn)(FloatPartsN *a, int n, float_status *s)
+{
+ switch (a->cls) {
+ case float_class_snan:
+ case float_class_qnan:
+ parts_return_nan(a, s);
+ break;
+ case float_class_zero:
+ case float_class_inf:
+ break;
+ case float_class_normal:
+ a->exp += MIN(MAX(n, -0x10000), 0x10000);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
--
2.25.1
- [PULL 00/29] softfloat patch queue, Richard Henderson, 2021/06/03
- [PULL 01/29] softfloat: Move round_to_uint_and_pack to softfloat-parts.c.inc, Richard Henderson, 2021/06/03
- [PULL 02/29] softfloat: Move int_to_float to softfloat-parts.c.inc, Richard Henderson, 2021/06/03
- [PULL 04/29] softfloat: Move minmax_flags to softfloat-parts.c.inc, Richard Henderson, 2021/06/03
- [PULL 05/29] softfloat: Implement float128_(min|minnum|minnummag|max|maxnum|maxnummag), Richard Henderson, 2021/06/03
- [PULL 03/29] softfloat: Move uint_to_float to softfloat-parts.c.inc, Richard Henderson, 2021/06/03
- [PULL 06/29] softfloat: Move compare_floats to softfloat-parts.c.inc, Richard Henderson, 2021/06/03
- [PULL 07/29] softfloat: Move scalbn_decomposed to softfloat-parts.c.inc,
Richard Henderson <=
- [PULL 09/29] softfloat: Split out parts_uncanon_normal, Richard Henderson, 2021/06/03
- [PULL 08/29] softfloat: Move sqrt_float to softfloat-parts.c.inc, Richard Henderson, 2021/06/03
- [PULL 12/29] softfloat: Adjust parts_uncanon_normal for floatx80, Richard Henderson, 2021/06/03
- [PULL 11/29] softfloat: Introduce Floatx80RoundPrec, Richard Henderson, 2021/06/03
- [PULL 13/29] tests/fp/fp-test: Reverse order of floatx80 precision tests, Richard Henderson, 2021/06/03
- [PULL 10/29] softfloat: Reduce FloatFmt, Richard Henderson, 2021/06/03
- [PULL 14/29] softfloat: Convert floatx80_add/sub to FloatParts, Richard Henderson, 2021/06/03
- [PULL 18/29] softfloat: Convert floatx80_round to FloatParts, Richard Henderson, 2021/06/03
- [PULL 19/29] softfloat: Convert floatx80_round_to_int to FloatParts, Richard Henderson, 2021/06/03
- [PULL 16/29] softfloat: Convert floatx80_div to FloatParts, Richard Henderson, 2021/06/03