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