Branch data Line data Source code
1 : : /* Decimal floating point support.
2 : : Copyright (C) 2005-2025 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #include "config.h"
21 : : #include "system.h"
22 : : #include "coretypes.h"
23 : : #include "tm.h"
24 : : #include "tree.h"
25 : : #include "dfp.h"
26 : :
27 : : /* The order of the following headers is important for making sure
28 : : decNumber structure is large enough to hold decimal128 digits. */
29 : :
30 : : #include "decimal128.h"
31 : : #include "decimal64.h"
32 : : #include "decimal32.h"
33 : :
34 : : #ifndef WORDS_BIGENDIAN
35 : : #define WORDS_BIGENDIAN 0
36 : : #endif
37 : :
38 : : /* Initialize R (a real with the decimal flag set) from DN. Can
39 : : utilize status passed in via CONTEXT, if a previous operation had
40 : : interesting status. */
41 : :
42 : : static void
43 : 920708 : decimal_from_decnumber (REAL_VALUE_TYPE *r, decNumber *dn, decContext *context)
44 : : {
45 : 920708 : memset (r, 0, sizeof (REAL_VALUE_TYPE));
46 : :
47 : 920708 : r->cl = rvc_normal;
48 : 920708 : if (decNumberIsNaN (dn))
49 : 486 : r->cl = rvc_nan;
50 : 920708 : if (decNumberIsInfinite (dn))
51 : 1287 : r->cl = rvc_inf;
52 : 920708 : if (context->status & DEC_Overflow)
53 : 929 : r->cl = rvc_inf;
54 : 920708 : if (decNumberIsNegative (dn))
55 : 291788 : r->sign = 1;
56 : 920708 : r->decimal = 1;
57 : :
58 : 920708 : if (r->cl != rvc_normal)
59 : : return;
60 : :
61 : 918935 : decContextDefault (context, DEC_INIT_DECIMAL128);
62 : 918935 : context->traps = 0;
63 : :
64 : 918935 : decimal128FromNumber ((decimal128 *) r->sig, dn, context);
65 : : }
66 : :
67 : : /* Create decimal encoded R from string S. */
68 : :
69 : : void
70 : 110950 : decimal_real_from_string (REAL_VALUE_TYPE *r, const char *s)
71 : : {
72 : 110950 : decNumber dn;
73 : 110950 : decContext set;
74 : 110950 : decContextDefault (&set, DEC_INIT_DECIMAL128);
75 : 110950 : set.traps = 0;
76 : :
77 : 110950 : decNumberFromString (&dn, s, &set);
78 : :
79 : : /* It would be more efficient to store directly in decNumber format,
80 : : but that is impractical from current data structure size.
81 : : Encoding as a decimal128 is much more compact. */
82 : 110950 : decimal_from_decnumber (r, &dn, &set);
83 : 110950 : }
84 : :
85 : : /* Initialize a decNumber from a REAL_VALUE_TYPE. */
86 : :
87 : : static void
88 : 1172641 : decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
89 : : {
90 : 1172641 : decContext set;
91 : 1172641 : decContextDefault (&set, DEC_INIT_DECIMAL128);
92 : 1172641 : set.traps = 0;
93 : :
94 : 1172641 : switch (r->cl)
95 : : {
96 : 4 : case rvc_zero:
97 : 4 : decNumberZero (dn);
98 : 4 : break;
99 : 583 : case rvc_inf:
100 : 583 : decNumberFromString (dn, "Infinity", &set);
101 : 583 : break;
102 : 219 : case rvc_nan:
103 : 219 : if (r->signalling)
104 : 37 : decNumberFromString (dn, "snan", &set);
105 : : else
106 : 182 : decNumberFromString (dn, "nan", &set);
107 : : break;
108 : 1171835 : case rvc_normal:
109 : 1171835 : if (!r->decimal)
110 : : {
111 : : /* dconst{1,2,m1,half} are used in various places in
112 : : the middle-end and optimizers, allow them here
113 : : as an exception by converting them to decimal. */
114 : 0 : if (memcmp (r, &dconst1, sizeof (*r)) == 0)
115 : : {
116 : 0 : decNumberFromString (dn, "1", &set);
117 : 0 : break;
118 : : }
119 : 0 : if (memcmp (r, &dconst2, sizeof (*r)) == 0)
120 : : {
121 : 0 : decNumberFromString (dn, "2", &set);
122 : 0 : break;
123 : : }
124 : 0 : if (memcmp (r, &dconstm1, sizeof (*r)) == 0)
125 : : {
126 : 0 : decNumberFromString (dn, "-1", &set);
127 : 0 : break;
128 : : }
129 : 0 : if (memcmp (r, &dconsthalf, sizeof (*r)) == 0)
130 : : {
131 : 0 : decNumberFromString (dn, "0.5", &set);
132 : 0 : break;
133 : : }
134 : 0 : gcc_unreachable ();
135 : : }
136 : 1171835 : decimal128ToNumber ((const decimal128 *) r->sig, dn);
137 : 1171835 : break;
138 : 0 : default:
139 : 0 : gcc_unreachable ();
140 : : }
141 : :
142 : : /* Fix up sign bit. */
143 : 1172641 : if (r->sign != decNumberIsNegative (dn))
144 : 182 : dn->bits ^= DECNEG;
145 : 1172641 : }
146 : :
147 : : /* Encode a real into an IEEE 754 decimal32 type. */
148 : :
149 : : void
150 : 11600 : encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
151 : : long *buf, const REAL_VALUE_TYPE *r)
152 : : {
153 : 11600 : decNumber dn;
154 : 11600 : decimal32 d32;
155 : 11600 : decContext set;
156 : 11600 : int32_t image;
157 : :
158 : 11600 : decContextDefault (&set, DEC_INIT_DECIMAL128);
159 : 11600 : set.traps = 0;
160 : :
161 : 11600 : decimal_to_decnumber (r, &dn);
162 : 11600 : decimal32FromNumber (&d32, &dn, &set);
163 : :
164 : 11600 : memcpy (&image, d32.bytes, sizeof (int32_t));
165 : 11600 : buf[0] = image;
166 : 11600 : }
167 : :
168 : : /* Decode an IEEE 754 decimal32 type into a real. */
169 : :
170 : : void
171 : 876 : decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
172 : : REAL_VALUE_TYPE *r, const long *buf)
173 : : {
174 : 876 : decNumber dn;
175 : 876 : decimal32 d32;
176 : 876 : decContext set;
177 : 876 : int32_t image;
178 : :
179 : 876 : decContextDefault (&set, DEC_INIT_DECIMAL128);
180 : 876 : set.traps = 0;
181 : :
182 : 876 : image = buf[0];
183 : 876 : memcpy (&d32.bytes, &image, sizeof (int32_t));
184 : :
185 : 876 : decimal32ToNumber (&d32, &dn);
186 : 876 : decimal_from_decnumber (r, &dn, &set);
187 : 876 : }
188 : :
189 : : /* Encode a real into an IEEE 754 decimal64 type. */
190 : :
191 : : void
192 : 13313 : encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
193 : : long *buf, const REAL_VALUE_TYPE *r)
194 : : {
195 : 13313 : decNumber dn;
196 : 13313 : decimal64 d64;
197 : 13313 : decContext set;
198 : 13313 : int32_t image;
199 : :
200 : 13313 : decContextDefault (&set, DEC_INIT_DECIMAL128);
201 : 13313 : set.traps = 0;
202 : :
203 : 13313 : decimal_to_decnumber (r, &dn);
204 : 13313 : decimal64FromNumber (&d64, &dn, &set);
205 : :
206 : 13313 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
207 : : {
208 : 13313 : memcpy (&image, &d64.bytes[0], sizeof (int32_t));
209 : 13313 : buf[0] = image;
210 : 13313 : memcpy (&image, &d64.bytes[4], sizeof (int32_t));
211 : 13313 : buf[1] = image;
212 : : }
213 : : else
214 : : {
215 : : memcpy (&image, &d64.bytes[4], sizeof (int32_t));
216 : : buf[0] = image;
217 : : memcpy (&image, &d64.bytes[0], sizeof (int32_t));
218 : : buf[1] = image;
219 : : }
220 : 13313 : }
221 : :
222 : : /* Decode an IEEE 754 decimal64 type into a real. */
223 : :
224 : : void
225 : 3052 : decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
226 : : REAL_VALUE_TYPE *r, const long *buf)
227 : : {
228 : 3052 : decNumber dn;
229 : 3052 : decimal64 d64;
230 : 3052 : decContext set;
231 : 3052 : int32_t image;
232 : :
233 : 3052 : decContextDefault (&set, DEC_INIT_DECIMAL128);
234 : 3052 : set.traps = 0;
235 : :
236 : 3052 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
237 : : {
238 : 3052 : image = buf[0];
239 : 3052 : memcpy (&d64.bytes[0], &image, sizeof (int32_t));
240 : 3052 : image = buf[1];
241 : 3052 : memcpy (&d64.bytes[4], &image, sizeof (int32_t));
242 : : }
243 : : else
244 : : {
245 : : image = buf[1];
246 : : memcpy (&d64.bytes[0], &image, sizeof (int32_t));
247 : : image = buf[0];
248 : : memcpy (&d64.bytes[4], &image, sizeof (int32_t));
249 : : }
250 : :
251 : 3052 : decimal64ToNumber (&d64, &dn);
252 : 3052 : decimal_from_decnumber (r, &dn, &set);
253 : 3052 : }
254 : :
255 : : /* Encode a real into an IEEE 754 decimal128 type. */
256 : :
257 : : void
258 : 15842 : encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
259 : : long *buf, const REAL_VALUE_TYPE *r)
260 : : {
261 : 15842 : decNumber dn;
262 : 15842 : decContext set;
263 : 15842 : decimal128 d128;
264 : 15842 : int32_t image;
265 : :
266 : 15842 : decContextDefault (&set, DEC_INIT_DECIMAL128);
267 : 15842 : set.traps = 0;
268 : :
269 : 15842 : decimal_to_decnumber (r, &dn);
270 : 15842 : decimal128FromNumber (&d128, &dn, &set);
271 : :
272 : 15842 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
273 : : {
274 : 15842 : memcpy (&image, &d128.bytes[0], sizeof (int32_t));
275 : 15842 : buf[0] = image;
276 : 15842 : memcpy (&image, &d128.bytes[4], sizeof (int32_t));
277 : 15842 : buf[1] = image;
278 : 15842 : memcpy (&image, &d128.bytes[8], sizeof (int32_t));
279 : 15842 : buf[2] = image;
280 : 15842 : memcpy (&image, &d128.bytes[12], sizeof (int32_t));
281 : 15842 : buf[3] = image;
282 : : }
283 : : else
284 : : {
285 : : memcpy (&image, &d128.bytes[12], sizeof (int32_t));
286 : : buf[0] = image;
287 : : memcpy (&image, &d128.bytes[8], sizeof (int32_t));
288 : : buf[1] = image;
289 : : memcpy (&image, &d128.bytes[4], sizeof (int32_t));
290 : : buf[2] = image;
291 : : memcpy (&image, &d128.bytes[0], sizeof (int32_t));
292 : : buf[3] = image;
293 : : }
294 : 15842 : }
295 : :
296 : : /* Decode an IEEE 754 decimal128 type into a real. */
297 : :
298 : : void
299 : 5624 : decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
300 : : REAL_VALUE_TYPE *r, const long *buf)
301 : : {
302 : 5624 : decNumber dn;
303 : 5624 : decimal128 d128;
304 : 5624 : decContext set;
305 : 5624 : int32_t image;
306 : :
307 : 5624 : decContextDefault (&set, DEC_INIT_DECIMAL128);
308 : 5624 : set.traps = 0;
309 : :
310 : 5624 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
311 : : {
312 : 5624 : image = buf[0];
313 : 5624 : memcpy (&d128.bytes[0], &image, sizeof (int32_t));
314 : 5624 : image = buf[1];
315 : 5624 : memcpy (&d128.bytes[4], &image, sizeof (int32_t));
316 : 5624 : image = buf[2];
317 : 5624 : memcpy (&d128.bytes[8], &image, sizeof (int32_t));
318 : 5624 : image = buf[3];
319 : 5624 : memcpy (&d128.bytes[12], &image, sizeof (int32_t));
320 : : }
321 : : else
322 : : {
323 : : image = buf[3];
324 : : memcpy (&d128.bytes[0], &image, sizeof (int32_t));
325 : : image = buf[2];
326 : : memcpy (&d128.bytes[4], &image, sizeof (int32_t));
327 : : image = buf[1];
328 : : memcpy (&d128.bytes[8], &image, sizeof (int32_t));
329 : : image = buf[0];
330 : : memcpy (&d128.bytes[12], &image, sizeof (int32_t));
331 : : }
332 : :
333 : 5624 : decimal128ToNumber (&d128, &dn);
334 : 5624 : decimal_from_decnumber (r, &dn, &set);
335 : 5624 : }
336 : :
337 : : /* Helper function to convert from a binary real internal
338 : : representation. */
339 : :
340 : : static void
341 : 97 : decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from,
342 : : const real_format *fmt)
343 : : {
344 : 97 : char string[256];
345 : 97 : if (from->cl == rvc_normal)
346 : : {
347 : 73 : const decimal128 *const d128 = (const decimal128 *) from->sig;
348 : 73 : decimal128ToString (d128, string);
349 : : }
350 : : else
351 : 24 : real_to_decimal (string, from, sizeof (string), 0, 1);
352 : 97 : real_from_string3 (to, string, fmt);
353 : 97 : }
354 : :
355 : :
356 : : /* Helper function to convert from a binary real internal
357 : : representation. */
358 : :
359 : : static void
360 : 83510 : decimal_from_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from)
361 : : {
362 : 83510 : char string[256];
363 : :
364 : : /* We convert to string, then to decNumber then to decimal128. */
365 : 83510 : real_to_decimal (string, from, sizeof (string), 0, 1);
366 : 83510 : decimal_real_from_string (to, string);
367 : : /* When a canonical NaN is originally created, it is not marked as
368 : : decimal. Ensure the result of converting to another decimal type
369 : : (which passes through this function) is also marked as
370 : : canonical. */
371 : 83510 : if (from->cl == rvc_nan && from->canonical)
372 : 284 : to->canonical = 1;
373 : 83510 : }
374 : :
375 : : /* Helper function to real.cc:do_compare() to handle decimal internal
376 : : representation including when one of the operands is still in the
377 : : binary internal representation. */
378 : :
379 : : int
380 : 361573 : decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
381 : : int nan_result)
382 : : {
383 : 361573 : decContext set;
384 : 361573 : decNumber dn, dn2, dn3;
385 : 361573 : REAL_VALUE_TYPE a1, b1;
386 : :
387 : : /* If either operand is non-decimal, create temporary versions. */
388 : 361573 : if (!a->decimal)
389 : : {
390 : 1677 : decimal_from_binary (&a1, a);
391 : 1677 : a = &a1;
392 : : }
393 : 361573 : if (!b->decimal)
394 : : {
395 : 79097 : decimal_from_binary (&b1, b);
396 : 79097 : b = &b1;
397 : : }
398 : :
399 : : /* Convert into decNumber form for comparison operation. */
400 : 361573 : decContextDefault (&set, DEC_INIT_DECIMAL128);
401 : 361573 : set.traps = 0;
402 : 361573 : decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
403 : 361573 : decimal128ToNumber ((const decimal128 *) b->sig, &dn3);
404 : :
405 : : /* Finally, do the comparison. */
406 : 361573 : decNumberCompare (&dn, &dn2, &dn3, &set);
407 : :
408 : : /* Return the comparison result. */
409 : 361573 : if (decNumberIsNaN (&dn))
410 : : return nan_result;
411 : 361573 : else if (decNumberIsZero (&dn))
412 : : return 0;
413 : 352185 : else if (decNumberIsNegative (&dn))
414 : : return -1;
415 : : else
416 : 243340 : return 1;
417 : : }
418 : :
419 : : /* Helper to round_for_format, handling decimal float types. */
420 : :
421 : : void
422 : 636222 : decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
423 : : {
424 : 636222 : decNumber dn;
425 : 636222 : decContext set;
426 : :
427 : : /* Real encoding occurs later. */
428 : 636222 : if (r->cl != rvc_normal)
429 : 402422 : return;
430 : :
431 : 635471 : decContextDefault (&set, DEC_INIT_DECIMAL128);
432 : 635471 : set.traps = 0;
433 : 635471 : decimal128ToNumber ((decimal128 *) r->sig, &dn);
434 : :
435 : 635471 : if (fmt == &decimal_quad_format)
436 : : {
437 : : /* The internal format is already in this format. */
438 : : return;
439 : : }
440 : 233800 : else if (fmt == &decimal_single_format)
441 : : {
442 : 62163 : decimal32 d32;
443 : 62163 : decContextDefault (&set, DEC_INIT_DECIMAL32);
444 : 62163 : set.traps = 0;
445 : :
446 : 62163 : decimal32FromNumber (&d32, &dn, &set);
447 : 62163 : decimal32ToNumber (&d32, &dn);
448 : : }
449 : 171637 : else if (fmt == &decimal_double_format)
450 : : {
451 : 171637 : decimal64 d64;
452 : 171637 : decContextDefault (&set, DEC_INIT_DECIMAL64);
453 : 171637 : set.traps = 0;
454 : :
455 : 171637 : decimal64FromNumber (&d64, &dn, &set);
456 : 171637 : decimal64ToNumber (&d64, &dn);
457 : : }
458 : : else
459 : 0 : gcc_unreachable ();
460 : :
461 : 233800 : decimal_from_decnumber (r, &dn, &set);
462 : : }
463 : :
464 : : /* Extend or truncate to a new mode. Handles conversions between
465 : : binary and decimal types. */
466 : :
467 : : void
468 : 596092 : decimal_real_convert (REAL_VALUE_TYPE *r, const real_format *fmt,
469 : : const REAL_VALUE_TYPE *a)
470 : : {
471 : 596092 : if (a->decimal && fmt->b == 10)
472 : : return;
473 : 2649 : if (a->decimal)
474 : 97 : decimal_to_binary (r, a, fmt);
475 : : else
476 : 2552 : decimal_from_binary (r, a);
477 : : }
478 : :
479 : : /* Render R_ORIG as a decimal floating point constant. Emit DIGITS
480 : : significant digits in the result, bounded by BUF_SIZE. If DIGITS
481 : : is 0, choose the maximum for the representation. If
482 : : CROP_TRAILING_ZEROS, strip trailing zeros. Currently, not honoring
483 : : DIGITS or CROP_TRAILING_ZEROS. */
484 : :
485 : : void
486 : 45 : decimal_real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig,
487 : : size_t buf_size,
488 : : size_t digits ATTRIBUTE_UNUSED,
489 : : int crop_trailing_zeros ATTRIBUTE_UNUSED)
490 : : {
491 : 45 : const decimal128 *const d128 = (const decimal128*) r_orig->sig;
492 : :
493 : : /* decimal128ToString requires space for at least 24 characters;
494 : : Require two more for suffix. */
495 : 45 : gcc_assert (buf_size >= 24);
496 : 45 : decimal128ToString (d128, str);
497 : 45 : }
498 : :
499 : : static bool
500 : 7184 : decimal_do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
501 : : const REAL_VALUE_TYPE *op1, int subtract_p)
502 : : {
503 : 7184 : decNumber dn;
504 : 7184 : decContext set;
505 : 7184 : decNumber dn2, dn3;
506 : :
507 : 7184 : decimal_to_decnumber (op0, &dn2);
508 : 7184 : decimal_to_decnumber (op1, &dn3);
509 : :
510 : 7184 : decContextDefault (&set, DEC_INIT_DECIMAL128);
511 : 7184 : set.traps = 0;
512 : :
513 : 7184 : if (subtract_p)
514 : 2821 : decNumberSubtract (&dn, &dn2, &dn3, &set);
515 : : else
516 : 4363 : decNumberAdd (&dn, &dn2, &dn3, &set);
517 : :
518 : 7184 : decimal_from_decnumber (r, &dn, &set);
519 : :
520 : : /* Return true, if inexact. */
521 : 7184 : return (set.status & DEC_Inexact);
522 : : }
523 : :
524 : : /* Compute R = OP0 * OP1. */
525 : :
526 : : static bool
527 : 557832 : decimal_do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
528 : : const REAL_VALUE_TYPE *op1)
529 : : {
530 : 557832 : decContext set;
531 : 557832 : decNumber dn, dn2, dn3;
532 : :
533 : 557832 : decimal_to_decnumber (op0, &dn2);
534 : 557832 : decimal_to_decnumber (op1, &dn3);
535 : :
536 : 557832 : decContextDefault (&set, DEC_INIT_DECIMAL128);
537 : 557832 : set.traps = 0;
538 : :
539 : 557832 : decNumberMultiply (&dn, &dn2, &dn3, &set);
540 : 557832 : decimal_from_decnumber (r, &dn, &set);
541 : :
542 : : /* Return true, if inexact. */
543 : 557832 : return (set.status & DEC_Inexact);
544 : : }
545 : :
546 : : /* Compute R = OP0 / OP1. */
547 : :
548 : : static bool
549 : 927 : decimal_do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
550 : : const REAL_VALUE_TYPE *op1)
551 : : {
552 : 927 : decContext set;
553 : 927 : decNumber dn, dn2, dn3;
554 : :
555 : 927 : decimal_to_decnumber (op0, &dn2);
556 : 927 : decimal_to_decnumber (op1, &dn3);
557 : :
558 : 927 : decContextDefault (&set, DEC_INIT_DECIMAL128);
559 : 927 : set.traps = 0;
560 : :
561 : 927 : decNumberDivide (&dn, &dn2, &dn3, &set);
562 : 927 : decimal_from_decnumber (r, &dn, &set);
563 : :
564 : : /* Return true, if inexact. */
565 : 927 : return (set.status & DEC_Inexact);
566 : : }
567 : :
568 : : /* Set R to A truncated to an integral value toward zero (decimal
569 : : floating point). */
570 : :
571 : : void
572 : 463 : decimal_do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
573 : : {
574 : 463 : decNumber dn, dn2;
575 : 463 : decContext set;
576 : :
577 : 463 : decContextDefault (&set, DEC_INIT_DECIMAL128);
578 : 463 : set.traps = 0;
579 : 463 : set.round = DEC_ROUND_DOWN;
580 : 463 : decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
581 : :
582 : 463 : decNumberToIntegralValue (&dn, &dn2, &set);
583 : 463 : decimal_from_decnumber (r, &dn, &set);
584 : 463 : }
585 : :
586 : : /* Render decimal float value R as an integer. */
587 : :
588 : : HOST_WIDE_INT
589 : 0 : decimal_real_to_integer (const REAL_VALUE_TYPE *r)
590 : : {
591 : 0 : decContext set;
592 : 0 : decNumber dn, dn2, dn3;
593 : 0 : REAL_VALUE_TYPE to;
594 : 0 : char string[256];
595 : :
596 : 0 : decContextDefault (&set, DEC_INIT_DECIMAL128);
597 : 0 : set.traps = 0;
598 : 0 : set.round = DEC_ROUND_DOWN;
599 : 0 : decimal128ToNumber ((const decimal128 *) r->sig, &dn);
600 : :
601 : 0 : decNumberToIntegralValue (&dn2, &dn, &set);
602 : 0 : decNumberZero (&dn3);
603 : 0 : decNumberRescale (&dn, &dn2, &dn3, &set);
604 : :
605 : : /* Convert to REAL_VALUE_TYPE and call appropriate conversion
606 : : function. */
607 : 0 : decNumberToString (&dn, string);
608 : 0 : real_from_string (&to, string);
609 : 0 : return real_to_integer (&to);
610 : : }
611 : :
612 : : /* Likewise, but returns a wide_int with PRECISION. *FAIL is set if the
613 : : value does not fit. */
614 : :
615 : : wide_int
616 : 393 : decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision)
617 : : {
618 : 393 : decContext set;
619 : 393 : decNumber dn, dn2, dn3;
620 : 393 : REAL_VALUE_TYPE to;
621 : 393 : char string[256];
622 : 393 : int scale = 0;
623 : :
624 : 393 : decContextDefault (&set, DEC_INIT_DECIMAL128);
625 : 393 : set.traps = 0;
626 : 393 : set.round = DEC_ROUND_DOWN;
627 : 393 : decimal128ToNumber ((const decimal128 *) r->sig, &dn);
628 : 393 : if (precision > 64 && decNumberIsFinite (&dn) && dn.exponent > 0)
629 : : {
630 : : /* libdecNumber doesn't really handle too large integers.
631 : : So when precision is large and exponent as well, trim the
632 : : exponent and adjust the resulting wide_int by multiplying
633 : : it multiple times with powers of ten. */
634 : 15 : scale = dn.exponent;
635 : 15 : dn.exponent = 0;
636 : : }
637 : :
638 : 393 : decNumberToIntegralValue (&dn2, &dn, &set);
639 : 393 : decNumberZero (&dn3);
640 : 393 : decNumberRescale (&dn, &dn2, &dn3, &set);
641 : :
642 : : /* Convert to REAL_VALUE_TYPE and call appropriate conversion
643 : : function. */
644 : 393 : decNumberToString (&dn, string);
645 : 393 : real_from_string (&to, string);
646 : 393 : bool failp = false;
647 : 393 : wide_int w = real_to_integer (&to, &failp, precision);
648 : 393 : if (failp)
649 : 0 : *fail = true;
650 : 393 : if (scale && !failp)
651 : : {
652 : 15 : bool isneg = wi::neg_p (w);
653 : 15 : if (isneg)
654 : 0 : w = -w;
655 : 15 : enum wi::overflow_type ovf = wi::OVF_NONE;
656 : 15 : unsigned HOST_WIDE_INT pow10s[] = {
657 : : HOST_WIDE_INT_UC (10),
658 : : HOST_WIDE_INT_UC (100),
659 : : HOST_WIDE_INT_UC (1000),
660 : : HOST_WIDE_INT_UC (10000),
661 : : HOST_WIDE_INT_UC (100000),
662 : : HOST_WIDE_INT_UC (1000000),
663 : : HOST_WIDE_INT_UC (10000000),
664 : : HOST_WIDE_INT_UC (100000000),
665 : : HOST_WIDE_INT_UC (1000000000),
666 : : HOST_WIDE_INT_UC (10000000000),
667 : : HOST_WIDE_INT_UC (100000000000),
668 : : HOST_WIDE_INT_UC (1000000000000),
669 : : HOST_WIDE_INT_UC (10000000000000),
670 : : HOST_WIDE_INT_UC (100000000000000),
671 : : HOST_WIDE_INT_UC (1000000000000000),
672 : : HOST_WIDE_INT_UC (10000000000000000),
673 : : HOST_WIDE_INT_UC (100000000000000000),
674 : : HOST_WIDE_INT_UC (1000000000000000000),
675 : : HOST_WIDE_INT_UC (10000000000000000000),
676 : : };
677 : 15 : int s = scale % 19;
678 : 15 : if (s)
679 : : {
680 : 14 : wide_int wm = wi::uhwi (pow10s[s - 1], w.get_precision ());
681 : 14 : w = wi::umul (w, wm, &ovf);
682 : 14 : if (ovf)
683 : 0 : scale = 0;
684 : 14 : }
685 : 15 : scale /= 19;
686 : 15 : wide_int wm = wi::uhwi (pow10s[18], w.get_precision ());
687 : 25 : while (scale)
688 : : {
689 : 15 : if (scale & 1)
690 : : {
691 : 9 : w = wi::umul (w, wm, &ovf);
692 : 9 : if (ovf)
693 : : break;
694 : : }
695 : 15 : scale >>= 1;
696 : 15 : if (!scale)
697 : : break;
698 : 10 : wm = wi::umul (wm, wm, &ovf);
699 : 10 : if (ovf)
700 : : break;
701 : : }
702 : 15 : if (ovf)
703 : : {
704 : 0 : *fail = true;
705 : 0 : if (isneg)
706 : 0 : return wi::set_bit_in_zero (precision - 1, precision);
707 : : else
708 : 0 : return ~wi::set_bit_in_zero (precision - 1, precision);
709 : : }
710 : 15 : if (isneg)
711 : 0 : w = -w;
712 : 15 : }
713 : 393 : return w;
714 : 393 : }
715 : :
716 : : /* Perform the decimal floating point operation described by CODE.
717 : : For a unary operation, OP1 will be NULL. This function returns
718 : : true if the result may be inexact due to loss of precision. */
719 : :
720 : : bool
721 : 575095 : decimal_real_arithmetic (REAL_VALUE_TYPE *r, enum tree_code code,
722 : : const REAL_VALUE_TYPE *op0,
723 : : const REAL_VALUE_TYPE *op1)
724 : : {
725 : 575095 : REAL_VALUE_TYPE a, b;
726 : :
727 : : /* If either operand is non-decimal, create temporaries. */
728 : 575095 : if (!op0->decimal)
729 : : {
730 : 56 : decimal_from_binary (&a, op0);
731 : 56 : op0 = &a;
732 : : }
733 : 575095 : if (op1 && !op1->decimal)
734 : : {
735 : 128 : decimal_from_binary (&b, op1);
736 : 128 : op1 = &b;
737 : : }
738 : :
739 : 575095 : switch (code)
740 : : {
741 : 4363 : case PLUS_EXPR:
742 : 4363 : return decimal_do_add (r, op0, op1, 0);
743 : :
744 : 2821 : case MINUS_EXPR:
745 : 2821 : return decimal_do_add (r, op0, op1, 1);
746 : :
747 : 557832 : case MULT_EXPR:
748 : 557832 : return decimal_do_multiply (r, op0, op1);
749 : :
750 : 927 : case RDIV_EXPR:
751 : 927 : return decimal_do_divide (r, op0, op1);
752 : :
753 : 0 : case MIN_EXPR:
754 : 0 : if (op1->cl == rvc_nan)
755 : 0 : *r = *op1;
756 : 0 : else if (real_compare (UNLT_EXPR, op0, op1))
757 : 0 : *r = *op0;
758 : : else
759 : 0 : *r = *op1;
760 : : return false;
761 : :
762 : 0 : case MAX_EXPR:
763 : 0 : if (op1->cl == rvc_nan)
764 : 0 : *r = *op1;
765 : 0 : else if (real_compare (LT_EXPR, op0, op1))
766 : 0 : *r = *op1;
767 : : else
768 : 0 : *r = *op0;
769 : : return false;
770 : :
771 : 9152 : case NEGATE_EXPR:
772 : 9152 : {
773 : 9152 : *r = *op0;
774 : : /* Flip sign bit. */
775 : 9152 : decimal128FlipSign ((decimal128 *) r->sig);
776 : : /* Keep sign field in sync. */
777 : 9152 : r->sign ^= 1;
778 : : }
779 : 9152 : return false;
780 : :
781 : 0 : case ABS_EXPR:
782 : 0 : {
783 : 0 : *r = *op0;
784 : : /* Clear sign bit. */
785 : 0 : decimal128ClearSign ((decimal128 *) r->sig);
786 : : /* Keep sign field in sync. */
787 : 0 : r->sign = 0;
788 : : }
789 : 0 : return false;
790 : :
791 : 0 : case FIX_TRUNC_EXPR:
792 : 0 : decimal_do_fix_trunc (r, op0);
793 : 0 : return false;
794 : :
795 : 0 : default:
796 : 0 : gcc_unreachable ();
797 : : }
798 : : }
799 : :
800 : : /* Fills R with the largest finite value representable in mode MODE.
801 : : If SIGN is nonzero, R is set to the most negative finite value. */
802 : :
803 : : void
804 : 81 : decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, machine_mode mode)
805 : : {
806 : 81 : const char *max;
807 : :
808 : 81 : switch (mode)
809 : : {
810 : : case E_SDmode:
811 : : max = "9.999999E96";
812 : : break;
813 : 17 : case E_DDmode:
814 : 17 : max = "9.999999999999999E384";
815 : 17 : break;
816 : 15 : case E_TDmode:
817 : 15 : max = "9.999999999999999999999999999999999E6144";
818 : 15 : break;
819 : 0 : default:
820 : 0 : gcc_unreachable ();
821 : : }
822 : :
823 : 81 : decimal_real_from_string (r, max);
824 : 81 : if (sign)
825 : 33 : decimal128SetSign ((decimal128 *) r->sig, 1);
826 : :
827 : 81 : r->sign = sign;
828 : 81 : }
|