1 /* Decimal floating point support.
2    Copyright (C) 2005-2013 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 "tm_p.h"
26 #include "dfp.h"
27 
28 /* The order of the following headers is important for making sure
29    decNumber structure is large enough to hold decimal128 digits.  */
30 
31 #include "decimal128.h"
32 #include "decimal128Local.h"
33 #include "decimal64.h"
34 #include "decimal32.h"
35 #include "decNumber.h"
36 
37 #ifndef WORDS_BIGENDIAN
38 #define WORDS_BIGENDIAN 0
39 #endif
40 
41 /* Initialize R (a real with the decimal flag set) from DN.  Can
42    utilize status passed in via CONTEXT, if a previous operation had
43    interesting status.  */
44 
45 static void
decimal_from_decnumber(REAL_VALUE_TYPE * r,decNumber * dn,decContext * context)46 decimal_from_decnumber (REAL_VALUE_TYPE *r, decNumber *dn, decContext *context)
47 {
48   memset (r, 0, sizeof (REAL_VALUE_TYPE));
49 
50   r->cl = rvc_normal;
51   if (decNumberIsNaN (dn))
52     r->cl = rvc_nan;
53   if (decNumberIsInfinite (dn))
54     r->cl = rvc_inf;
55   if (context->status & DEC_Overflow)
56     r->cl = rvc_inf;
57   if (decNumberIsNegative (dn))
58     r->sign = 1;
59   r->decimal = 1;
60 
61   if (r->cl != rvc_normal)
62     return;
63 
64   decContextDefault (context, DEC_INIT_DECIMAL128);
65   context->traps = 0;
66 
67   decimal128FromNumber ((decimal128 *) r->sig, dn, context);
68 }
69 
70 /* Create decimal encoded R from string S.  */
71 
72 void
decimal_real_from_string(REAL_VALUE_TYPE * r,const char * s)73 decimal_real_from_string (REAL_VALUE_TYPE *r, const char *s)
74 {
75   decNumber dn;
76   decContext set;
77   decContextDefault (&set, DEC_INIT_DECIMAL128);
78   set.traps = 0;
79 
80   decNumberFromString (&dn, s, &set);
81 
82   /* It would be more efficient to store directly in decNumber format,
83      but that is impractical from current data structure size.
84      Encoding as a decimal128 is much more compact.  */
85   decimal_from_decnumber (r, &dn, &set);
86 }
87 
88 /* Initialize a decNumber from a REAL_VALUE_TYPE.  */
89 
90 static void
decimal_to_decnumber(const REAL_VALUE_TYPE * r,decNumber * dn)91 decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
92 {
93   decContext set;
94   decContextDefault (&set, DEC_INIT_DECIMAL128);
95   set.traps = 0;
96 
97   switch (r->cl)
98     {
99     case rvc_zero:
100       decNumberZero (dn);
101       break;
102     case rvc_inf:
103       decNumberFromString (dn, "Infinity", &set);
104       break;
105     case rvc_nan:
106       if (r->signalling)
107         decNumberFromString (dn, "snan", &set);
108       else
109         decNumberFromString (dn, "nan", &set);
110       break;
111     case rvc_normal:
112       if (!r->decimal)
113 	{
114 	  /* dconst{1,2,m1,half} are used in various places in
115 	     the middle-end and optimizers, allow them here
116 	     as an exception by converting them to decimal.  */
117 	  if (memcmp (r, &dconst1, sizeof (*r)) == 0)
118 	    {
119 	      decNumberFromString (dn, "1", &set);
120 	      break;
121 	    }
122 	  if (memcmp (r, &dconst2, sizeof (*r)) == 0)
123 	    {
124 	      decNumberFromString (dn, "2", &set);
125 	      break;
126 	    }
127 	  if (memcmp (r, &dconstm1, sizeof (*r)) == 0)
128 	    {
129 	      decNumberFromString (dn, "-1", &set);
130 	      break;
131 	    }
132 	  if (memcmp (r, &dconsthalf, sizeof (*r)) == 0)
133 	    {
134 	      decNumberFromString (dn, "0.5", &set);
135 	      break;
136 	    }
137 	  gcc_unreachable ();
138 	}
139       decimal128ToNumber ((const decimal128 *) r->sig, dn);
140       break;
141     default:
142       gcc_unreachable ();
143     }
144 
145   /* Fix up sign bit.  */
146   if (r->sign != decNumberIsNegative (dn))
147     dn->bits ^= DECNEG;
148 }
149 
150 /* Encode a real into an IEEE 754 decimal32 type.  */
151 
152 void
encode_decimal32(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)153 encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
154 		  long *buf, const REAL_VALUE_TYPE *r)
155 {
156   decNumber dn;
157   decimal32 d32;
158   decContext set;
159   int32_t image;
160 
161   decContextDefault (&set, DEC_INIT_DECIMAL128);
162   set.traps = 0;
163 
164   decimal_to_decnumber (r, &dn);
165   decimal32FromNumber (&d32, &dn, &set);
166 
167   memcpy (&image, d32.bytes, sizeof (int32_t));
168   buf[0] = image;
169 }
170 
171 /* Decode an IEEE 754 decimal32 type into a real.  */
172 
173 void
decode_decimal32(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)174 decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
175 		  REAL_VALUE_TYPE *r, const long *buf)
176 {
177   decNumber dn;
178   decimal32 d32;
179   decContext set;
180   int32_t image;
181 
182   decContextDefault (&set, DEC_INIT_DECIMAL128);
183   set.traps = 0;
184 
185   image = buf[0];
186   memcpy (&d32.bytes, &image, sizeof (int32_t));
187 
188   decimal32ToNumber (&d32, &dn);
189   decimal_from_decnumber (r, &dn, &set);
190 }
191 
192 /* Encode a real into an IEEE 754 decimal64 type.  */
193 
194 void
encode_decimal64(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)195 encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
196 		  long *buf, const REAL_VALUE_TYPE *r)
197 {
198   decNumber dn;
199   decimal64 d64;
200   decContext set;
201   int32_t image;
202 
203   decContextDefault (&set, DEC_INIT_DECIMAL128);
204   set.traps = 0;
205 
206   decimal_to_decnumber (r, &dn);
207   decimal64FromNumber (&d64, &dn, &set);
208 
209   if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
210     {
211       memcpy (&image, &d64.bytes[0], sizeof (int32_t));
212       buf[0] = image;
213       memcpy (&image, &d64.bytes[4], sizeof (int32_t));
214       buf[1] = image;
215     }
216   else
217     {
218       memcpy (&image, &d64.bytes[4], sizeof (int32_t));
219       buf[0] = image;
220       memcpy (&image, &d64.bytes[0], sizeof (int32_t));
221       buf[1] = image;
222     }
223 }
224 
225 /* Decode an IEEE 754 decimal64 type into a real.  */
226 
227 void
decode_decimal64(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)228 decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
229 		  REAL_VALUE_TYPE *r, const long *buf)
230 {
231   decNumber dn;
232   decimal64 d64;
233   decContext set;
234   int32_t image;
235 
236   decContextDefault (&set, DEC_INIT_DECIMAL128);
237   set.traps = 0;
238 
239   if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
240     {
241       image = buf[0];
242       memcpy (&d64.bytes[0], &image, sizeof (int32_t));
243       image = buf[1];
244       memcpy (&d64.bytes[4], &image, sizeof (int32_t));
245     }
246   else
247     {
248       image = buf[1];
249       memcpy (&d64.bytes[0], &image, sizeof (int32_t));
250       image = buf[0];
251       memcpy (&d64.bytes[4], &image, sizeof (int32_t));
252     }
253 
254   decimal64ToNumber (&d64, &dn);
255   decimal_from_decnumber (r, &dn, &set);
256 }
257 
258 /* Encode a real into an IEEE 754 decimal128 type.  */
259 
260 void
encode_decimal128(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)261 encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
262 		   long *buf, const REAL_VALUE_TYPE *r)
263 {
264   decNumber dn;
265   decContext set;
266   decimal128 d128;
267   int32_t image;
268 
269   decContextDefault (&set, DEC_INIT_DECIMAL128);
270   set.traps = 0;
271 
272   decimal_to_decnumber (r, &dn);
273   decimal128FromNumber (&d128, &dn, &set);
274 
275   if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
276     {
277       memcpy (&image, &d128.bytes[0], sizeof (int32_t));
278       buf[0] = image;
279       memcpy (&image, &d128.bytes[4], sizeof (int32_t));
280       buf[1] = image;
281       memcpy (&image, &d128.bytes[8], sizeof (int32_t));
282       buf[2] = image;
283       memcpy (&image, &d128.bytes[12], sizeof (int32_t));
284       buf[3] = image;
285     }
286   else
287     {
288       memcpy (&image, &d128.bytes[12], sizeof (int32_t));
289       buf[0] = image;
290       memcpy (&image, &d128.bytes[8], sizeof (int32_t));
291       buf[1] = image;
292       memcpy (&image, &d128.bytes[4], sizeof (int32_t));
293       buf[2] = image;
294       memcpy (&image, &d128.bytes[0], sizeof (int32_t));
295       buf[3] = image;
296     }
297 }
298 
299 /* Decode an IEEE 754 decimal128 type into a real.  */
300 
301 void
decode_decimal128(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)302 decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
303 		   REAL_VALUE_TYPE *r, const long *buf)
304 {
305   decNumber dn;
306   decimal128 d128;
307   decContext set;
308   int32_t image;
309 
310   decContextDefault (&set, DEC_INIT_DECIMAL128);
311   set.traps = 0;
312 
313   if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
314     {
315       image = buf[0];
316       memcpy (&d128.bytes[0],  &image, sizeof (int32_t));
317       image = buf[1];
318       memcpy (&d128.bytes[4],  &image, sizeof (int32_t));
319       image = buf[2];
320       memcpy (&d128.bytes[8],  &image, sizeof (int32_t));
321       image = buf[3];
322       memcpy (&d128.bytes[12], &image, sizeof (int32_t));
323     }
324   else
325     {
326       image = buf[3];
327       memcpy (&d128.bytes[0],  &image, sizeof (int32_t));
328       image = buf[2];
329       memcpy (&d128.bytes[4],  &image, sizeof (int32_t));
330       image = buf[1];
331       memcpy (&d128.bytes[8],  &image, sizeof (int32_t));
332       image = buf[0];
333       memcpy (&d128.bytes[12], &image, sizeof (int32_t));
334     }
335 
336   decimal128ToNumber (&d128, &dn);
337   decimal_from_decnumber (r, &dn, &set);
338 }
339 
340 /* Helper function to convert from a binary real internal
341    representation.  */
342 
343 static void
decimal_to_binary(REAL_VALUE_TYPE * to,const REAL_VALUE_TYPE * from,enum machine_mode mode)344 decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from,
345 		   enum machine_mode mode)
346 {
347   char string[256];
348   const decimal128 *const d128 = (const decimal128 *) from->sig;
349 
350   decimal128ToString (d128, string);
351   real_from_string3 (to, string, mode);
352 }
353 
354 
355 /* Helper function to convert from a binary real internal
356    representation.  */
357 
358 static void
decimal_from_binary(REAL_VALUE_TYPE * to,const REAL_VALUE_TYPE * from)359 decimal_from_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from)
360 {
361   char string[256];
362 
363   /* We convert to string, then to decNumber then to decimal128.  */
364   real_to_decimal (string, from, sizeof (string), 0, 1);
365   decimal_real_from_string (to, string);
366 }
367 
368 /* Helper function to real.c:do_compare() to handle decimal internal
369    representation including when one of the operands is still in the
370    binary internal representation.  */
371 
372 int
decimal_do_compare(const REAL_VALUE_TYPE * a,const REAL_VALUE_TYPE * b,int nan_result)373 decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
374 		    int nan_result)
375 {
376   decContext set;
377   decNumber dn, dn2, dn3;
378   REAL_VALUE_TYPE a1, b1;
379 
380   /* If either operand is non-decimal, create temporary versions.  */
381   if (!a->decimal)
382     {
383       decimal_from_binary (&a1, a);
384       a = &a1;
385     }
386   if (!b->decimal)
387     {
388       decimal_from_binary (&b1, b);
389       b = &b1;
390     }
391 
392   /* Convert into decNumber form for comparison operation.  */
393   decContextDefault (&set, DEC_INIT_DECIMAL128);
394   set.traps = 0;
395   decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
396   decimal128ToNumber ((const decimal128 *) b->sig, &dn3);
397 
398   /* Finally, do the comparison.  */
399   decNumberCompare (&dn, &dn2, &dn3, &set);
400 
401   /* Return the comparison result.  */
402   if (decNumberIsNaN (&dn))
403     return nan_result;
404   else if (decNumberIsZero (&dn))
405     return 0;
406   else if (decNumberIsNegative (&dn))
407     return -1;
408   else
409     return 1;
410 }
411 
412 /* Helper to round_for_format, handling decimal float types.  */
413 
414 void
decimal_round_for_format(const struct real_format * fmt,REAL_VALUE_TYPE * r)415 decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
416 {
417   decNumber dn;
418   decContext set;
419 
420   /* Real encoding occurs later.  */
421   if (r->cl != rvc_normal)
422     return;
423 
424   decContextDefault (&set, DEC_INIT_DECIMAL128);
425   set.traps = 0;
426   decimal128ToNumber ((decimal128 *) r->sig, &dn);
427 
428   if (fmt == &decimal_quad_format)
429     {
430       /* The internal format is already in this format.  */
431       return;
432     }
433   else if (fmt == &decimal_single_format)
434     {
435       decimal32 d32;
436       decContextDefault (&set, DEC_INIT_DECIMAL32);
437       set.traps = 0;
438 
439       decimal32FromNumber (&d32, &dn, &set);
440       decimal32ToNumber (&d32, &dn);
441     }
442   else if (fmt == &decimal_double_format)
443     {
444       decimal64 d64;
445       decContextDefault (&set, DEC_INIT_DECIMAL64);
446       set.traps = 0;
447 
448       decimal64FromNumber (&d64, &dn, &set);
449       decimal64ToNumber (&d64, &dn);
450     }
451   else
452     gcc_unreachable ();
453 
454   decimal_from_decnumber (r, &dn, &set);
455 }
456 
457 /* Extend or truncate to a new mode.  Handles conversions between
458    binary and decimal types.  */
459 
460 void
decimal_real_convert(REAL_VALUE_TYPE * r,enum machine_mode mode,const REAL_VALUE_TYPE * a)461 decimal_real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode,
462 		      const REAL_VALUE_TYPE *a)
463 {
464   const struct real_format *fmt = REAL_MODE_FORMAT (mode);
465 
466   if (a->decimal && fmt->b == 10)
467     return;
468   if (a->decimal)
469       decimal_to_binary (r, a, mode);
470   else
471       decimal_from_binary (r, a);
472 }
473 
474 /* Render R_ORIG as a decimal floating point constant.  Emit DIGITS
475    significant digits in the result, bounded by BUF_SIZE.  If DIGITS
476    is 0, choose the maximum for the representation.  If
477    CROP_TRAILING_ZEROS, strip trailing zeros.  Currently, not honoring
478    DIGITS or CROP_TRAILING_ZEROS.  */
479 
480 void
decimal_real_to_decimal(char * str,const REAL_VALUE_TYPE * r_orig,size_t buf_size,size_t digits ATTRIBUTE_UNUSED,int crop_trailing_zeros ATTRIBUTE_UNUSED)481 decimal_real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig,
482 			 size_t buf_size,
483 			 size_t digits ATTRIBUTE_UNUSED,
484 			 int crop_trailing_zeros ATTRIBUTE_UNUSED)
485 {
486   const decimal128 *const d128 = (const decimal128*) r_orig->sig;
487 
488   /* decimal128ToString requires space for at least 24 characters;
489      Require two more for suffix.  */
490   gcc_assert (buf_size >= 24);
491   decimal128ToString (d128, str);
492 }
493 
494 static bool
decimal_do_add(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * op0,const REAL_VALUE_TYPE * op1,int subtract_p)495 decimal_do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
496 		const REAL_VALUE_TYPE *op1, int subtract_p)
497 {
498   decNumber dn;
499   decContext set;
500   decNumber dn2, dn3;
501 
502   decimal_to_decnumber (op0, &dn2);
503   decimal_to_decnumber (op1, &dn3);
504 
505   decContextDefault (&set, DEC_INIT_DECIMAL128);
506   set.traps = 0;
507 
508   if (subtract_p)
509     decNumberSubtract (&dn, &dn2, &dn3, &set);
510   else
511     decNumberAdd (&dn, &dn2, &dn3, &set);
512 
513   decimal_from_decnumber (r, &dn, &set);
514 
515   /* Return true, if inexact.  */
516   return (set.status & DEC_Inexact);
517 }
518 
519 /* Compute R = OP0 * OP1.  */
520 
521 static bool
decimal_do_multiply(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * op0,const REAL_VALUE_TYPE * op1)522 decimal_do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
523 		     const REAL_VALUE_TYPE *op1)
524 {
525   decContext set;
526   decNumber dn, dn2, dn3;
527 
528   decimal_to_decnumber (op0, &dn2);
529   decimal_to_decnumber (op1, &dn3);
530 
531   decContextDefault (&set, DEC_INIT_DECIMAL128);
532   set.traps = 0;
533 
534   decNumberMultiply (&dn, &dn2, &dn3, &set);
535   decimal_from_decnumber (r, &dn, &set);
536 
537   /* Return true, if inexact.  */
538   return (set.status & DEC_Inexact);
539 }
540 
541 /* Compute R = OP0 / OP1.  */
542 
543 static bool
decimal_do_divide(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * op0,const REAL_VALUE_TYPE * op1)544 decimal_do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
545 		   const REAL_VALUE_TYPE *op1)
546 {
547   decContext set;
548   decNumber dn, dn2, dn3;
549 
550   decimal_to_decnumber (op0, &dn2);
551   decimal_to_decnumber (op1, &dn3);
552 
553   decContextDefault (&set, DEC_INIT_DECIMAL128);
554   set.traps = 0;
555 
556   decNumberDivide (&dn, &dn2, &dn3, &set);
557   decimal_from_decnumber (r, &dn, &set);
558 
559   /* Return true, if inexact.  */
560   return (set.status & DEC_Inexact);
561 }
562 
563 /* Set R to A truncated to an integral value toward zero (decimal
564    floating point).  */
565 
566 void
decimal_do_fix_trunc(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a)567 decimal_do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
568 {
569   decNumber dn, dn2;
570   decContext set;
571 
572   decContextDefault (&set, DEC_INIT_DECIMAL128);
573   set.traps = 0;
574   set.round = DEC_ROUND_DOWN;
575   decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
576 
577   decNumberToIntegralValue (&dn, &dn2, &set);
578   decimal_from_decnumber (r, &dn, &set);
579 }
580 
581 /* Render decimal float value R as an integer.  */
582 
583 HOST_WIDE_INT
decimal_real_to_integer(const REAL_VALUE_TYPE * r)584 decimal_real_to_integer (const REAL_VALUE_TYPE *r)
585 {
586   decContext set;
587   decNumber dn, dn2, dn3;
588   REAL_VALUE_TYPE to;
589   char string[256];
590 
591   decContextDefault (&set, DEC_INIT_DECIMAL128);
592   set.traps = 0;
593   set.round = DEC_ROUND_DOWN;
594   decimal128ToNumber ((const decimal128 *) r->sig, &dn);
595 
596   decNumberToIntegralValue (&dn2, &dn, &set);
597   decNumberZero (&dn3);
598   decNumberRescale (&dn, &dn2, &dn3, &set);
599 
600   /* Convert to REAL_VALUE_TYPE and call appropriate conversion
601      function.  */
602   decNumberToString (&dn, string);
603   real_from_string (&to, string);
604   return real_to_integer (&to);
605 }
606 
607 /* Likewise, but to an integer pair, HI+LOW.  */
608 
609 void
decimal_real_to_integer2(HOST_WIDE_INT * plow,HOST_WIDE_INT * phigh,const REAL_VALUE_TYPE * r)610 decimal_real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh,
611 			  const REAL_VALUE_TYPE *r)
612 {
613   decContext set;
614   decNumber dn, dn2, dn3;
615   REAL_VALUE_TYPE to;
616   char string[256];
617 
618   decContextDefault (&set, DEC_INIT_DECIMAL128);
619   set.traps = 0;
620   set.round = DEC_ROUND_DOWN;
621   decimal128ToNumber ((const decimal128 *) r->sig, &dn);
622 
623   decNumberToIntegralValue (&dn2, &dn, &set);
624   decNumberZero (&dn3);
625   decNumberRescale (&dn, &dn2, &dn3, &set);
626 
627   /* Convert to REAL_VALUE_TYPE and call appropriate conversion
628      function.  */
629   decNumberToString (&dn, string);
630   real_from_string (&to, string);
631   real_to_integer2 (plow, phigh, &to);
632 }
633 
634 /* Perform the decimal floating point operation described by CODE.
635    For a unary operation, OP1 will be NULL.  This function returns
636    true if the result may be inexact due to loss of precision.  */
637 
638 bool
decimal_real_arithmetic(REAL_VALUE_TYPE * r,enum tree_code code,const REAL_VALUE_TYPE * op0,const REAL_VALUE_TYPE * op1)639 decimal_real_arithmetic (REAL_VALUE_TYPE *r, enum tree_code code,
640 			 const REAL_VALUE_TYPE *op0,
641 			 const REAL_VALUE_TYPE *op1)
642 {
643   REAL_VALUE_TYPE a, b;
644 
645   /* If either operand is non-decimal, create temporaries.  */
646   if (!op0->decimal)
647     {
648       decimal_from_binary (&a, op0);
649       op0 = &a;
650     }
651   if (op1 && !op1->decimal)
652     {
653       decimal_from_binary (&b, op1);
654       op1 = &b;
655     }
656 
657   switch (code)
658     {
659     case PLUS_EXPR:
660       return decimal_do_add (r, op0, op1, 0);
661 
662     case MINUS_EXPR:
663       return decimal_do_add (r, op0, op1, 1);
664 
665     case MULT_EXPR:
666       return decimal_do_multiply (r, op0, op1);
667 
668     case RDIV_EXPR:
669       return decimal_do_divide (r, op0, op1);
670 
671     case MIN_EXPR:
672       if (op1->cl == rvc_nan)
673         *r = *op1;
674       else if (real_compare (UNLT_EXPR, op0, op1))
675         *r = *op0;
676       else
677         *r = *op1;
678       return false;
679 
680     case MAX_EXPR:
681       if (op1->cl == rvc_nan)
682         *r = *op1;
683       else if (real_compare (LT_EXPR, op0, op1))
684         *r = *op1;
685       else
686         *r = *op0;
687       return false;
688 
689     case NEGATE_EXPR:
690       {
691 	*r = *op0;
692 	/* Flip sign bit.  */
693 	decimal128FlipSign ((decimal128 *) r->sig);
694 	/* Keep sign field in sync.  */
695 	r->sign ^= 1;
696       }
697       return false;
698 
699     case ABS_EXPR:
700       {
701         *r = *op0;
702 	/* Clear sign bit.  */
703 	decimal128ClearSign ((decimal128 *) r->sig);
704 	/* Keep sign field in sync.  */
705 	r->sign = 0;
706       }
707       return false;
708 
709     case FIX_TRUNC_EXPR:
710       decimal_do_fix_trunc (r, op0);
711       return false;
712 
713     default:
714       gcc_unreachable ();
715     }
716 }
717 
718 /* Fills R with the largest finite value representable in mode MODE.
719    If SIGN is nonzero, R is set to the most negative finite value.  */
720 
721 void
decimal_real_maxval(REAL_VALUE_TYPE * r,int sign,enum machine_mode mode)722 decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
723 {
724   const char *max;
725 
726   switch (mode)
727     {
728     case SDmode:
729       max = "9.999999E96";
730       break;
731     case DDmode:
732       max = "9.999999999999999E384";
733       break;
734     case TDmode:
735       max = "9.999999999999999999999999999999999E6144";
736       break;
737     default:
738       gcc_unreachable ();
739     }
740 
741   decimal_real_from_string (r, max);
742   if (sign)
743     decimal128SetSign ((decimal128 *) r->sig, 1);
744 }
745