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