OSDN Git Service

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