OSDN Git Service

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