Branch data Line data Source code
1 : : /* Decimal floating point support.
2 : : Copyright (C) 2005-2024 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 : 653659 : decimal_from_decnumber (REAL_VALUE_TYPE *r, decNumber *dn, decContext *context)
44 : : {
45 : 653659 : memset (r, 0, sizeof (REAL_VALUE_TYPE));
46 : :
47 : 653659 : r->cl = rvc_normal;
48 : 653659 : if (decNumberIsNaN (dn))
49 : 462 : r->cl = rvc_nan;
50 : 653659 : if (decNumberIsInfinite (dn))
51 : 1019 : r->cl = rvc_inf;
52 : 653659 : if (context->status & DEC_Overflow)
53 : 649 : r->cl = rvc_inf;
54 : 653659 : if (decNumberIsNegative (dn))
55 : 197963 : r->sign = 1;
56 : 653659 : r->decimal = 1;
57 : :
58 : 653659 : if (r->cl != rvc_normal)
59 : : return;
60 : :
61 : 652178 : decContextDefault (context, DEC_INIT_DECIMAL128);
62 : 652178 : context->traps = 0;
63 : :
64 : 652178 : decimal128FromNumber ((decimal128 *) r->sig, dn, context);
65 : : }
66 : :
67 : : /* Create decimal encoded R from string S. */
68 : :
69 : : void
70 : 110073 : decimal_real_from_string (REAL_VALUE_TYPE *r, const char *s)
71 : : {
72 : 110073 : decNumber dn;
73 : 110073 : decContext set;
74 : 110073 : decContextDefault (&set, DEC_INIT_DECIMAL128);
75 : 110073 : set.traps = 0;
76 : :
77 : 110073 : 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 : 110073 : decimal_from_decnumber (r, &dn, &set);
83 : 110073 : }
84 : :
85 : : /* Initialize a decNumber from a REAL_VALUE_TYPE. */
86 : :
87 : : static void
88 : 770458 : decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
89 : : {
90 : 770458 : decContext set;
91 : 770458 : decContextDefault (&set, DEC_INIT_DECIMAL128);
92 : 770458 : set.traps = 0;
93 : :
94 : 770458 : switch (r->cl)
95 : : {
96 : 4 : case rvc_zero:
97 : 4 : decNumberZero (dn);
98 : 4 : break;
99 : 581 : case rvc_inf:
100 : 581 : decNumberFromString (dn, "Infinity", &set);
101 : 581 : 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 : 769654 : case rvc_normal:
109 : 769654 : 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 : 769654 : decimal128ToNumber ((const decimal128 *) r->sig, dn);
137 : 769654 : break;
138 : 0 : default:
139 : 0 : gcc_unreachable ();
140 : : }
141 : :
142 : : /* Fix up sign bit. */
143 : 770458 : if (r->sign != decNumberIsNegative (dn))
144 : 182 : dn->bits ^= DECNEG;
145 : 770458 : }
146 : :
147 : : /* Encode a real into an IEEE 754 decimal32 type. */
148 : :
149 : : void
150 : 11587 : encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
151 : : long *buf, const REAL_VALUE_TYPE *r)
152 : : {
153 : 11587 : decNumber dn;
154 : 11587 : decimal32 d32;
155 : 11587 : decContext set;
156 : 11587 : int32_t image;
157 : :
158 : 11587 : decContextDefault (&set, DEC_INIT_DECIMAL128);
159 : 11587 : set.traps = 0;
160 : :
161 : 11587 : decimal_to_decnumber (r, &dn);
162 : 11587 : decimal32FromNumber (&d32, &dn, &set);
163 : :
164 : 11587 : memcpy (&image, d32.bytes, sizeof (int32_t));
165 : 11587 : buf[0] = image;
166 : 11587 : }
167 : :
168 : : /* Decode an IEEE 754 decimal32 type into a real. */
169 : :
170 : : void
171 : 844 : decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
172 : : REAL_VALUE_TYPE *r, const long *buf)
173 : : {
174 : 844 : decNumber dn;
175 : 844 : decimal32 d32;
176 : 844 : decContext set;
177 : 844 : int32_t image;
178 : :
179 : 844 : decContextDefault (&set, DEC_INIT_DECIMAL128);
180 : 844 : set.traps = 0;
181 : :
182 : 844 : image = buf[0];
183 : 844 : memcpy (&d32.bytes, &image, sizeof (int32_t));
184 : :
185 : 844 : decimal32ToNumber (&d32, &dn);
186 : 844 : decimal_from_decnumber (r, &dn, &set);
187 : 844 : }
188 : :
189 : : /* Encode a real into an IEEE 754 decimal64 type. */
190 : :
191 : : void
192 : 13383 : encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
193 : : long *buf, const REAL_VALUE_TYPE *r)
194 : : {
195 : 13383 : decNumber dn;
196 : 13383 : decimal64 d64;
197 : 13383 : decContext set;
198 : 13383 : int32_t image;
199 : :
200 : 13383 : decContextDefault (&set, DEC_INIT_DECIMAL128);
201 : 13383 : set.traps = 0;
202 : :
203 : 13383 : decimal_to_decnumber (r, &dn);
204 : 13383 : decimal64FromNumber (&d64, &dn, &set);
205 : :
206 : 13383 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
207 : : {
208 : 13383 : memcpy (&image, &d64.bytes[0], sizeof (int32_t));
209 : 13383 : buf[0] = image;
210 : 13383 : memcpy (&image, &d64.bytes[4], sizeof (int32_t));
211 : 13383 : 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 : 13383 : }
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 : 15890 : encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
259 : : long *buf, const REAL_VALUE_TYPE *r)
260 : : {
261 : 15890 : decNumber dn;
262 : 15890 : decContext set;
263 : 15890 : decimal128 d128;
264 : 15890 : int32_t image;
265 : :
266 : 15890 : decContextDefault (&set, DEC_INIT_DECIMAL128);
267 : 15890 : set.traps = 0;
268 : :
269 : 15890 : decimal_to_decnumber (r, &dn);
270 : 15890 : decimal128FromNumber (&d128, &dn, &set);
271 : :
272 : 15890 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
273 : : {
274 : 15890 : memcpy (&image, &d128.bytes[0], sizeof (int32_t));
275 : 15890 : buf[0] = image;
276 : 15890 : memcpy (&image, &d128.bytes[4], sizeof (int32_t));
277 : 15890 : buf[1] = image;
278 : 15890 : memcpy (&image, &d128.bytes[8], sizeof (int32_t));
279 : 15890 : buf[2] = image;
280 : 15890 : memcpy (&image, &d128.bytes[12], sizeof (int32_t));
281 : 15890 : 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 : 15890 : }
295 : :
296 : : /* Decode an IEEE 754 decimal128 type into a real. */
297 : :
298 : : void
299 : 5652 : decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
300 : : REAL_VALUE_TYPE *r, const long *buf)
301 : : {
302 : 5652 : decNumber dn;
303 : 5652 : decimal128 d128;
304 : 5652 : decContext set;
305 : 5652 : int32_t image;
306 : :
307 : 5652 : decContextDefault (&set, DEC_INIT_DECIMAL128);
308 : 5652 : set.traps = 0;
309 : :
310 : 5652 : if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
311 : : {
312 : 5652 : image = buf[0];
313 : 5652 : memcpy (&d128.bytes[0], &image, sizeof (int32_t));
314 : 5652 : image = buf[1];
315 : 5652 : memcpy (&d128.bytes[4], &image, sizeof (int32_t));
316 : 5652 : image = buf[2];
317 : 5652 : memcpy (&d128.bytes[8], &image, sizeof (int32_t));
318 : 5652 : image = buf[3];
319 : 5652 : 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 : 5652 : decimal128ToNumber (&d128, &dn);
334 : 5652 : decimal_from_decnumber (r, &dn, &set);
335 : 5652 : }
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 : 82632 : decimal_from_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from)
361 : : {
362 : 82632 : char string[256];
363 : :
364 : : /* We convert to string, then to decNumber then to decimal128. */
365 : 82632 : real_to_decimal (string, from, sizeof (string), 0, 1);
366 : 82632 : 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 : 82632 : if (from->cl == rvc_nan && from->canonical)
372 : 272 : to->canonical = 1;
373 : 82632 : }
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 : 260071 : decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
381 : : int nan_result)
382 : : {
383 : 260071 : decContext set;
384 : 260071 : decNumber dn, dn2, dn3;
385 : 260071 : REAL_VALUE_TYPE a1, b1;
386 : :
387 : : /* If either operand is non-decimal, create temporary versions. */
388 : 260071 : if (!a->decimal)
389 : : {
390 : 1669 : decimal_from_binary (&a1, a);
391 : 1669 : a = &a1;
392 : : }
393 : 260071 : if (!b->decimal)
394 : : {
395 : 78232 : decimal_from_binary (&b1, b);
396 : 78232 : b = &b1;
397 : : }
398 : :
399 : : /* Convert into decNumber form for comparison operation. */
400 : 260071 : decContextDefault (&set, DEC_INIT_DECIMAL128);
401 : 260071 : set.traps = 0;
402 : 260071 : decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
403 : 260071 : decimal128ToNumber ((const decimal128 *) b->sig, &dn3);
404 : :
405 : : /* Finally, do the comparison. */
406 : 260071 : decNumberCompare (&dn, &dn2, &dn3, &set);
407 : :
408 : : /* Return the comparison result. */
409 : 260071 : if (decNumberIsNaN (&dn))
410 : : return nan_result;
411 : 260071 : else if (decNumberIsZero (&dn))
412 : : return 0;
413 : 251273 : else if (decNumberIsNegative (&dn))
414 : : return -1;
415 : : else
416 : 178592 : return 1;
417 : : }
418 : :
419 : : /* Helper to round_for_format, handling decimal float types. */
420 : :
421 : : void
422 : 435292 : decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
423 : : {
424 : 435292 : decNumber dn;
425 : 435292 : decContext set;
426 : :
427 : : /* Real encoding occurs later. */
428 : 435292 : if (r->cl != rvc_normal)
429 : 266508 : return;
430 : :
431 : 434539 : decContextDefault (&set, DEC_INIT_DECIMAL128);
432 : 434539 : set.traps = 0;
433 : 434539 : decimal128ToNumber ((decimal128 *) r->sig, &dn);
434 : :
435 : 434539 : if (fmt == &decimal_quad_format)
436 : : {
437 : : /* The internal format is already in this format. */
438 : : return;
439 : : }
440 : 168784 : else if (fmt == &decimal_single_format)
441 : : {
442 : 48969 : decimal32 d32;
443 : 48969 : decContextDefault (&set, DEC_INIT_DECIMAL32);
444 : 48969 : set.traps = 0;
445 : :
446 : 48969 : decimal32FromNumber (&d32, &dn, &set);
447 : 48969 : decimal32ToNumber (&d32, &dn);
448 : : }
449 : 119815 : else if (fmt == &decimal_double_format)
450 : : {
451 : 119815 : decimal64 d64;
452 : 119815 : decContextDefault (&set, DEC_INIT_DECIMAL64);
453 : 119815 : set.traps = 0;
454 : :
455 : 119815 : decimal64FromNumber (&d64, &dn, &set);
456 : 119815 : decimal64ToNumber (&d64, &dn);
457 : : }
458 : : else
459 : 0 : gcc_unreachable ();
460 : :
461 : 168784 : 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 : 395057 : decimal_real_convert (REAL_VALUE_TYPE *r, const real_format *fmt,
469 : : const REAL_VALUE_TYPE *a)
470 : : {
471 : 395057 : if (a->decimal && fmt->b == 10)
472 : : return;
473 : 2648 : if (a->decimal)
474 : 97 : decimal_to_binary (r, a, fmt);
475 : : else
476 : 2551 : 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 : 7185 : decimal_do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
501 : : const REAL_VALUE_TYPE *op1, int subtract_p)
502 : : {
503 : 7185 : decNumber dn;
504 : 7185 : decContext set;
505 : 7185 : decNumber dn2, dn3;
506 : :
507 : 7185 : decimal_to_decnumber (op0, &dn2);
508 : 7185 : decimal_to_decnumber (op1, &dn3);
509 : :
510 : 7185 : decContextDefault (&set, DEC_INIT_DECIMAL128);
511 : 7185 : set.traps = 0;
512 : :
513 : 7185 : if (subtract_p)
514 : 2828 : decNumberSubtract (&dn, &dn2, &dn3, &set);
515 : : else
516 : 4357 : decNumberAdd (&dn, &dn2, &dn3, &set);
517 : :
518 : 7185 : decimal_from_decnumber (r, &dn, &set);
519 : :
520 : : /* Return true, if inexact. */
521 : 7185 : return (set.status & DEC_Inexact);
522 : : }
523 : :
524 : : /* Compute R = OP0 * OP1. */
525 : :
526 : : static bool
527 : 356276 : decimal_do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
528 : : const REAL_VALUE_TYPE *op1)
529 : : {
530 : 356276 : decContext set;
531 : 356276 : decNumber dn, dn2, dn3;
532 : :
533 : 356276 : decimal_to_decnumber (op0, &dn2);
534 : 356276 : decimal_to_decnumber (op1, &dn3);
535 : :
536 : 356276 : decContextDefault (&set, DEC_INIT_DECIMAL128);
537 : 356276 : set.traps = 0;
538 : :
539 : 356276 : decNumberMultiply (&dn, &dn2, &dn3, &set);
540 : 356276 : decimal_from_decnumber (r, &dn, &set);
541 : :
542 : : /* Return true, if inexact. */
543 : 356276 : return (set.status & DEC_Inexact);
544 : : }
545 : :
546 : : /* Compute R = OP0 / OP1. */
547 : :
548 : : static bool
549 : 1338 : decimal_do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
550 : : const REAL_VALUE_TYPE *op1)
551 : : {
552 : 1338 : decContext set;
553 : 1338 : decNumber dn, dn2, dn3;
554 : :
555 : 1338 : decimal_to_decnumber (op0, &dn2);
556 : 1338 : decimal_to_decnumber (op1, &dn3);
557 : :
558 : 1338 : decContextDefault (&set, DEC_INIT_DECIMAL128);
559 : 1338 : set.traps = 0;
560 : :
561 : 1338 : decNumberDivide (&dn, &dn2, &dn3, &set);
562 : 1338 : decimal_from_decnumber (r, &dn, &set);
563 : :
564 : : /* Return true, if inexact. */
565 : 1338 : 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 : 455 : decimal_do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
573 : : {
574 : 455 : decNumber dn, dn2;
575 : 455 : decContext set;
576 : :
577 : 455 : decContextDefault (&set, DEC_INIT_DECIMAL128);
578 : 455 : set.traps = 0;
579 : 455 : set.round = DEC_ROUND_DOWN;
580 : 455 : decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
581 : :
582 : 455 : decNumberToIntegralValue (&dn, &dn2, &set);
583 : 455 : decimal_from_decnumber (r, &dn, &set);
584 : 455 : }
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 : 368 : decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision)
617 : : {
618 : 368 : decContext set;
619 : 368 : decNumber dn, dn2, dn3;
620 : 368 : REAL_VALUE_TYPE to;
621 : 368 : char string[256];
622 : :
623 : 368 : decContextDefault (&set, DEC_INIT_DECIMAL128);
624 : 368 : set.traps = 0;
625 : 368 : set.round = DEC_ROUND_DOWN;
626 : 368 : decimal128ToNumber ((const decimal128 *) r->sig, &dn);
627 : :
628 : 368 : decNumberToIntegralValue (&dn2, &dn, &set);
629 : 368 : decNumberZero (&dn3);
630 : 368 : decNumberRescale (&dn, &dn2, &dn3, &set);
631 : :
632 : : /* Convert to REAL_VALUE_TYPE and call appropriate conversion
633 : : function. */
634 : 368 : decNumberToString (&dn, string);
635 : 368 : real_from_string (&to, string);
636 : 368 : return real_to_integer (&to, fail, precision);
637 : : }
638 : :
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. */
642 : :
643 : : bool
644 : 373855 : decimal_real_arithmetic (REAL_VALUE_TYPE *r, enum tree_code code,
645 : : const REAL_VALUE_TYPE *op0,
646 : : const REAL_VALUE_TYPE *op1)
647 : : {
648 : 373855 : REAL_VALUE_TYPE a, b;
649 : :
650 : : /* If either operand is non-decimal, create temporaries. */
651 : 373855 : if (!op0->decimal)
652 : : {
653 : 62 : decimal_from_binary (&a, op0);
654 : 62 : op0 = &a;
655 : : }
656 : 373855 : if (op1 && !op1->decimal)
657 : : {
658 : 118 : decimal_from_binary (&b, op1);
659 : 118 : op1 = &b;
660 : : }
661 : :
662 : 373855 : switch (code)
663 : : {
664 : 4357 : case PLUS_EXPR:
665 : 4357 : return decimal_do_add (r, op0, op1, 0);
666 : :
667 : 2828 : case MINUS_EXPR:
668 : 2828 : return decimal_do_add (r, op0, op1, 1);
669 : :
670 : 356276 : case MULT_EXPR:
671 : 356276 : return decimal_do_multiply (r, op0, op1);
672 : :
673 : 1338 : case RDIV_EXPR:
674 : 1338 : return decimal_do_divide (r, op0, op1);
675 : :
676 : 0 : case MIN_EXPR:
677 : 0 : if (op1->cl == rvc_nan)
678 : 0 : *r = *op1;
679 : 0 : else if (real_compare (UNLT_EXPR, op0, op1))
680 : 0 : *r = *op0;
681 : : else
682 : 0 : *r = *op1;
683 : : return false;
684 : :
685 : 0 : case MAX_EXPR:
686 : 0 : if (op1->cl == rvc_nan)
687 : 0 : *r = *op1;
688 : 0 : else if (real_compare (LT_EXPR, op0, op1))
689 : 0 : *r = *op1;
690 : : else
691 : 0 : *r = *op0;
692 : : return false;
693 : :
694 : 9056 : case NEGATE_EXPR:
695 : 9056 : {
696 : 9056 : *r = *op0;
697 : : /* Flip sign bit. */
698 : 9056 : decimal128FlipSign ((decimal128 *) r->sig);
699 : : /* Keep sign field in sync. */
700 : 9056 : r->sign ^= 1;
701 : : }
702 : 9056 : return false;
703 : :
704 : 0 : case ABS_EXPR:
705 : 0 : {
706 : 0 : *r = *op0;
707 : : /* Clear sign bit. */
708 : 0 : decimal128ClearSign ((decimal128 *) r->sig);
709 : : /* Keep sign field in sync. */
710 : 0 : r->sign = 0;
711 : : }
712 : 0 : return false;
713 : :
714 : 0 : case FIX_TRUNC_EXPR:
715 : 0 : decimal_do_fix_trunc (r, op0);
716 : 0 : return false;
717 : :
718 : 0 : default:
719 : 0 : gcc_unreachable ();
720 : : }
721 : : }
722 : :
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. */
725 : :
726 : : void
727 : 81 : decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, machine_mode mode)
728 : : {
729 : 81 : const char *max;
730 : :
731 : 81 : switch (mode)
732 : : {
733 : : case E_SDmode:
734 : : max = "9.999999E96";
735 : : break;
736 : 17 : case E_DDmode:
737 : 17 : max = "9.999999999999999E384";
738 : 17 : break;
739 : 15 : case E_TDmode:
740 : 15 : max = "9.999999999999999999999999999999999E6144";
741 : 15 : break;
742 : 0 : default:
743 : 0 : gcc_unreachable ();
744 : : }
745 : :
746 : 81 : decimal_real_from_string (r, max);
747 : 81 : if (sign)
748 : 33 : decimal128SetSign ((decimal128 *) r->sig, 1);
749 : :
750 : 81 : r->sign = sign;
751 : 81 : }
|