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