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