xref: /aosp_15_r20/external/llvm-libc/src/math/generic/range_reduction_double_common.h (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Range reduction for double precision sin/cos/tan -*- C++ --------*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_COMMON_H
10 #define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_COMMON_H
11 
12 #include "src/__support/FPUtil/FPBits.h"
13 #include "src/__support/FPUtil/double_double.h"
14 #include "src/__support/FPUtil/dyadic_float.h"
15 #include "src/__support/FPUtil/multiply_add.h"
16 #include "src/__support/FPUtil/nearest_integer.h"
17 #include "src/__support/common.h"
18 #include "src/__support/integer_literals.h"
19 #include "src/__support/macros/config.h"
20 #include "src/__support/macros/optimization.h"
21 
22 namespace LIBC_NAMESPACE_DECL {
23 
24 #ifdef LIBC_TARGET_CPU_HAS_FMA
25 static constexpr unsigned SPLIT = DEFAULT_DOUBLE_SPLIT;
26 #else
27 // When there is no-FMA instructions, in order to have exact product of 2 double
28 // precision with directional roundings, we need to lower the precision of the
29 // constants by at least 1 bit, and use a different splitting constant.
30 static constexpr unsigned SPLIT = 28;
31 #endif // LIBC_TARGET_CPU_HAS_FMA
32 
33 using LIBC_NAMESPACE::fputil::DoubleDouble;
34 using Float128 = LIBC_NAMESPACE::fputil::DyadicFloat<128>;
35 
36 #define FAST_PASS_EXPONENT 16
37 
38 // For 2^-7 < |x| < 2^16, return k and u such that:
39 //   k = round(x * 128/pi)
40 //   x mod pi/128 = x - k * pi/128 ~ u.hi + u.lo
41 // Error bound:
42 //   |(x - k * pi/128) - (u_hi + u_lo)| <= max(ulp(ulp(u_hi)), 2^-119)
43 //                                      <= 2^-111.
range_reduction_small(double x,DoubleDouble & u)44 LIBC_INLINE unsigned range_reduction_small(double x, DoubleDouble &u) {
45   // Values of -pi/128 used for inputs with absolute value <= 2^16.
46   // The first 3 parts are generated with (53 - 21 = 32)-bit precision, so that
47   // the product k * MPI_OVER_128[i] is exact.
48   // Generated by Sollya with:
49   // > display = hexadecimal!;
50   // > a = round(pi/128, 32, RN);
51   // > b = round(pi/128 - a, 32, RN);
52   // > c = round(pi/128 - a - b, D, RN);
53   // > print(-a, ",", -b, ",", -c);
54   constexpr double MPI_OVER_128[3] = {-0x1.921fb544p-6, -0x1.0b4611a6p-40,
55                                       -0x1.3198a2e037073p-75};
56   constexpr double ONE_TWENTY_EIGHT_OVER_PI_D = 0x1.45f306dc9c883p5;
57   double prod_hi = x * ONE_TWENTY_EIGHT_OVER_PI_D;
58   double kd = fputil::nearest_integer(prod_hi);
59 
60   // Let y = x - k * (pi/128)
61   // Then |y| < pi / 256
62   // With extra rounding errors, we can bound |y| < 1.6 * 2^-7.
63   double y_hi = fputil::multiply_add(kd, MPI_OVER_128[0], x); // Exact
64   // |u.hi| < 1.6*2^-7
65   u.hi = fputil::multiply_add(kd, MPI_OVER_128[1], y_hi);
66   double u0 = y_hi - u.hi; // Exact
67   // |u.lo| <= max(ulp(u.hi), |kd * MPI_OVER_128[2]|)
68   double u1 = fputil::multiply_add(kd, MPI_OVER_128[1], u0); // Exact
69   u.lo = fputil::multiply_add(kd, MPI_OVER_128[2], u1);
70   // Error bound:
71   // |x - k * pi/128| - (u.hi + u.lo) <= ulp(u.lo)
72   //                                  <= ulp(max(ulp(u.hi), kd*MPI_OVER_128[2]))
73   //                                  <= 2^(-7 - 104) = 2^-111.
74 
75   return static_cast<unsigned>(static_cast<int64_t>(kd));
76 }
77 
78 // Digits of 2^(16*i) / pi, generated by Sollya with:
79 // > procedure ulp(x, n) { return 2^(floor(log2(abs(x))) - n); };
80 // > for i from 0 to 63 do {
81 //     if i < 3 then { pi_inv = 0.25 + 2^(16*(i - 3)) / pi; }
82 //     else { pi_inv = 2^(16*(i-3)) / pi; };
83 //     pn = nearestint(pi_inv);
84 //     pi_frac = pi_inv - pn;
85 //     a = round(pi_frac, 51, RN);
86 //     b = round(pi_frac - a, 51, RN);
87 //     c = round(pi_frac - a - b, 51, RN);
88 //     d = round(pi_frac - a - b - c, D, RN);
89 //     print("{", 2^7 * a, ",", 2^7 * b, ",", 2^7 * c, ",", 2^7 * d, "},");
90 // };
91 //
92 // Notice that for [0..2] the leading bit of 2^(16*(i - 3)) / pi is very small,
93 // so we add 0.25 so that the conditions for the algorithms are still satisfied,
94 // and one of those conditions guarantees that ulp(0.25 * x_reduced) >= 2, and
95 // will safely be discarded.
96 
97 static constexpr double ONE_TWENTY_EIGHT_OVER_PI[64][4] = {
98     {0x1.0000000000014p5, 0x1.7cc1b727220a8p-49, 0x1.4fe13abe8fa9cp-101,
99      -0x1.911f924eb5336p-153},
100     {0x1.0000000145f3p5, 0x1.b727220a94fep-49, 0x1.3abe8fa9a6eep-101,
101      0x1.b6c52b3278872p-155},
102     {0x1.000145f306dc8p5, 0x1.c882a53f84ebp-47, -0x1.70565911f925p-101,
103      0x1.4acc9e21c821p-153},
104     {0x1.45f306dc9c884p5, -0x1.5ac07b1505c14p-47, -0x1.96447e493ad4cp-99,
105      -0x1.b0ef1bef806bap-152},
106     {-0x1.f246c6efab58p4, -0x1.ec5417056591p-49, -0x1.f924eb53361ep-101,
107      0x1.c820ff28b1d5fp-153},
108     {0x1.391054a7f09d4p4, 0x1.f47d4d377036cp-48, 0x1.8a5664f10e41p-100,
109      0x1.fe5163abdebbcp-154},
110     {0x1.529fc2757d1f4p2, 0x1.34ddc0db62958p-50, 0x1.93c439041fe5p-102,
111      0x1.63abdebbc561bp-154},
112     {-0x1.ec5417056591p-1, -0x1.f924eb53361ep-53, 0x1.c820ff28b1d6p-105,
113      -0x1.0a21d4f246dc9p-157},
114     {-0x1.505c1596447e4p5, -0x1.275a99b0ef1cp-48, 0x1.07f9458eaf7bp-100,
115      -0x1.0ea79236e4717p-152},
116     {-0x1.596447e493ad4p1, -0x1.9b0ef1bef806cp-52, 0x1.63abdebbc561cp-106,
117      -0x1.1b7238b7b645ap-159},
118     {0x1.bb81b6c52b328p5, -0x1.de37df00d74e4p-49, 0x1.5ef5de2b0db94p-101,
119      -0x1.c8e2ded9169p-153},
120     {0x1.b6c52b3278874p5, -0x1.f7c035d38a844p-47, 0x1.778ac36e48dc8p-99,
121      -0x1.6f6c8b47fe6dbp-152},
122     {0x1.2b3278872084p5, -0x1.ae9c5421443a8p-50, -0x1.e48db91c5bdb4p-102,
123      0x1.d2e006492eea1p-154},
124     {-0x1.8778df7c035d4p5, 0x1.d5ef5de2b0db8p-49, 0x1.2371d2126e97p-101,
125      0x1.924bba8274648p-160},
126     {-0x1.bef806ba71508p4, -0x1.443a9e48db91cp-50, -0x1.6f6c8b47fe6dcp-104,
127      0x1.77504e8c90e7fp-157},
128     {-0x1.ae9c5421443a8p-2, -0x1.e48db91c5bdb4p-54, 0x1.d2e006492eeap-106,
129      0x1.3a32439fc3bd6p-159},
130     {-0x1.38a84288753c8p5, -0x1.1b7238b7b645cp-47, 0x1.c00c925dd413cp-99,
131      -0x1.cdbc603c429c7p-151},
132     {-0x1.0a21d4f246dc8p3, -0x1.c5bdb22d1ff9cp-50, 0x1.25dd413a32438p-103,
133      0x1.fc3bd63962535p-155},
134     {-0x1.d4f246dc8e2ep3, 0x1.26e9700324978p-49, -0x1.5f62e6de301e4p-102,
135      0x1.eb1cb129a73efp-154},
136     {-0x1.236e4716f6c8cp4, 0x1.700324977505p-49, -0x1.736f180f10a7p-101,
137      -0x1.a76b2c608bbeep-153},
138     {0x1.b8e909374b8p4, 0x1.924bba8274648p-48, 0x1.cfe1deb1cb128p-102,
139      0x1.a73ee88235f53p-154},
140     {0x1.09374b801924cp4, -0x1.15f62e6de302p-50, 0x1.deb1cb129a74p-102,
141      -0x1.177dca0ad144cp-154},
142     {-0x1.68ffcdb688afcp3, 0x1.d1921cfe1debp-50, 0x1.cb129a73ee884p-102,
143      -0x1.ca0ad144bb7b1p-154},
144     {0x1.924bba8274648p0, 0x1.cfe1deb1cb128p-54, 0x1.a73ee88235f54p-106,
145      -0x1.144bb7b16639p-158},
146     {-0x1.a22bec5cdbc6p5, -0x1.e214e34ed658cp-50, -0x1.177dca0ad144cp-106,
147      0x1.213a671c09ad1p-160},
148     {0x1.3a32439fc3bd8p1, -0x1.c69dacb1822fp-51, 0x1.1afa975da2428p-105,
149      -0x1.6638fd94ba082p-158},
150     {-0x1.b78c0788538d4p4, 0x1.29a73ee88236p-50, -0x1.5a28976f62cc8p-103,
151      0x1.c09ad17df904ep-156},
152     {0x1.fc3bd63962534p5, 0x1.cfba208d7d4bcp-48, -0x1.12edec598e3f8p-100,
153      0x1.ad17df904e647p-152},
154     {-0x1.4e34ed658c118p2, 0x1.046bea5d7689p-51, 0x1.3a671c09ad17cp-104,
155      0x1.f904e64758e61p-156},
156     {0x1.62534e7dd1048p5, -0x1.415a28976f62cp-47, -0x1.8e3f652e8207p-100,
157      0x1.3991d63983534p-154},
158     {-0x1.63045df7282b4p4, -0x1.44bb7b16638fcp-50, -0x1.94ba081bec67p-102,
159      0x1.d639835339f4ap-154},
160     {0x1.d1046bea5d768p5, 0x1.213a671c09adp-48, 0x1.7df904e64759p-100,
161      -0x1.9f2b3182d8defp-152},
162     {0x1.afa975da24274p3, 0x1.9c7026b45f7e4p-50, 0x1.3991d63983534p-106,
163      -0x1.82d8dee81d108p-160},
164     {-0x1.a28976f62cc7p5, -0x1.fb29741037d8cp-47, -0x1.b8a719f2b3184p-100,
165      0x1.272117e2ef7e5p-152},
166     {-0x1.76f62cc71fb28p5, -0x1.741037d8cdc54p-47, 0x1.cc1a99cfa4e44p-101,
167      -0x1.d03a21036be27p-153},
168     {0x1.d338e04d68bfp5, -0x1.bec66e29c67ccp-50, 0x1.339f49c845f8cp-102,
169      -0x1.081b5f13801dap-156},
170     {0x1.c09ad17df905p4, -0x1.9b8a719f2b318p-48, -0x1.6c6f740e8840cp-103,
171      -0x1.af89c00ed0004p-155},
172     {0x1.68befc827323cp5, -0x1.38cf9598c16c8p-47, 0x1.08bf177bf2508p-99,
173      -0x1.3801da00087eap-152},
174     {-0x1.037d8cdc538dp5, 0x1.a99cfa4e422fcp-49, 0x1.77bf250763ffp-103,
175      0x1.2fffbc0b301fep-155},
176     {-0x1.8cdc538cf9598p5, -0x1.82d8dee81d108p-48, -0x1.b5f13801dap-104,
177      -0x1.0fd33f8086877p-157},
178     {-0x1.4e33e566305bp3, -0x1.bdd03a21036cp-49, 0x1.d8ffc4bffef04p-101,
179      -0x1.33f80868773a5p-153},
180     {-0x1.f2b3182d8dee8p4, -0x1.d1081b5f138p-52, -0x1.da00087e99fcp-104,
181      -0x1.0d0ee74a5f593p-158},
182     {-0x1.8c16c6f740e88p5, -0x1.036be27003b4p-49, -0x1.0fd33f8086878p-109,
183      0x1.8b5a0a6d1f6d3p-162},
184     {0x1.3908bf177bf24p5, 0x1.0763ff12fffbcp-47, 0x1.6603fbcbc462cp-104,
185      0x1.6829b47db4dap-156},
186     {0x1.7e2ef7e4a0ec8p4, -0x1.da00087e99fcp-56, -0x1.0d0ee74a5f594p-110,
187      0x1.1f6d367ecf27dp-162},
188     {-0x1.081b5f13801dcp4, 0x1.fff7816603fbcp-48, 0x1.788c5ad05369p-101,
189      -0x1.25930261b069fp-155},
190     {-0x1.af89c00ed0004p5, -0x1.fa67f010d0ee8p-50, 0x1.6b414da3eda6cp-103,
191      0x1.fb3c9f2c26dd4p-156},
192     {-0x1.c00ed00043f4cp5, -0x1.fc04343b9d298p-48, 0x1.4da3eda6cfdap-103,
193      -0x1.b069ec9161738p-155},
194     {0x1.2fffbc0b301fcp5, 0x1.e5e2316b414dcp-47, -0x1.c125930261b08p-99,
195      0x1.6136e9e8c7ecdp-151},
196     {-0x1.0fd33f8086878p3, 0x1.8b5a0a6d1f6d4p-50, -0x1.30261b069ec9p-103,
197      -0x1.61738132c3403p-155},
198     {-0x1.9fc04343b9d28p4, -0x1.7d64b824b2604p-48, -0x1.86c1a7b24585cp-101,
199      -0x1.c09961a015d29p-154},
200     {-0x1.0d0ee74a5f594p2, 0x1.1f6d367ecf27cp-50, 0x1.6136e9e8c7eccp-103,
201      0x1.3cbfd45aea4f7p-155},
202     {-0x1.dce94beb25c14p5, 0x1.a6cfd9e4f9614p-47, -0x1.22c2e70265868p-100,
203      -0x1.5d28ad8453814p-158},
204     {-0x1.4beb25c12593p5, -0x1.30d834f648b0cp-50, 0x1.8fd9a797fa8b4p-104,
205      0x1.d49eeb1faf97cp-156},
206     {0x1.b47db4d9fb3c8p4, 0x1.f2c26dd3d18fcp-48, 0x1.9a797fa8b5d48p-100,
207      0x1.eeb1faf97c5edp-152},
208     {-0x1.25930261b06ap5, 0x1.36e9e8c7ecd3cp-47, 0x1.7fa8b5d49eebp-100,
209      0x1.faf97c5ecf41dp-152},
210     {0x1.fb3c9f2c26dd4p4, -0x1.738132c3402bcp-51, 0x1.aea4f758fd7ccp-103,
211      -0x1.d0985f18c10ebp-159},
212     {-0x1.b069ec9161738p5, -0x1.32c3402ba515cp-51, 0x1.eeb1faf97c5ecp-104,
213      0x1.e839cfbc52949p-157},
214     {-0x1.ec9161738132cp5, -0x1.a015d28ad8454p-50, 0x1.faf97c5ecf41cp-104,
215      0x1.cfbc529497536p-157},
216     {-0x1.61738132c3404p5, 0x1.45aea4f758fd8p-47, -0x1.a0e84c2f8c608p-102,
217      -0x1.d6b5b45650128p-156},
218     {0x1.fb34f2ff516bcp3, -0x1.6c229c0a0d074p-49, -0x1.30be31821d6b4p-104,
219      -0x1.b4565012813b8p-156},
220     {0x1.3cbfd45aea4f8p5, -0x1.4e050683a130cp-48, 0x1.ce7de294a4ba8p-104,
221      0x1.afed7ec47e357p-156},
222     {-0x1.5d28ad8453814p2, -0x1.a0e84c2f8c608p-54, -0x1.d6b5b45650128p-108,
223      -0x1.3b81ca8bdea7fp-164},
224     {-0x1.15b08a702834p5, -0x1.d0985f18c10ecp-47, 0x1.4a4ba9afed7ecp-100,
225      0x1.1f8d5d0856033p-154},
226 };
227 
228 // For large range |x| >= 2^16, we perform the range reduction computations as:
229 //   u = x - k * pi/128 = (pi/128) * (x * (128/pi) - k).
230 // We use the exponent of x to find 4 double-chunks of 128/pi:
231 // c_hi, c_mid, c_lo, c_lo_2 such that:
232 //   1) ulp(round(x * c_hi, D, RN)) >= 2^8 = 256,
233 //   2) If x * c_hi = ph_hi + ph_lo and x * c_mid = pm_hi + pm_lo, then
234 //        min(ulp(ph_lo), ulp(pm_hi)) >= 2^-53.
235 // This will allow us to drop the high part ph_hi and the addition:
236 //   (ph_lo + pm_hi) mod 1
237 // can be exactly representable in a double precision.
238 // This will allow us to do split the computations as:
239 //   (x * 256/pi) ~ x * (c_hi + c_mid + c_lo + c_lo_2)    (mod 256)
240 //                ~ (ph_lo + pm_hi) + (pm_lo + x * c_lo) + x * c_lo_2.
241 // Then,
242 //   round(x * 128/pi) = round(ph_lo + pm_hi)    (mod 256)
243 // And the high part of fractional part of (x * 128/pi) can simply be:
244 //   {x * 128/pi}_hi = {ph_lo + pm_hi}.
245 // To prevent overflow when x is very large, we simply scale up
246 // (c_hi, c_mid, c_lo, c_lo_2) by a fixed power of 2 (based on the index) and
247 // scale down x by the same amount.
248 
249 struct LargeRangeReduction {
250 
251   // To be implemented in range_reduction_double_fma.h and
252   // range_reduction_double_nofma.h.
253   unsigned fast(double x, DoubleDouble &u);
254 
255 #ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
accurateLargeRangeReduction256   LIBC_INLINE Float128 accurate() const {
257     constexpr Float128 PI_OVER_128_F128 = {
258         Sign::POS, -133, 0xc90f'daa2'2168'c234'c4c6'628b'80dc'1cd1_u128};
259 
260     // y_lo = x * c_lo + pm.lo
261     Float128 y_lo_0(x_reduced * ONE_TWENTY_EIGHT_OVER_PI[idx][3]);
262     Float128 y_lo_1 = fputil::quick_add(Float128(y_lo), y_lo_0);
263     Float128 y_mid_f128 = fputil::quick_add(Float128(y_mid.lo), y_lo_1);
264     Float128 y_hi_f128 = fputil::quick_add(Float128(y_hi), Float128(y_mid.hi));
265     Float128 y = fputil::quick_add(y_hi_f128, y_mid_f128);
266 
267     return fputil::quick_mul(y, PI_OVER_128_F128);
268   }
269 #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
270 
271 private:
272   // Index of x in the look-up table ONE_TWENTY_EIGHT_OVER_PI.
273   unsigned idx;
274   // x scaled down by 2^(-16 *(idx - 3))).
275   double x_reduced;
276   // Parts of (x * 128/pi) mod 1.
277   double y_hi, y_lo;
278   DoubleDouble y_mid;
279 };
280 
281 #ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
282 static Float128 range_reduction_small_f128(double x) {
283   constexpr Float128 PI_OVER_128_F128 = {
284       Sign::POS, -133, 0xc90f'daa2'2168'c234'c4c6'628b'80dc'1cd1_u128};
285   constexpr double ONE_TWENTY_EIGHT_OVER_PI_D = 0x1.45f306dc9c883p5;
286   double prod_hi = x * ONE_TWENTY_EIGHT_OVER_PI_D;
287   double kd = fputil::nearest_integer(prod_hi);
288 
289   Float128 mk_f128(-kd);
290   Float128 x_f128(x);
291   Float128 p_hi =
292       fputil::quick_mul(x_f128, Float128(ONE_TWENTY_EIGHT_OVER_PI[3][0]));
293   Float128 p_mid =
294       fputil::quick_mul(x_f128, Float128(ONE_TWENTY_EIGHT_OVER_PI[3][1]));
295   Float128 p_lo =
296       fputil::quick_mul(x_f128, Float128(ONE_TWENTY_EIGHT_OVER_PI[3][2]));
297   Float128 s_hi = fputil::quick_add(p_hi, mk_f128);
298   Float128 s_lo = fputil::quick_add(p_mid, p_lo);
299   Float128 y = fputil::quick_add(s_hi, s_lo);
300 
301   return fputil::quick_mul(y, PI_OVER_128_F128);
302 }
303 
304 static constexpr Float128 SIN_K_PI_OVER_128_F128[65] = {
305     {Sign::POS, 0, 0},
306     {Sign::POS, -133, 0xc90a'afbd'1b33'efc9'c539'edcb'fda0'cf2c_u128},
307     {Sign::POS, -132, 0xc8fb'2f88'6ec0'9f37'6a17'954b'2b7c'5171_u128},
308     {Sign::POS, -131, 0x96a9'0496'70cf'ae65'f775'7409'4d3c'35c4_u128},
309     {Sign::POS, -131, 0xc8bd'35e1'4da1'5f0e'c739'6c89'4bbf'7389_u128},
310     {Sign::POS, -131, 0xfab2'72b5'4b98'71a2'7047'29ae'56d7'8a37_u128},
311     {Sign::POS, -130, 0x9640'8374'7309'd113'000a'89a1'1e07'c1fe_u128},
312     {Sign::POS, -130, 0xaf10'a224'59fe'32a6'3fee'f3bb'58b1'f10d_u128},
313     {Sign::POS, -130, 0xc7c5'c1e3'4d30'55b2'5cc8'c00e'4fcc'd850_u128},
314     {Sign::POS, -130, 0xe05c'1353'f27b'17e5'0ebc'61ad'e6ca'83cd_u128},
315     {Sign::POS, -130, 0xf8cf'cbd9'0af8'd57a'4221'dc4b'a772'598d_u128},
316     {Sign::POS, -129, 0x888e'9315'8fb3'bb04'9841'56f5'5334'4306_u128},
317     {Sign::POS, -129, 0x94a0'3176'acf8'2d45'ae4b'a773'da6b'f754_u128},
318     {Sign::POS, -129, 0xa09a'e4a0'bb30'0a19'2f89'5f44'a303'cc0b_u128},
319     {Sign::POS, -129, 0xac7c'd3ad'58fe'e7f0'811f'9539'84ef'f83e_u128},
320     {Sign::POS, -129, 0xb844'2987'd22c'f576'9cc3'ef36'746d'e3b8_u128},
321     {Sign::POS, -129, 0xc3ef'1535'754b'168d'3122'c2a5'9efd'dc37_u128},
322     {Sign::POS, -129, 0xcf7b'ca1d'476c'516d'a812'90bd'baad'62e4_u128},
323     {Sign::POS, -129, 0xdae8'804f'0ae6'015b'362c'b974'182e'3030_u128},
324     {Sign::POS, -129, 0xe633'74c9'8e22'f0b4'2872'ce1b'fc7a'd1cd_u128},
325     {Sign::POS, -129, 0xf15a'e9c0'37b1'd8f0'6c48'e9e3'420b'0f1e_u128},
326     {Sign::POS, -129, 0xfc5d'26df'c4d5'cfda'27c0'7c91'1290'b8d1_u128},
327     {Sign::POS, -128, 0x839c'3cc9'17ff'6cb4'bfd7'9717'f288'0abf_u128},
328     {Sign::POS, -128, 0x88f5'9aa0'da59'1421'b892'ca83'61d8'c84c_u128},
329     {Sign::POS, -128, 0x8e39'd9cd'7346'4364'bba4'cfec'bff5'4867_u128},
330     {Sign::POS, -128, 0x9368'2a66'e896'f544'b178'2191'1e71'c16e_u128},
331     {Sign::POS, -128, 0x987f'bfe7'0b81'a708'19ce'c845'ac87'a5c6_u128},
332     {Sign::POS, -128, 0x9d7f'd149'0285'c9e3'e25e'3954'9638'ae68_u128},
333     {Sign::POS, -128, 0xa267'9928'48ee'b0c0'3b51'67ee'359a'234e_u128},
334     {Sign::POS, -128, 0xa736'55df'1f2f'489e'149f'6e75'9934'68a3_u128},
335     {Sign::POS, -128, 0xabeb'49a4'6764'fd15'1bec'da80'89c1'a94c_u128},
336     {Sign::POS, -128, 0xb085'baa8'e966'f6da'e4ca'd00d'5c94'bcd2_u128},
337     {Sign::POS, -128, 0xb504'f333'f9de'6484'597d'89b3'754a'be9f_u128},
338     {Sign::POS, -128, 0xb968'41bf'7ffc'b21a'9de1'e3b2'2b8b'f4db_u128},
339     {Sign::POS, -128, 0xbdae'f913'557d'76f0'ac85'320f'528d'6d5d_u128},
340     {Sign::POS, -128, 0xc1d8'705f'fcbb'6e90'bdf0'715c'b8b2'0bd7_u128},
341     {Sign::POS, -128, 0xc5e4'0358'a8ba'05a7'43da'25d9'9267'326b_u128},
342     {Sign::POS, -128, 0xc9d1'124c'931f'da7a'8335'241b'e169'3225_u128},
343     {Sign::POS, -128, 0xcd9f'023f'9c3a'059e'23af'31db'7179'a4aa_u128},
344     {Sign::POS, -128, 0xd14d'3d02'313c'0eed'744f'ea20'e8ab'ef92_u128},
345     {Sign::POS, -128, 0xd4db'3148'750d'1819'f630'e8b6'dac8'3e69_u128},
346     {Sign::POS, -128, 0xd848'52c0'a80f'fcdb'24b9'fe00'6635'74a4_u128},
347     {Sign::POS, -128, 0xdb94'1a28'cb71'ec87'2c19'b632'53da'43fc_u128},
348     {Sign::POS, -128, 0xdebe'0563'7ca9'4cfb'4b19'aa71'fec3'ae6d_u128},
349     {Sign::POS, -128, 0xe1c5'978c'05ed'8691'f4e8'a837'2f8c'5810_u128},
350     {Sign::POS, -128, 0xe4aa'5909'a08f'a7b4'1227'85ae'67f5'515d_u128},
351     {Sign::POS, -128, 0xe76b'd7a1'e63b'9786'1251'2952'9d48'a92f_u128},
352     {Sign::POS, -128, 0xea09'a68a'6e49'cd62'15ad'45b4'a1b5'e823_u128},
353     {Sign::POS, -128, 0xec83'5e79'946a'3145'7e61'0231'ac1d'6181_u128},
354     {Sign::POS, -128, 0xeed8'9db6'6611'e307'86f8'c20f'b664'b01b_u128},
355     {Sign::POS, -128, 0xf109'0827'b437'25fd'6712'7db3'5b28'7316_u128},
356     {Sign::POS, -128, 0xf314'4762'4708'8f74'a548'6bdc'455d'56a2_u128},
357     {Sign::POS, -128, 0xf4fa'0ab6'316e'd2ec'163c'5c7f'03b7'18c5_u128},
358     {Sign::POS, -128, 0xf6ba'073b'424b'19e8'2c79'1f59'cc1f'fc23_u128},
359     {Sign::POS, -128, 0xf853'f7dc'9186'b952'c7ad'c6b4'9888'91bb_u128},
360     {Sign::POS, -128, 0xf9c7'9d63'272c'4628'4504'ae08'd19b'2980_u128},
361     {Sign::POS, -128, 0xfb14'be7f'bae5'8156'2172'a361'fd2a'722f_u128},
362     {Sign::POS, -128, 0xfc3b'27d3'8a5d'49ab'2567'78ff'cb5c'1769_u128},
363     {Sign::POS, -128, 0xfd3a'abf8'4528'b50b'eae6'bd95'1c1d'abbe_u128},
364     {Sign::POS, -128, 0xfe13'2387'0cfe'9a3d'90cd'1d95'9db6'74ef_u128},
365     {Sign::POS, -128, 0xfec4'6d1e'8929'2cf0'4139'0efd'c726'e9ef_u128},
366     {Sign::POS, -128, 0xff4e'6d68'0c41'd0a9'0f66'8633'f1ab'858a_u128},
367     {Sign::POS, -128, 0xffb1'0f1b'cb6b'ef1d'421e'8eda'af59'453e_u128},
368     {Sign::POS, -128, 0xffec'4304'2668'65d9'5657'5523'6696'1732_u128},
369     {Sign::POS, 0, 1},
370 };
371 #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
372 
373 } // namespace LIBC_NAMESPACE_DECL
374 
375 #endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_COMMON_H
376