Small fix for -fdump-ada-spec
[official-gcc.git] / gcc / dfp.cc
blob3c7f787feba7521006d42c71fe56a0723e96d2cb
1 /* Decimal floating point support.
2 Copyright (C) 2005-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "tree.h"
25 #include "dfp.h"
27 /* The order of the following headers is important for making sure
28 decNumber structure is large enough to hold decimal128 digits. */
30 #include "decimal128.h"
31 #include "decimal64.h"
32 #include "decimal32.h"
34 #ifndef WORDS_BIGENDIAN
35 #define WORDS_BIGENDIAN 0
36 #endif
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. */
42 static void
43 decimal_from_decnumber (REAL_VALUE_TYPE *r, decNumber *dn, decContext *context)
45 memset (r, 0, sizeof (REAL_VALUE_TYPE));
47 r->cl = rvc_normal;
48 if (decNumberIsNaN (dn))
49 r->cl = rvc_nan;
50 if (decNumberIsInfinite (dn))
51 r->cl = rvc_inf;
52 if (context->status & DEC_Overflow)
53 r->cl = rvc_inf;
54 if (decNumberIsNegative (dn))
55 r->sign = 1;
56 r->decimal = 1;
58 if (r->cl != rvc_normal)
59 return;
61 decContextDefault (context, DEC_INIT_DECIMAL128);
62 context->traps = 0;
64 decimal128FromNumber ((decimal128 *) r->sig, dn, context);
67 /* Create decimal encoded R from string S. */
69 void
70 decimal_real_from_string (REAL_VALUE_TYPE *r, const char *s)
72 decNumber dn;
73 decContext set;
74 decContextDefault (&set, DEC_INIT_DECIMAL128);
75 set.traps = 0;
77 decNumberFromString (&dn, s, &set);
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 decimal_from_decnumber (r, &dn, &set);
85 /* Initialize a decNumber from a REAL_VALUE_TYPE. */
87 static void
88 decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
90 decContext set;
91 decContextDefault (&set, DEC_INIT_DECIMAL128);
92 set.traps = 0;
94 switch (r->cl)
96 case rvc_zero:
97 decNumberZero (dn);
98 break;
99 case rvc_inf:
100 decNumberFromString (dn, "Infinity", &set);
101 break;
102 case rvc_nan:
103 if (r->signalling)
104 decNumberFromString (dn, "snan", &set);
105 else
106 decNumberFromString (dn, "nan", &set);
107 break;
108 case rvc_normal:
109 if (!r->decimal)
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 if (memcmp (r, &dconst1, sizeof (*r)) == 0)
116 decNumberFromString (dn, "1", &set);
117 break;
119 if (memcmp (r, &dconst2, sizeof (*r)) == 0)
121 decNumberFromString (dn, "2", &set);
122 break;
124 if (memcmp (r, &dconstm1, sizeof (*r)) == 0)
126 decNumberFromString (dn, "-1", &set);
127 break;
129 if (memcmp (r, &dconsthalf, sizeof (*r)) == 0)
131 decNumberFromString (dn, "0.5", &set);
132 break;
134 gcc_unreachable ();
136 decimal128ToNumber ((const decimal128 *) r->sig, dn);
137 break;
138 default:
139 gcc_unreachable ();
142 /* Fix up sign bit. */
143 if (r->sign != decNumberIsNegative (dn))
144 dn->bits ^= DECNEG;
147 /* Encode a real into an IEEE 754 decimal32 type. */
149 void
150 encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
151 long *buf, const REAL_VALUE_TYPE *r)
153 decNumber dn;
154 decimal32 d32;
155 decContext set;
156 int32_t image;
158 decContextDefault (&set, DEC_INIT_DECIMAL128);
159 set.traps = 0;
161 decimal_to_decnumber (r, &dn);
162 decimal32FromNumber (&d32, &dn, &set);
164 memcpy (&image, d32.bytes, sizeof (int32_t));
165 buf[0] = image;
168 /* Decode an IEEE 754 decimal32 type into a real. */
170 void
171 decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
172 REAL_VALUE_TYPE *r, const long *buf)
174 decNumber dn;
175 decimal32 d32;
176 decContext set;
177 int32_t image;
179 decContextDefault (&set, DEC_INIT_DECIMAL128);
180 set.traps = 0;
182 image = buf[0];
183 memcpy (&d32.bytes, &image, sizeof (int32_t));
185 decimal32ToNumber (&d32, &dn);
186 decimal_from_decnumber (r, &dn, &set);
189 /* Encode a real into an IEEE 754 decimal64 type. */
191 void
192 encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
193 long *buf, const REAL_VALUE_TYPE *r)
195 decNumber dn;
196 decimal64 d64;
197 decContext set;
198 int32_t image;
200 decContextDefault (&set, DEC_INIT_DECIMAL128);
201 set.traps = 0;
203 decimal_to_decnumber (r, &dn);
204 decimal64FromNumber (&d64, &dn, &set);
206 if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
208 memcpy (&image, &d64.bytes[0], sizeof (int32_t));
209 buf[0] = image;
210 memcpy (&image, &d64.bytes[4], sizeof (int32_t));
211 buf[1] = image;
213 else
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;
222 /* Decode an IEEE 754 decimal64 type into a real. */
224 void
225 decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
226 REAL_VALUE_TYPE *r, const long *buf)
228 decNumber dn;
229 decimal64 d64;
230 decContext set;
231 int32_t image;
233 decContextDefault (&set, DEC_INIT_DECIMAL128);
234 set.traps = 0;
236 if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
238 image = buf[0];
239 memcpy (&d64.bytes[0], &image, sizeof (int32_t));
240 image = buf[1];
241 memcpy (&d64.bytes[4], &image, sizeof (int32_t));
243 else
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));
251 decimal64ToNumber (&d64, &dn);
252 decimal_from_decnumber (r, &dn, &set);
255 /* Encode a real into an IEEE 754 decimal128 type. */
257 void
258 encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
259 long *buf, const REAL_VALUE_TYPE *r)
261 decNumber dn;
262 decContext set;
263 decimal128 d128;
264 int32_t image;
266 decContextDefault (&set, DEC_INIT_DECIMAL128);
267 set.traps = 0;
269 decimal_to_decnumber (r, &dn);
270 decimal128FromNumber (&d128, &dn, &set);
272 if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
274 memcpy (&image, &d128.bytes[0], sizeof (int32_t));
275 buf[0] = image;
276 memcpy (&image, &d128.bytes[4], sizeof (int32_t));
277 buf[1] = image;
278 memcpy (&image, &d128.bytes[8], sizeof (int32_t));
279 buf[2] = image;
280 memcpy (&image, &d128.bytes[12], sizeof (int32_t));
281 buf[3] = image;
283 else
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;
296 /* Decode an IEEE 754 decimal128 type into a real. */
298 void
299 decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
300 REAL_VALUE_TYPE *r, const long *buf)
302 decNumber dn;
303 decimal128 d128;
304 decContext set;
305 int32_t image;
307 decContextDefault (&set, DEC_INIT_DECIMAL128);
308 set.traps = 0;
310 if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
312 image = buf[0];
313 memcpy (&d128.bytes[0], &image, sizeof (int32_t));
314 image = buf[1];
315 memcpy (&d128.bytes[4], &image, sizeof (int32_t));
316 image = buf[2];
317 memcpy (&d128.bytes[8], &image, sizeof (int32_t));
318 image = buf[3];
319 memcpy (&d128.bytes[12], &image, sizeof (int32_t));
321 else
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));
333 decimal128ToNumber (&d128, &dn);
334 decimal_from_decnumber (r, &dn, &set);
337 /* Helper function to convert from a binary real internal
338 representation. */
340 static void
341 decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from,
342 const real_format *fmt)
344 char string[256];
345 if (from->cl == rvc_normal)
347 const decimal128 *const d128 = (const decimal128 *) from->sig;
348 decimal128ToString (d128, string);
350 else
351 real_to_decimal (string, from, sizeof (string), 0, 1);
352 real_from_string3 (to, string, fmt);
356 /* Helper function to convert from a binary real internal
357 representation. */
359 static void
360 decimal_from_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from)
362 char string[256];
364 /* We convert to string, then to decNumber then to decimal128. */
365 real_to_decimal (string, from, sizeof (string), 0, 1);
366 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 if (from->cl == rvc_nan && from->canonical)
372 to->canonical = 1;
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. */
380 decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
381 int nan_result)
383 decContext set;
384 decNumber dn, dn2, dn3;
385 REAL_VALUE_TYPE a1, b1;
387 /* If either operand is non-decimal, create temporary versions. */
388 if (!a->decimal)
390 decimal_from_binary (&a1, a);
391 a = &a1;
393 if (!b->decimal)
395 decimal_from_binary (&b1, b);
396 b = &b1;
399 /* Convert into decNumber form for comparison operation. */
400 decContextDefault (&set, DEC_INIT_DECIMAL128);
401 set.traps = 0;
402 decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
403 decimal128ToNumber ((const decimal128 *) b->sig, &dn3);
405 /* Finally, do the comparison. */
406 decNumberCompare (&dn, &dn2, &dn3, &set);
408 /* Return the comparison result. */
409 if (decNumberIsNaN (&dn))
410 return nan_result;
411 else if (decNumberIsZero (&dn))
412 return 0;
413 else if (decNumberIsNegative (&dn))
414 return -1;
415 else
416 return 1;
419 /* Helper to round_for_format, handling decimal float types. */
421 void
422 decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
424 decNumber dn;
425 decContext set;
427 /* Real encoding occurs later. */
428 if (r->cl != rvc_normal)
429 return;
431 decContextDefault (&set, DEC_INIT_DECIMAL128);
432 set.traps = 0;
433 decimal128ToNumber ((decimal128 *) r->sig, &dn);
435 if (fmt == &decimal_quad_format)
437 /* The internal format is already in this format. */
438 return;
440 else if (fmt == &decimal_single_format)
442 decimal32 d32;
443 decContextDefault (&set, DEC_INIT_DECIMAL32);
444 set.traps = 0;
446 decimal32FromNumber (&d32, &dn, &set);
447 decimal32ToNumber (&d32, &dn);
449 else if (fmt == &decimal_double_format)
451 decimal64 d64;
452 decContextDefault (&set, DEC_INIT_DECIMAL64);
453 set.traps = 0;
455 decimal64FromNumber (&d64, &dn, &set);
456 decimal64ToNumber (&d64, &dn);
458 else
459 gcc_unreachable ();
461 decimal_from_decnumber (r, &dn, &set);
464 /* Extend or truncate to a new mode. Handles conversions between
465 binary and decimal types. */
467 void
468 decimal_real_convert (REAL_VALUE_TYPE *r, const real_format *fmt,
469 const REAL_VALUE_TYPE *a)
471 if (a->decimal && fmt->b == 10)
472 return;
473 if (a->decimal)
474 decimal_to_binary (r, a, fmt);
475 else
476 decimal_from_binary (r, a);
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. */
485 void
486 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)
491 const decimal128 *const d128 = (const decimal128*) r_orig->sig;
493 /* decimal128ToString requires space for at least 24 characters;
494 Require two more for suffix. */
495 gcc_assert (buf_size >= 24);
496 decimal128ToString (d128, str);
499 static bool
500 decimal_do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
501 const REAL_VALUE_TYPE *op1, int subtract_p)
503 decNumber dn;
504 decContext set;
505 decNumber dn2, dn3;
507 decimal_to_decnumber (op0, &dn2);
508 decimal_to_decnumber (op1, &dn3);
510 decContextDefault (&set, DEC_INIT_DECIMAL128);
511 set.traps = 0;
513 if (subtract_p)
514 decNumberSubtract (&dn, &dn2, &dn3, &set);
515 else
516 decNumberAdd (&dn, &dn2, &dn3, &set);
518 decimal_from_decnumber (r, &dn, &set);
520 /* Return true, if inexact. */
521 return (set.status & DEC_Inexact);
524 /* Compute R = OP0 * OP1. */
526 static bool
527 decimal_do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
528 const REAL_VALUE_TYPE *op1)
530 decContext set;
531 decNumber dn, dn2, dn3;
533 decimal_to_decnumber (op0, &dn2);
534 decimal_to_decnumber (op1, &dn3);
536 decContextDefault (&set, DEC_INIT_DECIMAL128);
537 set.traps = 0;
539 decNumberMultiply (&dn, &dn2, &dn3, &set);
540 decimal_from_decnumber (r, &dn, &set);
542 /* Return true, if inexact. */
543 return (set.status & DEC_Inexact);
546 /* Compute R = OP0 / OP1. */
548 static bool
549 decimal_do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
550 const REAL_VALUE_TYPE *op1)
552 decContext set;
553 decNumber dn, dn2, dn3;
555 decimal_to_decnumber (op0, &dn2);
556 decimal_to_decnumber (op1, &dn3);
558 decContextDefault (&set, DEC_INIT_DECIMAL128);
559 set.traps = 0;
561 decNumberDivide (&dn, &dn2, &dn3, &set);
562 decimal_from_decnumber (r, &dn, &set);
564 /* Return true, if inexact. */
565 return (set.status & DEC_Inexact);
568 /* Set R to A truncated to an integral value toward zero (decimal
569 floating point). */
571 void
572 decimal_do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
574 decNumber dn, dn2;
575 decContext set;
577 decContextDefault (&set, DEC_INIT_DECIMAL128);
578 set.traps = 0;
579 set.round = DEC_ROUND_DOWN;
580 decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
582 decNumberToIntegralValue (&dn, &dn2, &set);
583 decimal_from_decnumber (r, &dn, &set);
586 /* Render decimal float value R as an integer. */
588 HOST_WIDE_INT
589 decimal_real_to_integer (const REAL_VALUE_TYPE *r)
591 decContext set;
592 decNumber dn, dn2, dn3;
593 REAL_VALUE_TYPE to;
594 char string[256];
596 decContextDefault (&set, DEC_INIT_DECIMAL128);
597 set.traps = 0;
598 set.round = DEC_ROUND_DOWN;
599 decimal128ToNumber ((const decimal128 *) r->sig, &dn);
601 decNumberToIntegralValue (&dn2, &dn, &set);
602 decNumberZero (&dn3);
603 decNumberRescale (&dn, &dn2, &dn3, &set);
605 /* Convert to REAL_VALUE_TYPE and call appropriate conversion
606 function. */
607 decNumberToString (&dn, string);
608 real_from_string (&to, string);
609 return real_to_integer (&to);
612 /* Likewise, but returns a wide_int with PRECISION. *FAIL is set if the
613 value does not fit. */
615 wide_int
616 decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision)
618 decContext set;
619 decNumber dn, dn2, dn3;
620 REAL_VALUE_TYPE to;
621 char string[256];
623 decContextDefault (&set, DEC_INIT_DECIMAL128);
624 set.traps = 0;
625 set.round = DEC_ROUND_DOWN;
626 decimal128ToNumber ((const decimal128 *) r->sig, &dn);
628 decNumberToIntegralValue (&dn2, &dn, &set);
629 decNumberZero (&dn3);
630 decNumberRescale (&dn, &dn2, &dn3, &set);
632 /* Convert to REAL_VALUE_TYPE and call appropriate conversion
633 function. */
634 decNumberToString (&dn, string);
635 real_from_string (&to, string);
636 return real_to_integer (&to, fail, precision);
639 /* Perform the decimal floating point operation described by CODE.
640 For a unary operation, OP1 will be NULL. This function returns
641 true if the result may be inexact due to loss of precision. */
643 bool
644 decimal_real_arithmetic (REAL_VALUE_TYPE *r, enum tree_code code,
645 const REAL_VALUE_TYPE *op0,
646 const REAL_VALUE_TYPE *op1)
648 REAL_VALUE_TYPE a, b;
650 /* If either operand is non-decimal, create temporaries. */
651 if (!op0->decimal)
653 decimal_from_binary (&a, op0);
654 op0 = &a;
656 if (op1 && !op1->decimal)
658 decimal_from_binary (&b, op1);
659 op1 = &b;
662 switch (code)
664 case PLUS_EXPR:
665 return decimal_do_add (r, op0, op1, 0);
667 case MINUS_EXPR:
668 return decimal_do_add (r, op0, op1, 1);
670 case MULT_EXPR:
671 return decimal_do_multiply (r, op0, op1);
673 case RDIV_EXPR:
674 return decimal_do_divide (r, op0, op1);
676 case MIN_EXPR:
677 if (op1->cl == rvc_nan)
678 *r = *op1;
679 else if (real_compare (UNLT_EXPR, op0, op1))
680 *r = *op0;
681 else
682 *r = *op1;
683 return false;
685 case MAX_EXPR:
686 if (op1->cl == rvc_nan)
687 *r = *op1;
688 else if (real_compare (LT_EXPR, op0, op1))
689 *r = *op1;
690 else
691 *r = *op0;
692 return false;
694 case NEGATE_EXPR:
696 *r = *op0;
697 /* Flip sign bit. */
698 decimal128FlipSign ((decimal128 *) r->sig);
699 /* Keep sign field in sync. */
700 r->sign ^= 1;
702 return false;
704 case ABS_EXPR:
706 *r = *op0;
707 /* Clear sign bit. */
708 decimal128ClearSign ((decimal128 *) r->sig);
709 /* Keep sign field in sync. */
710 r->sign = 0;
712 return false;
714 case FIX_TRUNC_EXPR:
715 decimal_do_fix_trunc (r, op0);
716 return false;
718 default:
719 gcc_unreachable ();
723 /* Fills R with the largest finite value representable in mode MODE.
724 If SIGN is nonzero, R is set to the most negative finite value. */
726 void
727 decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, machine_mode mode)
729 const char *max;
731 switch (mode)
733 case E_SDmode:
734 max = "9.999999E96";
735 break;
736 case E_DDmode:
737 max = "9.999999999999999E384";
738 break;
739 case E_TDmode:
740 max = "9.999999999999999999999999999999999E6144";
741 break;
742 default:
743 gcc_unreachable ();
746 decimal_real_from_string (r, max);
747 if (sign)
748 decimal128SetSign ((decimal128 *) r->sig, 1);
750 r->sign = sign;