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