OSDN Git Service

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