aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/aarch64/fpu
diff options
context:
space:
mode:
authorJoe Ramsay <Joe.Ramsay@arm.com>2024-02-20 16:59:38 +0000
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2024-04-04 10:32:48 +0100
commitcb5d84f1f8527116a724e729b98412567eed6404 (patch)
tree20b988130479df83207b0f4318f2eb3f0e879eae /sysdeps/aarch64/fpu
parent3db9d208dd5f30b12900989c6d2214782b8e2011 (diff)
downloadglibc-cb5d84f1f8527116a724e729b98412567eed6404.tar.xz
glibc-cb5d84f1f8527116a724e729b98412567eed6404.zip
aarch64/fpu: Add vector variants of erf
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
Diffstat (limited to 'sysdeps/aarch64/fpu')
-rw-r--r--sysdeps/aarch64/fpu/Makefile7
-rw-r--r--sysdeps/aarch64/fpu/Versions7
-rw-r--r--sysdeps/aarch64/fpu/advsimd_f32_protos.h1
-rw-r--r--sysdeps/aarch64/fpu/bits/math-vector.h8
-rw-r--r--sysdeps/aarch64/fpu/erf_advsimd.c161
-rw-r--r--sysdeps/aarch64/fpu/erf_data.c800
-rw-r--r--sysdeps/aarch64/fpu/erf_sve.c115
-rw-r--r--sysdeps/aarch64/fpu/erff_advsimd.c123
-rw-r--r--sysdeps/aarch64/fpu/erff_data.c544
-rw-r--r--sysdeps/aarch64/fpu/erff_sve.c93
-rw-r--r--sysdeps/aarch64/fpu/sv_erf_data.c1570
-rw-r--r--sysdeps/aarch64/fpu/sv_erff_data.c1058
-rw-r--r--sysdeps/aarch64/fpu/test-double-advsimd-wrappers.c1
-rw-r--r--sysdeps/aarch64/fpu/test-double-sve-wrappers.c1
-rw-r--r--sysdeps/aarch64/fpu/test-float-advsimd-wrappers.c1
-rw-r--r--sysdeps/aarch64/fpu/test-float-sve-wrappers.c1
-rw-r--r--sysdeps/aarch64/fpu/vecmath_config.h28
17 files changed, 4518 insertions, 1 deletions
diff --git a/sysdeps/aarch64/fpu/Makefile b/sysdeps/aarch64/fpu/Makefile
index 1fe4b52682..320b6ed43a 100644
--- a/sysdeps/aarch64/fpu/Makefile
+++ b/sysdeps/aarch64/fpu/Makefile
@@ -3,6 +3,7 @@ libmvec-supported-funcs = acos \
atan \
atan2 \
cos \
+ erf \
exp \
exp10 \
exp2 \
@@ -27,7 +28,11 @@ libmvec-support = $(addsuffix f_advsimd,$(float-advsimd-funcs)) \
v_log_data \
v_exp_data \
v_log2_data \
- v_log10_data
+ v_log10_data \
+ erf_data \
+ erff_data \
+ sv_erf_data \
+ sv_erff_data
endif
sve-cflags = -march=armv8-a+sve
diff --git a/sysdeps/aarch64/fpu/Versions b/sysdeps/aarch64/fpu/Versions
index accd101184..d7b1e87191 100644
--- a/sysdeps/aarch64/fpu/Versions
+++ b/sysdeps/aarch64/fpu/Versions
@@ -78,4 +78,11 @@ libmvec {
_ZGVsMxv_tanf;
_ZGVsMxv_tan;
}
+ GLIBC_2.40 {
+ _ZGVnN2v_erf;
+ _ZGVnN2v_erff;
+ _ZGVnN4v_erff;
+ _ZGVsMxv_erf;
+ _ZGVsMxv_erff;
+ }
}
diff --git a/sysdeps/aarch64/fpu/advsimd_f32_protos.h b/sysdeps/aarch64/fpu/advsimd_f32_protos.h
index 8fec7a4b44..d8d88de218 100644
--- a/sysdeps/aarch64/fpu/advsimd_f32_protos.h
+++ b/sysdeps/aarch64/fpu/advsimd_f32_protos.h
@@ -21,6 +21,7 @@ libmvec_hidden_proto (V_NAME_F1(acos));
libmvec_hidden_proto (V_NAME_F1(asin));
libmvec_hidden_proto (V_NAME_F1(atan));
libmvec_hidden_proto (V_NAME_F1(cos));
+libmvec_hidden_proto (V_NAME_F1(erf));
libmvec_hidden_proto (V_NAME_F1(exp10));
libmvec_hidden_proto (V_NAME_F1(exp2));
libmvec_hidden_proto (V_NAME_F1(exp));
diff --git a/sysdeps/aarch64/fpu/bits/math-vector.h b/sysdeps/aarch64/fpu/bits/math-vector.h
index 04837bdcd7..71f53363a0 100644
--- a/sysdeps/aarch64/fpu/bits/math-vector.h
+++ b/sysdeps/aarch64/fpu/bits/math-vector.h
@@ -49,6 +49,10 @@
# define __DECL_SIMD_cos __DECL_SIMD_aarch64
# undef __DECL_SIMD_cosf
# define __DECL_SIMD_cosf __DECL_SIMD_aarch64
+# undef __DECL_SIMD_erf
+# define __DECL_SIMD_erf __DECL_SIMD_aarch64
+# undef __DECL_SIMD_erff
+# define __DECL_SIMD_erff __DECL_SIMD_aarch64
# undef __DECL_SIMD_exp
# define __DECL_SIMD_exp __DECL_SIMD_aarch64
# undef __DECL_SIMD_expf
@@ -120,6 +124,7 @@ __vpcs __f32x4_t _ZGVnN4v_acosf (__f32x4_t);
__vpcs __f32x4_t _ZGVnN4v_asinf (__f32x4_t);
__vpcs __f32x4_t _ZGVnN4v_atanf (__f32x4_t);
__vpcs __f32x4_t _ZGVnN4v_cosf (__f32x4_t);
+__vpcs __f32x4_t _ZGVnN4v_erff (__f32x4_t);
__vpcs __f32x4_t _ZGVnN4v_expf (__f32x4_t);
__vpcs __f32x4_t _ZGVnN4v_exp10f (__f32x4_t);
__vpcs __f32x4_t _ZGVnN4v_exp2f (__f32x4_t);
@@ -136,6 +141,7 @@ __vpcs __f64x2_t _ZGVnN2v_acos (__f64x2_t);
__vpcs __f64x2_t _ZGVnN2v_asin (__f64x2_t);
__vpcs __f64x2_t _ZGVnN2v_atan (__f64x2_t);
__vpcs __f64x2_t _ZGVnN2v_cos (__f64x2_t);
+__vpcs __f64x2_t _ZGVnN2v_erf (__f64x2_t);
__vpcs __f64x2_t _ZGVnN2v_exp (__f64x2_t);
__vpcs __f64x2_t _ZGVnN2v_exp10 (__f64x2_t);
__vpcs __f64x2_t _ZGVnN2v_exp2 (__f64x2_t);
@@ -157,6 +163,7 @@ __sv_f32_t _ZGVsMxv_acosf (__sv_f32_t, __sv_bool_t);
__sv_f32_t _ZGVsMxv_asinf (__sv_f32_t, __sv_bool_t);
__sv_f32_t _ZGVsMxv_atanf (__sv_f32_t, __sv_bool_t);
__sv_f32_t _ZGVsMxv_cosf (__sv_f32_t, __sv_bool_t);
+__sv_f32_t _ZGVsMxv_erff (__sv_f32_t, __sv_bool_t);
__sv_f32_t _ZGVsMxv_expf (__sv_f32_t, __sv_bool_t);
__sv_f32_t _ZGVsMxv_exp10f (__sv_f32_t, __sv_bool_t);
__sv_f32_t _ZGVsMxv_exp2f (__sv_f32_t, __sv_bool_t);
@@ -173,6 +180,7 @@ __sv_f64_t _ZGVsMxv_acos (__sv_f64_t, __sv_bool_t);
__sv_f64_t _ZGVsMxv_asin (__sv_f64_t, __sv_bool_t);
__sv_f64_t _ZGVsMxv_atan (__sv_f64_t, __sv_bool_t);
__sv_f64_t _ZGVsMxv_cos (__sv_f64_t, __sv_bool_t);
+__sv_f64_t _ZGVsMxv_erf (__sv_f64_t, __sv_bool_t);
__sv_f64_t _ZGVsMxv_exp (__sv_f64_t, __sv_bool_t);
__sv_f64_t _ZGVsMxv_exp10 (__sv_f64_t, __sv_bool_t);
__sv_f64_t _ZGVsMxv_exp2 (__sv_f64_t, __sv_bool_t);
diff --git a/sysdeps/aarch64/fpu/erf_advsimd.c b/sysdeps/aarch64/fpu/erf_advsimd.c
new file mode 100644
index 0000000000..3e70cbc025
--- /dev/null
+++ b/sysdeps/aarch64/fpu/erf_advsimd.c
@@ -0,0 +1,161 @@
+/* Double-precision vector (Advanced SIMD) erf function
+
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include "v_math.h"
+
+static const struct data
+{
+ float64x2_t third;
+ float64x2_t tenth, two_over_five, two_over_fifteen;
+ float64x2_t two_over_nine, two_over_fortyfive;
+ float64x2_t max, shift;
+#if WANT_SIMD_EXCEPT
+ float64x2_t tiny_bound, huge_bound, scale_minus_one;
+#endif
+} data = {
+ .third = V2 (0x1.5555555555556p-2), /* used to compute 2/3 and 1/6 too. */
+ .two_over_fifteen = V2 (0x1.1111111111111p-3),
+ .tenth = V2 (-0x1.999999999999ap-4),
+ .two_over_five = V2 (-0x1.999999999999ap-2),
+ .two_over_nine = V2 (-0x1.c71c71c71c71cp-3),
+ .two_over_fortyfive = V2 (0x1.6c16c16c16c17p-5),
+ .max = V2 (5.9921875), /* 6 - 1/128. */
+ .shift = V2 (0x1p45),
+#if WANT_SIMD_EXCEPT
+ .huge_bound = V2 (0x1p205),
+ .tiny_bound = V2 (0x1p-226),
+ .scale_minus_one = V2 (0x1.06eba8214db69p-3), /* 2/sqrt(pi) - 1.0. */
+#endif
+};
+
+#define AbsMask 0x7fffffffffffffff
+
+struct entry
+{
+ float64x2_t erf;
+ float64x2_t scale;
+};
+
+static inline struct entry
+lookup (uint64x2_t i)
+{
+ struct entry e;
+ float64x2_t e1 = vld1q_f64 ((float64_t *) (__erf_data.tab + i[0])),
+ e2 = vld1q_f64 ((float64_t *) (__erf_data.tab + i[1]));
+ e.erf = vuzp1q_f64 (e1, e2);
+ e.scale = vuzp2q_f64 (e1, e2);
+ return e;
+}
+
+/* Double-precision implementation of vector erf(x).
+ Approximation based on series expansion near x rounded to
+ nearest multiple of 1/128.
+ Let d = x - r, and scale = 2 / sqrt(pi) * exp(-r^2). For x near r,
+
+ erf(x) ~ erf(r) + scale * d * [
+ + 1
+ - r d
+ + 1/3 (2 r^2 - 1) d^2
+ - 1/6 (r (2 r^2 - 3)) d^3
+ + 1/30 (4 r^4 - 12 r^2 + 3) d^4
+ - 1/90 (4 r^4 - 20 r^2 + 15) d^5
+ ]
+
+ Maximum measure error: 2.29 ULP
+ V_NAME_D1 (erf)(-0x1.00003c924e5d1p-8) got -0x1.20dd59132ebadp-8
+ want -0x1.20dd59132ebafp-8. */
+float64x2_t VPCS_ATTR V_NAME_D1 (erf) (float64x2_t x)
+{
+ const struct data *dat = ptr_barrier (&data);
+
+ float64x2_t a = vabsq_f64 (x);
+ /* Reciprocal conditions that do not catch NaNs so they can be used in BSLs
+ to return expected results. */
+ uint64x2_t a_le_max = vcleq_f64 (a, dat->max);
+ uint64x2_t a_gt_max = vcgtq_f64 (a, dat->max);
+
+#if WANT_SIMD_EXCEPT
+ /* |x| huge or tiny. */
+ uint64x2_t cmp1 = vcgtq_f64 (a, dat->huge_bound);
+ uint64x2_t cmp2 = vcltq_f64 (a, dat->tiny_bound);
+ uint64x2_t cmp = vorrq_u64 (cmp1, cmp2);
+ /* If any lanes are special, mask them with 1 for small x or 8 for large
+ values and retain a copy of a to allow special case handler to fix special
+ lanes later. This is only necessary if fenv exceptions are to be triggered
+ correctly. */
+ if (__glibc_unlikely (v_any_u64 (cmp)))
+ {
+ a = vbslq_f64 (cmp1, v_f64 (8.0), a);
+ a = vbslq_f64 (cmp2, v_f64 (1.0), a);
+ }
+#endif
+
+ /* Set r to multiple of 1/128 nearest to |x|. */
+ float64x2_t shift = dat->shift;
+ float64x2_t z = vaddq_f64 (a, shift);
+
+ /* Lookup erf(r) and scale(r) in table, without shortcut for small values,
+ but with saturated indices for large values and NaNs in order to avoid
+ segfault. */
+ uint64x2_t i
+ = vsubq_u64 (vreinterpretq_u64_f64 (z), vreinterpretq_u64_f64 (shift));
+ i = vbslq_u64 (a_le_max, i, v_u64 (768));
+ struct entry e = lookup (i);
+
+ float64x2_t r = vsubq_f64 (z, shift);
+
+ /* erf(x) ~ erf(r) + scale * d * poly (r, d). */
+ float64x2_t d = vsubq_f64 (a, r);
+ float64x2_t d2 = vmulq_f64 (d, d);
+ float64x2_t r2 = vmulq_f64 (r, r);
+
+ /* poly (d, r) = 1 + p1(r) * d + p2(r) * d^2 + ... + p5(r) * d^5. */
+ float64x2_t p1 = r;
+ float64x2_t p2
+ = vfmsq_f64 (dat->third, r2, vaddq_f64 (dat->third, dat->third));
+ float64x2_t p3 = vmulq_f64 (r, vfmaq_f64 (v_f64 (-0.5), r2, dat->third));
+ float64x2_t p4 = vfmaq_f64 (dat->two_over_five, r2, dat->two_over_fifteen);
+ p4 = vfmsq_f64 (dat->tenth, r2, p4);
+ float64x2_t p5 = vfmaq_f64 (dat->two_over_nine, r2, dat->two_over_fortyfive);
+ p5 = vmulq_f64 (r, vfmaq_f64 (vmulq_f64 (v_f64 (0.5), dat->third), r2, p5));
+
+ float64x2_t p34 = vfmaq_f64 (p3, d, p4);
+ float64x2_t p12 = vfmaq_f64 (p1, d, p2);
+ float64x2_t y = vfmaq_f64 (p34, d2, p5);
+ y = vfmaq_f64 (p12, d2, y);
+
+ y = vfmaq_f64 (e.erf, e.scale, vfmsq_f64 (d, d2, y));
+
+ /* Solves the |x| = inf and NaN cases. */
+ y = vbslq_f64 (a_gt_max, v_f64 (1.0), y);
+
+ /* Copy sign. */
+ y = vbslq_f64 (v_u64 (AbsMask), y, x);
+
+#if WANT_SIMD_EXCEPT
+ if (__glibc_unlikely (v_any_u64 (cmp2)))
+ {
+ /* Neutralise huge values of x before fixing small values. */
+ x = vbslq_f64 (cmp1, v_f64 (1.0), x);
+ /* Fix tiny values that trigger spurious underflow. */
+ return vbslq_f64 (cmp2, vfmaq_f64 (x, dat->scale_minus_one, x), y);
+ }
+#endif
+ return y;
+}
diff --git a/sysdeps/aarch64/fpu/erf_data.c b/sysdeps/aarch64/fpu/erf_data.c
new file mode 100644
index 0000000000..6d2dcd235c
--- /dev/null
+++ b/sysdeps/aarch64/fpu/erf_data.c
@@ -0,0 +1,800 @@
+/* Table for Advanced SIMD erf approximation
+
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include "vecmath_config.h"
+
+/* Lookup table used in erf.
+ For each possible rounded input r (multiples of 1/128), between
+ r = 0.0 and r = 6.0 (769 values):
+ - the first entry __erff_data.tab.erf contains the values of erf(r),
+ - the second entry __erff_data.tab.scale contains the values of
+ 2/sqrt(pi)*exp(-r^2). Note that indices 0 and 1 are never hit by the
+ algorithm, since lookup is performed only for x >= 1/64-1/512. */
+const struct erf_data __erf_data = {
+ .tab = { { 0x0.0000000000000p+0, 0x1.20dd750429b6dp+0 },
+ { 0x1.20dbf3deb1340p-7, 0x1.20d8f1975c85dp+0 },
+ { 0x1.20d77083f17a0p-6, 0x1.20cb67bd452c7p+0 },
+ { 0x1.b137e0cf584dcp-6, 0x1.20b4d8bac36c1p+0 },
+ { 0x1.20c5645dd2538p-5, 0x1.209546ad13ccfp+0 },
+ { 0x1.68e5d3bbc9526p-5, 0x1.206cb4897b148p+0 },
+ { 0x1.b0fafef135745p-5, 0x1.203b261cd0052p+0 },
+ { 0x1.f902a77bd3821p-5, 0x1.2000a00ae3804p+0 },
+ { 0x1.207d480e90658p-4, 0x1.1fbd27cdc72d3p+0 },
+ { 0x1.44703e87e8593p-4, 0x1.1f70c3b4f2cc7p+0 },
+ { 0x1.68591a1e83b5dp-4, 0x1.1f1b7ae44867fp+0 },
+ { 0x1.8c36beb8a8d23p-4, 0x1.1ebd5552f795bp+0 },
+ { 0x1.b0081148a873ap-4, 0x1.1e565bca400d4p+0 },
+ { 0x1.d3cbf7e70a4b3p-4, 0x1.1de697e413d28p+0 },
+ { 0x1.f78159ec8bb50p-4, 0x1.1d6e14099944ap+0 },
+ { 0x1.0d939005f65e5p-3, 0x1.1cecdb718d61cp+0 },
+ { 0x1.1f5e1a35c3b89p-3, 0x1.1c62fa1e869b6p+0 },
+ { 0x1.311fc15f56d14p-3, 0x1.1bd07cdd189acp+0 },
+ { 0x1.42d7fc2f64959p-3, 0x1.1b357141d95d5p+0 },
+ { 0x1.548642321d7c6p-3, 0x1.1a91e5a748165p+0 },
+ { 0x1.662a0bdf7a89fp-3, 0x1.19e5e92b964abp+0 },
+ { 0x1.77c2d2a765f9ep-3, 0x1.19318bae53a04p+0 },
+ { 0x1.895010fdbdbfdp-3, 0x1.1874ddcdfce24p+0 },
+ { 0x1.9ad142662e14dp-3, 0x1.17aff0e56ec10p+0 },
+ { 0x1.ac45e37fe2526p-3, 0x1.16e2d7093cd8cp+0 },
+ { 0x1.bdad72110a648p-3, 0x1.160da304ed92fp+0 },
+ { 0x1.cf076d1233237p-3, 0x1.153068581b781p+0 },
+ { 0x1.e05354b96ff36p-3, 0x1.144b3b337c90cp+0 },
+ { 0x1.f190aa85540e2p-3, 0x1.135e3075d076bp+0 },
+ { 0x1.015f78a3dcf3dp-2, 0x1.12695da8b5bdep+0 },
+ { 0x1.09eed6982b948p-2, 0x1.116cd8fd67618p+0 },
+ { 0x1.127631eb8de32p-2, 0x1.1068b94962e5ep+0 },
+ { 0x1.1af54e232d609p-2, 0x1.0f5d1602f7e41p+0 },
+ { 0x1.236bef825d9a2p-2, 0x1.0e4a073dc1b91p+0 },
+ { 0x1.2bd9db0f7827fp-2, 0x1.0d2fa5a70c168p+0 },
+ { 0x1.343ed6989b7d9p-2, 0x1.0c0e0a8223359p+0 },
+ { 0x1.3c9aa8b84bedap-2, 0x1.0ae54fa490722p+0 },
+ { 0x1.44ed18d9f6462p-2, 0x1.09b58f724416bp+0 },
+ { 0x1.4d35ef3e5372ep-2, 0x1.087ee4d9ad247p+0 },
+ { 0x1.5574f4ffac98ep-2, 0x1.07416b4fbfe7cp+0 },
+ { 0x1.5da9f415ff23fp-2, 0x1.05fd3ecbec297p+0 },
+ { 0x1.65d4b75b00471p-2, 0x1.04b27bc403d30p+0 },
+ { 0x1.6df50a8dff772p-2, 0x1.03613f2812dafp+0 },
+ { 0x1.760aba57a76bfp-2, 0x1.0209a65e29545p+0 },
+ { 0x1.7e15944d9d3e4p-2, 0x1.00abcf3e187a9p+0 },
+ { 0x1.861566f5fd3c0p-2, 0x1.fe8fb01a47307p-1 },
+ { 0x1.8e0a01cab516bp-2, 0x1.fbbbbef34b4b2p-1 },
+ { 0x1.95f3353cbb146p-2, 0x1.f8dc092d58ff8p-1 },
+ { 0x1.9dd0d2b721f39p-2, 0x1.f5f0cdaf15313p-1 },
+ { 0x1.a5a2aca209394p-2, 0x1.f2fa4c16c0019p-1 },
+ { 0x1.ad68966569a87p-2, 0x1.eff8c4b1375dbp-1 },
+ { 0x1.b522646bbda68p-2, 0x1.ecec7870ebca7p-1 },
+ { 0x1.bccfec24855b8p-2, 0x1.e9d5a8e4c934ep-1 },
+ { 0x1.c4710406a65fcp-2, 0x1.e6b4982f158b9p-1 },
+ { 0x1.cc058392a6d2dp-2, 0x1.e38988fc46e72p-1 },
+ { 0x1.d38d4354c3bd0p-2, 0x1.e054be79d3042p-1 },
+ { 0x1.db081ce6e2a48p-2, 0x1.dd167c4cf9d2ap-1 },
+ { 0x1.e275eaf25e458p-2, 0x1.d9cf06898cdafp-1 },
+ { 0x1.e9d68931ae650p-2, 0x1.d67ea1a8b5368p-1 },
+ { 0x1.f129d471eabb1p-2, 0x1.d325927fb9d89p-1 },
+ { 0x1.f86faa9428f9dp-2, 0x1.cfc41e36c7df9p-1 },
+ { 0x1.ffa7ea8eb5fd0p-2, 0x1.cc5a8a3fbea40p-1 },
+ { 0x1.03693a371519cp-1, 0x1.c8e91c4d01368p-1 },
+ { 0x1.06f794ab2cae7p-1, 0x1.c5701a484ef9dp-1 },
+ { 0x1.0a7ef5c18edd2p-1, 0x1.c1efca49a5011p-1 },
+ { 0x1.0dff4f247f6c6p-1, 0x1.be68728e29d5dp-1 },
+ { 0x1.1178930ada115p-1, 0x1.bada596f25436p-1 },
+ { 0x1.14eab43841b55p-1, 0x1.b745c55905bf8p-1 },
+ { 0x1.1855a5fd3dd50p-1, 0x1.b3aafcc27502ep-1 },
+ { 0x1.1bb95c3746199p-1, 0x1.b00a46237d5bep-1 },
+ { 0x1.1f15cb50bc4dep-1, 0x1.ac63e7ecc1411p-1 },
+ { 0x1.226ae840d4d70p-1, 0x1.a8b8287ec6a09p-1 },
+ { 0x1.25b8a88b6dd7fp-1, 0x1.a5074e2157620p-1 },
+ { 0x1.28ff0240d52cdp-1, 0x1.a1519efaf889ep-1 },
+ { 0x1.2c3debfd7d6c1p-1, 0x1.9d97610879642p-1 },
+ { 0x1.2f755ce9a21f4p-1, 0x1.99d8da149c13fp-1 },
+ { 0x1.32a54cb8db67bp-1, 0x1.96164fafd8de3p-1 },
+ { 0x1.35cdb3a9a144dp-1, 0x1.925007283d7aap-1 },
+ { 0x1.38ee8a84beb71p-1, 0x1.8e86458169af8p-1 },
+ { 0x1.3c07ca9cb4f9ep-1, 0x1.8ab94f6caa71dp-1 },
+ { 0x1.3f196dcd0f135p-1, 0x1.86e9694134b9ep-1 },
+ { 0x1.42236e79a5fa6p-1, 0x1.8316d6f48133dp-1 },
+ { 0x1.4525c78dd5966p-1, 0x1.7f41dc12c9e89p-1 },
+ { 0x1.4820747ba2dc2p-1, 0x1.7b6abbb7aaf19p-1 },
+ { 0x1.4b13713ad3513p-1, 0x1.7791b886e7403p-1 },
+ { 0x1.4dfeba47f63ccp-1, 0x1.73b714a552763p-1 },
+ { 0x1.50e24ca35fd2cp-1, 0x1.6fdb11b1e0c34p-1 },
+ { 0x1.53be25d016a4fp-1, 0x1.6bfdf0beddaf5p-1 },
+ { 0x1.569243d2b3a9bp-1, 0x1.681ff24b4ab04p-1 },
+ { 0x1.595ea53035283p-1, 0x1.6441563c665d4p-1 },
+ { 0x1.5c2348ecc4dc3p-1, 0x1.60625bd75d07bp-1 },
+ { 0x1.5ee02e8a71a53p-1, 0x1.5c8341bb23767p-1 },
+ { 0x1.61955607dd15dp-1, 0x1.58a445da7c74cp-1 },
+ { 0x1.6442bfdedd397p-1, 0x1.54c5a57629db0p-1 },
+ { 0x1.66e86d0312e82p-1, 0x1.50e79d1749ac9p-1 },
+ { 0x1.69865ee075011p-1, 0x1.4d0a6889dfd9fp-1 },
+ { 0x1.6c1c9759d0e5fp-1, 0x1.492e42d78d2c5p-1 },
+ { 0x1.6eab18c74091bp-1, 0x1.4553664273d24p-1 },
+ { 0x1.7131e5f496a5ap-1, 0x1.417a0c4049fd0p-1 },
+ { 0x1.73b1021fc0cb8p-1, 0x1.3da26d759aef5p-1 },
+ { 0x1.762870f720c6fp-1, 0x1.39ccc1b136d5ap-1 },
+ { 0x1.78983697dc96fp-1, 0x1.35f93fe7d1b3dp-1 },
+ { 0x1.7b00578c26037p-1, 0x1.32281e2fd1a92p-1 },
+ { 0x1.7d60d8c979f7bp-1, 0x1.2e5991bd4cbfcp-1 },
+ { 0x1.7fb9bfaed8078p-1, 0x1.2a8dcede3673bp-1 },
+ { 0x1.820b1202f27fbp-1, 0x1.26c508f6bd0ffp-1 },
+ { 0x1.8454d5f25760dp-1, 0x1.22ff727dd6f7bp-1 },
+ { 0x1.8697120d92a4ap-1, 0x1.1f3d3cf9ffe5ap-1 },
+ { 0x1.88d1cd474a2e0p-1, 0x1.1b7e98fe26217p-1 },
+ { 0x1.8b050ef253c37p-1, 0x1.17c3b626c7a11p-1 },
+ { 0x1.8d30debfc572ep-1, 0x1.140cc3173f007p-1 },
+ { 0x1.8f5544bd00c04p-1, 0x1.1059ed7740313p-1 },
+ { 0x1.91724951b8fc6p-1, 0x1.0cab61f084b93p-1 },
+ { 0x1.9387f53df5238p-1, 0x1.09014c2ca74dap-1 },
+ { 0x1.959651980da31p-1, 0x1.055bd6d32e8d7p-1 },
+ { 0x1.979d67caa6631p-1, 0x1.01bb2b87c6968p-1 },
+ { 0x1.999d4192a5715p-1, 0x1.fc3ee5d1524b0p-2 },
+ { 0x1.9b95e8fd26abap-1, 0x1.f511a91a67d2ap-2 },
+ { 0x1.9d8768656cc42p-1, 0x1.edeeee0959518p-2 },
+ { 0x1.9f71ca72cffb6p-1, 0x1.e6d6ffaa65a25p-2 },
+ { 0x1.a1551a16aaeafp-1, 0x1.dfca26f5bbf88p-2 },
+ { 0x1.a331628a45b92p-1, 0x1.d8c8aace11e63p-2 },
+ { 0x1.a506af4cc00f4p-1, 0x1.d1d2cfff91594p-2 },
+ { 0x1.a6d50c20fa293p-1, 0x1.cae8d93f1d7b6p-2 },
+ { 0x1.a89c850b7d54dp-1, 0x1.c40b0729ed547p-2 },
+ { 0x1.aa5d265064366p-1, 0x1.bd3998457afdap-2 },
+ { 0x1.ac16fc7143263p-1, 0x1.b674c8ffc6283p-2 },
+ { 0x1.adca142b10f98p-1, 0x1.afbcd3afe8ab6p-2 },
+ { 0x1.af767a741088bp-1, 0x1.a911f096fbc26p-2 },
+ { 0x1.b11c3c79bb424p-1, 0x1.a27455e14c93cp-2 },
+ { 0x1.b2bb679ead19cp-1, 0x1.9be437a7de946p-2 },
+ { 0x1.b4540978921eep-1, 0x1.9561c7f23a47bp-2 },
+ { 0x1.b5e62fce16095p-1, 0x1.8eed36b886d93p-2 },
+ { 0x1.b771e894d602ep-1, 0x1.8886b1e5ecfd1p-2 },
+ { 0x1.b8f741ef54f83p-1, 0x1.822e655b417e6p-2 },
+ { 0x1.ba764a2af2b78p-1, 0x1.7be47af1f5d89p-2 },
+ { 0x1.bbef0fbde6221p-1, 0x1.75a91a7f4d2edp-2 },
+ { 0x1.bd61a1453ab44p-1, 0x1.6f7c69d7d3ef8p-2 },
+ { 0x1.bece0d82d1a5cp-1, 0x1.695e8cd31867ep-2 },
+ { 0x1.c034635b66e23p-1, 0x1.634fa54fa285fp-2 },
+ { 0x1.c194b1d49a184p-1, 0x1.5d4fd33729015p-2 },
+ { 0x1.c2ef0812fc1bdp-1, 0x1.575f3483021c3p-2 },
+ { 0x1.c443755820d64p-1, 0x1.517de540ce2a3p-2 },
+ { 0x1.c5920900b5fd1p-1, 0x1.4babff975a04cp-2 },
+ { 0x1.c6dad2829ec62p-1, 0x1.45e99bcbb7915p-2 },
+ { 0x1.c81de16b14cefp-1, 0x1.4036d0468a7a2p-2 },
+ { 0x1.c95b455cce69dp-1, 0x1.3a93b1998736cp-2 },
+ { 0x1.ca930e0e2a825p-1, 0x1.35005285227f1p-2 },
+ { 0x1.cbc54b476248dp-1, 0x1.2f7cc3fe6f423p-2 },
+ { 0x1.ccf20ce0c0d27p-1, 0x1.2a09153529381p-2 },
+ { 0x1.ce1962c0e0d8bp-1, 0x1.24a55399ea239p-2 },
+ { 0x1.cf3b5cdaf0c39p-1, 0x1.1f518ae487dc8p-2 },
+ { 0x1.d0580b2cfd249p-1, 0x1.1a0dc51a9934dp-2 },
+ { 0x1.d16f7dbe41ca0p-1, 0x1.14da0a961fd14p-2 },
+ { 0x1.d281c49d818d0p-1, 0x1.0fb6620c550afp-2 },
+ { 0x1.d38eefdf64fddp-1, 0x1.0aa2d09497f2bp-2 },
+ { 0x1.d4970f9ce00d9p-1, 0x1.059f59af7a906p-2 },
+ { 0x1.d59a33f19ed42p-1, 0x1.00abff4dec7a3p-2 },
+ { 0x1.d6986cfa798e7p-1, 0x1.f79183b101c5bp-3 },
+ { 0x1.d791cad3eff01p-1, 0x1.edeb406d9c824p-3 },
+ { 0x1.d8865d98abe01p-1, 0x1.e4652fadcb6b2p-3 },
+ { 0x1.d97635600bb89p-1, 0x1.daff4969c0b04p-3 },
+ { 0x1.da61623cb41e0p-1, 0x1.d1b982c501370p-3 },
+ { 0x1.db47f43b2980dp-1, 0x1.c893ce1dcbef7p-3 },
+ { 0x1.dc29fb60715afp-1, 0x1.bf8e1b1ca2279p-3 },
+ { 0x1.dd0787a8bb39dp-1, 0x1.b6a856c3ed54fp-3 },
+ { 0x1.dde0a90611a0dp-1, 0x1.ade26b7fbed95p-3 },
+ { 0x1.deb56f5f12d28p-1, 0x1.a53c4135a6526p-3 },
+ { 0x1.df85ea8db188ep-1, 0x1.9cb5bd549b111p-3 },
+ { 0x1.e0522a5dfda73p-1, 0x1.944ec2e4f5630p-3 },
+ { 0x1.e11a3e8cf4eb8p-1, 0x1.8c07329874652p-3 },
+ { 0x1.e1de3