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