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