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