xref: /dragonfly/contrib/gcc-4.7/gcc/real.c (revision e4b17023)
1*e4b17023SJohn Marino /* real.c - software floating point emulation.
2*e4b17023SJohn Marino    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
3*e4b17023SJohn Marino    2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
4*e4b17023SJohn Marino    Free Software Foundation, Inc.
5*e4b17023SJohn Marino    Contributed by Stephen L. Moshier (moshier@world.std.com).
6*e4b17023SJohn Marino    Re-written by Richard Henderson <rth@redhat.com>
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino    This file is part of GCC.
9*e4b17023SJohn Marino 
10*e4b17023SJohn Marino    GCC is free software; you can redistribute it and/or modify it under
11*e4b17023SJohn Marino    the terms of the GNU General Public License as published by the Free
12*e4b17023SJohn Marino    Software Foundation; either version 3, or (at your option) any later
13*e4b17023SJohn Marino    version.
14*e4b17023SJohn Marino 
15*e4b17023SJohn Marino    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16*e4b17023SJohn Marino    WARRANTY; without even the implied warranty of MERCHANTABILITY or
17*e4b17023SJohn Marino    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18*e4b17023SJohn Marino    for more details.
19*e4b17023SJohn Marino 
20*e4b17023SJohn Marino    You should have received a copy of the GNU General Public License
21*e4b17023SJohn Marino    along with GCC; see the file COPYING3.  If not see
22*e4b17023SJohn Marino    <http://www.gnu.org/licenses/>.  */
23*e4b17023SJohn Marino 
24*e4b17023SJohn Marino #include "config.h"
25*e4b17023SJohn Marino #include "system.h"
26*e4b17023SJohn Marino #include "coretypes.h"
27*e4b17023SJohn Marino #include "tm.h"
28*e4b17023SJohn Marino #include "tree.h"
29*e4b17023SJohn Marino #include "diagnostic-core.h"
30*e4b17023SJohn Marino #include "real.h"
31*e4b17023SJohn Marino #include "realmpfr.h"
32*e4b17023SJohn Marino #include "tm_p.h"
33*e4b17023SJohn Marino #include "dfp.h"
34*e4b17023SJohn Marino 
35*e4b17023SJohn Marino /* The floating point model used internally is not exactly IEEE 754
36*e4b17023SJohn Marino    compliant, and close to the description in the ISO C99 standard,
37*e4b17023SJohn Marino    section 5.2.4.2.2 Characteristics of floating types.
38*e4b17023SJohn Marino 
39*e4b17023SJohn Marino    Specifically
40*e4b17023SJohn Marino 
41*e4b17023SJohn Marino 	x = s * b^e * \sum_{k=1}^p f_k * b^{-k}
42*e4b17023SJohn Marino 
43*e4b17023SJohn Marino 	where
44*e4b17023SJohn Marino 		s = sign (+- 1)
45*e4b17023SJohn Marino 		b = base or radix, here always 2
46*e4b17023SJohn Marino 		e = exponent
47*e4b17023SJohn Marino 		p = precision (the number of base-b digits in the significand)
48*e4b17023SJohn Marino 		f_k = the digits of the significand.
49*e4b17023SJohn Marino 
50*e4b17023SJohn Marino    We differ from typical IEEE 754 encodings in that the entire
51*e4b17023SJohn Marino    significand is fractional.  Normalized significands are in the
52*e4b17023SJohn Marino    range [0.5, 1.0).
53*e4b17023SJohn Marino 
54*e4b17023SJohn Marino    A requirement of the model is that P be larger than the largest
55*e4b17023SJohn Marino    supported target floating-point type by at least 2 bits.  This gives
56*e4b17023SJohn Marino    us proper rounding when we truncate to the target type.  In addition,
57*e4b17023SJohn Marino    E must be large enough to hold the smallest supported denormal number
58*e4b17023SJohn Marino    in a normalized form.
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino    Both of these requirements are easily satisfied.  The largest target
61*e4b17023SJohn Marino    significand is 113 bits; we store at least 160.  The smallest
62*e4b17023SJohn Marino    denormal number fits in 17 exponent bits; we store 26.
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino    Note that the decimal string conversion routines are sensitive to
65*e4b17023SJohn Marino    rounding errors.  Since the raw arithmetic routines do not themselves
66*e4b17023SJohn Marino    have guard digits or rounding, the computation of 10**exp can
67*e4b17023SJohn Marino    accumulate more than a few digits of error.  The previous incarnation
68*e4b17023SJohn Marino    of real.c successfully used a 144-bit fraction; given the current
69*e4b17023SJohn Marino    layout of REAL_VALUE_TYPE we're forced to expand to at least 160 bits.  */
70*e4b17023SJohn Marino 
71*e4b17023SJohn Marino 
72*e4b17023SJohn Marino /* Used to classify two numbers simultaneously.  */
73*e4b17023SJohn Marino #define CLASS2(A, B)  ((A) << 2 | (B))
74*e4b17023SJohn Marino 
75*e4b17023SJohn Marino #if HOST_BITS_PER_LONG != 64 && HOST_BITS_PER_LONG != 32
76*e4b17023SJohn Marino  #error "Some constant folding done by hand to avoid shift count warnings"
77*e4b17023SJohn Marino #endif
78*e4b17023SJohn Marino 
79*e4b17023SJohn Marino static void get_zero (REAL_VALUE_TYPE *, int);
80*e4b17023SJohn Marino static void get_canonical_qnan (REAL_VALUE_TYPE *, int);
81*e4b17023SJohn Marino static void get_canonical_snan (REAL_VALUE_TYPE *, int);
82*e4b17023SJohn Marino static void get_inf (REAL_VALUE_TYPE *, int);
83*e4b17023SJohn Marino static bool sticky_rshift_significand (REAL_VALUE_TYPE *,
84*e4b17023SJohn Marino 				       const REAL_VALUE_TYPE *, unsigned int);
85*e4b17023SJohn Marino static void rshift_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
86*e4b17023SJohn Marino 				unsigned int);
87*e4b17023SJohn Marino static void lshift_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
88*e4b17023SJohn Marino 				unsigned int);
89*e4b17023SJohn Marino static void lshift_significand_1 (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
90*e4b17023SJohn Marino static bool add_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *,
91*e4b17023SJohn Marino 			      const REAL_VALUE_TYPE *);
92*e4b17023SJohn Marino static bool sub_significands (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
93*e4b17023SJohn Marino 			      const REAL_VALUE_TYPE *, int);
94*e4b17023SJohn Marino static void neg_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
95*e4b17023SJohn Marino static int cmp_significands (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
96*e4b17023SJohn Marino static int cmp_significand_0 (const REAL_VALUE_TYPE *);
97*e4b17023SJohn Marino static void set_significand_bit (REAL_VALUE_TYPE *, unsigned int);
98*e4b17023SJohn Marino static void clear_significand_bit (REAL_VALUE_TYPE *, unsigned int);
99*e4b17023SJohn Marino static bool test_significand_bit (REAL_VALUE_TYPE *, unsigned int);
100*e4b17023SJohn Marino static void clear_significand_below (REAL_VALUE_TYPE *, unsigned int);
101*e4b17023SJohn Marino static bool div_significands (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
102*e4b17023SJohn Marino 			      const REAL_VALUE_TYPE *);
103*e4b17023SJohn Marino static void normalize (REAL_VALUE_TYPE *);
104*e4b17023SJohn Marino 
105*e4b17023SJohn Marino static bool do_add (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
106*e4b17023SJohn Marino 		    const REAL_VALUE_TYPE *, int);
107*e4b17023SJohn Marino static bool do_multiply (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
108*e4b17023SJohn Marino 			 const REAL_VALUE_TYPE *);
109*e4b17023SJohn Marino static bool do_divide (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
110*e4b17023SJohn Marino 		       const REAL_VALUE_TYPE *);
111*e4b17023SJohn Marino static int do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
112*e4b17023SJohn Marino static void do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
113*e4b17023SJohn Marino 
114*e4b17023SJohn Marino static unsigned long rtd_divmod (REAL_VALUE_TYPE *, REAL_VALUE_TYPE *);
115*e4b17023SJohn Marino static void decimal_from_integer (REAL_VALUE_TYPE *);
116*e4b17023SJohn Marino static void decimal_integer_string (char *, const REAL_VALUE_TYPE *,
117*e4b17023SJohn Marino 				    size_t);
118*e4b17023SJohn Marino 
119*e4b17023SJohn Marino static const REAL_VALUE_TYPE * ten_to_ptwo (int);
120*e4b17023SJohn Marino static const REAL_VALUE_TYPE * ten_to_mptwo (int);
121*e4b17023SJohn Marino static const REAL_VALUE_TYPE * real_digit (int);
122*e4b17023SJohn Marino static void times_pten (REAL_VALUE_TYPE *, int);
123*e4b17023SJohn Marino 
124*e4b17023SJohn Marino static void round_for_format (const struct real_format *, REAL_VALUE_TYPE *);
125*e4b17023SJohn Marino 
126*e4b17023SJohn Marino /* Initialize R with a positive zero.  */
127*e4b17023SJohn Marino 
128*e4b17023SJohn Marino static inline void
get_zero(REAL_VALUE_TYPE * r,int sign)129*e4b17023SJohn Marino get_zero (REAL_VALUE_TYPE *r, int sign)
130*e4b17023SJohn Marino {
131*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
132*e4b17023SJohn Marino   r->sign = sign;
133*e4b17023SJohn Marino }
134*e4b17023SJohn Marino 
135*e4b17023SJohn Marino /* Initialize R with the canonical quiet NaN.  */
136*e4b17023SJohn Marino 
137*e4b17023SJohn Marino static inline void
get_canonical_qnan(REAL_VALUE_TYPE * r,int sign)138*e4b17023SJohn Marino get_canonical_qnan (REAL_VALUE_TYPE *r, int sign)
139*e4b17023SJohn Marino {
140*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
141*e4b17023SJohn Marino   r->cl = rvc_nan;
142*e4b17023SJohn Marino   r->sign = sign;
143*e4b17023SJohn Marino   r->canonical = 1;
144*e4b17023SJohn Marino }
145*e4b17023SJohn Marino 
146*e4b17023SJohn Marino static inline void
get_canonical_snan(REAL_VALUE_TYPE * r,int sign)147*e4b17023SJohn Marino get_canonical_snan (REAL_VALUE_TYPE *r, int sign)
148*e4b17023SJohn Marino {
149*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
150*e4b17023SJohn Marino   r->cl = rvc_nan;
151*e4b17023SJohn Marino   r->sign = sign;
152*e4b17023SJohn Marino   r->signalling = 1;
153*e4b17023SJohn Marino   r->canonical = 1;
154*e4b17023SJohn Marino }
155*e4b17023SJohn Marino 
156*e4b17023SJohn Marino static inline void
get_inf(REAL_VALUE_TYPE * r,int sign)157*e4b17023SJohn Marino get_inf (REAL_VALUE_TYPE *r, int sign)
158*e4b17023SJohn Marino {
159*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
160*e4b17023SJohn Marino   r->cl = rvc_inf;
161*e4b17023SJohn Marino   r->sign = sign;
162*e4b17023SJohn Marino }
163*e4b17023SJohn Marino 
164*e4b17023SJohn Marino 
165*e4b17023SJohn Marino /* Right-shift the significand of A by N bits; put the result in the
166*e4b17023SJohn Marino    significand of R.  If any one bits are shifted out, return true.  */
167*e4b17023SJohn Marino 
168*e4b17023SJohn Marino static bool
sticky_rshift_significand(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a,unsigned int n)169*e4b17023SJohn Marino sticky_rshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
170*e4b17023SJohn Marino 			   unsigned int n)
171*e4b17023SJohn Marino {
172*e4b17023SJohn Marino   unsigned long sticky = 0;
173*e4b17023SJohn Marino   unsigned int i, ofs = 0;
174*e4b17023SJohn Marino 
175*e4b17023SJohn Marino   if (n >= HOST_BITS_PER_LONG)
176*e4b17023SJohn Marino     {
177*e4b17023SJohn Marino       for (i = 0, ofs = n / HOST_BITS_PER_LONG; i < ofs; ++i)
178*e4b17023SJohn Marino 	sticky |= a->sig[i];
179*e4b17023SJohn Marino       n &= HOST_BITS_PER_LONG - 1;
180*e4b17023SJohn Marino     }
181*e4b17023SJohn Marino 
182*e4b17023SJohn Marino   if (n != 0)
183*e4b17023SJohn Marino     {
184*e4b17023SJohn Marino       sticky |= a->sig[ofs] & (((unsigned long)1 << n) - 1);
185*e4b17023SJohn Marino       for (i = 0; i < SIGSZ; ++i)
186*e4b17023SJohn Marino 	{
187*e4b17023SJohn Marino 	  r->sig[i]
188*e4b17023SJohn Marino 	    = (((ofs + i >= SIGSZ ? 0 : a->sig[ofs + i]) >> n)
189*e4b17023SJohn Marino 	       | ((ofs + i + 1 >= SIGSZ ? 0 : a->sig[ofs + i + 1])
190*e4b17023SJohn Marino 		  << (HOST_BITS_PER_LONG - n)));
191*e4b17023SJohn Marino 	}
192*e4b17023SJohn Marino     }
193*e4b17023SJohn Marino   else
194*e4b17023SJohn Marino     {
195*e4b17023SJohn Marino       for (i = 0; ofs + i < SIGSZ; ++i)
196*e4b17023SJohn Marino 	r->sig[i] = a->sig[ofs + i];
197*e4b17023SJohn Marino       for (; i < SIGSZ; ++i)
198*e4b17023SJohn Marino 	r->sig[i] = 0;
199*e4b17023SJohn Marino     }
200*e4b17023SJohn Marino 
201*e4b17023SJohn Marino   return sticky != 0;
202*e4b17023SJohn Marino }
203*e4b17023SJohn Marino 
204*e4b17023SJohn Marino /* Right-shift the significand of A by N bits; put the result in the
205*e4b17023SJohn Marino    significand of R.  */
206*e4b17023SJohn Marino 
207*e4b17023SJohn Marino static void
rshift_significand(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a,unsigned int n)208*e4b17023SJohn Marino rshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
209*e4b17023SJohn Marino 		    unsigned int n)
210*e4b17023SJohn Marino {
211*e4b17023SJohn Marino   unsigned int i, ofs = n / HOST_BITS_PER_LONG;
212*e4b17023SJohn Marino 
213*e4b17023SJohn Marino   n &= HOST_BITS_PER_LONG - 1;
214*e4b17023SJohn Marino   if (n != 0)
215*e4b17023SJohn Marino     {
216*e4b17023SJohn Marino       for (i = 0; i < SIGSZ; ++i)
217*e4b17023SJohn Marino 	{
218*e4b17023SJohn Marino 	  r->sig[i]
219*e4b17023SJohn Marino 	    = (((ofs + i >= SIGSZ ? 0 : a->sig[ofs + i]) >> n)
220*e4b17023SJohn Marino 	       | ((ofs + i + 1 >= SIGSZ ? 0 : a->sig[ofs + i + 1])
221*e4b17023SJohn Marino 		  << (HOST_BITS_PER_LONG - n)));
222*e4b17023SJohn Marino 	}
223*e4b17023SJohn Marino     }
224*e4b17023SJohn Marino   else
225*e4b17023SJohn Marino     {
226*e4b17023SJohn Marino       for (i = 0; ofs + i < SIGSZ; ++i)
227*e4b17023SJohn Marino 	r->sig[i] = a->sig[ofs + i];
228*e4b17023SJohn Marino       for (; i < SIGSZ; ++i)
229*e4b17023SJohn Marino 	r->sig[i] = 0;
230*e4b17023SJohn Marino     }
231*e4b17023SJohn Marino }
232*e4b17023SJohn Marino 
233*e4b17023SJohn Marino /* Left-shift the significand of A by N bits; put the result in the
234*e4b17023SJohn Marino    significand of R.  */
235*e4b17023SJohn Marino 
236*e4b17023SJohn Marino static void
lshift_significand(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a,unsigned int n)237*e4b17023SJohn Marino lshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
238*e4b17023SJohn Marino 		    unsigned int n)
239*e4b17023SJohn Marino {
240*e4b17023SJohn Marino   unsigned int i, ofs = n / HOST_BITS_PER_LONG;
241*e4b17023SJohn Marino 
242*e4b17023SJohn Marino   n &= HOST_BITS_PER_LONG - 1;
243*e4b17023SJohn Marino   if (n == 0)
244*e4b17023SJohn Marino     {
245*e4b17023SJohn Marino       for (i = 0; ofs + i < SIGSZ; ++i)
246*e4b17023SJohn Marino 	r->sig[SIGSZ-1-i] = a->sig[SIGSZ-1-i-ofs];
247*e4b17023SJohn Marino       for (; i < SIGSZ; ++i)
248*e4b17023SJohn Marino 	r->sig[SIGSZ-1-i] = 0;
249*e4b17023SJohn Marino     }
250*e4b17023SJohn Marino   else
251*e4b17023SJohn Marino     for (i = 0; i < SIGSZ; ++i)
252*e4b17023SJohn Marino       {
253*e4b17023SJohn Marino 	r->sig[SIGSZ-1-i]
254*e4b17023SJohn Marino 	  = (((ofs + i >= SIGSZ ? 0 : a->sig[SIGSZ-1-i-ofs]) << n)
255*e4b17023SJohn Marino 	     | ((ofs + i + 1 >= SIGSZ ? 0 : a->sig[SIGSZ-1-i-ofs-1])
256*e4b17023SJohn Marino 		>> (HOST_BITS_PER_LONG - n)));
257*e4b17023SJohn Marino       }
258*e4b17023SJohn Marino }
259*e4b17023SJohn Marino 
260*e4b17023SJohn Marino /* Likewise, but N is specialized to 1.  */
261*e4b17023SJohn Marino 
262*e4b17023SJohn Marino static inline void
lshift_significand_1(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a)263*e4b17023SJohn Marino lshift_significand_1 (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
264*e4b17023SJohn Marino {
265*e4b17023SJohn Marino   unsigned int i;
266*e4b17023SJohn Marino 
267*e4b17023SJohn Marino   for (i = SIGSZ - 1; i > 0; --i)
268*e4b17023SJohn Marino     r->sig[i] = (a->sig[i] << 1) | (a->sig[i-1] >> (HOST_BITS_PER_LONG - 1));
269*e4b17023SJohn Marino   r->sig[0] = a->sig[0] << 1;
270*e4b17023SJohn Marino }
271*e4b17023SJohn Marino 
272*e4b17023SJohn Marino /* Add the significands of A and B, placing the result in R.  Return
273*e4b17023SJohn Marino    true if there was carry out of the most significant word.  */
274*e4b17023SJohn Marino 
275*e4b17023SJohn Marino static inline bool
add_significands(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a,const REAL_VALUE_TYPE * b)276*e4b17023SJohn Marino add_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
277*e4b17023SJohn Marino 		  const REAL_VALUE_TYPE *b)
278*e4b17023SJohn Marino {
279*e4b17023SJohn Marino   bool carry = false;
280*e4b17023SJohn Marino   int i;
281*e4b17023SJohn Marino 
282*e4b17023SJohn Marino   for (i = 0; i < SIGSZ; ++i)
283*e4b17023SJohn Marino     {
284*e4b17023SJohn Marino       unsigned long ai = a->sig[i];
285*e4b17023SJohn Marino       unsigned long ri = ai + b->sig[i];
286*e4b17023SJohn Marino 
287*e4b17023SJohn Marino       if (carry)
288*e4b17023SJohn Marino 	{
289*e4b17023SJohn Marino 	  carry = ri < ai;
290*e4b17023SJohn Marino 	  carry |= ++ri == 0;
291*e4b17023SJohn Marino 	}
292*e4b17023SJohn Marino       else
293*e4b17023SJohn Marino 	carry = ri < ai;
294*e4b17023SJohn Marino 
295*e4b17023SJohn Marino       r->sig[i] = ri;
296*e4b17023SJohn Marino     }
297*e4b17023SJohn Marino 
298*e4b17023SJohn Marino   return carry;
299*e4b17023SJohn Marino }
300*e4b17023SJohn Marino 
301*e4b17023SJohn Marino /* Subtract the significands of A and B, placing the result in R.  CARRY is
302*e4b17023SJohn Marino    true if there's a borrow incoming to the least significant word.
303*e4b17023SJohn Marino    Return true if there was borrow out of the most significant word.  */
304*e4b17023SJohn Marino 
305*e4b17023SJohn Marino static inline bool
sub_significands(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a,const REAL_VALUE_TYPE * b,int carry)306*e4b17023SJohn Marino sub_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
307*e4b17023SJohn Marino 		  const REAL_VALUE_TYPE *b, int carry)
308*e4b17023SJohn Marino {
309*e4b17023SJohn Marino   int i;
310*e4b17023SJohn Marino 
311*e4b17023SJohn Marino   for (i = 0; i < SIGSZ; ++i)
312*e4b17023SJohn Marino     {
313*e4b17023SJohn Marino       unsigned long ai = a->sig[i];
314*e4b17023SJohn Marino       unsigned long ri = ai - b->sig[i];
315*e4b17023SJohn Marino 
316*e4b17023SJohn Marino       if (carry)
317*e4b17023SJohn Marino 	{
318*e4b17023SJohn Marino 	  carry = ri > ai;
319*e4b17023SJohn Marino 	  carry |= ~--ri == 0;
320*e4b17023SJohn Marino 	}
321*e4b17023SJohn Marino       else
322*e4b17023SJohn Marino 	carry = ri > ai;
323*e4b17023SJohn Marino 
324*e4b17023SJohn Marino       r->sig[i] = ri;
325*e4b17023SJohn Marino     }
326*e4b17023SJohn Marino 
327*e4b17023SJohn Marino   return carry;
328*e4b17023SJohn Marino }
329*e4b17023SJohn Marino 
330*e4b17023SJohn Marino /* Negate the significand A, placing the result in R.  */
331*e4b17023SJohn Marino 
332*e4b17023SJohn Marino static inline void
neg_significand(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a)333*e4b17023SJohn Marino neg_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
334*e4b17023SJohn Marino {
335*e4b17023SJohn Marino   bool carry = true;
336*e4b17023SJohn Marino   int i;
337*e4b17023SJohn Marino 
338*e4b17023SJohn Marino   for (i = 0; i < SIGSZ; ++i)
339*e4b17023SJohn Marino     {
340*e4b17023SJohn Marino       unsigned long ri, ai = a->sig[i];
341*e4b17023SJohn Marino 
342*e4b17023SJohn Marino       if (carry)
343*e4b17023SJohn Marino 	{
344*e4b17023SJohn Marino 	  if (ai)
345*e4b17023SJohn Marino 	    {
346*e4b17023SJohn Marino 	      ri = -ai;
347*e4b17023SJohn Marino 	      carry = false;
348*e4b17023SJohn Marino 	    }
349*e4b17023SJohn Marino 	  else
350*e4b17023SJohn Marino 	    ri = ai;
351*e4b17023SJohn Marino 	}
352*e4b17023SJohn Marino       else
353*e4b17023SJohn Marino 	ri = ~ai;
354*e4b17023SJohn Marino 
355*e4b17023SJohn Marino       r->sig[i] = ri;
356*e4b17023SJohn Marino     }
357*e4b17023SJohn Marino }
358*e4b17023SJohn Marino 
359*e4b17023SJohn Marino /* Compare significands.  Return tri-state vs zero.  */
360*e4b17023SJohn Marino 
361*e4b17023SJohn Marino static inline int
cmp_significands(const REAL_VALUE_TYPE * a,const REAL_VALUE_TYPE * b)362*e4b17023SJohn Marino cmp_significands (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
363*e4b17023SJohn Marino {
364*e4b17023SJohn Marino   int i;
365*e4b17023SJohn Marino 
366*e4b17023SJohn Marino   for (i = SIGSZ - 1; i >= 0; --i)
367*e4b17023SJohn Marino     {
368*e4b17023SJohn Marino       unsigned long ai = a->sig[i];
369*e4b17023SJohn Marino       unsigned long bi = b->sig[i];
370*e4b17023SJohn Marino 
371*e4b17023SJohn Marino       if (ai > bi)
372*e4b17023SJohn Marino 	return 1;
373*e4b17023SJohn Marino       if (ai < bi)
374*e4b17023SJohn Marino 	return -1;
375*e4b17023SJohn Marino     }
376*e4b17023SJohn Marino 
377*e4b17023SJohn Marino   return 0;
378*e4b17023SJohn Marino }
379*e4b17023SJohn Marino 
380*e4b17023SJohn Marino /* Return true if A is nonzero.  */
381*e4b17023SJohn Marino 
382*e4b17023SJohn Marino static inline int
cmp_significand_0(const REAL_VALUE_TYPE * a)383*e4b17023SJohn Marino cmp_significand_0 (const REAL_VALUE_TYPE *a)
384*e4b17023SJohn Marino {
385*e4b17023SJohn Marino   int i;
386*e4b17023SJohn Marino 
387*e4b17023SJohn Marino   for (i = SIGSZ - 1; i >= 0; --i)
388*e4b17023SJohn Marino     if (a->sig[i])
389*e4b17023SJohn Marino       return 1;
390*e4b17023SJohn Marino 
391*e4b17023SJohn Marino   return 0;
392*e4b17023SJohn Marino }
393*e4b17023SJohn Marino 
394*e4b17023SJohn Marino /* Set bit N of the significand of R.  */
395*e4b17023SJohn Marino 
396*e4b17023SJohn Marino static inline void
set_significand_bit(REAL_VALUE_TYPE * r,unsigned int n)397*e4b17023SJohn Marino set_significand_bit (REAL_VALUE_TYPE *r, unsigned int n)
398*e4b17023SJohn Marino {
399*e4b17023SJohn Marino   r->sig[n / HOST_BITS_PER_LONG]
400*e4b17023SJohn Marino     |= (unsigned long)1 << (n % HOST_BITS_PER_LONG);
401*e4b17023SJohn Marino }
402*e4b17023SJohn Marino 
403*e4b17023SJohn Marino /* Clear bit N of the significand of R.  */
404*e4b17023SJohn Marino 
405*e4b17023SJohn Marino static inline void
clear_significand_bit(REAL_VALUE_TYPE * r,unsigned int n)406*e4b17023SJohn Marino clear_significand_bit (REAL_VALUE_TYPE *r, unsigned int n)
407*e4b17023SJohn Marino {
408*e4b17023SJohn Marino   r->sig[n / HOST_BITS_PER_LONG]
409*e4b17023SJohn Marino     &= ~((unsigned long)1 << (n % HOST_BITS_PER_LONG));
410*e4b17023SJohn Marino }
411*e4b17023SJohn Marino 
412*e4b17023SJohn Marino /* Test bit N of the significand of R.  */
413*e4b17023SJohn Marino 
414*e4b17023SJohn Marino static inline bool
test_significand_bit(REAL_VALUE_TYPE * r,unsigned int n)415*e4b17023SJohn Marino test_significand_bit (REAL_VALUE_TYPE *r, unsigned int n)
416*e4b17023SJohn Marino {
417*e4b17023SJohn Marino   /* ??? Compiler bug here if we return this expression directly.
418*e4b17023SJohn Marino      The conversion to bool strips the "&1" and we wind up testing
419*e4b17023SJohn Marino      e.g. 2 != 0 -> true.  Seen in gcc version 3.2 20020520.  */
420*e4b17023SJohn Marino   int t = (r->sig[n / HOST_BITS_PER_LONG] >> (n % HOST_BITS_PER_LONG)) & 1;
421*e4b17023SJohn Marino   return t;
422*e4b17023SJohn Marino }
423*e4b17023SJohn Marino 
424*e4b17023SJohn Marino /* Clear bits 0..N-1 of the significand of R.  */
425*e4b17023SJohn Marino 
426*e4b17023SJohn Marino static void
clear_significand_below(REAL_VALUE_TYPE * r,unsigned int n)427*e4b17023SJohn Marino clear_significand_below (REAL_VALUE_TYPE *r, unsigned int n)
428*e4b17023SJohn Marino {
429*e4b17023SJohn Marino   int i, w = n / HOST_BITS_PER_LONG;
430*e4b17023SJohn Marino 
431*e4b17023SJohn Marino   for (i = 0; i < w; ++i)
432*e4b17023SJohn Marino     r->sig[i] = 0;
433*e4b17023SJohn Marino 
434*e4b17023SJohn Marino   r->sig[w] &= ~(((unsigned long)1 << (n % HOST_BITS_PER_LONG)) - 1);
435*e4b17023SJohn Marino }
436*e4b17023SJohn Marino 
437*e4b17023SJohn Marino /* Divide the significands of A and B, placing the result in R.  Return
438*e4b17023SJohn Marino    true if the division was inexact.  */
439*e4b17023SJohn Marino 
440*e4b17023SJohn Marino static inline bool
div_significands(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a,const REAL_VALUE_TYPE * b)441*e4b17023SJohn Marino div_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
442*e4b17023SJohn Marino 		  const REAL_VALUE_TYPE *b)
443*e4b17023SJohn Marino {
444*e4b17023SJohn Marino   REAL_VALUE_TYPE u;
445*e4b17023SJohn Marino   int i, bit = SIGNIFICAND_BITS - 1;
446*e4b17023SJohn Marino   unsigned long msb, inexact;
447*e4b17023SJohn Marino 
448*e4b17023SJohn Marino   u = *a;
449*e4b17023SJohn Marino   memset (r->sig, 0, sizeof (r->sig));
450*e4b17023SJohn Marino 
451*e4b17023SJohn Marino   msb = 0;
452*e4b17023SJohn Marino   goto start;
453*e4b17023SJohn Marino   do
454*e4b17023SJohn Marino     {
455*e4b17023SJohn Marino       msb = u.sig[SIGSZ-1] & SIG_MSB;
456*e4b17023SJohn Marino       lshift_significand_1 (&u, &u);
457*e4b17023SJohn Marino     start:
458*e4b17023SJohn Marino       if (msb || cmp_significands (&u, b) >= 0)
459*e4b17023SJohn Marino 	{
460*e4b17023SJohn Marino 	  sub_significands (&u, &u, b, 0);
461*e4b17023SJohn Marino 	  set_significand_bit (r, bit);
462*e4b17023SJohn Marino 	}
463*e4b17023SJohn Marino     }
464*e4b17023SJohn Marino   while (--bit >= 0);
465*e4b17023SJohn Marino 
466*e4b17023SJohn Marino   for (i = 0, inexact = 0; i < SIGSZ; i++)
467*e4b17023SJohn Marino     inexact |= u.sig[i];
468*e4b17023SJohn Marino 
469*e4b17023SJohn Marino   return inexact != 0;
470*e4b17023SJohn Marino }
471*e4b17023SJohn Marino 
472*e4b17023SJohn Marino /* Adjust the exponent and significand of R such that the most
473*e4b17023SJohn Marino    significant bit is set.  We underflow to zero and overflow to
474*e4b17023SJohn Marino    infinity here, without denormals.  (The intermediate representation
475*e4b17023SJohn Marino    exponent is large enough to handle target denormals normalized.)  */
476*e4b17023SJohn Marino 
477*e4b17023SJohn Marino static void
normalize(REAL_VALUE_TYPE * r)478*e4b17023SJohn Marino normalize (REAL_VALUE_TYPE *r)
479*e4b17023SJohn Marino {
480*e4b17023SJohn Marino   int shift = 0, exp;
481*e4b17023SJohn Marino   int i, j;
482*e4b17023SJohn Marino 
483*e4b17023SJohn Marino   if (r->decimal)
484*e4b17023SJohn Marino     return;
485*e4b17023SJohn Marino 
486*e4b17023SJohn Marino   /* Find the first word that is nonzero.  */
487*e4b17023SJohn Marino   for (i = SIGSZ - 1; i >= 0; i--)
488*e4b17023SJohn Marino     if (r->sig[i] == 0)
489*e4b17023SJohn Marino       shift += HOST_BITS_PER_LONG;
490*e4b17023SJohn Marino     else
491*e4b17023SJohn Marino       break;
492*e4b17023SJohn Marino 
493*e4b17023SJohn Marino   /* Zero significand flushes to zero.  */
494*e4b17023SJohn Marino   if (i < 0)
495*e4b17023SJohn Marino     {
496*e4b17023SJohn Marino       r->cl = rvc_zero;
497*e4b17023SJohn Marino       SET_REAL_EXP (r, 0);
498*e4b17023SJohn Marino       return;
499*e4b17023SJohn Marino     }
500*e4b17023SJohn Marino 
501*e4b17023SJohn Marino   /* Find the first bit that is nonzero.  */
502*e4b17023SJohn Marino   for (j = 0; ; j++)
503*e4b17023SJohn Marino     if (r->sig[i] & ((unsigned long)1 << (HOST_BITS_PER_LONG - 1 - j)))
504*e4b17023SJohn Marino       break;
505*e4b17023SJohn Marino   shift += j;
506*e4b17023SJohn Marino 
507*e4b17023SJohn Marino   if (shift > 0)
508*e4b17023SJohn Marino     {
509*e4b17023SJohn Marino       exp = REAL_EXP (r) - shift;
510*e4b17023SJohn Marino       if (exp > MAX_EXP)
511*e4b17023SJohn Marino 	get_inf (r, r->sign);
512*e4b17023SJohn Marino       else if (exp < -MAX_EXP)
513*e4b17023SJohn Marino 	get_zero (r, r->sign);
514*e4b17023SJohn Marino       else
515*e4b17023SJohn Marino 	{
516*e4b17023SJohn Marino 	  SET_REAL_EXP (r, exp);
517*e4b17023SJohn Marino 	  lshift_significand (r, r, shift);
518*e4b17023SJohn Marino 	}
519*e4b17023SJohn Marino     }
520*e4b17023SJohn Marino }
521*e4b17023SJohn Marino 
522*e4b17023SJohn Marino /* Calculate R = A + (SUBTRACT_P ? -B : B).  Return true if the
523*e4b17023SJohn Marino    result may be inexact due to a loss of precision.  */
524*e4b17023SJohn Marino 
525*e4b17023SJohn Marino static bool
do_add(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a,const REAL_VALUE_TYPE * b,int subtract_p)526*e4b17023SJohn Marino do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
527*e4b17023SJohn Marino 	const REAL_VALUE_TYPE *b, int subtract_p)
528*e4b17023SJohn Marino {
529*e4b17023SJohn Marino   int dexp, sign, exp;
530*e4b17023SJohn Marino   REAL_VALUE_TYPE t;
531*e4b17023SJohn Marino   bool inexact = false;
532*e4b17023SJohn Marino 
533*e4b17023SJohn Marino   /* Determine if we need to add or subtract.  */
534*e4b17023SJohn Marino   sign = a->sign;
535*e4b17023SJohn Marino   subtract_p = (sign ^ b->sign) ^ subtract_p;
536*e4b17023SJohn Marino 
537*e4b17023SJohn Marino   switch (CLASS2 (a->cl, b->cl))
538*e4b17023SJohn Marino     {
539*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_zero):
540*e4b17023SJohn Marino       /* -0 + -0 = -0, -0 - +0 = -0; all other cases yield +0.  */
541*e4b17023SJohn Marino       get_zero (r, sign & !subtract_p);
542*e4b17023SJohn Marino       return false;
543*e4b17023SJohn Marino 
544*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_normal):
545*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_inf):
546*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_nan):
547*e4b17023SJohn Marino       /* 0 + ANY = ANY.  */
548*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_nan):
549*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_nan):
550*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_nan):
551*e4b17023SJohn Marino       /* ANY + NaN = NaN.  */
552*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_inf):
553*e4b17023SJohn Marino       /* R + Inf = Inf.  */
554*e4b17023SJohn Marino       *r = *b;
555*e4b17023SJohn Marino       r->sign = sign ^ subtract_p;
556*e4b17023SJohn Marino       return false;
557*e4b17023SJohn Marino 
558*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_zero):
559*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_zero):
560*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_zero):
561*e4b17023SJohn Marino       /* ANY + 0 = ANY.  */
562*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_normal):
563*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_inf):
564*e4b17023SJohn Marino       /* NaN + ANY = NaN.  */
565*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_normal):
566*e4b17023SJohn Marino       /* Inf + R = Inf.  */
567*e4b17023SJohn Marino       *r = *a;
568*e4b17023SJohn Marino       return false;
569*e4b17023SJohn Marino 
570*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_inf):
571*e4b17023SJohn Marino       if (subtract_p)
572*e4b17023SJohn Marino 	/* Inf - Inf = NaN.  */
573*e4b17023SJohn Marino 	get_canonical_qnan (r, 0);
574*e4b17023SJohn Marino       else
575*e4b17023SJohn Marino 	/* Inf + Inf = Inf.  */
576*e4b17023SJohn Marino 	*r = *a;
577*e4b17023SJohn Marino       return false;
578*e4b17023SJohn Marino 
579*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_normal):
580*e4b17023SJohn Marino       break;
581*e4b17023SJohn Marino 
582*e4b17023SJohn Marino     default:
583*e4b17023SJohn Marino       gcc_unreachable ();
584*e4b17023SJohn Marino     }
585*e4b17023SJohn Marino 
586*e4b17023SJohn Marino   /* Swap the arguments such that A has the larger exponent.  */
587*e4b17023SJohn Marino   dexp = REAL_EXP (a) - REAL_EXP (b);
588*e4b17023SJohn Marino   if (dexp < 0)
589*e4b17023SJohn Marino     {
590*e4b17023SJohn Marino       const REAL_VALUE_TYPE *t;
591*e4b17023SJohn Marino       t = a, a = b, b = t;
592*e4b17023SJohn Marino       dexp = -dexp;
593*e4b17023SJohn Marino       sign ^= subtract_p;
594*e4b17023SJohn Marino     }
595*e4b17023SJohn Marino   exp = REAL_EXP (a);
596*e4b17023SJohn Marino 
597*e4b17023SJohn Marino   /* If the exponents are not identical, we need to shift the
598*e4b17023SJohn Marino      significand of B down.  */
599*e4b17023SJohn Marino   if (dexp > 0)
600*e4b17023SJohn Marino     {
601*e4b17023SJohn Marino       /* If the exponents are too far apart, the significands
602*e4b17023SJohn Marino 	 do not overlap, which makes the subtraction a noop.  */
603*e4b17023SJohn Marino       if (dexp >= SIGNIFICAND_BITS)
604*e4b17023SJohn Marino 	{
605*e4b17023SJohn Marino 	  *r = *a;
606*e4b17023SJohn Marino 	  r->sign = sign;
607*e4b17023SJohn Marino 	  return true;
608*e4b17023SJohn Marino 	}
609*e4b17023SJohn Marino 
610*e4b17023SJohn Marino       inexact |= sticky_rshift_significand (&t, b, dexp);
611*e4b17023SJohn Marino       b = &t;
612*e4b17023SJohn Marino     }
613*e4b17023SJohn Marino 
614*e4b17023SJohn Marino   if (subtract_p)
615*e4b17023SJohn Marino     {
616*e4b17023SJohn Marino       if (sub_significands (r, a, b, inexact))
617*e4b17023SJohn Marino 	{
618*e4b17023SJohn Marino 	  /* We got a borrow out of the subtraction.  That means that
619*e4b17023SJohn Marino 	     A and B had the same exponent, and B had the larger
620*e4b17023SJohn Marino 	     significand.  We need to swap the sign and negate the
621*e4b17023SJohn Marino 	     significand.  */
622*e4b17023SJohn Marino 	  sign ^= 1;
623*e4b17023SJohn Marino 	  neg_significand (r, r);
624*e4b17023SJohn Marino 	}
625*e4b17023SJohn Marino     }
626*e4b17023SJohn Marino   else
627*e4b17023SJohn Marino     {
628*e4b17023SJohn Marino       if (add_significands (r, a, b))
629*e4b17023SJohn Marino 	{
630*e4b17023SJohn Marino 	  /* We got carry out of the addition.  This means we need to
631*e4b17023SJohn Marino 	     shift the significand back down one bit and increase the
632*e4b17023SJohn Marino 	     exponent.  */
633*e4b17023SJohn Marino 	  inexact |= sticky_rshift_significand (r, r, 1);
634*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] |= SIG_MSB;
635*e4b17023SJohn Marino 	  if (++exp > MAX_EXP)
636*e4b17023SJohn Marino 	    {
637*e4b17023SJohn Marino 	      get_inf (r, sign);
638*e4b17023SJohn Marino 	      return true;
639*e4b17023SJohn Marino 	    }
640*e4b17023SJohn Marino 	}
641*e4b17023SJohn Marino     }
642*e4b17023SJohn Marino 
643*e4b17023SJohn Marino   r->cl = rvc_normal;
644*e4b17023SJohn Marino   r->sign = sign;
645*e4b17023SJohn Marino   SET_REAL_EXP (r, exp);
646*e4b17023SJohn Marino   /* Zero out the remaining fields.  */
647*e4b17023SJohn Marino   r->signalling = 0;
648*e4b17023SJohn Marino   r->canonical = 0;
649*e4b17023SJohn Marino   r->decimal = 0;
650*e4b17023SJohn Marino 
651*e4b17023SJohn Marino   /* Re-normalize the result.  */
652*e4b17023SJohn Marino   normalize (r);
653*e4b17023SJohn Marino 
654*e4b17023SJohn Marino   /* Special case: if the subtraction results in zero, the result
655*e4b17023SJohn Marino      is positive.  */
656*e4b17023SJohn Marino   if (r->cl == rvc_zero)
657*e4b17023SJohn Marino     r->sign = 0;
658*e4b17023SJohn Marino   else
659*e4b17023SJohn Marino     r->sig[0] |= inexact;
660*e4b17023SJohn Marino 
661*e4b17023SJohn Marino   return inexact;
662*e4b17023SJohn Marino }
663*e4b17023SJohn Marino 
664*e4b17023SJohn Marino /* Calculate R = A * B.  Return true if the result may be inexact.  */
665*e4b17023SJohn Marino 
666*e4b17023SJohn Marino static bool
do_multiply(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a,const REAL_VALUE_TYPE * b)667*e4b17023SJohn Marino do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
668*e4b17023SJohn Marino 	     const REAL_VALUE_TYPE *b)
669*e4b17023SJohn Marino {
670*e4b17023SJohn Marino   REAL_VALUE_TYPE u, t, *rr;
671*e4b17023SJohn Marino   unsigned int i, j, k;
672*e4b17023SJohn Marino   int sign = a->sign ^ b->sign;
673*e4b17023SJohn Marino   bool inexact = false;
674*e4b17023SJohn Marino 
675*e4b17023SJohn Marino   switch (CLASS2 (a->cl, b->cl))
676*e4b17023SJohn Marino     {
677*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_zero):
678*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_normal):
679*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_zero):
680*e4b17023SJohn Marino       /* +-0 * ANY = 0 with appropriate sign.  */
681*e4b17023SJohn Marino       get_zero (r, sign);
682*e4b17023SJohn Marino       return false;
683*e4b17023SJohn Marino 
684*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_nan):
685*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_nan):
686*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_nan):
687*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_nan):
688*e4b17023SJohn Marino       /* ANY * NaN = NaN.  */
689*e4b17023SJohn Marino       *r = *b;
690*e4b17023SJohn Marino       r->sign = sign;
691*e4b17023SJohn Marino       return false;
692*e4b17023SJohn Marino 
693*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_zero):
694*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_normal):
695*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_inf):
696*e4b17023SJohn Marino       /* NaN * ANY = NaN.  */
697*e4b17023SJohn Marino       *r = *a;
698*e4b17023SJohn Marino       r->sign = sign;
699*e4b17023SJohn Marino       return false;
700*e4b17023SJohn Marino 
701*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_inf):
702*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_zero):
703*e4b17023SJohn Marino       /* 0 * Inf = NaN */
704*e4b17023SJohn Marino       get_canonical_qnan (r, sign);
705*e4b17023SJohn Marino       return false;
706*e4b17023SJohn Marino 
707*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_inf):
708*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_inf):
709*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_normal):
710*e4b17023SJohn Marino       /* Inf * Inf = Inf, R * Inf = Inf */
711*e4b17023SJohn Marino       get_inf (r, sign);
712*e4b17023SJohn Marino       return false;
713*e4b17023SJohn Marino 
714*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_normal):
715*e4b17023SJohn Marino       break;
716*e4b17023SJohn Marino 
717*e4b17023SJohn Marino     default:
718*e4b17023SJohn Marino       gcc_unreachable ();
719*e4b17023SJohn Marino     }
720*e4b17023SJohn Marino 
721*e4b17023SJohn Marino   if (r == a || r == b)
722*e4b17023SJohn Marino     rr = &t;
723*e4b17023SJohn Marino   else
724*e4b17023SJohn Marino     rr = r;
725*e4b17023SJohn Marino   get_zero (rr, 0);
726*e4b17023SJohn Marino 
727*e4b17023SJohn Marino   /* Collect all the partial products.  Since we don't have sure access
728*e4b17023SJohn Marino      to a widening multiply, we split each long into two half-words.
729*e4b17023SJohn Marino 
730*e4b17023SJohn Marino      Consider the long-hand form of a four half-word multiplication:
731*e4b17023SJohn Marino 
732*e4b17023SJohn Marino 		 A  B  C  D
733*e4b17023SJohn Marino 	      *  E  F  G  H
734*e4b17023SJohn Marino 	     --------------
735*e4b17023SJohn Marino 	        DE DF DG DH
736*e4b17023SJohn Marino 	     CE CF CG CH
737*e4b17023SJohn Marino 	  BE BF BG BH
738*e4b17023SJohn Marino        AE AF AG AH
739*e4b17023SJohn Marino 
740*e4b17023SJohn Marino      We construct partial products of the widened half-word products
741*e4b17023SJohn Marino      that are known to not overlap, e.g. DF+DH.  Each such partial
742*e4b17023SJohn Marino      product is given its proper exponent, which allows us to sum them
743*e4b17023SJohn Marino      and obtain the finished product.  */
744*e4b17023SJohn Marino 
745*e4b17023SJohn Marino   for (i = 0; i < SIGSZ * 2; ++i)
746*e4b17023SJohn Marino     {
747*e4b17023SJohn Marino       unsigned long ai = a->sig[i / 2];
748*e4b17023SJohn Marino       if (i & 1)
749*e4b17023SJohn Marino 	ai >>= HOST_BITS_PER_LONG / 2;
750*e4b17023SJohn Marino       else
751*e4b17023SJohn Marino 	ai &= ((unsigned long)1 << (HOST_BITS_PER_LONG / 2)) - 1;
752*e4b17023SJohn Marino 
753*e4b17023SJohn Marino       if (ai == 0)
754*e4b17023SJohn Marino 	continue;
755*e4b17023SJohn Marino 
756*e4b17023SJohn Marino       for (j = 0; j < 2; ++j)
757*e4b17023SJohn Marino 	{
758*e4b17023SJohn Marino 	  int exp = (REAL_EXP (a) - (2*SIGSZ-1-i)*(HOST_BITS_PER_LONG/2)
759*e4b17023SJohn Marino 		     + (REAL_EXP (b) - (1-j)*(HOST_BITS_PER_LONG/2)));
760*e4b17023SJohn Marino 
761*e4b17023SJohn Marino 	  if (exp > MAX_EXP)
762*e4b17023SJohn Marino 	    {
763*e4b17023SJohn Marino 	      get_inf (r, sign);
764*e4b17023SJohn Marino 	      return true;
765*e4b17023SJohn Marino 	    }
766*e4b17023SJohn Marino 	  if (exp < -MAX_EXP)
767*e4b17023SJohn Marino 	    {
768*e4b17023SJohn Marino 	      /* Would underflow to zero, which we shouldn't bother adding.  */
769*e4b17023SJohn Marino 	      inexact = true;
770*e4b17023SJohn Marino 	      continue;
771*e4b17023SJohn Marino 	    }
772*e4b17023SJohn Marino 
773*e4b17023SJohn Marino 	  memset (&u, 0, sizeof (u));
774*e4b17023SJohn Marino 	  u.cl = rvc_normal;
775*e4b17023SJohn Marino 	  SET_REAL_EXP (&u, exp);
776*e4b17023SJohn Marino 
777*e4b17023SJohn Marino 	  for (k = j; k < SIGSZ * 2; k += 2)
778*e4b17023SJohn Marino 	    {
779*e4b17023SJohn Marino 	      unsigned long bi = b->sig[k / 2];
780*e4b17023SJohn Marino 	      if (k & 1)
781*e4b17023SJohn Marino 		bi >>= HOST_BITS_PER_LONG / 2;
782*e4b17023SJohn Marino 	      else
783*e4b17023SJohn Marino 		bi &= ((unsigned long)1 << (HOST_BITS_PER_LONG / 2)) - 1;
784*e4b17023SJohn Marino 
785*e4b17023SJohn Marino 	      u.sig[k / 2] = ai * bi;
786*e4b17023SJohn Marino 	    }
787*e4b17023SJohn Marino 
788*e4b17023SJohn Marino 	  normalize (&u);
789*e4b17023SJohn Marino 	  inexact |= do_add (rr, rr, &u, 0);
790*e4b17023SJohn Marino 	}
791*e4b17023SJohn Marino     }
792*e4b17023SJohn Marino 
793*e4b17023SJohn Marino   rr->sign = sign;
794*e4b17023SJohn Marino   if (rr != r)
795*e4b17023SJohn Marino     *r = t;
796*e4b17023SJohn Marino 
797*e4b17023SJohn Marino   return inexact;
798*e4b17023SJohn Marino }
799*e4b17023SJohn Marino 
800*e4b17023SJohn Marino /* Calculate R = A / B.  Return true if the result may be inexact.  */
801*e4b17023SJohn Marino 
802*e4b17023SJohn Marino static bool
do_divide(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a,const REAL_VALUE_TYPE * b)803*e4b17023SJohn Marino do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
804*e4b17023SJohn Marino 	   const REAL_VALUE_TYPE *b)
805*e4b17023SJohn Marino {
806*e4b17023SJohn Marino   int exp, sign = a->sign ^ b->sign;
807*e4b17023SJohn Marino   REAL_VALUE_TYPE t, *rr;
808*e4b17023SJohn Marino   bool inexact;
809*e4b17023SJohn Marino 
810*e4b17023SJohn Marino   switch (CLASS2 (a->cl, b->cl))
811*e4b17023SJohn Marino     {
812*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_zero):
813*e4b17023SJohn Marino       /* 0 / 0 = NaN.  */
814*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_inf):
815*e4b17023SJohn Marino       /* Inf / Inf = NaN.  */
816*e4b17023SJohn Marino       get_canonical_qnan (r, sign);
817*e4b17023SJohn Marino       return false;
818*e4b17023SJohn Marino 
819*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_normal):
820*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_inf):
821*e4b17023SJohn Marino       /* 0 / ANY = 0.  */
822*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_inf):
823*e4b17023SJohn Marino       /* R / Inf = 0.  */
824*e4b17023SJohn Marino       get_zero (r, sign);
825*e4b17023SJohn Marino       return false;
826*e4b17023SJohn Marino 
827*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_zero):
828*e4b17023SJohn Marino       /* R / 0 = Inf.  */
829*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_zero):
830*e4b17023SJohn Marino       /* Inf / 0 = Inf.  */
831*e4b17023SJohn Marino       get_inf (r, sign);
832*e4b17023SJohn Marino       return false;
833*e4b17023SJohn Marino 
834*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_nan):
835*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_nan):
836*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_nan):
837*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_nan):
838*e4b17023SJohn Marino       /* ANY / NaN = NaN.  */
839*e4b17023SJohn Marino       *r = *b;
840*e4b17023SJohn Marino       r->sign = sign;
841*e4b17023SJohn Marino       return false;
842*e4b17023SJohn Marino 
843*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_zero):
844*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_normal):
845*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_inf):
846*e4b17023SJohn Marino       /* NaN / ANY = NaN.  */
847*e4b17023SJohn Marino       *r = *a;
848*e4b17023SJohn Marino       r->sign = sign;
849*e4b17023SJohn Marino       return false;
850*e4b17023SJohn Marino 
851*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_normal):
852*e4b17023SJohn Marino       /* Inf / R = Inf.  */
853*e4b17023SJohn Marino       get_inf (r, sign);
854*e4b17023SJohn Marino       return false;
855*e4b17023SJohn Marino 
856*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_normal):
857*e4b17023SJohn Marino       break;
858*e4b17023SJohn Marino 
859*e4b17023SJohn Marino     default:
860*e4b17023SJohn Marino       gcc_unreachable ();
861*e4b17023SJohn Marino     }
862*e4b17023SJohn Marino 
863*e4b17023SJohn Marino   if (r == a || r == b)
864*e4b17023SJohn Marino     rr = &t;
865*e4b17023SJohn Marino   else
866*e4b17023SJohn Marino     rr = r;
867*e4b17023SJohn Marino 
868*e4b17023SJohn Marino   /* Make sure all fields in the result are initialized.  */
869*e4b17023SJohn Marino   get_zero (rr, 0);
870*e4b17023SJohn Marino   rr->cl = rvc_normal;
871*e4b17023SJohn Marino   rr->sign = sign;
872*e4b17023SJohn Marino 
873*e4b17023SJohn Marino   exp = REAL_EXP (a) - REAL_EXP (b) + 1;
874*e4b17023SJohn Marino   if (exp > MAX_EXP)
875*e4b17023SJohn Marino     {
876*e4b17023SJohn Marino       get_inf (r, sign);
877*e4b17023SJohn Marino       return true;
878*e4b17023SJohn Marino     }
879*e4b17023SJohn Marino   if (exp < -MAX_EXP)
880*e4b17023SJohn Marino     {
881*e4b17023SJohn Marino       get_zero (r, sign);
882*e4b17023SJohn Marino       return true;
883*e4b17023SJohn Marino     }
884*e4b17023SJohn Marino   SET_REAL_EXP (rr, exp);
885*e4b17023SJohn Marino 
886*e4b17023SJohn Marino   inexact = div_significands (rr, a, b);
887*e4b17023SJohn Marino 
888*e4b17023SJohn Marino   /* Re-normalize the result.  */
889*e4b17023SJohn Marino   normalize (rr);
890*e4b17023SJohn Marino   rr->sig[0] |= inexact;
891*e4b17023SJohn Marino 
892*e4b17023SJohn Marino   if (rr != r)
893*e4b17023SJohn Marino     *r = t;
894*e4b17023SJohn Marino 
895*e4b17023SJohn Marino   return inexact;
896*e4b17023SJohn Marino }
897*e4b17023SJohn Marino 
898*e4b17023SJohn Marino /* Return a tri-state comparison of A vs B.  Return NAN_RESULT if
899*e4b17023SJohn Marino    one of the two operands is a NaN.  */
900*e4b17023SJohn Marino 
901*e4b17023SJohn Marino static int
do_compare(const REAL_VALUE_TYPE * a,const REAL_VALUE_TYPE * b,int nan_result)902*e4b17023SJohn Marino do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
903*e4b17023SJohn Marino 	    int nan_result)
904*e4b17023SJohn Marino {
905*e4b17023SJohn Marino   int ret;
906*e4b17023SJohn Marino 
907*e4b17023SJohn Marino   switch (CLASS2 (a->cl, b->cl))
908*e4b17023SJohn Marino     {
909*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_zero):
910*e4b17023SJohn Marino       /* Sign of zero doesn't matter for compares.  */
911*e4b17023SJohn Marino       return 0;
912*e4b17023SJohn Marino 
913*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_zero):
914*e4b17023SJohn Marino       /* Decimal float zero is special and uses rvc_normal, not rvc_zero.  */
915*e4b17023SJohn Marino       if (a->decimal)
916*e4b17023SJohn Marino 	return decimal_do_compare (a, b, nan_result);
917*e4b17023SJohn Marino       /* Fall through.  */
918*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_zero):
919*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_normal):
920*e4b17023SJohn Marino       return (a->sign ? -1 : 1);
921*e4b17023SJohn Marino 
922*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_inf):
923*e4b17023SJohn Marino       return -a->sign - -b->sign;
924*e4b17023SJohn Marino 
925*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_normal):
926*e4b17023SJohn Marino       /* Decimal float zero is special and uses rvc_normal, not rvc_zero.  */
927*e4b17023SJohn Marino       if (b->decimal)
928*e4b17023SJohn Marino 	return decimal_do_compare (a, b, nan_result);
929*e4b17023SJohn Marino       /* Fall through.  */
930*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_inf):
931*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_inf):
932*e4b17023SJohn Marino       return (b->sign ? 1 : -1);
933*e4b17023SJohn Marino 
934*e4b17023SJohn Marino     case CLASS2 (rvc_zero, rvc_nan):
935*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_nan):
936*e4b17023SJohn Marino     case CLASS2 (rvc_inf, rvc_nan):
937*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_nan):
938*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_zero):
939*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_normal):
940*e4b17023SJohn Marino     case CLASS2 (rvc_nan, rvc_inf):
941*e4b17023SJohn Marino       return nan_result;
942*e4b17023SJohn Marino 
943*e4b17023SJohn Marino     case CLASS2 (rvc_normal, rvc_normal):
944*e4b17023SJohn Marino       break;
945*e4b17023SJohn Marino 
946*e4b17023SJohn Marino     default:
947*e4b17023SJohn Marino       gcc_unreachable ();
948*e4b17023SJohn Marino     }
949*e4b17023SJohn Marino 
950*e4b17023SJohn Marino   if (a->sign != b->sign)
951*e4b17023SJohn Marino     return -a->sign - -b->sign;
952*e4b17023SJohn Marino 
953*e4b17023SJohn Marino   if (a->decimal || b->decimal)
954*e4b17023SJohn Marino     return decimal_do_compare (a, b, nan_result);
955*e4b17023SJohn Marino 
956*e4b17023SJohn Marino   if (REAL_EXP (a) > REAL_EXP (b))
957*e4b17023SJohn Marino     ret = 1;
958*e4b17023SJohn Marino   else if (REAL_EXP (a) < REAL_EXP (b))
959*e4b17023SJohn Marino     ret = -1;
960*e4b17023SJohn Marino   else
961*e4b17023SJohn Marino     ret = cmp_significands (a, b);
962*e4b17023SJohn Marino 
963*e4b17023SJohn Marino   return (a->sign ? -ret : ret);
964*e4b17023SJohn Marino }
965*e4b17023SJohn Marino 
966*e4b17023SJohn Marino /* Return A truncated to an integral value toward zero.  */
967*e4b17023SJohn Marino 
968*e4b17023SJohn Marino static void
do_fix_trunc(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * a)969*e4b17023SJohn Marino do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
970*e4b17023SJohn Marino {
971*e4b17023SJohn Marino   *r = *a;
972*e4b17023SJohn Marino 
973*e4b17023SJohn Marino   switch (r->cl)
974*e4b17023SJohn Marino     {
975*e4b17023SJohn Marino     case rvc_zero:
976*e4b17023SJohn Marino     case rvc_inf:
977*e4b17023SJohn Marino     case rvc_nan:
978*e4b17023SJohn Marino       break;
979*e4b17023SJohn Marino 
980*e4b17023SJohn Marino     case rvc_normal:
981*e4b17023SJohn Marino       if (r->decimal)
982*e4b17023SJohn Marino 	{
983*e4b17023SJohn Marino 	  decimal_do_fix_trunc (r, a);
984*e4b17023SJohn Marino 	  return;
985*e4b17023SJohn Marino 	}
986*e4b17023SJohn Marino       if (REAL_EXP (r) <= 0)
987*e4b17023SJohn Marino 	get_zero (r, r->sign);
988*e4b17023SJohn Marino       else if (REAL_EXP (r) < SIGNIFICAND_BITS)
989*e4b17023SJohn Marino 	clear_significand_below (r, SIGNIFICAND_BITS - REAL_EXP (r));
990*e4b17023SJohn Marino       break;
991*e4b17023SJohn Marino 
992*e4b17023SJohn Marino     default:
993*e4b17023SJohn Marino       gcc_unreachable ();
994*e4b17023SJohn Marino     }
995*e4b17023SJohn Marino }
996*e4b17023SJohn Marino 
997*e4b17023SJohn Marino /* Perform the binary or unary operation described by CODE.
998*e4b17023SJohn Marino    For a unary operation, leave OP1 NULL.  This function returns
999*e4b17023SJohn Marino    true if the result may be inexact due to loss of precision.  */
1000*e4b17023SJohn Marino 
1001*e4b17023SJohn Marino bool
real_arithmetic(REAL_VALUE_TYPE * r,int icode,const REAL_VALUE_TYPE * op0,const REAL_VALUE_TYPE * op1)1002*e4b17023SJohn Marino real_arithmetic (REAL_VALUE_TYPE *r, int icode, const REAL_VALUE_TYPE *op0,
1003*e4b17023SJohn Marino 		 const REAL_VALUE_TYPE *op1)
1004*e4b17023SJohn Marino {
1005*e4b17023SJohn Marino   enum tree_code code = (enum tree_code) icode;
1006*e4b17023SJohn Marino 
1007*e4b17023SJohn Marino   if (op0->decimal || (op1 && op1->decimal))
1008*e4b17023SJohn Marino     return decimal_real_arithmetic (r, code, op0, op1);
1009*e4b17023SJohn Marino 
1010*e4b17023SJohn Marino   switch (code)
1011*e4b17023SJohn Marino     {
1012*e4b17023SJohn Marino     case PLUS_EXPR:
1013*e4b17023SJohn Marino       /* Clear any padding areas in *r if it isn't equal to one of the
1014*e4b17023SJohn Marino 	 operands so that we can later do bitwise comparisons later on.  */
1015*e4b17023SJohn Marino       if (r != op0 && r != op1)
1016*e4b17023SJohn Marino 	memset (r, '\0', sizeof (*r));
1017*e4b17023SJohn Marino       return do_add (r, op0, op1, 0);
1018*e4b17023SJohn Marino 
1019*e4b17023SJohn Marino     case MINUS_EXPR:
1020*e4b17023SJohn Marino       if (r != op0 && r != op1)
1021*e4b17023SJohn Marino 	memset (r, '\0', sizeof (*r));
1022*e4b17023SJohn Marino       return do_add (r, op0, op1, 1);
1023*e4b17023SJohn Marino 
1024*e4b17023SJohn Marino     case MULT_EXPR:
1025*e4b17023SJohn Marino       if (r != op0 && r != op1)
1026*e4b17023SJohn Marino 	memset (r, '\0', sizeof (*r));
1027*e4b17023SJohn Marino       return do_multiply (r, op0, op1);
1028*e4b17023SJohn Marino 
1029*e4b17023SJohn Marino     case RDIV_EXPR:
1030*e4b17023SJohn Marino       if (r != op0 && r != op1)
1031*e4b17023SJohn Marino 	memset (r, '\0', sizeof (*r));
1032*e4b17023SJohn Marino       return do_divide (r, op0, op1);
1033*e4b17023SJohn Marino 
1034*e4b17023SJohn Marino     case MIN_EXPR:
1035*e4b17023SJohn Marino       if (op1->cl == rvc_nan)
1036*e4b17023SJohn Marino 	*r = *op1;
1037*e4b17023SJohn Marino       else if (do_compare (op0, op1, -1) < 0)
1038*e4b17023SJohn Marino 	*r = *op0;
1039*e4b17023SJohn Marino       else
1040*e4b17023SJohn Marino 	*r = *op1;
1041*e4b17023SJohn Marino       break;
1042*e4b17023SJohn Marino 
1043*e4b17023SJohn Marino     case MAX_EXPR:
1044*e4b17023SJohn Marino       if (op1->cl == rvc_nan)
1045*e4b17023SJohn Marino 	*r = *op1;
1046*e4b17023SJohn Marino       else if (do_compare (op0, op1, 1) < 0)
1047*e4b17023SJohn Marino 	*r = *op1;
1048*e4b17023SJohn Marino       else
1049*e4b17023SJohn Marino 	*r = *op0;
1050*e4b17023SJohn Marino       break;
1051*e4b17023SJohn Marino 
1052*e4b17023SJohn Marino     case NEGATE_EXPR:
1053*e4b17023SJohn Marino       *r = *op0;
1054*e4b17023SJohn Marino       r->sign ^= 1;
1055*e4b17023SJohn Marino       break;
1056*e4b17023SJohn Marino 
1057*e4b17023SJohn Marino     case ABS_EXPR:
1058*e4b17023SJohn Marino       *r = *op0;
1059*e4b17023SJohn Marino       r->sign = 0;
1060*e4b17023SJohn Marino       break;
1061*e4b17023SJohn Marino 
1062*e4b17023SJohn Marino     case FIX_TRUNC_EXPR:
1063*e4b17023SJohn Marino       do_fix_trunc (r, op0);
1064*e4b17023SJohn Marino       break;
1065*e4b17023SJohn Marino 
1066*e4b17023SJohn Marino     default:
1067*e4b17023SJohn Marino       gcc_unreachable ();
1068*e4b17023SJohn Marino     }
1069*e4b17023SJohn Marino   return false;
1070*e4b17023SJohn Marino }
1071*e4b17023SJohn Marino 
1072*e4b17023SJohn Marino REAL_VALUE_TYPE
real_value_negate(const REAL_VALUE_TYPE * op0)1073*e4b17023SJohn Marino real_value_negate (const REAL_VALUE_TYPE *op0)
1074*e4b17023SJohn Marino {
1075*e4b17023SJohn Marino   REAL_VALUE_TYPE r;
1076*e4b17023SJohn Marino   real_arithmetic (&r, NEGATE_EXPR, op0, NULL);
1077*e4b17023SJohn Marino   return r;
1078*e4b17023SJohn Marino }
1079*e4b17023SJohn Marino 
1080*e4b17023SJohn Marino REAL_VALUE_TYPE
real_value_abs(const REAL_VALUE_TYPE * op0)1081*e4b17023SJohn Marino real_value_abs (const REAL_VALUE_TYPE *op0)
1082*e4b17023SJohn Marino {
1083*e4b17023SJohn Marino   REAL_VALUE_TYPE r;
1084*e4b17023SJohn Marino   real_arithmetic (&r, ABS_EXPR, op0, NULL);
1085*e4b17023SJohn Marino   return r;
1086*e4b17023SJohn Marino }
1087*e4b17023SJohn Marino 
1088*e4b17023SJohn Marino bool
real_compare(int icode,const REAL_VALUE_TYPE * op0,const REAL_VALUE_TYPE * op1)1089*e4b17023SJohn Marino real_compare (int icode, const REAL_VALUE_TYPE *op0,
1090*e4b17023SJohn Marino 	      const REAL_VALUE_TYPE *op1)
1091*e4b17023SJohn Marino {
1092*e4b17023SJohn Marino   enum tree_code code = (enum tree_code) icode;
1093*e4b17023SJohn Marino 
1094*e4b17023SJohn Marino   switch (code)
1095*e4b17023SJohn Marino     {
1096*e4b17023SJohn Marino     case LT_EXPR:
1097*e4b17023SJohn Marino       return do_compare (op0, op1, 1) < 0;
1098*e4b17023SJohn Marino     case LE_EXPR:
1099*e4b17023SJohn Marino       return do_compare (op0, op1, 1) <= 0;
1100*e4b17023SJohn Marino     case GT_EXPR:
1101*e4b17023SJohn Marino       return do_compare (op0, op1, -1) > 0;
1102*e4b17023SJohn Marino     case GE_EXPR:
1103*e4b17023SJohn Marino       return do_compare (op0, op1, -1) >= 0;
1104*e4b17023SJohn Marino     case EQ_EXPR:
1105*e4b17023SJohn Marino       return do_compare (op0, op1, -1) == 0;
1106*e4b17023SJohn Marino     case NE_EXPR:
1107*e4b17023SJohn Marino       return do_compare (op0, op1, -1) != 0;
1108*e4b17023SJohn Marino     case UNORDERED_EXPR:
1109*e4b17023SJohn Marino       return op0->cl == rvc_nan || op1->cl == rvc_nan;
1110*e4b17023SJohn Marino     case ORDERED_EXPR:
1111*e4b17023SJohn Marino       return op0->cl != rvc_nan && op1->cl != rvc_nan;
1112*e4b17023SJohn Marino     case UNLT_EXPR:
1113*e4b17023SJohn Marino       return do_compare (op0, op1, -1) < 0;
1114*e4b17023SJohn Marino     case UNLE_EXPR:
1115*e4b17023SJohn Marino       return do_compare (op0, op1, -1) <= 0;
1116*e4b17023SJohn Marino     case UNGT_EXPR:
1117*e4b17023SJohn Marino       return do_compare (op0, op1, 1) > 0;
1118*e4b17023SJohn Marino     case UNGE_EXPR:
1119*e4b17023SJohn Marino       return do_compare (op0, op1, 1) >= 0;
1120*e4b17023SJohn Marino     case UNEQ_EXPR:
1121*e4b17023SJohn Marino       return do_compare (op0, op1, 0) == 0;
1122*e4b17023SJohn Marino     case LTGT_EXPR:
1123*e4b17023SJohn Marino       return do_compare (op0, op1, 0) != 0;
1124*e4b17023SJohn Marino 
1125*e4b17023SJohn Marino     default:
1126*e4b17023SJohn Marino       gcc_unreachable ();
1127*e4b17023SJohn Marino     }
1128*e4b17023SJohn Marino }
1129*e4b17023SJohn Marino 
1130*e4b17023SJohn Marino /* Return floor log2(R).  */
1131*e4b17023SJohn Marino 
1132*e4b17023SJohn Marino int
real_exponent(const REAL_VALUE_TYPE * r)1133*e4b17023SJohn Marino real_exponent (const REAL_VALUE_TYPE *r)
1134*e4b17023SJohn Marino {
1135*e4b17023SJohn Marino   switch (r->cl)
1136*e4b17023SJohn Marino     {
1137*e4b17023SJohn Marino     case rvc_zero:
1138*e4b17023SJohn Marino       return 0;
1139*e4b17023SJohn Marino     case rvc_inf:
1140*e4b17023SJohn Marino     case rvc_nan:
1141*e4b17023SJohn Marino       return (unsigned int)-1 >> 1;
1142*e4b17023SJohn Marino     case rvc_normal:
1143*e4b17023SJohn Marino       return REAL_EXP (r);
1144*e4b17023SJohn Marino     default:
1145*e4b17023SJohn Marino       gcc_unreachable ();
1146*e4b17023SJohn Marino     }
1147*e4b17023SJohn Marino }
1148*e4b17023SJohn Marino 
1149*e4b17023SJohn Marino /* R = OP0 * 2**EXP.  */
1150*e4b17023SJohn Marino 
1151*e4b17023SJohn Marino void
real_ldexp(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * op0,int exp)1152*e4b17023SJohn Marino real_ldexp (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0, int exp)
1153*e4b17023SJohn Marino {
1154*e4b17023SJohn Marino   *r = *op0;
1155*e4b17023SJohn Marino   switch (r->cl)
1156*e4b17023SJohn Marino     {
1157*e4b17023SJohn Marino     case rvc_zero:
1158*e4b17023SJohn Marino     case rvc_inf:
1159*e4b17023SJohn Marino     case rvc_nan:
1160*e4b17023SJohn Marino       break;
1161*e4b17023SJohn Marino 
1162*e4b17023SJohn Marino     case rvc_normal:
1163*e4b17023SJohn Marino       exp += REAL_EXP (op0);
1164*e4b17023SJohn Marino       if (exp > MAX_EXP)
1165*e4b17023SJohn Marino 	get_inf (r, r->sign);
1166*e4b17023SJohn Marino       else if (exp < -MAX_EXP)
1167*e4b17023SJohn Marino 	get_zero (r, r->sign);
1168*e4b17023SJohn Marino       else
1169*e4b17023SJohn Marino 	SET_REAL_EXP (r, exp);
1170*e4b17023SJohn Marino       break;
1171*e4b17023SJohn Marino 
1172*e4b17023SJohn Marino     default:
1173*e4b17023SJohn Marino       gcc_unreachable ();
1174*e4b17023SJohn Marino     }
1175*e4b17023SJohn Marino }
1176*e4b17023SJohn Marino 
1177*e4b17023SJohn Marino /* Determine whether a floating-point value X is infinite.  */
1178*e4b17023SJohn Marino 
1179*e4b17023SJohn Marino bool
real_isinf(const REAL_VALUE_TYPE * r)1180*e4b17023SJohn Marino real_isinf (const REAL_VALUE_TYPE *r)
1181*e4b17023SJohn Marino {
1182*e4b17023SJohn Marino   return (r->cl == rvc_inf);
1183*e4b17023SJohn Marino }
1184*e4b17023SJohn Marino 
1185*e4b17023SJohn Marino /* Determine whether a floating-point value X is a NaN.  */
1186*e4b17023SJohn Marino 
1187*e4b17023SJohn Marino bool
real_isnan(const REAL_VALUE_TYPE * r)1188*e4b17023SJohn Marino real_isnan (const REAL_VALUE_TYPE *r)
1189*e4b17023SJohn Marino {
1190*e4b17023SJohn Marino   return (r->cl == rvc_nan);
1191*e4b17023SJohn Marino }
1192*e4b17023SJohn Marino 
1193*e4b17023SJohn Marino /* Determine whether a floating-point value X is finite.  */
1194*e4b17023SJohn Marino 
1195*e4b17023SJohn Marino bool
real_isfinite(const REAL_VALUE_TYPE * r)1196*e4b17023SJohn Marino real_isfinite (const REAL_VALUE_TYPE *r)
1197*e4b17023SJohn Marino {
1198*e4b17023SJohn Marino   return (r->cl != rvc_nan) && (r->cl != rvc_inf);
1199*e4b17023SJohn Marino }
1200*e4b17023SJohn Marino 
1201*e4b17023SJohn Marino /* Determine whether a floating-point value X is negative.  */
1202*e4b17023SJohn Marino 
1203*e4b17023SJohn Marino bool
real_isneg(const REAL_VALUE_TYPE * r)1204*e4b17023SJohn Marino real_isneg (const REAL_VALUE_TYPE *r)
1205*e4b17023SJohn Marino {
1206*e4b17023SJohn Marino   return r->sign;
1207*e4b17023SJohn Marino }
1208*e4b17023SJohn Marino 
1209*e4b17023SJohn Marino /* Determine whether a floating-point value X is minus zero.  */
1210*e4b17023SJohn Marino 
1211*e4b17023SJohn Marino bool
real_isnegzero(const REAL_VALUE_TYPE * r)1212*e4b17023SJohn Marino real_isnegzero (const REAL_VALUE_TYPE *r)
1213*e4b17023SJohn Marino {
1214*e4b17023SJohn Marino   return r->sign && r->cl == rvc_zero;
1215*e4b17023SJohn Marino }
1216*e4b17023SJohn Marino 
1217*e4b17023SJohn Marino /* Compare two floating-point objects for bitwise identity.  */
1218*e4b17023SJohn Marino 
1219*e4b17023SJohn Marino bool
real_identical(const REAL_VALUE_TYPE * a,const REAL_VALUE_TYPE * b)1220*e4b17023SJohn Marino real_identical (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
1221*e4b17023SJohn Marino {
1222*e4b17023SJohn Marino   int i;
1223*e4b17023SJohn Marino 
1224*e4b17023SJohn Marino   if (a->cl != b->cl)
1225*e4b17023SJohn Marino     return false;
1226*e4b17023SJohn Marino   if (a->sign != b->sign)
1227*e4b17023SJohn Marino     return false;
1228*e4b17023SJohn Marino 
1229*e4b17023SJohn Marino   switch (a->cl)
1230*e4b17023SJohn Marino     {
1231*e4b17023SJohn Marino     case rvc_zero:
1232*e4b17023SJohn Marino     case rvc_inf:
1233*e4b17023SJohn Marino       return true;
1234*e4b17023SJohn Marino 
1235*e4b17023SJohn Marino     case rvc_normal:
1236*e4b17023SJohn Marino       if (a->decimal != b->decimal)
1237*e4b17023SJohn Marino         return false;
1238*e4b17023SJohn Marino       if (REAL_EXP (a) != REAL_EXP (b))
1239*e4b17023SJohn Marino 	return false;
1240*e4b17023SJohn Marino       break;
1241*e4b17023SJohn Marino 
1242*e4b17023SJohn Marino     case rvc_nan:
1243*e4b17023SJohn Marino       if (a->signalling != b->signalling)
1244*e4b17023SJohn Marino 	return false;
1245*e4b17023SJohn Marino       /* The significand is ignored for canonical NaNs.  */
1246*e4b17023SJohn Marino       if (a->canonical || b->canonical)
1247*e4b17023SJohn Marino 	return a->canonical == b->canonical;
1248*e4b17023SJohn Marino       break;
1249*e4b17023SJohn Marino 
1250*e4b17023SJohn Marino     default:
1251*e4b17023SJohn Marino       gcc_unreachable ();
1252*e4b17023SJohn Marino     }
1253*e4b17023SJohn Marino 
1254*e4b17023SJohn Marino   for (i = 0; i < SIGSZ; ++i)
1255*e4b17023SJohn Marino     if (a->sig[i] != b->sig[i])
1256*e4b17023SJohn Marino       return false;
1257*e4b17023SJohn Marino 
1258*e4b17023SJohn Marino   return true;
1259*e4b17023SJohn Marino }
1260*e4b17023SJohn Marino 
1261*e4b17023SJohn Marino /* Try to change R into its exact multiplicative inverse in machine
1262*e4b17023SJohn Marino    mode MODE.  Return true if successful.  */
1263*e4b17023SJohn Marino 
1264*e4b17023SJohn Marino bool
exact_real_inverse(enum machine_mode mode,REAL_VALUE_TYPE * r)1265*e4b17023SJohn Marino exact_real_inverse (enum machine_mode mode, REAL_VALUE_TYPE *r)
1266*e4b17023SJohn Marino {
1267*e4b17023SJohn Marino   const REAL_VALUE_TYPE *one = real_digit (1);
1268*e4b17023SJohn Marino   REAL_VALUE_TYPE u;
1269*e4b17023SJohn Marino   int i;
1270*e4b17023SJohn Marino 
1271*e4b17023SJohn Marino   if (r->cl != rvc_normal)
1272*e4b17023SJohn Marino     return false;
1273*e4b17023SJohn Marino 
1274*e4b17023SJohn Marino   /* Check for a power of two: all significand bits zero except the MSB.  */
1275*e4b17023SJohn Marino   for (i = 0; i < SIGSZ-1; ++i)
1276*e4b17023SJohn Marino     if (r->sig[i] != 0)
1277*e4b17023SJohn Marino       return false;
1278*e4b17023SJohn Marino   if (r->sig[SIGSZ-1] != SIG_MSB)
1279*e4b17023SJohn Marino     return false;
1280*e4b17023SJohn Marino 
1281*e4b17023SJohn Marino   /* Find the inverse and truncate to the required mode.  */
1282*e4b17023SJohn Marino   do_divide (&u, one, r);
1283*e4b17023SJohn Marino   real_convert (&u, mode, &u);
1284*e4b17023SJohn Marino 
1285*e4b17023SJohn Marino   /* The rounding may have overflowed.  */
1286*e4b17023SJohn Marino   if (u.cl != rvc_normal)
1287*e4b17023SJohn Marino     return false;
1288*e4b17023SJohn Marino   for (i = 0; i < SIGSZ-1; ++i)
1289*e4b17023SJohn Marino     if (u.sig[i] != 0)
1290*e4b17023SJohn Marino       return false;
1291*e4b17023SJohn Marino   if (u.sig[SIGSZ-1] != SIG_MSB)
1292*e4b17023SJohn Marino     return false;
1293*e4b17023SJohn Marino 
1294*e4b17023SJohn Marino   *r = u;
1295*e4b17023SJohn Marino   return true;
1296*e4b17023SJohn Marino }
1297*e4b17023SJohn Marino 
1298*e4b17023SJohn Marino /* Return true if arithmetic on values in IMODE that were promoted
1299*e4b17023SJohn Marino    from values in TMODE is equivalent to direct arithmetic on values
1300*e4b17023SJohn Marino    in TMODE.  */
1301*e4b17023SJohn Marino 
1302*e4b17023SJohn Marino bool
real_can_shorten_arithmetic(enum machine_mode imode,enum machine_mode tmode)1303*e4b17023SJohn Marino real_can_shorten_arithmetic (enum machine_mode imode, enum machine_mode tmode)
1304*e4b17023SJohn Marino {
1305*e4b17023SJohn Marino   const struct real_format *tfmt, *ifmt;
1306*e4b17023SJohn Marino   tfmt = REAL_MODE_FORMAT (tmode);
1307*e4b17023SJohn Marino   ifmt = REAL_MODE_FORMAT (imode);
1308*e4b17023SJohn Marino   /* These conditions are conservative rather than trying to catch the
1309*e4b17023SJohn Marino      exact boundary conditions; the main case to allow is IEEE float
1310*e4b17023SJohn Marino      and double.  */
1311*e4b17023SJohn Marino   return (ifmt->b == tfmt->b
1312*e4b17023SJohn Marino 	  && ifmt->p > 2 * tfmt->p
1313*e4b17023SJohn Marino 	  && ifmt->emin < 2 * tfmt->emin - tfmt->p - 2
1314*e4b17023SJohn Marino 	  && ifmt->emin < tfmt->emin - tfmt->emax - tfmt->p - 2
1315*e4b17023SJohn Marino 	  && ifmt->emax > 2 * tfmt->emax + 2
1316*e4b17023SJohn Marino 	  && ifmt->emax > tfmt->emax - tfmt->emin + tfmt->p + 2
1317*e4b17023SJohn Marino 	  && ifmt->round_towards_zero == tfmt->round_towards_zero
1318*e4b17023SJohn Marino 	  && (ifmt->has_sign_dependent_rounding
1319*e4b17023SJohn Marino 	      == tfmt->has_sign_dependent_rounding)
1320*e4b17023SJohn Marino 	  && ifmt->has_nans >= tfmt->has_nans
1321*e4b17023SJohn Marino 	  && ifmt->has_inf >= tfmt->has_inf
1322*e4b17023SJohn Marino 	  && ifmt->has_signed_zero >= tfmt->has_signed_zero
1323*e4b17023SJohn Marino 	  && !MODE_COMPOSITE_P (tmode)
1324*e4b17023SJohn Marino 	  && !MODE_COMPOSITE_P (imode));
1325*e4b17023SJohn Marino }
1326*e4b17023SJohn Marino 
1327*e4b17023SJohn Marino /* Render R as an integer.  */
1328*e4b17023SJohn Marino 
1329*e4b17023SJohn Marino HOST_WIDE_INT
real_to_integer(const REAL_VALUE_TYPE * r)1330*e4b17023SJohn Marino real_to_integer (const REAL_VALUE_TYPE *r)
1331*e4b17023SJohn Marino {
1332*e4b17023SJohn Marino   unsigned HOST_WIDE_INT i;
1333*e4b17023SJohn Marino 
1334*e4b17023SJohn Marino   switch (r->cl)
1335*e4b17023SJohn Marino     {
1336*e4b17023SJohn Marino     case rvc_zero:
1337*e4b17023SJohn Marino     underflow:
1338*e4b17023SJohn Marino       return 0;
1339*e4b17023SJohn Marino 
1340*e4b17023SJohn Marino     case rvc_inf:
1341*e4b17023SJohn Marino     case rvc_nan:
1342*e4b17023SJohn Marino     overflow:
1343*e4b17023SJohn Marino       i = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1);
1344*e4b17023SJohn Marino       if (!r->sign)
1345*e4b17023SJohn Marino 	i--;
1346*e4b17023SJohn Marino       return i;
1347*e4b17023SJohn Marino 
1348*e4b17023SJohn Marino     case rvc_normal:
1349*e4b17023SJohn Marino       if (r->decimal)
1350*e4b17023SJohn Marino 	return decimal_real_to_integer (r);
1351*e4b17023SJohn Marino 
1352*e4b17023SJohn Marino       if (REAL_EXP (r) <= 0)
1353*e4b17023SJohn Marino 	goto underflow;
1354*e4b17023SJohn Marino       /* Only force overflow for unsigned overflow.  Signed overflow is
1355*e4b17023SJohn Marino 	 undefined, so it doesn't matter what we return, and some callers
1356*e4b17023SJohn Marino 	 expect to be able to use this routine for both signed and
1357*e4b17023SJohn Marino 	 unsigned conversions.  */
1358*e4b17023SJohn Marino       if (REAL_EXP (r) > HOST_BITS_PER_WIDE_INT)
1359*e4b17023SJohn Marino 	goto overflow;
1360*e4b17023SJohn Marino 
1361*e4b17023SJohn Marino       if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
1362*e4b17023SJohn Marino 	i = r->sig[SIGSZ-1];
1363*e4b17023SJohn Marino       else
1364*e4b17023SJohn Marino 	{
1365*e4b17023SJohn Marino 	  gcc_assert (HOST_BITS_PER_WIDE_INT == 2 * HOST_BITS_PER_LONG);
1366*e4b17023SJohn Marino 	  i = r->sig[SIGSZ-1];
1367*e4b17023SJohn Marino 	  i = i << (HOST_BITS_PER_LONG - 1) << 1;
1368*e4b17023SJohn Marino 	  i |= r->sig[SIGSZ-2];
1369*e4b17023SJohn Marino 	}
1370*e4b17023SJohn Marino 
1371*e4b17023SJohn Marino       i >>= HOST_BITS_PER_WIDE_INT - REAL_EXP (r);
1372*e4b17023SJohn Marino 
1373*e4b17023SJohn Marino       if (r->sign)
1374*e4b17023SJohn Marino 	i = -i;
1375*e4b17023SJohn Marino       return i;
1376*e4b17023SJohn Marino 
1377*e4b17023SJohn Marino     default:
1378*e4b17023SJohn Marino       gcc_unreachable ();
1379*e4b17023SJohn Marino     }
1380*e4b17023SJohn Marino }
1381*e4b17023SJohn Marino 
1382*e4b17023SJohn Marino /* Likewise, but to an integer pair, HI+LOW.  */
1383*e4b17023SJohn Marino 
1384*e4b17023SJohn Marino void
real_to_integer2(HOST_WIDE_INT * plow,HOST_WIDE_INT * phigh,const REAL_VALUE_TYPE * r)1385*e4b17023SJohn Marino real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh,
1386*e4b17023SJohn Marino 		  const REAL_VALUE_TYPE *r)
1387*e4b17023SJohn Marino {
1388*e4b17023SJohn Marino   REAL_VALUE_TYPE t;
1389*e4b17023SJohn Marino   HOST_WIDE_INT low, high;
1390*e4b17023SJohn Marino   int exp;
1391*e4b17023SJohn Marino 
1392*e4b17023SJohn Marino   switch (r->cl)
1393*e4b17023SJohn Marino     {
1394*e4b17023SJohn Marino     case rvc_zero:
1395*e4b17023SJohn Marino     underflow:
1396*e4b17023SJohn Marino       low = high = 0;
1397*e4b17023SJohn Marino       break;
1398*e4b17023SJohn Marino 
1399*e4b17023SJohn Marino     case rvc_inf:
1400*e4b17023SJohn Marino     case rvc_nan:
1401*e4b17023SJohn Marino     overflow:
1402*e4b17023SJohn Marino       high = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1);
1403*e4b17023SJohn Marino       if (r->sign)
1404*e4b17023SJohn Marino 	low = 0;
1405*e4b17023SJohn Marino       else
1406*e4b17023SJohn Marino 	{
1407*e4b17023SJohn Marino 	  high--;
1408*e4b17023SJohn Marino 	  low = -1;
1409*e4b17023SJohn Marino 	}
1410*e4b17023SJohn Marino       break;
1411*e4b17023SJohn Marino 
1412*e4b17023SJohn Marino     case rvc_normal:
1413*e4b17023SJohn Marino       if (r->decimal)
1414*e4b17023SJohn Marino 	{
1415*e4b17023SJohn Marino 	  decimal_real_to_integer2 (plow, phigh, r);
1416*e4b17023SJohn Marino 	  return;
1417*e4b17023SJohn Marino 	}
1418*e4b17023SJohn Marino 
1419*e4b17023SJohn Marino       exp = REAL_EXP (r);
1420*e4b17023SJohn Marino       if (exp <= 0)
1421*e4b17023SJohn Marino 	goto underflow;
1422*e4b17023SJohn Marino       /* Only force overflow for unsigned overflow.  Signed overflow is
1423*e4b17023SJohn Marino 	 undefined, so it doesn't matter what we return, and some callers
1424*e4b17023SJohn Marino 	 expect to be able to use this routine for both signed and
1425*e4b17023SJohn Marino 	 unsigned conversions.  */
1426*e4b17023SJohn Marino       if (exp > 2*HOST_BITS_PER_WIDE_INT)
1427*e4b17023SJohn Marino 	goto overflow;
1428*e4b17023SJohn Marino 
1429*e4b17023SJohn Marino       rshift_significand (&t, r, 2*HOST_BITS_PER_WIDE_INT - exp);
1430*e4b17023SJohn Marino       if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
1431*e4b17023SJohn Marino 	{
1432*e4b17023SJohn Marino 	  high = t.sig[SIGSZ-1];
1433*e4b17023SJohn Marino 	  low = t.sig[SIGSZ-2];
1434*e4b17023SJohn Marino 	}
1435*e4b17023SJohn Marino       else
1436*e4b17023SJohn Marino 	{
1437*e4b17023SJohn Marino 	  gcc_assert (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG);
1438*e4b17023SJohn Marino 	  high = t.sig[SIGSZ-1];
1439*e4b17023SJohn Marino 	  high = high << (HOST_BITS_PER_LONG - 1) << 1;
1440*e4b17023SJohn Marino 	  high |= t.sig[SIGSZ-2];
1441*e4b17023SJohn Marino 
1442*e4b17023SJohn Marino 	  low = t.sig[SIGSZ-3];
1443*e4b17023SJohn Marino 	  low = low << (HOST_BITS_PER_LONG - 1) << 1;
1444*e4b17023SJohn Marino 	  low |= t.sig[SIGSZ-4];
1445*e4b17023SJohn Marino 	}
1446*e4b17023SJohn Marino 
1447*e4b17023SJohn Marino       if (r->sign)
1448*e4b17023SJohn Marino 	{
1449*e4b17023SJohn Marino 	  if (low == 0)
1450*e4b17023SJohn Marino 	    high = -high;
1451*e4b17023SJohn Marino 	  else
1452*e4b17023SJohn Marino 	    low = -low, high = ~high;
1453*e4b17023SJohn Marino 	}
1454*e4b17023SJohn Marino       break;
1455*e4b17023SJohn Marino 
1456*e4b17023SJohn Marino     default:
1457*e4b17023SJohn Marino       gcc_unreachable ();
1458*e4b17023SJohn Marino     }
1459*e4b17023SJohn Marino 
1460*e4b17023SJohn Marino   *plow = low;
1461*e4b17023SJohn Marino   *phigh = high;
1462*e4b17023SJohn Marino }
1463*e4b17023SJohn Marino 
1464*e4b17023SJohn Marino /* A subroutine of real_to_decimal.  Compute the quotient and remainder
1465*e4b17023SJohn Marino    of NUM / DEN.  Return the quotient and place the remainder in NUM.
1466*e4b17023SJohn Marino    It is expected that NUM / DEN are close enough that the quotient is
1467*e4b17023SJohn Marino    small.  */
1468*e4b17023SJohn Marino 
1469*e4b17023SJohn Marino static unsigned long
rtd_divmod(REAL_VALUE_TYPE * num,REAL_VALUE_TYPE * den)1470*e4b17023SJohn Marino rtd_divmod (REAL_VALUE_TYPE *num, REAL_VALUE_TYPE *den)
1471*e4b17023SJohn Marino {
1472*e4b17023SJohn Marino   unsigned long q, msb;
1473*e4b17023SJohn Marino   int expn = REAL_EXP (num), expd = REAL_EXP (den);
1474*e4b17023SJohn Marino 
1475*e4b17023SJohn Marino   if (expn < expd)
1476*e4b17023SJohn Marino     return 0;
1477*e4b17023SJohn Marino 
1478*e4b17023SJohn Marino   q = msb = 0;
1479*e4b17023SJohn Marino   goto start;
1480*e4b17023SJohn Marino   do
1481*e4b17023SJohn Marino     {
1482*e4b17023SJohn Marino       msb = num->sig[SIGSZ-1] & SIG_MSB;
1483*e4b17023SJohn Marino       q <<= 1;
1484*e4b17023SJohn Marino       lshift_significand_1 (num, num);
1485*e4b17023SJohn Marino     start:
1486*e4b17023SJohn Marino       if (msb || cmp_significands (num, den) >= 0)
1487*e4b17023SJohn Marino 	{
1488*e4b17023SJohn Marino 	  sub_significands (num, num, den, 0);
1489*e4b17023SJohn Marino 	  q |= 1;
1490*e4b17023SJohn Marino 	}
1491*e4b17023SJohn Marino     }
1492*e4b17023SJohn Marino   while (--expn >= expd);
1493*e4b17023SJohn Marino 
1494*e4b17023SJohn Marino   SET_REAL_EXP (num, expd);
1495*e4b17023SJohn Marino   normalize (num);
1496*e4b17023SJohn Marino 
1497*e4b17023SJohn Marino   return q;
1498*e4b17023SJohn Marino }
1499*e4b17023SJohn Marino 
1500*e4b17023SJohn Marino /* Render R as a decimal floating point constant.  Emit DIGITS significant
1501*e4b17023SJohn Marino    digits in the result, bounded by BUF_SIZE.  If DIGITS is 0, choose the
1502*e4b17023SJohn Marino    maximum for the representation.  If CROP_TRAILING_ZEROS, strip trailing
1503*e4b17023SJohn Marino    zeros.  If MODE is VOIDmode, round to nearest value.  Otherwise, round
1504*e4b17023SJohn Marino    to a string that, when parsed back in mode MODE, yields the same value.  */
1505*e4b17023SJohn Marino 
1506*e4b17023SJohn Marino #define M_LOG10_2	0.30102999566398119521
1507*e4b17023SJohn Marino 
1508*e4b17023SJohn Marino void
real_to_decimal_for_mode(char * str,const REAL_VALUE_TYPE * r_orig,size_t buf_size,size_t digits,int crop_trailing_zeros,enum machine_mode mode)1509*e4b17023SJohn Marino real_to_decimal_for_mode (char *str, const REAL_VALUE_TYPE *r_orig,
1510*e4b17023SJohn Marino 			  size_t buf_size, size_t digits,
1511*e4b17023SJohn Marino 			  int crop_trailing_zeros, enum machine_mode mode)
1512*e4b17023SJohn Marino {
1513*e4b17023SJohn Marino   const struct real_format *fmt = NULL;
1514*e4b17023SJohn Marino   const REAL_VALUE_TYPE *one, *ten;
1515*e4b17023SJohn Marino   REAL_VALUE_TYPE r, pten, u, v;
1516*e4b17023SJohn Marino   int dec_exp, cmp_one, digit;
1517*e4b17023SJohn Marino   size_t max_digits;
1518*e4b17023SJohn Marino   char *p, *first, *last;
1519*e4b17023SJohn Marino   bool sign;
1520*e4b17023SJohn Marino   bool round_up;
1521*e4b17023SJohn Marino 
1522*e4b17023SJohn Marino   if (mode != VOIDmode)
1523*e4b17023SJohn Marino    {
1524*e4b17023SJohn Marino      fmt = REAL_MODE_FORMAT (mode);
1525*e4b17023SJohn Marino      gcc_assert (fmt);
1526*e4b17023SJohn Marino    }
1527*e4b17023SJohn Marino 
1528*e4b17023SJohn Marino   r = *r_orig;
1529*e4b17023SJohn Marino   switch (r.cl)
1530*e4b17023SJohn Marino     {
1531*e4b17023SJohn Marino     case rvc_zero:
1532*e4b17023SJohn Marino       strcpy (str, (r.sign ? "-0.0" : "0.0"));
1533*e4b17023SJohn Marino       return;
1534*e4b17023SJohn Marino     case rvc_normal:
1535*e4b17023SJohn Marino       break;
1536*e4b17023SJohn Marino     case rvc_inf:
1537*e4b17023SJohn Marino       strcpy (str, (r.sign ? "-Inf" : "+Inf"));
1538*e4b17023SJohn Marino       return;
1539*e4b17023SJohn Marino     case rvc_nan:
1540*e4b17023SJohn Marino       /* ??? Print the significand as well, if not canonical?  */
1541*e4b17023SJohn Marino       sprintf (str, "%c%cNaN", (r_orig->sign ? '-' : '+'),
1542*e4b17023SJohn Marino 	       (r_orig->signalling ? 'S' : 'Q'));
1543*e4b17023SJohn Marino       return;
1544*e4b17023SJohn Marino     default:
1545*e4b17023SJohn Marino       gcc_unreachable ();
1546*e4b17023SJohn Marino     }
1547*e4b17023SJohn Marino 
1548*e4b17023SJohn Marino   if (r.decimal)
1549*e4b17023SJohn Marino     {
1550*e4b17023SJohn Marino       decimal_real_to_decimal (str, &r, buf_size, digits, crop_trailing_zeros);
1551*e4b17023SJohn Marino       return;
1552*e4b17023SJohn Marino     }
1553*e4b17023SJohn Marino 
1554*e4b17023SJohn Marino   /* Bound the number of digits printed by the size of the representation.  */
1555*e4b17023SJohn Marino   max_digits = SIGNIFICAND_BITS * M_LOG10_2;
1556*e4b17023SJohn Marino   if (digits == 0 || digits > max_digits)
1557*e4b17023SJohn Marino     digits = max_digits;
1558*e4b17023SJohn Marino 
1559*e4b17023SJohn Marino   /* Estimate the decimal exponent, and compute the length of the string it
1560*e4b17023SJohn Marino      will print as.  Be conservative and add one to account for possible
1561*e4b17023SJohn Marino      overflow or rounding error.  */
1562*e4b17023SJohn Marino   dec_exp = REAL_EXP (&r) * M_LOG10_2;
1563*e4b17023SJohn Marino   for (max_digits = 1; dec_exp ; max_digits++)
1564*e4b17023SJohn Marino     dec_exp /= 10;
1565*e4b17023SJohn Marino 
1566*e4b17023SJohn Marino   /* Bound the number of digits printed by the size of the output buffer.  */
1567*e4b17023SJohn Marino   max_digits = buf_size - 1 - 1 - 2 - max_digits - 1;
1568*e4b17023SJohn Marino   gcc_assert (max_digits <= buf_size);
1569*e4b17023SJohn Marino   if (digits > max_digits)
1570*e4b17023SJohn Marino     digits = max_digits;
1571*e4b17023SJohn Marino 
1572*e4b17023SJohn Marino   one = real_digit (1);
1573*e4b17023SJohn Marino   ten = ten_to_ptwo (0);
1574*e4b17023SJohn Marino 
1575*e4b17023SJohn Marino   sign = r.sign;
1576*e4b17023SJohn Marino   r.sign = 0;
1577*e4b17023SJohn Marino 
1578*e4b17023SJohn Marino   dec_exp = 0;
1579*e4b17023SJohn Marino   pten = *one;
1580*e4b17023SJohn Marino 
1581*e4b17023SJohn Marino   cmp_one = do_compare (&r, one, 0);
1582*e4b17023SJohn Marino   if (cmp_one > 0)
1583*e4b17023SJohn Marino     {
1584*e4b17023SJohn Marino       int m;
1585*e4b17023SJohn Marino 
1586*e4b17023SJohn Marino       /* Number is greater than one.  Convert significand to an integer
1587*e4b17023SJohn Marino 	 and strip trailing decimal zeros.  */
1588*e4b17023SJohn Marino 
1589*e4b17023SJohn Marino       u = r;
1590*e4b17023SJohn Marino       SET_REAL_EXP (&u, SIGNIFICAND_BITS - 1);
1591*e4b17023SJohn Marino 
1592*e4b17023SJohn Marino       /* Largest M, such that 10**2**M fits within SIGNIFICAND_BITS.  */
1593*e4b17023SJohn Marino       m = floor_log2 (max_digits);
1594*e4b17023SJohn Marino 
1595*e4b17023SJohn Marino       /* Iterate over the bits of the possible powers of 10 that might
1596*e4b17023SJohn Marino 	 be present in U and eliminate them.  That is, if we find that
1597*e4b17023SJohn Marino 	 10**2**M divides U evenly, keep the division and increase
1598*e4b17023SJohn Marino 	 DEC_EXP by 2**M.  */
1599*e4b17023SJohn Marino       do
1600*e4b17023SJohn Marino 	{
1601*e4b17023SJohn Marino 	  REAL_VALUE_TYPE t;
1602*e4b17023SJohn Marino 
1603*e4b17023SJohn Marino 	  do_divide (&t, &u, ten_to_ptwo (m));
1604*e4b17023SJohn Marino 	  do_fix_trunc (&v, &t);
1605*e4b17023SJohn Marino 	  if (cmp_significands (&v, &t) == 0)
1606*e4b17023SJohn Marino 	    {
1607*e4b17023SJohn Marino 	      u = t;
1608*e4b17023SJohn Marino 	      dec_exp += 1 << m;
1609*e4b17023SJohn Marino 	    }
1610*e4b17023SJohn Marino 	}
1611*e4b17023SJohn Marino       while (--m >= 0);
1612*e4b17023SJohn Marino 
1613*e4b17023SJohn Marino       /* Revert the scaling to integer that we performed earlier.  */
1614*e4b17023SJohn Marino       SET_REAL_EXP (&u, REAL_EXP (&u) + REAL_EXP (&r)
1615*e4b17023SJohn Marino 		    - (SIGNIFICAND_BITS - 1));
1616*e4b17023SJohn Marino       r = u;
1617*e4b17023SJohn Marino 
1618*e4b17023SJohn Marino       /* Find power of 10.  Do this by dividing out 10**2**M when
1619*e4b17023SJohn Marino 	 this is larger than the current remainder.  Fill PTEN with
1620*e4b17023SJohn Marino 	 the power of 10 that we compute.  */
1621*e4b17023SJohn Marino       if (REAL_EXP (&r) > 0)
1622*e4b17023SJohn Marino 	{
1623*e4b17023SJohn Marino 	  m = floor_log2 ((int)(REAL_EXP (&r) * M_LOG10_2)) + 1;
1624*e4b17023SJohn Marino 	  do
1625*e4b17023SJohn Marino 	    {
1626*e4b17023SJohn Marino 	      const REAL_VALUE_TYPE *ptentwo = ten_to_ptwo (m);
1627*e4b17023SJohn Marino 	      if (do_compare (&u, ptentwo, 0) >= 0)
1628*e4b17023SJohn Marino 	        {
1629*e4b17023SJohn Marino 	          do_divide (&u, &u, ptentwo);
1630*e4b17023SJohn Marino 	          do_multiply (&pten, &pten, ptentwo);
1631*e4b17023SJohn Marino 	          dec_exp += 1 << m;
1632*e4b17023SJohn Marino 	        }
1633*e4b17023SJohn Marino 	    }
1634*e4b17023SJohn Marino           while (--m >= 0);
1635*e4b17023SJohn Marino 	}
1636*e4b17023SJohn Marino       else
1637*e4b17023SJohn Marino 	/* We managed to divide off enough tens in the above reduction
1638*e4b17023SJohn Marino 	   loop that we've now got a negative exponent.  Fall into the
1639*e4b17023SJohn Marino 	   less-than-one code to compute the proper value for PTEN.  */
1640*e4b17023SJohn Marino 	cmp_one = -1;
1641*e4b17023SJohn Marino     }
1642*e4b17023SJohn Marino   if (cmp_one < 0)
1643*e4b17023SJohn Marino     {
1644*e4b17023SJohn Marino       int m;
1645*e4b17023SJohn Marino 
1646*e4b17023SJohn Marino       /* Number is less than one.  Pad significand with leading
1647*e4b17023SJohn Marino 	 decimal zeros.  */
1648*e4b17023SJohn Marino 
1649*e4b17023SJohn Marino       v = r;
1650*e4b17023SJohn Marino       while (1)
1651*e4b17023SJohn Marino 	{
1652*e4b17023SJohn Marino 	  /* Stop if we'd shift bits off the bottom.  */
1653*e4b17023SJohn Marino 	  if (v.sig[0] & 7)
1654*e4b17023SJohn Marino 	    break;
1655*e4b17023SJohn Marino 
1656*e4b17023SJohn Marino 	  do_multiply (&u, &v, ten);
1657*e4b17023SJohn Marino 
1658*e4b17023SJohn Marino 	  /* Stop if we're now >= 1.  */
1659*e4b17023SJohn Marino 	  if (REAL_EXP (&u) > 0)
1660*e4b17023SJohn Marino 	    break;
1661*e4b17023SJohn Marino 
1662*e4b17023SJohn Marino 	  v = u;
1663*e4b17023SJohn Marino 	  dec_exp -= 1;
1664*e4b17023SJohn Marino 	}
1665*e4b17023SJohn Marino       r = v;
1666*e4b17023SJohn Marino 
1667*e4b17023SJohn Marino       /* Find power of 10.  Do this by multiplying in P=10**2**M when
1668*e4b17023SJohn Marino 	 the current remainder is smaller than 1/P.  Fill PTEN with the
1669*e4b17023SJohn Marino 	 power of 10 that we compute.  */
1670*e4b17023SJohn Marino       m = floor_log2 ((int)(-REAL_EXP (&r) * M_LOG10_2)) + 1;
1671*e4b17023SJohn Marino       do
1672*e4b17023SJohn Marino 	{
1673*e4b17023SJohn Marino 	  const REAL_VALUE_TYPE *ptentwo = ten_to_ptwo (m);
1674*e4b17023SJohn Marino 	  const REAL_VALUE_TYPE *ptenmtwo = ten_to_mptwo (m);
1675*e4b17023SJohn Marino 
1676*e4b17023SJohn Marino 	  if (do_compare (&v, ptenmtwo, 0) <= 0)
1677*e4b17023SJohn Marino 	    {
1678*e4b17023SJohn Marino 	      do_multiply (&v, &v, ptentwo);
1679*e4b17023SJohn Marino 	      do_multiply (&pten, &pten, ptentwo);
1680*e4b17023SJohn Marino 	      dec_exp -= 1 << m;
1681*e4b17023SJohn Marino 	    }
1682*e4b17023SJohn Marino 	}
1683*e4b17023SJohn Marino       while (--m >= 0);
1684*e4b17023SJohn Marino 
1685*e4b17023SJohn Marino       /* Invert the positive power of 10 that we've collected so far.  */
1686*e4b17023SJohn Marino       do_divide (&pten, one, &pten);
1687*e4b17023SJohn Marino     }
1688*e4b17023SJohn Marino 
1689*e4b17023SJohn Marino   p = str;
1690*e4b17023SJohn Marino   if (sign)
1691*e4b17023SJohn Marino     *p++ = '-';
1692*e4b17023SJohn Marino   first = p++;
1693*e4b17023SJohn Marino 
1694*e4b17023SJohn Marino   /* At this point, PTEN should contain the nearest power of 10 smaller
1695*e4b17023SJohn Marino      than R, such that this division produces the first digit.
1696*e4b17023SJohn Marino 
1697*e4b17023SJohn Marino      Using a divide-step primitive that returns the complete integral
1698*e4b17023SJohn Marino      remainder avoids the rounding error that would be produced if
1699*e4b17023SJohn Marino      we were to use do_divide here and then simply multiply by 10 for
1700*e4b17023SJohn Marino      each subsequent digit.  */
1701*e4b17023SJohn Marino 
1702*e4b17023SJohn Marino   digit = rtd_divmod (&r, &pten);
1703*e4b17023SJohn Marino 
1704*e4b17023SJohn Marino   /* Be prepared for error in that division via underflow ...  */
1705*e4b17023SJohn Marino   if (digit == 0 && cmp_significand_0 (&r))
1706*e4b17023SJohn Marino     {
1707*e4b17023SJohn Marino       /* Multiply by 10 and try again.  */
1708*e4b17023SJohn Marino       do_multiply (&r, &r, ten);
1709*e4b17023SJohn Marino       digit = rtd_divmod (&r, &pten);
1710*e4b17023SJohn Marino       dec_exp -= 1;
1711*e4b17023SJohn Marino       gcc_assert (digit != 0);
1712*e4b17023SJohn Marino     }
1713*e4b17023SJohn Marino 
1714*e4b17023SJohn Marino   /* ... or overflow.  */
1715*e4b17023SJohn Marino   if (digit == 10)
1716*e4b17023SJohn Marino     {
1717*e4b17023SJohn Marino       *p++ = '1';
1718*e4b17023SJohn Marino       if (--digits > 0)
1719*e4b17023SJohn Marino 	*p++ = '0';
1720*e4b17023SJohn Marino       dec_exp += 1;
1721*e4b17023SJohn Marino     }
1722*e4b17023SJohn Marino   else
1723*e4b17023SJohn Marino     {
1724*e4b17023SJohn Marino       gcc_assert (digit <= 10);
1725*e4b17023SJohn Marino       *p++ = digit + '0';
1726*e4b17023SJohn Marino     }
1727*e4b17023SJohn Marino 
1728*e4b17023SJohn Marino   /* Generate subsequent digits.  */
1729*e4b17023SJohn Marino   while (--digits > 0)
1730*e4b17023SJohn Marino     {
1731*e4b17023SJohn Marino       do_multiply (&r, &r, ten);
1732*e4b17023SJohn Marino       digit = rtd_divmod (&r, &pten);
1733*e4b17023SJohn Marino       *p++ = digit + '0';
1734*e4b17023SJohn Marino     }
1735*e4b17023SJohn Marino   last = p;
1736*e4b17023SJohn Marino 
1737*e4b17023SJohn Marino   /* Generate one more digit with which to do rounding.  */
1738*e4b17023SJohn Marino   do_multiply (&r, &r, ten);
1739*e4b17023SJohn Marino   digit = rtd_divmod (&r, &pten);
1740*e4b17023SJohn Marino 
1741*e4b17023SJohn Marino   /* Round the result.  */
1742*e4b17023SJohn Marino   if (fmt && fmt->round_towards_zero)
1743*e4b17023SJohn Marino     {
1744*e4b17023SJohn Marino       /* If the format uses round towards zero when parsing the string
1745*e4b17023SJohn Marino 	 back in, we need to always round away from zero here.  */
1746*e4b17023SJohn Marino       if (cmp_significand_0 (&r))
1747*e4b17023SJohn Marino 	digit++;
1748*e4b17023SJohn Marino       round_up = digit > 0;
1749*e4b17023SJohn Marino     }
1750*e4b17023SJohn Marino   else
1751*e4b17023SJohn Marino     {
1752*e4b17023SJohn Marino       if (digit == 5)
1753*e4b17023SJohn Marino 	{
1754*e4b17023SJohn Marino 	  /* Round to nearest.  If R is nonzero there are additional
1755*e4b17023SJohn Marino 	     nonzero digits to be extracted.  */
1756*e4b17023SJohn Marino 	  if (cmp_significand_0 (&r))
1757*e4b17023SJohn Marino 	    digit++;
1758*e4b17023SJohn Marino 	  /* Round to even.  */
1759*e4b17023SJohn Marino 	  else if ((p[-1] - '0') & 1)
1760*e4b17023SJohn Marino 	    digit++;
1761*e4b17023SJohn Marino 	}
1762*e4b17023SJohn Marino 
1763*e4b17023SJohn Marino       round_up = digit > 5;
1764*e4b17023SJohn Marino     }
1765*e4b17023SJohn Marino 
1766*e4b17023SJohn Marino   if (round_up)
1767*e4b17023SJohn Marino     {
1768*e4b17023SJohn Marino       while (p > first)
1769*e4b17023SJohn Marino 	{
1770*e4b17023SJohn Marino 	  digit = *--p;
1771*e4b17023SJohn Marino 	  if (digit == '9')
1772*e4b17023SJohn Marino 	    *p = '0';
1773*e4b17023SJohn Marino 	  else
1774*e4b17023SJohn Marino 	    {
1775*e4b17023SJohn Marino 	      *p = digit + 1;
1776*e4b17023SJohn Marino 	      break;
1777*e4b17023SJohn Marino 	    }
1778*e4b17023SJohn Marino 	}
1779*e4b17023SJohn Marino 
1780*e4b17023SJohn Marino       /* Carry out of the first digit.  This means we had all 9's and
1781*e4b17023SJohn Marino 	 now have all 0's.  "Prepend" a 1 by overwriting the first 0.  */
1782*e4b17023SJohn Marino       if (p == first)
1783*e4b17023SJohn Marino 	{
1784*e4b17023SJohn Marino 	  first[1] = '1';
1785*e4b17023SJohn Marino 	  dec_exp++;
1786*e4b17023SJohn Marino 	}
1787*e4b17023SJohn Marino     }
1788*e4b17023SJohn Marino 
1789*e4b17023SJohn Marino   /* Insert the decimal point.  */
1790*e4b17023SJohn Marino   first[0] = first[1];
1791*e4b17023SJohn Marino   first[1] = '.';
1792*e4b17023SJohn Marino 
1793*e4b17023SJohn Marino   /* If requested, drop trailing zeros.  Never crop past "1.0".  */
1794*e4b17023SJohn Marino   if (crop_trailing_zeros)
1795*e4b17023SJohn Marino     while (last > first + 3 && last[-1] == '0')
1796*e4b17023SJohn Marino       last--;
1797*e4b17023SJohn Marino 
1798*e4b17023SJohn Marino   /* Append the exponent.  */
1799*e4b17023SJohn Marino   sprintf (last, "e%+d", dec_exp);
1800*e4b17023SJohn Marino 
1801*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
1802*e4b17023SJohn Marino   /* Verify that we can read the original value back in.  */
1803*e4b17023SJohn Marino   if (mode != VOIDmode)
1804*e4b17023SJohn Marino     {
1805*e4b17023SJohn Marino       real_from_string (&r, str);
1806*e4b17023SJohn Marino       real_convert (&r, mode, &r);
1807*e4b17023SJohn Marino       gcc_assert (real_identical (&r, r_orig));
1808*e4b17023SJohn Marino     }
1809*e4b17023SJohn Marino #endif
1810*e4b17023SJohn Marino }
1811*e4b17023SJohn Marino 
1812*e4b17023SJohn Marino /* Likewise, except always uses round-to-nearest.  */
1813*e4b17023SJohn Marino 
1814*e4b17023SJohn Marino void
real_to_decimal(char * str,const REAL_VALUE_TYPE * r_orig,size_t buf_size,size_t digits,int crop_trailing_zeros)1815*e4b17023SJohn Marino real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig, size_t buf_size,
1816*e4b17023SJohn Marino 		 size_t digits, int crop_trailing_zeros)
1817*e4b17023SJohn Marino {
1818*e4b17023SJohn Marino   real_to_decimal_for_mode (str, r_orig, buf_size,
1819*e4b17023SJohn Marino 			    digits, crop_trailing_zeros, VOIDmode);
1820*e4b17023SJohn Marino }
1821*e4b17023SJohn Marino 
1822*e4b17023SJohn Marino /* Render R as a hexadecimal floating point constant.  Emit DIGITS
1823*e4b17023SJohn Marino    significant digits in the result, bounded by BUF_SIZE.  If DIGITS is 0,
1824*e4b17023SJohn Marino    choose the maximum for the representation.  If CROP_TRAILING_ZEROS,
1825*e4b17023SJohn Marino    strip trailing zeros.  */
1826*e4b17023SJohn Marino 
1827*e4b17023SJohn Marino void
real_to_hexadecimal(char * str,const REAL_VALUE_TYPE * r,size_t buf_size,size_t digits,int crop_trailing_zeros)1828*e4b17023SJohn Marino real_to_hexadecimal (char *str, const REAL_VALUE_TYPE *r, size_t buf_size,
1829*e4b17023SJohn Marino 		     size_t digits, int crop_trailing_zeros)
1830*e4b17023SJohn Marino {
1831*e4b17023SJohn Marino   int i, j, exp = REAL_EXP (r);
1832*e4b17023SJohn Marino   char *p, *first;
1833*e4b17023SJohn Marino   char exp_buf[16];
1834*e4b17023SJohn Marino   size_t max_digits;
1835*e4b17023SJohn Marino 
1836*e4b17023SJohn Marino   switch (r->cl)
1837*e4b17023SJohn Marino     {
1838*e4b17023SJohn Marino     case rvc_zero:
1839*e4b17023SJohn Marino       exp = 0;
1840*e4b17023SJohn Marino       break;
1841*e4b17023SJohn Marino     case rvc_normal:
1842*e4b17023SJohn Marino       break;
1843*e4b17023SJohn Marino     case rvc_inf:
1844*e4b17023SJohn Marino       strcpy (str, (r->sign ? "-Inf" : "+Inf"));
1845*e4b17023SJohn Marino       return;
1846*e4b17023SJohn Marino     case rvc_nan:
1847*e4b17023SJohn Marino       /* ??? Print the significand as well, if not canonical?  */
1848*e4b17023SJohn Marino       sprintf (str, "%c%cNaN", (r->sign ? '-' : '+'),
1849*e4b17023SJohn Marino 	       (r->signalling ? 'S' : 'Q'));
1850*e4b17023SJohn Marino       return;
1851*e4b17023SJohn Marino     default:
1852*e4b17023SJohn Marino       gcc_unreachable ();
1853*e4b17023SJohn Marino     }
1854*e4b17023SJohn Marino 
1855*e4b17023SJohn Marino   if (r->decimal)
1856*e4b17023SJohn Marino     {
1857*e4b17023SJohn Marino       /* Hexadecimal format for decimal floats is not interesting. */
1858*e4b17023SJohn Marino       strcpy (str, "N/A");
1859*e4b17023SJohn Marino       return;
1860*e4b17023SJohn Marino     }
1861*e4b17023SJohn Marino 
1862*e4b17023SJohn Marino   if (digits == 0)
1863*e4b17023SJohn Marino     digits = SIGNIFICAND_BITS / 4;
1864*e4b17023SJohn Marino 
1865*e4b17023SJohn Marino   /* Bound the number of digits printed by the size of the output buffer.  */
1866*e4b17023SJohn Marino 
1867*e4b17023SJohn Marino   sprintf (exp_buf, "p%+d", exp);
1868*e4b17023SJohn Marino   max_digits = buf_size - strlen (exp_buf) - r->sign - 4 - 1;
1869*e4b17023SJohn Marino   gcc_assert (max_digits <= buf_size);
1870*e4b17023SJohn Marino   if (digits > max_digits)
1871*e4b17023SJohn Marino     digits = max_digits;
1872*e4b17023SJohn Marino 
1873*e4b17023SJohn Marino   p = str;
1874*e4b17023SJohn Marino   if (r->sign)
1875*e4b17023SJohn Marino     *p++ = '-';
1876*e4b17023SJohn Marino   *p++ = '0';
1877*e4b17023SJohn Marino   *p++ = 'x';
1878*e4b17023SJohn Marino   *p++ = '0';
1879*e4b17023SJohn Marino   *p++ = '.';
1880*e4b17023SJohn Marino   first = p;
1881*e4b17023SJohn Marino 
1882*e4b17023SJohn Marino   for (i = SIGSZ - 1; i >= 0; --i)
1883*e4b17023SJohn Marino     for (j = HOST_BITS_PER_LONG - 4; j >= 0; j -= 4)
1884*e4b17023SJohn Marino       {
1885*e4b17023SJohn Marino 	*p++ = "0123456789abcdef"[(r->sig[i] >> j) & 15];
1886*e4b17023SJohn Marino 	if (--digits == 0)
1887*e4b17023SJohn Marino 	  goto out;
1888*e4b17023SJohn Marino       }
1889*e4b17023SJohn Marino 
1890*e4b17023SJohn Marino  out:
1891*e4b17023SJohn Marino   if (crop_trailing_zeros)
1892*e4b17023SJohn Marino     while (p > first + 1 && p[-1] == '0')
1893*e4b17023SJohn Marino       p--;
1894*e4b17023SJohn Marino 
1895*e4b17023SJohn Marino   sprintf (p, "p%+d", exp);
1896*e4b17023SJohn Marino }
1897*e4b17023SJohn Marino 
1898*e4b17023SJohn Marino /* Initialize R from a decimal or hexadecimal string.  The string is
1899*e4b17023SJohn Marino    assumed to have been syntax checked already.  Return -1 if the
1900*e4b17023SJohn Marino    value underflows, +1 if overflows, and 0 otherwise. */
1901*e4b17023SJohn Marino 
1902*e4b17023SJohn Marino int
real_from_string(REAL_VALUE_TYPE * r,const char * str)1903*e4b17023SJohn Marino real_from_string (REAL_VALUE_TYPE *r, const char *str)
1904*e4b17023SJohn Marino {
1905*e4b17023SJohn Marino   int exp = 0;
1906*e4b17023SJohn Marino   bool sign = false;
1907*e4b17023SJohn Marino 
1908*e4b17023SJohn Marino   get_zero (r, 0);
1909*e4b17023SJohn Marino 
1910*e4b17023SJohn Marino   if (*str == '-')
1911*e4b17023SJohn Marino     {
1912*e4b17023SJohn Marino       sign = true;
1913*e4b17023SJohn Marino       str++;
1914*e4b17023SJohn Marino     }
1915*e4b17023SJohn Marino   else if (*str == '+')
1916*e4b17023SJohn Marino     str++;
1917*e4b17023SJohn Marino 
1918*e4b17023SJohn Marino   if (!strncmp (str, "QNaN", 4))
1919*e4b17023SJohn Marino     {
1920*e4b17023SJohn Marino       get_canonical_qnan (r, sign);
1921*e4b17023SJohn Marino       return 0;
1922*e4b17023SJohn Marino     }
1923*e4b17023SJohn Marino   else if (!strncmp (str, "SNaN", 4))
1924*e4b17023SJohn Marino     {
1925*e4b17023SJohn Marino       get_canonical_snan (r, sign);
1926*e4b17023SJohn Marino       return 0;
1927*e4b17023SJohn Marino     }
1928*e4b17023SJohn Marino   else if (!strncmp (str, "Inf", 3))
1929*e4b17023SJohn Marino     {
1930*e4b17023SJohn Marino       get_inf (r, sign);
1931*e4b17023SJohn Marino       return 0;
1932*e4b17023SJohn Marino     }
1933*e4b17023SJohn Marino 
1934*e4b17023SJohn Marino   if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
1935*e4b17023SJohn Marino     {
1936*e4b17023SJohn Marino       /* Hexadecimal floating point.  */
1937*e4b17023SJohn Marino       int pos = SIGNIFICAND_BITS - 4, d;
1938*e4b17023SJohn Marino 
1939*e4b17023SJohn Marino       str += 2;
1940*e4b17023SJohn Marino 
1941*e4b17023SJohn Marino       while (*str == '0')
1942*e4b17023SJohn Marino 	str++;
1943*e4b17023SJohn Marino       while (1)
1944*e4b17023SJohn Marino 	{
1945*e4b17023SJohn Marino 	  d = hex_value (*str);
1946*e4b17023SJohn Marino 	  if (d == _hex_bad)
1947*e4b17023SJohn Marino 	    break;
1948*e4b17023SJohn Marino 	  if (pos >= 0)
1949*e4b17023SJohn Marino 	    {
1950*e4b17023SJohn Marino 	      r->sig[pos / HOST_BITS_PER_LONG]
1951*e4b17023SJohn Marino 		|= (unsigned long) d << (pos % HOST_BITS_PER_LONG);
1952*e4b17023SJohn Marino 	      pos -= 4;
1953*e4b17023SJohn Marino 	    }
1954*e4b17023SJohn Marino 	  else if (d)
1955*e4b17023SJohn Marino 	    /* Ensure correct rounding by setting last bit if there is
1956*e4b17023SJohn Marino 	       a subsequent nonzero digit.  */
1957*e4b17023SJohn Marino 	    r->sig[0] |= 1;
1958*e4b17023SJohn Marino 	  exp += 4;
1959*e4b17023SJohn Marino 	  str++;
1960*e4b17023SJohn Marino 	}
1961*e4b17023SJohn Marino       if (*str == '.')
1962*e4b17023SJohn Marino 	{
1963*e4b17023SJohn Marino 	  str++;
1964*e4b17023SJohn Marino 	  if (pos == SIGNIFICAND_BITS - 4)
1965*e4b17023SJohn Marino 	    {
1966*e4b17023SJohn Marino 	      while (*str == '0')
1967*e4b17023SJohn Marino 		str++, exp -= 4;
1968*e4b17023SJohn Marino 	    }
1969*e4b17023SJohn Marino 	  while (1)
1970*e4b17023SJohn Marino 	    {
1971*e4b17023SJohn Marino 	      d = hex_value (*str);
1972*e4b17023SJohn Marino 	      if (d == _hex_bad)
1973*e4b17023SJohn Marino 		break;
1974*e4b17023SJohn Marino 	      if (pos >= 0)
1975*e4b17023SJohn Marino 		{
1976*e4b17023SJohn Marino 		  r->sig[pos / HOST_BITS_PER_LONG]
1977*e4b17023SJohn Marino 		    |= (unsigned long) d << (pos % HOST_BITS_PER_LONG);
1978*e4b17023SJohn Marino 		  pos -= 4;
1979*e4b17023SJohn Marino 		}
1980*e4b17023SJohn Marino 	      else if (d)
1981*e4b17023SJohn Marino 		/* Ensure correct rounding by setting last bit if there is
1982*e4b17023SJohn Marino 		   a subsequent nonzero digit.  */
1983*e4b17023SJohn Marino 		r->sig[0] |= 1;
1984*e4b17023SJohn Marino 	      str++;
1985*e4b17023SJohn Marino 	    }
1986*e4b17023SJohn Marino 	}
1987*e4b17023SJohn Marino 
1988*e4b17023SJohn Marino       /* If the mantissa is zero, ignore the exponent.  */
1989*e4b17023SJohn Marino       if (!cmp_significand_0 (r))
1990*e4b17023SJohn Marino 	goto is_a_zero;
1991*e4b17023SJohn Marino 
1992*e4b17023SJohn Marino       if (*str == 'p' || *str == 'P')
1993*e4b17023SJohn Marino 	{
1994*e4b17023SJohn Marino 	  bool exp_neg = false;
1995*e4b17023SJohn Marino 
1996*e4b17023SJohn Marino 	  str++;
1997*e4b17023SJohn Marino 	  if (*str == '-')
1998*e4b17023SJohn Marino 	    {
1999*e4b17023SJohn Marino 	      exp_neg = true;
2000*e4b17023SJohn Marino 	      str++;
2001*e4b17023SJohn Marino 	    }
2002*e4b17023SJohn Marino 	  else if (*str == '+')
2003*e4b17023SJohn Marino 	    str++;
2004*e4b17023SJohn Marino 
2005*e4b17023SJohn Marino 	  d = 0;
2006*e4b17023SJohn Marino 	  while (ISDIGIT (*str))
2007*e4b17023SJohn Marino 	    {
2008*e4b17023SJohn Marino 	      d *= 10;
2009*e4b17023SJohn Marino 	      d += *str - '0';
2010*e4b17023SJohn Marino 	      if (d > MAX_EXP)
2011*e4b17023SJohn Marino 		{
2012*e4b17023SJohn Marino 		  /* Overflowed the exponent.  */
2013*e4b17023SJohn Marino 		  if (exp_neg)
2014*e4b17023SJohn Marino 		    goto underflow;
2015*e4b17023SJohn Marino 		  else
2016*e4b17023SJohn Marino 		    goto overflow;
2017*e4b17023SJohn Marino 		}
2018*e4b17023SJohn Marino 	      str++;
2019*e4b17023SJohn Marino 	    }
2020*e4b17023SJohn Marino 	  if (exp_neg)
2021*e4b17023SJohn Marino 	    d = -d;
2022*e4b17023SJohn Marino 
2023*e4b17023SJohn Marino 	  exp += d;
2024*e4b17023SJohn Marino 	}
2025*e4b17023SJohn Marino 
2026*e4b17023SJohn Marino       r->cl = rvc_normal;
2027*e4b17023SJohn Marino       SET_REAL_EXP (r, exp);
2028*e4b17023SJohn Marino 
2029*e4b17023SJohn Marino       normalize (r);
2030*e4b17023SJohn Marino     }
2031*e4b17023SJohn Marino   else
2032*e4b17023SJohn Marino     {
2033*e4b17023SJohn Marino       /* Decimal floating point.  */
2034*e4b17023SJohn Marino       const REAL_VALUE_TYPE *ten = ten_to_ptwo (0);
2035*e4b17023SJohn Marino       int d;
2036*e4b17023SJohn Marino 
2037*e4b17023SJohn Marino       while (*str == '0')
2038*e4b17023SJohn Marino 	str++;
2039*e4b17023SJohn Marino       while (ISDIGIT (*str))
2040*e4b17023SJohn Marino 	{
2041*e4b17023SJohn Marino 	  d = *str++ - '0';
2042*e4b17023SJohn Marino 	  do_multiply (r, r, ten);
2043*e4b17023SJohn Marino 	  if (d)
2044*e4b17023SJohn Marino 	    do_add (r, r, real_digit (d), 0);
2045*e4b17023SJohn Marino 	}
2046*e4b17023SJohn Marino       if (*str == '.')
2047*e4b17023SJohn Marino 	{
2048*e4b17023SJohn Marino 	  str++;
2049*e4b17023SJohn Marino 	  if (r->cl == rvc_zero)
2050*e4b17023SJohn Marino 	    {
2051*e4b17023SJohn Marino 	      while (*str == '0')
2052*e4b17023SJohn Marino 		str++, exp--;
2053*e4b17023SJohn Marino 	    }
2054*e4b17023SJohn Marino 	  while (ISDIGIT (*str))
2055*e4b17023SJohn Marino 	    {
2056*e4b17023SJohn Marino 	      d = *str++ - '0';
2057*e4b17023SJohn Marino 	      do_multiply (r, r, ten);
2058*e4b17023SJohn Marino 	      if (d)
2059*e4b17023SJohn Marino 	        do_add (r, r, real_digit (d), 0);
2060*e4b17023SJohn Marino 	      exp--;
2061*e4b17023SJohn Marino 	    }
2062*e4b17023SJohn Marino 	}
2063*e4b17023SJohn Marino 
2064*e4b17023SJohn Marino       /* If the mantissa is zero, ignore the exponent.  */
2065*e4b17023SJohn Marino       if (r->cl == rvc_zero)
2066*e4b17023SJohn Marino 	goto is_a_zero;
2067*e4b17023SJohn Marino 
2068*e4b17023SJohn Marino       if (*str == 'e' || *str == 'E')
2069*e4b17023SJohn Marino 	{
2070*e4b17023SJohn Marino 	  bool exp_neg = false;
2071*e4b17023SJohn Marino 
2072*e4b17023SJohn Marino 	  str++;
2073*e4b17023SJohn Marino 	  if (*str == '-')
2074*e4b17023SJohn Marino 	    {
2075*e4b17023SJohn Marino 	      exp_neg = true;
2076*e4b17023SJohn Marino 	      str++;
2077*e4b17023SJohn Marino 	    }
2078*e4b17023SJohn Marino 	  else if (*str == '+')
2079*e4b17023SJohn Marino 	    str++;
2080*e4b17023SJohn Marino 
2081*e4b17023SJohn Marino 	  d = 0;
2082*e4b17023SJohn Marino 	  while (ISDIGIT (*str))
2083*e4b17023SJohn Marino 	    {
2084*e4b17023SJohn Marino 	      d *= 10;
2085*e4b17023SJohn Marino 	      d += *str - '0';
2086*e4b17023SJohn Marino 	      if (d > MAX_EXP)
2087*e4b17023SJohn Marino 		{
2088*e4b17023SJohn Marino 		  /* Overflowed the exponent.  */
2089*e4b17023SJohn Marino 		  if (exp_neg)
2090*e4b17023SJohn Marino 		    goto underflow;
2091*e4b17023SJohn Marino 		  else
2092*e4b17023SJohn Marino 		    goto overflow;
2093*e4b17023SJohn Marino 		}
2094*e4b17023SJohn Marino 	      str++;
2095*e4b17023SJohn Marino 	    }
2096*e4b17023SJohn Marino 	  if (exp_neg)
2097*e4b17023SJohn Marino 	    d = -d;
2098*e4b17023SJohn Marino 	  exp += d;
2099*e4b17023SJohn Marino 	}
2100*e4b17023SJohn Marino 
2101*e4b17023SJohn Marino       if (exp)
2102*e4b17023SJohn Marino 	times_pten (r, exp);
2103*e4b17023SJohn Marino     }
2104*e4b17023SJohn Marino 
2105*e4b17023SJohn Marino   r->sign = sign;
2106*e4b17023SJohn Marino   return 0;
2107*e4b17023SJohn Marino 
2108*e4b17023SJohn Marino  is_a_zero:
2109*e4b17023SJohn Marino   get_zero (r, sign);
2110*e4b17023SJohn Marino   return 0;
2111*e4b17023SJohn Marino 
2112*e4b17023SJohn Marino  underflow:
2113*e4b17023SJohn Marino   get_zero (r, sign);
2114*e4b17023SJohn Marino   return -1;
2115*e4b17023SJohn Marino 
2116*e4b17023SJohn Marino  overflow:
2117*e4b17023SJohn Marino   get_inf (r, sign);
2118*e4b17023SJohn Marino   return 1;
2119*e4b17023SJohn Marino }
2120*e4b17023SJohn Marino 
2121*e4b17023SJohn Marino /* Legacy.  Similar, but return the result directly.  */
2122*e4b17023SJohn Marino 
2123*e4b17023SJohn Marino REAL_VALUE_TYPE
real_from_string2(const char * s,enum machine_mode mode)2124*e4b17023SJohn Marino real_from_string2 (const char *s, enum machine_mode mode)
2125*e4b17023SJohn Marino {
2126*e4b17023SJohn Marino   REAL_VALUE_TYPE r;
2127*e4b17023SJohn Marino 
2128*e4b17023SJohn Marino   real_from_string (&r, s);
2129*e4b17023SJohn Marino   if (mode != VOIDmode)
2130*e4b17023SJohn Marino     real_convert (&r, mode, &r);
2131*e4b17023SJohn Marino 
2132*e4b17023SJohn Marino   return r;
2133*e4b17023SJohn Marino }
2134*e4b17023SJohn Marino 
2135*e4b17023SJohn Marino /* Initialize R from string S and desired MODE. */
2136*e4b17023SJohn Marino 
2137*e4b17023SJohn Marino void
real_from_string3(REAL_VALUE_TYPE * r,const char * s,enum machine_mode mode)2138*e4b17023SJohn Marino real_from_string3 (REAL_VALUE_TYPE *r, const char *s, enum machine_mode mode)
2139*e4b17023SJohn Marino {
2140*e4b17023SJohn Marino   if (DECIMAL_FLOAT_MODE_P (mode))
2141*e4b17023SJohn Marino     decimal_real_from_string (r, s);
2142*e4b17023SJohn Marino   else
2143*e4b17023SJohn Marino     real_from_string (r, s);
2144*e4b17023SJohn Marino 
2145*e4b17023SJohn Marino   if (mode != VOIDmode)
2146*e4b17023SJohn Marino     real_convert (r, mode, r);
2147*e4b17023SJohn Marino }
2148*e4b17023SJohn Marino 
2149*e4b17023SJohn Marino /* Initialize R from the integer pair HIGH+LOW.  */
2150*e4b17023SJohn Marino 
2151*e4b17023SJohn Marino void
real_from_integer(REAL_VALUE_TYPE * r,enum machine_mode mode,unsigned HOST_WIDE_INT low,HOST_WIDE_INT high,int unsigned_p)2152*e4b17023SJohn Marino real_from_integer (REAL_VALUE_TYPE *r, enum machine_mode mode,
2153*e4b17023SJohn Marino 		   unsigned HOST_WIDE_INT low, HOST_WIDE_INT high,
2154*e4b17023SJohn Marino 		   int unsigned_p)
2155*e4b17023SJohn Marino {
2156*e4b17023SJohn Marino   if (low == 0 && high == 0)
2157*e4b17023SJohn Marino     get_zero (r, 0);
2158*e4b17023SJohn Marino   else
2159*e4b17023SJohn Marino     {
2160*e4b17023SJohn Marino       memset (r, 0, sizeof (*r));
2161*e4b17023SJohn Marino       r->cl = rvc_normal;
2162*e4b17023SJohn Marino       r->sign = high < 0 && !unsigned_p;
2163*e4b17023SJohn Marino       SET_REAL_EXP (r, 2 * HOST_BITS_PER_WIDE_INT);
2164*e4b17023SJohn Marino 
2165*e4b17023SJohn Marino       if (r->sign)
2166*e4b17023SJohn Marino 	{
2167*e4b17023SJohn Marino 	  high = ~high;
2168*e4b17023SJohn Marino 	  if (low == 0)
2169*e4b17023SJohn Marino 	    high += 1;
2170*e4b17023SJohn Marino 	  else
2171*e4b17023SJohn Marino 	    low = -low;
2172*e4b17023SJohn Marino 	}
2173*e4b17023SJohn Marino 
2174*e4b17023SJohn Marino       if (HOST_BITS_PER_LONG == HOST_BITS_PER_WIDE_INT)
2175*e4b17023SJohn Marino 	{
2176*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = high;
2177*e4b17023SJohn Marino 	  r->sig[SIGSZ-2] = low;
2178*e4b17023SJohn Marino 	}
2179*e4b17023SJohn Marino       else
2180*e4b17023SJohn Marino 	{
2181*e4b17023SJohn Marino 	  gcc_assert (HOST_BITS_PER_LONG*2 == HOST_BITS_PER_WIDE_INT);
2182*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = high >> (HOST_BITS_PER_LONG - 1) >> 1;
2183*e4b17023SJohn Marino 	  r->sig[SIGSZ-2] = high;
2184*e4b17023SJohn Marino 	  r->sig[SIGSZ-3] = low >> (HOST_BITS_PER_LONG - 1) >> 1;
2185*e4b17023SJohn Marino 	  r->sig[SIGSZ-4] = low;
2186*e4b17023SJohn Marino 	}
2187*e4b17023SJohn Marino 
2188*e4b17023SJohn Marino       normalize (r);
2189*e4b17023SJohn Marino     }
2190*e4b17023SJohn Marino 
2191*e4b17023SJohn Marino   if (DECIMAL_FLOAT_MODE_P (mode))
2192*e4b17023SJohn Marino     decimal_from_integer (r);
2193*e4b17023SJohn Marino   else if (mode != VOIDmode)
2194*e4b17023SJohn Marino     real_convert (r, mode, r);
2195*e4b17023SJohn Marino }
2196*e4b17023SJohn Marino 
2197*e4b17023SJohn Marino /* Render R, an integral value, as a floating point constant with no
2198*e4b17023SJohn Marino    specified exponent.  */
2199*e4b17023SJohn Marino 
2200*e4b17023SJohn Marino static void
decimal_integer_string(char * str,const REAL_VALUE_TYPE * r_orig,size_t buf_size)2201*e4b17023SJohn Marino decimal_integer_string (char *str, const REAL_VALUE_TYPE *r_orig,
2202*e4b17023SJohn Marino 			size_t buf_size)
2203*e4b17023SJohn Marino {
2204*e4b17023SJohn Marino   int dec_exp, digit, digits;
2205*e4b17023SJohn Marino   REAL_VALUE_TYPE r, pten;
2206*e4b17023SJohn Marino   char *p;
2207*e4b17023SJohn Marino   bool sign;
2208*e4b17023SJohn Marino 
2209*e4b17023SJohn Marino   r = *r_orig;
2210*e4b17023SJohn Marino 
2211*e4b17023SJohn Marino   if (r.cl == rvc_zero)
2212*e4b17023SJohn Marino     {
2213*e4b17023SJohn Marino       strcpy (str, "0.");
2214*e4b17023SJohn Marino       return;
2215*e4b17023SJohn Marino     }
2216*e4b17023SJohn Marino 
2217*e4b17023SJohn Marino   sign = r.sign;
2218*e4b17023SJohn Marino   r.sign = 0;
2219*e4b17023SJohn Marino 
2220*e4b17023SJohn Marino   dec_exp = REAL_EXP (&r) * M_LOG10_2;
2221*e4b17023SJohn Marino   digits = dec_exp + 1;
2222*e4b17023SJohn Marino   gcc_assert ((digits + 2) < (int)buf_size);
2223*e4b17023SJohn Marino 
2224*e4b17023SJohn Marino   pten = *real_digit (1);
2225*e4b17023SJohn Marino   times_pten (&pten, dec_exp);
2226*e4b17023SJohn Marino 
2227*e4b17023SJohn Marino   p = str;
2228*e4b17023SJohn Marino   if (sign)
2229*e4b17023SJohn Marino     *p++ = '-';
2230*e4b17023SJohn Marino 
2231*e4b17023SJohn Marino   digit = rtd_divmod (&r, &pten);
2232*e4b17023SJohn Marino   gcc_assert (digit >= 0 && digit <= 9);
2233*e4b17023SJohn Marino   *p++ = digit + '0';
2234*e4b17023SJohn Marino   while (--digits > 0)
2235*e4b17023SJohn Marino     {
2236*e4b17023SJohn Marino       times_pten (&r, 1);
2237*e4b17023SJohn Marino       digit = rtd_divmod (&r, &pten);
2238*e4b17023SJohn Marino       *p++ = digit + '0';
2239*e4b17023SJohn Marino     }
2240*e4b17023SJohn Marino   *p++ = '.';
2241*e4b17023SJohn Marino   *p++ = '\0';
2242*e4b17023SJohn Marino }
2243*e4b17023SJohn Marino 
2244*e4b17023SJohn Marino /* Convert a real with an integral value to decimal float.  */
2245*e4b17023SJohn Marino 
2246*e4b17023SJohn Marino static void
decimal_from_integer(REAL_VALUE_TYPE * r)2247*e4b17023SJohn Marino decimal_from_integer (REAL_VALUE_TYPE *r)
2248*e4b17023SJohn Marino {
2249*e4b17023SJohn Marino   char str[256];
2250*e4b17023SJohn Marino 
2251*e4b17023SJohn Marino   decimal_integer_string (str, r, sizeof (str) - 1);
2252*e4b17023SJohn Marino   decimal_real_from_string (r, str);
2253*e4b17023SJohn Marino }
2254*e4b17023SJohn Marino 
2255*e4b17023SJohn Marino /* Returns 10**2**N.  */
2256*e4b17023SJohn Marino 
2257*e4b17023SJohn Marino static const REAL_VALUE_TYPE *
ten_to_ptwo(int n)2258*e4b17023SJohn Marino ten_to_ptwo (int n)
2259*e4b17023SJohn Marino {
2260*e4b17023SJohn Marino   static REAL_VALUE_TYPE tens[EXP_BITS];
2261*e4b17023SJohn Marino 
2262*e4b17023SJohn Marino   gcc_assert (n >= 0);
2263*e4b17023SJohn Marino   gcc_assert (n < EXP_BITS);
2264*e4b17023SJohn Marino 
2265*e4b17023SJohn Marino   if (tens[n].cl == rvc_zero)
2266*e4b17023SJohn Marino     {
2267*e4b17023SJohn Marino       if (n < (HOST_BITS_PER_WIDE_INT == 64 ? 5 : 4))
2268*e4b17023SJohn Marino 	{
2269*e4b17023SJohn Marino 	  HOST_WIDE_INT t = 10;
2270*e4b17023SJohn Marino 	  int i;
2271*e4b17023SJohn Marino 
2272*e4b17023SJohn Marino 	  for (i = 0; i < n; ++i)
2273*e4b17023SJohn Marino 	    t *= t;
2274*e4b17023SJohn Marino 
2275*e4b17023SJohn Marino 	  real_from_integer (&tens[n], VOIDmode, t, 0, 1);
2276*e4b17023SJohn Marino 	}
2277*e4b17023SJohn Marino       else
2278*e4b17023SJohn Marino 	{
2279*e4b17023SJohn Marino 	  const REAL_VALUE_TYPE *t = ten_to_ptwo (n - 1);
2280*e4b17023SJohn Marino 	  do_multiply (&tens[n], t, t);
2281*e4b17023SJohn Marino 	}
2282*e4b17023SJohn Marino     }
2283*e4b17023SJohn Marino 
2284*e4b17023SJohn Marino   return &tens[n];
2285*e4b17023SJohn Marino }
2286*e4b17023SJohn Marino 
2287*e4b17023SJohn Marino /* Returns 10**(-2**N).  */
2288*e4b17023SJohn Marino 
2289*e4b17023SJohn Marino static const REAL_VALUE_TYPE *
ten_to_mptwo(int n)2290*e4b17023SJohn Marino ten_to_mptwo (int n)
2291*e4b17023SJohn Marino {
2292*e4b17023SJohn Marino   static REAL_VALUE_TYPE tens[EXP_BITS];
2293*e4b17023SJohn Marino 
2294*e4b17023SJohn Marino   gcc_assert (n >= 0);
2295*e4b17023SJohn Marino   gcc_assert (n < EXP_BITS);
2296*e4b17023SJohn Marino 
2297*e4b17023SJohn Marino   if (tens[n].cl == rvc_zero)
2298*e4b17023SJohn Marino     do_divide (&tens[n], real_digit (1), ten_to_ptwo (n));
2299*e4b17023SJohn Marino 
2300*e4b17023SJohn Marino   return &tens[n];
2301*e4b17023SJohn Marino }
2302*e4b17023SJohn Marino 
2303*e4b17023SJohn Marino /* Returns N.  */
2304*e4b17023SJohn Marino 
2305*e4b17023SJohn Marino static const REAL_VALUE_TYPE *
real_digit(int n)2306*e4b17023SJohn Marino real_digit (int n)
2307*e4b17023SJohn Marino {
2308*e4b17023SJohn Marino   static REAL_VALUE_TYPE num[10];
2309*e4b17023SJohn Marino 
2310*e4b17023SJohn Marino   gcc_assert (n >= 0);
2311*e4b17023SJohn Marino   gcc_assert (n <= 9);
2312*e4b17023SJohn Marino 
2313*e4b17023SJohn Marino   if (n > 0 && num[n].cl == rvc_zero)
2314*e4b17023SJohn Marino     real_from_integer (&num[n], VOIDmode, n, 0, 1);
2315*e4b17023SJohn Marino 
2316*e4b17023SJohn Marino   return &num[n];
2317*e4b17023SJohn Marino }
2318*e4b17023SJohn Marino 
2319*e4b17023SJohn Marino /* Multiply R by 10**EXP.  */
2320*e4b17023SJohn Marino 
2321*e4b17023SJohn Marino static void
times_pten(REAL_VALUE_TYPE * r,int exp)2322*e4b17023SJohn Marino times_pten (REAL_VALUE_TYPE *r, int exp)
2323*e4b17023SJohn Marino {
2324*e4b17023SJohn Marino   REAL_VALUE_TYPE pten, *rr;
2325*e4b17023SJohn Marino   bool negative = (exp < 0);
2326*e4b17023SJohn Marino   int i;
2327*e4b17023SJohn Marino 
2328*e4b17023SJohn Marino   if (negative)
2329*e4b17023SJohn Marino     {
2330*e4b17023SJohn Marino       exp = -exp;
2331*e4b17023SJohn Marino       pten = *real_digit (1);
2332*e4b17023SJohn Marino       rr = &pten;
2333*e4b17023SJohn Marino     }
2334*e4b17023SJohn Marino   else
2335*e4b17023SJohn Marino     rr = r;
2336*e4b17023SJohn Marino 
2337*e4b17023SJohn Marino   for (i = 0; exp > 0; ++i, exp >>= 1)
2338*e4b17023SJohn Marino     if (exp & 1)
2339*e4b17023SJohn Marino       do_multiply (rr, rr, ten_to_ptwo (i));
2340*e4b17023SJohn Marino 
2341*e4b17023SJohn Marino   if (negative)
2342*e4b17023SJohn Marino     do_divide (r, r, &pten);
2343*e4b17023SJohn Marino }
2344*e4b17023SJohn Marino 
2345*e4b17023SJohn Marino /* Returns the special REAL_VALUE_TYPE corresponding to 'e'.  */
2346*e4b17023SJohn Marino 
2347*e4b17023SJohn Marino const REAL_VALUE_TYPE *
dconst_e_ptr(void)2348*e4b17023SJohn Marino dconst_e_ptr (void)
2349*e4b17023SJohn Marino {
2350*e4b17023SJohn Marino   static REAL_VALUE_TYPE value;
2351*e4b17023SJohn Marino 
2352*e4b17023SJohn Marino   /* Initialize mathematical constants for constant folding builtins.
2353*e4b17023SJohn Marino      These constants need to be given to at least 160 bits precision.  */
2354*e4b17023SJohn Marino   if (value.cl == rvc_zero)
2355*e4b17023SJohn Marino     {
2356*e4b17023SJohn Marino       mpfr_t m;
2357*e4b17023SJohn Marino       mpfr_init2 (m, SIGNIFICAND_BITS);
2358*e4b17023SJohn Marino       mpfr_set_ui (m, 1, GMP_RNDN);
2359*e4b17023SJohn Marino       mpfr_exp (m, m, GMP_RNDN);
2360*e4b17023SJohn Marino       real_from_mpfr (&value, m, NULL_TREE, GMP_RNDN);
2361*e4b17023SJohn Marino       mpfr_clear (m);
2362*e4b17023SJohn Marino 
2363*e4b17023SJohn Marino     }
2364*e4b17023SJohn Marino   return &value;
2365*e4b17023SJohn Marino }
2366*e4b17023SJohn Marino 
2367*e4b17023SJohn Marino /* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */
2368*e4b17023SJohn Marino 
2369*e4b17023SJohn Marino const REAL_VALUE_TYPE *
dconst_third_ptr(void)2370*e4b17023SJohn Marino dconst_third_ptr (void)
2371*e4b17023SJohn Marino {
2372*e4b17023SJohn Marino   static REAL_VALUE_TYPE value;
2373*e4b17023SJohn Marino 
2374*e4b17023SJohn Marino   /* Initialize mathematical constants for constant folding builtins.
2375*e4b17023SJohn Marino      These constants need to be given to at least 160 bits precision.  */
2376*e4b17023SJohn Marino   if (value.cl == rvc_zero)
2377*e4b17023SJohn Marino     {
2378*e4b17023SJohn Marino       real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (3));
2379*e4b17023SJohn Marino     }
2380*e4b17023SJohn Marino   return &value;
2381*e4b17023SJohn Marino }
2382*e4b17023SJohn Marino 
2383*e4b17023SJohn Marino /* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2).  */
2384*e4b17023SJohn Marino 
2385*e4b17023SJohn Marino const REAL_VALUE_TYPE *
dconst_sqrt2_ptr(void)2386*e4b17023SJohn Marino dconst_sqrt2_ptr (void)
2387*e4b17023SJohn Marino {
2388*e4b17023SJohn Marino   static REAL_VALUE_TYPE value;
2389*e4b17023SJohn Marino 
2390*e4b17023SJohn Marino   /* Initialize mathematical constants for constant folding builtins.
2391*e4b17023SJohn Marino      These constants need to be given to at least 160 bits precision.  */
2392*e4b17023SJohn Marino   if (value.cl == rvc_zero)
2393*e4b17023SJohn Marino     {
2394*e4b17023SJohn Marino       mpfr_t m;
2395*e4b17023SJohn Marino       mpfr_init2 (m, SIGNIFICAND_BITS);
2396*e4b17023SJohn Marino       mpfr_sqrt_ui (m, 2, GMP_RNDN);
2397*e4b17023SJohn Marino       real_from_mpfr (&value, m, NULL_TREE, GMP_RNDN);
2398*e4b17023SJohn Marino       mpfr_clear (m);
2399*e4b17023SJohn Marino     }
2400*e4b17023SJohn Marino   return &value;
2401*e4b17023SJohn Marino }
2402*e4b17023SJohn Marino 
2403*e4b17023SJohn Marino /* Fills R with +Inf.  */
2404*e4b17023SJohn Marino 
2405*e4b17023SJohn Marino void
real_inf(REAL_VALUE_TYPE * r)2406*e4b17023SJohn Marino real_inf (REAL_VALUE_TYPE *r)
2407*e4b17023SJohn Marino {
2408*e4b17023SJohn Marino   get_inf (r, 0);
2409*e4b17023SJohn Marino }
2410*e4b17023SJohn Marino 
2411*e4b17023SJohn Marino /* Fills R with a NaN whose significand is described by STR.  If QUIET,
2412*e4b17023SJohn Marino    we force a QNaN, else we force an SNaN.  The string, if not empty,
2413*e4b17023SJohn Marino    is parsed as a number and placed in the significand.  Return true
2414*e4b17023SJohn Marino    if the string was successfully parsed.  */
2415*e4b17023SJohn Marino 
2416*e4b17023SJohn Marino bool
real_nan(REAL_VALUE_TYPE * r,const char * str,int quiet,enum machine_mode mode)2417*e4b17023SJohn Marino real_nan (REAL_VALUE_TYPE *r, const char *str, int quiet,
2418*e4b17023SJohn Marino 	  enum machine_mode mode)
2419*e4b17023SJohn Marino {
2420*e4b17023SJohn Marino   const struct real_format *fmt;
2421*e4b17023SJohn Marino 
2422*e4b17023SJohn Marino   fmt = REAL_MODE_FORMAT (mode);
2423*e4b17023SJohn Marino   gcc_assert (fmt);
2424*e4b17023SJohn Marino 
2425*e4b17023SJohn Marino   if (*str == 0)
2426*e4b17023SJohn Marino     {
2427*e4b17023SJohn Marino       if (quiet)
2428*e4b17023SJohn Marino 	get_canonical_qnan (r, 0);
2429*e4b17023SJohn Marino       else
2430*e4b17023SJohn Marino 	get_canonical_snan (r, 0);
2431*e4b17023SJohn Marino     }
2432*e4b17023SJohn Marino   else
2433*e4b17023SJohn Marino     {
2434*e4b17023SJohn Marino       int base = 10, d;
2435*e4b17023SJohn Marino 
2436*e4b17023SJohn Marino       memset (r, 0, sizeof (*r));
2437*e4b17023SJohn Marino       r->cl = rvc_nan;
2438*e4b17023SJohn Marino 
2439*e4b17023SJohn Marino       /* Parse akin to strtol into the significand of R.  */
2440*e4b17023SJohn Marino 
2441*e4b17023SJohn Marino       while (ISSPACE (*str))
2442*e4b17023SJohn Marino 	str++;
2443*e4b17023SJohn Marino       if (*str == '-')
2444*e4b17023SJohn Marino 	str++;
2445*e4b17023SJohn Marino       else if (*str == '+')
2446*e4b17023SJohn Marino 	str++;
2447*e4b17023SJohn Marino       if (*str == '0')
2448*e4b17023SJohn Marino 	{
2449*e4b17023SJohn Marino 	  str++;
2450*e4b17023SJohn Marino 	  if (*str == 'x' || *str == 'X')
2451*e4b17023SJohn Marino 	    {
2452*e4b17023SJohn Marino 	      base = 16;
2453*e4b17023SJohn Marino 	      str++;
2454*e4b17023SJohn Marino 	    }
2455*e4b17023SJohn Marino 	  else
2456*e4b17023SJohn Marino 	    base = 8;
2457*e4b17023SJohn Marino 	}
2458*e4b17023SJohn Marino 
2459*e4b17023SJohn Marino       while ((d = hex_value (*str)) < base)
2460*e4b17023SJohn Marino 	{
2461*e4b17023SJohn Marino 	  REAL_VALUE_TYPE u;
2462*e4b17023SJohn Marino 
2463*e4b17023SJohn Marino 	  switch (base)
2464*e4b17023SJohn Marino 	    {
2465*e4b17023SJohn Marino 	    case 8:
2466*e4b17023SJohn Marino 	      lshift_significand (r, r, 3);
2467*e4b17023SJohn Marino 	      break;
2468*e4b17023SJohn Marino 	    case 16:
2469*e4b17023SJohn Marino 	      lshift_significand (r, r, 4);
2470*e4b17023SJohn Marino 	      break;
2471*e4b17023SJohn Marino 	    case 10:
2472*e4b17023SJohn Marino 	      lshift_significand_1 (&u, r);
2473*e4b17023SJohn Marino 	      lshift_significand (r, r, 3);
2474*e4b17023SJohn Marino 	      add_significands (r, r, &u);
2475*e4b17023SJohn Marino 	      break;
2476*e4b17023SJohn Marino 	    default:
2477*e4b17023SJohn Marino 	      gcc_unreachable ();
2478*e4b17023SJohn Marino 	    }
2479*e4b17023SJohn Marino 
2480*e4b17023SJohn Marino 	  get_zero (&u, 0);
2481*e4b17023SJohn Marino 	  u.sig[0] = d;
2482*e4b17023SJohn Marino 	  add_significands (r, r, &u);
2483*e4b17023SJohn Marino 
2484*e4b17023SJohn Marino 	  str++;
2485*e4b17023SJohn Marino 	}
2486*e4b17023SJohn Marino 
2487*e4b17023SJohn Marino       /* Must have consumed the entire string for success.  */
2488*e4b17023SJohn Marino       if (*str != 0)
2489*e4b17023SJohn Marino 	return false;
2490*e4b17023SJohn Marino 
2491*e4b17023SJohn Marino       /* Shift the significand into place such that the bits
2492*e4b17023SJohn Marino 	 are in the most significant bits for the format.  */
2493*e4b17023SJohn Marino       lshift_significand (r, r, SIGNIFICAND_BITS - fmt->pnan);
2494*e4b17023SJohn Marino 
2495*e4b17023SJohn Marino       /* Our MSB is always unset for NaNs.  */
2496*e4b17023SJohn Marino       r->sig[SIGSZ-1] &= ~SIG_MSB;
2497*e4b17023SJohn Marino 
2498*e4b17023SJohn Marino       /* Force quiet or signalling NaN.  */
2499*e4b17023SJohn Marino       r->signalling = !quiet;
2500*e4b17023SJohn Marino     }
2501*e4b17023SJohn Marino 
2502*e4b17023SJohn Marino   return true;
2503*e4b17023SJohn Marino }
2504*e4b17023SJohn Marino 
2505*e4b17023SJohn Marino /* Fills R with the largest finite value representable in mode MODE.
2506*e4b17023SJohn Marino    If SIGN is nonzero, R is set to the most negative finite value.  */
2507*e4b17023SJohn Marino 
2508*e4b17023SJohn Marino void
real_maxval(REAL_VALUE_TYPE * r,int sign,enum machine_mode mode)2509*e4b17023SJohn Marino real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
2510*e4b17023SJohn Marino {
2511*e4b17023SJohn Marino   const struct real_format *fmt;
2512*e4b17023SJohn Marino   int np2;
2513*e4b17023SJohn Marino 
2514*e4b17023SJohn Marino   fmt = REAL_MODE_FORMAT (mode);
2515*e4b17023SJohn Marino   gcc_assert (fmt);
2516*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
2517*e4b17023SJohn Marino 
2518*e4b17023SJohn Marino   if (fmt->b == 10)
2519*e4b17023SJohn Marino     decimal_real_maxval (r, sign, mode);
2520*e4b17023SJohn Marino   else
2521*e4b17023SJohn Marino     {
2522*e4b17023SJohn Marino       r->cl = rvc_normal;
2523*e4b17023SJohn Marino       r->sign = sign;
2524*e4b17023SJohn Marino       SET_REAL_EXP (r, fmt->emax);
2525*e4b17023SJohn Marino 
2526*e4b17023SJohn Marino       np2 = SIGNIFICAND_BITS - fmt->p;
2527*e4b17023SJohn Marino       memset (r->sig, -1, SIGSZ * sizeof (unsigned long));
2528*e4b17023SJohn Marino       clear_significand_below (r, np2);
2529*e4b17023SJohn Marino 
2530*e4b17023SJohn Marino       if (fmt->pnan < fmt->p)
2531*e4b17023SJohn Marino 	/* This is an IBM extended double format made up of two IEEE
2532*e4b17023SJohn Marino 	   doubles.  The value of the long double is the sum of the
2533*e4b17023SJohn Marino 	   values of the two parts.  The most significant part is
2534*e4b17023SJohn Marino 	   required to be the value of the long double rounded to the
2535*e4b17023SJohn Marino 	   nearest double.  Rounding means we need a slightly smaller
2536*e4b17023SJohn Marino 	   value for LDBL_MAX.  */
2537*e4b17023SJohn Marino 	clear_significand_bit (r, SIGNIFICAND_BITS - fmt->pnan - 1);
2538*e4b17023SJohn Marino     }
2539*e4b17023SJohn Marino }
2540*e4b17023SJohn Marino 
2541*e4b17023SJohn Marino /* Fills R with 2**N.  */
2542*e4b17023SJohn Marino 
2543*e4b17023SJohn Marino void
real_2expN(REAL_VALUE_TYPE * r,int n,enum machine_mode fmode)2544*e4b17023SJohn Marino real_2expN (REAL_VALUE_TYPE *r, int n, enum machine_mode fmode)
2545*e4b17023SJohn Marino {
2546*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
2547*e4b17023SJohn Marino 
2548*e4b17023SJohn Marino   n++;
2549*e4b17023SJohn Marino   if (n > MAX_EXP)
2550*e4b17023SJohn Marino     r->cl = rvc_inf;
2551*e4b17023SJohn Marino   else if (n < -MAX_EXP)
2552*e4b17023SJohn Marino     ;
2553*e4b17023SJohn Marino   else
2554*e4b17023SJohn Marino     {
2555*e4b17023SJohn Marino       r->cl = rvc_normal;
2556*e4b17023SJohn Marino       SET_REAL_EXP (r, n);
2557*e4b17023SJohn Marino       r->sig[SIGSZ-1] = SIG_MSB;
2558*e4b17023SJohn Marino     }
2559*e4b17023SJohn Marino   if (DECIMAL_FLOAT_MODE_P (fmode))
2560*e4b17023SJohn Marino     decimal_real_convert (r, fmode, r);
2561*e4b17023SJohn Marino }
2562*e4b17023SJohn Marino 
2563*e4b17023SJohn Marino 
2564*e4b17023SJohn Marino static void
round_for_format(const struct real_format * fmt,REAL_VALUE_TYPE * r)2565*e4b17023SJohn Marino round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
2566*e4b17023SJohn Marino {
2567*e4b17023SJohn Marino   int p2, np2, i, w;
2568*e4b17023SJohn Marino   int emin2m1, emax2;
2569*e4b17023SJohn Marino   bool round_up = false;
2570*e4b17023SJohn Marino 
2571*e4b17023SJohn Marino   if (r->decimal)
2572*e4b17023SJohn Marino     {
2573*e4b17023SJohn Marino       if (fmt->b == 10)
2574*e4b17023SJohn Marino 	{
2575*e4b17023SJohn Marino 	  decimal_round_for_format (fmt, r);
2576*e4b17023SJohn Marino 	  return;
2577*e4b17023SJohn Marino 	}
2578*e4b17023SJohn Marino       /* FIXME. We can come here via fp_easy_constant
2579*e4b17023SJohn Marino 	 (e.g. -O0 on '_Decimal32 x = 1.0 + 2.0dd'), but have not
2580*e4b17023SJohn Marino 	 investigated whether this convert needs to be here, or
2581*e4b17023SJohn Marino 	 something else is missing. */
2582*e4b17023SJohn Marino       decimal_real_convert (r, DFmode, r);
2583*e4b17023SJohn Marino     }
2584*e4b17023SJohn Marino 
2585*e4b17023SJohn Marino   p2 = fmt->p;
2586*e4b17023SJohn Marino   emin2m1 = fmt->emin - 1;
2587*e4b17023SJohn Marino   emax2 = fmt->emax;
2588*e4b17023SJohn Marino 
2589*e4b17023SJohn Marino   np2 = SIGNIFICAND_BITS - p2;
2590*e4b17023SJohn Marino   switch (r->cl)
2591*e4b17023SJohn Marino     {
2592*e4b17023SJohn Marino     underflow:
2593*e4b17023SJohn Marino       get_zero (r, r->sign);
2594*e4b17023SJohn Marino     case rvc_zero:
2595*e4b17023SJohn Marino       if (!fmt->has_signed_zero)
2596*e4b17023SJohn Marino 	r->sign = 0;
2597*e4b17023SJohn Marino       return;
2598*e4b17023SJohn Marino 
2599*e4b17023SJohn Marino     overflow:
2600*e4b17023SJohn Marino       get_inf (r, r->sign);
2601*e4b17023SJohn Marino     case rvc_inf:
2602*e4b17023SJohn Marino       return;
2603*e4b17023SJohn Marino 
2604*e4b17023SJohn Marino     case rvc_nan:
2605*e4b17023SJohn Marino       clear_significand_below (r, np2);
2606*e4b17023SJohn Marino       return;
2607*e4b17023SJohn Marino 
2608*e4b17023SJohn Marino     case rvc_normal:
2609*e4b17023SJohn Marino       break;
2610*e4b17023SJohn Marino 
2611*e4b17023SJohn Marino     default:
2612*e4b17023SJohn Marino       gcc_unreachable ();
2613*e4b17023SJohn Marino     }
2614*e4b17023SJohn Marino 
2615*e4b17023SJohn Marino   /* Check the range of the exponent.  If we're out of range,
2616*e4b17023SJohn Marino      either underflow or overflow.  */
2617*e4b17023SJohn Marino   if (REAL_EXP (r) > emax2)
2618*e4b17023SJohn Marino     goto overflow;
2619*e4b17023SJohn Marino   else if (REAL_EXP (r) <= emin2m1)
2620*e4b17023SJohn Marino     {
2621*e4b17023SJohn Marino       int diff;
2622*e4b17023SJohn Marino 
2623*e4b17023SJohn Marino       if (!fmt->has_denorm)
2624*e4b17023SJohn Marino 	{
2625*e4b17023SJohn Marino 	  /* Don't underflow completely until we've had a chance to round.  */
2626*e4b17023SJohn Marino 	  if (REAL_EXP (r) < emin2m1)
2627*e4b17023SJohn Marino 	    goto underflow;
2628*e4b17023SJohn Marino 	}
2629*e4b17023SJohn Marino       else
2630*e4b17023SJohn Marino 	{
2631*e4b17023SJohn Marino 	  diff = emin2m1 - REAL_EXP (r) + 1;
2632*e4b17023SJohn Marino 	  if (diff > p2)
2633*e4b17023SJohn Marino 	    goto underflow;
2634*e4b17023SJohn Marino 
2635*e4b17023SJohn Marino 	  /* De-normalize the significand.  */
2636*e4b17023SJohn Marino 	  r->sig[0] |= sticky_rshift_significand (r, r, diff);
2637*e4b17023SJohn Marino 	  SET_REAL_EXP (r, REAL_EXP (r) + diff);
2638*e4b17023SJohn Marino 	}
2639*e4b17023SJohn Marino     }
2640*e4b17023SJohn Marino 
2641*e4b17023SJohn Marino   if (!fmt->round_towards_zero)
2642*e4b17023SJohn Marino     {
2643*e4b17023SJohn Marino       /* There are P2 true significand bits, followed by one guard bit,
2644*e4b17023SJohn Marino          followed by one sticky bit, followed by stuff.  Fold nonzero
2645*e4b17023SJohn Marino          stuff into the sticky bit.  */
2646*e4b17023SJohn Marino       unsigned long sticky;
2647*e4b17023SJohn Marino       bool guard, lsb;
2648*e4b17023SJohn Marino 
2649*e4b17023SJohn Marino       sticky = 0;
2650*e4b17023SJohn Marino       for (i = 0, w = (np2 - 1) / HOST_BITS_PER_LONG; i < w; ++i)
2651*e4b17023SJohn Marino 	sticky |= r->sig[i];
2652*e4b17023SJohn Marino       sticky |= r->sig[w]
2653*e4b17023SJohn Marino 		& (((unsigned long)1 << ((np2 - 1) % HOST_BITS_PER_LONG)) - 1);
2654*e4b17023SJohn Marino 
2655*e4b17023SJohn Marino       guard = test_significand_bit (r, np2 - 1);
2656*e4b17023SJohn Marino       lsb = test_significand_bit (r, np2);
2657*e4b17023SJohn Marino 
2658*e4b17023SJohn Marino       /* Round to even.  */
2659*e4b17023SJohn Marino       round_up = guard && (sticky || lsb);
2660*e4b17023SJohn Marino     }
2661*e4b17023SJohn Marino 
2662*e4b17023SJohn Marino   if (round_up)
2663*e4b17023SJohn Marino     {
2664*e4b17023SJohn Marino       REAL_VALUE_TYPE u;
2665*e4b17023SJohn Marino       get_zero (&u, 0);
2666*e4b17023SJohn Marino       set_significand_bit (&u, np2);
2667*e4b17023SJohn Marino 
2668*e4b17023SJohn Marino       if (add_significands (r, r, &u))
2669*e4b17023SJohn Marino 	{
2670*e4b17023SJohn Marino 	  /* Overflow.  Means the significand had been all ones, and
2671*e4b17023SJohn Marino 	     is now all zeros.  Need to increase the exponent, and
2672*e4b17023SJohn Marino 	     possibly re-normalize it.  */
2673*e4b17023SJohn Marino 	  SET_REAL_EXP (r, REAL_EXP (r) + 1);
2674*e4b17023SJohn Marino 	  if (REAL_EXP (r) > emax2)
2675*e4b17023SJohn Marino 	    goto overflow;
2676*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = SIG_MSB;
2677*e4b17023SJohn Marino 	}
2678*e4b17023SJohn Marino     }
2679*e4b17023SJohn Marino 
2680*e4b17023SJohn Marino   /* Catch underflow that we deferred until after rounding.  */
2681*e4b17023SJohn Marino   if (REAL_EXP (r) <= emin2m1)
2682*e4b17023SJohn Marino     goto underflow;
2683*e4b17023SJohn Marino 
2684*e4b17023SJohn Marino   /* Clear out trailing garbage.  */
2685*e4b17023SJohn Marino   clear_significand_below (r, np2);
2686*e4b17023SJohn Marino }
2687*e4b17023SJohn Marino 
2688*e4b17023SJohn Marino /* Extend or truncate to a new mode.  */
2689*e4b17023SJohn Marino 
2690*e4b17023SJohn Marino void
real_convert(REAL_VALUE_TYPE * r,enum machine_mode mode,const REAL_VALUE_TYPE * a)2691*e4b17023SJohn Marino real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode,
2692*e4b17023SJohn Marino 	      const REAL_VALUE_TYPE *a)
2693*e4b17023SJohn Marino {
2694*e4b17023SJohn Marino   const struct real_format *fmt;
2695*e4b17023SJohn Marino 
2696*e4b17023SJohn Marino   fmt = REAL_MODE_FORMAT (mode);
2697*e4b17023SJohn Marino   gcc_assert (fmt);
2698*e4b17023SJohn Marino 
2699*e4b17023SJohn Marino   *r = *a;
2700*e4b17023SJohn Marino 
2701*e4b17023SJohn Marino   if (a->decimal || fmt->b == 10)
2702*e4b17023SJohn Marino     decimal_real_convert (r, mode, a);
2703*e4b17023SJohn Marino 
2704*e4b17023SJohn Marino   round_for_format (fmt, r);
2705*e4b17023SJohn Marino 
2706*e4b17023SJohn Marino   /* round_for_format de-normalizes denormals.  Undo just that part.  */
2707*e4b17023SJohn Marino   if (r->cl == rvc_normal)
2708*e4b17023SJohn Marino     normalize (r);
2709*e4b17023SJohn Marino }
2710*e4b17023SJohn Marino 
2711*e4b17023SJohn Marino /* Legacy.  Likewise, except return the struct directly.  */
2712*e4b17023SJohn Marino 
2713*e4b17023SJohn Marino REAL_VALUE_TYPE
real_value_truncate(enum machine_mode mode,REAL_VALUE_TYPE a)2714*e4b17023SJohn Marino real_value_truncate (enum machine_mode mode, REAL_VALUE_TYPE a)
2715*e4b17023SJohn Marino {
2716*e4b17023SJohn Marino   REAL_VALUE_TYPE r;
2717*e4b17023SJohn Marino   real_convert (&r, mode, &a);
2718*e4b17023SJohn Marino   return r;
2719*e4b17023SJohn Marino }
2720*e4b17023SJohn Marino 
2721*e4b17023SJohn Marino /* Return true if truncating to MODE is exact.  */
2722*e4b17023SJohn Marino 
2723*e4b17023SJohn Marino bool
exact_real_truncate(enum machine_mode mode,const REAL_VALUE_TYPE * a)2724*e4b17023SJohn Marino exact_real_truncate (enum machine_mode mode, const REAL_VALUE_TYPE *a)
2725*e4b17023SJohn Marino {
2726*e4b17023SJohn Marino   const struct real_format *fmt;
2727*e4b17023SJohn Marino   REAL_VALUE_TYPE t;
2728*e4b17023SJohn Marino   int emin2m1;
2729*e4b17023SJohn Marino 
2730*e4b17023SJohn Marino   fmt = REAL_MODE_FORMAT (mode);
2731*e4b17023SJohn Marino   gcc_assert (fmt);
2732*e4b17023SJohn Marino 
2733*e4b17023SJohn Marino   /* Don't allow conversion to denormals.  */
2734*e4b17023SJohn Marino   emin2m1 = fmt->emin - 1;
2735*e4b17023SJohn Marino   if (REAL_EXP (a) <= emin2m1)
2736*e4b17023SJohn Marino     return false;
2737*e4b17023SJohn Marino 
2738*e4b17023SJohn Marino   /* After conversion to the new mode, the value must be identical.  */
2739*e4b17023SJohn Marino   real_convert (&t, mode, a);
2740*e4b17023SJohn Marino   return real_identical (&t, a);
2741*e4b17023SJohn Marino }
2742*e4b17023SJohn Marino 
2743*e4b17023SJohn Marino /* Write R to the given target format.  Place the words of the result
2744*e4b17023SJohn Marino    in target word order in BUF.  There are always 32 bits in each
2745*e4b17023SJohn Marino    long, no matter the size of the host long.
2746*e4b17023SJohn Marino 
2747*e4b17023SJohn Marino    Legacy: return word 0 for implementing REAL_VALUE_TO_TARGET_SINGLE.  */
2748*e4b17023SJohn Marino 
2749*e4b17023SJohn Marino long
real_to_target_fmt(long * buf,const REAL_VALUE_TYPE * r_orig,const struct real_format * fmt)2750*e4b17023SJohn Marino real_to_target_fmt (long *buf, const REAL_VALUE_TYPE *r_orig,
2751*e4b17023SJohn Marino 		    const struct real_format *fmt)
2752*e4b17023SJohn Marino {
2753*e4b17023SJohn Marino   REAL_VALUE_TYPE r;
2754*e4b17023SJohn Marino   long buf1;
2755*e4b17023SJohn Marino 
2756*e4b17023SJohn Marino   r = *r_orig;
2757*e4b17023SJohn Marino   round_for_format (fmt, &r);
2758*e4b17023SJohn Marino 
2759*e4b17023SJohn Marino   if (!buf)
2760*e4b17023SJohn Marino     buf = &buf1;
2761*e4b17023SJohn Marino   (*fmt->encode) (fmt, buf, &r);
2762*e4b17023SJohn Marino 
2763*e4b17023SJohn Marino   return *buf;
2764*e4b17023SJohn Marino }
2765*e4b17023SJohn Marino 
2766*e4b17023SJohn Marino /* Similar, but look up the format from MODE.  */
2767*e4b17023SJohn Marino 
2768*e4b17023SJohn Marino long
real_to_target(long * buf,const REAL_VALUE_TYPE * r,enum machine_mode mode)2769*e4b17023SJohn Marino real_to_target (long *buf, const REAL_VALUE_TYPE *r, enum machine_mode mode)
2770*e4b17023SJohn Marino {
2771*e4b17023SJohn Marino   const struct real_format *fmt;
2772*e4b17023SJohn Marino 
2773*e4b17023SJohn Marino   fmt = REAL_MODE_FORMAT (mode);
2774*e4b17023SJohn Marino   gcc_assert (fmt);
2775*e4b17023SJohn Marino 
2776*e4b17023SJohn Marino   return real_to_target_fmt (buf, r, fmt);
2777*e4b17023SJohn Marino }
2778*e4b17023SJohn Marino 
2779*e4b17023SJohn Marino /* Read R from the given target format.  Read the words of the result
2780*e4b17023SJohn Marino    in target word order in BUF.  There are always 32 bits in each
2781*e4b17023SJohn Marino    long, no matter the size of the host long.  */
2782*e4b17023SJohn Marino 
2783*e4b17023SJohn Marino void
real_from_target_fmt(REAL_VALUE_TYPE * r,const long * buf,const struct real_format * fmt)2784*e4b17023SJohn Marino real_from_target_fmt (REAL_VALUE_TYPE *r, const long *buf,
2785*e4b17023SJohn Marino 		      const struct real_format *fmt)
2786*e4b17023SJohn Marino {
2787*e4b17023SJohn Marino   (*fmt->decode) (fmt, r, buf);
2788*e4b17023SJohn Marino }
2789*e4b17023SJohn Marino 
2790*e4b17023SJohn Marino /* Similar, but look up the format from MODE.  */
2791*e4b17023SJohn Marino 
2792*e4b17023SJohn Marino void
real_from_target(REAL_VALUE_TYPE * r,const long * buf,enum machine_mode mode)2793*e4b17023SJohn Marino real_from_target (REAL_VALUE_TYPE *r, const long *buf, enum machine_mode mode)
2794*e4b17023SJohn Marino {
2795*e4b17023SJohn Marino   const struct real_format *fmt;
2796*e4b17023SJohn Marino 
2797*e4b17023SJohn Marino   fmt = REAL_MODE_FORMAT (mode);
2798*e4b17023SJohn Marino   gcc_assert (fmt);
2799*e4b17023SJohn Marino 
2800*e4b17023SJohn Marino   (*fmt->decode) (fmt, r, buf);
2801*e4b17023SJohn Marino }
2802*e4b17023SJohn Marino 
2803*e4b17023SJohn Marino /* Return the number of bits of the largest binary value that the
2804*e4b17023SJohn Marino    significand of MODE will hold.  */
2805*e4b17023SJohn Marino /* ??? Legacy.  Should get access to real_format directly.  */
2806*e4b17023SJohn Marino 
2807*e4b17023SJohn Marino int
significand_size(enum machine_mode mode)2808*e4b17023SJohn Marino significand_size (enum machine_mode mode)
2809*e4b17023SJohn Marino {
2810*e4b17023SJohn Marino   const struct real_format *fmt;
2811*e4b17023SJohn Marino 
2812*e4b17023SJohn Marino   fmt = REAL_MODE_FORMAT (mode);
2813*e4b17023SJohn Marino   if (fmt == NULL)
2814*e4b17023SJohn Marino     return 0;
2815*e4b17023SJohn Marino 
2816*e4b17023SJohn Marino   if (fmt->b == 10)
2817*e4b17023SJohn Marino     {
2818*e4b17023SJohn Marino       /* Return the size in bits of the largest binary value that can be
2819*e4b17023SJohn Marino 	 held by the decimal coefficient for this mode.  This is one more
2820*e4b17023SJohn Marino 	 than the number of bits required to hold the largest coefficient
2821*e4b17023SJohn Marino 	 of this mode.  */
2822*e4b17023SJohn Marino       double log2_10 = 3.3219281;
2823*e4b17023SJohn Marino       return fmt->p * log2_10;
2824*e4b17023SJohn Marino     }
2825*e4b17023SJohn Marino   return fmt->p;
2826*e4b17023SJohn Marino }
2827*e4b17023SJohn Marino 
2828*e4b17023SJohn Marino /* Return a hash value for the given real value.  */
2829*e4b17023SJohn Marino /* ??? The "unsigned int" return value is intended to be hashval_t,
2830*e4b17023SJohn Marino    but I didn't want to pull hashtab.h into real.h.  */
2831*e4b17023SJohn Marino 
2832*e4b17023SJohn Marino unsigned int
real_hash(const REAL_VALUE_TYPE * r)2833*e4b17023SJohn Marino real_hash (const REAL_VALUE_TYPE *r)
2834*e4b17023SJohn Marino {
2835*e4b17023SJohn Marino   unsigned int h;
2836*e4b17023SJohn Marino   size_t i;
2837*e4b17023SJohn Marino 
2838*e4b17023SJohn Marino   h = r->cl | (r->sign << 2);
2839*e4b17023SJohn Marino   switch (r->cl)
2840*e4b17023SJohn Marino     {
2841*e4b17023SJohn Marino     case rvc_zero:
2842*e4b17023SJohn Marino     case rvc_inf:
2843*e4b17023SJohn Marino       return h;
2844*e4b17023SJohn Marino 
2845*e4b17023SJohn Marino     case rvc_normal:
2846*e4b17023SJohn Marino       h |= REAL_EXP (r) << 3;
2847*e4b17023SJohn Marino       break;
2848*e4b17023SJohn Marino 
2849*e4b17023SJohn Marino     case rvc_nan:
2850*e4b17023SJohn Marino       if (r->signalling)
2851*e4b17023SJohn Marino 	h ^= (unsigned int)-1;
2852*e4b17023SJohn Marino       if (r->canonical)
2853*e4b17023SJohn Marino 	return h;
2854*e4b17023SJohn Marino       break;
2855*e4b17023SJohn Marino 
2856*e4b17023SJohn Marino     default:
2857*e4b17023SJohn Marino       gcc_unreachable ();
2858*e4b17023SJohn Marino     }
2859*e4b17023SJohn Marino 
2860*e4b17023SJohn Marino   if (sizeof(unsigned long) > sizeof(unsigned int))
2861*e4b17023SJohn Marino     for (i = 0; i < SIGSZ; ++i)
2862*e4b17023SJohn Marino       {
2863*e4b17023SJohn Marino 	unsigned long s = r->sig[i];
2864*e4b17023SJohn Marino 	h ^= s ^ (s >> (HOST_BITS_PER_LONG / 2));
2865*e4b17023SJohn Marino       }
2866*e4b17023SJohn Marino   else
2867*e4b17023SJohn Marino     for (i = 0; i < SIGSZ; ++i)
2868*e4b17023SJohn Marino       h ^= r->sig[i];
2869*e4b17023SJohn Marino 
2870*e4b17023SJohn Marino   return h;
2871*e4b17023SJohn Marino }
2872*e4b17023SJohn Marino 
2873*e4b17023SJohn Marino /* IEEE single-precision format.  */
2874*e4b17023SJohn Marino 
2875*e4b17023SJohn Marino static void encode_ieee_single (const struct real_format *fmt,
2876*e4b17023SJohn Marino 				long *, const REAL_VALUE_TYPE *);
2877*e4b17023SJohn Marino static void decode_ieee_single (const struct real_format *,
2878*e4b17023SJohn Marino 				REAL_VALUE_TYPE *, const long *);
2879*e4b17023SJohn Marino 
2880*e4b17023SJohn Marino static void
encode_ieee_single(const struct real_format * fmt,long * buf,const REAL_VALUE_TYPE * r)2881*e4b17023SJohn Marino encode_ieee_single (const struct real_format *fmt, long *buf,
2882*e4b17023SJohn Marino 		    const REAL_VALUE_TYPE *r)
2883*e4b17023SJohn Marino {
2884*e4b17023SJohn Marino   unsigned long image, sig, exp;
2885*e4b17023SJohn Marino   unsigned long sign = r->sign;
2886*e4b17023SJohn Marino   bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
2887*e4b17023SJohn Marino 
2888*e4b17023SJohn Marino   image = sign << 31;
2889*e4b17023SJohn Marino   sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff;
2890*e4b17023SJohn Marino 
2891*e4b17023SJohn Marino   switch (r->cl)
2892*e4b17023SJohn Marino     {
2893*e4b17023SJohn Marino     case rvc_zero:
2894*e4b17023SJohn Marino       break;
2895*e4b17023SJohn Marino 
2896*e4b17023SJohn Marino     case rvc_inf:
2897*e4b17023SJohn Marino       if (fmt->has_inf)
2898*e4b17023SJohn Marino 	image |= 255 << 23;
2899*e4b17023SJohn Marino       else
2900*e4b17023SJohn Marino 	image |= 0x7fffffff;
2901*e4b17023SJohn Marino       break;
2902*e4b17023SJohn Marino 
2903*e4b17023SJohn Marino     case rvc_nan:
2904*e4b17023SJohn Marino       if (fmt->has_nans)
2905*e4b17023SJohn Marino 	{
2906*e4b17023SJohn Marino 	  if (r->canonical)
2907*e4b17023SJohn Marino 	    sig = (fmt->canonical_nan_lsbs_set ? (1 << 22) - 1 : 0);
2908*e4b17023SJohn Marino 	  if (r->signalling == fmt->qnan_msb_set)
2909*e4b17023SJohn Marino 	    sig &= ~(1 << 22);
2910*e4b17023SJohn Marino 	  else
2911*e4b17023SJohn Marino 	    sig |= 1 << 22;
2912*e4b17023SJohn Marino 	  if (sig == 0)
2913*e4b17023SJohn Marino 	    sig = 1 << 21;
2914*e4b17023SJohn Marino 
2915*e4b17023SJohn Marino 	  image |= 255 << 23;
2916*e4b17023SJohn Marino 	  image |= sig;
2917*e4b17023SJohn Marino 	}
2918*e4b17023SJohn Marino       else
2919*e4b17023SJohn Marino 	image |= 0x7fffffff;
2920*e4b17023SJohn Marino       break;
2921*e4b17023SJohn Marino 
2922*e4b17023SJohn Marino     case rvc_normal:
2923*e4b17023SJohn Marino       /* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
2924*e4b17023SJohn Marino 	 whereas the intermediate representation is 0.F x 2**exp.
2925*e4b17023SJohn Marino 	 Which means we're off by one.  */
2926*e4b17023SJohn Marino       if (denormal)
2927*e4b17023SJohn Marino 	exp = 0;
2928*e4b17023SJohn Marino       else
2929*e4b17023SJohn Marino       exp = REAL_EXP (r) + 127 - 1;
2930*e4b17023SJohn Marino       image |= exp << 23;
2931*e4b17023SJohn Marino       image |= sig;
2932*e4b17023SJohn Marino       break;
2933*e4b17023SJohn Marino 
2934*e4b17023SJohn Marino     default:
2935*e4b17023SJohn Marino       gcc_unreachable ();
2936*e4b17023SJohn Marino     }
2937*e4b17023SJohn Marino 
2938*e4b17023SJohn Marino   buf[0] = image;
2939*e4b17023SJohn Marino }
2940*e4b17023SJohn Marino 
2941*e4b17023SJohn Marino static void
decode_ieee_single(const struct real_format * fmt,REAL_VALUE_TYPE * r,const long * buf)2942*e4b17023SJohn Marino decode_ieee_single (const struct real_format *fmt, REAL_VALUE_TYPE *r,
2943*e4b17023SJohn Marino 		    const long *buf)
2944*e4b17023SJohn Marino {
2945*e4b17023SJohn Marino   unsigned long image = buf[0] & 0xffffffff;
2946*e4b17023SJohn Marino   bool sign = (image >> 31) & 1;
2947*e4b17023SJohn Marino   int exp = (image >> 23) & 0xff;
2948*e4b17023SJohn Marino 
2949*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
2950*e4b17023SJohn Marino   image <<= HOST_BITS_PER_LONG - 24;
2951*e4b17023SJohn Marino   image &= ~SIG_MSB;
2952*e4b17023SJohn Marino 
2953*e4b17023SJohn Marino   if (exp == 0)
2954*e4b17023SJohn Marino     {
2955*e4b17023SJohn Marino       if (image && fmt->has_denorm)
2956*e4b17023SJohn Marino 	{
2957*e4b17023SJohn Marino 	  r->cl = rvc_normal;
2958*e4b17023SJohn Marino 	  r->sign = sign;
2959*e4b17023SJohn Marino 	  SET_REAL_EXP (r, -126);
2960*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = image << 1;
2961*e4b17023SJohn Marino 	  normalize (r);
2962*e4b17023SJohn Marino 	}
2963*e4b17023SJohn Marino       else if (fmt->has_signed_zero)
2964*e4b17023SJohn Marino 	r->sign = sign;
2965*e4b17023SJohn Marino     }
2966*e4b17023SJohn Marino   else if (exp == 255 && (fmt->has_nans || fmt->has_inf))
2967*e4b17023SJohn Marino     {
2968*e4b17023SJohn Marino       if (image)
2969*e4b17023SJohn Marino 	{
2970*e4b17023SJohn Marino 	  r->cl = rvc_nan;
2971*e4b17023SJohn Marino 	  r->sign = sign;
2972*e4b17023SJohn Marino 	  r->signalling = (((image >> (HOST_BITS_PER_LONG - 2)) & 1)
2973*e4b17023SJohn Marino 			   ^ fmt->qnan_msb_set);
2974*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = image;
2975*e4b17023SJohn Marino 	}
2976*e4b17023SJohn Marino       else
2977*e4b17023SJohn Marino 	{
2978*e4b17023SJohn Marino 	  r->cl = rvc_inf;
2979*e4b17023SJohn Marino 	  r->sign = sign;
2980*e4b17023SJohn Marino 	}
2981*e4b17023SJohn Marino     }
2982*e4b17023SJohn Marino   else
2983*e4b17023SJohn Marino     {
2984*e4b17023SJohn Marino       r->cl = rvc_normal;
2985*e4b17023SJohn Marino       r->sign = sign;
2986*e4b17023SJohn Marino       SET_REAL_EXP (r, exp - 127 + 1);
2987*e4b17023SJohn Marino       r->sig[SIGSZ-1] = image | SIG_MSB;
2988*e4b17023SJohn Marino     }
2989*e4b17023SJohn Marino }
2990*e4b17023SJohn Marino 
2991*e4b17023SJohn Marino const struct real_format ieee_single_format =
2992*e4b17023SJohn Marino   {
2993*e4b17023SJohn Marino     encode_ieee_single,
2994*e4b17023SJohn Marino     decode_ieee_single,
2995*e4b17023SJohn Marino     2,
2996*e4b17023SJohn Marino     24,
2997*e4b17023SJohn Marino     24,
2998*e4b17023SJohn Marino     -125,
2999*e4b17023SJohn Marino     128,
3000*e4b17023SJohn Marino     31,
3001*e4b17023SJohn Marino     31,
3002*e4b17023SJohn Marino     false,
3003*e4b17023SJohn Marino     true,
3004*e4b17023SJohn Marino     true,
3005*e4b17023SJohn Marino     true,
3006*e4b17023SJohn Marino     true,
3007*e4b17023SJohn Marino     true,
3008*e4b17023SJohn Marino     true,
3009*e4b17023SJohn Marino     false
3010*e4b17023SJohn Marino   };
3011*e4b17023SJohn Marino 
3012*e4b17023SJohn Marino const struct real_format mips_single_format =
3013*e4b17023SJohn Marino   {
3014*e4b17023SJohn Marino     encode_ieee_single,
3015*e4b17023SJohn Marino     decode_ieee_single,
3016*e4b17023SJohn Marino     2,
3017*e4b17023SJohn Marino     24,
3018*e4b17023SJohn Marino     24,
3019*e4b17023SJohn Marino     -125,
3020*e4b17023SJohn Marino     128,
3021*e4b17023SJohn Marino     31,
3022*e4b17023SJohn Marino     31,
3023*e4b17023SJohn Marino     false,
3024*e4b17023SJohn Marino     true,
3025*e4b17023SJohn Marino     true,
3026*e4b17023SJohn Marino     true,
3027*e4b17023SJohn Marino     true,
3028*e4b17023SJohn Marino     true,
3029*e4b17023SJohn Marino     false,
3030*e4b17023SJohn Marino     true
3031*e4b17023SJohn Marino   };
3032*e4b17023SJohn Marino 
3033*e4b17023SJohn Marino const struct real_format motorola_single_format =
3034*e4b17023SJohn Marino   {
3035*e4b17023SJohn Marino     encode_ieee_single,
3036*e4b17023SJohn Marino     decode_ieee_single,
3037*e4b17023SJohn Marino     2,
3038*e4b17023SJohn Marino     24,
3039*e4b17023SJohn Marino     24,
3040*e4b17023SJohn Marino     -125,
3041*e4b17023SJohn Marino     128,
3042*e4b17023SJohn Marino     31,
3043*e4b17023SJohn Marino     31,
3044*e4b17023SJohn Marino     false,
3045*e4b17023SJohn Marino     true,
3046*e4b17023SJohn Marino     true,
3047*e4b17023SJohn Marino     true,
3048*e4b17023SJohn Marino     true,
3049*e4b17023SJohn Marino     true,
3050*e4b17023SJohn Marino     true,
3051*e4b17023SJohn Marino     true
3052*e4b17023SJohn Marino   };
3053*e4b17023SJohn Marino 
3054*e4b17023SJohn Marino /*  SPU Single Precision (Extended-Range Mode) format is the same as IEEE
3055*e4b17023SJohn Marino     single precision with the following differences:
3056*e4b17023SJohn Marino       - Infinities are not supported.  Instead MAX_FLOAT or MIN_FLOAT
3057*e4b17023SJohn Marino 	are generated.
3058*e4b17023SJohn Marino       - NaNs are not supported.
3059*e4b17023SJohn Marino       - The range of non-zero numbers in binary is
3060*e4b17023SJohn Marino 	(001)[1.]000...000 to (255)[1.]111...111.
3061*e4b17023SJohn Marino       - Denormals can be represented, but are treated as +0.0 when
3062*e4b17023SJohn Marino 	used as an operand and are never generated as a result.
3063*e4b17023SJohn Marino       - -0.0 can be represented, but a zero result is always +0.0.
3064*e4b17023SJohn Marino       - the only supported rounding mode is trunction (towards zero).  */
3065*e4b17023SJohn Marino const struct real_format spu_single_format =
3066*e4b17023SJohn Marino   {
3067*e4b17023SJohn Marino     encode_ieee_single,
3068*e4b17023SJohn Marino     decode_ieee_single,
3069*e4b17023SJohn Marino     2,
3070*e4b17023SJohn Marino     24,
3071*e4b17023SJohn Marino     24,
3072*e4b17023SJohn Marino     -125,
3073*e4b17023SJohn Marino     129,
3074*e4b17023SJohn Marino     31,
3075*e4b17023SJohn Marino     31,
3076*e4b17023SJohn Marino     true,
3077*e4b17023SJohn Marino     false,
3078*e4b17023SJohn Marino     false,
3079*e4b17023SJohn Marino     false,
3080*e4b17023SJohn Marino     true,
3081*e4b17023SJohn Marino     true,
3082*e4b17023SJohn Marino     false,
3083*e4b17023SJohn Marino     false
3084*e4b17023SJohn Marino   };
3085*e4b17023SJohn Marino 
3086*e4b17023SJohn Marino /* IEEE double-precision format.  */
3087*e4b17023SJohn Marino 
3088*e4b17023SJohn Marino static void encode_ieee_double (const struct real_format *fmt,
3089*e4b17023SJohn Marino 				long *, const REAL_VALUE_TYPE *);
3090*e4b17023SJohn Marino static void decode_ieee_double (const struct real_format *,
3091*e4b17023SJohn Marino 				REAL_VALUE_TYPE *, const long *);
3092*e4b17023SJohn Marino 
3093*e4b17023SJohn Marino static void
encode_ieee_double(const struct real_format * fmt,long * buf,const REAL_VALUE_TYPE * r)3094*e4b17023SJohn Marino encode_ieee_double (const struct real_format *fmt, long *buf,
3095*e4b17023SJohn Marino 		    const REAL_VALUE_TYPE *r)
3096*e4b17023SJohn Marino {
3097*e4b17023SJohn Marino   unsigned long image_lo, image_hi, sig_lo, sig_hi, exp;
3098*e4b17023SJohn Marino   bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
3099*e4b17023SJohn Marino 
3100*e4b17023SJohn Marino   image_hi = r->sign << 31;
3101*e4b17023SJohn Marino   image_lo = 0;
3102*e4b17023SJohn Marino 
3103*e4b17023SJohn Marino   if (HOST_BITS_PER_LONG == 64)
3104*e4b17023SJohn Marino     {
3105*e4b17023SJohn Marino       sig_hi = r->sig[SIGSZ-1];
3106*e4b17023SJohn Marino       sig_lo = (sig_hi >> (64 - 53)) & 0xffffffff;
3107*e4b17023SJohn Marino       sig_hi = (sig_hi >> (64 - 53 + 1) >> 31) & 0xfffff;
3108*e4b17023SJohn Marino     }
3109*e4b17023SJohn Marino   else
3110*e4b17023SJohn Marino     {
3111*e4b17023SJohn Marino       sig_hi = r->sig[SIGSZ-1];
3112*e4b17023SJohn Marino       sig_lo = r->sig[SIGSZ-2];
3113*e4b17023SJohn Marino       sig_lo = (sig_hi << 21) | (sig_lo >> 11);
3114*e4b17023SJohn Marino       sig_hi = (sig_hi >> 11) & 0xfffff;
3115*e4b17023SJohn Marino     }
3116*e4b17023SJohn Marino 
3117*e4b17023SJohn Marino   switch (r->cl)
3118*e4b17023SJohn Marino     {
3119*e4b17023SJohn Marino     case rvc_zero:
3120*e4b17023SJohn Marino       break;
3121*e4b17023SJohn Marino 
3122*e4b17023SJohn Marino     case rvc_inf:
3123*e4b17023SJohn Marino       if (fmt->has_inf)
3124*e4b17023SJohn Marino 	image_hi |= 2047 << 20;
3125*e4b17023SJohn Marino       else
3126*e4b17023SJohn Marino 	{
3127*e4b17023SJohn Marino 	  image_hi |= 0x7fffffff;
3128*e4b17023SJohn Marino 	  image_lo = 0xffffffff;
3129*e4b17023SJohn Marino 	}
3130*e4b17023SJohn Marino       break;
3131*e4b17023SJohn Marino 
3132*e4b17023SJohn Marino     case rvc_nan:
3133*e4b17023SJohn Marino       if (fmt->has_nans)
3134*e4b17023SJohn Marino 	{
3135*e4b17023SJohn Marino 	  if (r->canonical)
3136*e4b17023SJohn Marino 	    {
3137*e4b17023SJohn Marino 	      if (fmt->canonical_nan_lsbs_set)
3138*e4b17023SJohn Marino 		{
3139*e4b17023SJohn Marino 		  sig_hi = (1 << 19) - 1;
3140*e4b17023SJohn Marino 		  sig_lo = 0xffffffff;
3141*e4b17023SJohn Marino 		}
3142*e4b17023SJohn Marino 	      else
3143*e4b17023SJohn Marino 		{
3144*e4b17023SJohn Marino 		  sig_hi = 0;
3145*e4b17023SJohn Marino 		  sig_lo = 0;
3146*e4b17023SJohn Marino 		}
3147*e4b17023SJohn Marino 	    }
3148*e4b17023SJohn Marino 	  if (r->signalling == fmt->qnan_msb_set)
3149*e4b17023SJohn Marino 	    sig_hi &= ~(1 << 19);
3150*e4b17023SJohn Marino 	  else
3151*e4b17023SJohn Marino 	    sig_hi |= 1 << 19;
3152*e4b17023SJohn Marino 	  if (sig_hi == 0 && sig_lo == 0)
3153*e4b17023SJohn Marino 	    sig_hi = 1 << 18;
3154*e4b17023SJohn Marino 
3155*e4b17023SJohn Marino 	  image_hi |= 2047 << 20;
3156*e4b17023SJohn Marino 	  image_hi |= sig_hi;
3157*e4b17023SJohn Marino 	  image_lo = sig_lo;
3158*e4b17023SJohn Marino 	}
3159*e4b17023SJohn Marino       else
3160*e4b17023SJohn Marino 	{
3161*e4b17023SJohn Marino 	  image_hi |= 0x7fffffff;
3162*e4b17023SJohn Marino 	  image_lo = 0xffffffff;
3163*e4b17023SJohn Marino 	}
3164*e4b17023SJohn Marino       break;
3165*e4b17023SJohn Marino 
3166*e4b17023SJohn Marino     case rvc_normal:
3167*e4b17023SJohn Marino       /* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
3168*e4b17023SJohn Marino 	 whereas the intermediate representation is 0.F x 2**exp.
3169*e4b17023SJohn Marino 	 Which means we're off by one.  */
3170*e4b17023SJohn Marino       if (denormal)
3171*e4b17023SJohn Marino 	exp = 0;
3172*e4b17023SJohn Marino       else
3173*e4b17023SJohn Marino 	exp = REAL_EXP (r) + 1023 - 1;
3174*e4b17023SJohn Marino       image_hi |= exp << 20;
3175*e4b17023SJohn Marino       image_hi |= sig_hi;
3176*e4b17023SJohn Marino       image_lo = sig_lo;
3177*e4b17023SJohn Marino       break;
3178*e4b17023SJohn Marino 
3179*e4b17023SJohn Marino     default:
3180*e4b17023SJohn Marino       gcc_unreachable ();
3181*e4b17023SJohn Marino     }
3182*e4b17023SJohn Marino 
3183*e4b17023SJohn Marino   if (FLOAT_WORDS_BIG_ENDIAN)
3184*e4b17023SJohn Marino     buf[0] = image_hi, buf[1] = image_lo;
3185*e4b17023SJohn Marino   else
3186*e4b17023SJohn Marino     buf[0] = image_lo, buf[1] = image_hi;
3187*e4b17023SJohn Marino }
3188*e4b17023SJohn Marino 
3189*e4b17023SJohn Marino static void
decode_ieee_double(const struct real_format * fmt,REAL_VALUE_TYPE * r,const long * buf)3190*e4b17023SJohn Marino decode_ieee_double (const struct real_format *fmt, REAL_VALUE_TYPE *r,
3191*e4b17023SJohn Marino 		    const long *buf)
3192*e4b17023SJohn Marino {
3193*e4b17023SJohn Marino   unsigned long image_hi, image_lo;
3194*e4b17023SJohn Marino   bool sign;
3195*e4b17023SJohn Marino   int exp;
3196*e4b17023SJohn Marino 
3197*e4b17023SJohn Marino   if (FLOAT_WORDS_BIG_ENDIAN)
3198*e4b17023SJohn Marino     image_hi = buf[0], image_lo = buf[1];
3199*e4b17023SJohn Marino   else
3200*e4b17023SJohn Marino     image_lo = buf[0], image_hi = buf[1];
3201*e4b17023SJohn Marino   image_lo &= 0xffffffff;
3202*e4b17023SJohn Marino   image_hi &= 0xffffffff;
3203*e4b17023SJohn Marino 
3204*e4b17023SJohn Marino   sign = (image_hi >> 31) & 1;
3205*e4b17023SJohn Marino   exp = (image_hi >> 20) & 0x7ff;
3206*e4b17023SJohn Marino 
3207*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
3208*e4b17023SJohn Marino 
3209*e4b17023SJohn Marino   image_hi <<= 32 - 21;
3210*e4b17023SJohn Marino   image_hi |= image_lo >> 21;
3211*e4b17023SJohn Marino   image_hi &= 0x7fffffff;
3212*e4b17023SJohn Marino   image_lo <<= 32 - 21;
3213*e4b17023SJohn Marino 
3214*e4b17023SJohn Marino   if (exp == 0)
3215*e4b17023SJohn Marino     {
3216*e4b17023SJohn Marino       if ((image_hi || image_lo) && fmt->has_denorm)
3217*e4b17023SJohn Marino 	{
3218*e4b17023SJohn Marino 	  r->cl = rvc_normal;
3219*e4b17023SJohn Marino 	  r->sign = sign;
3220*e4b17023SJohn Marino 	  SET_REAL_EXP (r, -1022);
3221*e4b17023SJohn Marino 	  if (HOST_BITS_PER_LONG == 32)
3222*e4b17023SJohn Marino 	    {
3223*e4b17023SJohn Marino 	      image_hi = (image_hi << 1) | (image_lo >> 31);
3224*e4b17023SJohn Marino 	      image_lo <<= 1;
3225*e4b17023SJohn Marino 	      r->sig[SIGSZ-1] = image_hi;
3226*e4b17023SJohn Marino 	      r->sig[SIGSZ-2] = image_lo;
3227*e4b17023SJohn Marino 	    }
3228*e4b17023SJohn Marino 	  else
3229*e4b17023SJohn Marino 	    {
3230*e4b17023SJohn Marino 	      image_hi = (image_hi << 31 << 2) | (image_lo << 1);
3231*e4b17023SJohn Marino 	      r->sig[SIGSZ-1] = image_hi;
3232*e4b17023SJohn Marino 	    }
3233*e4b17023SJohn Marino 	  normalize (r);
3234*e4b17023SJohn Marino 	}
3235*e4b17023SJohn Marino       else if (fmt->has_signed_zero)
3236*e4b17023SJohn Marino 	r->sign = sign;
3237*e4b17023SJohn Marino     }
3238*e4b17023SJohn Marino   else if (exp == 2047 && (fmt->has_nans || fmt->has_inf))
3239*e4b17023SJohn Marino     {
3240*e4b17023SJohn Marino       if (image_hi || image_lo)
3241*e4b17023SJohn Marino 	{
3242*e4b17023SJohn Marino 	  r->cl = rvc_nan;
3243*e4b17023SJohn Marino 	  r->sign = sign;
3244*e4b17023SJohn Marino 	  r->signalling = ((image_hi >> 30) & 1) ^ fmt->qnan_msb_set;
3245*e4b17023SJohn Marino 	  if (HOST_BITS_PER_LONG == 32)
3246*e4b17023SJohn Marino 	    {
3247*e4b17023SJohn Marino 	      r->sig[SIGSZ-1] = image_hi;
3248*e4b17023SJohn Marino 	      r->sig[SIGSZ-2] = image_lo;
3249*e4b17023SJohn Marino 	    }
3250*e4b17023SJohn Marino 	  else
3251*e4b17023SJohn Marino 	    r->sig[SIGSZ-1] = (image_hi << 31 << 1) | image_lo;
3252*e4b17023SJohn Marino 	}
3253*e4b17023SJohn Marino       else
3254*e4b17023SJohn Marino 	{
3255*e4b17023SJohn Marino 	  r->cl = rvc_inf;
3256*e4b17023SJohn Marino 	  r->sign = sign;
3257*e4b17023SJohn Marino 	}
3258*e4b17023SJohn Marino     }
3259*e4b17023SJohn Marino   else
3260*e4b17023SJohn Marino     {
3261*e4b17023SJohn Marino       r->cl = rvc_normal;
3262*e4b17023SJohn Marino       r->sign = sign;
3263*e4b17023SJohn Marino       SET_REAL_EXP (r, exp - 1023 + 1);
3264*e4b17023SJohn Marino       if (HOST_BITS_PER_LONG == 32)
3265*e4b17023SJohn Marino 	{
3266*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = image_hi | SIG_MSB;
3267*e4b17023SJohn Marino 	  r->sig[SIGSZ-2] = image_lo;
3268*e4b17023SJohn Marino 	}
3269*e4b17023SJohn Marino       else
3270*e4b17023SJohn Marino 	r->sig[SIGSZ-1] = (image_hi << 31 << 1) | image_lo | SIG_MSB;
3271*e4b17023SJohn Marino     }
3272*e4b17023SJohn Marino }
3273*e4b17023SJohn Marino 
3274*e4b17023SJohn Marino const struct real_format ieee_double_format =
3275*e4b17023SJohn Marino   {
3276*e4b17023SJohn Marino     encode_ieee_double,
3277*e4b17023SJohn Marino     decode_ieee_double,
3278*e4b17023SJohn Marino     2,
3279*e4b17023SJohn Marino     53,
3280*e4b17023SJohn Marino     53,
3281*e4b17023SJohn Marino     -1021,
3282*e4b17023SJohn Marino     1024,
3283*e4b17023SJohn Marino     63,
3284*e4b17023SJohn Marino     63,
3285*e4b17023SJohn Marino     false,
3286*e4b17023SJohn Marino     true,
3287*e4b17023SJohn Marino     true,
3288*e4b17023SJohn Marino     true,
3289*e4b17023SJohn Marino     true,
3290*e4b17023SJohn Marino     true,
3291*e4b17023SJohn Marino     true,
3292*e4b17023SJohn Marino     false
3293*e4b17023SJohn Marino   };
3294*e4b17023SJohn Marino 
3295*e4b17023SJohn Marino const struct real_format mips_double_format =
3296*e4b17023SJohn Marino   {
3297*e4b17023SJohn Marino     encode_ieee_double,
3298*e4b17023SJohn Marino     decode_ieee_double,
3299*e4b17023SJohn Marino     2,
3300*e4b17023SJohn Marino     53,
3301*e4b17023SJohn Marino     53,
3302*e4b17023SJohn Marino     -1021,
3303*e4b17023SJohn Marino     1024,
3304*e4b17023SJohn Marino     63,
3305*e4b17023SJohn Marino     63,
3306*e4b17023SJohn Marino     false,
3307*e4b17023SJohn Marino     true,
3308*e4b17023SJohn Marino     true,
3309*e4b17023SJohn Marino     true,
3310*e4b17023SJohn Marino     true,
3311*e4b17023SJohn Marino     true,
3312*e4b17023SJohn Marino     false,
3313*e4b17023SJohn Marino     true
3314*e4b17023SJohn Marino   };
3315*e4b17023SJohn Marino 
3316*e4b17023SJohn Marino const struct real_format motorola_double_format =
3317*e4b17023SJohn Marino   {
3318*e4b17023SJohn Marino     encode_ieee_double,
3319*e4b17023SJohn Marino     decode_ieee_double,
3320*e4b17023SJohn Marino     2,
3321*e4b17023SJohn Marino     53,
3322*e4b17023SJohn Marino     53,
3323*e4b17023SJohn Marino     -1021,
3324*e4b17023SJohn Marino     1024,
3325*e4b17023SJohn Marino     63,
3326*e4b17023SJohn Marino     63,
3327*e4b17023SJohn Marino     false,
3328*e4b17023SJohn Marino     true,
3329*e4b17023SJohn Marino     true,
3330*e4b17023SJohn Marino     true,
3331*e4b17023SJohn Marino     true,
3332*e4b17023SJohn Marino     true,
3333*e4b17023SJohn Marino     true,
3334*e4b17023SJohn Marino     true
3335*e4b17023SJohn Marino   };
3336*e4b17023SJohn Marino 
3337*e4b17023SJohn Marino /* IEEE extended real format.  This comes in three flavors: Intel's as
3338*e4b17023SJohn Marino    a 12 byte image, Intel's as a 16 byte image, and Motorola's.  Intel
3339*e4b17023SJohn Marino    12- and 16-byte images may be big- or little endian; Motorola's is
3340*e4b17023SJohn Marino    always big endian.  */
3341*e4b17023SJohn Marino 
3342*e4b17023SJohn Marino /* Helper subroutine which converts from the internal format to the
3343*e4b17023SJohn Marino    12-byte little-endian Intel format.  Functions below adjust this
3344*e4b17023SJohn Marino    for the other possible formats.  */
3345*e4b17023SJohn Marino static void
encode_ieee_extended(const struct real_format * fmt,long * buf,const REAL_VALUE_TYPE * r)3346*e4b17023SJohn Marino encode_ieee_extended (const struct real_format *fmt, long *buf,
3347*e4b17023SJohn Marino 		      const REAL_VALUE_TYPE *r)
3348*e4b17023SJohn Marino {
3349*e4b17023SJohn Marino   unsigned long image_hi, sig_hi, sig_lo;
3350*e4b17023SJohn Marino   bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
3351*e4b17023SJohn Marino 
3352*e4b17023SJohn Marino   image_hi = r->sign << 15;
3353*e4b17023SJohn Marino   sig_hi = sig_lo = 0;
3354*e4b17023SJohn Marino 
3355*e4b17023SJohn Marino   switch (r->cl)
3356*e4b17023SJohn Marino     {
3357*e4b17023SJohn Marino     case rvc_zero:
3358*e4b17023SJohn Marino       break;
3359*e4b17023SJohn Marino 
3360*e4b17023SJohn Marino     case rvc_inf:
3361*e4b17023SJohn Marino       if (fmt->has_inf)
3362*e4b17023SJohn Marino 	{
3363*e4b17023SJohn Marino 	  image_hi |= 32767;
3364*e4b17023SJohn Marino 
3365*e4b17023SJohn Marino 	  /* Intel requires the explicit integer bit to be set, otherwise
3366*e4b17023SJohn Marino 	     it considers the value a "pseudo-infinity".  Motorola docs
3367*e4b17023SJohn Marino 	     say it doesn't care.  */
3368*e4b17023SJohn Marino 	  sig_hi = 0x80000000;
3369*e4b17023SJohn Marino 	}
3370*e4b17023SJohn Marino       else
3371*e4b17023SJohn Marino 	{
3372*e4b17023SJohn Marino 	  image_hi |= 32767;
3373*e4b17023SJohn Marino 	  sig_lo = sig_hi = 0xffffffff;
3374*e4b17023SJohn Marino 	}
3375*e4b17023SJohn Marino       break;
3376*e4b17023SJohn Marino 
3377*e4b17023SJohn Marino     case rvc_nan:
3378*e4b17023SJohn Marino       if (fmt->has_nans)
3379*e4b17023SJohn Marino 	{
3380*e4b17023SJohn Marino 	  image_hi |= 32767;
3381*e4b17023SJohn Marino 	  if (r->canonical)
3382*e4b17023SJohn Marino 	    {
3383*e4b17023SJohn Marino 	      if (fmt->canonical_nan_lsbs_set)
3384*e4b17023SJohn Marino 		{
3385*e4b17023SJohn Marino 		  sig_hi = (1 << 30) - 1;
3386*e4b17023SJohn Marino 		  sig_lo = 0xffffffff;
3387*e4b17023SJohn Marino 		}
3388*e4b17023SJohn Marino 	    }
3389*e4b17023SJohn Marino 	  else if (HOST_BITS_PER_LONG == 32)
3390*e4b17023SJohn Marino 	    {
3391*e4b17023SJohn Marino 	      sig_hi = r->sig[SIGSZ-1];
3392*e4b17023SJohn Marino 	      sig_lo = r->sig[SIGSZ-2];
3393*e4b17023SJohn Marino 	    }
3394*e4b17023SJohn Marino 	  else
3395*e4b17023SJohn Marino 	    {
3396*e4b17023SJohn Marino 	      sig_lo = r->sig[SIGSZ-1];
3397*e4b17023SJohn Marino 	      sig_hi = sig_lo >> 31 >> 1;
3398*e4b17023SJohn Marino 	      sig_lo &= 0xffffffff;
3399*e4b17023SJohn Marino 	    }
3400*e4b17023SJohn Marino 	  if (r->signalling == fmt->qnan_msb_set)
3401*e4b17023SJohn Marino 	    sig_hi &= ~(1 << 30);
3402*e4b17023SJohn Marino 	  else
3403*e4b17023SJohn Marino 	    sig_hi |= 1 << 30;
3404*e4b17023SJohn Marino 	  if ((sig_hi & 0x7fffffff) == 0 && sig_lo == 0)
3405*e4b17023SJohn Marino 	    sig_hi = 1 << 29;
3406*e4b17023SJohn Marino 
3407*e4b17023SJohn Marino 	  /* Intel requires the explicit integer bit to be set, otherwise
3408*e4b17023SJohn Marino 	     it considers the value a "pseudo-nan".  Motorola docs say it
3409*e4b17023SJohn Marino 	     doesn't care.  */
3410*e4b17023SJohn Marino 	  sig_hi |= 0x80000000;
3411*e4b17023SJohn Marino 	}
3412*e4b17023SJohn Marino       else
3413*e4b17023SJohn Marino 	{
3414*e4b17023SJohn Marino 	  image_hi |= 32767;
3415*e4b17023SJohn Marino 	  sig_lo = sig_hi = 0xffffffff;
3416*e4b17023SJohn Marino 	}
3417*e4b17023SJohn Marino       break;
3418*e4b17023SJohn Marino 
3419*e4b17023SJohn Marino     case rvc_normal:
3420*e4b17023SJohn Marino       {
3421*e4b17023SJohn Marino 	int exp = REAL_EXP (r);
3422*e4b17023SJohn Marino 
3423*e4b17023SJohn Marino 	/* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
3424*e4b17023SJohn Marino 	   whereas the intermediate representation is 0.F x 2**exp.
3425*e4b17023SJohn Marino 	   Which means we're off by one.
3426*e4b17023SJohn Marino 
3427*e4b17023SJohn Marino 	   Except for Motorola, which consider exp=0 and explicit
3428*e4b17023SJohn Marino 	   integer bit set to continue to be normalized.  In theory
3429*e4b17023SJohn Marino 	   this discrepancy has been taken care of by the difference
3430*e4b17023SJohn Marino 	   in fmt->emin in round_for_format.  */
3431*e4b17023SJohn Marino 
3432*e4b17023SJohn Marino 	if (denormal)
3433*e4b17023SJohn Marino 	  exp = 0;
3434*e4b17023SJohn Marino 	else
3435*e4b17023SJohn Marino 	  {
3436*e4b17023SJohn Marino 	    exp += 16383 - 1;
3437*e4b17023SJohn Marino 	    gcc_assert (exp >= 0);
3438*e4b17023SJohn Marino 	  }
3439*e4b17023SJohn Marino 	image_hi |= exp;
3440*e4b17023SJohn Marino 
3441*e4b17023SJohn Marino 	if (HOST_BITS_PER_LONG == 32)
3442*e4b17023SJohn Marino 	  {
3443*e4b17023SJohn Marino 	    sig_hi = r->sig[SIGSZ-1];
3444*e4b17023SJohn Marino 	    sig_lo = r->sig[SIGSZ-2];
3445*e4b17023SJohn Marino 	  }
3446*e4b17023SJohn Marino 	else
3447*e4b17023SJohn Marino 	  {
3448*e4b17023SJohn Marino 	    sig_lo = r->sig[SIGSZ-1];
3449*e4b17023SJohn Marino 	    sig_hi = sig_lo >> 31 >> 1;
3450*e4b17023SJohn Marino 	    sig_lo &= 0xffffffff;
3451*e4b17023SJohn Marino 	  }
3452*e4b17023SJohn Marino       }
3453*e4b17023SJohn Marino       break;
3454*e4b17023SJohn Marino 
3455*e4b17023SJohn Marino     default:
3456*e4b17023SJohn Marino       gcc_unreachable ();
3457*e4b17023SJohn Marino     }
3458*e4b17023SJohn Marino 
3459*e4b17023SJohn Marino   buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi;
3460*e4b17023SJohn Marino }
3461*e4b17023SJohn Marino 
3462*e4b17023SJohn Marino /* Convert from the internal format to the 12-byte Motorola format
3463*e4b17023SJohn Marino    for an IEEE extended real.  */
3464*e4b17023SJohn Marino static void
encode_ieee_extended_motorola(const struct real_format * fmt,long * buf,const REAL_VALUE_TYPE * r)3465*e4b17023SJohn Marino encode_ieee_extended_motorola (const struct real_format *fmt, long *buf,
3466*e4b17023SJohn Marino 			       const REAL_VALUE_TYPE *r)
3467*e4b17023SJohn Marino {
3468*e4b17023SJohn Marino   long intermed[3];
3469*e4b17023SJohn Marino   encode_ieee_extended (fmt, intermed, r);
3470*e4b17023SJohn Marino 
3471*e4b17023SJohn Marino   /* Motorola chips are assumed always to be big-endian.  Also, the
3472*e4b17023SJohn Marino      padding in a Motorola extended real goes between the exponent and
3473*e4b17023SJohn Marino      the mantissa.  At this point the mantissa is entirely within
3474*e4b17023SJohn Marino      elements 0 and 1 of intermed, and the exponent entirely within
3475*e4b17023SJohn Marino      element 2, so all we have to do is swap the order around, and
3476*e4b17023SJohn Marino      shift element 2 left 16 bits.  */
3477*e4b17023SJohn Marino   buf[0] = intermed[2] << 16;
3478*e4b17023SJohn Marino   buf[1] = intermed[1];
3479*e4b17023SJohn Marino   buf[2] = intermed[0];
3480*e4b17023SJohn Marino }
3481*e4b17023SJohn Marino 
3482*e4b17023SJohn Marino /* Convert from the internal format to the 12-byte Intel format for
3483*e4b17023SJohn Marino    an IEEE extended real.  */
3484*e4b17023SJohn Marino static void
encode_ieee_extended_intel_96(const struct real_format * fmt,long * buf,const REAL_VALUE_TYPE * r)3485*e4b17023SJohn Marino encode_ieee_extended_intel_96 (const struct real_format *fmt, long *buf,
3486*e4b17023SJohn Marino 			       const REAL_VALUE_TYPE *r)
3487*e4b17023SJohn Marino {
3488*e4b17023SJohn Marino   if (FLOAT_WORDS_BIG_ENDIAN)
3489*e4b17023SJohn Marino     {
3490*e4b17023SJohn Marino       /* All the padding in an Intel-format extended real goes at the high
3491*e4b17023SJohn Marino 	 end, which in this case is after the mantissa, not the exponent.
3492*e4b17023SJohn Marino 	 Therefore we must shift everything down 16 bits.  */
3493*e4b17023SJohn Marino       long intermed[3];
3494*e4b17023SJohn Marino       encode_ieee_extended (fmt, intermed, r);
3495*e4b17023SJohn Marino       buf[0] = ((intermed[2] << 16) | ((unsigned long)(intermed[1] & 0xFFFF0000) >> 16));
3496*e4b17023SJohn Marino       buf[1] = ((intermed[1] << 16) | ((unsigned long)(intermed[0] & 0xFFFF0000) >> 16));
3497*e4b17023SJohn Marino       buf[2] =  (intermed[0] << 16);
3498*e4b17023SJohn Marino     }
3499*e4b17023SJohn Marino   else
3500*e4b17023SJohn Marino     /* encode_ieee_extended produces what we want directly.  */
3501*e4b17023SJohn Marino     encode_ieee_extended (fmt, buf, r);
3502*e4b17023SJohn Marino }
3503*e4b17023SJohn Marino 
3504*e4b17023SJohn Marino /* Convert from the internal format to the 16-byte Intel format for
3505*e4b17023SJohn Marino    an IEEE extended real.  */
3506*e4b17023SJohn Marino static void
encode_ieee_extended_intel_128(const struct real_format * fmt,long * buf,const REAL_VALUE_TYPE * r)3507*e4b17023SJohn Marino encode_ieee_extended_intel_128 (const struct real_format *fmt, long *buf,
3508*e4b17023SJohn Marino 				const REAL_VALUE_TYPE *r)
3509*e4b17023SJohn Marino {
3510*e4b17023SJohn Marino   /* All the padding in an Intel-format extended real goes at the high end.  */
3511*e4b17023SJohn Marino   encode_ieee_extended_intel_96 (fmt, buf, r);
3512*e4b17023SJohn Marino   buf[3] = 0;
3513*e4b17023SJohn Marino }
3514*e4b17023SJohn Marino 
3515*e4b17023SJohn Marino /* As above, we have a helper function which converts from 12-byte
3516*e4b17023SJohn Marino    little-endian Intel format to internal format.  Functions below
3517*e4b17023SJohn Marino    adjust for the other possible formats.  */
3518*e4b17023SJohn Marino static void
decode_ieee_extended(const struct real_format * fmt,REAL_VALUE_TYPE * r,const long * buf)3519*e4b17023SJohn Marino decode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r,
3520*e4b17023SJohn Marino 		      const long *buf)
3521*e4b17023SJohn Marino {
3522*e4b17023SJohn Marino   unsigned long image_hi, sig_hi, sig_lo;
3523*e4b17023SJohn Marino   bool sign;
3524*e4b17023SJohn Marino   int exp;
3525*e4b17023SJohn Marino 
3526*e4b17023SJohn Marino   sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2];
3527*e4b17023SJohn Marino   sig_lo &= 0xffffffff;
3528*e4b17023SJohn Marino   sig_hi &= 0xffffffff;
3529*e4b17023SJohn Marino   image_hi &= 0xffffffff;
3530*e4b17023SJohn Marino 
3531*e4b17023SJohn Marino   sign = (image_hi >> 15) & 1;
3532*e4b17023SJohn Marino   exp = image_hi & 0x7fff;
3533*e4b17023SJohn Marino 
3534*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
3535*e4b17023SJohn Marino 
3536*e4b17023SJohn Marino   if (exp == 0)
3537*e4b17023SJohn Marino     {
3538*e4b17023SJohn Marino       if ((sig_hi || sig_lo) && fmt->has_denorm)
3539*e4b17023SJohn Marino 	{
3540*e4b17023SJohn Marino 	  r->cl = rvc_normal;
3541*e4b17023SJohn Marino 	  r->sign = sign;
3542*e4b17023SJohn Marino 
3543*e4b17023SJohn Marino 	  /* When the IEEE format contains a hidden bit, we know that
3544*e4b17023SJohn Marino 	     it's zero at this point, and so shift up the significand
3545*e4b17023SJohn Marino 	     and decrease the exponent to match.  In this case, Motorola
3546*e4b17023SJohn Marino 	     defines the explicit integer bit to be valid, so we don't
3547*e4b17023SJohn Marino 	     know whether the msb is set or not.  */
3548*e4b17023SJohn Marino 	  SET_REAL_EXP (r, fmt->emin);
3549*e4b17023SJohn Marino 	  if (HOST_BITS_PER_LONG == 32)
3550*e4b17023SJohn Marino 	    {
3551*e4b17023SJohn Marino 	      r->sig[SIGSZ-1] = sig_hi;
3552*e4b17023SJohn Marino 	      r->sig[SIGSZ-2] = sig_lo;
3553*e4b17023SJohn Marino 	    }
3554*e4b17023SJohn Marino 	  else
3555*e4b17023SJohn Marino 	    r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo;
3556*e4b17023SJohn Marino 
3557*e4b17023SJohn Marino 	  normalize (r);
3558*e4b17023SJohn Marino 	}
3559*e4b17023SJohn Marino       else if (fmt->has_signed_zero)
3560*e4b17023SJohn Marino 	r->sign = sign;
3561*e4b17023SJohn Marino     }
3562*e4b17023SJohn Marino   else if (exp == 32767 && (fmt->has_nans || fmt->has_inf))
3563*e4b17023SJohn Marino     {
3564*e4b17023SJohn Marino       /* See above re "pseudo-infinities" and "pseudo-nans".
3565*e4b17023SJohn Marino 	 Short summary is that the MSB will likely always be
3566*e4b17023SJohn Marino 	 set, and that we don't care about it.  */
3567*e4b17023SJohn Marino       sig_hi &= 0x7fffffff;
3568*e4b17023SJohn Marino 
3569*e4b17023SJohn Marino       if (sig_hi || sig_lo)
3570*e4b17023SJohn Marino 	{
3571*e4b17023SJohn Marino 	  r->cl = rvc_nan;
3572*e4b17023SJohn Marino 	  r->sign = sign;
3573*e4b17023SJohn Marino 	  r->signalling = ((sig_hi >> 30) & 1) ^ fmt->qnan_msb_set;
3574*e4b17023SJohn Marino 	  if (HOST_BITS_PER_LONG == 32)
3575*e4b17023SJohn Marino 	    {
3576*e4b17023SJohn Marino 	      r->sig[SIGSZ-1] = sig_hi;
3577*e4b17023SJohn Marino 	      r->sig[SIGSZ-2] = sig_lo;
3578*e4b17023SJohn Marino 	    }
3579*e4b17023SJohn Marino 	  else
3580*e4b17023SJohn Marino 	    r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo;
3581*e4b17023SJohn Marino 	}
3582*e4b17023SJohn Marino       else
3583*e4b17023SJohn Marino 	{
3584*e4b17023SJohn Marino 	  r->cl = rvc_inf;
3585*e4b17023SJohn Marino 	  r->sign = sign;
3586*e4b17023SJohn Marino 	}
3587*e4b17023SJohn Marino     }
3588*e4b17023SJohn Marino   else
3589*e4b17023SJohn Marino     {
3590*e4b17023SJohn Marino       r->cl = rvc_normal;
3591*e4b17023SJohn Marino       r->sign = sign;
3592*e4b17023SJohn Marino       SET_REAL_EXP (r, exp - 16383 + 1);
3593*e4b17023SJohn Marino       if (HOST_BITS_PER_LONG == 32)
3594*e4b17023SJohn Marino 	{
3595*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = sig_hi;
3596*e4b17023SJohn Marino 	  r->sig[SIGSZ-2] = sig_lo;
3597*e4b17023SJohn Marino 	}
3598*e4b17023SJohn Marino       else
3599*e4b17023SJohn Marino 	r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo;
3600*e4b17023SJohn Marino     }
3601*e4b17023SJohn Marino }
3602*e4b17023SJohn Marino 
3603*e4b17023SJohn Marino /* Convert from the internal format to the 12-byte Motorola format
3604*e4b17023SJohn Marino    for an IEEE extended real.  */
3605*e4b17023SJohn Marino static void
decode_ieee_extended_motorola(const struct real_format * fmt,REAL_VALUE_TYPE * r,const long * buf)3606*e4b17023SJohn Marino decode_ieee_extended_motorola (const struct real_format *fmt, REAL_VALUE_TYPE *r,
3607*e4b17023SJohn Marino 			       const long *buf)
3608*e4b17023SJohn Marino {
3609*e4b17023SJohn Marino   long intermed[3];
3610*e4b17023SJohn Marino 
3611*e4b17023SJohn Marino   /* Motorola chips are assumed always to be big-endian.  Also, the
3612*e4b17023SJohn Marino      padding in a Motorola extended real goes between the exponent and
3613*e4b17023SJohn Marino      the mantissa; remove it.  */
3614*e4b17023SJohn Marino   intermed[0] = buf[2];
3615*e4b17023SJohn Marino   intermed[1] = buf[1];
3616*e4b17023SJohn Marino   intermed[2] = (unsigned long)buf[0] >> 16;
3617*e4b17023SJohn Marino 
3618*e4b17023SJohn Marino   decode_ieee_extended (fmt, r, intermed);
3619*e4b17023SJohn Marino }
3620*e4b17023SJohn Marino 
3621*e4b17023SJohn Marino /* Convert from the internal format to the 12-byte Intel format for
3622*e4b17023SJohn Marino    an IEEE extended real.  */
3623*e4b17023SJohn Marino static void
decode_ieee_extended_intel_96(const struct real_format * fmt,REAL_VALUE_TYPE * r,const long * buf)3624*e4b17023SJohn Marino decode_ieee_extended_intel_96 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
3625*e4b17023SJohn Marino 			       const long *buf)
3626*e4b17023SJohn Marino {
3627*e4b17023SJohn Marino   if (FLOAT_WORDS_BIG_ENDIAN)
3628*e4b17023SJohn Marino     {
3629*e4b17023SJohn Marino       /* All the padding in an Intel-format extended real goes at the high
3630*e4b17023SJohn Marino 	 end, which in this case is after the mantissa, not the exponent.
3631*e4b17023SJohn Marino 	 Therefore we must shift everything up 16 bits.  */
3632*e4b17023SJohn Marino       long intermed[3];
3633*e4b17023SJohn Marino 
3634*e4b17023SJohn Marino       intermed[0] = (((unsigned long)buf[2] >> 16) | (buf[1] << 16));
3635*e4b17023SJohn Marino       intermed[1] = (((unsigned long)buf[1] >> 16) | (buf[0] << 16));
3636*e4b17023SJohn Marino       intermed[2] =  ((unsigned long)buf[0] >> 16);
3637*e4b17023SJohn Marino 
3638*e4b17023SJohn Marino       decode_ieee_extended (fmt, r, intermed);
3639*e4b17023SJohn Marino     }
3640*e4b17023SJohn Marino   else
3641*e4b17023SJohn Marino     /* decode_ieee_extended produces what we want directly.  */
3642*e4b17023SJohn Marino     decode_ieee_extended (fmt, r, buf);
3643*e4b17023SJohn Marino }
3644*e4b17023SJohn Marino 
3645*e4b17023SJohn Marino /* Convert from the internal format to the 16-byte Intel format for
3646*e4b17023SJohn Marino    an IEEE extended real.  */
3647*e4b17023SJohn Marino static void
decode_ieee_extended_intel_128(const struct real_format * fmt,REAL_VALUE_TYPE * r,const long * buf)3648*e4b17023SJohn Marino decode_ieee_extended_intel_128 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
3649*e4b17023SJohn Marino 				const long *buf)
3650*e4b17023SJohn Marino {
3651*e4b17023SJohn Marino   /* All the padding in an Intel-format extended real goes at the high end.  */
3652*e4b17023SJohn Marino   decode_ieee_extended_intel_96 (fmt, r, buf);
3653*e4b17023SJohn Marino }
3654*e4b17023SJohn Marino 
3655*e4b17023SJohn Marino const struct real_format ieee_extended_motorola_format =
3656*e4b17023SJohn Marino   {
3657*e4b17023SJohn Marino     encode_ieee_extended_motorola,
3658*e4b17023SJohn Marino     decode_ieee_extended_motorola,
3659*e4b17023SJohn Marino     2,
3660*e4b17023SJohn Marino     64,
3661*e4b17023SJohn Marino     64,
3662*e4b17023SJohn Marino     -16382,
3663*e4b17023SJohn Marino     16384,
3664*e4b17023SJohn Marino     95,
3665*e4b17023SJohn Marino     95,
3666*e4b17023SJohn Marino     false,
3667*e4b17023SJohn Marino     true,
3668*e4b17023SJohn Marino     true,
3669*e4b17023SJohn Marino     true,
3670*e4b17023SJohn Marino     true,
3671*e4b17023SJohn Marino     true,
3672*e4b17023SJohn Marino     true,
3673*e4b17023SJohn Marino     true
3674*e4b17023SJohn Marino   };
3675*e4b17023SJohn Marino 
3676*e4b17023SJohn Marino const struct real_format ieee_extended_intel_96_format =
3677*e4b17023SJohn Marino   {
3678*e4b17023SJohn Marino     encode_ieee_extended_intel_96,
3679*e4b17023SJohn Marino     decode_ieee_extended_intel_96,
3680*e4b17023SJohn Marino     2,
3681*e4b17023SJohn Marino     64,
3682*e4b17023SJohn Marino     64,
3683*e4b17023SJohn Marino     -16381,
3684*e4b17023SJohn Marino     16384,
3685*e4b17023SJohn Marino     79,
3686*e4b17023SJohn Marino     79,
3687*e4b17023SJohn Marino     false,
3688*e4b17023SJohn Marino     true,
3689*e4b17023SJohn Marino     true,
3690*e4b17023SJohn Marino     true,
3691*e4b17023SJohn Marino     true,
3692*e4b17023SJohn Marino     true,
3693*e4b17023SJohn Marino     true,
3694*e4b17023SJohn Marino     false
3695*e4b17023SJohn Marino   };
3696*e4b17023SJohn Marino 
3697*e4b17023SJohn Marino const struct real_format ieee_extended_intel_128_format =
3698*e4b17023SJohn Marino   {
3699*e4b17023SJohn Marino     encode_ieee_extended_intel_128,
3700*e4b17023SJohn Marino     decode_ieee_extended_intel_128,
3701*e4b17023SJohn Marino     2,
3702*e4b17023SJohn Marino     64,
3703*e4b17023SJohn Marino     64,
3704*e4b17023SJohn Marino     -16381,
3705*e4b17023SJohn Marino     16384,
3706*e4b17023SJohn Marino     79,
3707*e4b17023SJohn Marino     79,
3708*e4b17023SJohn Marino     false,
3709*e4b17023SJohn Marino     true,
3710*e4b17023SJohn Marino     true,
3711*e4b17023SJohn Marino     true,
3712*e4b17023SJohn Marino     true,
3713*e4b17023SJohn Marino     true,
3714*e4b17023SJohn Marino     true,
3715*e4b17023SJohn Marino     false
3716*e4b17023SJohn Marino   };
3717*e4b17023SJohn Marino 
3718*e4b17023SJohn Marino /* The following caters to i386 systems that set the rounding precision
3719*e4b17023SJohn Marino    to 53 bits instead of 64, e.g. FreeBSD.  */
3720*e4b17023SJohn Marino const struct real_format ieee_extended_intel_96_round_53_format =
3721*e4b17023SJohn Marino   {
3722*e4b17023SJohn Marino     encode_ieee_extended_intel_96,
3723*e4b17023SJohn Marino     decode_ieee_extended_intel_96,
3724*e4b17023SJohn Marino     2,
3725*e4b17023SJohn Marino     53,
3726*e4b17023SJohn Marino     53,
3727*e4b17023SJohn Marino     -16381,
3728*e4b17023SJohn Marino     16384,
3729*e4b17023SJohn Marino     79,
3730*e4b17023SJohn Marino     79,
3731*e4b17023SJohn Marino     false,
3732*e4b17023SJohn Marino     true,
3733*e4b17023SJohn Marino     true,
3734*e4b17023SJohn Marino     true,
3735*e4b17023SJohn Marino     true,
3736*e4b17023SJohn Marino     true,
3737*e4b17023SJohn Marino     true,
3738*e4b17023SJohn Marino     false
3739*e4b17023SJohn Marino   };
3740*e4b17023SJohn Marino 
3741*e4b17023SJohn Marino /* IBM 128-bit extended precision format: a pair of IEEE double precision
3742*e4b17023SJohn Marino    numbers whose sum is equal to the extended precision value.  The number
3743*e4b17023SJohn Marino    with greater magnitude is first.  This format has the same magnitude
3744*e4b17023SJohn Marino    range as an IEEE double precision value, but effectively 106 bits of
3745*e4b17023SJohn Marino    significand precision.  Infinity and NaN are represented by their IEEE
3746*e4b17023SJohn Marino    double precision value stored in the first number, the second number is
3747*e4b17023SJohn Marino    +0.0 or -0.0 for Infinity and don't-care for NaN.  */
3748*e4b17023SJohn Marino 
3749*e4b17023SJohn Marino static void encode_ibm_extended (const struct real_format *fmt,
3750*e4b17023SJohn Marino 				 long *, const REAL_VALUE_TYPE *);
3751*e4b17023SJohn Marino static void decode_ibm_extended (const struct real_format *,
3752*e4b17023SJohn Marino 				 REAL_VALUE_TYPE *, const long *);
3753*e4b17023SJohn Marino 
3754*e4b17023SJohn Marino static void
encode_ibm_extended(const struct real_format * fmt,long * buf,const REAL_VALUE_TYPE * r)3755*e4b17023SJohn Marino encode_ibm_extended (const struct real_format *fmt, long *buf,
3756*e4b17023SJohn Marino 		     const REAL_VALUE_TYPE *r)
3757*e4b17023SJohn Marino {
3758*e4b17023SJohn Marino   REAL_VALUE_TYPE u, normr, v;
3759*e4b17023SJohn Marino   const struct real_format *base_fmt;
3760*e4b17023SJohn Marino 
3761*e4b17023SJohn Marino   base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format;
3762*e4b17023SJohn Marino 
3763*e4b17023SJohn Marino   /* Renormalize R before doing any arithmetic on it.  */
3764*e4b17023SJohn Marino   normr = *r;
3765*e4b17023SJohn Marino   if (normr.cl == rvc_normal)
3766*e4b17023SJohn Marino     normalize (&normr);
3767*e4b17023SJohn Marino 
3768*e4b17023SJohn Marino   /* u = IEEE double precision portion of significand.  */
3769*e4b17023SJohn Marino   u = normr;
3770*e4b17023SJohn Marino   round_for_format (base_fmt, &u);
3771*e4b17023SJohn Marino   encode_ieee_double (base_fmt, &buf[0], &u);
3772*e4b17023SJohn Marino 
3773*e4b17023SJohn Marino   if (u.cl == rvc_normal)
3774*e4b17023SJohn Marino     {
3775*e4b17023SJohn Marino       do_add (&v, &normr, &u, 1);
3776*e4b17023SJohn Marino       /* Call round_for_format since we might need to denormalize.  */
3777*e4b17023SJohn Marino       round_for_format (base_fmt, &v);
3778*e4b17023SJohn Marino       encode_ieee_double (base_fmt, &buf[2], &v);
3779*e4b17023SJohn Marino     }
3780*e4b17023SJohn Marino   else
3781*e4b17023SJohn Marino     {
3782*e4b17023SJohn Marino       /* Inf, NaN, 0 are all representable as doubles, so the
3783*e4b17023SJohn Marino 	 least-significant part can be 0.0.  */
3784*e4b17023SJohn Marino       buf[2] = 0;
3785*e4b17023SJohn Marino       buf[3] = 0;
3786*e4b17023SJohn Marino     }
3787*e4b17023SJohn Marino }
3788*e4b17023SJohn Marino 
3789*e4b17023SJohn Marino static void
decode_ibm_extended(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)3790*e4b17023SJohn Marino decode_ibm_extended (const struct real_format *fmt ATTRIBUTE_UNUSED, REAL_VALUE_TYPE *r,
3791*e4b17023SJohn Marino 		     const long *buf)
3792*e4b17023SJohn Marino {
3793*e4b17023SJohn Marino   REAL_VALUE_TYPE u, v;
3794*e4b17023SJohn Marino   const struct real_format *base_fmt;
3795*e4b17023SJohn Marino 
3796*e4b17023SJohn Marino   base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format;
3797*e4b17023SJohn Marino   decode_ieee_double (base_fmt, &u, &buf[0]);
3798*e4b17023SJohn Marino 
3799*e4b17023SJohn Marino   if (u.cl != rvc_zero && u.cl != rvc_inf && u.cl != rvc_nan)
3800*e4b17023SJohn Marino     {
3801*e4b17023SJohn Marino       decode_ieee_double (base_fmt, &v, &buf[2]);
3802*e4b17023SJohn Marino       do_add (r, &u, &v, 0);
3803*e4b17023SJohn Marino     }
3804*e4b17023SJohn Marino   else
3805*e4b17023SJohn Marino     *r = u;
3806*e4b17023SJohn Marino }
3807*e4b17023SJohn Marino 
3808*e4b17023SJohn Marino const struct real_format ibm_extended_format =
3809*e4b17023SJohn Marino   {
3810*e4b17023SJohn Marino     encode_ibm_extended,
3811*e4b17023SJohn Marino     decode_ibm_extended,
3812*e4b17023SJohn Marino     2,
3813*e4b17023SJohn Marino     53 + 53,
3814*e4b17023SJohn Marino     53,
3815*e4b17023SJohn Marino     -1021 + 53,
3816*e4b17023SJohn Marino     1024,
3817*e4b17023SJohn Marino     127,
3818*e4b17023SJohn Marino     -1,
3819*e4b17023SJohn Marino     false,
3820*e4b17023SJohn Marino     true,
3821*e4b17023SJohn Marino     true,
3822*e4b17023SJohn Marino     true,
3823*e4b17023SJohn Marino     true,
3824*e4b17023SJohn Marino     true,
3825*e4b17023SJohn Marino     true,
3826*e4b17023SJohn Marino     false
3827*e4b17023SJohn Marino   };
3828*e4b17023SJohn Marino 
3829*e4b17023SJohn Marino const struct real_format mips_extended_format =
3830*e4b17023SJohn Marino   {
3831*e4b17023SJohn Marino     encode_ibm_extended,
3832*e4b17023SJohn Marino     decode_ibm_extended,
3833*e4b17023SJohn Marino     2,
3834*e4b17023SJohn Marino     53 + 53,
3835*e4b17023SJohn Marino     53,
3836*e4b17023SJohn Marino     -1021 + 53,
3837*e4b17023SJohn Marino     1024,
3838*e4b17023SJohn Marino     127,
3839*e4b17023SJohn Marino     -1,
3840*e4b17023SJohn Marino     false,
3841*e4b17023SJohn Marino     true,
3842*e4b17023SJohn Marino     true,
3843*e4b17023SJohn Marino     true,
3844*e4b17023SJohn Marino     true,
3845*e4b17023SJohn Marino     true,
3846*e4b17023SJohn Marino     false,
3847*e4b17023SJohn Marino     true
3848*e4b17023SJohn Marino   };
3849*e4b17023SJohn Marino 
3850*e4b17023SJohn Marino 
3851*e4b17023SJohn Marino /* IEEE quad precision format.  */
3852*e4b17023SJohn Marino 
3853*e4b17023SJohn Marino static void encode_ieee_quad (const struct real_format *fmt,
3854*e4b17023SJohn Marino 			      long *, const REAL_VALUE_TYPE *);
3855*e4b17023SJohn Marino static void decode_ieee_quad (const struct real_format *,
3856*e4b17023SJohn Marino 			      REAL_VALUE_TYPE *, const long *);
3857*e4b17023SJohn Marino 
3858*e4b17023SJohn Marino static void
encode_ieee_quad(const struct real_format * fmt,long * buf,const REAL_VALUE_TYPE * r)3859*e4b17023SJohn Marino encode_ieee_quad (const struct real_format *fmt, long *buf,
3860*e4b17023SJohn Marino 		  const REAL_VALUE_TYPE *r)
3861*e4b17023SJohn Marino {
3862*e4b17023SJohn Marino   unsigned long image3, image2, image1, image0, exp;
3863*e4b17023SJohn Marino   bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
3864*e4b17023SJohn Marino   REAL_VALUE_TYPE u;
3865*e4b17023SJohn Marino 
3866*e4b17023SJohn Marino   image3 = r->sign << 31;
3867*e4b17023SJohn Marino   image2 = 0;
3868*e4b17023SJohn Marino   image1 = 0;
3869*e4b17023SJohn Marino   image0 = 0;
3870*e4b17023SJohn Marino 
3871*e4b17023SJohn Marino   rshift_significand (&u, r, SIGNIFICAND_BITS - 113);
3872*e4b17023SJohn Marino 
3873*e4b17023SJohn Marino   switch (r->cl)
3874*e4b17023SJohn Marino     {
3875*e4b17023SJohn Marino     case rvc_zero:
3876*e4b17023SJohn Marino       break;
3877*e4b17023SJohn Marino 
3878*e4b17023SJohn Marino     case rvc_inf:
3879*e4b17023SJohn Marino       if (fmt->has_inf)
3880*e4b17023SJohn Marino 	image3 |= 32767 << 16;
3881*e4b17023SJohn Marino       else
3882*e4b17023SJohn Marino 	{
3883*e4b17023SJohn Marino 	  image3 |= 0x7fffffff;
3884*e4b17023SJohn Marino 	  image2 = 0xffffffff;
3885*e4b17023SJohn Marino 	  image1 = 0xffffffff;
3886*e4b17023SJohn Marino 	  image0 = 0xffffffff;
3887*e4b17023SJohn Marino 	}
3888*e4b17023SJohn Marino       break;
3889*e4b17023SJohn Marino 
3890*e4b17023SJohn Marino     case rvc_nan:
3891*e4b17023SJohn Marino       if (fmt->has_nans)
3892*e4b17023SJohn Marino 	{
3893*e4b17023SJohn Marino 	  image3 |= 32767 << 16;
3894*e4b17023SJohn Marino 
3895*e4b17023SJohn Marino 	  if (r->canonical)
3896*e4b17023SJohn Marino 	    {
3897*e4b17023SJohn Marino 	      if (fmt->canonical_nan_lsbs_set)
3898*e4b17023SJohn Marino 		{
3899*e4b17023SJohn Marino 		  image3 |= 0x7fff;
3900*e4b17023SJohn Marino 		  image2 = image1 = image0 = 0xffffffff;
3901*e4b17023SJohn Marino 		}
3902*e4b17023SJohn Marino 	    }
3903*e4b17023SJohn Marino 	  else if (HOST_BITS_PER_LONG == 32)
3904*e4b17023SJohn Marino 	    {
3905*e4b17023SJohn Marino 	      image0 = u.sig[0];
3906*e4b17023SJohn Marino 	      image1 = u.sig[1];
3907*e4b17023SJohn Marino 	      image2 = u.sig[2];
3908*e4b17023SJohn Marino 	      image3 |= u.sig[3] & 0xffff;
3909*e4b17023SJohn Marino 	    }
3910*e4b17023SJohn Marino 	  else
3911*e4b17023SJohn Marino 	    {
3912*e4b17023SJohn Marino 	      image0 = u.sig[0];
3913*e4b17023SJohn Marino 	      image1 = image0 >> 31 >> 1;
3914*e4b17023SJohn Marino 	      image2 = u.sig[1];
3915*e4b17023SJohn Marino 	      image3 |= (image2 >> 31 >> 1) & 0xffff;
3916*e4b17023SJohn Marino 	      image0 &= 0xffffffff;
3917*e4b17023SJohn Marino 	      image2 &= 0xffffffff;
3918*e4b17023SJohn Marino 	    }
3919*e4b17023SJohn Marino 	  if (r->signalling == fmt->qnan_msb_set)
3920*e4b17023SJohn Marino 	    image3 &= ~0x8000;
3921*e4b17023SJohn Marino 	  else
3922*e4b17023SJohn Marino 	    image3 |= 0x8000;
3923*e4b17023SJohn Marino 	  if (((image3 & 0xffff) | image2 | image1 | image0) == 0)
3924*e4b17023SJohn Marino 	    image3 |= 0x4000;
3925*e4b17023SJohn Marino 	}
3926*e4b17023SJohn Marino       else
3927*e4b17023SJohn Marino 	{
3928*e4b17023SJohn Marino 	  image3 |= 0x7fffffff;
3929*e4b17023SJohn Marino 	  image2 = 0xffffffff;
3930*e4b17023SJohn Marino 	  image1 = 0xffffffff;
3931*e4b17023SJohn Marino 	  image0 = 0xffffffff;
3932*e4b17023SJohn Marino 	}
3933*e4b17023SJohn Marino       break;
3934*e4b17023SJohn Marino 
3935*e4b17023SJohn Marino     case rvc_normal:
3936*e4b17023SJohn Marino       /* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
3937*e4b17023SJohn Marino 	 whereas the intermediate representation is 0.F x 2**exp.
3938*e4b17023SJohn Marino 	 Which means we're off by one.  */
3939*e4b17023SJohn Marino       if (denormal)
3940*e4b17023SJohn Marino 	exp = 0;
3941*e4b17023SJohn Marino       else
3942*e4b17023SJohn Marino 	exp = REAL_EXP (r) + 16383 - 1;
3943*e4b17023SJohn Marino       image3 |= exp << 16;
3944*e4b17023SJohn Marino 
3945*e4b17023SJohn Marino       if (HOST_BITS_PER_LONG == 32)
3946*e4b17023SJohn Marino 	{
3947*e4b17023SJohn Marino 	  image0 = u.sig[0];
3948*e4b17023SJohn Marino 	  image1 = u.sig[1];
3949*e4b17023SJohn Marino 	  image2 = u.sig[2];
3950*e4b17023SJohn Marino 	  image3 |= u.sig[3] & 0xffff;
3951*e4b17023SJohn Marino 	}
3952*e4b17023SJohn Marino       else
3953*e4b17023SJohn Marino 	{
3954*e4b17023SJohn Marino 	  image0 = u.sig[0];
3955*e4b17023SJohn Marino 	  image1 = image0 >> 31 >> 1;
3956*e4b17023SJohn Marino 	  image2 = u.sig[1];
3957*e4b17023SJohn Marino 	  image3 |= (image2 >> 31 >> 1) & 0xffff;
3958*e4b17023SJohn Marino 	  image0 &= 0xffffffff;
3959*e4b17023SJohn Marino 	  image2 &= 0xffffffff;
3960*e4b17023SJohn Marino 	}
3961*e4b17023SJohn Marino       break;
3962*e4b17023SJohn Marino 
3963*e4b17023SJohn Marino     default:
3964*e4b17023SJohn Marino       gcc_unreachable ();
3965*e4b17023SJohn Marino     }
3966*e4b17023SJohn Marino 
3967*e4b17023SJohn Marino   if (FLOAT_WORDS_BIG_ENDIAN)
3968*e4b17023SJohn Marino     {
3969*e4b17023SJohn Marino       buf[0] = image3;
3970*e4b17023SJohn Marino       buf[1] = image2;
3971*e4b17023SJohn Marino       buf[2] = image1;
3972*e4b17023SJohn Marino       buf[3] = image0;
3973*e4b17023SJohn Marino     }
3974*e4b17023SJohn Marino   else
3975*e4b17023SJohn Marino     {
3976*e4b17023SJohn Marino       buf[0] = image0;
3977*e4b17023SJohn Marino       buf[1] = image1;
3978*e4b17023SJohn Marino       buf[2] = image2;
3979*e4b17023SJohn Marino       buf[3] = image3;
3980*e4b17023SJohn Marino     }
3981*e4b17023SJohn Marino }
3982*e4b17023SJohn Marino 
3983*e4b17023SJohn Marino static void
decode_ieee_quad(const struct real_format * fmt,REAL_VALUE_TYPE * r,const long * buf)3984*e4b17023SJohn Marino decode_ieee_quad (const struct real_format *fmt, REAL_VALUE_TYPE *r,
3985*e4b17023SJohn Marino 		  const long *buf)
3986*e4b17023SJohn Marino {
3987*e4b17023SJohn Marino   unsigned long image3, image2, image1, image0;
3988*e4b17023SJohn Marino   bool sign;
3989*e4b17023SJohn Marino   int exp;
3990*e4b17023SJohn Marino 
3991*e4b17023SJohn Marino   if (FLOAT_WORDS_BIG_ENDIAN)
3992*e4b17023SJohn Marino     {
3993*e4b17023SJohn Marino       image3 = buf[0];
3994*e4b17023SJohn Marino       image2 = buf[1];
3995*e4b17023SJohn Marino       image1 = buf[2];
3996*e4b17023SJohn Marino       image0 = buf[3];
3997*e4b17023SJohn Marino     }
3998*e4b17023SJohn Marino   else
3999*e4b17023SJohn Marino     {
4000*e4b17023SJohn Marino       image0 = buf[0];
4001*e4b17023SJohn Marino       image1 = buf[1];
4002*e4b17023SJohn Marino       image2 = buf[2];
4003*e4b17023SJohn Marino       image3 = buf[3];
4004*e4b17023SJohn Marino     }
4005*e4b17023SJohn Marino   image0 &= 0xffffffff;
4006*e4b17023SJohn Marino   image1 &= 0xffffffff;
4007*e4b17023SJohn Marino   image2 &= 0xffffffff;
4008*e4b17023SJohn Marino 
4009*e4b17023SJohn Marino   sign = (image3 >> 31) & 1;
4010*e4b17023SJohn Marino   exp = (image3 >> 16) & 0x7fff;
4011*e4b17023SJohn Marino   image3 &= 0xffff;
4012*e4b17023SJohn Marino 
4013*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
4014*e4b17023SJohn Marino 
4015*e4b17023SJohn Marino   if (exp == 0)
4016*e4b17023SJohn Marino     {
4017*e4b17023SJohn Marino       if ((image3 | image2 | image1 | image0) && fmt->has_denorm)
4018*e4b17023SJohn Marino 	{
4019*e4b17023SJohn Marino 	  r->cl = rvc_normal;
4020*e4b17023SJohn Marino 	  r->sign = sign;
4021*e4b17023SJohn Marino 
4022*e4b17023SJohn Marino 	  SET_REAL_EXP (r, -16382 + (SIGNIFICAND_BITS - 112));
4023*e4b17023SJohn Marino 	  if (HOST_BITS_PER_LONG == 32)
4024*e4b17023SJohn Marino 	    {
4025*e4b17023SJohn Marino 	      r->sig[0] = image0;
4026*e4b17023SJohn Marino 	      r->sig[1] = image1;
4027*e4b17023SJohn Marino 	      r->sig[2] = image2;
4028*e4b17023SJohn Marino 	      r->sig[3] = image3;
4029*e4b17023SJohn Marino 	    }
4030*e4b17023SJohn Marino 	  else
4031*e4b17023SJohn Marino 	    {
4032*e4b17023SJohn Marino 	      r->sig[0] = (image1 << 31 << 1) | image0;
4033*e4b17023SJohn Marino 	      r->sig[1] = (image3 << 31 << 1) | image2;
4034*e4b17023SJohn Marino 	    }
4035*e4b17023SJohn Marino 
4036*e4b17023SJohn Marino 	  normalize (r);
4037*e4b17023SJohn Marino 	}
4038*e4b17023SJohn Marino       else if (fmt->has_signed_zero)
4039*e4b17023SJohn Marino 	r->sign = sign;
4040*e4b17023SJohn Marino     }
4041*e4b17023SJohn Marino   else if (exp == 32767 && (fmt->has_nans || fmt->has_inf))
4042*e4b17023SJohn Marino     {
4043*e4b17023SJohn Marino       if (image3 | image2 | image1 | image0)
4044*e4b17023SJohn Marino 	{
4045*e4b17023SJohn Marino 	  r->cl = rvc_nan;
4046*e4b17023SJohn Marino 	  r->sign = sign;
4047*e4b17023SJohn Marino 	  r->signalling = ((image3 >> 15) & 1) ^ fmt->qnan_msb_set;
4048*e4b17023SJohn Marino 
4049*e4b17023SJohn Marino 	  if (HOST_BITS_PER_LONG == 32)
4050*e4b17023SJohn Marino 	    {
4051*e4b17023SJohn Marino 	      r->sig[0] = image0;
4052*e4b17023SJohn Marino 	      r->sig[1] = image1;
4053*e4b17023SJohn Marino 	      r->sig[2] = image2;
4054*e4b17023SJohn Marino 	      r->sig[3] = image3;
4055*e4b17023SJohn Marino 	    }
4056*e4b17023SJohn Marino 	  else
4057*e4b17023SJohn Marino 	    {
4058*e4b17023SJohn Marino 	      r->sig[0] = (image1 << 31 << 1) | image0;
4059*e4b17023SJohn Marino 	      r->sig[1] = (image3 << 31 << 1) | image2;
4060*e4b17023SJohn Marino 	    }
4061*e4b17023SJohn Marino 	  lshift_significand (r, r, SIGNIFICAND_BITS - 113);
4062*e4b17023SJohn Marino 	}
4063*e4b17023SJohn Marino       else
4064*e4b17023SJohn Marino 	{
4065*e4b17023SJohn Marino 	  r->cl = rvc_inf;
4066*e4b17023SJohn Marino 	  r->sign = sign;
4067*e4b17023SJohn Marino 	}
4068*e4b17023SJohn Marino     }
4069*e4b17023SJohn Marino   else
4070*e4b17023SJohn Marino     {
4071*e4b17023SJohn Marino       r->cl = rvc_normal;
4072*e4b17023SJohn Marino       r->sign = sign;
4073*e4b17023SJohn Marino       SET_REAL_EXP (r, exp - 16383 + 1);
4074*e4b17023SJohn Marino 
4075*e4b17023SJohn Marino       if (HOST_BITS_PER_LONG == 32)
4076*e4b17023SJohn Marino 	{
4077*e4b17023SJohn Marino 	  r->sig[0] = image0;
4078*e4b17023SJohn Marino 	  r->sig[1] = image1;
4079*e4b17023SJohn Marino 	  r->sig[2] = image2;
4080*e4b17023SJohn Marino 	  r->sig[3] = image3;
4081*e4b17023SJohn Marino 	}
4082*e4b17023SJohn Marino       else
4083*e4b17023SJohn Marino 	{
4084*e4b17023SJohn Marino 	  r->sig[0] = (image1 << 31 << 1) | image0;
4085*e4b17023SJohn Marino 	  r->sig[1] = (image3 << 31 << 1) | image2;
4086*e4b17023SJohn Marino 	}
4087*e4b17023SJohn Marino       lshift_significand (r, r, SIGNIFICAND_BITS - 113);
4088*e4b17023SJohn Marino       r->sig[SIGSZ-1] |= SIG_MSB;
4089*e4b17023SJohn Marino     }
4090*e4b17023SJohn Marino }
4091*e4b17023SJohn Marino 
4092*e4b17023SJohn Marino const struct real_format ieee_quad_format =
4093*e4b17023SJohn Marino   {
4094*e4b17023SJohn Marino     encode_ieee_quad,
4095*e4b17023SJohn Marino     decode_ieee_quad,
4096*e4b17023SJohn Marino     2,
4097*e4b17023SJohn Marino     113,
4098*e4b17023SJohn Marino     113,
4099*e4b17023SJohn Marino     -16381,
4100*e4b17023SJohn Marino     16384,
4101*e4b17023SJohn Marino     127,
4102*e4b17023SJohn Marino     127,
4103*e4b17023SJohn Marino     false,
4104*e4b17023SJohn Marino     true,
4105*e4b17023SJohn Marino     true,
4106*e4b17023SJohn Marino     true,
4107*e4b17023SJohn Marino     true,
4108*e4b17023SJohn Marino     true,
4109*e4b17023SJohn Marino     true,
4110*e4b17023SJohn Marino     false
4111*e4b17023SJohn Marino   };
4112*e4b17023SJohn Marino 
4113*e4b17023SJohn Marino const struct real_format mips_quad_format =
4114*e4b17023SJohn Marino   {
4115*e4b17023SJohn Marino     encode_ieee_quad,
4116*e4b17023SJohn Marino     decode_ieee_quad,
4117*e4b17023SJohn Marino     2,
4118*e4b17023SJohn Marino     113,
4119*e4b17023SJohn Marino     113,
4120*e4b17023SJohn Marino     -16381,
4121*e4b17023SJohn Marino     16384,
4122*e4b17023SJohn Marino     127,
4123*e4b17023SJohn Marino     127,
4124*e4b17023SJohn Marino     false,
4125*e4b17023SJohn Marino     true,
4126*e4b17023SJohn Marino     true,
4127*e4b17023SJohn Marino     true,
4128*e4b17023SJohn Marino     true,
4129*e4b17023SJohn Marino     true,
4130*e4b17023SJohn Marino     false,
4131*e4b17023SJohn Marino     true
4132*e4b17023SJohn Marino   };
4133*e4b17023SJohn Marino 
4134*e4b17023SJohn Marino /* Descriptions of VAX floating point formats can be found beginning at
4135*e4b17023SJohn Marino 
4136*e4b17023SJohn Marino    http://h71000.www7.hp.com/doc/73FINAL/4515/4515pro_013.html#f_floating_point_format
4137*e4b17023SJohn Marino 
4138*e4b17023SJohn Marino    The thing to remember is that they're almost IEEE, except for word
4139*e4b17023SJohn Marino    order, exponent bias, and the lack of infinities, nans, and denormals.
4140*e4b17023SJohn Marino 
4141*e4b17023SJohn Marino    We don't implement the H_floating format here, simply because neither
4142*e4b17023SJohn Marino    the VAX or Alpha ports use it.  */
4143*e4b17023SJohn Marino 
4144*e4b17023SJohn Marino static void encode_vax_f (const struct real_format *fmt,
4145*e4b17023SJohn Marino 			  long *, const REAL_VALUE_TYPE *);
4146*e4b17023SJohn Marino static void decode_vax_f (const struct real_format *,
4147*e4b17023SJohn Marino 			  REAL_VALUE_TYPE *, const long *);
4148*e4b17023SJohn Marino static void encode_vax_d (const struct real_format *fmt,
4149*e4b17023SJohn Marino 			  long *, const REAL_VALUE_TYPE *);
4150*e4b17023SJohn Marino static void decode_vax_d (const struct real_format *,
4151*e4b17023SJohn Marino 			  REAL_VALUE_TYPE *, const long *);
4152*e4b17023SJohn Marino static void encode_vax_g (const struct real_format *fmt,
4153*e4b17023SJohn Marino 			  long *, const REAL_VALUE_TYPE *);
4154*e4b17023SJohn Marino static void decode_vax_g (const struct real_format *,
4155*e4b17023SJohn Marino 			  REAL_VALUE_TYPE *, const long *);
4156*e4b17023SJohn Marino 
4157*e4b17023SJohn Marino static void
encode_vax_f(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)4158*e4b17023SJohn Marino encode_vax_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
4159*e4b17023SJohn Marino 	      const REAL_VALUE_TYPE *r)
4160*e4b17023SJohn Marino {
4161*e4b17023SJohn Marino   unsigned long sign, exp, sig, image;
4162*e4b17023SJohn Marino 
4163*e4b17023SJohn Marino   sign = r->sign << 15;
4164*e4b17023SJohn Marino 
4165*e4b17023SJohn Marino   switch (r->cl)
4166*e4b17023SJohn Marino     {
4167*e4b17023SJohn Marino     case rvc_zero:
4168*e4b17023SJohn Marino       image = 0;
4169*e4b17023SJohn Marino       break;
4170*e4b17023SJohn Marino 
4171*e4b17023SJohn Marino     case rvc_inf:
4172*e4b17023SJohn Marino     case rvc_nan:
4173*e4b17023SJohn Marino       image = 0xffff7fff | sign;
4174*e4b17023SJohn Marino       break;
4175*e4b17023SJohn Marino 
4176*e4b17023SJohn Marino     case rvc_normal:
4177*e4b17023SJohn Marino       sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff;
4178*e4b17023SJohn Marino       exp = REAL_EXP (r) + 128;
4179*e4b17023SJohn Marino 
4180*e4b17023SJohn Marino       image = (sig << 16) & 0xffff0000;
4181*e4b17023SJohn Marino       image |= sign;
4182*e4b17023SJohn Marino       image |= exp << 7;
4183*e4b17023SJohn Marino       image |= sig >> 16;
4184*e4b17023SJohn Marino       break;
4185*e4b17023SJohn Marino 
4186*e4b17023SJohn Marino     default:
4187*e4b17023SJohn Marino       gcc_unreachable ();
4188*e4b17023SJohn Marino     }
4189*e4b17023SJohn Marino 
4190*e4b17023SJohn Marino   buf[0] = image;
4191*e4b17023SJohn Marino }
4192*e4b17023SJohn Marino 
4193*e4b17023SJohn Marino static void
decode_vax_f(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)4194*e4b17023SJohn Marino decode_vax_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
4195*e4b17023SJohn Marino 	      REAL_VALUE_TYPE *r, const long *buf)
4196*e4b17023SJohn Marino {
4197*e4b17023SJohn Marino   unsigned long image = buf[0] & 0xffffffff;
4198*e4b17023SJohn Marino   int exp = (image >> 7) & 0xff;
4199*e4b17023SJohn Marino 
4200*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
4201*e4b17023SJohn Marino 
4202*e4b17023SJohn Marino   if (exp != 0)
4203*e4b17023SJohn Marino     {
4204*e4b17023SJohn Marino       r->cl = rvc_normal;
4205*e4b17023SJohn Marino       r->sign = (image >> 15) & 1;
4206*e4b17023SJohn Marino       SET_REAL_EXP (r, exp - 128);
4207*e4b17023SJohn Marino 
4208*e4b17023SJohn Marino       image = ((image & 0x7f) << 16) | ((image >> 16) & 0xffff);
4209*e4b17023SJohn Marino       r->sig[SIGSZ-1] = (image << (HOST_BITS_PER_LONG - 24)) | SIG_MSB;
4210*e4b17023SJohn Marino     }
4211*e4b17023SJohn Marino }
4212*e4b17023SJohn Marino 
4213*e4b17023SJohn Marino static void
encode_vax_d(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)4214*e4b17023SJohn Marino encode_vax_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
4215*e4b17023SJohn Marino 	      const REAL_VALUE_TYPE *r)
4216*e4b17023SJohn Marino {
4217*e4b17023SJohn Marino   unsigned long image0, image1, sign = r->sign << 15;
4218*e4b17023SJohn Marino 
4219*e4b17023SJohn Marino   switch (r->cl)
4220*e4b17023SJohn Marino     {
4221*e4b17023SJohn Marino     case rvc_zero:
4222*e4b17023SJohn Marino       image0 = image1 = 0;
4223*e4b17023SJohn Marino       break;
4224*e4b17023SJohn Marino 
4225*e4b17023SJohn Marino     case rvc_inf:
4226*e4b17023SJohn Marino     case rvc_nan:
4227*e4b17023SJohn Marino       image0 = 0xffff7fff | sign;
4228*e4b17023SJohn Marino       image1 = 0xffffffff;
4229*e4b17023SJohn Marino       break;
4230*e4b17023SJohn Marino 
4231*e4b17023SJohn Marino     case rvc_normal:
4232*e4b17023SJohn Marino       /* Extract the significand into straight hi:lo.  */
4233*e4b17023SJohn Marino       if (HOST_BITS_PER_LONG == 64)
4234*e4b17023SJohn Marino 	{
4235*e4b17023SJohn Marino 	  image0 = r->sig[SIGSZ-1];
4236*e4b17023SJohn Marino 	  image1 = (image0 >> (64 - 56)) & 0xffffffff;
4237*e4b17023SJohn Marino 	  image0 = (image0 >> (64 - 56 + 1) >> 31) & 0x7fffff;
4238*e4b17023SJohn Marino 	}
4239*e4b17023SJohn Marino       else
4240*e4b17023SJohn Marino 	{
4241*e4b17023SJohn Marino 	  image0 = r->sig[SIGSZ-1];
4242*e4b17023SJohn Marino 	  image1 = r->sig[SIGSZ-2];
4243*e4b17023SJohn Marino 	  image1 = (image0 << 24) | (image1 >> 8);
4244*e4b17023SJohn Marino 	  image0 = (image0 >> 8) & 0xffffff;
4245*e4b17023SJohn Marino 	}
4246*e4b17023SJohn Marino 
4247*e4b17023SJohn Marino       /* Rearrange the half-words of the significand to match the
4248*e4b17023SJohn Marino 	 external format.  */
4249*e4b17023SJohn Marino       image0 = ((image0 << 16) | (image0 >> 16)) & 0xffff007f;
4250*e4b17023SJohn Marino       image1 = ((image1 << 16) | (image1 >> 16)) & 0xffffffff;
4251*e4b17023SJohn Marino 
4252*e4b17023SJohn Marino       /* Add the sign and exponent.  */
4253*e4b17023SJohn Marino       image0 |= sign;
4254*e4b17023SJohn Marino       image0 |= (REAL_EXP (r) + 128) << 7;
4255*e4b17023SJohn Marino       break;
4256*e4b17023SJohn Marino 
4257*e4b17023SJohn Marino     default:
4258*e4b17023SJohn Marino       gcc_unreachable ();
4259*e4b17023SJohn Marino     }
4260*e4b17023SJohn Marino 
4261*e4b17023SJohn Marino   if (FLOAT_WORDS_BIG_ENDIAN)
4262*e4b17023SJohn Marino     buf[0] = image1, buf[1] = image0;
4263*e4b17023SJohn Marino   else
4264*e4b17023SJohn Marino     buf[0] = image0, buf[1] = image1;
4265*e4b17023SJohn Marino }
4266*e4b17023SJohn Marino 
4267*e4b17023SJohn Marino static void
decode_vax_d(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)4268*e4b17023SJohn Marino decode_vax_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
4269*e4b17023SJohn Marino 	      REAL_VALUE_TYPE *r, const long *buf)
4270*e4b17023SJohn Marino {
4271*e4b17023SJohn Marino   unsigned long image0, image1;
4272*e4b17023SJohn Marino   int exp;
4273*e4b17023SJohn Marino 
4274*e4b17023SJohn Marino   if (FLOAT_WORDS_BIG_ENDIAN)
4275*e4b17023SJohn Marino     image1 = buf[0], image0 = buf[1];
4276*e4b17023SJohn Marino   else
4277*e4b17023SJohn Marino     image0 = buf[0], image1 = buf[1];
4278*e4b17023SJohn Marino   image0 &= 0xffffffff;
4279*e4b17023SJohn Marino   image1 &= 0xffffffff;
4280*e4b17023SJohn Marino 
4281*e4b17023SJohn Marino   exp = (image0 >> 7) & 0xff;
4282*e4b17023SJohn Marino 
4283*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
4284*e4b17023SJohn Marino 
4285*e4b17023SJohn Marino   if (exp != 0)
4286*e4b17023SJohn Marino     {
4287*e4b17023SJohn Marino       r->cl = rvc_normal;
4288*e4b17023SJohn Marino       r->sign = (image0 >> 15) & 1;
4289*e4b17023SJohn Marino       SET_REAL_EXP (r, exp - 128);
4290*e4b17023SJohn Marino 
4291*e4b17023SJohn Marino       /* Rearrange the half-words of the external format into
4292*e4b17023SJohn Marino 	 proper ascending order.  */
4293*e4b17023SJohn Marino       image0 = ((image0 & 0x7f) << 16) | ((image0 >> 16) & 0xffff);
4294*e4b17023SJohn Marino       image1 = ((image1 & 0xffff) << 16) | ((image1 >> 16) & 0xffff);
4295*e4b17023SJohn Marino 
4296*e4b17023SJohn Marino       if (HOST_BITS_PER_LONG == 64)
4297*e4b17023SJohn Marino 	{
4298*e4b17023SJohn Marino 	  image0 = (image0 << 31 << 1) | image1;
4299*e4b17023SJohn Marino 	  image0 <<= 64 - 56;
4300*e4b17023SJohn Marino 	  image0 |= SIG_MSB;
4301*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = image0;
4302*e4b17023SJohn Marino 	}
4303*e4b17023SJohn Marino       else
4304*e4b17023SJohn Marino 	{
4305*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = image0;
4306*e4b17023SJohn Marino 	  r->sig[SIGSZ-2] = image1;
4307*e4b17023SJohn Marino 	  lshift_significand (r, r, 2*HOST_BITS_PER_LONG - 56);
4308*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] |= SIG_MSB;
4309*e4b17023SJohn Marino 	}
4310*e4b17023SJohn Marino     }
4311*e4b17023SJohn Marino }
4312*e4b17023SJohn Marino 
4313*e4b17023SJohn Marino static void
encode_vax_g(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)4314*e4b17023SJohn Marino encode_vax_g (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
4315*e4b17023SJohn Marino 	      const REAL_VALUE_TYPE *r)
4316*e4b17023SJohn Marino {
4317*e4b17023SJohn Marino   unsigned long image0, image1, sign = r->sign << 15;
4318*e4b17023SJohn Marino 
4319*e4b17023SJohn Marino   switch (r->cl)
4320*e4b17023SJohn Marino     {
4321*e4b17023SJohn Marino     case rvc_zero:
4322*e4b17023SJohn Marino       image0 = image1 = 0;
4323*e4b17023SJohn Marino       break;
4324*e4b17023SJohn Marino 
4325*e4b17023SJohn Marino     case rvc_inf:
4326*e4b17023SJohn Marino     case rvc_nan:
4327*e4b17023SJohn Marino       image0 = 0xffff7fff | sign;
4328*e4b17023SJohn Marino       image1 = 0xffffffff;
4329*e4b17023SJohn Marino       break;
4330*e4b17023SJohn Marino 
4331*e4b17023SJohn Marino     case rvc_normal:
4332*e4b17023SJohn Marino       /* Extract the significand into straight hi:lo.  */
4333*e4b17023SJohn Marino       if (HOST_BITS_PER_LONG == 64)
4334*e4b17023SJohn Marino 	{
4335*e4b17023SJohn Marino 	  image0 = r->sig[SIGSZ-1];
4336*e4b17023SJohn Marino 	  image1 = (image0 >> (64 - 53)) & 0xffffffff;
4337*e4b17023SJohn Marino 	  image0 = (image0 >> (64 - 53 + 1) >> 31) & 0xfffff;
4338*e4b17023SJohn Marino 	}
4339*e4b17023SJohn Marino       else
4340*e4b17023SJohn Marino 	{
4341*e4b17023SJohn Marino 	  image0 = r->sig[SIGSZ-1];
4342*e4b17023SJohn Marino 	  image1 = r->sig[SIGSZ-2];
4343*e4b17023SJohn Marino 	  image1 = (image0 << 21) | (image1 >> 11);
4344*e4b17023SJohn Marino 	  image0 = (image0 >> 11) & 0xfffff;
4345*e4b17023SJohn Marino 	}
4346*e4b17023SJohn Marino 
4347*e4b17023SJohn Marino       /* Rearrange the half-words of the significand to match the
4348*e4b17023SJohn Marino 	 external format.  */
4349*e4b17023SJohn Marino       image0 = ((image0 << 16) | (image0 >> 16)) & 0xffff000f;
4350*e4b17023SJohn Marino       image1 = ((image1 << 16) | (image1 >> 16)) & 0xffffffff;
4351*e4b17023SJohn Marino 
4352*e4b17023SJohn Marino       /* Add the sign and exponent.  */
4353*e4b17023SJohn Marino       image0 |= sign;
4354*e4b17023SJohn Marino       image0 |= (REAL_EXP (r) + 1024) << 4;
4355*e4b17023SJohn Marino       break;
4356*e4b17023SJohn Marino 
4357*e4b17023SJohn Marino     default:
4358*e4b17023SJohn Marino       gcc_unreachable ();
4359*e4b17023SJohn Marino     }
4360*e4b17023SJohn Marino 
4361*e4b17023SJohn Marino   if (FLOAT_WORDS_BIG_ENDIAN)
4362*e4b17023SJohn Marino     buf[0] = image1, buf[1] = image0;
4363*e4b17023SJohn Marino   else
4364*e4b17023SJohn Marino     buf[0] = image0, buf[1] = image1;
4365*e4b17023SJohn Marino }
4366*e4b17023SJohn Marino 
4367*e4b17023SJohn Marino static void
decode_vax_g(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)4368*e4b17023SJohn Marino decode_vax_g (const struct real_format *fmt ATTRIBUTE_UNUSED,
4369*e4b17023SJohn Marino 	      REAL_VALUE_TYPE *r, const long *buf)
4370*e4b17023SJohn Marino {
4371*e4b17023SJohn Marino   unsigned long image0, image1;
4372*e4b17023SJohn Marino   int exp;
4373*e4b17023SJohn Marino 
4374*e4b17023SJohn Marino   if (FLOAT_WORDS_BIG_ENDIAN)
4375*e4b17023SJohn Marino     image1 = buf[0], image0 = buf[1];
4376*e4b17023SJohn Marino   else
4377*e4b17023SJohn Marino     image0 = buf[0], image1 = buf[1];
4378*e4b17023SJohn Marino   image0 &= 0xffffffff;
4379*e4b17023SJohn Marino   image1 &= 0xffffffff;
4380*e4b17023SJohn Marino 
4381*e4b17023SJohn Marino   exp = (image0 >> 4) & 0x7ff;
4382*e4b17023SJohn Marino 
4383*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
4384*e4b17023SJohn Marino 
4385*e4b17023SJohn Marino   if (exp != 0)
4386*e4b17023SJohn Marino     {
4387*e4b17023SJohn Marino       r->cl = rvc_normal;
4388*e4b17023SJohn Marino       r->sign = (image0 >> 15) & 1;
4389*e4b17023SJohn Marino       SET_REAL_EXP (r, exp - 1024);
4390*e4b17023SJohn Marino 
4391*e4b17023SJohn Marino       /* Rearrange the half-words of the external format into
4392*e4b17023SJohn Marino 	 proper ascending order.  */
4393*e4b17023SJohn Marino       image0 = ((image0 & 0xf) << 16) | ((image0 >> 16) & 0xffff);
4394*e4b17023SJohn Marino       image1 = ((image1 & 0xffff) << 16) | ((image1 >> 16) & 0xffff);
4395*e4b17023SJohn Marino 
4396*e4b17023SJohn Marino       if (HOST_BITS_PER_LONG == 64)
4397*e4b17023SJohn Marino 	{
4398*e4b17023SJohn Marino 	  image0 = (image0 << 31 << 1) | image1;
4399*e4b17023SJohn Marino 	  image0 <<= 64 - 53;
4400*e4b17023SJohn Marino 	  image0 |= SIG_MSB;
4401*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = image0;
4402*e4b17023SJohn Marino 	}
4403*e4b17023SJohn Marino       else
4404*e4b17023SJohn Marino 	{
4405*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = image0;
4406*e4b17023SJohn Marino 	  r->sig[SIGSZ-2] = image1;
4407*e4b17023SJohn Marino 	  lshift_significand (r, r, 64 - 53);
4408*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] |= SIG_MSB;
4409*e4b17023SJohn Marino 	}
4410*e4b17023SJohn Marino     }
4411*e4b17023SJohn Marino }
4412*e4b17023SJohn Marino 
4413*e4b17023SJohn Marino const struct real_format vax_f_format =
4414*e4b17023SJohn Marino   {
4415*e4b17023SJohn Marino     encode_vax_f,
4416*e4b17023SJohn Marino     decode_vax_f,
4417*e4b17023SJohn Marino     2,
4418*e4b17023SJohn Marino     24,
4419*e4b17023SJohn Marino     24,
4420*e4b17023SJohn Marino     -127,
4421*e4b17023SJohn Marino     127,
4422*e4b17023SJohn Marino     15,
4423*e4b17023SJohn Marino     15,
4424*e4b17023SJohn Marino     false,
4425*e4b17023SJohn Marino     false,
4426*e4b17023SJohn Marino     false,
4427*e4b17023SJohn Marino     false,
4428*e4b17023SJohn Marino     false,
4429*e4b17023SJohn Marino     false,
4430*e4b17023SJohn Marino     false,
4431*e4b17023SJohn Marino     false
4432*e4b17023SJohn Marino   };
4433*e4b17023SJohn Marino 
4434*e4b17023SJohn Marino const struct real_format vax_d_format =
4435*e4b17023SJohn Marino   {
4436*e4b17023SJohn Marino     encode_vax_d,
4437*e4b17023SJohn Marino     decode_vax_d,
4438*e4b17023SJohn Marino     2,
4439*e4b17023SJohn Marino     56,
4440*e4b17023SJohn Marino     56,
4441*e4b17023SJohn Marino     -127,
4442*e4b17023SJohn Marino     127,
4443*e4b17023SJohn Marino     15,
4444*e4b17023SJohn Marino     15,
4445*e4b17023SJohn Marino     false,
4446*e4b17023SJohn Marino     false,
4447*e4b17023SJohn Marino     false,
4448*e4b17023SJohn Marino     false,
4449*e4b17023SJohn Marino     false,
4450*e4b17023SJohn Marino     false,
4451*e4b17023SJohn Marino     false,
4452*e4b17023SJohn Marino     false
4453*e4b17023SJohn Marino   };
4454*e4b17023SJohn Marino 
4455*e4b17023SJohn Marino const struct real_format vax_g_format =
4456*e4b17023SJohn Marino   {
4457*e4b17023SJohn Marino     encode_vax_g,
4458*e4b17023SJohn Marino     decode_vax_g,
4459*e4b17023SJohn Marino     2,
4460*e4b17023SJohn Marino     53,
4461*e4b17023SJohn Marino     53,
4462*e4b17023SJohn Marino     -1023,
4463*e4b17023SJohn Marino     1023,
4464*e4b17023SJohn Marino     15,
4465*e4b17023SJohn Marino     15,
4466*e4b17023SJohn Marino     false,
4467*e4b17023SJohn Marino     false,
4468*e4b17023SJohn Marino     false,
4469*e4b17023SJohn Marino     false,
4470*e4b17023SJohn Marino     false,
4471*e4b17023SJohn Marino     false,
4472*e4b17023SJohn Marino     false,
4473*e4b17023SJohn Marino     false
4474*e4b17023SJohn Marino   };
4475*e4b17023SJohn Marino 
4476*e4b17023SJohn Marino /* Encode real R into a single precision DFP value in BUF.  */
4477*e4b17023SJohn Marino static void
encode_decimal_single(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf ATTRIBUTE_UNUSED,const REAL_VALUE_TYPE * r ATTRIBUTE_UNUSED)4478*e4b17023SJohn Marino encode_decimal_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
4479*e4b17023SJohn Marino                        long *buf ATTRIBUTE_UNUSED,
4480*e4b17023SJohn Marino 		       const REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED)
4481*e4b17023SJohn Marino {
4482*e4b17023SJohn Marino   encode_decimal32 (fmt, buf, r);
4483*e4b17023SJohn Marino }
4484*e4b17023SJohn Marino 
4485*e4b17023SJohn Marino /* Decode a single precision DFP value in BUF into a real R.  */
4486*e4b17023SJohn Marino static void
decode_decimal_single(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r ATTRIBUTE_UNUSED,const long * buf ATTRIBUTE_UNUSED)4487*e4b17023SJohn Marino decode_decimal_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
4488*e4b17023SJohn Marino 		       REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED,
4489*e4b17023SJohn Marino 		       const long *buf ATTRIBUTE_UNUSED)
4490*e4b17023SJohn Marino {
4491*e4b17023SJohn Marino   decode_decimal32 (fmt, r, buf);
4492*e4b17023SJohn Marino }
4493*e4b17023SJohn Marino 
4494*e4b17023SJohn Marino /* Encode real R into a double precision DFP value in BUF.  */
4495*e4b17023SJohn Marino static void
encode_decimal_double(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf ATTRIBUTE_UNUSED,const REAL_VALUE_TYPE * r ATTRIBUTE_UNUSED)4496*e4b17023SJohn Marino encode_decimal_double (const struct real_format *fmt ATTRIBUTE_UNUSED,
4497*e4b17023SJohn Marino 		       long *buf ATTRIBUTE_UNUSED,
4498*e4b17023SJohn Marino 		       const REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED)
4499*e4b17023SJohn Marino {
4500*e4b17023SJohn Marino   encode_decimal64 (fmt, buf, r);
4501*e4b17023SJohn Marino }
4502*e4b17023SJohn Marino 
4503*e4b17023SJohn Marino /* Decode a double precision DFP value in BUF into a real R.  */
4504*e4b17023SJohn Marino static void
decode_decimal_double(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r ATTRIBUTE_UNUSED,const long * buf ATTRIBUTE_UNUSED)4505*e4b17023SJohn Marino decode_decimal_double (const struct real_format *fmt ATTRIBUTE_UNUSED,
4506*e4b17023SJohn Marino 		       REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED,
4507*e4b17023SJohn Marino 		       const long *buf ATTRIBUTE_UNUSED)
4508*e4b17023SJohn Marino {
4509*e4b17023SJohn Marino   decode_decimal64 (fmt, r, buf);
4510*e4b17023SJohn Marino }
4511*e4b17023SJohn Marino 
4512*e4b17023SJohn Marino /* Encode real R into a quad precision DFP value in BUF.  */
4513*e4b17023SJohn Marino static void
encode_decimal_quad(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf ATTRIBUTE_UNUSED,const REAL_VALUE_TYPE * r ATTRIBUTE_UNUSED)4514*e4b17023SJohn Marino encode_decimal_quad (const struct real_format *fmt ATTRIBUTE_UNUSED,
4515*e4b17023SJohn Marino 		     long *buf ATTRIBUTE_UNUSED,
4516*e4b17023SJohn Marino 		     const REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED)
4517*e4b17023SJohn Marino {
4518*e4b17023SJohn Marino   encode_decimal128 (fmt, buf, r);
4519*e4b17023SJohn Marino }
4520*e4b17023SJohn Marino 
4521*e4b17023SJohn Marino /* Decode a quad precision DFP value in BUF into a real R.  */
4522*e4b17023SJohn Marino static void
decode_decimal_quad(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r ATTRIBUTE_UNUSED,const long * buf ATTRIBUTE_UNUSED)4523*e4b17023SJohn Marino decode_decimal_quad (const struct real_format *fmt ATTRIBUTE_UNUSED,
4524*e4b17023SJohn Marino 		     REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED,
4525*e4b17023SJohn Marino 		     const long *buf ATTRIBUTE_UNUSED)
4526*e4b17023SJohn Marino {
4527*e4b17023SJohn Marino   decode_decimal128 (fmt, r, buf);
4528*e4b17023SJohn Marino }
4529*e4b17023SJohn Marino 
4530*e4b17023SJohn Marino /* Single precision decimal floating point (IEEE 754). */
4531*e4b17023SJohn Marino const struct real_format decimal_single_format =
4532*e4b17023SJohn Marino   {
4533*e4b17023SJohn Marino     encode_decimal_single,
4534*e4b17023SJohn Marino     decode_decimal_single,
4535*e4b17023SJohn Marino     10,
4536*e4b17023SJohn Marino     7,
4537*e4b17023SJohn Marino     7,
4538*e4b17023SJohn Marino     -94,
4539*e4b17023SJohn Marino     97,
4540*e4b17023SJohn Marino     31,
4541*e4b17023SJohn Marino     31,
4542*e4b17023SJohn Marino     false,
4543*e4b17023SJohn Marino     true,
4544*e4b17023SJohn Marino     true,
4545*e4b17023SJohn Marino     true,
4546*e4b17023SJohn Marino     true,
4547*e4b17023SJohn Marino     true,
4548*e4b17023SJohn Marino     true,
4549*e4b17023SJohn Marino     false
4550*e4b17023SJohn Marino   };
4551*e4b17023SJohn Marino 
4552*e4b17023SJohn Marino /* Double precision decimal floating point (IEEE 754). */
4553*e4b17023SJohn Marino const struct real_format decimal_double_format =
4554*e4b17023SJohn Marino   {
4555*e4b17023SJohn Marino     encode_decimal_double,
4556*e4b17023SJohn Marino     decode_decimal_double,
4557*e4b17023SJohn Marino     10,
4558*e4b17023SJohn Marino     16,
4559*e4b17023SJohn Marino     16,
4560*e4b17023SJohn Marino     -382,
4561*e4b17023SJohn Marino     385,
4562*e4b17023SJohn Marino     63,
4563*e4b17023SJohn Marino     63,
4564*e4b17023SJohn Marino     false,
4565*e4b17023SJohn Marino     true,
4566*e4b17023SJohn Marino     true,
4567*e4b17023SJohn Marino     true,
4568*e4b17023SJohn Marino     true,
4569*e4b17023SJohn Marino     true,
4570*e4b17023SJohn Marino     true,
4571*e4b17023SJohn Marino     false
4572*e4b17023SJohn Marino   };
4573*e4b17023SJohn Marino 
4574*e4b17023SJohn Marino /* Quad precision decimal floating point (IEEE 754). */
4575*e4b17023SJohn Marino const struct real_format decimal_quad_format =
4576*e4b17023SJohn Marino   {
4577*e4b17023SJohn Marino     encode_decimal_quad,
4578*e4b17023SJohn Marino     decode_decimal_quad,
4579*e4b17023SJohn Marino     10,
4580*e4b17023SJohn Marino     34,
4581*e4b17023SJohn Marino     34,
4582*e4b17023SJohn Marino     -6142,
4583*e4b17023SJohn Marino     6145,
4584*e4b17023SJohn Marino     127,
4585*e4b17023SJohn Marino     127,
4586*e4b17023SJohn Marino     false,
4587*e4b17023SJohn Marino     true,
4588*e4b17023SJohn Marino     true,
4589*e4b17023SJohn Marino     true,
4590*e4b17023SJohn Marino     true,
4591*e4b17023SJohn Marino     true,
4592*e4b17023SJohn Marino     true,
4593*e4b17023SJohn Marino     false
4594*e4b17023SJohn Marino   };
4595*e4b17023SJohn Marino 
4596*e4b17023SJohn Marino /* Encode half-precision floats.  This routine is used both for the IEEE
4597*e4b17023SJohn Marino    ARM alternative encodings.  */
4598*e4b17023SJohn Marino static void
encode_ieee_half(const struct real_format * fmt,long * buf,const REAL_VALUE_TYPE * r)4599*e4b17023SJohn Marino encode_ieee_half (const struct real_format *fmt, long *buf,
4600*e4b17023SJohn Marino 		  const REAL_VALUE_TYPE *r)
4601*e4b17023SJohn Marino {
4602*e4b17023SJohn Marino   unsigned long image, sig, exp;
4603*e4b17023SJohn Marino   unsigned long sign = r->sign;
4604*e4b17023SJohn Marino   bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
4605*e4b17023SJohn Marino 
4606*e4b17023SJohn Marino   image = sign << 15;
4607*e4b17023SJohn Marino   sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 11)) & 0x3ff;
4608*e4b17023SJohn Marino 
4609*e4b17023SJohn Marino   switch (r->cl)
4610*e4b17023SJohn Marino     {
4611*e4b17023SJohn Marino     case rvc_zero:
4612*e4b17023SJohn Marino       break;
4613*e4b17023SJohn Marino 
4614*e4b17023SJohn Marino     case rvc_inf:
4615*e4b17023SJohn Marino       if (fmt->has_inf)
4616*e4b17023SJohn Marino 	image |= 31 << 10;
4617*e4b17023SJohn Marino       else
4618*e4b17023SJohn Marino 	image |= 0x7fff;
4619*e4b17023SJohn Marino       break;
4620*e4b17023SJohn Marino 
4621*e4b17023SJohn Marino     case rvc_nan:
4622*e4b17023SJohn Marino       if (fmt->has_nans)
4623*e4b17023SJohn Marino 	{
4624*e4b17023SJohn Marino 	  if (r->canonical)
4625*e4b17023SJohn Marino 	    sig = (fmt->canonical_nan_lsbs_set ? (1 << 9) - 1 : 0);
4626*e4b17023SJohn Marino 	  if (r->signalling == fmt->qnan_msb_set)
4627*e4b17023SJohn Marino 	    sig &= ~(1 << 9);
4628*e4b17023SJohn Marino 	  else
4629*e4b17023SJohn Marino 	    sig |= 1 << 9;
4630*e4b17023SJohn Marino 	  if (sig == 0)
4631*e4b17023SJohn Marino 	    sig = 1 << 8;
4632*e4b17023SJohn Marino 
4633*e4b17023SJohn Marino 	  image |= 31 << 10;
4634*e4b17023SJohn Marino 	  image |= sig;
4635*e4b17023SJohn Marino 	}
4636*e4b17023SJohn Marino       else
4637*e4b17023SJohn Marino 	image |= 0x3ff;
4638*e4b17023SJohn Marino       break;
4639*e4b17023SJohn Marino 
4640*e4b17023SJohn Marino     case rvc_normal:
4641*e4b17023SJohn Marino       /* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
4642*e4b17023SJohn Marino 	 whereas the intermediate representation is 0.F x 2**exp.
4643*e4b17023SJohn Marino 	 Which means we're off by one.  */
4644*e4b17023SJohn Marino       if (denormal)
4645*e4b17023SJohn Marino 	exp = 0;
4646*e4b17023SJohn Marino       else
4647*e4b17023SJohn Marino 	exp = REAL_EXP (r) + 15 - 1;
4648*e4b17023SJohn Marino       image |= exp << 10;
4649*e4b17023SJohn Marino       image |= sig;
4650*e4b17023SJohn Marino       break;
4651*e4b17023SJohn Marino 
4652*e4b17023SJohn Marino     default:
4653*e4b17023SJohn Marino       gcc_unreachable ();
4654*e4b17023SJohn Marino     }
4655*e4b17023SJohn Marino 
4656*e4b17023SJohn Marino   buf[0] = image;
4657*e4b17023SJohn Marino }
4658*e4b17023SJohn Marino 
4659*e4b17023SJohn Marino /* Decode half-precision floats.  This routine is used both for the IEEE
4660*e4b17023SJohn Marino    ARM alternative encodings.  */
4661*e4b17023SJohn Marino static void
decode_ieee_half(const struct real_format * fmt,REAL_VALUE_TYPE * r,const long * buf)4662*e4b17023SJohn Marino decode_ieee_half (const struct real_format *fmt, REAL_VALUE_TYPE *r,
4663*e4b17023SJohn Marino 		  const long *buf)
4664*e4b17023SJohn Marino {
4665*e4b17023SJohn Marino   unsigned long image = buf[0] & 0xffff;
4666*e4b17023SJohn Marino   bool sign = (image >> 15) & 1;
4667*e4b17023SJohn Marino   int exp = (image >> 10) & 0x1f;
4668*e4b17023SJohn Marino 
4669*e4b17023SJohn Marino   memset (r, 0, sizeof (*r));
4670*e4b17023SJohn Marino   image <<= HOST_BITS_PER_LONG - 11;
4671*e4b17023SJohn Marino   image &= ~SIG_MSB;
4672*e4b17023SJohn Marino 
4673*e4b17023SJohn Marino   if (exp == 0)
4674*e4b17023SJohn Marino     {
4675*e4b17023SJohn Marino       if (image && fmt->has_denorm)
4676*e4b17023SJohn Marino 	{
4677*e4b17023SJohn Marino 	  r->cl = rvc_normal;
4678*e4b17023SJohn Marino 	  r->sign = sign;
4679*e4b17023SJohn Marino 	  SET_REAL_EXP (r, -14);
4680*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = image << 1;
4681*e4b17023SJohn Marino 	  normalize (r);
4682*e4b17023SJohn Marino 	}
4683*e4b17023SJohn Marino       else if (fmt->has_signed_zero)
4684*e4b17023SJohn Marino 	r->sign = sign;
4685*e4b17023SJohn Marino     }
4686*e4b17023SJohn Marino   else if (exp == 31 && (fmt->has_nans || fmt->has_inf))
4687*e4b17023SJohn Marino     {
4688*e4b17023SJohn Marino       if (image)
4689*e4b17023SJohn Marino 	{
4690*e4b17023SJohn Marino 	  r->cl = rvc_nan;
4691*e4b17023SJohn Marino 	  r->sign = sign;
4692*e4b17023SJohn Marino 	  r->signalling = (((image >> (HOST_BITS_PER_LONG - 2)) & 1)
4693*e4b17023SJohn Marino 			   ^ fmt->qnan_msb_set);
4694*e4b17023SJohn Marino 	  r->sig[SIGSZ-1] = image;
4695*e4b17023SJohn Marino 	}
4696*e4b17023SJohn Marino       else
4697*e4b17023SJohn Marino 	{
4698*e4b17023SJohn Marino 	  r->cl = rvc_inf;
4699*e4b17023SJohn Marino 	  r->sign = sign;
4700*e4b17023SJohn Marino 	}
4701*e4b17023SJohn Marino     }
4702*e4b17023SJohn Marino   else
4703*e4b17023SJohn Marino     {
4704*e4b17023SJohn Marino       r->cl = rvc_normal;
4705*e4b17023SJohn Marino       r->sign = sign;
4706*e4b17023SJohn Marino       SET_REAL_EXP (r, exp - 15 + 1);
4707*e4b17023SJohn Marino       r->sig[SIGSZ-1] = image | SIG_MSB;
4708*e4b17023SJohn Marino     }
4709*e4b17023SJohn Marino }
4710*e4b17023SJohn Marino 
4711*e4b17023SJohn Marino /* Half-precision format, as specified in IEEE 754R.  */
4712*e4b17023SJohn Marino const struct real_format ieee_half_format =
4713*e4b17023SJohn Marino   {
4714*e4b17023SJohn Marino     encode_ieee_half,
4715*e4b17023SJohn Marino     decode_ieee_half,
4716*e4b17023SJohn Marino     2,
4717*e4b17023SJohn Marino     11,
4718*e4b17023SJohn Marino     11,
4719*e4b17023SJohn Marino     -13,
4720*e4b17023SJohn Marino     16,
4721*e4b17023SJohn Marino     15,
4722*e4b17023SJohn Marino     15,
4723*e4b17023SJohn Marino     false,
4724*e4b17023SJohn Marino     true,
4725*e4b17023SJohn Marino     true,
4726*e4b17023SJohn Marino     true,
4727*e4b17023SJohn Marino     true,
4728*e4b17023SJohn Marino     true,
4729*e4b17023SJohn Marino     true,
4730*e4b17023SJohn Marino     false
4731*e4b17023SJohn Marino   };
4732*e4b17023SJohn Marino 
4733*e4b17023SJohn Marino /* ARM's alternative half-precision format, similar to IEEE but with
4734*e4b17023SJohn Marino    no reserved exponent value for NaNs and infinities; rather, it just
4735*e4b17023SJohn Marino    extends the range of exponents by one.  */
4736*e4b17023SJohn Marino const struct real_format arm_half_format =
4737*e4b17023SJohn Marino   {
4738*e4b17023SJohn Marino     encode_ieee_half,
4739*e4b17023SJohn Marino     decode_ieee_half,
4740*e4b17023SJohn Marino     2,
4741*e4b17023SJohn Marino     11,
4742*e4b17023SJohn Marino     11,
4743*e4b17023SJohn Marino     -13,
4744*e4b17023SJohn Marino     17,
4745*e4b17023SJohn Marino     15,
4746*e4b17023SJohn Marino     15,
4747*e4b17023SJohn Marino     false,
4748*e4b17023SJohn Marino     true,
4749*e4b17023SJohn Marino     false,
4750*e4b17023SJohn Marino     false,
4751*e4b17023SJohn Marino     true,
4752*e4b17023SJohn Marino     true,
4753*e4b17023SJohn Marino     false,
4754*e4b17023SJohn Marino     false
4755*e4b17023SJohn Marino   };
4756*e4b17023SJohn Marino 
4757*e4b17023SJohn Marino /* A synthetic "format" for internal arithmetic.  It's the size of the
4758*e4b17023SJohn Marino    internal significand minus the two bits needed for proper rounding.
4759*e4b17023SJohn Marino    The encode and decode routines exist only to satisfy our paranoia
4760*e4b17023SJohn Marino    harness.  */
4761*e4b17023SJohn Marino 
4762*e4b17023SJohn Marino static void encode_internal (const struct real_format *fmt,
4763*e4b17023SJohn Marino 			     long *, const REAL_VALUE_TYPE *);
4764*e4b17023SJohn Marino static void decode_internal (const struct real_format *,
4765*e4b17023SJohn Marino 			     REAL_VALUE_TYPE *, const long *);
4766*e4b17023SJohn Marino 
4767*e4b17023SJohn Marino static void
encode_internal(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)4768*e4b17023SJohn Marino encode_internal (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
4769*e4b17023SJohn Marino 		 const REAL_VALUE_TYPE *r)
4770*e4b17023SJohn Marino {
4771*e4b17023SJohn Marino   memcpy (buf, r, sizeof (*r));
4772*e4b17023SJohn Marino }
4773*e4b17023SJohn Marino 
4774*e4b17023SJohn Marino static void
decode_internal(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)4775*e4b17023SJohn Marino decode_internal (const struct real_format *fmt ATTRIBUTE_UNUSED,
4776*e4b17023SJohn Marino 		 REAL_VALUE_TYPE *r, const long *buf)
4777*e4b17023SJohn Marino {
4778*e4b17023SJohn Marino   memcpy (r, buf, sizeof (*r));
4779*e4b17023SJohn Marino }
4780*e4b17023SJohn Marino 
4781*e4b17023SJohn Marino const struct real_format real_internal_format =
4782*e4b17023SJohn Marino   {
4783*e4b17023SJohn Marino     encode_internal,
4784*e4b17023SJohn Marino     decode_internal,
4785*e4b17023SJohn Marino     2,
4786*e4b17023SJohn Marino     SIGNIFICAND_BITS - 2,
4787*e4b17023SJohn Marino     SIGNIFICAND_BITS - 2,
4788*e4b17023SJohn Marino     -MAX_EXP,
4789*e4b17023SJohn Marino     MAX_EXP,
4790*e4b17023SJohn Marino     -1,
4791*e4b17023SJohn Marino     -1,
4792*e4b17023SJohn Marino     false,
4793*e4b17023SJohn Marino     false,
4794*e4b17023SJohn Marino     true,
4795*e4b17023SJohn Marino     true,
4796*e4b17023SJohn Marino     false,
4797*e4b17023SJohn Marino     true,
4798*e4b17023SJohn Marino     true,
4799*e4b17023SJohn Marino     false
4800*e4b17023SJohn Marino   };
4801*e4b17023SJohn Marino 
4802*e4b17023SJohn Marino /* Calculate the square root of X in mode MODE, and store the result
4803*e4b17023SJohn Marino    in R.  Return TRUE if the operation does not raise an exception.
4804*e4b17023SJohn Marino    For details see "High Precision Division and Square Root",
4805*e4b17023SJohn Marino    Alan H. Karp and Peter Markstein, HP Lab Report 93-93-42, June
4806*e4b17023SJohn Marino    1993.  http://www.hpl.hp.com/techreports/93/HPL-93-42.pdf.  */
4807*e4b17023SJohn Marino 
4808*e4b17023SJohn Marino bool
real_sqrt(REAL_VALUE_TYPE * r,enum machine_mode mode,const REAL_VALUE_TYPE * x)4809*e4b17023SJohn Marino real_sqrt (REAL_VALUE_TYPE *r, enum machine_mode mode,
4810*e4b17023SJohn Marino 	   const REAL_VALUE_TYPE *x)
4811*e4b17023SJohn Marino {
4812*e4b17023SJohn Marino   static REAL_VALUE_TYPE halfthree;
4813*e4b17023SJohn Marino   static bool init = false;
4814*e4b17023SJohn Marino   REAL_VALUE_TYPE h, t, i;
4815*e4b17023SJohn Marino   int iter, exp;
4816*e4b17023SJohn Marino 
4817*e4b17023SJohn Marino   /* sqrt(-0.0) is -0.0.  */
4818*e4b17023SJohn Marino   if (real_isnegzero (x))
4819*e4b17023SJohn Marino     {
4820*e4b17023SJohn Marino       *r = *x;
4821*e4b17023SJohn Marino       return false;
4822*e4b17023SJohn Marino     }
4823*e4b17023SJohn Marino 
4824*e4b17023SJohn Marino   /* Negative arguments return NaN.  */
4825*e4b17023SJohn Marino   if (real_isneg (x))
4826*e4b17023SJohn Marino     {
4827*e4b17023SJohn Marino       get_canonical_qnan (r, 0);
4828*e4b17023SJohn Marino       return false;
4829*e4b17023SJohn Marino     }
4830*e4b17023SJohn Marino 
4831*e4b17023SJohn Marino   /* Infinity and NaN return themselves.  */
4832*e4b17023SJohn Marino   if (!real_isfinite (x))
4833*e4b17023SJohn Marino     {
4834*e4b17023SJohn Marino       *r = *x;
4835*e4b17023SJohn Marino       return false;
4836*e4b17023SJohn Marino     }
4837*e4b17023SJohn Marino 
4838*e4b17023SJohn Marino   if (!init)
4839*e4b17023SJohn Marino     {
4840*e4b17023SJohn Marino       do_add (&halfthree, &dconst1, &dconsthalf, 0);
4841*e4b17023SJohn Marino       init = true;
4842*e4b17023SJohn Marino     }
4843*e4b17023SJohn Marino 
4844*e4b17023SJohn Marino   /* Initial guess for reciprocal sqrt, i.  */
4845*e4b17023SJohn Marino   exp = real_exponent (x);
4846*e4b17023SJohn Marino   real_ldexp (&i, &dconst1, -exp/2);
4847*e4b17023SJohn Marino 
4848*e4b17023SJohn Marino   /* Newton's iteration for reciprocal sqrt, i.  */
4849*e4b17023SJohn Marino   for (iter = 0; iter < 16; iter++)
4850*e4b17023SJohn Marino     {
4851*e4b17023SJohn Marino       /* i(n+1) = i(n) * (1.5 - 0.5*i(n)*i(n)*x).  */
4852*e4b17023SJohn Marino       do_multiply (&t, x, &i);
4853*e4b17023SJohn Marino       do_multiply (&h, &t, &i);
4854*e4b17023SJohn Marino       do_multiply (&t, &h, &dconsthalf);
4855*e4b17023SJohn Marino       do_add (&h, &halfthree, &t, 1);
4856*e4b17023SJohn Marino       do_multiply (&t, &i, &h);
4857*e4b17023SJohn Marino 
4858*e4b17023SJohn Marino       /* Check for early convergence.  */
4859*e4b17023SJohn Marino       if (iter >= 6 && real_identical (&i, &t))
4860*e4b17023SJohn Marino 	break;
4861*e4b17023SJohn Marino 
4862*e4b17023SJohn Marino       /* ??? Unroll loop to avoid copying.  */
4863*e4b17023SJohn Marino       i = t;
4864*e4b17023SJohn Marino     }
4865*e4b17023SJohn Marino 
4866*e4b17023SJohn Marino   /* Final iteration: r = i*x + 0.5*i*x*(1.0 - i*(i*x)).  */
4867*e4b17023SJohn Marino   do_multiply (&t, x, &i);
4868*e4b17023SJohn Marino   do_multiply (&h, &t, &i);
4869*e4b17023SJohn Marino   do_add (&i, &dconst1, &h, 1);
4870*e4b17023SJohn Marino   do_multiply (&h, &t, &i);
4871*e4b17023SJohn Marino   do_multiply (&i, &dconsthalf, &h);
4872*e4b17023SJohn Marino   do_add (&h, &t, &i, 0);
4873*e4b17023SJohn Marino 
4874*e4b17023SJohn Marino   /* ??? We need a Tuckerman test to get the last bit.  */
4875*e4b17023SJohn Marino 
4876*e4b17023SJohn Marino   real_convert (r, mode, &h);
4877*e4b17023SJohn Marino   return true;
4878*e4b17023SJohn Marino }
4879*e4b17023SJohn Marino 
4880*e4b17023SJohn Marino /* Calculate X raised to the integer exponent N in mode MODE and store
4881*e4b17023SJohn Marino    the result in R.  Return true if the result may be inexact due to
4882*e4b17023SJohn Marino    loss of precision.  The algorithm is the classic "left-to-right binary
4883*e4b17023SJohn Marino    method" described in section 4.6.3 of Donald Knuth's "Seminumerical
4884*e4b17023SJohn Marino    Algorithms", "The Art of Computer Programming", Volume 2.  */
4885*e4b17023SJohn Marino 
4886*e4b17023SJohn Marino bool
real_powi(REAL_VALUE_TYPE * r,enum machine_mode mode,const REAL_VALUE_TYPE * x,HOST_WIDE_INT n)4887*e4b17023SJohn Marino real_powi (REAL_VALUE_TYPE *r, enum machine_mode mode,
4888*e4b17023SJohn Marino 	   const REAL_VALUE_TYPE *x, HOST_WIDE_INT n)
4889*e4b17023SJohn Marino {
4890*e4b17023SJohn Marino   unsigned HOST_WIDE_INT bit;
4891*e4b17023SJohn Marino   REAL_VALUE_TYPE t;
4892*e4b17023SJohn Marino   bool inexact = false;
4893*e4b17023SJohn Marino   bool init = false;
4894*e4b17023SJohn Marino   bool neg;
4895*e4b17023SJohn Marino   int i;
4896*e4b17023SJohn Marino 
4897*e4b17023SJohn Marino   if (n == 0)
4898*e4b17023SJohn Marino     {
4899*e4b17023SJohn Marino       *r = dconst1;
4900*e4b17023SJohn Marino       return false;
4901*e4b17023SJohn Marino     }
4902*e4b17023SJohn Marino   else if (n < 0)
4903*e4b17023SJohn Marino     {
4904*e4b17023SJohn Marino       /* Don't worry about overflow, from now on n is unsigned.  */
4905*e4b17023SJohn Marino       neg = true;
4906*e4b17023SJohn Marino       n = -n;
4907*e4b17023SJohn Marino     }
4908*e4b17023SJohn Marino   else
4909*e4b17023SJohn Marino     neg = false;
4910*e4b17023SJohn Marino 
4911*e4b17023SJohn Marino   t = *x;
4912*e4b17023SJohn Marino   bit = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1);
4913*e4b17023SJohn Marino   for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
4914*e4b17023SJohn Marino     {
4915*e4b17023SJohn Marino       if (init)
4916*e4b17023SJohn Marino 	{
4917*e4b17023SJohn Marino 	  inexact |= do_multiply (&t, &t, &t);
4918*e4b17023SJohn Marino 	  if (n & bit)
4919*e4b17023SJohn Marino 	    inexact |= do_multiply (&t, &t, x);
4920*e4b17023SJohn Marino 	}
4921*e4b17023SJohn Marino       else if (n & bit)
4922*e4b17023SJohn Marino 	init = true;
4923*e4b17023SJohn Marino       bit >>= 1;
4924*e4b17023SJohn Marino     }
4925*e4b17023SJohn Marino 
4926*e4b17023SJohn Marino   if (neg)
4927*e4b17023SJohn Marino     inexact |= do_divide (&t, &dconst1, &t);
4928*e4b17023SJohn Marino 
4929*e4b17023SJohn Marino   real_convert (r, mode, &t);
4930*e4b17023SJohn Marino   return inexact;
4931*e4b17023SJohn Marino }
4932*e4b17023SJohn Marino 
4933*e4b17023SJohn Marino /* Round X to the nearest integer not larger in absolute value, i.e.
4934*e4b17023SJohn Marino    towards zero, placing the result in R in mode MODE.  */
4935*e4b17023SJohn Marino 
4936*e4b17023SJohn Marino void
real_trunc(REAL_VALUE_TYPE * r,enum machine_mode mode,const REAL_VALUE_TYPE * x)4937*e4b17023SJohn Marino real_trunc (REAL_VALUE_TYPE *r, enum machine_mode mode,
4938*e4b17023SJohn Marino 	    const REAL_VALUE_TYPE *x)
4939*e4b17023SJohn Marino {
4940*e4b17023SJohn Marino   do_fix_trunc (r, x);
4941*e4b17023SJohn Marino   if (mode != VOIDmode)
4942*e4b17023SJohn Marino     real_convert (r, mode, r);
4943*e4b17023SJohn Marino }
4944*e4b17023SJohn Marino 
4945*e4b17023SJohn Marino /* Round X to the largest integer not greater in value, i.e. round
4946*e4b17023SJohn Marino    down, placing the result in R in mode MODE.  */
4947*e4b17023SJohn Marino 
4948*e4b17023SJohn Marino void
real_floor(REAL_VALUE_TYPE * r,enum machine_mode mode,const REAL_VALUE_TYPE * x)4949*e4b17023SJohn Marino real_floor (REAL_VALUE_TYPE *r, enum machine_mode mode,
4950*e4b17023SJohn Marino 	    const REAL_VALUE_TYPE *x)
4951*e4b17023SJohn Marino {
4952*e4b17023SJohn Marino   REAL_VALUE_TYPE t;
4953*e4b17023SJohn Marino 
4954*e4b17023SJohn Marino   do_fix_trunc (&t, x);
4955*e4b17023SJohn Marino   if (! real_identical (&t, x) && x->sign)
4956*e4b17023SJohn Marino     do_add (&t, &t, &dconstm1, 0);
4957*e4b17023SJohn Marino   if (mode != VOIDmode)
4958*e4b17023SJohn Marino     real_convert (r, mode, &t);
4959*e4b17023SJohn Marino   else
4960*e4b17023SJohn Marino     *r = t;
4961*e4b17023SJohn Marino }
4962*e4b17023SJohn Marino 
4963*e4b17023SJohn Marino /* Round X to the smallest integer not less then argument, i.e. round
4964*e4b17023SJohn Marino    up, placing the result in R in mode MODE.  */
4965*e4b17023SJohn Marino 
4966*e4b17023SJohn Marino void
real_ceil(REAL_VALUE_TYPE * r,enum machine_mode mode,const REAL_VALUE_TYPE * x)4967*e4b17023SJohn Marino real_ceil (REAL_VALUE_TYPE *r, enum machine_mode mode,
4968*e4b17023SJohn Marino 	   const REAL_VALUE_TYPE *x)
4969*e4b17023SJohn Marino {
4970*e4b17023SJohn Marino   REAL_VALUE_TYPE t;
4971*e4b17023SJohn Marino 
4972*e4b17023SJohn Marino   do_fix_trunc (&t, x);
4973*e4b17023SJohn Marino   if (! real_identical (&t, x) && ! x->sign)
4974*e4b17023SJohn Marino     do_add (&t, &t, &dconst1, 0);
4975*e4b17023SJohn Marino   if (mode != VOIDmode)
4976*e4b17023SJohn Marino     real_convert (r, mode, &t);
4977*e4b17023SJohn Marino   else
4978*e4b17023SJohn Marino     *r = t;
4979*e4b17023SJohn Marino }
4980*e4b17023SJohn Marino 
4981*e4b17023SJohn Marino /* Round X to the nearest integer, but round halfway cases away from
4982*e4b17023SJohn Marino    zero.  */
4983*e4b17023SJohn Marino 
4984*e4b17023SJohn Marino void
real_round(REAL_VALUE_TYPE * r,enum machine_mode mode,const REAL_VALUE_TYPE * x)4985*e4b17023SJohn Marino real_round (REAL_VALUE_TYPE *r, enum machine_mode mode,
4986*e4b17023SJohn Marino 	    const REAL_VALUE_TYPE *x)
4987*e4b17023SJohn Marino {
4988*e4b17023SJohn Marino   do_add (r, x, &dconsthalf, x->sign);
4989*e4b17023SJohn Marino   do_fix_trunc (r, r);
4990*e4b17023SJohn Marino   if (mode != VOIDmode)
4991*e4b17023SJohn Marino     real_convert (r, mode, r);
4992*e4b17023SJohn Marino }
4993*e4b17023SJohn Marino 
4994*e4b17023SJohn Marino /* Set the sign of R to the sign of X.  */
4995*e4b17023SJohn Marino 
4996*e4b17023SJohn Marino void
real_copysign(REAL_VALUE_TYPE * r,const REAL_VALUE_TYPE * x)4997*e4b17023SJohn Marino real_copysign (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *x)
4998*e4b17023SJohn Marino {
4999*e4b17023SJohn Marino   r->sign = x->sign;
5000*e4b17023SJohn Marino }
5001*e4b17023SJohn Marino 
5002*e4b17023SJohn Marino /* Check whether the real constant value given is an integer.  */
5003*e4b17023SJohn Marino 
5004*e4b17023SJohn Marino bool
real_isinteger(const REAL_VALUE_TYPE * c,enum machine_mode mode)5005*e4b17023SJohn Marino real_isinteger (const REAL_VALUE_TYPE *c, enum machine_mode mode)
5006*e4b17023SJohn Marino {
5007*e4b17023SJohn Marino   REAL_VALUE_TYPE cint;
5008*e4b17023SJohn Marino 
5009*e4b17023SJohn Marino   real_trunc (&cint, mode, c);
5010*e4b17023SJohn Marino   return real_identical (c, &cint);
5011*e4b17023SJohn Marino }
5012*e4b17023SJohn Marino 
5013*e4b17023SJohn Marino /* Write into BUF the maximum representable finite floating-point
5014*e4b17023SJohn Marino    number, (1 - b**-p) * b**emax for a given FP format FMT as a hex
5015*e4b17023SJohn Marino    float string.  LEN is the size of BUF, and the buffer must be large
5016*e4b17023SJohn Marino    enough to contain the resulting string.  */
5017*e4b17023SJohn Marino 
5018*e4b17023SJohn Marino void
get_max_float(const struct real_format * fmt,char * buf,size_t len)5019*e4b17023SJohn Marino get_max_float (const struct real_format *fmt, char *buf, size_t len)
5020*e4b17023SJohn Marino {
5021*e4b17023SJohn Marino   int i, n;
5022*e4b17023SJohn Marino   char *p;
5023*e4b17023SJohn Marino 
5024*e4b17023SJohn Marino   strcpy (buf, "0x0.");
5025*e4b17023SJohn Marino   n = fmt->p;
5026*e4b17023SJohn Marino   for (i = 0, p = buf + 4; i + 3 < n; i += 4)
5027*e4b17023SJohn Marino     *p++ = 'f';
5028*e4b17023SJohn Marino   if (i < n)
5029*e4b17023SJohn Marino     *p++ = "08ce"[n - i];
5030*e4b17023SJohn Marino   sprintf (p, "p%d", fmt->emax);
5031*e4b17023SJohn Marino   if (fmt->pnan < fmt->p)
5032*e4b17023SJohn Marino     {
5033*e4b17023SJohn Marino       /* This is an IBM extended double format made up of two IEEE
5034*e4b17023SJohn Marino 	 doubles.  The value of the long double is the sum of the
5035*e4b17023SJohn Marino 	 values of the two parts.  The most significant part is
5036*e4b17023SJohn Marino 	 required to be the value of the long double rounded to the
5037*e4b17023SJohn Marino 	 nearest double.  Rounding means we need a slightly smaller
5038*e4b17023SJohn Marino 	 value for LDBL_MAX.  */
5039*e4b17023SJohn Marino       buf[4 + fmt->pnan / 4] = "7bde"[fmt->pnan % 4];
5040*e4b17023SJohn Marino     }
5041*e4b17023SJohn Marino 
5042*e4b17023SJohn Marino   gcc_assert (strlen (buf) < len);
5043*e4b17023SJohn Marino }
5044