Line data Source code
1 : /* Decimal floating point support.
2 : Copyright (C) 2005-2026 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 915531 : decimal_from_decnumber (REAL_VALUE_TYPE *r, decNumber *dn, decContext *context)
44 : {
45 915531 : memset (r, 0, sizeof (REAL_VALUE_TYPE));
46 :
47 915531 : r->cl = rvc_normal;
48 915531 : if (decNumberIsNaN (dn))
49 486 : r->cl = rvc_nan;
50 915531 : if (decNumberIsInfinite (dn))
51 1287 : r->cl = rvc_inf;
52 915531 : if (context->status & DEC_Overflow)
53 929 : r->cl = rvc_inf;
54 915531 : if (decNumberIsNegative (dn))
55 291761 : r->sign = 1;
56 915531 : r->decimal = 1;
57 :
58 915531 : if (r->cl != rvc_normal)
59 : return;
60 :
61 913758 : decContextDefault (context, DEC_INIT_DECIMAL128);
62 913758 : context->traps = 0;
63 :
64 913758 : decimal128FromNumber ((decimal128 *) r->sig, dn, context);
65 : }
66 :
67 : /* Create decimal encoded R from string S. */
68 :
69 : void
70 108231 : decimal_real_from_string (REAL_VALUE_TYPE *r, const char *s)
71 : {
72 108231 : decNumber dn;
73 108231 : decContext set;
74 108231 : decContextDefault (&set, DEC_INIT_DECIMAL128);
75 108231 : set.traps = 0;
76 :
77 108231 : 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 108231 : decimal_from_decnumber (r, &dn, &set);
83 108231 : }
84 :
85 : /* Initialize a decNumber from a REAL_VALUE_TYPE. */
86 :
87 : static void
88 1170705 : decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
89 : {
90 1170705 : decContext set;
91 1170705 : decContextDefault (&set, DEC_INIT_DECIMAL128);
92 1170705 : set.traps = 0;
93 :
94 1170705 : 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 1169899 : case rvc_normal:
109 1169899 : 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 1169899 : decimal128ToNumber ((const decimal128 *) r->sig, dn);
137 1169899 : break;
138 0 : default:
139 0 : gcc_unreachable ();
140 : }
141 :
142 : /* Fix up sign bit. */
143 1170705 : if (r->sign != decNumberIsNegative (dn))
144 182 : dn->bits ^= DECNEG;
145 1170705 : }
146 :
147 : /* Encode a real into an IEEE 754 decimal32 type. */
148 :
149 : void
150 10535 : encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
151 : long *buf, const REAL_VALUE_TYPE *r)
152 : {
153 10535 : decNumber dn;
154 10535 : decimal32 d32;
155 10535 : decContext set;
156 10535 : int32_t image;
157 :
158 10535 : decContextDefault (&set, DEC_INIT_DECIMAL128);
159 10535 : set.traps = 0;
160 :
161 10535 : decimal_to_decnumber (r, &dn);
162 10535 : decimal32FromNumber (&d32, &dn, &set);
163 :
164 10535 : memcpy (&image, d32.bytes, sizeof (int32_t));
165 10535 : buf[0] = image;
166 10535 : }
167 :
168 : /* Decode an IEEE 754 decimal32 type into a real. */
169 :
170 : void
171 859 : decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
172 : REAL_VALUE_TYPE *r, const long *buf)
173 : {
174 859 : decNumber dn;
175 859 : decimal32 d32;
176 859 : decContext set;
177 859 : int32_t image;
178 :
179 859 : decContextDefault (&set, DEC_INIT_DECIMAL128);
180 859 : set.traps = 0;
181 :
182 859 : image = buf[0];
183 859 : memcpy (&d32.bytes, &image, sizeof (int32_t));
184 :
185 859 : decimal32ToNumber (&d32, &dn);
186 859 : decimal_from_decnumber (r, &dn, &set);
187 859 : }
188 :
189 : /* Encode a real into an IEEE 754 decimal64 type. */
190 :
191 : void
192 12207 : encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
193 : long *buf, const REAL_VALUE_TYPE *r)
194 : {
195 12207 : decNumber dn;
196 12207 : decimal64 d64;
197 12207 : decContext set;
198 12207 : int32_t image;
199 :
200 12207 : decContextDefault (&set, DEC_INIT_DECIMAL128);
201 12207 : set.traps = 0;
202 :
203 12207 : decimal_to_decnumber (r, &dn);
204 12207 : decimal64FromNumber (&d64, &dn, &set);
205 :
206 12207 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
207 : {
208 12207 : memcpy (&image, &d64.bytes[0], sizeof (int32_t));
209 12207 : buf[0] = image;
210 12207 : memcpy (&image, &d64.bytes[4], sizeof (int32_t));
211 12207 : 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 12207 : }
221 :
222 : /* Decode an IEEE 754 decimal64 type into a real. */
223 :
224 : void
225 3072 : decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
226 : REAL_VALUE_TYPE *r, const long *buf)
227 : {
228 3072 : decNumber dn;
229 3072 : decimal64 d64;
230 3072 : decContext set;
231 3072 : int32_t image;
232 :
233 3072 : decContextDefault (&set, DEC_INIT_DECIMAL128);
234 3072 : set.traps = 0;
235 :
236 3072 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
237 : {
238 3072 : image = buf[0];
239 3072 : memcpy (&d64.bytes[0], &image, sizeof (int32_t));
240 3072 : image = buf[1];
241 3072 : 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 3072 : decimal64ToNumber (&d64, &dn);
252 3072 : decimal_from_decnumber (r, &dn, &set);
253 3072 : }
254 :
255 : /* Encode a real into an IEEE 754 decimal128 type. */
256 :
257 : void
258 16053 : encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
259 : long *buf, const REAL_VALUE_TYPE *r)
260 : {
261 16053 : decNumber dn;
262 16053 : decContext set;
263 16053 : decimal128 d128;
264 16053 : int32_t image;
265 :
266 16053 : decContextDefault (&set, DEC_INIT_DECIMAL128);
267 16053 : set.traps = 0;
268 :
269 16053 : decimal_to_decnumber (r, &dn);
270 16053 : decimal128FromNumber (&d128, &dn, &set);
271 :
272 16053 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
273 : {
274 16053 : memcpy (&image, &d128.bytes[0], sizeof (int32_t));
275 16053 : buf[0] = image;
276 16053 : memcpy (&image, &d128.bytes[4], sizeof (int32_t));
277 16053 : buf[1] = image;
278 16053 : memcpy (&image, &d128.bytes[8], sizeof (int32_t));
279 16053 : buf[2] = image;
280 16053 : memcpy (&image, &d128.bytes[12], sizeof (int32_t));
281 16053 : 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 16053 : }
295 :
296 : /* Decode an IEEE 754 decimal128 type into a real. */
297 :
298 : void
299 5637 : decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
300 : REAL_VALUE_TYPE *r, const long *buf)
301 : {
302 5637 : decNumber dn;
303 5637 : decimal128 d128;
304 5637 : decContext set;
305 5637 : int32_t image;
306 :
307 5637 : decContextDefault (&set, DEC_INIT_DECIMAL128);
308 5637 : set.traps = 0;
309 :
310 5637 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
311 : {
312 5637 : image = buf[0];
313 5637 : memcpy (&d128.bytes[0], &image, sizeof (int32_t));
314 5637 : image = buf[1];
315 5637 : memcpy (&d128.bytes[4], &image, sizeof (int32_t));
316 5637 : image = buf[2];
317 5637 : memcpy (&d128.bytes[8], &image, sizeof (int32_t));
318 5637 : image = buf[3];
319 5637 : 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 5637 : decimal128ToNumber (&d128, &dn);
334 5637 : decimal_from_decnumber (r, &dn, &set);
335 5637 : }
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 81074 : decimal_from_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from)
361 : {
362 81074 : char string[256];
363 :
364 : /* We convert to string, then to decNumber then to decimal128. */
365 81074 : real_to_decimal (string, from, sizeof (string), 0, 1);
366 81074 : 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 81074 : if (from->cl == rvc_nan && from->canonical)
372 284 : to->canonical = 1;
373 81074 : }
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 359119 : decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
381 : int nan_result)
382 : {
383 359119 : decContext set;
384 359119 : decNumber dn, dn2, dn3;
385 359119 : REAL_VALUE_TYPE a1, b1;
386 :
387 : /* If either operand is non-decimal, create temporary versions. */
388 359119 : if (!a->decimal)
389 : {
390 1677 : decimal_from_binary (&a1, a);
391 1677 : a = &a1;
392 : }
393 359119 : if (!b->decimal)
394 : {
395 76643 : decimal_from_binary (&b1, b);
396 76643 : b = &b1;
397 : }
398 :
399 : /* Convert into decNumber form for comparison operation. */
400 359119 : decContextDefault (&set, DEC_INIT_DECIMAL128);
401 359119 : set.traps = 0;
402 359119 : decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
403 359119 : decimal128ToNumber ((const decimal128 *) b->sig, &dn3);
404 :
405 : /* Finally, do the comparison. */
406 359119 : decNumberCompare (&dn, &dn2, &dn3, &set);
407 :
408 : /* Return the comparison result. */
409 359119 : if (decNumberIsNaN (&dn))
410 : return nan_result;
411 359119 : else if (decNumberIsZero (&dn))
412 : return 0;
413 350785 : else if (decNumberIsNegative (&dn))
414 : return -1;
415 : else
416 242125 : return 1;
417 : }
418 :
419 : /* Helper to round_for_format, handling decimal float types. */
420 :
421 : void
422 634010 : decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
423 : {
424 634010 : decNumber dn;
425 634010 : decContext set;
426 :
427 : /* Real encoding occurs later. */
428 634010 : if (r->cl != rvc_normal)
429 402696 : return;
430 :
431 633259 : decContextDefault (&set, DEC_INIT_DECIMAL128);
432 633259 : set.traps = 0;
433 633259 : decimal128ToNumber ((decimal128 *) r->sig, &dn);
434 :
435 633259 : if (fmt == &decimal_quad_format)
436 : {
437 : /* The internal format is already in this format. */
438 : return;
439 : }
440 231314 : else if (fmt == &decimal_single_format)
441 : {
442 60990 : decimal32 d32;
443 60990 : decContextDefault (&set, DEC_INIT_DECIMAL32);
444 60990 : set.traps = 0;
445 :
446 60990 : decimal32FromNumber (&d32, &dn, &set);
447 60990 : decimal32ToNumber (&d32, &dn);
448 : }
449 170324 : else if (fmt == &decimal_double_format)
450 : {
451 170324 : decimal64 d64;
452 170324 : decContextDefault (&set, DEC_INIT_DECIMAL64);
453 170324 : set.traps = 0;
454 :
455 170324 : decimal64FromNumber (&d64, &dn, &set);
456 170324 : decimal64ToNumber (&d64, &dn);
457 : }
458 : else
459 0 : gcc_unreachable ();
460 :
461 231314 : 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 595840 : decimal_real_convert (REAL_VALUE_TYPE *r, const real_format *fmt,
469 : const REAL_VALUE_TYPE *a)
470 : {
471 595840 : if (a->decimal && fmt->b == 10)
472 : return;
473 2667 : if (a->decimal)
474 97 : decimal_to_binary (r, a, fmt);
475 : else
476 2570 : 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 7196 : decimal_do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
501 : const REAL_VALUE_TYPE *op1, int subtract_p)
502 : {
503 7196 : decNumber dn;
504 7196 : decContext set;
505 7196 : decNumber dn2, dn3;
506 :
507 7196 : decimal_to_decnumber (op0, &dn2);
508 7196 : decimal_to_decnumber (op1, &dn3);
509 :
510 7196 : decContextDefault (&set, DEC_INIT_DECIMAL128);
511 7196 : set.traps = 0;
512 :
513 7196 : if (subtract_p)
514 2821 : decNumberSubtract (&dn, &dn2, &dn3, &set);
515 : else
516 4375 : decNumberAdd (&dn, &dn2, &dn3, &set);
517 :
518 7196 : decimal_from_decnumber (r, &dn, &set);
519 :
520 : /* Return true, if inexact. */
521 7196 : 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 395 : decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision)
617 : {
618 395 : decContext set;
619 395 : decNumber dn, dn2, dn3;
620 395 : REAL_VALUE_TYPE to;
621 395 : char string[256];
622 395 : int scale = 0;
623 :
624 395 : decContextDefault (&set, DEC_INIT_DECIMAL128);
625 395 : set.traps = 0;
626 395 : set.round = DEC_ROUND_DOWN;
627 395 : decimal128ToNumber ((const decimal128 *) r->sig, &dn);
628 395 : 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 16 : scale = dn.exponent;
635 16 : dn.exponent = 0;
636 : }
637 :
638 395 : decNumberToIntegralValue (&dn2, &dn, &set);
639 395 : decNumberZero (&dn3);
640 395 : decNumberRescale (&dn, &dn2, &dn3, &set);
641 :
642 : /* Convert to REAL_VALUE_TYPE and call appropriate conversion
643 : function. */
644 395 : decNumberToString (&dn, string);
645 395 : real_from_string (&to, string);
646 395 : bool failp = false;
647 395 : wide_int w = real_to_integer (&to, &failp, precision);
648 395 : if (failp)
649 0 : *fail = true;
650 395 : if (scale && !failp)
651 : {
652 16 : bool isneg = wi::neg_p (w);
653 16 : if (isneg)
654 0 : w = -w;
655 16 : enum wi::overflow_type ovf = wi::OVF_NONE;
656 16 : 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 16 : int s = scale % 19;
678 16 : if (s)
679 : {
680 15 : wide_int wm = wi::uhwi (pow10s[s - 1], w.get_precision ());
681 15 : w = wi::umul (w, wm, &ovf);
682 15 : if (ovf)
683 0 : scale = 0;
684 15 : }
685 16 : scale /= 19;
686 16 : wide_int wm = wi::uhwi (pow10s[18], w.get_precision ());
687 26 : 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 16 : 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 16 : if (isneg)
711 0 : w = -w;
712 16 : }
713 395 : return w;
714 395 : }
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 575107 : 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 575107 : REAL_VALUE_TYPE a, b;
726 :
727 : /* If either operand is non-decimal, create temporaries. */
728 575107 : if (!op0->decimal)
729 : {
730 56 : decimal_from_binary (&a, op0);
731 56 : op0 = &a;
732 : }
733 575107 : if (op1 && !op1->decimal)
734 : {
735 128 : decimal_from_binary (&b, op1);
736 128 : op1 = &b;
737 : }
738 :
739 575107 : switch (code)
740 : {
741 4375 : case PLUS_EXPR:
742 4375 : 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 : }
|