fpu: Drop parts_log2
Use parts64_log2 at each call site. That leaves parts128_log2 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:40 UTC
d2a727e34732e57fb40d9f42d0c09a6d3a6c6ddf
2 files changed
+125
-139
fpu/softfloat-parts.c.inc
-131
@@ -1671,134 +1671,3 @@ static void partsN(scalbn)(FloatPartsN *a, int n, float_status *s)
1671
g_assert_not_reached();
1672
}
1673
}
1674
-
1675
-/*
1676
- * Return log2(A)
1677
- */
1678
-static void partsN(log2)(FloatPartsN *a, float_status *s, const FloatFmt *fmt)
1679
-{
1680
- uint64_t a0, a1, r, t, ign;
1681
- FloatPartsN f;
1682
- int i, n, a_exp, f_exp;
1683
-
1684
- if (unlikely(a->cls != float_class_normal)) {
1685
- switch (a->cls) {
1686
- case float_class_denormal:
1687
- if (!a->sign) {
1688
- /* -ve denormal will be InvalidOperation */
1689
- float_raise(float_flag_input_denormal_used, s);
1690
- }
1691
- break;
1692
- case float_class_snan:
1693
- case float_class_qnan:
1694
- partsN(return_nan)(a, s);
1695
- return;
1696
- case float_class_zero:
1697
- float_raise(float_flag_divbyzero, s);
1698
- /* log2(0) = -inf */
1699
- a->cls = float_class_inf;
1700
- a->sign = 1;
1701
- return;
1702
- case float_class_inf:
1703
- if (unlikely(a->sign)) {
1704
- goto d_nan;
1705
- }
1706
- return;
1707
- default:
1708
- g_assert_not_reached();
1709
- }
1710
- }
1711
- if (unlikely(a->sign)) {
1712
- goto d_nan;
1713
- }
1714
-
1715
- /* TODO: This algorithm looses bits too quickly for float128. */
1716
- g_assert(N == 64);
1717
-
1718
- a_exp = a->exp;
1719
- f_exp = -1;
1720
-
1721
- r = 0;
1722
- t = DECOMPOSED_IMPLICIT_BIT;
1723
- a0 = a->frac_hi;
1724
- a1 = 0;
1725
-
1726
- n = fmt->frac_size + 2;
1727
- if (unlikely(a_exp == -1)) {
1728
- /*
1729
- * When a_exp == -1, we're computing the log2 of a value [0.5,1.0).
1730
- * When the value is very close to 1.0, there are lots of 1's in
1731
- * the msb parts of the fraction. At the end, when we subtract
1732
- * this value from -1.0, we can see a catastrophic loss of precision,
1733
- * as 0x800..000 - 0x7ff..ffx becomes 0x000..00y, leaving only the
1734
- * bits of y in the final result. To minimize this, compute as many
1735
- * digits as we can.
1736
- * ??? This case needs another algorithm to avoid this.
1737
- */
1738
- n = fmt->frac_size * 2 + 2;
1739
- /* Don't compute a value overlapping the sticky bit */
1740
- n = MIN(n, 62);
1741
- }
1742
-
1743
- for (i = 0; i < n; i++) {
1744
- if (a1) {
1745
- mul128To256(a0, a1, a0, a1, &a0, &a1, &ign, &ign);
1746
- } else if (a0 & 0xffffffffull) {
1747
- mul64To128(a0, a0, &a0, &a1);
1748
- } else if (a0 & ~DECOMPOSED_IMPLICIT_BIT) {
1749
- a0 >>= 32;
1750
- a0 *= a0;
1751
- } else {
1752
- goto exact;
1753
- }
1754
-
1755
- if (a0 & DECOMPOSED_IMPLICIT_BIT) {
1756
- if (unlikely(a_exp == 0 && r == 0)) {
1757
- /*
1758
- * When a_exp == 0, we're computing the log2 of a value
1759
- * [1.0,2.0). When the value is very close to 1.0, there
1760
- * are lots of 0's in the msb parts of the fraction.
1761
- * We need to compute more digits to produce a correct
1762
- * result -- restart at the top of the fraction.
1763
- * ??? This is likely to lose precision quickly, as for
1764
- * float128; we may need another method.
1765
- */
1766
- f_exp -= i;
1767
- t = r = DECOMPOSED_IMPLICIT_BIT;
1768
- i = 0;
1769
- } else {
1770
- r |= t;
1771
- }
1772
- } else {
1773
- add128(a0, a1, a0, a1, &a0, &a1);
1774
- }
1775
- t >>= 1;
1776
- }
1777
-
1778
- /* Set sticky for inexact. */
1779
- r |= (a1 || a0 & ~DECOMPOSED_IMPLICIT_BIT);
1780
-
1781
- exact:
1782
- partsN(sint_to_float)(a, a_exp, 0, s);
1783
- if (r == 0) {
1784
- return;
1785
- }
1786
-
1787
- memset(&f, 0, sizeof(f));
1788
- f.cls = float_class_normal;
1789
- f.frac_hi = r;
1790
- f.exp = f_exp - frac_normalize(&f);
1791
-
1792
- if (a_exp < 0) {
1793
- partsN(sub_normal)(a, &f);
1794
- } else if (a_exp > 0) {
1795
- partsN(add_normal)(a, &f);
1796
- } else {
1797
- *a = f;
1798
- }
1799
- return;
1800
-
1801
- d_nan:
1802
- float_raise(float_flag_invalid, s);
1803
- partsN(default_nan)(a, s);
1804
-}
fpu/softfloat.c
+125
-8
@@ -779,12 +779,6 @@ static float128 QEMU_FLATTEN float128_pack_raw(const FloatParts128 *p)
779
FloatParts128 *: parts128_##NAME, \
780
FloatParts256 *: parts256_##NAME)
781
782
-static void parts64_log2(FloatParts64 *a, float_status *s, const FloatFmt *f);
783
-static void parts128_log2(FloatParts128 *a, float_status *s, const FloatFmt *f);
784
-
785
-#define parts_log2(A, S, F) \
786
- PARTS_GENERIC_64_128(log2, A)(A, S, F)
787
-
782
/*
783
* Helper functions for softfloat-parts.c.inc, per-size operations.
784
*/
@@ -4851,12 +4845,135 @@ floatx80 floatx80_sqrt(floatx80 a, float_status *s)
4845
/*
4846
* log2
4847
*/
4848
+
4849
+static void parts64_log2(FloatParts64 *a, float_status *s, const FloatFmt *fmt)
4850
+{
4851
+ uint64_t a0, a1, r, t, ign;
4852
+ int i, n, a_exp, f_exp;
4853
+
4854
+ if (unlikely(a->cls != float_class_normal)) {
4855
+ switch (a->cls) {
4856
+ case float_class_denormal:
4857
+ if (!a->sign) {
4858
+ /* -ve denormal will be InvalidOperation */
4859
+ float_raise(float_flag_input_denormal_used, s);
4860
+ }
4861
+ break;
4862
+ case float_class_snan:
4863
+ case float_class_qnan:
4864
+ parts64_return_nan(a, s);
4865
+ return;
4866
+ case float_class_zero:
4867
+ float_raise(float_flag_divbyzero, s);
4868
+ /* log2(0) = -inf */
4869
+ a->cls = float_class_inf;
4870
+ a->sign = 1;
4871
+ return;
4872
+ case float_class_inf:
4873
+ if (unlikely(a->sign)) {
4874
+ goto d_nan;
4875
+ }
4876
+ return;
4877
+ default:
4878
+ g_assert_not_reached();
4879
+ }
4880
+ }
4881
+ if (unlikely(a->sign)) {
4882
+ goto d_nan;
4883
+ }
4884
+
4885
+ a_exp = a->exp;
4886
+ f_exp = -1;
4887
+
4888
+ r = 0;
4889
+ t = DECOMPOSED_IMPLICIT_BIT;
4890
+ a0 = a->frac_hi;
4891
+ a1 = 0;
4892
+
4893
+ n = fmt->frac_size + 2;
4894
+ if (unlikely(a_exp == -1)) {
4895
+ /*
4896
+ * When a_exp == -1, we're computing the log2 of a value [0.5,1.0).
4897
+ * When the value is very close to 1.0, there are lots of 1's in
4898
+ * the msb parts of the fraction. At the end, when we subtract
4899
+ * this value from -1.0, we can see a catastrophic loss of precision,
4900
+ * as 0x800..000 - 0x7ff..ffx becomes 0x000..00y, leaving only the
4901
+ * bits of y in the final result. To minimize this, compute as many
4902
+ * digits as we can.
4903
+ * ??? This case needs another algorithm to avoid this.
4904
+ */
4905
+ n = fmt->frac_size * 2 + 2;
4906
+ /* Don't compute a value overlapping the sticky bit */
4907
+ n = MIN(n, 62);
4908
+ }
4909
+
4910
+ for (i = 0; i < n; i++) {
4911
+ if (a1) {
4912
+ mul128To256(a0, a1, a0, a1, &a0, &a1, &ign, &ign);
4913
+ } else if (a0 & 0xffffffffull) {
4914
+ mul64To128(a0, a0, &a0, &a1);
4915
+ } else if (a0 & ~DECOMPOSED_IMPLICIT_BIT) {
4916
+ a0 >>= 32;
4917
+ a0 *= a0;
4918
+ } else {
4919
+ goto exact;
4920
+ }
4921
+
4922
+ if (a0 & DECOMPOSED_IMPLICIT_BIT) {
4923
+ if (unlikely(a_exp == 0 && r == 0)) {
4924
+ /*
4925
+ * When a_exp == 0, we're computing the log2 of a value
4926
+ * [1.0,2.0). When the value is very close to 1.0, there
4927
+ * are lots of 0's in the msb parts of the fraction.
4928
+ * We need to compute more digits to produce a correct
4929
+ * result -- restart at the top of the fraction.
4930
+ * ??? This is likely to lose precision quickly, as for
4931
+ * float128; we may need another method.
4932
+ */
4933
+ f_exp -= i;
4934
+ t = r = DECOMPOSED_IMPLICIT_BIT;
4935
+ i = 0;
4936
+ } else {
4937
+ r |= t;
4938
+ }
4939
+ } else {
4940
+ add128(a0, a1, a0, a1, &a0, &a1);
4941
+ }
4942
+ t >>= 1;
4943
+ }
4944
+
4945
+ /* Set sticky for inexact. */
4946
+ r |= (a1 || a0 & ~DECOMPOSED_IMPLICIT_BIT);
4947
+
4948
+ exact:
4949
+ parts64_sint_to_float(a, a_exp, 0, s);
4950
+ if (r != 0) {
4951
+ FloatParts64 f = {
4952
+ .cls = float_class_normal, .frac = r
4953
+ };
4954
+ f.exp = f_exp - frac_normalize(&f);
4955
+
4956
+ if (a_exp < 0) {
4957
+ parts64_sub_normal(a, &f);
4958
+ } else if (a_exp > 0) {
4959
+ parts64_add_normal(a, &f);
4960
+ } else {
4961
+ *a = f;
4962
+ }
4963
+ }
4964
+ return;
4965
+
4966
+ d_nan:
4967
+ float_raise(float_flag_invalid, s);
4968
+ parts64_default_nan(a, s);
4969
+}
4970
+
4971
float32 float32_log2(float32 a, float_status *status)
4972
{
4973
FloatParts64 p;
4974
4975
float32_unpack_canonical(&p, a, status);
4859
- parts_log2(&p, status, &float32_params);
4976
+ parts64_log2(&p, status, &float32_params);
4977
return float32_round_pack_canonical(&p, status);
4978
}
4979
@@ -4865,7 +4982,7 @@ float64 float64_log2(float64 a, float_status *status)
4982
FloatParts64 p;
4983
4984
float64_unpack_canonical(&p, a, status);
4868
- parts_log2(&p, status, &float64_params);
4985
+ parts64_log2(&p, status, &float64_params);
4986
return float64_round_pack_canonical(&p, status);
4987
}
4988