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