libstdc++: Use if-constexpr in std::__try_use_facet [PR113099]
[official-gcc.git] / libdecnumber / bid / bid2dpd_dpd2bid.c
blob5bd19249e45d4703633696c6361e8b9c0365969e
1 /* Copyright (C) 2007-2024 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
8 version.
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
24 #undef IN_LIBGCC2
25 #include "bid-dpd.h"
27 /* get full 64x64bit product */
28 #define __mul_64x64_to_128(P, CX, CY) \
29 { \
30 UINT64 CXH, CXL, CYH,CYL,PL,PH,PM,PM2; \
31 CXH = (CX) >> 32; \
32 CXL = (UINT32)(CX); \
33 CYH = (CY) >> 32; \
34 CYL = (UINT32)(CY); \
36 PM = CXH*CYL; \
37 PH = CXH*CYH; \
38 PL = CXL*CYL; \
39 PM2 = CXL*CYH; \
40 PH += (PM>>32); \
41 PM = (UINT64)((UINT32)PM)+PM2+(PL>>32); \
43 (P).w[1] = PH + (PM>>32); \
44 (P).w[0] = (PM<<32)+(UINT32)PL; \
47 /* add 64-bit value to 128-bit */
48 #define __add_128_64(R128, A128, B64) \
49 { \
50 UINT64 R64H; \
51 R64H = (A128).w[1]; \
52 (R128).w[0] = (B64) + (A128).w[0]; \
53 if((R128).w[0] < (B64)) R64H ++; \
54 (R128).w[1] = R64H; \
57 /* add 128-bit value to 128-bit (assume no carry-out) */
58 #define __add_128_128(R128, A128, B128) \
59 { \
60 UINT128 Q128; \
61 Q128.w[1] = (A128).w[1]+(B128).w[1]; \
62 Q128.w[0] = (B128).w[0] + (A128).w[0]; \
63 if(Q128.w[0] < (B128).w[0]) Q128.w[1] ++; \
64 (R128).w[1] = Q128.w[1]; \
65 (R128).w[0] = Q128.w[0]; \
68 #define __mul_128x128_high(Q, A, B) \
69 { \
70 UINT128 ALBL, ALBH, AHBL, AHBH, QM, QM2; \
72 __mul_64x64_to_128(ALBH, (A).w[0], (B).w[1]); \
73 __mul_64x64_to_128(AHBL, (B).w[0], (A).w[1]); \
74 __mul_64x64_to_128(ALBL, (A).w[0], (B).w[0]); \
75 __mul_64x64_to_128(AHBH, (A).w[1],(B).w[1]); \
77 __add_128_128(QM, ALBH, AHBL); \
78 __add_128_64(QM2, QM, ALBL.w[1]); \
79 __add_128_64((Q), AHBH, QM2.w[1]); \
82 #include "bid2dpd_dpd2bid.h"
84 static const unsigned int dm103[] =
85 { 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000 };
87 void _bid_to_dpd32 (_Decimal32 *, _Decimal32 *);
89 void
90 _bid_to_dpd32 (_Decimal32 *pres, _Decimal32 *px) {
91 unsigned int sign, coefficient_x, exp, dcoeff;
92 unsigned int b2, b1, b0, b01, res;
93 _Decimal32 x = *px;
95 sign = (x & 0x80000000);
96 if ((x & 0x60000000ul) == 0x60000000ul) {
97 /* special encodings */
98 if ((x & 0x78000000ul) == 0x78000000ul) {
99 *pres = x; /* NaN or Infinity */
100 return;
102 /* coefficient */
103 coefficient_x = (x & 0x001ffffful) | 0x00800000ul;
104 if (coefficient_x >= 10000000) coefficient_x = 0;
105 /* get exponent */
106 exp = (x >> 21) & 0xff;
107 } else {
108 exp = (x >> 23) & 0xff;
109 coefficient_x = (x & 0x007ffffful);
111 b01 = coefficient_x / 1000;
112 b2 = coefficient_x - 1000 * b01;
113 b0 = b01 / 1000;
114 b1 = b01 - 1000 * b0;
115 dcoeff = b2d[b2] | b2d2[b1];
116 if (b0 >= 8) { /* is b0 8 or 9? */
117 res = sign | ((0x600 | ((exp >> 6) << 7) |
118 ((b0 & 1) << 6) | (exp & 0x3f)) << 20) | dcoeff;
119 } else { /* else b0 is 0..7 */
120 res = sign | ((((exp >> 6) << 9) | (b0 << 6) |
121 (exp & 0x3f)) << 20) | dcoeff;
123 *pres = res;
126 void _dpd_to_bid32 (_Decimal32 *, _Decimal32 *);
128 void
129 _dpd_to_bid32 (_Decimal32 *pres, _Decimal32 *px) {
130 unsigned int r;
131 unsigned int sign, exp, bcoeff;
132 UINT64 trailing;
133 unsigned int d0, d1, d2;
134 _Decimal32 x = *px;
136 sign = (x & 0x80000000);
137 trailing = (x & 0x000fffff);
138 if ((x & 0x78000000) == 0x78000000) {
139 *pres = x;
140 return;
142 /* normal number */
143 if ((x & 0x60000000) == 0x60000000) { /* G0..G1 = 11 -> d0 = 8 + G4 */
144 d0 = d2b3[((x >> 26) & 1) | 8]; /* d0 = (comb & 0x0100 ? 9 : 8); */
145 exp = (x >> 27) & 3; /* exp leading bits are G2..G3 */
146 } else {
147 d0 = d2b3[(x >> 26) & 0x7];
148 exp = (x >> 29) & 3; /* exp loading bits are G0..G1 */
150 d1 = d2b2[(trailing >> 10) & 0x3ff];
151 d2 = d2b[(trailing) & 0x3ff];
152 bcoeff = d2 + d1 + d0;
153 exp = (exp << 6) + ((x >> 20) & 0x3f);
154 if (bcoeff < (1 << 23)) {
155 r = exp;
156 r <<= 23;
157 r |= (bcoeff | sign);
158 } else {
159 r = exp;
160 r <<= 21;
161 r |= (sign | 0x60000000ul);
162 /* add coeff, without leading bits */
163 r |= (((unsigned int) bcoeff) & 0x1fffff);
165 *pres = r;
168 void _bid_to_dpd64 (_Decimal64 *, _Decimal64 *);
170 void
171 _bid_to_dpd64 (_Decimal64 *pres, _Decimal64 *px) {
172 UINT64 res;
173 UINT64 sign, comb, exp, B34, B01;
174 UINT64 d103, D61;
175 UINT64 b0, b2, b3, b5;
176 unsigned int b1, b4;
177 UINT64 bcoeff;
178 UINT64 dcoeff;
179 unsigned int yhi, ylo;
180 _Decimal64 x = *px;
182 sign = (x & 0x8000000000000000ull);
183 comb = (x & 0x7ffc000000000000ull) >> 51;
184 if ((comb & 0xf00) == 0xf00) {
185 *pres = x;
186 return;
188 /* Normal number */
189 if ((comb & 0xc00) == 0xc00) { /* G0..G1 = 11 -> exp is G2..G11 */
190 exp = (comb) & 0x3ff;
191 bcoeff = (x & 0x0007ffffffffffffull) | 0x0020000000000000ull;
192 if (bcoeff >= 10000000000000000ull)
193 bcoeff = 0;
194 } else {
195 exp = (comb >> 2) & 0x3ff;
196 bcoeff = (x & 0x001fffffffffffffull);
198 D61 = 2305843009ull; /* Floor(2^61 / 10^9) */
199 /* Multiply the binary coefficient by ceil(2^64 / 1000), and take the upper
200 64-bits in order to compute a division by 1000. */
201 yhi = (D61 * (UINT64)(bcoeff >> (UINT64)27)) >> (UINT64)34;
202 ylo = bcoeff - 1000000000ull * yhi;
203 if (ylo >= 1000000000) {
204 ylo = ylo - 1000000000;
205 yhi = yhi + 1;
207 d103 = 0x4189374c;
208 B34 = ((UINT64) ylo * d103) >> (32 + 8);
209 B01 = ((UINT64) yhi * d103) >> (32 + 8);
210 b5 = ylo - B34 * 1000;
211 b2 = yhi - B01 * 1000;
212 b3 = ((UINT64) B34 * d103) >> (32 + 8);
213 b0 = ((UINT64) B01 * d103) >> (32 + 8);
214 b4 = (unsigned int) B34 - (unsigned int) b3 *1000;
215 b1 = (unsigned int) B01 - (unsigned int) dm103[b0];
216 dcoeff = b2d[b5] | b2d2[b4] | b2d3[b3] | b2d4[b2] | b2d5[b1];
217 if (b0 >= 8) /* is b0 8 or 9? */
218 res = sign | ((0x1800 | ((exp >> 8) << 9) | ((b0 & 1) << 8) |
219 (exp & 0xff)) << 50) | dcoeff;
220 else /* else b0 is 0..7 */
221 res = sign | ((((exp >> 8) << 11) | (b0 << 8) |
222 (exp & 0xff)) << 50) | dcoeff;
223 *pres = res;
226 void _dpd_to_bid64 (_Decimal64 *, _Decimal64 *);
228 void
229 _dpd_to_bid64 (_Decimal64 *pres, _Decimal64 *px) {
230 UINT64 res;
231 UINT64 sign, comb, exp;
232 UINT64 trailing;
233 UINT64 d0, d1, d2;
234 unsigned int d3, d4, d5;
235 UINT64 bcoeff, mask;
236 _Decimal64 x = *px;
238 sign = (x & 0x8000000000000000ull);
239 comb = (x & 0x7ffc000000000000ull) >> 50;
240 trailing = (x & 0x0003ffffffffffffull);
241 if ((comb & 0x1e00) == 0x1e00) {
242 *pres = x;
243 return;
245 /* normal number */
246 if ((comb & 0x1800) == 0x1800) { /* G0..G1 = 11 -> d0 = 8 + G4 */
247 d0 = d2b6[((comb >> 8) & 1) | 8]; /* d0 = (comb & 0x0100 ? 9 : 8); */
248 exp = (comb & 0x600) >> 1; /* exp = (comb & 0x0400 ? 1 : 0) * 0x200 +
249 (comb & 0x0200 ? 1 : 0) * 0x100; exp leading bits are G2..G3 */
250 } else {
251 d0 = d2b6[(comb >> 8) & 0x7];
252 exp = (comb & 0x1800) >> 3; /* exp = (comb & 0x1000 ? 1 : 0) * 0x200 +
253 (comb & 0x0800 ? 1 : 0) * 0x100; exp loading bits are G0..G1 */
255 d1 = d2b5[(trailing >> 40) & 0x3ff];
256 d2 = d2b4[(trailing >> 30) & 0x3ff];
257 d3 = d2b3[(trailing >> 20) & 0x3ff];
258 d4 = d2b2[(trailing >> 10) & 0x3ff];
259 d5 = d2b[(trailing) & 0x3ff];
260 bcoeff = (d5 + d4 + d3) + d2 + d1 + d0;
261 exp += (comb & 0xff);
262 mask = 1;
263 mask <<= 53;
264 if (bcoeff < mask) { /* check whether coefficient fits in 10*5+3 bits */
265 res = exp;
266 res <<= 53;
267 res |= (bcoeff | sign);
268 *pres = res;
269 return;
271 /* special format */
272 res = (exp << 51) | (sign | 0x6000000000000000ull);
273 /* add coeff, without leading bits */
274 mask = (mask >> 2) - 1;
275 bcoeff &= mask;
276 res |= bcoeff;
277 *pres = res;
280 void _bid_to_dpd128 (_Decimal128 *, _Decimal128 *);
282 void
283 _bid_to_dpd128 (_Decimal128 *pres, _Decimal128 *px) {
284 UINT128 res;
285 UINT128 sign;
286 unsigned int comb;
287 UINT128 bcoeff;
288 UINT128 dcoeff;
289 UINT128 BH, d1018, BT2, BT1;
290 UINT64 exp, BL, d109;
291 UINT64 d106, d103;
292 UINT64 k1, k2, k4, k5, k7, k8, k10, k11;
293 unsigned int BHH32, BLL32, BHL32, BLH32, k0, k3, k6, k9, amount;
294 _Decimal128 x = *px;
296 sign.w[1] = (x.w[1] & 0x8000000000000000ull);
297 sign.w[0] = 0;
298 comb = (x.w[1] /*& 0x7fffc00000000000ull */ ) >> 46;
299 exp = 0;
300 if ((comb & 0x1e000) == 0x1e000) {
301 res = x;
302 } else { /* normal number */
303 if ((comb & 0x18000) == 0x18000) {
304 /* Noncanonical significand (prepending 8 or 9 to any 110-bit
305 trailing significand field produces a value above 10^34). */
306 exp = (comb & 0x7fff) >> 1;
307 bcoeff.w[1] = 0;
308 bcoeff.w[0] = 0;
309 } else {
310 exp = ((x.w[1] & 0x7fff000000000000ull) >> 49) & 0x3fff;
311 bcoeff.w[1] = (x.w[1] & 0x0001ffffffffffffull);
312 bcoeff.w[0] = x.w[0];
313 if (bcoeff.w[1] > 0x1ed09bead87c0ull
314 || (bcoeff.w[1] == 0x1ed09bead87c0ull
315 && bcoeff.w[0] >= 0x378d8e6400000000ull)) {
316 bcoeff.w[1] = 0;
317 bcoeff.w[0] = 0;
320 d1018 = reciprocals10_128[18];
321 __mul_128x128_high (BH, bcoeff, d1018);
322 amount = recip_scale[18];
323 BH.w[0] = (BH.w[0] >> amount) | (BH.w[1] << (64 - amount));
324 BL = bcoeff.w[0] - BH.w[0] * 1000000000000000000ull;
325 d109 = reciprocals10_64[9];
326 __mul_64x64_to_128 (BT1, BH.w[0], d109);
327 BHH32 = (unsigned int) (BT1.w[1] >> short_recip_scale[9]);
328 BHL32 = (unsigned int) BH.w[0] - BHH32 * 1000000000;
329 __mul_64x64_to_128 (BT2, BL, d109);
330 BLH32 = (unsigned int) (BT2.w[1] >> short_recip_scale[9]);
331 BLL32 = (unsigned int) BL - BLH32 * 1000000000;
332 d106 = 0x431BDE83;
333 d103 = 0x4189374c;
334 k0 = ((UINT64) BHH32 * d106) >> (32 + 18);
335 BHH32 -= (unsigned int) k0 *1000000;
336 k1 = ((UINT64) BHH32 * d103) >> (32 + 8);
337 k2 = BHH32 - (unsigned int) k1 *1000;
338 k3 = ((UINT64) BHL32 * d106) >> (32 + 18);
339 BHL32 -= (unsigned int) k3 *1000000;
340 k4 = ((UINT64) BHL32 * d103) >> (32 + 8);
341 k5 = BHL32 - (unsigned int) k4 *1000;
342 k6 = ((UINT64) BLH32 * d106) >> (32 + 18);
343 BLH32 -= (unsigned int) k6 *1000000;
344 k7 = ((UINT64) BLH32 * d103) >> (32 + 8);
345 k8 = BLH32 - (unsigned int) k7 *1000;
346 k9 = ((UINT64) BLL32 * d106) >> (32 + 18);
347 BLL32 -= (unsigned int) k9 *1000000;
348 k10 = ((UINT64) BLL32 * d103) >> (32 + 8);
349 k11 = BLL32 - (unsigned int) k10 *1000;
350 dcoeff.w[1] = (b2d[k5] >> 4) | (b2d[k4] << 6) | (b2d[k3] << 16) |
351 (b2d[k2] << 26) | (b2d[k1] << 36);
352 dcoeff.w[0] = b2d[k11] | (b2d[k10] << 10) | (b2d[k9] << 20) |
353 (b2d[k8] << 30) | (b2d[k7] << 40) | (b2d[k6] << 50) | (b2d[k5] << 60);
354 res.w[0] = dcoeff.w[0];
355 if (k0 >= 8) {
356 res.w[1] = sign.w[1] | ((0x18000 | ((exp >> 12) << 13) |
357 ((k0 & 1) << 12) | (exp & 0xfff)) << 46) | dcoeff.w[1];
358 } else {
359 res.w[1] = sign.w[1] | ((((exp >> 12) << 15) | (k0 << 12) |
360 (exp & 0xfff)) << 46) | dcoeff.w[1];
363 *pres = res;
366 void _dpd_to_bid128 (_Decimal128 *, _Decimal128 *);
368 void
369 _dpd_to_bid128 (_Decimal128 *pres, _Decimal128 *px) {
370 UINT128 res;
371 UINT128 sign;
372 UINT64 exp, comb;
373 UINT128 trailing;
374 UINT64 d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11;
375 UINT128 bcoeff;
376 UINT64 tl, th;
377 _Decimal128 x = *px;
379 sign.w[1] = (x.w[1] & 0x8000000000000000ull);
380 sign.w[0] = 0;
381 comb = (x.w[1] & 0x7fffc00000000000ull) >> 46;
382 trailing.w[1] = x.w[1];
383 trailing.w[0] = x.w[0];
384 if ((comb & 0x1e000) == 0x1e000) {
385 *pres = x;
386 return;
388 if ((comb & 0x18000) == 0x18000) { /* G0..G1 = 11 -> d0 = 8 + G4 */
389 d0 = d2b6[8 + ((comb & 0x01000) >> 12)];
390 exp = (comb & 0x06000) >> 1; /* exp leading bits are G2..G3 */
391 } else {
392 d0 = d2b6[((comb & 0x07000) >> 12)];
393 exp = (comb & 0x18000) >> 3; /* exp loading bits are G0..G1 */
395 d11 = d2b[(trailing.w[0]) & 0x3ff];
396 d10 = d2b2[(trailing.w[0] >> 10) & 0x3ff];
397 d9 = d2b3[(trailing.w[0] >> 20) & 0x3ff];
398 d8 = d2b4[(trailing.w[0] >> 30) & 0x3ff];
399 d7 = d2b5[(trailing.w[0] >> 40) & 0x3ff];
400 d6 = d2b6[(trailing.w[0] >> 50) & 0x3ff];
401 d5 = d2b[(trailing.w[0] >> 60) | ((trailing.w[1] & 0x3f) << 4)];
402 d4 = d2b2[(trailing.w[1] >> 6) & 0x3ff];
403 d3 = d2b3[(trailing.w[1] >> 16) & 0x3ff];
404 d2 = d2b4[(trailing.w[1] >> 26) & 0x3ff];
405 d1 = d2b5[(trailing.w[1] >> 36) & 0x3ff];
406 tl = d11 + d10 + d9 + d8 + d7 + d6;
407 th = d5 + d4 + d3 + d2 + d1 + d0;
408 __mul_64x64_to_128 (bcoeff, th, 1000000000000000000ull);
409 __add_128_64 (bcoeff, bcoeff, tl);
410 exp += (comb & 0xfff);
411 res.w[0] = bcoeff.w[0];
412 res.w[1] = (exp << 49) | sign.w[1] | bcoeff.w[1];
413 *pres = res;