1117395Skan/* real.c - software floating point emulation. 2132718Skan Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3169689Skan 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 418334Speter Contributed by Stephen L. Moshier (moshier@world.std.com). 5132718Skan Re-written by Richard Henderson <rth@redhat.com> 618334Speter 7117395Skan This file is part of GCC. 818334Speter 9117395Skan GCC is free software; you can redistribute it and/or modify it under 10117395Skan the terms of the GNU General Public License as published by the Free 11117395Skan Software Foundation; either version 2, or (at your option) any later 12117395Skan version. 1318334Speter 14117395Skan GCC is distributed in the hope that it will be useful, but WITHOUT ANY 15117395Skan WARRANTY; without even the implied warranty of MERCHANTABILITY or 16117395Skan FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17117395Skan for more details. 1818334Speter 19117395Skan You should have received a copy of the GNU General Public License 20117395Skan along with GCC; see the file COPYING. If not, write to the Free 21169689Skan Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 22169689Skan 02110-1301, USA. */ 2318334Speter 2418334Speter#include "config.h" 2550397Sobrien#include "system.h" 26132718Skan#include "coretypes.h" 27132718Skan#include "tm.h" 2818334Speter#include "tree.h" 2950397Sobrien#include "toplev.h" 30117395Skan#include "real.h" 3190075Sobrien#include "tm_p.h" 32169689Skan#include "dfp.h" 3318334Speter 34117395Skan/* The floating point model used internally is not exactly IEEE 754 35132718Skan compliant, and close to the description in the ISO C99 standard, 36117395Skan section 5.2.4.2.2 Characteristics of floating types. 3718334Speter 38117395Skan Specifically 3918334Speter 40117395Skan x = s * b^e * \sum_{k=1}^p f_k * b^{-k} 4118334Speter 42117395Skan where 43117395Skan s = sign (+- 1) 44117395Skan b = base or radix, here always 2 45117395Skan e = exponent 46117395Skan p = precision (the number of base-b digits in the significand) 47117395Skan f_k = the digits of the significand. 4818334Speter 49117395Skan We differ from typical IEEE 754 encodings in that the entire 50117395Skan significand is fractional. Normalized significands are in the 51117395Skan range [0.5, 1.0). 5218334Speter 53132718Skan A requirement of the model is that P be larger than the largest 54132718Skan supported target floating-point type by at least 2 bits. This gives 55132718Skan us proper rounding when we truncate to the target type. In addition, 56132718Skan E must be large enough to hold the smallest supported denormal number 57132718Skan in a normalized form. 5818334Speter 59117395Skan Both of these requirements are easily satisfied. The largest target 60117395Skan significand is 113 bits; we store at least 160. The smallest 61132718Skan denormal number fits in 17 exponent bits; we store 27. 6218334Speter 63132718Skan Note that the decimal string conversion routines are sensitive to 64132718Skan rounding errors. Since the raw arithmetic routines do not themselves 65117395Skan have guard digits or rounding, the computation of 10**exp can 66117395Skan accumulate more than a few digits of error. The previous incarnation 67132718Skan of real.c successfully used a 144-bit fraction; given the current 68117395Skan layout of REAL_VALUE_TYPE we're forced to expand to at least 160 bits. 6918334Speter 70117395Skan Target floating point models that use base 16 instead of base 2 71117395Skan (i.e. IBM 370), are handled during round_for_format, in which we 72117395Skan canonicalize the exponent to be a multiple of 4 (log2(16)), and 73117395Skan adjust the significand to match. */ 7418334Speter 7550397Sobrien 76117395Skan/* Used to classify two numbers simultaneously. */ 77117395Skan#define CLASS2(A, B) ((A) << 2 | (B)) 7818334Speter 79117395Skan#if HOST_BITS_PER_LONG != 64 && HOST_BITS_PER_LONG != 32 80117395Skan #error "Some constant folding done by hand to avoid shift count warnings" 81117395Skan#endif 8218334Speter 83132718Skanstatic void get_zero (REAL_VALUE_TYPE *, int); 84132718Skanstatic void get_canonical_qnan (REAL_VALUE_TYPE *, int); 85132718Skanstatic void get_canonical_snan (REAL_VALUE_TYPE *, int); 86132718Skanstatic void get_inf (REAL_VALUE_TYPE *, int); 87132718Skanstatic bool sticky_rshift_significand (REAL_VALUE_TYPE *, 88132718Skan const REAL_VALUE_TYPE *, unsigned int); 89132718Skanstatic void rshift_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, 90132718Skan unsigned int); 91132718Skanstatic void lshift_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, 92132718Skan unsigned int); 93132718Skanstatic void lshift_significand_1 (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); 94132718Skanstatic bool add_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *, 95132718Skan const REAL_VALUE_TYPE *); 96132718Skanstatic bool sub_significands (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, 97132718Skan const REAL_VALUE_TYPE *, int); 98132718Skanstatic void neg_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); 99132718Skanstatic int cmp_significands (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); 100132718Skanstatic int cmp_significand_0 (const REAL_VALUE_TYPE *); 101132718Skanstatic void set_significand_bit (REAL_VALUE_TYPE *, unsigned int); 102132718Skanstatic void clear_significand_bit (REAL_VALUE_TYPE *, unsigned int); 103132718Skanstatic bool test_significand_bit (REAL_VALUE_TYPE *, unsigned int); 104132718Skanstatic void clear_significand_below (REAL_VALUE_TYPE *, unsigned int); 105132718Skanstatic bool div_significands (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, 106132718Skan const REAL_VALUE_TYPE *); 107132718Skanstatic void normalize (REAL_VALUE_TYPE *); 10818334Speter 109132718Skanstatic bool do_add (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, 110132718Skan const REAL_VALUE_TYPE *, int); 111132718Skanstatic bool do_multiply (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, 112132718Skan const REAL_VALUE_TYPE *); 113132718Skanstatic bool do_divide (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, 114132718Skan const REAL_VALUE_TYPE *); 115132718Skanstatic int do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int); 116132718Skanstatic void do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); 11718334Speter 118132718Skanstatic unsigned long rtd_divmod (REAL_VALUE_TYPE *, REAL_VALUE_TYPE *); 11918334Speter 120132718Skanstatic const REAL_VALUE_TYPE * ten_to_ptwo (int); 121132718Skanstatic const REAL_VALUE_TYPE * ten_to_mptwo (int); 122132718Skanstatic const REAL_VALUE_TYPE * real_digit (int); 123132718Skanstatic void times_pten (REAL_VALUE_TYPE *, int); 12418334Speter 125132718Skanstatic void round_for_format (const struct real_format *, REAL_VALUE_TYPE *); 12618334Speter 127117395Skan/* Initialize R with a positive zero. */ 12818334Speter 129117395Skanstatic inline void 130132718Skanget_zero (REAL_VALUE_TYPE *r, int sign) 131117395Skan{ 132117395Skan memset (r, 0, sizeof (*r)); 133117395Skan r->sign = sign; 134117395Skan} 13518334Speter 136117395Skan/* Initialize R with the canonical quiet NaN. */ 13790075Sobrien 138117395Skanstatic inline void 139132718Skanget_canonical_qnan (REAL_VALUE_TYPE *r, int sign) 140117395Skan{ 141117395Skan memset (r, 0, sizeof (*r)); 142169689Skan r->cl = rvc_nan; 143117395Skan r->sign = sign; 144132718Skan r->canonical = 1; 145117395Skan} 14618334Speter 147117395Skanstatic inline void 148132718Skanget_canonical_snan (REAL_VALUE_TYPE *r, int sign) 149117395Skan{ 150117395Skan memset (r, 0, sizeof (*r)); 151169689Skan r->cl = rvc_nan; 152117395Skan r->sign = sign; 153132718Skan r->signalling = 1; 154132718Skan r->canonical = 1; 155117395Skan} 15618334Speter 157117395Skanstatic inline void 158132718Skanget_inf (REAL_VALUE_TYPE *r, int sign) 159117395Skan{ 160117395Skan memset (r, 0, sizeof (*r)); 161169689Skan r->cl = rvc_inf; 162117395Skan r->sign = sign; 163117395Skan} 16418334Speter 16518334Speter 166117395Skan/* Right-shift the significand of A by N bits; put the result in the 167117395Skan significand of R. If any one bits are shifted out, return true. */ 16818334Speter 169117395Skanstatic bool 170132718Skansticky_rshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, 171132718Skan unsigned int n) 17218334Speter{ 173117395Skan unsigned long sticky = 0; 174117395Skan unsigned int i, ofs = 0; 17518334Speter 176117395Skan if (n >= HOST_BITS_PER_LONG) 17718334Speter { 178117395Skan for (i = 0, ofs = n / HOST_BITS_PER_LONG; i < ofs; ++i) 179117395Skan sticky |= a->sig[i]; 180117395Skan n &= HOST_BITS_PER_LONG - 1; 181117395Skan } 182117395Skan 183117395Skan if (n != 0) 184117395Skan { 185117395Skan sticky |= a->sig[ofs] & (((unsigned long)1 << n) - 1); 186117395Skan for (i = 0; i < SIGSZ; ++i) 18718334Speter { 188117395Skan r->sig[i] 189117395Skan = (((ofs + i >= SIGSZ ? 0 : a->sig[ofs + i]) >> n) 190117395Skan | ((ofs + i + 1 >= SIGSZ ? 0 : a->sig[ofs + i + 1]) 191117395Skan << (HOST_BITS_PER_LONG - n))); 19218334Speter } 19318334Speter } 19418334Speter else 19518334Speter { 196117395Skan for (i = 0; ofs + i < SIGSZ; ++i) 197117395Skan r->sig[i] = a->sig[ofs + i]; 198117395Skan for (; i < SIGSZ; ++i) 199117395Skan r->sig[i] = 0; 200117395Skan } 20118334Speter 202117395Skan return sticky != 0; 20318334Speter} 20418334Speter 205117395Skan/* Right-shift the significand of A by N bits; put the result in the 206117395Skan significand of R. */ 20718334Speter 208117395Skanstatic void 209132718Skanrshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, 210132718Skan unsigned int n) 21118334Speter{ 212117395Skan unsigned int i, ofs = n / HOST_BITS_PER_LONG; 21318334Speter 214117395Skan n &= HOST_BITS_PER_LONG - 1; 215117395Skan if (n != 0) 21618334Speter { 217117395Skan for (i = 0; i < SIGSZ; ++i) 218117395Skan { 219117395Skan r->sig[i] 220117395Skan = (((ofs + i >= SIGSZ ? 0 : a->sig[ofs + i]) >> n) 221117395Skan | ((ofs + i + 1 >= SIGSZ ? 0 : a->sig[ofs + i + 1]) 222117395Skan << (HOST_BITS_PER_LONG - n))); 223117395Skan } 22418334Speter } 225117395Skan else 22618334Speter { 227117395Skan for (i = 0; ofs + i < SIGSZ; ++i) 228117395Skan r->sig[i] = a->sig[ofs + i]; 229117395Skan for (; i < SIGSZ; ++i) 230117395Skan r->sig[i] = 0; 23118334Speter } 23218334Speter} 23318334Speter 234117395Skan/* Left-shift the significand of A by N bits; put the result in the 235117395Skan significand of R. */ 23618334Speter 237117395Skanstatic void 238132718Skanlshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, 239132718Skan unsigned int n) 24018334Speter{ 241117395Skan unsigned int i, ofs = n / HOST_BITS_PER_LONG; 24218334Speter 243117395Skan n &= HOST_BITS_PER_LONG - 1; 244117395Skan if (n == 0) 245117395Skan { 246117395Skan for (i = 0; ofs + i < SIGSZ; ++i) 247117395Skan r->sig[SIGSZ-1-i] = a->sig[SIGSZ-1-i-ofs]; 248117395Skan for (; i < SIGSZ; ++i) 249117395Skan r->sig[SIGSZ-1-i] = 0; 250117395Skan } 251117395Skan else 252117395Skan for (i = 0; i < SIGSZ; ++i) 253117395Skan { 254117395Skan r->sig[SIGSZ-1-i] 255117395Skan = (((ofs + i >= SIGSZ ? 0 : a->sig[SIGSZ-1-i-ofs]) << n) 256117395Skan | ((ofs + i + 1 >= SIGSZ ? 0 : a->sig[SIGSZ-1-i-ofs-1]) 257117395Skan >> (HOST_BITS_PER_LONG - n))); 258117395Skan } 25918334Speter} 26018334Speter 261117395Skan/* Likewise, but N is specialized to 1. */ 26218334Speter 263117395Skanstatic inline void 264132718Skanlshift_significand_1 (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a) 26518334Speter{ 266117395Skan unsigned int i; 26718334Speter 268117395Skan for (i = SIGSZ - 1; i > 0; --i) 269117395Skan r->sig[i] = (a->sig[i] << 1) | (a->sig[i-1] >> (HOST_BITS_PER_LONG - 1)); 270117395Skan r->sig[0] = a->sig[0] << 1; 27118334Speter} 27218334Speter 273117395Skan/* Add the significands of A and B, placing the result in R. Return 274117395Skan true if there was carry out of the most significant word. */ 27518334Speter 276117395Skanstatic inline bool 277132718Skanadd_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, 278132718Skan const REAL_VALUE_TYPE *b) 27918334Speter{ 280117395Skan bool carry = false; 281117395Skan int i; 28218334Speter 283117395Skan for (i = 0; i < SIGSZ; ++i) 28418334Speter { 285117395Skan unsigned long ai = a->sig[i]; 286117395Skan unsigned long ri = ai + b->sig[i]; 28750397Sobrien 288117395Skan if (carry) 289117395Skan { 290117395Skan carry = ri < ai; 291117395Skan carry |= ++ri == 0; 292117395Skan } 293117395Skan else 294117395Skan carry = ri < ai; 29550397Sobrien 296117395Skan r->sig[i] = ri; 29718334Speter } 29818334Speter 299117395Skan return carry; 30018334Speter} 30118334Speter 302117395Skan/* Subtract the significands of A and B, placing the result in R. CARRY is 303117395Skan true if there's a borrow incoming to the least significant word. 304117395Skan Return true if there was borrow out of the most significant word. */ 30518334Speter 306117395Skanstatic inline bool 307132718Skansub_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, 308132718Skan const REAL_VALUE_TYPE *b, int carry) 30918334Speter{ 310117395Skan int i; 31118334Speter 312117395Skan for (i = 0; i < SIGSZ; ++i) 31318334Speter { 314117395Skan unsigned long ai = a->sig[i]; 315117395Skan unsigned long ri = ai - b->sig[i]; 31618334Speter 317117395Skan if (carry) 318117395Skan { 319117395Skan carry = ri > ai; 320117395Skan carry |= ~--ri == 0; 321117395Skan } 322117395Skan else 323117395Skan carry = ri > ai; 32418334Speter 325117395Skan r->sig[i] = ri; 32618334Speter } 32718334Speter 328117395Skan return carry; 329132718Skan} 33018334Speter 331117395Skan/* Negate the significand A, placing the result in R. */ 33218334Speter 333117395Skanstatic inline void 334132718Skanneg_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a) 33518334Speter{ 336117395Skan bool carry = true; 337117395Skan int i; 33818334Speter 339117395Skan for (i = 0; i < SIGSZ; ++i) 34018334Speter { 341117395Skan unsigned long ri, ai = a->sig[i]; 342117395Skan 343117395Skan if (carry) 344117395Skan { 345117395Skan if (ai) 346117395Skan { 347117395Skan ri = -ai; 348117395Skan carry = false; 349117395Skan } 350117395Skan else 351117395Skan ri = ai; 352117395Skan } 35318334Speter else 354117395Skan ri = ~ai; 355117395Skan 356117395Skan r->sig[i] = ri; 35718334Speter } 358132718Skan} 35950397Sobrien 360117395Skan/* Compare significands. Return tri-state vs zero. */ 36150397Sobrien 362132718Skanstatic inline int 363132718Skancmp_significands (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b) 364117395Skan{ 365117395Skan int i; 36650397Sobrien 367117395Skan for (i = SIGSZ - 1; i >= 0; --i) 368117395Skan { 369117395Skan unsigned long ai = a->sig[i]; 370117395Skan unsigned long bi = b->sig[i]; 37150397Sobrien 372117395Skan if (ai > bi) 373117395Skan return 1; 374117395Skan if (ai < bi) 375117395Skan return -1; 376117395Skan } 37750397Sobrien 378117395Skan return 0; 37918334Speter} 38018334Speter 381117395Skan/* Return true if A is nonzero. */ 38218334Speter 383132718Skanstatic inline int 384132718Skancmp_significand_0 (const REAL_VALUE_TYPE *a) 38518334Speter{ 386117395Skan int i; 38718334Speter 388117395Skan for (i = SIGSZ - 1; i >= 0; --i) 389117395Skan if (a->sig[i]) 390117395Skan return 1; 39150397Sobrien 392117395Skan return 0; 39318334Speter} 39418334Speter 395117395Skan/* Set bit N of the significand of R. */ 39618334Speter 397117395Skanstatic inline void 398132718Skanset_significand_bit (REAL_VALUE_TYPE *r, unsigned int n) 39918334Speter{ 400117395Skan r->sig[n / HOST_BITS_PER_LONG] 401117395Skan |= (unsigned long)1 << (n % HOST_BITS_PER_LONG); 40218334Speter} 40318334Speter 404117395Skan/* Clear bit N of the significand of R. */ 40518334Speter 406117395Skanstatic inline void 407132718Skanclear_significand_bit (REAL_VALUE_TYPE *r, unsigned int n) 40818334Speter{ 409117395Skan r->sig[n / HOST_BITS_PER_LONG] 410117395Skan &= ~((unsigned long)1 << (n % HOST_BITS_PER_LONG)); 41118334Speter} 41218334Speter 413117395Skan/* Test bit N of the significand of R. */ 41418334Speter 415117395Skanstatic inline bool 416132718Skantest_significand_bit (REAL_VALUE_TYPE *r, unsigned int n) 41718334Speter{ 418117395Skan /* ??? Compiler bug here if we return this expression directly. 419117395Skan The conversion to bool strips the "&1" and we wind up testing 420117395Skan e.g. 2 != 0 -> true. Seen in gcc version 3.2 20020520. */ 421117395Skan int t = (r->sig[n / HOST_BITS_PER_LONG] >> (n % HOST_BITS_PER_LONG)) & 1; 422117395Skan return t; 42318334Speter} 42418334Speter 425117395Skan/* Clear bits 0..N-1 of the significand of R. */ 42618334Speter 427117395Skanstatic void 428132718Skanclear_significand_below (REAL_VALUE_TYPE *r, unsigned int n) 42918334Speter{ 430117395Skan int i, w = n / HOST_BITS_PER_LONG; 43118334Speter 432117395Skan for (i = 0; i < w; ++i) 433117395Skan r->sig[i] = 0; 434117395Skan 435117395Skan r->sig[w] &= ~(((unsigned long)1 << (n % HOST_BITS_PER_LONG)) - 1); 43618334Speter} 43718334Speter 438117395Skan/* Divide the significands of A and B, placing the result in R. Return 439117395Skan true if the division was inexact. */ 44018334Speter 441117395Skanstatic inline bool 442132718Skandiv_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, 443132718Skan const REAL_VALUE_TYPE *b) 44418334Speter{ 445117395Skan REAL_VALUE_TYPE u; 446117395Skan int i, bit = SIGNIFICAND_BITS - 1; 447117395Skan unsigned long msb, inexact; 44818334Speter 449117395Skan u = *a; 450117395Skan memset (r->sig, 0, sizeof (r->sig)); 45118334Speter 452117395Skan msb = 0; 453117395Skan goto start; 454117395Skan do 45518334Speter { 456117395Skan msb = u.sig[SIGSZ-1] & SIG_MSB; 457117395Skan lshift_significand_1 (&u, &u); 458117395Skan start: 459117395Skan if (msb || cmp_significands (&u, b) >= 0) 460117395Skan { 461117395Skan sub_significands (&u, &u, b, 0); 462117395Skan set_significand_bit (r, bit); 463117395Skan } 464117395Skan } 465117395Skan while (--bit >= 0); 46618334Speter 467117395Skan for (i = 0, inexact = 0; i < SIGSZ; i++) 468117395Skan inexact |= u.sig[i]; 46918334Speter 470117395Skan return inexact != 0; 47118334Speter} 47218334Speter 473117395Skan/* Adjust the exponent and significand of R such that the most 474117395Skan significant bit is set. We underflow to zero and overflow to 475117395Skan infinity here, without denormals. (The intermediate representation 476117395Skan exponent is large enough to handle target denormals normalized.) */ 47750397Sobrien 478117395Skanstatic void 479132718Skannormalize (REAL_VALUE_TYPE *r) 48050397Sobrien{ 481117395Skan int shift = 0, exp; 482117395Skan int i, j; 48350397Sobrien 484169689Skan if (r->decimal) 485169689Skan return; 486169689Skan 487117395Skan /* Find the first word that is nonzero. */ 488117395Skan for (i = SIGSZ - 1; i >= 0; i--) 489117395Skan if (r->sig[i] == 0) 490117395Skan shift += HOST_BITS_PER_LONG; 491117395Skan else 492117395Skan break; 49350397Sobrien 494117395Skan /* Zero significand flushes to zero. */ 495117395Skan if (i < 0) 49650397Sobrien { 497169689Skan r->cl = rvc_zero; 498169689Skan SET_REAL_EXP (r, 0); 499117395Skan return; 50050397Sobrien } 50150397Sobrien 502117395Skan /* Find the first bit that is nonzero. */ 503117395Skan for (j = 0; ; j++) 504117395Skan if (r->sig[i] & ((unsigned long)1 << (HOST_BITS_PER_LONG - 1 - j))) 505117395Skan break; 506117395Skan shift += j; 50750397Sobrien 508117395Skan if (shift > 0) 50950397Sobrien { 510169689Skan exp = REAL_EXP (r) - shift; 511117395Skan if (exp > MAX_EXP) 512117395Skan get_inf (r, r->sign); 513117395Skan else if (exp < -MAX_EXP) 514117395Skan get_zero (r, r->sign); 515117395Skan else 516117395Skan { 517169689Skan SET_REAL_EXP (r, exp); 518117395Skan lshift_significand (r, r, shift); 519117395Skan } 52050397Sobrien } 52150397Sobrien} 52218334Speter 523132718Skan/* Calculate R = A + (SUBTRACT_P ? -B : B). Return true if the 524132718Skan result may be inexact due to a loss of precision. */ 52518334Speter 526132718Skanstatic bool 527132718Skando_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, 528132718Skan const REAL_VALUE_TYPE *b, int subtract_p) 52918334Speter{ 530117395Skan int dexp, sign, exp; 531117395Skan REAL_VALUE_TYPE t; 532117395Skan bool inexact = false; 53318334Speter 534117395Skan /* Determine if we need to add or subtract. */ 535117395Skan sign = a->sign; 536117395Skan subtract_p = (sign ^ b->sign) ^ subtract_p; 53718334Speter 538169689Skan switch (CLASS2 (a->cl, b->cl)) 539117395Skan { 540117395Skan case CLASS2 (rvc_zero, rvc_zero): 541117395Skan /* -0 + -0 = -0, -0 - +0 = -0; all other cases yield +0. */ 542117395Skan get_zero (r, sign & !subtract_p); 543132718Skan return false; 54418334Speter 545117395Skan case CLASS2 (rvc_zero, rvc_normal): 546117395Skan case CLASS2 (rvc_zero, rvc_inf): 547117395Skan case CLASS2 (rvc_zero, rvc_nan): 548117395Skan /* 0 + ANY = ANY. */ 549117395Skan case CLASS2 (rvc_normal, rvc_nan): 550117395Skan case CLASS2 (rvc_inf, rvc_nan): 551117395Skan case CLASS2 (rvc_nan, rvc_nan): 552117395Skan /* ANY + NaN = NaN. */ 553117395Skan case CLASS2 (rvc_normal, rvc_inf): 554117395Skan /* R + Inf = Inf. */ 555117395Skan *r = *b; 556117395Skan r->sign = sign ^ subtract_p; 557132718Skan return false; 55818334Speter 559117395Skan case CLASS2 (rvc_normal, rvc_zero): 560117395Skan case CLASS2 (rvc_inf, rvc_zero): 561117395Skan case CLASS2 (rvc_nan, rvc_zero): 562117395Skan /* ANY + 0 = ANY. */ 563117395Skan case CLASS2 (rvc_nan, rvc_normal): 564117395Skan case CLASS2 (rvc_nan, rvc_inf): 565117395Skan /* NaN + ANY = NaN. */ 566117395Skan case CLASS2 (rvc_inf, rvc_normal): 567117395Skan /* Inf + R = Inf. */ 568117395Skan *r = *a; 569132718Skan return false; 57018334Speter 571117395Skan case CLASS2 (rvc_inf, rvc_inf): 572117395Skan if (subtract_p) 573117395Skan /* Inf - Inf = NaN. */ 574117395Skan get_canonical_qnan (r, 0); 575117395Skan else 576117395Skan /* Inf + Inf = Inf. */ 577117395Skan *r = *a; 578132718Skan return false; 57918334Speter 580117395Skan case CLASS2 (rvc_normal, rvc_normal): 581117395Skan break; 58218334Speter 583117395Skan default: 584169689Skan gcc_unreachable (); 585117395Skan } 58618334Speter 587117395Skan /* Swap the arguments such that A has the larger exponent. */ 588169689Skan dexp = REAL_EXP (a) - REAL_EXP (b); 589117395Skan if (dexp < 0) 590117395Skan { 591117395Skan const REAL_VALUE_TYPE *t; 592117395Skan t = a, a = b, b = t; 593117395Skan dexp = -dexp; 594117395Skan sign ^= subtract_p; 595117395Skan } 596169689Skan exp = REAL_EXP (a); 59718334Speter 598117395Skan /* If the exponents are not identical, we need to shift the 599117395Skan significand of B down. */ 600117395Skan if (dexp > 0) 601117395Skan { 602117395Skan /* If the exponents are too far apart, the significands 603117395Skan do not overlap, which makes the subtraction a noop. */ 604117395Skan if (dexp >= SIGNIFICAND_BITS) 605117395Skan { 606117395Skan *r = *a; 607117395Skan r->sign = sign; 608132718Skan return true; 609117395Skan } 61018334Speter 611117395Skan inexact |= sticky_rshift_significand (&t, b, dexp); 612117395Skan b = &t; 613117395Skan } 61418334Speter 615117395Skan if (subtract_p) 616117395Skan { 617117395Skan if (sub_significands (r, a, b, inexact)) 618117395Skan { 619117395Skan /* We got a borrow out of the subtraction. That means that 620117395Skan A and B had the same exponent, and B had the larger 621117395Skan significand. We need to swap the sign and negate the 622117395Skan significand. */ 623117395Skan sign ^= 1; 624117395Skan neg_significand (r, r); 625117395Skan } 626117395Skan } 627117395Skan else 628117395Skan { 629117395Skan if (add_significands (r, a, b)) 630117395Skan { 631117395Skan /* We got carry out of the addition. This means we need to 632117395Skan shift the significand back down one bit and increase the 633117395Skan exponent. */ 634117395Skan inexact |= sticky_rshift_significand (r, r, 1); 635117395Skan r->sig[SIGSZ-1] |= SIG_MSB; 636117395Skan if (++exp > MAX_EXP) 637117395Skan { 638117395Skan get_inf (r, sign); 639132718Skan return true; 640117395Skan } 641117395Skan } 642117395Skan } 64318334Speter 644169689Skan r->cl = rvc_normal; 645117395Skan r->sign = sign; 646169689Skan SET_REAL_EXP (r, exp); 647146895Skan /* Zero out the remaining fields. */ 648146895Skan r->signalling = 0; 649146895Skan r->canonical = 0; 650169689Skan r->decimal = 0; 65118334Speter 652117395Skan /* Re-normalize the result. */ 653117395Skan normalize (r); 65418334Speter 655117395Skan /* Special case: if the subtraction results in zero, the result 656117395Skan is positive. */ 657169689Skan if (r->cl == rvc_zero) 658117395Skan r->sign = 0; 659117395Skan else 660117395Skan r->sig[0] |= inexact; 661132718Skan 662132718Skan return inexact; 66318334Speter} 66418334Speter 665132718Skan/* Calculate R = A * B. Return true if the result may be inexact. */ 66618334Speter 667132718Skanstatic bool 668132718Skando_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, 669132718Skan const REAL_VALUE_TYPE *b) 67018334Speter{ 671117395Skan REAL_VALUE_TYPE u, t, *rr; 672117395Skan unsigned int i, j, k; 673117395Skan int sign = a->sign ^ b->sign; 674132718Skan bool inexact = false; 67518334Speter 676169689Skan switch (CLASS2 (a->cl, b->cl)) 677117395Skan { 678117395Skan case CLASS2 (rvc_zero, rvc_zero): 679117395Skan case CLASS2 (rvc_zero, rvc_normal): 680117395Skan case CLASS2 (rvc_normal, rvc_zero): 681117395Skan /* +-0 * ANY = 0 with appropriate sign. */ 682117395Skan get_zero (r, sign); 683132718Skan return false; 68418334Speter 685117395Skan case CLASS2 (rvc_zero, rvc_nan): 686117395Skan case CLASS2 (rvc_normal, rvc_nan): 687117395Skan case CLASS2 (rvc_inf, rvc_nan): 688117395Skan case CLASS2 (rvc_nan, rvc_nan): 689117395Skan /* ANY * NaN = NaN. */ 690117395Skan *r = *b; 691117395Skan r->sign = sign; 692132718Skan return false; 69318334Speter 694117395Skan case CLASS2 (rvc_nan, rvc_zero): 695117395Skan case CLASS2 (rvc_nan, rvc_normal): 696117395Skan case CLASS2 (rvc_nan, rvc_inf): 697117395Skan /* NaN * ANY = NaN. */ 698117395Skan *r = *a; 699117395Skan r->sign = sign; 700132718Skan return false; 70118334Speter 702117395Skan case CLASS2 (rvc_zero, rvc_inf): 703117395Skan case CLASS2 (rvc_inf, rvc_zero): 704117395Skan /* 0 * Inf = NaN */ 705117395Skan get_canonical_qnan (r, sign); 706132718Skan return false; 70718334Speter 708117395Skan case CLASS2 (rvc_inf, rvc_inf): 709117395Skan case CLASS2 (rvc_normal, rvc_inf): 710117395Skan case CLASS2 (rvc_inf, rvc_normal): 711117395Skan /* Inf * Inf = Inf, R * Inf = Inf */ 712117395Skan get_inf (r, sign); 713132718Skan return false; 71418334Speter 715117395Skan case CLASS2 (rvc_normal, rvc_normal): 716117395Skan break; 71718334Speter 718117395Skan default: 719169689Skan gcc_unreachable (); 720117395Skan } 72118334Speter 722117395Skan if (r == a || r == b) 723117395Skan rr = &t; 724117395Skan else 725117395Skan rr = r; 726117395Skan get_zero (rr, 0); 72752284Sobrien 728117395Skan /* Collect all the partial products. Since we don't have sure access 729117395Skan to a widening multiply, we split each long into two half-words. 73052284Sobrien 731117395Skan Consider the long-hand form of a four half-word multiplication: 73252284Sobrien 733117395Skan A B C D 734117395Skan * E F G H 735117395Skan -------------- 736117395Skan DE DF DG DH 737117395Skan CE CF CG CH 738117395Skan BE BF BG BH 739117395Skan AE AF AG AH 74052284Sobrien 741117395Skan We construct partial products of the widened half-word products 742117395Skan that are known to not overlap, e.g. DF+DH. Each such partial 743117395Skan product is given its proper exponent, which allows us to sum them 744117395Skan and obtain the finished product. */ 74518334Speter 746117395Skan for (i = 0; i < SIGSZ * 2; ++i) 747117395Skan { 748117395Skan unsigned long ai = a->sig[i / 2]; 749117395Skan if (i & 1) 750117395Skan ai >>= HOST_BITS_PER_LONG / 2; 751117395Skan else 752117395Skan ai &= ((unsigned long)1 << (HOST_BITS_PER_LONG / 2)) - 1; 75352284Sobrien 754117395Skan if (ai == 0) 755117395Skan continue; 75652284Sobrien 757117395Skan for (j = 0; j < 2; ++j) 758117395Skan { 759169689Skan int exp = (REAL_EXP (a) - (2*SIGSZ-1-i)*(HOST_BITS_PER_LONG/2) 760169689Skan + (REAL_EXP (b) - (1-j)*(HOST_BITS_PER_LONG/2))); 76118334Speter 762117395Skan if (exp > MAX_EXP) 763132718Skan { 764132718Skan get_inf (r, sign); 765132718Skan return true; 766132718Skan } 767117395Skan if (exp < -MAX_EXP) 768132718Skan { 769132718Skan /* Would underflow to zero, which we shouldn't bother adding. */ 770132718Skan inexact = true; 771132718Skan continue; 772132718Skan } 77318334Speter 774132718Skan memset (&u, 0, sizeof (u)); 775169689Skan u.cl = rvc_normal; 776169689Skan SET_REAL_EXP (&u, exp); 77752284Sobrien 778117395Skan for (k = j; k < SIGSZ * 2; k += 2) 779117395Skan { 780117395Skan unsigned long bi = b->sig[k / 2]; 781117395Skan if (k & 1) 782117395Skan bi >>= HOST_BITS_PER_LONG / 2; 783117395Skan else 784117395Skan bi &= ((unsigned long)1 << (HOST_BITS_PER_LONG / 2)) - 1; 78552284Sobrien 786117395Skan u.sig[k / 2] = ai * bi; 787117395Skan } 78852284Sobrien 789117395Skan normalize (&u); 790132718Skan inexact |= do_add (rr, rr, &u, 0); 791117395Skan } 792117395Skan } 79352284Sobrien 794117395Skan rr->sign = sign; 795117395Skan if (rr != r) 796117395Skan *r = t; 797132718Skan 798132718Skan return inexact; 799117395Skan} 80018334Speter 801132718Skan/* Calculate R = A / B. Return true if the result may be inexact. */ 80218334Speter 803132718Skanstatic bool 804132718Skando_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, 805132718Skan const REAL_VALUE_TYPE *b) 80618334Speter{ 807117395Skan int exp, sign = a->sign ^ b->sign; 808117395Skan REAL_VALUE_TYPE t, *rr; 809117395Skan bool inexact; 81018334Speter 811169689Skan switch (CLASS2 (a->cl, b->cl)) 812117395Skan { 813117395Skan case CLASS2 (rvc_zero, rvc_zero): 814117395Skan /* 0 / 0 = NaN. */ 815117395Skan case CLASS2 (rvc_inf, rvc_inf): 816117395Skan /* Inf / Inf = NaN. */ 817117395Skan get_canonical_qnan (r, sign); 818132718Skan return false; 81918334Speter 820117395Skan case CLASS2 (rvc_zero, rvc_normal): 821117395Skan case CLASS2 (rvc_zero, rvc_inf): 822117395Skan /* 0 / ANY = 0. */ 823117395Skan case CLASS2 (rvc_normal, rvc_inf): 824117395Skan /* R / Inf = 0. */ 825117395Skan get_zero (r, sign); 826132718Skan return false; 82718334Speter 828117395Skan case CLASS2 (rvc_normal, rvc_zero): 829117395Skan /* R / 0 = Inf. */ 830117395Skan case CLASS2 (rvc_inf, rvc_zero): 831117395Skan /* Inf / 0 = Inf. */ 832117395Skan get_inf (r, sign); 833132718Skan return false; 83418334Speter 835117395Skan case CLASS2 (rvc_zero, rvc_nan): 836117395Skan case CLASS2 (rvc_normal, rvc_nan): 837117395Skan case CLASS2 (rvc_inf, rvc_nan): 838117395Skan case CLASS2 (rvc_nan, rvc_nan): 839117395Skan /* ANY / NaN = NaN. */ 840117395Skan *r = *b; 841117395Skan r->sign = sign; 842132718Skan return false; 84318334Speter 844117395Skan case CLASS2 (rvc_nan, rvc_zero): 845117395Skan case CLASS2 (rvc_nan, rvc_normal): 846117395Skan case CLASS2 (rvc_nan, rvc_inf): 847117395Skan /* NaN / ANY = NaN. */ 848117395Skan *r = *a; 849117395Skan r->sign = sign; 850132718Skan return false; 85118334Speter 852117395Skan case CLASS2 (rvc_inf, rvc_normal): 853117395Skan /* Inf / R = Inf. */ 854117395Skan get_inf (r, sign); 855132718Skan return false; 85618334Speter 857117395Skan case CLASS2 (rvc_normal, rvc_normal): 858117395Skan break; 85918334Speter 860117395Skan default: 861169689Skan gcc_unreachable (); 862117395Skan } 86318334Speter 864117395Skan if (r == a || r == b) 865117395Skan rr = &t; 866117395Skan else 867117395Skan rr = r; 86818334Speter 869132718Skan /* Make sure all fields in the result are initialized. */ 870132718Skan get_zero (rr, 0); 871169689Skan rr->cl = rvc_normal; 872117395Skan rr->sign = sign; 87318334Speter 874169689Skan exp = REAL_EXP (a) - REAL_EXP (b) + 1; 875117395Skan if (exp > MAX_EXP) 876132718Skan { 877132718Skan get_inf (r, sign); 878132718Skan return true; 879132718Skan } 880117395Skan if (exp < -MAX_EXP) 881132718Skan { 882132718Skan get_zero (r, sign); 883132718Skan return true; 884132718Skan } 885169689Skan SET_REAL_EXP (rr, exp); 88618334Speter 887117395Skan inexact = div_significands (rr, a, b); 88818334Speter 889117395Skan /* Re-normalize the result. */ 890117395Skan normalize (rr); 891117395Skan rr->sig[0] |= inexact; 892117395Skan 893117395Skan if (rr != r) 894117395Skan *r = t; 895132718Skan 896132718Skan return inexact; 89718334Speter} 89818334Speter 899117395Skan/* Return a tri-state comparison of A vs B. Return NAN_RESULT if 900117395Skan one of the two operands is a NaN. */ 90118334Speter 90252284Sobrienstatic int 903132718Skando_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b, 904132718Skan int nan_result) 90518334Speter{ 906117395Skan int ret; 90718334Speter 908169689Skan switch (CLASS2 (a->cl, b->cl)) 909117395Skan { 910117395Skan case CLASS2 (rvc_zero, rvc_zero): 911117395Skan /* Sign of zero doesn't matter for compares. */ 912117395Skan return 0; 91318334Speter 914117395Skan case CLASS2 (rvc_inf, rvc_zero): 915117395Skan case CLASS2 (rvc_inf, rvc_normal): 916117395Skan case CLASS2 (rvc_normal, rvc_zero): 917117395Skan return (a->sign ? -1 : 1); 91818334Speter 919117395Skan case CLASS2 (rvc_inf, rvc_inf): 920117395Skan return -a->sign - -b->sign; 92118334Speter 922117395Skan case CLASS2 (rvc_zero, rvc_normal): 923117395Skan case CLASS2 (rvc_zero, rvc_inf): 924117395Skan case CLASS2 (rvc_normal, rvc_inf): 925117395Skan return (b->sign ? 1 : -1); 92618334Speter 927117395Skan case CLASS2 (rvc_zero, rvc_nan): 928117395Skan case CLASS2 (rvc_normal, rvc_nan): 929117395Skan case CLASS2 (rvc_inf, rvc_nan): 930117395Skan case CLASS2 (rvc_nan, rvc_nan): 931117395Skan case CLASS2 (rvc_nan, rvc_zero): 932117395Skan case CLASS2 (rvc_nan, rvc_normal): 933117395Skan case CLASS2 (rvc_nan, rvc_inf): 934117395Skan return nan_result; 93518334Speter 936117395Skan case CLASS2 (rvc_normal, rvc_normal): 937117395Skan break; 93818334Speter 939117395Skan default: 940169689Skan gcc_unreachable (); 94118334Speter } 94218334Speter 943117395Skan if (a->sign != b->sign) 944117395Skan return -a->sign - -b->sign; 94518334Speter 946169689Skan if (a->decimal || b->decimal) 947169689Skan return decimal_do_compare (a, b, nan_result); 948169689Skan 949169689Skan if (REAL_EXP (a) > REAL_EXP (b)) 950117395Skan ret = 1; 951169689Skan else if (REAL_EXP (a) < REAL_EXP (b)) 952117395Skan ret = -1; 953117395Skan else 954117395Skan ret = cmp_significands (a, b); 95518334Speter 956117395Skan return (a->sign ? -ret : ret); 95718334Speter} 95818334Speter 959117395Skan/* Return A truncated to an integral value toward zero. */ 96018334Speter 96152284Sobrienstatic void 962132718Skando_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a) 96318334Speter{ 964117395Skan *r = *a; 96518334Speter 966169689Skan switch (r->cl) 96718334Speter { 968117395Skan case rvc_zero: 969117395Skan case rvc_inf: 970117395Skan case rvc_nan: 971117395Skan break; 97218334Speter 973117395Skan case rvc_normal: 974169689Skan if (r->decimal) 975169689Skan { 976169689Skan decimal_do_fix_trunc (r, a); 977169689Skan return; 978169689Skan } 979169689Skan if (REAL_EXP (r) <= 0) 980117395Skan get_zero (r, r->sign); 981169689Skan else if (REAL_EXP (r) < SIGNIFICAND_BITS) 982169689Skan clear_significand_below (r, SIGNIFICAND_BITS - REAL_EXP (r)); 983117395Skan break; 984117395Skan 985117395Skan default: 986169689Skan gcc_unreachable (); 98718334Speter } 98818334Speter} 98918334Speter 990117395Skan/* Perform the binary or unary operation described by CODE. 991169689Skan For a unary operation, leave OP1 NULL. This function returns 992169689Skan true if the result may be inexact due to loss of precision. */ 99318334Speter 994169689Skanbool 995132718Skanreal_arithmetic (REAL_VALUE_TYPE *r, int icode, const REAL_VALUE_TYPE *op0, 996132718Skan const REAL_VALUE_TYPE *op1) 99718334Speter{ 998117395Skan enum tree_code code = icode; 99918334Speter 1000169689Skan if (op0->decimal || (op1 && op1->decimal)) 1001169689Skan return decimal_real_arithmetic (r, icode, op0, op1); 1002169689Skan 1003117395Skan switch (code) 100418334Speter { 1005117395Skan case PLUS_EXPR: 1006169689Skan return do_add (r, op0, op1, 0); 100718334Speter 1008117395Skan case MINUS_EXPR: 1009169689Skan return do_add (r, op0, op1, 1); 101018334Speter 1011117395Skan case MULT_EXPR: 1012169689Skan return do_multiply (r, op0, op1); 101318334Speter 1014117395Skan case RDIV_EXPR: 1015169689Skan return do_divide (r, op0, op1); 101618334Speter 1017117395Skan case MIN_EXPR: 1018169689Skan if (op1->cl == rvc_nan) 1019117395Skan *r = *op1; 1020117395Skan else if (do_compare (op0, op1, -1) < 0) 1021117395Skan *r = *op0; 1022117395Skan else 1023117395Skan *r = *op1; 1024117395Skan break; 102518334Speter 1026117395Skan case MAX_EXPR: 1027169689Skan if (op1->cl == rvc_nan) 1028117395Skan *r = *op1; 1029117395Skan else if (do_compare (op0, op1, 1) < 0) 1030117395Skan *r = *op1; 1031117395Skan else 1032117395Skan *r = *op0; 1033117395Skan break; 103418334Speter 1035117395Skan case NEGATE_EXPR: 1036117395Skan *r = *op0; 1037117395Skan r->sign ^= 1; 1038117395Skan break; 103918334Speter 1040117395Skan case ABS_EXPR: 1041117395Skan *r = *op0; 1042117395Skan r->sign = 0; 1043117395Skan break; 104418334Speter 1045117395Skan case FIX_TRUNC_EXPR: 1046117395Skan do_fix_trunc (r, op0); 1047117395Skan break; 104818334Speter 1049117395Skan default: 1050169689Skan gcc_unreachable (); 1051117395Skan } 1052169689Skan return false; 105318334Speter} 105418334Speter 1055117395Skan/* Legacy. Similar, but return the result directly. */ 105618334Speter 1057117395SkanREAL_VALUE_TYPE 1058132718Skanreal_arithmetic2 (int icode, const REAL_VALUE_TYPE *op0, 1059132718Skan const REAL_VALUE_TYPE *op1) 106018334Speter{ 1061117395Skan REAL_VALUE_TYPE r; 1062117395Skan real_arithmetic (&r, icode, op0, op1); 1063117395Skan return r; 106418334Speter} 106518334Speter 1066117395Skanbool 1067132718Skanreal_compare (int icode, const REAL_VALUE_TYPE *op0, 1068132718Skan const REAL_VALUE_TYPE *op1) 106918334Speter{ 1070117395Skan enum tree_code code = icode; 107118334Speter 1072117395Skan switch (code) 107318334Speter { 1074117395Skan case LT_EXPR: 1075117395Skan return do_compare (op0, op1, 1) < 0; 1076117395Skan case LE_EXPR: 1077117395Skan return do_compare (op0, op1, 1) <= 0; 1078117395Skan case GT_EXPR: 1079117395Skan return do_compare (op0, op1, -1) > 0; 1080117395Skan case GE_EXPR: 1081117395Skan return do_compare (op0, op1, -1) >= 0; 1082117395Skan case EQ_EXPR: 1083117395Skan return do_compare (op0, op1, -1) == 0; 1084117395Skan case NE_EXPR: 1085117395Skan return do_compare (op0, op1, -1) != 0; 1086117395Skan case UNORDERED_EXPR: 1087169689Skan return op0->cl == rvc_nan || op1->cl == rvc_nan; 1088117395Skan case ORDERED_EXPR: 1089169689Skan return op0->cl != rvc_nan && op1->cl != rvc_nan; 1090117395Skan case UNLT_EXPR: 1091117395Skan return do_compare (op0, op1, -1) < 0; 1092117395Skan case UNLE_EXPR: 1093117395Skan return do_compare (op0, op1, -1) <= 0; 1094117395Skan case UNGT_EXPR: 1095117395Skan return do_compare (op0, op1, 1) > 0; 1096117395Skan case UNGE_EXPR: 1097117395Skan return do_compare (op0, op1, 1) >= 0; 1098117395Skan case UNEQ_EXPR: 1099117395Skan return do_compare (op0, op1, 0) == 0; 1100169689Skan case LTGT_EXPR: 1101169689Skan return do_compare (op0, op1, 0) != 0; 1102117395Skan 1103117395Skan default: 1104169689Skan gcc_unreachable (); 110518334Speter } 110618334Speter} 110718334Speter 1108117395Skan/* Return floor log2(R). */ 110918334Speter 1110117395Skanint 1111132718Skanreal_exponent (const REAL_VALUE_TYPE *r) 111218334Speter{ 1113169689Skan switch (r->cl) 1114117395Skan { 1115117395Skan case rvc_zero: 1116117395Skan return 0; 1117117395Skan case rvc_inf: 1118117395Skan case rvc_nan: 1119117395Skan return (unsigned int)-1 >> 1; 1120117395Skan case rvc_normal: 1121169689Skan return REAL_EXP (r); 1122117395Skan default: 1123169689Skan gcc_unreachable (); 1124117395Skan } 112518334Speter} 112618334Speter 1127117395Skan/* R = OP0 * 2**EXP. */ 112818334Speter 1129117395Skanvoid 1130132718Skanreal_ldexp (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0, int exp) 113118334Speter{ 1132117395Skan *r = *op0; 1133169689Skan switch (r->cl) 1134117395Skan { 1135117395Skan case rvc_zero: 1136117395Skan case rvc_inf: 1137117395Skan case rvc_nan: 1138117395Skan break; 113918334Speter 1140117395Skan case rvc_normal: 1141169689Skan exp += REAL_EXP (op0); 1142117395Skan if (exp > MAX_EXP) 1143117395Skan get_inf (r, r->sign); 1144117395Skan else if (exp < -MAX_EXP) 1145117395Skan get_zero (r, r->sign); 1146117395Skan else 1147169689Skan SET_REAL_EXP (r, exp); 1148117395Skan break; 114918334Speter 1150117395Skan default: 1151169689Skan gcc_unreachable (); 1152117395Skan } 115318334Speter} 115418334Speter 1155117395Skan/* Determine whether a floating-point value X is infinite. */ 115618334Speter 1157117395Skanbool 1158132718Skanreal_isinf (const REAL_VALUE_TYPE *r) 115918334Speter{ 1160169689Skan return (r->cl == rvc_inf); 116118334Speter} 116218334Speter 1163117395Skan/* Determine whether a floating-point value X is a NaN. */ 116418334Speter 1165117395Skanbool 1166132718Skanreal_isnan (const REAL_VALUE_TYPE *r) 116718334Speter{ 1168169689Skan return (r->cl == rvc_nan); 116918334Speter} 117018334Speter 1171117395Skan/* Determine whether a floating-point value X is negative. */ 117218334Speter 1173117395Skanbool 1174132718Skanreal_isneg (const REAL_VALUE_TYPE *r) 117518334Speter{ 1176117395Skan return r->sign; 117718334Speter} 117818334Speter 1179117395Skan/* Determine whether a floating-point value X is minus zero. */ 118018334Speter 1181117395Skanbool 1182132718Skanreal_isnegzero (const REAL_VALUE_TYPE *r) 118318334Speter{ 1184169689Skan return r->sign && r->cl == rvc_zero; 118518334Speter} 118618334Speter 1187117395Skan/* Compare two floating-point objects for bitwise identity. */ 118818334Speter 1189132718Skanbool 1190132718Skanreal_identical (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b) 119118334Speter{ 119218334Speter int i; 119318334Speter 1194169689Skan if (a->cl != b->cl) 1195117395Skan return false; 1196117395Skan if (a->sign != b->sign) 1197117395Skan return false; 119818334Speter 1199169689Skan switch (a->cl) 120018334Speter { 1201117395Skan case rvc_zero: 1202117395Skan case rvc_inf: 1203132718Skan return true; 120418334Speter 1205117395Skan case rvc_normal: 1206169689Skan if (a->decimal != b->decimal) 1207169689Skan return false; 1208169689Skan if (REAL_EXP (a) != REAL_EXP (b)) 1209132718Skan return false; 1210132718Skan break; 1211132718Skan 1212117395Skan case rvc_nan: 1213132718Skan if (a->signalling != b->signalling) 1214132718Skan return false; 1215132718Skan /* The significand is ignored for canonical NaNs. */ 1216132718Skan if (a->canonical || b->canonical) 1217132718Skan return a->canonical == b->canonical; 1218117395Skan break; 121918334Speter 1220117395Skan default: 1221169689Skan gcc_unreachable (); 1222117395Skan } 122318334Speter 1224132718Skan for (i = 0; i < SIGSZ; ++i) 1225132718Skan if (a->sig[i] != b->sig[i]) 1226132718Skan return false; 1227132718Skan 1228117395Skan return true; 122918334Speter} 123018334Speter 1231117395Skan/* Try to change R into its exact multiplicative inverse in machine 1232117395Skan mode MODE. Return true if successful. */ 123318334Speter 1234117395Skanbool 1235132718Skanexact_real_inverse (enum machine_mode mode, REAL_VALUE_TYPE *r) 123618334Speter{ 1237117395Skan const REAL_VALUE_TYPE *one = real_digit (1); 1238117395Skan REAL_VALUE_TYPE u; 123918334Speter int i; 1240132718Skan 1241169689Skan if (r->cl != rvc_normal) 1242117395Skan return false; 124318334Speter 1244117395Skan /* Check for a power of two: all significand bits zero except the MSB. */ 1245117395Skan for (i = 0; i < SIGSZ-1; ++i) 1246117395Skan if (r->sig[i] != 0) 1247117395Skan return false; 1248117395Skan if (r->sig[SIGSZ-1] != SIG_MSB) 1249117395Skan return false; 125018334Speter 1251117395Skan /* Find the inverse and truncate to the required mode. */ 1252117395Skan do_divide (&u, one, r); 1253117395Skan real_convert (&u, mode, &u); 1254132718Skan 1255117395Skan /* The rounding may have overflowed. */ 1256169689Skan if (u.cl != rvc_normal) 1257117395Skan return false; 1258117395Skan for (i = 0; i < SIGSZ-1; ++i) 1259117395Skan if (u.sig[i] != 0) 1260117395Skan return false; 1261117395Skan if (u.sig[SIGSZ-1] != SIG_MSB) 1262117395Skan return false; 126318334Speter 1264117395Skan *r = u; 1265117395Skan return true; 126618334Speter} 1267117395Skan 1268117395Skan/* Render R as an integer. */ 126918334Speter 1270117395SkanHOST_WIDE_INT 1271132718Skanreal_to_integer (const REAL_VALUE_TYPE *r) 127218334Speter{ 1273117395Skan unsigned HOST_WIDE_INT i; 127418334Speter 1275169689Skan switch (r->cl) 127618334Speter { 1277117395Skan case rvc_zero: 1278117395Skan underflow: 1279117395Skan return 0; 128018334Speter 1281117395Skan case rvc_inf: 1282117395Skan case rvc_nan: 1283117395Skan overflow: 1284117395Skan i = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1); 1285117395Skan if (!r->sign) 1286117395Skan i--; 1287117395Skan return i; 128818334Speter 1289117395Skan case rvc_normal: 1290169689Skan if (r->decimal) 1291169689Skan return decimal_real_to_integer (r); 1292169689Skan 1293169689Skan if (REAL_EXP (r) <= 0) 1294117395Skan goto underflow; 1295132718Skan /* Only force overflow for unsigned overflow. Signed overflow is 1296132718Skan undefined, so it doesn't matter what we return, and some callers 1297132718Skan expect to be able to use this routine for both signed and 1298132718Skan unsigned conversions. */ 1299169689Skan if (REAL_EXP (r) > HOST_BITS_PER_WIDE_INT) 1300117395Skan goto overflow; 130118334Speter 1302117395Skan if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG) 1303117395Skan i = r->sig[SIGSZ-1]; 1304169689Skan else 1305117395Skan { 1306169689Skan gcc_assert (HOST_BITS_PER_WIDE_INT == 2 * HOST_BITS_PER_LONG); 1307117395Skan i = r->sig[SIGSZ-1]; 1308117395Skan i = i << (HOST_BITS_PER_LONG - 1) << 1; 1309117395Skan i |= r->sig[SIGSZ-2]; 1310117395Skan } 131118334Speter 1312169689Skan i >>= HOST_BITS_PER_WIDE_INT - REAL_EXP (r); 131318334Speter 1314117395Skan if (r->sign) 1315117395Skan i = -i; 1316117395Skan return i; 131718334Speter 1318117395Skan default: 1319169689Skan gcc_unreachable (); 1320117395Skan } 1321117395Skan} 132218334Speter 1323117395Skan/* Likewise, but to an integer pair, HI+LOW. */ 132418334Speter 1325117395Skanvoid 1326132718Skanreal_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh, 1327132718Skan const REAL_VALUE_TYPE *r) 132818334Speter{ 1329117395Skan REAL_VALUE_TYPE t; 1330117395Skan HOST_WIDE_INT low, high; 1331117395Skan int exp; 133218334Speter 1333169689Skan switch (r->cl) 133418334Speter { 1335117395Skan case rvc_zero: 1336117395Skan underflow: 1337117395Skan low = high = 0; 1338117395Skan break; 133918334Speter 1340117395Skan case rvc_inf: 1341117395Skan case rvc_nan: 1342117395Skan overflow: 1343117395Skan high = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1); 1344117395Skan if (r->sign) 1345117395Skan low = 0; 1346117395Skan else 1347117395Skan { 1348117395Skan high--; 1349117395Skan low = -1; 1350117395Skan } 1351117395Skan break; 135218334Speter 1353117395Skan case rvc_normal: 1354169689Skan if (r->decimal) 1355169689Skan { 1356169689Skan decimal_real_to_integer2 (plow, phigh, r); 1357169689Skan return; 1358169689Skan } 1359169689Skan 1360169689Skan exp = REAL_EXP (r); 1361117395Skan if (exp <= 0) 1362117395Skan goto underflow; 1363132718Skan /* Only force overflow for unsigned overflow. Signed overflow is 1364132718Skan undefined, so it doesn't matter what we return, and some callers 1365132718Skan expect to be able to use this routine for both signed and 1366132718Skan unsigned conversions. */ 1367117395Skan if (exp > 2*HOST_BITS_PER_WIDE_INT) 1368117395Skan goto overflow; 1369117395Skan 1370117395Skan rshift_significand (&t, r, 2*HOST_BITS_PER_WIDE_INT - exp); 1371117395Skan if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG) 137218334Speter { 1373117395Skan high = t.sig[SIGSZ-1]; 1374117395Skan low = t.sig[SIGSZ-2]; 137518334Speter } 1376169689Skan else 1377117395Skan { 1378169689Skan gcc_assert (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG); 1379117395Skan high = t.sig[SIGSZ-1]; 1380117395Skan high = high << (HOST_BITS_PER_LONG - 1) << 1; 1381117395Skan high |= t.sig[SIGSZ-2]; 138218334Speter 1383117395Skan low = t.sig[SIGSZ-3]; 1384117395Skan low = low << (HOST_BITS_PER_LONG - 1) << 1; 1385117395Skan low |= t.sig[SIGSZ-4]; 1386117395Skan } 138718334Speter 1388117395Skan if (r->sign) 138918334Speter { 1390117395Skan if (low == 0) 1391117395Skan high = -high; 139218334Speter else 1393117395Skan low = -low, high = ~high; 139418334Speter } 1395117395Skan break; 1396117395Skan 1397117395Skan default: 1398169689Skan gcc_unreachable (); 139918334Speter } 140018334Speter 1401117395Skan *plow = low; 1402117395Skan *phigh = high; 1403117395Skan} 140418334Speter 1405117395Skan/* A subroutine of real_to_decimal. Compute the quotient and remainder 1406117395Skan of NUM / DEN. Return the quotient and place the remainder in NUM. 1407117395Skan It is expected that NUM / DEN are close enough that the quotient is 1408117395Skan small. */ 140918334Speter 1410117395Skanstatic unsigned long 1411132718Skanrtd_divmod (REAL_VALUE_TYPE *num, REAL_VALUE_TYPE *den) 1412117395Skan{ 1413117395Skan unsigned long q, msb; 1414169689Skan int expn = REAL_EXP (num), expd = REAL_EXP (den); 1415117395Skan 1416117395Skan if (expn < expd) 1417117395Skan return 0; 1418117395Skan 1419117395Skan q = msb = 0; 1420117395Skan goto start; 1421117395Skan do 142218334Speter { 1423117395Skan msb = num->sig[SIGSZ-1] & SIG_MSB; 1424117395Skan q <<= 1; 1425117395Skan lshift_significand_1 (num, num); 1426117395Skan start: 1427117395Skan if (msb || cmp_significands (num, den) >= 0) 142818334Speter { 1429117395Skan sub_significands (num, num, den, 0); 1430117395Skan q |= 1; 143118334Speter } 143218334Speter } 1433117395Skan while (--expn >= expd); 143418334Speter 1435169689Skan SET_REAL_EXP (num, expd); 1436117395Skan normalize (num); 143718334Speter 1438117395Skan return q; 143918334Speter} 144018334Speter 1441117395Skan/* Render R as a decimal floating point constant. Emit DIGITS significant 1442117395Skan digits in the result, bounded by BUF_SIZE. If DIGITS is 0, choose the 1443117395Skan maximum for the representation. If CROP_TRAILING_ZEROS, strip trailing 1444117395Skan zeros. */ 144518334Speter 1446117395Skan#define M_LOG10_2 0.30102999566398119521 144750397Sobrien 1448117395Skanvoid 1449132718Skanreal_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig, size_t buf_size, 1450132718Skan size_t digits, int crop_trailing_zeros) 145118334Speter{ 1452117395Skan const REAL_VALUE_TYPE *one, *ten; 1453117395Skan REAL_VALUE_TYPE r, pten, u, v; 1454117395Skan int dec_exp, cmp_one, digit; 1455117395Skan size_t max_digits; 1456117395Skan char *p, *first, *last; 1457117395Skan bool sign; 145818334Speter 1459117395Skan r = *r_orig; 1460169689Skan switch (r.cl) 146118334Speter { 1462117395Skan case rvc_zero: 1463117395Skan strcpy (str, (r.sign ? "-0.0" : "0.0")); 1464117395Skan return; 1465117395Skan case rvc_normal: 1466117395Skan break; 1467117395Skan case rvc_inf: 1468117395Skan strcpy (str, (r.sign ? "-Inf" : "+Inf")); 1469117395Skan return; 1470117395Skan case rvc_nan: 1471117395Skan /* ??? Print the significand as well, if not canonical? */ 1472117395Skan strcpy (str, (r.sign ? "-NaN" : "+NaN")); 1473117395Skan return; 1474117395Skan default: 1475169689Skan gcc_unreachable (); 147618334Speter } 147718334Speter 1478169689Skan if (r.decimal) 1479169689Skan { 1480169689Skan decimal_real_to_decimal (str, &r, buf_size, digits, crop_trailing_zeros); 1481169689Skan return; 1482169689Skan } 1483169689Skan 1484117395Skan /* Bound the number of digits printed by the size of the representation. */ 1485117395Skan max_digits = SIGNIFICAND_BITS * M_LOG10_2; 1486117395Skan if (digits == 0 || digits > max_digits) 1487117395Skan digits = max_digits; 148818334Speter 1489117395Skan /* Estimate the decimal exponent, and compute the length of the string it 1490117395Skan will print as. Be conservative and add one to account for possible 1491117395Skan overflow or rounding error. */ 1492169689Skan dec_exp = REAL_EXP (&r) * M_LOG10_2; 1493117395Skan for (max_digits = 1; dec_exp ; max_digits++) 1494117395Skan dec_exp /= 10; 149518334Speter 1496117395Skan /* Bound the number of digits printed by the size of the output buffer. */ 1497117395Skan max_digits = buf_size - 1 - 1 - 2 - max_digits - 1; 1498169689Skan gcc_assert (max_digits <= buf_size); 1499117395Skan if (digits > max_digits) 1500117395Skan digits = max_digits; 150118334Speter 1502117395Skan one = real_digit (1); 1503117395Skan ten = ten_to_ptwo (0); 150418334Speter 1505117395Skan sign = r.sign; 1506117395Skan r.sign = 0; 150718334Speter 1508117395Skan dec_exp = 0; 1509117395Skan pten = *one; 151018334Speter 1511117395Skan cmp_one = do_compare (&r, one, 0); 1512117395Skan if (cmp_one > 0) 151318334Speter { 1514117395Skan int m; 151518334Speter 1516117395Skan /* Number is greater than one. Convert significand to an integer 1517117395Skan and strip trailing decimal zeros. */ 151818334Speter 1519117395Skan u = r; 1520169689Skan SET_REAL_EXP (&u, SIGNIFICAND_BITS - 1); 152118334Speter 1522117395Skan /* Largest M, such that 10**2**M fits within SIGNIFICAND_BITS. */ 1523117395Skan m = floor_log2 (max_digits); 152418334Speter 1525117395Skan /* Iterate over the bits of the possible powers of 10 that might 1526117395Skan be present in U and eliminate them. That is, if we find that 1527132718Skan 10**2**M divides U evenly, keep the division and increase 1528117395Skan DEC_EXP by 2**M. */ 1529117395Skan do 1530117395Skan { 1531117395Skan REAL_VALUE_TYPE t; 153218334Speter 1533117395Skan do_divide (&t, &u, ten_to_ptwo (m)); 1534117395Skan do_fix_trunc (&v, &t); 1535117395Skan if (cmp_significands (&v, &t) == 0) 153618334Speter { 1537117395Skan u = t; 1538117395Skan dec_exp += 1 << m; 153918334Speter } 154018334Speter } 1541117395Skan while (--m >= 0); 154218334Speter 1543117395Skan /* Revert the scaling to integer that we performed earlier. */ 1544169689Skan SET_REAL_EXP (&u, REAL_EXP (&u) + REAL_EXP (&r) 1545169689Skan - (SIGNIFICAND_BITS - 1)); 1546117395Skan r = u; 154718334Speter 1548117395Skan /* Find power of 10. Do this by dividing out 10**2**M when 1549132718Skan this is larger than the current remainder. Fill PTEN with 1550117395Skan the power of 10 that we compute. */ 1551169689Skan if (REAL_EXP (&r) > 0) 155218334Speter { 1553169689Skan m = floor_log2 ((int)(REAL_EXP (&r) * M_LOG10_2)) + 1; 1554117395Skan do 1555117395Skan { 1556117395Skan const REAL_VALUE_TYPE *ptentwo = ten_to_ptwo (m); 1557117395Skan if (do_compare (&u, ptentwo, 0) >= 0) 1558117395Skan { 1559117395Skan do_divide (&u, &u, ptentwo); 1560117395Skan do_multiply (&pten, &pten, ptentwo); 1561117395Skan dec_exp += 1 << m; 1562117395Skan } 1563117395Skan } 1564117395Skan while (--m >= 0); 156518334Speter } 156618334Speter else 1567117395Skan /* We managed to divide off enough tens in the above reduction 1568117395Skan loop that we've now got a negative exponent. Fall into the 1569117395Skan less-than-one code to compute the proper value for PTEN. */ 1570117395Skan cmp_one = -1; 157118334Speter } 1572117395Skan if (cmp_one < 0) 1573117395Skan { 1574117395Skan int m; 157518334Speter 1576117395Skan /* Number is less than one. Pad significand with leading 1577117395Skan decimal zeros. */ 157818334Speter 1579117395Skan v = r; 1580117395Skan while (1) 1581117395Skan { 1582117395Skan /* Stop if we'd shift bits off the bottom. */ 1583117395Skan if (v.sig[0] & 7) 1584117395Skan break; 158518334Speter 1586117395Skan do_multiply (&u, &v, ten); 158718334Speter 1588117395Skan /* Stop if we're now >= 1. */ 1589169689Skan if (REAL_EXP (&u) > 0) 1590117395Skan break; 159118334Speter 1592117395Skan v = u; 1593117395Skan dec_exp -= 1; 1594117395Skan } 1595117395Skan r = v; 159652284Sobrien 1597117395Skan /* Find power of 10. Do this by multiplying in P=10**2**M when 1598117395Skan the current remainder is smaller than 1/P. Fill PTEN with the 1599117395Skan power of 10 that we compute. */ 1600169689Skan m = floor_log2 ((int)(-REAL_EXP (&r) * M_LOG10_2)) + 1; 1601117395Skan do 1602117395Skan { 1603117395Skan const REAL_VALUE_TYPE *ptentwo = ten_to_ptwo (m); 1604117395Skan const REAL_VALUE_TYPE *ptenmtwo = ten_to_mptwo (m); 160552284Sobrien 1606117395Skan if (do_compare (&v, ptenmtwo, 0) <= 0) 1607117395Skan { 1608117395Skan do_multiply (&v, &v, ptentwo); 1609117395Skan do_multiply (&pten, &pten, ptentwo); 1610117395Skan dec_exp -= 1 << m; 1611117395Skan } 1612117395Skan } 1613117395Skan while (--m >= 0); 161452284Sobrien 1615117395Skan /* Invert the positive power of 10 that we've collected so far. */ 1616117395Skan do_divide (&pten, one, &pten); 1617117395Skan } 161818334Speter 1619117395Skan p = str; 1620117395Skan if (sign) 1621117395Skan *p++ = '-'; 1622117395Skan first = p++; 162318334Speter 1624117395Skan /* At this point, PTEN should contain the nearest power of 10 smaller 1625117395Skan than R, such that this division produces the first digit. 162618334Speter 1627117395Skan Using a divide-step primitive that returns the complete integral 1628117395Skan remainder avoids the rounding error that would be produced if 1629117395Skan we were to use do_divide here and then simply multiply by 10 for 1630117395Skan each subsequent digit. */ 163118334Speter 1632117395Skan digit = rtd_divmod (&r, &pten); 163318334Speter 1634117395Skan /* Be prepared for error in that division via underflow ... */ 1635117395Skan if (digit == 0 && cmp_significand_0 (&r)) 163618334Speter { 1637117395Skan /* Multiply by 10 and try again. */ 1638117395Skan do_multiply (&r, &r, ten); 1639117395Skan digit = rtd_divmod (&r, &pten); 1640117395Skan dec_exp -= 1; 1641169689Skan gcc_assert (digit != 0); 164218334Speter } 1643117395Skan 1644117395Skan /* ... or overflow. */ 1645117395Skan if (digit == 10) 164618334Speter { 1647117395Skan *p++ = '1'; 1648117395Skan if (--digits > 0) 1649117395Skan *p++ = '0'; 1650117395Skan dec_exp += 1; 165118334Speter } 1652117395Skan else 1653169689Skan { 1654169689Skan gcc_assert (digit <= 10); 1655169689Skan *p++ = digit + '0'; 1656169689Skan } 1657117395Skan 1658117395Skan /* Generate subsequent digits. */ 1659117395Skan while (--digits > 0) 166018334Speter { 1661117395Skan do_multiply (&r, &r, ten); 1662117395Skan digit = rtd_divmod (&r, &pten); 1663117395Skan *p++ = digit + '0'; 166418334Speter } 1665117395Skan last = p; 166650397Sobrien 1667117395Skan /* Generate one more digit with which to do rounding. */ 1668117395Skan do_multiply (&r, &r, ten); 1669117395Skan digit = rtd_divmod (&r, &pten); 167050397Sobrien 1671117395Skan /* Round the result. */ 1672117395Skan if (digit == 5) 167318334Speter { 1674117395Skan /* Round to nearest. If R is nonzero there are additional 1675117395Skan nonzero digits to be extracted. */ 1676117395Skan if (cmp_significand_0 (&r)) 1677117395Skan digit++; 1678117395Skan /* Round to even. */ 1679117395Skan else if ((p[-1] - '0') & 1) 1680117395Skan digit++; 168118334Speter } 1682117395Skan if (digit > 5) 168318334Speter { 1684117395Skan while (p > first) 168518334Speter { 1686117395Skan digit = *--p; 1687117395Skan if (digit == '9') 1688117395Skan *p = '0'; 168918334Speter else 169018334Speter { 1691117395Skan *p = digit + 1; 1692117395Skan break; 169318334Speter } 169418334Speter } 1695117395Skan 1696117395Skan /* Carry out of the first digit. This means we had all 9's and 1697117395Skan now have all 0's. "Prepend" a 1 by overwriting the first 0. */ 1698117395Skan if (p == first) 169918334Speter { 1700117395Skan first[1] = '1'; 1701117395Skan dec_exp++; 170218334Speter } 170318334Speter } 1704132718Skan 1705117395Skan /* Insert the decimal point. */ 1706117395Skan first[0] = first[1]; 1707117395Skan first[1] = '.'; 1708117395Skan 1709117395Skan /* If requested, drop trailing zeros. Never crop past "1.0". */ 1710117395Skan if (crop_trailing_zeros) 1711117395Skan while (last > first + 3 && last[-1] == '0') 1712117395Skan last--; 1713117395Skan 1714117395Skan /* Append the exponent. */ 1715117395Skan sprintf (last, "e%+d", dec_exp); 171618334Speter} 171718334Speter 1718117395Skan/* Render R as a hexadecimal floating point constant. Emit DIGITS 1719117395Skan significant digits in the result, bounded by BUF_SIZE. If DIGITS is 0, 1720117395Skan choose the maximum for the representation. If CROP_TRAILING_ZEROS, 1721117395Skan strip trailing zeros. */ 172218334Speter 1723117395Skanvoid 1724132718Skanreal_to_hexadecimal (char *str, const REAL_VALUE_TYPE *r, size_t buf_size, 1725132718Skan size_t digits, int crop_trailing_zeros) 172618334Speter{ 1727169689Skan int i, j, exp = REAL_EXP (r); 1728117395Skan char *p, *first; 1729117395Skan char exp_buf[16]; 1730117395Skan size_t max_digits; 173118334Speter 1732169689Skan switch (r->cl) 173318334Speter { 1734117395Skan case rvc_zero: 1735117395Skan exp = 0; 1736117395Skan break; 1737117395Skan case rvc_normal: 1738117395Skan break; 1739117395Skan case rvc_inf: 1740117395Skan strcpy (str, (r->sign ? "-Inf" : "+Inf")); 174118334Speter return; 1742117395Skan case rvc_nan: 1743117395Skan /* ??? Print the significand as well, if not canonical? */ 1744117395Skan strcpy (str, (r->sign ? "-NaN" : "+NaN")); 174518334Speter return; 1746117395Skan default: 1747169689Skan gcc_unreachable (); 174818334Speter } 174918334Speter 1750169689Skan if (r->decimal) 1751169689Skan { 1752169689Skan /* Hexadecimal format for decimal floats is not interesting. */ 1753169689Skan strcpy (str, "N/A"); 1754169689Skan return; 1755169689Skan } 1756169689Skan 1757117395Skan if (digits == 0) 1758117395Skan digits = SIGNIFICAND_BITS / 4; 175918334Speter 1760117395Skan /* Bound the number of digits printed by the size of the output buffer. */ 176118334Speter 1762117395Skan sprintf (exp_buf, "p%+d", exp); 1763117395Skan max_digits = buf_size - strlen (exp_buf) - r->sign - 4 - 1; 1764169689Skan gcc_assert (max_digits <= buf_size); 1765117395Skan if (digits > max_digits) 1766117395Skan digits = max_digits; 1767117395Skan 1768117395Skan p = str; 1769117395Skan if (r->sign) 1770117395Skan *p++ = '-'; 1771117395Skan *p++ = '0'; 1772117395Skan *p++ = 'x'; 1773117395Skan *p++ = '0'; 1774117395Skan *p++ = '.'; 1775117395Skan first = p; 1776117395Skan 1777117395Skan for (i = SIGSZ - 1; i >= 0; --i) 1778117395Skan for (j = HOST_BITS_PER_LONG - 4; j >= 0; j -= 4) 1779117395Skan { 1780117395Skan *p++ = "0123456789abcdef"[(r->sig[i] >> j) & 15]; 1781117395Skan if (--digits == 0) 1782117395Skan goto out; 1783117395Skan } 1784117395Skan 1785117395Skan out: 1786117395Skan if (crop_trailing_zeros) 1787117395Skan while (p > first + 1 && p[-1] == '0') 1788117395Skan p--; 1789117395Skan 1790117395Skan sprintf (p, "p%+d", exp); 179118334Speter} 179218334Speter 1793117395Skan/* Initialize R from a decimal or hexadecimal string. The string is 1794117395Skan assumed to have been syntax checked already. */ 179518334Speter 1796117395Skanvoid 1797132718Skanreal_from_string (REAL_VALUE_TYPE *r, const char *str) 179818334Speter{ 1799117395Skan int exp = 0; 1800117395Skan bool sign = false; 180118334Speter 1802117395Skan get_zero (r, 0); 1803117395Skan 1804117395Skan if (*str == '-') 180518334Speter { 1806117395Skan sign = true; 1807117395Skan str++; 180818334Speter } 1809117395Skan else if (*str == '+') 1810117395Skan str++; 1811117395Skan 1812132718Skan if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) 181318334Speter { 1814117395Skan /* Hexadecimal floating point. */ 1815117395Skan int pos = SIGNIFICAND_BITS - 4, d; 181618334Speter 1817117395Skan str += 2; 1818117395Skan 1819117395Skan while (*str == '0') 1820117395Skan str++; 1821117395Skan while (1) 1822117395Skan { 1823117395Skan d = hex_value (*str); 1824117395Skan if (d == _hex_bad) 1825117395Skan break; 1826117395Skan if (pos >= 0) 182718334Speter { 1828117395Skan r->sig[pos / HOST_BITS_PER_LONG] 1829117395Skan |= (unsigned long) d << (pos % HOST_BITS_PER_LONG); 1830117395Skan pos -= 4; 183118334Speter } 1832169689Skan else if (d) 1833169689Skan /* Ensure correct rounding by setting last bit if there is 1834169689Skan a subsequent nonzero digit. */ 1835169689Skan r->sig[0] |= 1; 1836117395Skan exp += 4; 1837117395Skan str++; 1838117395Skan } 1839117395Skan if (*str == '.') 1840117395Skan { 1841117395Skan str++; 1842117395Skan if (pos == SIGNIFICAND_BITS - 4) 184318334Speter { 1844117395Skan while (*str == '0') 1845117395Skan str++, exp -= 4; 184618334Speter } 1847117395Skan while (1) 184818334Speter { 1849117395Skan d = hex_value (*str); 1850117395Skan if (d == _hex_bad) 1851117395Skan break; 1852117395Skan if (pos >= 0) 185318334Speter { 1854117395Skan r->sig[pos / HOST_BITS_PER_LONG] 1855117395Skan |= (unsigned long) d << (pos % HOST_BITS_PER_LONG); 1856117395Skan pos -= 4; 185718334Speter } 1858169689Skan else if (d) 1859169689Skan /* Ensure correct rounding by setting last bit if there is 1860169689Skan a subsequent nonzero digit. */ 1861169689Skan r->sig[0] |= 1; 1862117395Skan str++; 186318334Speter } 186418334Speter } 1865169689Skan 1866169689Skan /* If the mantissa is zero, ignore the exponent. */ 1867169689Skan if (!cmp_significand_0 (r)) 1868169689Skan goto underflow; 1869169689Skan 1870117395Skan if (*str == 'p' || *str == 'P') 1871117395Skan { 1872117395Skan bool exp_neg = false; 187318334Speter 1874117395Skan str++; 1875117395Skan if (*str == '-') 1876117395Skan { 1877117395Skan exp_neg = true; 1878117395Skan str++; 1879117395Skan } 1880117395Skan else if (*str == '+') 1881117395Skan str++; 188218334Speter 1883117395Skan d = 0; 1884117395Skan while (ISDIGIT (*str)) 1885117395Skan { 1886117395Skan d *= 10; 1887117395Skan d += *str - '0'; 1888117395Skan if (d > MAX_EXP) 1889117395Skan { 1890117395Skan /* Overflowed the exponent. */ 1891117395Skan if (exp_neg) 1892117395Skan goto underflow; 1893117395Skan else 1894117395Skan goto overflow; 1895117395Skan } 1896117395Skan str++; 1897117395Skan } 1898117395Skan if (exp_neg) 1899117395Skan d = -d; 190018334Speter 1901117395Skan exp += d; 1902117395Skan } 190318334Speter 1904169689Skan r->cl = rvc_normal; 1905169689Skan SET_REAL_EXP (r, exp); 190618334Speter 1907117395Skan normalize (r); 190818334Speter } 1909117395Skan else 191018334Speter { 1911117395Skan /* Decimal floating point. */ 1912117395Skan const REAL_VALUE_TYPE *ten = ten_to_ptwo (0); 1913117395Skan int d; 1914117395Skan 1915117395Skan while (*str == '0') 1916117395Skan str++; 1917117395Skan while (ISDIGIT (*str)) 191818334Speter { 1919117395Skan d = *str++ - '0'; 1920117395Skan do_multiply (r, r, ten); 1921117395Skan if (d) 1922117395Skan do_add (r, r, real_digit (d), 0); 192318334Speter } 1924117395Skan if (*str == '.') 192518334Speter { 1926117395Skan str++; 1927169689Skan if (r->cl == rvc_zero) 192818334Speter { 1929117395Skan while (*str == '0') 1930117395Skan str++, exp--; 193118334Speter } 1932117395Skan while (ISDIGIT (*str)) 1933117395Skan { 1934117395Skan d = *str++ - '0'; 1935117395Skan do_multiply (r, r, ten); 1936117395Skan if (d) 1937117395Skan do_add (r, r, real_digit (d), 0); 1938117395Skan exp--; 1939117395Skan } 194018334Speter } 194118334Speter 1942169689Skan /* If the mantissa is zero, ignore the exponent. */ 1943169689Skan if (r->cl == rvc_zero) 1944169689Skan goto underflow; 1945169689Skan 1946117395Skan if (*str == 'e' || *str == 'E') 1947117395Skan { 1948117395Skan bool exp_neg = false; 194918334Speter 1950117395Skan str++; 1951117395Skan if (*str == '-') 195218334Speter { 1953117395Skan exp_neg = true; 1954117395Skan str++; 195518334Speter } 1956117395Skan else if (*str == '+') 1957117395Skan str++; 195818334Speter 1959117395Skan d = 0; 1960117395Skan while (ISDIGIT (*str)) 196118334Speter { 1962117395Skan d *= 10; 1963117395Skan d += *str - '0'; 1964117395Skan if (d > MAX_EXP) 1965117395Skan { 1966117395Skan /* Overflowed the exponent. */ 1967117395Skan if (exp_neg) 1968117395Skan goto underflow; 1969117395Skan else 1970117395Skan goto overflow; 1971117395Skan } 1972117395Skan str++; 197318334Speter } 1974117395Skan if (exp_neg) 1975117395Skan d = -d; 1976117395Skan exp += d; 197718334Speter } 1978117395Skan 1979117395Skan if (exp) 1980117395Skan times_pten (r, exp); 198118334Speter } 198218334Speter 1983117395Skan r->sign = sign; 1984117395Skan return; 198518334Speter 1986117395Skan underflow: 1987117395Skan get_zero (r, sign); 1988117395Skan return; 198918334Speter 1990117395Skan overflow: 1991117395Skan get_inf (r, sign); 1992117395Skan return; 199318334Speter} 199418334Speter 1995117395Skan/* Legacy. Similar, but return the result directly. */ 199618334Speter 1997117395SkanREAL_VALUE_TYPE 1998132718Skanreal_from_string2 (const char *s, enum machine_mode mode) 199918334Speter{ 2000117395Skan REAL_VALUE_TYPE r; 200118334Speter 2002117395Skan real_from_string (&r, s); 2003117395Skan if (mode != VOIDmode) 2004117395Skan real_convert (&r, mode, &r); 200518334Speter 2006117395Skan return r; 200718334Speter} 200818334Speter 2009169689Skan/* Initialize R from string S and desired MODE. */ 2010169689Skan 2011169689Skanvoid 2012169689Skanreal_from_string3 (REAL_VALUE_TYPE *r, const char *s, enum machine_mode mode) 2013169689Skan{ 2014169689Skan if (DECIMAL_FLOAT_MODE_P (mode)) 2015169689Skan decimal_real_from_string (r, s); 2016169689Skan else 2017169689Skan real_from_string (r, s); 2018169689Skan 2019169689Skan if (mode != VOIDmode) 2020169689Skan real_convert (r, mode, r); 2021169689Skan} 2022169689Skan 2023117395Skan/* Initialize R from the integer pair HIGH+LOW. */ 202418334Speter 2025117395Skanvoid 2026132718Skanreal_from_integer (REAL_VALUE_TYPE *r, enum machine_mode mode, 2027132718Skan unsigned HOST_WIDE_INT low, HOST_WIDE_INT high, 2028132718Skan int unsigned_p) 202918334Speter{ 2030117395Skan if (low == 0 && high == 0) 2031117395Skan get_zero (r, 0); 2032117395Skan else 203318334Speter { 2034146895Skan memset (r, 0, sizeof (*r)); 2035169689Skan r->cl = rvc_normal; 2036117395Skan r->sign = high < 0 && !unsigned_p; 2037169689Skan SET_REAL_EXP (r, 2 * HOST_BITS_PER_WIDE_INT); 203818334Speter 2039117395Skan if (r->sign) 204018334Speter { 2041117395Skan high = ~high; 2042117395Skan if (low == 0) 2043117395Skan high += 1; 2044117395Skan else 2045117395Skan low = -low; 2046117395Skan } 204718334Speter 2048117395Skan if (HOST_BITS_PER_LONG == HOST_BITS_PER_WIDE_INT) 2049117395Skan { 2050117395Skan r->sig[SIGSZ-1] = high; 2051117395Skan r->sig[SIGSZ-2] = low; 205218334Speter } 2053169689Skan else 205418334Speter { 2055169689Skan gcc_assert (HOST_BITS_PER_LONG*2 == HOST_BITS_PER_WIDE_INT); 2056117395Skan r->sig[SIGSZ-1] = high >> (HOST_BITS_PER_LONG - 1) >> 1; 2057117395Skan r->sig[SIGSZ-2] = high; 2058117395Skan r->sig[SIGSZ-3] = low >> (HOST_BITS_PER_LONG - 1) >> 1; 2059117395Skan r->sig[SIGSZ-4] = low; 206018334Speter } 206150397Sobrien 2062117395Skan normalize (r); 206318334Speter } 2064117395Skan 2065117395Skan if (mode != VOIDmode) 2066117395Skan real_convert (r, mode, r); 206718334Speter} 206818334Speter 2069117395Skan/* Returns 10**2**N. */ 207018334Speter 2071117395Skanstatic const REAL_VALUE_TYPE * 2072132718Skanten_to_ptwo (int n) 207318334Speter{ 2074117395Skan static REAL_VALUE_TYPE tens[EXP_BITS]; 207518334Speter 2076169689Skan gcc_assert (n >= 0); 2077169689Skan gcc_assert (n < EXP_BITS); 2078117395Skan 2079169689Skan if (tens[n].cl == rvc_zero) 208018334Speter { 2081117395Skan if (n < (HOST_BITS_PER_WIDE_INT == 64 ? 5 : 4)) 208218334Speter { 2083117395Skan HOST_WIDE_INT t = 10; 2084117395Skan int i; 2085117395Skan 2086117395Skan for (i = 0; i < n; ++i) 2087117395Skan t *= t; 2088117395Skan 2089117395Skan real_from_integer (&tens[n], VOIDmode, t, 0, 1); 209018334Speter } 209118334Speter else 209218334Speter { 2093117395Skan const REAL_VALUE_TYPE *t = ten_to_ptwo (n - 1); 2094117395Skan do_multiply (&tens[n], t, t); 209518334Speter } 209618334Speter } 2097117395Skan 2098117395Skan return &tens[n]; 209918334Speter} 210018334Speter 2101117395Skan/* Returns 10**(-2**N). */ 210218334Speter 2103117395Skanstatic const REAL_VALUE_TYPE * 2104132718Skanten_to_mptwo (int n) 210518334Speter{ 2106117395Skan static REAL_VALUE_TYPE tens[EXP_BITS]; 210718334Speter 2108169689Skan gcc_assert (n >= 0); 2109169689Skan gcc_assert (n < EXP_BITS); 211018334Speter 2111169689Skan if (tens[n].cl == rvc_zero) 2112117395Skan do_divide (&tens[n], real_digit (1), ten_to_ptwo (n)); 211350397Sobrien 2114117395Skan return &tens[n]; 2115117395Skan} 211650397Sobrien 2117117395Skan/* Returns N. */ 211850397Sobrien 2119117395Skanstatic const REAL_VALUE_TYPE * 2120132718Skanreal_digit (int n) 2121117395Skan{ 2122117395Skan static REAL_VALUE_TYPE num[10]; 212350397Sobrien 2124169689Skan gcc_assert (n >= 0); 2125169689Skan gcc_assert (n <= 9); 212618334Speter 2127169689Skan if (n > 0 && num[n].cl == rvc_zero) 2128117395Skan real_from_integer (&num[n], VOIDmode, n, 0, 1); 212918334Speter 2130117395Skan return &num[n]; 213118334Speter} 213218334Speter 2133117395Skan/* Multiply R by 10**EXP. */ 213418334Speter 213552284Sobrienstatic void 2136132718Skantimes_pten (REAL_VALUE_TYPE *r, int exp) 213718334Speter{ 2138117395Skan REAL_VALUE_TYPE pten, *rr; 2139117395Skan bool negative = (exp < 0); 2140117395Skan int i; 214118334Speter 2142117395Skan if (negative) 214318334Speter { 2144117395Skan exp = -exp; 2145117395Skan pten = *real_digit (1); 2146117395Skan rr = &pten; 214718334Speter } 214818334Speter else 2149117395Skan rr = r; 215018334Speter 2151117395Skan for (i = 0; exp > 0; ++i, exp >>= 1) 2152117395Skan if (exp & 1) 2153117395Skan do_multiply (rr, rr, ten_to_ptwo (i)); 2154117395Skan 2155117395Skan if (negative) 2156117395Skan do_divide (r, r, &pten); 215718334Speter} 215818334Speter 2159117395Skan/* Fills R with +Inf. */ 216018334Speter 2161117395Skanvoid 2162132718Skanreal_inf (REAL_VALUE_TYPE *r) 216318334Speter{ 2164117395Skan get_inf (r, 0); 216518334Speter} 216618334Speter 2167117395Skan/* Fills R with a NaN whose significand is described by STR. If QUIET, 2168117395Skan we force a QNaN, else we force an SNaN. The string, if not empty, 2169117395Skan is parsed as a number and placed in the significand. Return true 2170117395Skan if the string was successfully parsed. */ 217118334Speter 2172117395Skanbool 2173132718Skanreal_nan (REAL_VALUE_TYPE *r, const char *str, int quiet, 2174132718Skan enum machine_mode mode) 217518334Speter{ 2176117395Skan const struct real_format *fmt; 217718334Speter 2178132718Skan fmt = REAL_MODE_FORMAT (mode); 2179169689Skan gcc_assert (fmt); 218018334Speter 2181117395Skan if (*str == 0) 218218334Speter { 2183117395Skan if (quiet) 2184117395Skan get_canonical_qnan (r, 0); 218518334Speter else 2186117395Skan get_canonical_snan (r, 0); 218718334Speter } 218818334Speter else 218918334Speter { 2190117395Skan int base = 10, d; 2191117395Skan 2192117395Skan memset (r, 0, sizeof (*r)); 2193169689Skan r->cl = rvc_nan; 2194117395Skan 2195117395Skan /* Parse akin to strtol into the significand of R. */ 2196117395Skan 2197117395Skan while (ISSPACE (*str)) 2198117395Skan str++; 2199117395Skan if (*str == '-') 2200169689Skan str++; 2201117395Skan else if (*str == '+') 2202117395Skan str++; 2203117395Skan if (*str == '0') 220418334Speter { 2205169689Skan str++; 2206169689Skan if (*str == 'x' || *str == 'X') 2207169689Skan { 2208169689Skan base = 16; 2209169689Skan str++; 2210169689Skan } 2211117395Skan else 2212117395Skan base = 8; 221318334Speter } 221418334Speter 2215117395Skan while ((d = hex_value (*str)) < base) 2216117395Skan { 2217117395Skan REAL_VALUE_TYPE u; 221818334Speter 2219117395Skan switch (base) 2220117395Skan { 2221117395Skan case 8: 2222117395Skan lshift_significand (r, r, 3); 2223117395Skan break; 2224117395Skan case 16: 2225117395Skan lshift_significand (r, r, 4); 2226117395Skan break; 2227117395Skan case 10: 2228117395Skan lshift_significand_1 (&u, r); 2229117395Skan lshift_significand (r, r, 3); 2230117395Skan add_significands (r, r, &u); 2231117395Skan break; 2232117395Skan default: 2233169689Skan gcc_unreachable (); 2234117395Skan } 223518334Speter 2236117395Skan get_zero (&u, 0); 2237117395Skan u.sig[0] = d; 2238117395Skan add_significands (r, r, &u); 223918334Speter 2240117395Skan str++; 2241117395Skan } 224218334Speter 2243117395Skan /* Must have consumed the entire string for success. */ 2244117395Skan if (*str != 0) 2245117395Skan return false; 224618334Speter 2247117395Skan /* Shift the significand into place such that the bits 2248117395Skan are in the most significant bits for the format. */ 2249132718Skan lshift_significand (r, r, SIGNIFICAND_BITS - fmt->pnan); 225018334Speter 2251117395Skan /* Our MSB is always unset for NaNs. */ 2252117395Skan r->sig[SIGSZ-1] &= ~SIG_MSB; 225318334Speter 2254117395Skan /* Force quiet or signalling NaN. */ 2255132718Skan r->signalling = !quiet; 2256117395Skan } 225718334Speter 2258117395Skan return true; 225950397Sobrien} 226050397Sobrien 2261132718Skan/* Fills R with the largest finite value representable in mode MODE. 2262132718Skan If SIGN is nonzero, R is set to the most negative finite value. */ 2263132718Skan 2264132718Skanvoid 2265132718Skanreal_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode) 2266132718Skan{ 2267132718Skan const struct real_format *fmt; 2268132718Skan int np2; 2269132718Skan 2270132718Skan fmt = REAL_MODE_FORMAT (mode); 2271169689Skan gcc_assert (fmt); 2272169689Skan memset (r, 0, sizeof (*r)); 2273169689Skan 2274169689Skan if (fmt->b == 10) 2275169689Skan decimal_real_maxval (r, sign, mode); 2276169689Skan else 2277169689Skan { 2278169689Skan r->cl = rvc_normal; 2279169689Skan r->sign = sign; 2280169689Skan SET_REAL_EXP (r, fmt->emax * fmt->log2_b); 2281132718Skan 2282169689Skan np2 = SIGNIFICAND_BITS - fmt->p * fmt->log2_b; 2283169689Skan memset (r->sig, -1, SIGSZ * sizeof (unsigned long)); 2284169689Skan clear_significand_below (r, np2); 2285132718Skan 2286169689Skan if (fmt->pnan < fmt->p) 2287169689Skan /* This is an IBM extended double format made up of two IEEE 2288169689Skan doubles. The value of the long double is the sum of the 2289169689Skan values of the two parts. The most significant part is 2290169689Skan required to be the value of the long double rounded to the 2291169689Skan nearest double. Rounding means we need a slightly smaller 2292169689Skan value for LDBL_MAX. */ 2293169689Skan clear_significand_bit (r, SIGNIFICAND_BITS - fmt->pnan); 2294169689Skan } 2295132718Skan} 2296132718Skan 2297117395Skan/* Fills R with 2**N. */ 229850397Sobrien 2299117395Skanvoid 2300132718Skanreal_2expN (REAL_VALUE_TYPE *r, int n) 230150397Sobrien{ 2302117395Skan memset (r, 0, sizeof (*r)); 2303117395Skan 2304117395Skan n++; 2305117395Skan if (n > MAX_EXP) 2306169689Skan r->cl = rvc_inf; 2307117395Skan else if (n < -MAX_EXP) 2308117395Skan ; 2309117395Skan else 2310117395Skan { 2311169689Skan r->cl = rvc_normal; 2312169689Skan SET_REAL_EXP (r, n); 2313117395Skan r->sig[SIGSZ-1] = SIG_MSB; 2314117395Skan } 231550397Sobrien} 231650397Sobrien 2317117395Skan 231852284Sobrienstatic void 2319132718Skanround_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r) 232018334Speter{ 2321117395Skan int p2, np2, i, w; 2322117395Skan unsigned long sticky; 2323117395Skan bool guard, lsb; 2324117395Skan int emin2m1, emax2; 232518334Speter 2326169689Skan if (r->decimal) 2327169689Skan { 2328169689Skan if (fmt->b == 10) 2329169689Skan { 2330169689Skan decimal_round_for_format (fmt, r); 2331169689Skan return; 2332169689Skan } 2333169689Skan /* FIXME. We can come here via fp_easy_constant 2334169689Skan (e.g. -O0 on '_Decimal32 x = 1.0 + 2.0dd'), but have not 2335169689Skan investigated whether this convert needs to be here, or 2336169689Skan something else is missing. */ 2337169689Skan decimal_real_convert (r, DFmode, r); 2338169689Skan } 2339169689Skan 2340117395Skan p2 = fmt->p * fmt->log2_b; 2341117395Skan emin2m1 = (fmt->emin - 1) * fmt->log2_b; 2342117395Skan emax2 = fmt->emax * fmt->log2_b; 2343117395Skan 2344117395Skan np2 = SIGNIFICAND_BITS - p2; 2345169689Skan switch (r->cl) 234618334Speter { 2347117395Skan underflow: 2348117395Skan get_zero (r, r->sign); 2349117395Skan case rvc_zero: 2350117395Skan if (!fmt->has_signed_zero) 2351117395Skan r->sign = 0; 235218334Speter return; 235318334Speter 2354117395Skan overflow: 2355117395Skan get_inf (r, r->sign); 2356117395Skan case rvc_inf: 2357117395Skan return; 235818334Speter 2359117395Skan case rvc_nan: 2360117395Skan clear_significand_below (r, np2); 236118334Speter return; 2362117395Skan 2363117395Skan case rvc_normal: 2364117395Skan break; 2365117395Skan 2366117395Skan default: 2367169689Skan gcc_unreachable (); 236818334Speter } 236918334Speter 2370117395Skan /* If we're not base2, normalize the exponent to a multiple of 2371117395Skan the true base. */ 2372117395Skan if (fmt->log2_b != 1) 237350397Sobrien { 2374169689Skan int shift; 2375169689Skan 2376169689Skan gcc_assert (fmt->b != 10); 2377169689Skan shift = REAL_EXP (r) & (fmt->log2_b - 1); 2378117395Skan if (shift) 237918334Speter { 2380117395Skan shift = fmt->log2_b - shift; 2381117395Skan r->sig[0] |= sticky_rshift_significand (r, r, shift); 2382169689Skan SET_REAL_EXP (r, REAL_EXP (r) + shift); 238318334Speter } 2384117395Skan } 2385117395Skan 2386117395Skan /* Check the range of the exponent. If we're out of range, 2387117395Skan either underflow or overflow. */ 2388169689Skan if (REAL_EXP (r) > emax2) 2389117395Skan goto overflow; 2390169689Skan else if (REAL_EXP (r) <= emin2m1) 2391117395Skan { 2392117395Skan int diff; 2393117395Skan 2394117395Skan if (!fmt->has_denorm) 239518334Speter { 2396117395Skan /* Don't underflow completely until we've had a chance to round. */ 2397169689Skan if (REAL_EXP (r) < emin2m1) 2398117395Skan goto underflow; 239918334Speter } 240018334Speter else 240118334Speter { 2402169689Skan diff = emin2m1 - REAL_EXP (r) + 1; 2403117395Skan if (diff > p2) 2404117395Skan goto underflow; 2405117395Skan 2406117395Skan /* De-normalize the significand. */ 2407117395Skan r->sig[0] |= sticky_rshift_significand (r, r, diff); 2408169689Skan SET_REAL_EXP (r, REAL_EXP (r) + diff); 240918334Speter } 241018334Speter } 2411117395Skan 2412117395Skan /* There are P2 true significand bits, followed by one guard bit, 2413117395Skan followed by one sticky bit, followed by stuff. Fold nonzero 2414117395Skan stuff into the sticky bit. */ 2415117395Skan 2416117395Skan sticky = 0; 2417117395Skan for (i = 0, w = (np2 - 1) / HOST_BITS_PER_LONG; i < w; ++i) 2418117395Skan sticky |= r->sig[i]; 2419117395Skan sticky |= 2420117395Skan r->sig[w] & (((unsigned long)1 << ((np2 - 1) % HOST_BITS_PER_LONG)) - 1); 2421117395Skan 2422117395Skan guard = test_significand_bit (r, np2 - 1); 2423117395Skan lsb = test_significand_bit (r, np2); 2424117395Skan 2425117395Skan /* Round to even. */ 2426117395Skan if (guard && (sticky || lsb)) 242718334Speter { 2428117395Skan REAL_VALUE_TYPE u; 2429117395Skan get_zero (&u, 0); 2430117395Skan set_significand_bit (&u, np2); 243118334Speter 2432117395Skan if (add_significands (r, r, &u)) 2433117395Skan { 2434117395Skan /* Overflow. Means the significand had been all ones, and 2435117395Skan is now all zeros. Need to increase the exponent, and 2436117395Skan possibly re-normalize it. */ 2437169689Skan SET_REAL_EXP (r, REAL_EXP (r) + 1); 2438169689Skan if (REAL_EXP (r) > emax2) 2439117395Skan goto overflow; 2440117395Skan r->sig[SIGSZ-1] = SIG_MSB; 244118334Speter 2442117395Skan if (fmt->log2_b != 1) 2443117395Skan { 2444169689Skan int shift = REAL_EXP (r) & (fmt->log2_b - 1); 2445117395Skan if (shift) 2446117395Skan { 2447117395Skan shift = fmt->log2_b - shift; 2448117395Skan rshift_significand (r, r, shift); 2449169689Skan SET_REAL_EXP (r, REAL_EXP (r) + shift); 2450169689Skan if (REAL_EXP (r) > emax2) 2451117395Skan goto overflow; 2452117395Skan } 2453117395Skan } 2454117395Skan } 2455117395Skan } 245618334Speter 2457117395Skan /* Catch underflow that we deferred until after rounding. */ 2458169689Skan if (REAL_EXP (r) <= emin2m1) 2459117395Skan goto underflow; 246018334Speter 2461117395Skan /* Clear out trailing garbage. */ 2462117395Skan clear_significand_below (r, np2); 2463117395Skan} 246418334Speter 2465117395Skan/* Extend or truncate to a new mode. */ 246618334Speter 2467117395Skanvoid 2468132718Skanreal_convert (REAL_VALUE_TYPE *r, enum machine_mode mode, 2469132718Skan const REAL_VALUE_TYPE *a) 247018334Speter{ 2471117395Skan const struct real_format *fmt; 247218334Speter 2473132718Skan fmt = REAL_MODE_FORMAT (mode); 2474169689Skan gcc_assert (fmt); 247518334Speter 2476117395Skan *r = *a; 2477169689Skan 2478169689Skan if (a->decimal || fmt->b == 10) 2479169689Skan decimal_real_convert (r, mode, a); 2480169689Skan 2481117395Skan round_for_format (fmt, r); 2482117395Skan 2483117395Skan /* round_for_format de-normalizes denormals. Undo just that part. */ 2484169689Skan if (r->cl == rvc_normal) 2485117395Skan normalize (r); 248618334Speter} 248718334Speter 2488117395Skan/* Legacy. Likewise, except return the struct directly. */ 248950397Sobrien 2490117395SkanREAL_VALUE_TYPE 2491132718Skanreal_value_truncate (enum machine_mode mode, REAL_VALUE_TYPE a) 249250397Sobrien{ 2493117395Skan REAL_VALUE_TYPE r; 2494117395Skan real_convert (&r, mode, &a); 2495117395Skan return r; 249650397Sobrien} 249750397Sobrien 2498117395Skan/* Return true if truncating to MODE is exact. */ 249950397Sobrien 2500117395Skanbool 2501132718Skanexact_real_truncate (enum machine_mode mode, const REAL_VALUE_TYPE *a) 250250397Sobrien{ 2503169689Skan const struct real_format *fmt; 2504117395Skan REAL_VALUE_TYPE t; 2505169689Skan int emin2m1; 2506169689Skan 2507169689Skan fmt = REAL_MODE_FORMAT (mode); 2508169689Skan gcc_assert (fmt); 2509169689Skan 2510169689Skan /* Don't allow conversion to denormals. */ 2511169689Skan emin2m1 = (fmt->emin - 1) * fmt->log2_b; 2512169689Skan if (REAL_EXP (a) <= emin2m1) 2513169689Skan return false; 2514169689Skan 2515169689Skan /* After conversion to the new mode, the value must be identical. */ 2516117395Skan real_convert (&t, mode, a); 2517117395Skan return real_identical (&t, a); 251850397Sobrien} 251950397Sobrien 2520117395Skan/* Write R to the given target format. Place the words of the result 2521117395Skan in target word order in BUF. There are always 32 bits in each 2522117395Skan long, no matter the size of the host long. 252350397Sobrien 2524117395Skan Legacy: return word 0 for implementing REAL_VALUE_TO_TARGET_SINGLE. */ 252518334Speter 2526117395Skanlong 2527132718Skanreal_to_target_fmt (long *buf, const REAL_VALUE_TYPE *r_orig, 2528132718Skan const struct real_format *fmt) 252918334Speter{ 2530117395Skan REAL_VALUE_TYPE r; 2531117395Skan long buf1; 253218334Speter 2533117395Skan r = *r_orig; 2534117395Skan round_for_format (fmt, &r); 2535117395Skan 2536117395Skan if (!buf) 2537117395Skan buf = &buf1; 2538117395Skan (*fmt->encode) (fmt, buf, &r); 2539117395Skan 2540117395Skan return *buf; 254118334Speter} 254218334Speter 2543117395Skan/* Similar, but look up the format from MODE. */ 254418334Speter 2545117395Skanlong 2546132718Skanreal_to_target (long *buf, const REAL_VALUE_TYPE *r, enum machine_mode mode) 254718334Speter{ 2548117395Skan const struct real_format *fmt; 254918334Speter 2550132718Skan fmt = REAL_MODE_FORMAT (mode); 2551169689Skan gcc_assert (fmt); 255218334Speter 2553117395Skan return real_to_target_fmt (buf, r, fmt); 255418334Speter} 255518334Speter 2556117395Skan/* Read R from the given target format. Read the words of the result 2557117395Skan in target word order in BUF. There are always 32 bits in each 2558117395Skan long, no matter the size of the host long. */ 255918334Speter 2560117395Skanvoid 2561132718Skanreal_from_target_fmt (REAL_VALUE_TYPE *r, const long *buf, 2562132718Skan const struct real_format *fmt) 256318334Speter{ 2564117395Skan (*fmt->decode) (fmt, r, buf); 2565132718Skan} 256618334Speter 2567117395Skan/* Similar, but look up the format from MODE. */ 256818334Speter 2569117395Skanvoid 2570132718Skanreal_from_target (REAL_VALUE_TYPE *r, const long *buf, enum machine_mode mode) 2571117395Skan{ 2572117395Skan const struct real_format *fmt; 257318334Speter 2574132718Skan fmt = REAL_MODE_FORMAT (mode); 2575169689Skan gcc_assert (fmt); 257618334Speter 2577117395Skan (*fmt->decode) (fmt, r, buf); 2578132718Skan} 257918334Speter 2580169689Skan/* Return the number of bits of the largest binary value that the 2581169689Skan significand of MODE will hold. */ 2582117395Skan/* ??? Legacy. Should get access to real_format directly. */ 258318334Speter 2584117395Skanint 2585132718Skansignificand_size (enum machine_mode mode) 2586117395Skan{ 2587117395Skan const struct real_format *fmt; 258818334Speter 2589132718Skan fmt = REAL_MODE_FORMAT (mode); 2590117395Skan if (fmt == NULL) 2591117395Skan return 0; 2592117395Skan 2593169689Skan if (fmt->b == 10) 2594169689Skan { 2595169689Skan /* Return the size in bits of the largest binary value that can be 2596169689Skan held by the decimal coefficient for this mode. This is one more 2597169689Skan than the number of bits required to hold the largest coefficient 2598169689Skan of this mode. */ 2599169689Skan double log2_10 = 3.3219281; 2600169689Skan return fmt->p * log2_10; 2601169689Skan } 2602117395Skan return fmt->p * fmt->log2_b; 260318334Speter} 260418334Speter 2605117395Skan/* Return a hash value for the given real value. */ 2606117395Skan/* ??? The "unsigned int" return value is intended to be hashval_t, 2607117395Skan but I didn't want to pull hashtab.h into real.h. */ 260818334Speter 2609117395Skanunsigned int 2610132718Skanreal_hash (const REAL_VALUE_TYPE *r) 261118334Speter{ 2612117395Skan unsigned int h; 2613117395Skan size_t i; 261418334Speter 2615169689Skan h = r->cl | (r->sign << 2); 2616169689Skan switch (r->cl) 261718334Speter { 2618117395Skan case rvc_zero: 2619117395Skan case rvc_inf: 2620132718Skan return h; 2621117395Skan 2622117395Skan case rvc_normal: 2623169689Skan h |= REAL_EXP (r) << 3; 2624132718Skan break; 2625117395Skan 2626117395Skan case rvc_nan: 2627132718Skan if (r->signalling) 2628132718Skan h ^= (unsigned int)-1; 2629132718Skan if (r->canonical) 2630132718Skan return h; 2631117395Skan break; 2632117395Skan 2633117395Skan default: 2634169689Skan gcc_unreachable (); 263518334Speter } 263618334Speter 2637132718Skan if (sizeof(unsigned long) > sizeof(unsigned int)) 2638132718Skan for (i = 0; i < SIGSZ; ++i) 2639132718Skan { 2640132718Skan unsigned long s = r->sig[i]; 2641132718Skan h ^= s ^ (s >> (HOST_BITS_PER_LONG / 2)); 2642132718Skan } 2643132718Skan else 2644132718Skan for (i = 0; i < SIGSZ; ++i) 2645132718Skan h ^= r->sig[i]; 2646132718Skan 2647117395Skan return h; 264818334Speter} 2649117395Skan 2650117395Skan/* IEEE single-precision format. */ 265118334Speter 2652132718Skanstatic void encode_ieee_single (const struct real_format *fmt, 2653132718Skan long *, const REAL_VALUE_TYPE *); 2654132718Skanstatic void decode_ieee_single (const struct real_format *, 2655132718Skan REAL_VALUE_TYPE *, const long *); 265618334Speter 265752284Sobrienstatic void 2658132718Skanencode_ieee_single (const struct real_format *fmt, long *buf, 2659132718Skan const REAL_VALUE_TYPE *r) 266018334Speter{ 2661117395Skan unsigned long image, sig, exp; 2662122180Skan unsigned long sign = r->sign; 2663117395Skan bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0; 266418334Speter 2665122180Skan image = sign << 31; 2666117395Skan sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff; 266718334Speter 2668169689Skan switch (r->cl) 2669117395Skan { 2670117395Skan case rvc_zero: 2671117395Skan break; 267218334Speter 2673117395Skan case rvc_inf: 2674117395Skan if (fmt->has_inf) 2675117395Skan image |= 255 << 23; 2676117395Skan else 2677117395Skan image |= 0x7fffffff; 2678117395Skan break; 267918334Speter 2680117395Skan case rvc_nan: 2681117395Skan if (fmt->has_nans) 2682117395Skan { 2683132718Skan if (r->canonical) 2684132718Skan sig = 0; 2685132718Skan if (r->signalling == fmt->qnan_msb_set) 2686132718Skan sig &= ~(1 << 22); 2687132718Skan else 2688132718Skan sig |= 1 << 22; 2689132718Skan /* We overload qnan_msb_set here: it's only clear for 2690132718Skan mips_ieee_single, which wants all mantissa bits but the 2691132718Skan quiet/signalling one set in canonical NaNs (at least 2692132718Skan Quiet ones). */ 2693132718Skan if (r->canonical && !fmt->qnan_msb_set) 2694132718Skan sig |= (1 << 22) - 1; 2695132718Skan else if (sig == 0) 2696132718Skan sig = 1 << 21; 2697132718Skan 2698117395Skan image |= 255 << 23; 2699117395Skan image |= sig; 2700117395Skan } 2701117395Skan else 2702117395Skan image |= 0x7fffffff; 2703117395Skan break; 270418334Speter 2705117395Skan case rvc_normal: 2706117395Skan /* Recall that IEEE numbers are interpreted as 1.F x 2**exp, 2707117395Skan whereas the intermediate representation is 0.F x 2**exp. 2708117395Skan Which means we're off by one. */ 2709117395Skan if (denormal) 2710117395Skan exp = 0; 2711117395Skan else 2712169689Skan exp = REAL_EXP (r) + 127 - 1; 2713117395Skan image |= exp << 23; 2714117395Skan image |= sig; 2715117395Skan break; 271618334Speter 2717117395Skan default: 2718169689Skan gcc_unreachable (); 2719117395Skan } 2720117395Skan 2721117395Skan buf[0] = image; 2722117395Skan} 2723117395Skan 272452284Sobrienstatic void 2725132718Skandecode_ieee_single (const struct real_format *fmt, REAL_VALUE_TYPE *r, 2726132718Skan const long *buf) 272718334Speter{ 2728117395Skan unsigned long image = buf[0] & 0xffffffff; 2729117395Skan bool sign = (image >> 31) & 1; 2730117395Skan int exp = (image >> 23) & 0xff; 273118334Speter 2732117395Skan memset (r, 0, sizeof (*r)); 2733117395Skan image <<= HOST_BITS_PER_LONG - 24; 2734117395Skan image &= ~SIG_MSB; 2735117395Skan 2736117395Skan if (exp == 0) 273718334Speter { 2738117395Skan if (image && fmt->has_denorm) 2739117395Skan { 2740169689Skan r->cl = rvc_normal; 2741117395Skan r->sign = sign; 2742169689Skan SET_REAL_EXP (r, -126); 2743117395Skan r->sig[SIGSZ-1] = image << 1; 2744117395Skan normalize (r); 2745117395Skan } 2746117395Skan else if (fmt->has_signed_zero) 2747117395Skan r->sign = sign; 274818334Speter } 2749117395Skan else if (exp == 255 && (fmt->has_nans || fmt->has_inf)) 275018334Speter { 2751117395Skan if (image) 2752117395Skan { 2753169689Skan r->cl = rvc_nan; 2754117395Skan r->sign = sign; 2755132718Skan r->signalling = (((image >> (HOST_BITS_PER_LONG - 2)) & 1) 2756132718Skan ^ fmt->qnan_msb_set); 2757117395Skan r->sig[SIGSZ-1] = image; 2758117395Skan } 275918334Speter else 276018334Speter { 2761169689Skan r->cl = rvc_inf; 2762117395Skan r->sign = sign; 276318334Speter } 276418334Speter } 2765117395Skan else 276618334Speter { 2767169689Skan r->cl = rvc_normal; 2768117395Skan r->sign = sign; 2769169689Skan SET_REAL_EXP (r, exp - 127 + 1); 2770117395Skan r->sig[SIGSZ-1] = image | SIG_MSB; 277118334Speter } 277218334Speter} 277318334Speter 2774132718Skanconst struct real_format ieee_single_format = 2775117395Skan { 2776117395Skan encode_ieee_single, 2777117395Skan decode_ieee_single, 2778117395Skan 2, 2779117395Skan 1, 2780117395Skan 24, 2781132718Skan 24, 2782117395Skan -125, 2783117395Skan 128, 2784132718Skan 31, 2785169689Skan 31, 2786117395Skan true, 2787117395Skan true, 2788117395Skan true, 2789117395Skan true, 2790117395Skan true 2791117395Skan }; 279218334Speter 2793132718Skanconst struct real_format mips_single_format = 2794132718Skan { 2795132718Skan encode_ieee_single, 2796132718Skan decode_ieee_single, 2797132718Skan 2, 2798132718Skan 1, 2799132718Skan 24, 2800132718Skan 24, 2801132718Skan -125, 2802132718Skan 128, 2803132718Skan 31, 2804169689Skan 31, 2805132718Skan true, 2806132718Skan true, 2807132718Skan true, 2808132718Skan true, 2809132718Skan false 2810132718Skan }; 2811132718Skan 2812117395Skan 2813117395Skan/* IEEE double-precision format. */ 281418334Speter 2815132718Skanstatic void encode_ieee_double (const struct real_format *fmt, 2816132718Skan long *, const REAL_VALUE_TYPE *); 2817132718Skanstatic void decode_ieee_double (const struct real_format *, 2818132718Skan REAL_VALUE_TYPE *, const long *); 2819117395Skan 282052284Sobrienstatic void 2821132718Skanencode_ieee_double (const struct real_format *fmt, long *buf, 2822132718Skan const REAL_VALUE_TYPE *r) 282318334Speter{ 2824117395Skan unsigned long image_lo, image_hi, sig_lo, sig_hi, exp; 2825117395Skan bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0; 282618334Speter 2827117395Skan image_hi = r->sign << 31; 2828117395Skan image_lo = 0; 2829117395Skan 2830117395Skan if (HOST_BITS_PER_LONG == 64) 283118334Speter { 2832117395Skan sig_hi = r->sig[SIGSZ-1]; 2833117395Skan sig_lo = (sig_hi >> (64 - 53)) & 0xffffffff; 2834117395Skan sig_hi = (sig_hi >> (64 - 53 + 1) >> 31) & 0xfffff; 283518334Speter } 2836117395Skan else 283718334Speter { 2838117395Skan sig_hi = r->sig[SIGSZ-1]; 2839117395Skan sig_lo = r->sig[SIGSZ-2]; 2840117395Skan sig_lo = (sig_hi << 21) | (sig_lo >> 11); 2841117395Skan sig_hi = (sig_hi >> 11) & 0xfffff; 284218334Speter } 2843117395Skan 2844169689Skan switch (r->cl) 284518334Speter { 2846117395Skan case rvc_zero: 2847117395Skan break; 2848117395Skan 2849117395Skan case rvc_inf: 2850117395Skan if (fmt->has_inf) 2851117395Skan image_hi |= 2047 << 20; 2852117395Skan else 285318334Speter { 2854117395Skan image_hi |= 0x7fffffff; 2855117395Skan image_lo = 0xffffffff; 285618334Speter } 2857117395Skan break; 2858117395Skan 2859117395Skan case rvc_nan: 2860117395Skan if (fmt->has_nans) 2861117395Skan { 2862132718Skan if (r->canonical) 2863132718Skan sig_hi = sig_lo = 0; 2864132718Skan if (r->signalling == fmt->qnan_msb_set) 2865132718Skan sig_hi &= ~(1 << 19); 2866132718Skan else 2867132718Skan sig_hi |= 1 << 19; 2868132718Skan /* We overload qnan_msb_set here: it's only clear for 2869132718Skan mips_ieee_single, which wants all mantissa bits but the 2870132718Skan quiet/signalling one set in canonical NaNs (at least 2871132718Skan Quiet ones). */ 2872132718Skan if (r->canonical && !fmt->qnan_msb_set) 2873132718Skan { 2874132718Skan sig_hi |= (1 << 19) - 1; 2875132718Skan sig_lo = 0xffffffff; 2876132718Skan } 2877132718Skan else if (sig_hi == 0 && sig_lo == 0) 2878132718Skan sig_hi = 1 << 18; 2879132718Skan 2880117395Skan image_hi |= 2047 << 20; 2881117395Skan image_hi |= sig_hi; 2882117395Skan image_lo = sig_lo; 2883117395Skan } 2884117395Skan else 2885117395Skan { 2886117395Skan image_hi |= 0x7fffffff; 2887117395Skan image_lo = 0xffffffff; 2888117395Skan } 2889117395Skan break; 2890117395Skan 2891117395Skan case rvc_normal: 2892117395Skan /* Recall that IEEE numbers are interpreted as 1.F x 2**exp, 2893117395Skan whereas the intermediate representation is 0.F x 2**exp. 2894117395Skan Which means we're off by one. */ 2895117395Skan if (denormal) 2896117395Skan exp = 0; 2897117395Skan else 2898169689Skan exp = REAL_EXP (r) + 1023 - 1; 2899117395Skan image_hi |= exp << 20; 2900117395Skan image_hi |= sig_hi; 2901117395Skan image_lo = sig_lo; 2902117395Skan break; 2903117395Skan 2904117395Skan default: 2905169689Skan gcc_unreachable (); 290618334Speter } 2907117395Skan 2908117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 2909117395Skan buf[0] = image_hi, buf[1] = image_lo; 291018334Speter else 2911117395Skan buf[0] = image_lo, buf[1] = image_hi; 2912117395Skan} 291318334Speter 2914117395Skanstatic void 2915132718Skandecode_ieee_double (const struct real_format *fmt, REAL_VALUE_TYPE *r, 2916132718Skan const long *buf) 2917117395Skan{ 2918117395Skan unsigned long image_hi, image_lo; 2919117395Skan bool sign; 2920117395Skan int exp; 292118334Speter 2922117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 2923117395Skan image_hi = buf[0], image_lo = buf[1]; 292418334Speter else 2925117395Skan image_lo = buf[0], image_hi = buf[1]; 2926117395Skan image_lo &= 0xffffffff; 2927117395Skan image_hi &= 0xffffffff; 292818334Speter 2929117395Skan sign = (image_hi >> 31) & 1; 2930117395Skan exp = (image_hi >> 20) & 0x7ff; 293118334Speter 2932117395Skan memset (r, 0, sizeof (*r)); 293318334Speter 2934117395Skan image_hi <<= 32 - 21; 2935117395Skan image_hi |= image_lo >> 21; 2936117395Skan image_hi &= 0x7fffffff; 2937117395Skan image_lo <<= 32 - 21; 293818334Speter 2939117395Skan if (exp == 0) 294018334Speter { 2941117395Skan if ((image_hi || image_lo) && fmt->has_denorm) 294218334Speter { 2943169689Skan r->cl = rvc_normal; 2944117395Skan r->sign = sign; 2945169689Skan SET_REAL_EXP (r, -1022); 2946117395Skan if (HOST_BITS_PER_LONG == 32) 2947117395Skan { 2948117395Skan image_hi = (image_hi << 1) | (image_lo >> 31); 2949117395Skan image_lo <<= 1; 2950117395Skan r->sig[SIGSZ-1] = image_hi; 2951117395Skan r->sig[SIGSZ-2] = image_lo; 2952117395Skan } 2953117395Skan else 2954117395Skan { 2955117395Skan image_hi = (image_hi << 31 << 2) | (image_lo << 1); 2956117395Skan r->sig[SIGSZ-1] = image_hi; 2957117395Skan } 2958117395Skan normalize (r); 295918334Speter } 2960117395Skan else if (fmt->has_signed_zero) 2961117395Skan r->sign = sign; 2962117395Skan } 2963117395Skan else if (exp == 2047 && (fmt->has_nans || fmt->has_inf)) 2964117395Skan { 2965117395Skan if (image_hi || image_lo) 2966117395Skan { 2967169689Skan r->cl = rvc_nan; 2968117395Skan r->sign = sign; 2969132718Skan r->signalling = ((image_hi >> 30) & 1) ^ fmt->qnan_msb_set; 2970117395Skan if (HOST_BITS_PER_LONG == 32) 2971117395Skan { 2972117395Skan r->sig[SIGSZ-1] = image_hi; 2973117395Skan r->sig[SIGSZ-2] = image_lo; 2974117395Skan } 2975117395Skan else 2976117395Skan r->sig[SIGSZ-1] = (image_hi << 31 << 1) | image_lo; 297718334Speter } 2978117395Skan else 297918334Speter { 2980169689Skan r->cl = rvc_inf; 2981117395Skan r->sign = sign; 298218334Speter } 298318334Speter } 298418334Speter else 298518334Speter { 2986169689Skan r->cl = rvc_normal; 2987117395Skan r->sign = sign; 2988169689Skan SET_REAL_EXP (r, exp - 1023 + 1); 2989117395Skan if (HOST_BITS_PER_LONG == 32) 299018334Speter { 2991117395Skan r->sig[SIGSZ-1] = image_hi | SIG_MSB; 2992117395Skan r->sig[SIGSZ-2] = image_lo; 299318334Speter } 2994117395Skan else 2995117395Skan r->sig[SIGSZ-1] = (image_hi << 31 << 1) | image_lo | SIG_MSB; 299618334Speter } 299718334Speter} 299818334Speter 2999132718Skanconst struct real_format ieee_double_format = 3000117395Skan { 3001117395Skan encode_ieee_double, 3002117395Skan decode_ieee_double, 3003117395Skan 2, 3004117395Skan 1, 3005117395Skan 53, 3006132718Skan 53, 3007117395Skan -1021, 3008117395Skan 1024, 3009132718Skan 63, 3010169689Skan 63, 3011117395Skan true, 3012117395Skan true, 3013117395Skan true, 3014117395Skan true, 3015117395Skan true 3016117395Skan }; 301718334Speter 3018132718Skanconst struct real_format mips_double_format = 3019132718Skan { 3020132718Skan encode_ieee_double, 3021132718Skan decode_ieee_double, 3022132718Skan 2, 3023132718Skan 1, 3024132718Skan 53, 3025132718Skan 53, 3026132718Skan -1021, 3027132718Skan 1024, 3028132718Skan 63, 3029169689Skan 63, 3030132718Skan true, 3031132718Skan true, 3032132718Skan true, 3033132718Skan true, 3034132718Skan false 3035132718Skan }; 3036132718Skan 3037117395Skan 3038132718Skan/* IEEE extended real format. This comes in three flavors: Intel's as 3039132718Skan a 12 byte image, Intel's as a 16 byte image, and Motorola's. Intel 3040132718Skan 12- and 16-byte images may be big- or little endian; Motorola's is 3041132718Skan always big endian. */ 3042117395Skan 3043132718Skan/* Helper subroutine which converts from the internal format to the 3044132718Skan 12-byte little-endian Intel format. Functions below adjust this 3045132718Skan for the other possible formats. */ 3046117395Skanstatic void 3047132718Skanencode_ieee_extended (const struct real_format *fmt, long *buf, 3048132718Skan const REAL_VALUE_TYPE *r) 304918334Speter{ 3050117395Skan unsigned long image_hi, sig_hi, sig_lo; 3051117395Skan bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0; 305218334Speter 3053117395Skan image_hi = r->sign << 15; 3054117395Skan sig_hi = sig_lo = 0; 3055117395Skan 3056169689Skan switch (r->cl) 305718334Speter { 3058117395Skan case rvc_zero: 3059117395Skan break; 306018334Speter 3061117395Skan case rvc_inf: 3062117395Skan if (fmt->has_inf) 306318334Speter { 3064117395Skan image_hi |= 32767; 3065117395Skan 3066117395Skan /* Intel requires the explicit integer bit to be set, otherwise 3067117395Skan it considers the value a "pseudo-infinity". Motorola docs 3068117395Skan say it doesn't care. */ 3069117395Skan sig_hi = 0x80000000; 307018334Speter } 3071117395Skan else 3072117395Skan { 3073117395Skan image_hi |= 32767; 3074117395Skan sig_lo = sig_hi = 0xffffffff; 3075117395Skan } 3076117395Skan break; 307718334Speter 3078117395Skan case rvc_nan: 3079117395Skan if (fmt->has_nans) 3080117395Skan { 3081117395Skan image_hi |= 32767; 3082117395Skan if (HOST_BITS_PER_LONG == 32) 3083117395Skan { 3084117395Skan sig_hi = r->sig[SIGSZ-1]; 3085117395Skan sig_lo = r->sig[SIGSZ-2]; 3086117395Skan } 3087117395Skan else 3088117395Skan { 3089117395Skan sig_lo = r->sig[SIGSZ-1]; 3090117395Skan sig_hi = sig_lo >> 31 >> 1; 3091117395Skan sig_lo &= 0xffffffff; 3092117395Skan } 3093132718Skan if (r->signalling == fmt->qnan_msb_set) 3094132718Skan sig_hi &= ~(1 << 30); 3095132718Skan else 3096132718Skan sig_hi |= 1 << 30; 3097132718Skan if ((sig_hi & 0x7fffffff) == 0 && sig_lo == 0) 3098132718Skan sig_hi = 1 << 29; 309918334Speter 3100117395Skan /* Intel requires the explicit integer bit to be set, otherwise 3101117395Skan it considers the value a "pseudo-nan". Motorola docs say it 3102117395Skan doesn't care. */ 3103117395Skan sig_hi |= 0x80000000; 3104117395Skan } 3105117395Skan else 310618334Speter { 3107117395Skan image_hi |= 32767; 3108117395Skan sig_lo = sig_hi = 0xffffffff; 310918334Speter } 3110117395Skan break; 311118334Speter 3112117395Skan case rvc_normal: 3113117395Skan { 3114169689Skan int exp = REAL_EXP (r); 311518334Speter 3116117395Skan /* Recall that IEEE numbers are interpreted as 1.F x 2**exp, 3117117395Skan whereas the intermediate representation is 0.F x 2**exp. 3118132718Skan Which means we're off by one. 311918334Speter 3120117395Skan Except for Motorola, which consider exp=0 and explicit 3121117395Skan integer bit set to continue to be normalized. In theory 3122132718Skan this discrepancy has been taken care of by the difference 3123117395Skan in fmt->emin in round_for_format. */ 312418334Speter 3125117395Skan if (denormal) 3126117395Skan exp = 0; 3127117395Skan else 3128117395Skan { 3129117395Skan exp += 16383 - 1; 3130169689Skan gcc_assert (exp >= 0); 3131117395Skan } 3132117395Skan image_hi |= exp; 313318334Speter 3134117395Skan if (HOST_BITS_PER_LONG == 32) 3135117395Skan { 3136117395Skan sig_hi = r->sig[SIGSZ-1]; 3137117395Skan sig_lo = r->sig[SIGSZ-2]; 3138117395Skan } 3139117395Skan else 3140117395Skan { 3141117395Skan sig_lo = r->sig[SIGSZ-1]; 3142117395Skan sig_hi = sig_lo >> 31 >> 1; 3143117395Skan sig_lo &= 0xffffffff; 3144117395Skan } 3145117395Skan } 3146117395Skan break; 314718334Speter 3148117395Skan default: 3149169689Skan gcc_unreachable (); 3150117395Skan } 315118334Speter 3152132718Skan buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi; 3153132718Skan} 3154132718Skan 3155132718Skan/* Convert from the internal format to the 12-byte Motorola format 3156132718Skan for an IEEE extended real. */ 3157132718Skanstatic void 3158132718Skanencode_ieee_extended_motorola (const struct real_format *fmt, long *buf, 3159132718Skan const REAL_VALUE_TYPE *r) 3160132718Skan{ 3161132718Skan long intermed[3]; 3162132718Skan encode_ieee_extended (fmt, intermed, r); 3163132718Skan 3164132718Skan /* Motorola chips are assumed always to be big-endian. Also, the 3165132718Skan padding in a Motorola extended real goes between the exponent and 3166132718Skan the mantissa. At this point the mantissa is entirely within 3167132718Skan elements 0 and 1 of intermed, and the exponent entirely within 3168132718Skan element 2, so all we have to do is swap the order around, and 3169132718Skan shift element 2 left 16 bits. */ 3170132718Skan buf[0] = intermed[2] << 16; 3171132718Skan buf[1] = intermed[1]; 3172132718Skan buf[2] = intermed[0]; 3173132718Skan} 3174132718Skan 3175132718Skan/* Convert from the internal format to the 12-byte Intel format for 3176132718Skan an IEEE extended real. */ 3177132718Skanstatic void 3178132718Skanencode_ieee_extended_intel_96 (const struct real_format *fmt, long *buf, 3179132718Skan const REAL_VALUE_TYPE *r) 3180132718Skan{ 3181117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 3182132718Skan { 3183132718Skan /* All the padding in an Intel-format extended real goes at the high 3184132718Skan end, which in this case is after the mantissa, not the exponent. 3185132718Skan Therefore we must shift everything down 16 bits. */ 3186132718Skan long intermed[3]; 3187132718Skan encode_ieee_extended (fmt, intermed, r); 3188132718Skan buf[0] = ((intermed[2] << 16) | ((unsigned long)(intermed[1] & 0xFFFF0000) >> 16)); 3189132718Skan buf[1] = ((intermed[1] << 16) | ((unsigned long)(intermed[0] & 0xFFFF0000) >> 16)); 3190132718Skan buf[2] = (intermed[0] << 16); 3191132718Skan } 3192117395Skan else 3193132718Skan /* encode_ieee_extended produces what we want directly. */ 3194132718Skan encode_ieee_extended (fmt, buf, r); 319518334Speter} 319618334Speter 3197132718Skan/* Convert from the internal format to the 16-byte Intel format for 3198132718Skan an IEEE extended real. */ 319952284Sobrienstatic void 3200132718Skanencode_ieee_extended_intel_128 (const struct real_format *fmt, long *buf, 3201132718Skan const REAL_VALUE_TYPE *r) 320218334Speter{ 3203132718Skan /* All the padding in an Intel-format extended real goes at the high end. */ 3204132718Skan encode_ieee_extended_intel_96 (fmt, buf, r); 3205132718Skan buf[3] = 0; 320618334Speter} 320718334Speter 3208132718Skan/* As above, we have a helper function which converts from 12-byte 3209132718Skan little-endian Intel format to internal format. Functions below 3210132718Skan adjust for the other possible formats. */ 321152284Sobrienstatic void 3212132718Skandecode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r, 3213132718Skan const long *buf) 321418334Speter{ 3215117395Skan unsigned long image_hi, sig_hi, sig_lo; 3216117395Skan bool sign; 3217117395Skan int exp; 321818334Speter 3219132718Skan sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2]; 3220117395Skan sig_lo &= 0xffffffff; 3221117395Skan sig_hi &= 0xffffffff; 3222117395Skan image_hi &= 0xffffffff; 322318334Speter 3224117395Skan sign = (image_hi >> 15) & 1; 3225117395Skan exp = image_hi & 0x7fff; 322618334Speter 3227117395Skan memset (r, 0, sizeof (*r)); 322818334Speter 3229117395Skan if (exp == 0) 323018334Speter { 3231117395Skan if ((sig_hi || sig_lo) && fmt->has_denorm) 323218334Speter { 3233169689Skan r->cl = rvc_normal; 3234117395Skan r->sign = sign; 323518334Speter 3236117395Skan /* When the IEEE format contains a hidden bit, we know that 3237117395Skan it's zero at this point, and so shift up the significand 3238117395Skan and decrease the exponent to match. In this case, Motorola 3239117395Skan defines the explicit integer bit to be valid, so we don't 3240117395Skan know whether the msb is set or not. */ 3241169689Skan SET_REAL_EXP (r, fmt->emin); 3242117395Skan if (HOST_BITS_PER_LONG == 32) 324318334Speter { 3244117395Skan r->sig[SIGSZ-1] = sig_hi; 3245117395Skan r->sig[SIGSZ-2] = sig_lo; 324618334Speter } 3247117395Skan else 3248117395Skan r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo; 324918334Speter 3250117395Skan normalize (r); 325118334Speter } 3252117395Skan else if (fmt->has_signed_zero) 3253117395Skan r->sign = sign; 325418334Speter } 3255117395Skan else if (exp == 32767 && (fmt->has_nans || fmt->has_inf)) 3256117395Skan { 3257117395Skan /* See above re "pseudo-infinities" and "pseudo-nans". 3258117395Skan Short summary is that the MSB will likely always be 3259117395Skan set, and that we don't care about it. */ 3260117395Skan sig_hi &= 0x7fffffff; 3261117395Skan 3262117395Skan if (sig_hi || sig_lo) 326318334Speter { 3264169689Skan r->cl = rvc_nan; 3265117395Skan r->sign = sign; 3266132718Skan r->signalling = ((sig_hi >> 30) & 1) ^ fmt->qnan_msb_set; 3267117395Skan if (HOST_BITS_PER_LONG == 32) 326818334Speter { 3269117395Skan r->sig[SIGSZ-1] = sig_hi; 3270117395Skan r->sig[SIGSZ-2] = sig_lo; 327118334Speter } 3272117395Skan else 3273117395Skan r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo; 327418334Speter } 327518334Speter else 327618334Speter { 3277169689Skan r->cl = rvc_inf; 3278117395Skan r->sign = sign; 327918334Speter } 328018334Speter } 328118334Speter else 328218334Speter { 3283169689Skan r->cl = rvc_normal; 3284117395Skan r->sign = sign; 3285169689Skan SET_REAL_EXP (r, exp - 16383 + 1); 3286117395Skan if (HOST_BITS_PER_LONG == 32) 328718334Speter { 3288117395Skan r->sig[SIGSZ-1] = sig_hi; 3289117395Skan r->sig[SIGSZ-2] = sig_lo; 329018334Speter } 3291117395Skan else 3292117395Skan r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo; 329318334Speter } 329418334Speter} 329518334Speter 3296132718Skan/* Convert from the internal format to the 12-byte Motorola format 3297132718Skan for an IEEE extended real. */ 3298117395Skanstatic void 3299132718Skandecode_ieee_extended_motorola (const struct real_format *fmt, REAL_VALUE_TYPE *r, 3300132718Skan const long *buf) 3301117395Skan{ 3302132718Skan long intermed[3]; 3303132718Skan 3304132718Skan /* Motorola chips are assumed always to be big-endian. Also, the 3305132718Skan padding in a Motorola extended real goes between the exponent and 3306132718Skan the mantissa; remove it. */ 3307132718Skan intermed[0] = buf[2]; 3308132718Skan intermed[1] = buf[1]; 3309132718Skan intermed[2] = (unsigned long)buf[0] >> 16; 3310132718Skan 3311132718Skan decode_ieee_extended (fmt, r, intermed); 3312117395Skan} 331318334Speter 3314132718Skan/* Convert from the internal format to the 12-byte Intel format for 3315132718Skan an IEEE extended real. */ 3316132718Skanstatic void 3317132718Skandecode_ieee_extended_intel_96 (const struct real_format *fmt, REAL_VALUE_TYPE *r, 3318132718Skan const long *buf) 3319132718Skan{ 3320132718Skan if (FLOAT_WORDS_BIG_ENDIAN) 3321132718Skan { 3322132718Skan /* All the padding in an Intel-format extended real goes at the high 3323132718Skan end, which in this case is after the mantissa, not the exponent. 3324132718Skan Therefore we must shift everything up 16 bits. */ 3325132718Skan long intermed[3]; 3326132718Skan 3327132718Skan intermed[0] = (((unsigned long)buf[2] >> 16) | (buf[1] << 16)); 3328132718Skan intermed[1] = (((unsigned long)buf[1] >> 16) | (buf[0] << 16)); 3329132718Skan intermed[2] = ((unsigned long)buf[0] >> 16); 3330132718Skan 3331132718Skan decode_ieee_extended (fmt, r, intermed); 3332132718Skan } 3333132718Skan else 3334132718Skan /* decode_ieee_extended produces what we want directly. */ 3335132718Skan decode_ieee_extended (fmt, r, buf); 3336132718Skan} 3337132718Skan 3338132718Skan/* Convert from the internal format to the 16-byte Intel format for 3339132718Skan an IEEE extended real. */ 3340132718Skanstatic void 3341132718Skandecode_ieee_extended_intel_128 (const struct real_format *fmt, REAL_VALUE_TYPE *r, 3342132718Skan const long *buf) 3343132718Skan{ 3344132718Skan /* All the padding in an Intel-format extended real goes at the high end. */ 3345132718Skan decode_ieee_extended_intel_96 (fmt, r, buf); 3346132718Skan} 3347132718Skan 3348132718Skanconst struct real_format ieee_extended_motorola_format = 3349117395Skan { 3350132718Skan encode_ieee_extended_motorola, 3351132718Skan decode_ieee_extended_motorola, 3352117395Skan 2, 3353117395Skan 1, 3354117395Skan 64, 3355132718Skan 64, 3356117395Skan -16382, 3357117395Skan 16384, 3358132718Skan 95, 3359169689Skan 95, 3360117395Skan true, 3361117395Skan true, 3362117395Skan true, 3363117395Skan true, 3364117395Skan true 3365117395Skan }; 336618334Speter 3367132718Skanconst struct real_format ieee_extended_intel_96_format = 3368117395Skan { 3369132718Skan encode_ieee_extended_intel_96, 3370132718Skan decode_ieee_extended_intel_96, 3371117395Skan 2, 3372117395Skan 1, 3373117395Skan 64, 3374132718Skan 64, 3375117395Skan -16381, 3376117395Skan 16384, 3377132718Skan 79, 3378169689Skan 79, 3379117395Skan true, 3380117395Skan true, 3381117395Skan true, 3382117395Skan true, 3383117395Skan true 3384117395Skan }; 338518334Speter 3386132718Skanconst struct real_format ieee_extended_intel_128_format = 3387117395Skan { 3388132718Skan encode_ieee_extended_intel_128, 3389132718Skan decode_ieee_extended_intel_128, 3390117395Skan 2, 3391117395Skan 1, 3392117395Skan 64, 3393132718Skan 64, 3394117395Skan -16381, 3395117395Skan 16384, 3396132718Skan 79, 3397169689Skan 79, 3398117395Skan true, 3399117395Skan true, 3400117395Skan true, 3401117395Skan true, 3402117395Skan true 3403117395Skan }; 340418334Speter 3405117395Skan/* The following caters to i386 systems that set the rounding precision 3406117395Skan to 53 bits instead of 64, e.g. FreeBSD. */ 3407132718Skanconst struct real_format ieee_extended_intel_96_round_53_format = 3408117395Skan { 3409132718Skan encode_ieee_extended_intel_96, 3410132718Skan decode_ieee_extended_intel_96, 3411117395Skan 2, 3412117395Skan 1, 3413117395Skan 53, 3414132718Skan 53, 3415117395Skan -16381, 3416117395Skan 16384, 3417132718Skan 79, 3418169689Skan 79, 3419117395Skan true, 3420117395Skan true, 3421117395Skan true, 3422117395Skan true, 3423117395Skan true 3424117395Skan }; 3425117395Skan 3426117395Skan/* IBM 128-bit extended precision format: a pair of IEEE double precision 3427117395Skan numbers whose sum is equal to the extended precision value. The number 3428117395Skan with greater magnitude is first. This format has the same magnitude 3429117395Skan range as an IEEE double precision value, but effectively 106 bits of 3430117395Skan significand precision. Infinity and NaN are represented by their IEEE 3431117395Skan double precision value stored in the first number, the second number is 3432169689Skan +0.0 or -0.0 for Infinity and don't-care for NaN. */ 3433117395Skan 3434132718Skanstatic void encode_ibm_extended (const struct real_format *fmt, 3435132718Skan long *, const REAL_VALUE_TYPE *); 3436132718Skanstatic void decode_ibm_extended (const struct real_format *, 3437132718Skan REAL_VALUE_TYPE *, const long *); 3438117395Skan 343952284Sobrienstatic void 3440132718Skanencode_ibm_extended (const struct real_format *fmt, long *buf, 3441132718Skan const REAL_VALUE_TYPE *r) 344218334Speter{ 3443132718Skan REAL_VALUE_TYPE u, normr, v; 3444132718Skan const struct real_format *base_fmt; 344518334Speter 3446132718Skan base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format; 344718334Speter 3448132718Skan /* Renormlize R before doing any arithmetic on it. */ 3449132718Skan normr = *r; 3450169689Skan if (normr.cl == rvc_normal) 3451132718Skan normalize (&normr); 345218334Speter 3453132718Skan /* u = IEEE double precision portion of significand. */ 3454132718Skan u = normr; 3455132718Skan round_for_format (base_fmt, &u); 3456132718Skan encode_ieee_double (base_fmt, &buf[0], &u); 345718334Speter 3458169689Skan if (u.cl == rvc_normal) 3459132718Skan { 3460132718Skan do_add (&v, &normr, &u, 1); 3461132718Skan /* Call round_for_format since we might need to denormalize. */ 3462132718Skan round_for_format (base_fmt, &v); 3463132718Skan encode_ieee_double (base_fmt, &buf[2], &v); 3464117395Skan } 3465132718Skan else 3466132718Skan { 3467132718Skan /* Inf, NaN, 0 are all representable as doubles, so the 3468132718Skan least-significant part can be 0.0. */ 3469132718Skan buf[2] = 0; 3470132718Skan buf[3] = 0; 3471132718Skan } 347218334Speter} 347318334Speter 347452284Sobrienstatic void 3475132718Skandecode_ibm_extended (const struct real_format *fmt ATTRIBUTE_UNUSED, REAL_VALUE_TYPE *r, 3476132718Skan const long *buf) 347718334Speter{ 3478117395Skan REAL_VALUE_TYPE u, v; 3479132718Skan const struct real_format *base_fmt; 348018334Speter 3481132718Skan base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format; 3482132718Skan decode_ieee_double (base_fmt, &u, &buf[0]); 348318334Speter 3484169689Skan if (u.cl != rvc_zero && u.cl != rvc_inf && u.cl != rvc_nan) 3485117395Skan { 3486132718Skan decode_ieee_double (base_fmt, &v, &buf[2]); 3487117395Skan do_add (r, &u, &v, 0); 3488117395Skan } 3489117395Skan else 3490117395Skan *r = u; 349118334Speter} 349218334Speter 3493132718Skanconst struct real_format ibm_extended_format = 3494117395Skan { 3495117395Skan encode_ibm_extended, 3496117395Skan decode_ibm_extended, 3497117395Skan 2, 3498117395Skan 1, 3499117395Skan 53 + 53, 3500132718Skan 53, 3501117395Skan -1021 + 53, 3502117395Skan 1024, 3503169689Skan 127, 3504132718Skan -1, 3505117395Skan true, 3506117395Skan true, 3507117395Skan true, 3508117395Skan true, 3509117395Skan true 3510117395Skan }; 351118334Speter 3512132718Skanconst struct real_format mips_extended_format = 3513132718Skan { 3514132718Skan encode_ibm_extended, 3515132718Skan decode_ibm_extended, 3516132718Skan 2, 3517132718Skan 1, 3518132718Skan 53 + 53, 3519132718Skan 53, 3520132718Skan -1021 + 53, 3521132718Skan 1024, 3522169689Skan 127, 3523132718Skan -1, 3524132718Skan true, 3525132718Skan true, 3526132718Skan true, 3527132718Skan true, 3528132718Skan false 3529132718Skan }; 3530132718Skan 3531117395Skan 3532117395Skan/* IEEE quad precision format. */ 3533117395Skan 3534132718Skanstatic void encode_ieee_quad (const struct real_format *fmt, 3535132718Skan long *, const REAL_VALUE_TYPE *); 3536132718Skanstatic void decode_ieee_quad (const struct real_format *, 3537132718Skan REAL_VALUE_TYPE *, const long *); 3538117395Skan 353952284Sobrienstatic void 3540132718Skanencode_ieee_quad (const struct real_format *fmt, long *buf, 3541132718Skan const REAL_VALUE_TYPE *r) 354218334Speter{ 3543117395Skan unsigned long image3, image2, image1, image0, exp; 3544117395Skan bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0; 3545117395Skan REAL_VALUE_TYPE u; 354618334Speter 3547117395Skan image3 = r->sign << 31; 3548117395Skan image2 = 0; 3549117395Skan image1 = 0; 3550117395Skan image0 = 0; 355152284Sobrien 3552117395Skan rshift_significand (&u, r, SIGNIFICAND_BITS - 113); 355352284Sobrien 3554169689Skan switch (r->cl) 355552284Sobrien { 3556117395Skan case rvc_zero: 3557117395Skan break; 355852284Sobrien 3559117395Skan case rvc_inf: 3560117395Skan if (fmt->has_inf) 3561117395Skan image3 |= 32767 << 16; 3562117395Skan else 356318334Speter { 3564117395Skan image3 |= 0x7fffffff; 3565117395Skan image2 = 0xffffffff; 3566117395Skan image1 = 0xffffffff; 3567117395Skan image0 = 0xffffffff; 356818334Speter } 3569117395Skan break; 357018334Speter 3571117395Skan case rvc_nan: 3572117395Skan if (fmt->has_nans) 3573117395Skan { 3574117395Skan image3 |= 32767 << 16; 357518334Speter 3576132718Skan if (r->canonical) 357752284Sobrien { 3578132718Skan /* Don't use bits from the significand. The 3579132718Skan initialization above is right. */ 3580132718Skan } 3581132718Skan else if (HOST_BITS_PER_LONG == 32) 3582132718Skan { 3583117395Skan image0 = u.sig[0]; 3584117395Skan image1 = u.sig[1]; 3585117395Skan image2 = u.sig[2]; 3586117395Skan image3 |= u.sig[3] & 0xffff; 358752284Sobrien } 358852284Sobrien else 358952284Sobrien { 3590117395Skan image0 = u.sig[0]; 3591117395Skan image1 = image0 >> 31 >> 1; 3592117395Skan image2 = u.sig[1]; 3593117395Skan image3 |= (image2 >> 31 >> 1) & 0xffff; 3594117395Skan image0 &= 0xffffffff; 3595117395Skan image2 &= 0xffffffff; 3596117395Skan } 3597132718Skan if (r->signalling == fmt->qnan_msb_set) 3598132718Skan image3 &= ~0x8000; 3599132718Skan else 3600132718Skan image3 |= 0x8000; 3601132718Skan /* We overload qnan_msb_set here: it's only clear for 3602132718Skan mips_ieee_single, which wants all mantissa bits but the 3603132718Skan quiet/signalling one set in canonical NaNs (at least 3604132718Skan Quiet ones). */ 3605132718Skan if (r->canonical && !fmt->qnan_msb_set) 3606132718Skan { 3607132718Skan image3 |= 0x7fff; 3608132718Skan image2 = image1 = image0 = 0xffffffff; 3609132718Skan } 3610132718Skan else if (((image3 & 0xffff) | image2 | image1 | image0) == 0) 3611132718Skan image3 |= 0x4000; 361218334Speter } 361318334Speter else 361418334Speter { 3615117395Skan image3 |= 0x7fffffff; 3616117395Skan image2 = 0xffffffff; 3617117395Skan image1 = 0xffffffff; 3618117395Skan image0 = 0xffffffff; 361918334Speter } 362018334Speter break; 362118334Speter 3622117395Skan case rvc_normal: 3623117395Skan /* Recall that IEEE numbers are interpreted as 1.F x 2**exp, 3624117395Skan whereas the intermediate representation is 0.F x 2**exp. 3625117395Skan Which means we're off by one. */ 3626117395Skan if (denormal) 3627117395Skan exp = 0; 3628117395Skan else 3629169689Skan exp = REAL_EXP (r) + 16383 - 1; 3630117395Skan image3 |= exp << 16; 363118334Speter 3632117395Skan if (HOST_BITS_PER_LONG == 32) 363352284Sobrien { 3634117395Skan image0 = u.sig[0]; 3635117395Skan image1 = u.sig[1]; 3636117395Skan image2 = u.sig[2]; 3637117395Skan image3 |= u.sig[3] & 0xffff; 363852284Sobrien } 3639117395Skan else 364018334Speter { 3641117395Skan image0 = u.sig[0]; 3642117395Skan image1 = image0 >> 31 >> 1; 3643117395Skan image2 = u.sig[1]; 3644117395Skan image3 |= (image2 >> 31 >> 1) & 0xffff; 3645117395Skan image0 &= 0xffffffff; 3646117395Skan image2 &= 0xffffffff; 364718334Speter } 3648117395Skan break; 3649117395Skan 3650117395Skan default: 3651169689Skan gcc_unreachable (); 365218334Speter } 365318334Speter 3654117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 365518334Speter { 3656117395Skan buf[0] = image3; 3657117395Skan buf[1] = image2; 3658117395Skan buf[2] = image1; 3659117395Skan buf[3] = image0; 366018334Speter } 366118334Speter else 366218334Speter { 3663117395Skan buf[0] = image0; 3664117395Skan buf[1] = image1; 3665117395Skan buf[2] = image2; 3666117395Skan buf[3] = image3; 366718334Speter } 366818334Speter} 366918334Speter 367052284Sobrienstatic void 3671132718Skandecode_ieee_quad (const struct real_format *fmt, REAL_VALUE_TYPE *r, 3672132718Skan const long *buf) 367318334Speter{ 3674117395Skan unsigned long image3, image2, image1, image0; 3675117395Skan bool sign; 3676117395Skan int exp; 367718334Speter 3678117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 367918334Speter { 3680117395Skan image3 = buf[0]; 3681117395Skan image2 = buf[1]; 3682117395Skan image1 = buf[2]; 3683117395Skan image0 = buf[3]; 368418334Speter } 3685117395Skan else 368618334Speter { 3687117395Skan image0 = buf[0]; 3688117395Skan image1 = buf[1]; 3689117395Skan image2 = buf[2]; 3690117395Skan image3 = buf[3]; 369118334Speter } 3692117395Skan image0 &= 0xffffffff; 3693117395Skan image1 &= 0xffffffff; 3694117395Skan image2 &= 0xffffffff; 369518334Speter 3696117395Skan sign = (image3 >> 31) & 1; 3697117395Skan exp = (image3 >> 16) & 0x7fff; 3698117395Skan image3 &= 0xffff; 3699117395Skan 3700117395Skan memset (r, 0, sizeof (*r)); 3701117395Skan 3702117395Skan if (exp == 0) 370318334Speter { 3704117395Skan if ((image3 | image2 | image1 | image0) && fmt->has_denorm) 370518334Speter { 3706169689Skan r->cl = rvc_normal; 3707117395Skan r->sign = sign; 3708117395Skan 3709169689Skan SET_REAL_EXP (r, -16382 + (SIGNIFICAND_BITS - 112)); 3710117395Skan if (HOST_BITS_PER_LONG == 32) 371118334Speter { 3712117395Skan r->sig[0] = image0; 3713117395Skan r->sig[1] = image1; 3714117395Skan r->sig[2] = image2; 3715117395Skan r->sig[3] = image3; 371618334Speter } 3717117395Skan else 3718117395Skan { 3719117395Skan r->sig[0] = (image1 << 31 << 1) | image0; 3720117395Skan r->sig[1] = (image3 << 31 << 1) | image2; 3721117395Skan } 3722117395Skan 3723117395Skan normalize (r); 372418334Speter } 3725117395Skan else if (fmt->has_signed_zero) 3726117395Skan r->sign = sign; 372718334Speter } 3728117395Skan else if (exp == 32767 && (fmt->has_nans || fmt->has_inf)) 372918334Speter { 3730117395Skan if (image3 | image2 | image1 | image0) 3731117395Skan { 3732169689Skan r->cl = rvc_nan; 3733117395Skan r->sign = sign; 3734132718Skan r->signalling = ((image3 >> 15) & 1) ^ fmt->qnan_msb_set; 373518334Speter 3736117395Skan if (HOST_BITS_PER_LONG == 32) 3737117395Skan { 3738117395Skan r->sig[0] = image0; 3739117395Skan r->sig[1] = image1; 3740117395Skan r->sig[2] = image2; 3741117395Skan r->sig[3] = image3; 3742117395Skan } 3743117395Skan else 3744117395Skan { 3745117395Skan r->sig[0] = (image1 << 31 << 1) | image0; 3746117395Skan r->sig[1] = (image3 << 31 << 1) | image2; 3747117395Skan } 3748117395Skan lshift_significand (r, r, SIGNIFICAND_BITS - 113); 3749117395Skan } 3750117395Skan else 3751117395Skan { 3752169689Skan r->cl = rvc_inf; 3753117395Skan r->sign = sign; 3754117395Skan } 375518334Speter } 3756117395Skan else 375718334Speter { 3758169689Skan r->cl = rvc_normal; 3759117395Skan r->sign = sign; 3760169689Skan SET_REAL_EXP (r, exp - 16383 + 1); 376118334Speter 3762117395Skan if (HOST_BITS_PER_LONG == 32) 376318334Speter { 3764117395Skan r->sig[0] = image0; 3765117395Skan r->sig[1] = image1; 3766117395Skan r->sig[2] = image2; 3767117395Skan r->sig[3] = image3; 376818334Speter } 376918334Speter else 3770117395Skan { 3771117395Skan r->sig[0] = (image1 << 31 << 1) | image0; 3772117395Skan r->sig[1] = (image3 << 31 << 1) | image2; 3773117395Skan } 3774117395Skan lshift_significand (r, r, SIGNIFICAND_BITS - 113); 3775117395Skan r->sig[SIGSZ-1] |= SIG_MSB; 377618334Speter } 377718334Speter} 377818334Speter 3779132718Skanconst struct real_format ieee_quad_format = 3780117395Skan { 3781117395Skan encode_ieee_quad, 3782117395Skan decode_ieee_quad, 3783117395Skan 2, 3784117395Skan 1, 3785117395Skan 113, 3786132718Skan 113, 3787117395Skan -16381, 3788117395Skan 16384, 3789132718Skan 127, 3790169689Skan 127, 3791117395Skan true, 3792117395Skan true, 3793117395Skan true, 3794117395Skan true, 3795117395Skan true 3796117395Skan }; 3797132718Skan 3798132718Skanconst struct real_format mips_quad_format = 3799132718Skan { 3800132718Skan encode_ieee_quad, 3801132718Skan decode_ieee_quad, 3802132718Skan 2, 3803132718Skan 1, 3804132718Skan 113, 3805132718Skan 113, 3806132718Skan -16381, 3807132718Skan 16384, 3808132718Skan 127, 3809169689Skan 127, 3810132718Skan true, 3811132718Skan true, 3812132718Skan true, 3813132718Skan true, 3814132718Skan false 3815132718Skan }; 3816117395Skan 3817117395Skan/* Descriptions of VAX floating point formats can be found beginning at 381818334Speter 3819132718Skan http://h71000.www7.hp.com/doc/73FINAL/4515/4515pro_013.html#f_floating_point_format 382052284Sobrien 3821117395Skan The thing to remember is that they're almost IEEE, except for word 3822117395Skan order, exponent bias, and the lack of infinities, nans, and denormals. 382352284Sobrien 3824117395Skan We don't implement the H_floating format here, simply because neither 3825117395Skan the VAX or Alpha ports use it. */ 382618334Speter 3827132718Skanstatic void encode_vax_f (const struct real_format *fmt, 3828132718Skan long *, const REAL_VALUE_TYPE *); 3829132718Skanstatic void decode_vax_f (const struct real_format *, 3830132718Skan REAL_VALUE_TYPE *, const long *); 3831132718Skanstatic void encode_vax_d (const struct real_format *fmt, 3832132718Skan long *, const REAL_VALUE_TYPE *); 3833132718Skanstatic void decode_vax_d (const struct real_format *, 3834132718Skan REAL_VALUE_TYPE *, const long *); 3835132718Skanstatic void encode_vax_g (const struct real_format *fmt, 3836132718Skan long *, const REAL_VALUE_TYPE *); 3837132718Skanstatic void decode_vax_g (const struct real_format *, 3838132718Skan REAL_VALUE_TYPE *, const long *); 3839132718Skan 384052284Sobrienstatic void 3841132718Skanencode_vax_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf, 3842132718Skan const REAL_VALUE_TYPE *r) 384318334Speter{ 3844117395Skan unsigned long sign, exp, sig, image; 384518334Speter 3846117395Skan sign = r->sign << 15; 3847117395Skan 3848169689Skan switch (r->cl) 384952284Sobrien { 3850117395Skan case rvc_zero: 3851117395Skan image = 0; 3852117395Skan break; 385352284Sobrien 3854117395Skan case rvc_inf: 3855117395Skan case rvc_nan: 3856117395Skan image = 0xffff7fff | sign; 3857117395Skan break; 385818334Speter 3859117395Skan case rvc_normal: 3860117395Skan sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff; 3861169689Skan exp = REAL_EXP (r) + 128; 386218334Speter 3863117395Skan image = (sig << 16) & 0xffff0000; 3864117395Skan image |= sign; 3865117395Skan image |= exp << 7; 3866117395Skan image |= sig >> 16; 3867117395Skan break; 386818334Speter 3869117395Skan default: 3870169689Skan gcc_unreachable (); 3871117395Skan } 387218334Speter 3873117395Skan buf[0] = image; 387418334Speter} 387518334Speter 387652284Sobrienstatic void 3877132718Skandecode_vax_f (const struct real_format *fmt ATTRIBUTE_UNUSED, 3878132718Skan REAL_VALUE_TYPE *r, const long *buf) 387918334Speter{ 3880117395Skan unsigned long image = buf[0] & 0xffffffff; 3881117395Skan int exp = (image >> 7) & 0xff; 388218334Speter 3883117395Skan memset (r, 0, sizeof (*r)); 3884117395Skan 3885117395Skan if (exp != 0) 3886117395Skan { 3887169689Skan r->cl = rvc_normal; 3888117395Skan r->sign = (image >> 15) & 1; 3889169689Skan SET_REAL_EXP (r, exp - 128); 3890117395Skan 3891117395Skan image = ((image & 0x7f) << 16) | ((image >> 16) & 0xffff); 3892117395Skan r->sig[SIGSZ-1] = (image << (HOST_BITS_PER_LONG - 24)) | SIG_MSB; 3893117395Skan } 389418334Speter} 389518334Speter 389652284Sobrienstatic void 3897132718Skanencode_vax_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf, 3898132718Skan const REAL_VALUE_TYPE *r) 389918334Speter{ 3900117395Skan unsigned long image0, image1, sign = r->sign << 15; 390118334Speter 3902169689Skan switch (r->cl) 390318334Speter { 3904117395Skan case rvc_zero: 3905117395Skan image0 = image1 = 0; 3906117395Skan break; 390718334Speter 3908117395Skan case rvc_inf: 3909117395Skan case rvc_nan: 3910117395Skan image0 = 0xffff7fff | sign; 3911117395Skan image1 = 0xffffffff; 3912117395Skan break; 391318334Speter 3914117395Skan case rvc_normal: 3915117395Skan /* Extract the significand into straight hi:lo. */ 3916117395Skan if (HOST_BITS_PER_LONG == 64) 3917117395Skan { 3918117395Skan image0 = r->sig[SIGSZ-1]; 3919117395Skan image1 = (image0 >> (64 - 56)) & 0xffffffff; 3920117395Skan image0 = (image0 >> (64 - 56 + 1) >> 31) & 0x7fffff; 3921117395Skan } 3922117395Skan else 3923117395Skan { 3924117395Skan image0 = r->sig[SIGSZ-1]; 3925117395Skan image1 = r->sig[SIGSZ-2]; 3926117395Skan image1 = (image0 << 24) | (image1 >> 8); 3927117395Skan image0 = (image0 >> 8) & 0xffffff; 3928117395Skan } 392918334Speter 3930117395Skan /* Rearrange the half-words of the significand to match the 3931117395Skan external format. */ 3932117395Skan image0 = ((image0 << 16) | (image0 >> 16)) & 0xffff007f; 3933117395Skan image1 = ((image1 << 16) | (image1 >> 16)) & 0xffffffff; 393418334Speter 3935117395Skan /* Add the sign and exponent. */ 3936117395Skan image0 |= sign; 3937169689Skan image0 |= (REAL_EXP (r) + 128) << 7; 3938117395Skan break; 3939117395Skan 3940117395Skan default: 3941169689Skan gcc_unreachable (); 394218334Speter } 394318334Speter 3944117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 3945117395Skan buf[0] = image1, buf[1] = image0; 394618334Speter else 3947117395Skan buf[0] = image0, buf[1] = image1; 394818334Speter} 394918334Speter 3950117395Skanstatic void 3951132718Skandecode_vax_d (const struct real_format *fmt ATTRIBUTE_UNUSED, 3952132718Skan REAL_VALUE_TYPE *r, const long *buf) 3953117395Skan{ 3954117395Skan unsigned long image0, image1; 3955117395Skan int exp; 395618334Speter 3957117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 3958117395Skan image1 = buf[0], image0 = buf[1]; 3959117395Skan else 3960117395Skan image0 = buf[0], image1 = buf[1]; 3961117395Skan image0 &= 0xffffffff; 3962117395Skan image1 &= 0xffffffff; 396318334Speter 3964132718Skan exp = (image0 >> 7) & 0xff; 396518334Speter 3966117395Skan memset (r, 0, sizeof (*r)); 396718334Speter 3968117395Skan if (exp != 0) 3969117395Skan { 3970169689Skan r->cl = rvc_normal; 3971117395Skan r->sign = (image0 >> 15) & 1; 3972169689Skan SET_REAL_EXP (r, exp - 128); 397318334Speter 3974117395Skan /* Rearrange the half-words of the external format into 3975117395Skan proper ascending order. */ 3976117395Skan image0 = ((image0 & 0x7f) << 16) | ((image0 >> 16) & 0xffff); 3977117395Skan image1 = ((image1 & 0xffff) << 16) | ((image1 >> 16) & 0xffff); 397818334Speter 3979117395Skan if (HOST_BITS_PER_LONG == 64) 398018334Speter { 3981117395Skan image0 = (image0 << 31 << 1) | image1; 3982117395Skan image0 <<= 64 - 56; 3983117395Skan image0 |= SIG_MSB; 3984117395Skan r->sig[SIGSZ-1] = image0; 398518334Speter } 3986117395Skan else 398718334Speter { 3988117395Skan r->sig[SIGSZ-1] = image0; 3989117395Skan r->sig[SIGSZ-2] = image1; 3990117395Skan lshift_significand (r, r, 2*HOST_BITS_PER_LONG - 56); 3991117395Skan r->sig[SIGSZ-1] |= SIG_MSB; 399218334Speter } 399318334Speter } 399418334Speter} 399518334Speter 399652284Sobrienstatic void 3997132718Skanencode_vax_g (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf, 3998132718Skan const REAL_VALUE_TYPE *r) 399950397Sobrien{ 4000117395Skan unsigned long image0, image1, sign = r->sign << 15; 400150397Sobrien 4002169689Skan switch (r->cl) 400350397Sobrien { 4004117395Skan case rvc_zero: 4005117395Skan image0 = image1 = 0; 4006117395Skan break; 400790075Sobrien 4008117395Skan case rvc_inf: 4009117395Skan case rvc_nan: 4010117395Skan image0 = 0xffff7fff | sign; 4011117395Skan image1 = 0xffffffff; 4012117395Skan break; 401350397Sobrien 4014117395Skan case rvc_normal: 4015117395Skan /* Extract the significand into straight hi:lo. */ 4016117395Skan if (HOST_BITS_PER_LONG == 64) 4017117395Skan { 4018117395Skan image0 = r->sig[SIGSZ-1]; 4019117395Skan image1 = (image0 >> (64 - 53)) & 0xffffffff; 4020117395Skan image0 = (image0 >> (64 - 53 + 1) >> 31) & 0xfffff; 4021117395Skan } 402290075Sobrien else 4023117395Skan { 4024117395Skan image0 = r->sig[SIGSZ-1]; 4025117395Skan image1 = r->sig[SIGSZ-2]; 4026117395Skan image1 = (image0 << 21) | (image1 >> 11); 4027117395Skan image0 = (image0 >> 11) & 0xfffff; 4028117395Skan } 402950397Sobrien 4030117395Skan /* Rearrange the half-words of the significand to match the 4031117395Skan external format. */ 4032117395Skan image0 = ((image0 << 16) | (image0 >> 16)) & 0xffff000f; 4033117395Skan image1 = ((image1 << 16) | (image1 >> 16)) & 0xffffffff; 403450397Sobrien 4035117395Skan /* Add the sign and exponent. */ 4036117395Skan image0 |= sign; 4037169689Skan image0 |= (REAL_EXP (r) + 1024) << 4; 4038117395Skan break; 403950397Sobrien 4040117395Skan default: 4041169689Skan gcc_unreachable (); 404290075Sobrien } 4043117395Skan 4044117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 4045117395Skan buf[0] = image1, buf[1] = image0; 404650397Sobrien else 4047117395Skan buf[0] = image0, buf[1] = image1; 404850397Sobrien} 404950397Sobrien 405052284Sobrienstatic void 4051132718Skandecode_vax_g (const struct real_format *fmt ATTRIBUTE_UNUSED, 4052132718Skan REAL_VALUE_TYPE *r, const long *buf) 405350397Sobrien{ 4054117395Skan unsigned long image0, image1; 4055117395Skan int exp; 405650397Sobrien 4057117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 4058117395Skan image1 = buf[0], image0 = buf[1]; 4059117395Skan else 4060117395Skan image0 = buf[0], image1 = buf[1]; 4061117395Skan image0 &= 0xffffffff; 4062117395Skan image1 &= 0xffffffff; 406350397Sobrien 4064117395Skan exp = (image0 >> 4) & 0x7ff; 406550397Sobrien 4066117395Skan memset (r, 0, sizeof (*r)); 406750397Sobrien 4068117395Skan if (exp != 0) 406950397Sobrien { 4070169689Skan r->cl = rvc_normal; 4071117395Skan r->sign = (image0 >> 15) & 1; 4072169689Skan SET_REAL_EXP (r, exp - 1024); 407352284Sobrien 4074117395Skan /* Rearrange the half-words of the external format into 4075117395Skan proper ascending order. */ 4076117395Skan image0 = ((image0 & 0xf) << 16) | ((image0 >> 16) & 0xffff); 4077117395Skan image1 = ((image1 & 0xffff) << 16) | ((image1 >> 16) & 0xffff); 407852284Sobrien 4079117395Skan if (HOST_BITS_PER_LONG == 64) 408050397Sobrien { 4081117395Skan image0 = (image0 << 31 << 1) | image1; 4082117395Skan image0 <<= 64 - 53; 4083117395Skan image0 |= SIG_MSB; 4084117395Skan r->sig[SIGSZ-1] = image0; 408550397Sobrien } 4086117395Skan else 408750397Sobrien { 4088117395Skan r->sig[SIGSZ-1] = image0; 4089117395Skan r->sig[SIGSZ-2] = image1; 4090117395Skan lshift_significand (r, r, 64 - 53); 4091117395Skan r->sig[SIGSZ-1] |= SIG_MSB; 409250397Sobrien } 409350397Sobrien } 409450397Sobrien} 409550397Sobrien 4096132718Skanconst struct real_format vax_f_format = 4097117395Skan { 4098117395Skan encode_vax_f, 4099117395Skan decode_vax_f, 4100117395Skan 2, 4101117395Skan 1, 4102117395Skan 24, 4103132718Skan 24, 4104117395Skan -127, 4105117395Skan 127, 4106132718Skan 15, 4107169689Skan 15, 4108117395Skan false, 4109117395Skan false, 4110117395Skan false, 4111117395Skan false, 4112117395Skan false 4113117395Skan }; 411418334Speter 4115132718Skanconst struct real_format vax_d_format = 4116117395Skan { 4117117395Skan encode_vax_d, 4118117395Skan decode_vax_d, 4119117395Skan 2, 4120117395Skan 1, 4121117395Skan 56, 4122132718Skan 56, 4123117395Skan -127, 4124117395Skan 127, 4125132718Skan 15, 4126169689Skan 15, 4127117395Skan false, 4128117395Skan false, 4129117395Skan false, 4130117395Skan false, 4131117395Skan false 4132117395Skan }; 413318334Speter 4134132718Skanconst struct real_format vax_g_format = 4135117395Skan { 4136117395Skan encode_vax_g, 4137117395Skan decode_vax_g, 4138117395Skan 2, 4139117395Skan 1, 4140117395Skan 53, 4141132718Skan 53, 4142117395Skan -1023, 4143117395Skan 1023, 4144132718Skan 15, 4145169689Skan 15, 4146117395Skan false, 4147117395Skan false, 4148117395Skan false, 4149117395Skan false, 4150117395Skan false 4151117395Skan }; 4152117395Skan 4153117395Skan/* A good reference for these can be found in chapter 9 of 4154117395Skan "ESA/390 Principles of Operation", IBM document number SA22-7201-01. 4155117395Skan An on-line version can be found here: 415618334Speter 4157117395Skan http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/DZ9AR001/9.1?DT=19930923083613 4158117395Skan*/ 415918334Speter 4160132718Skanstatic void encode_i370_single (const struct real_format *fmt, 4161132718Skan long *, const REAL_VALUE_TYPE *); 4162132718Skanstatic void decode_i370_single (const struct real_format *, 4163132718Skan REAL_VALUE_TYPE *, const long *); 4164132718Skanstatic void encode_i370_double (const struct real_format *fmt, 4165132718Skan long *, const REAL_VALUE_TYPE *); 4166132718Skanstatic void decode_i370_double (const struct real_format *, 4167132718Skan REAL_VALUE_TYPE *, const long *); 416818334Speter 416918334Speterstatic void 4170132718Skanencode_i370_single (const struct real_format *fmt ATTRIBUTE_UNUSED, 4171132718Skan long *buf, const REAL_VALUE_TYPE *r) 417218334Speter{ 4173117395Skan unsigned long sign, exp, sig, image; 417418334Speter 4175117395Skan sign = r->sign << 31; 4176117395Skan 4177169689Skan switch (r->cl) 417818334Speter { 4179117395Skan case rvc_zero: 4180117395Skan image = 0; 418118334Speter break; 418250397Sobrien 4183117395Skan case rvc_inf: 4184117395Skan case rvc_nan: 4185117395Skan image = 0x7fffffff | sign; 418618334Speter break; 418750397Sobrien 4188117395Skan case rvc_normal: 4189117395Skan sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0xffffff; 4190169689Skan exp = ((REAL_EXP (r) / 4) + 64) << 24; 4191117395Skan image = sign | exp | sig; 419218334Speter break; 419350397Sobrien 419418334Speter default: 4195169689Skan gcc_unreachable (); 419618334Speter } 4197117395Skan 4198117395Skan buf[0] = image; 419918334Speter} 420018334Speter 4201117395Skanstatic void 4202132718Skandecode_i370_single (const struct real_format *fmt ATTRIBUTE_UNUSED, 4203132718Skan REAL_VALUE_TYPE *r, const long *buf) 420418334Speter{ 4205117395Skan unsigned long sign, sig, image = buf[0]; 4206117395Skan int exp; 420718334Speter 4208117395Skan sign = (image >> 31) & 1; 4209117395Skan exp = (image >> 24) & 0x7f; 4210117395Skan sig = image & 0xffffff; 421118334Speter 4212117395Skan memset (r, 0, sizeof (*r)); 421318334Speter 4214117395Skan if (exp || sig) 421550397Sobrien { 4216169689Skan r->cl = rvc_normal; 4217117395Skan r->sign = sign; 4218169689Skan SET_REAL_EXP (r, (exp - 64) * 4); 4219117395Skan r->sig[SIGSZ-1] = sig << (HOST_BITS_PER_LONG - 24); 4220117395Skan normalize (r); 422150397Sobrien } 422250397Sobrien} 422350397Sobrien 4224117395Skanstatic void 4225132718Skanencode_i370_double (const struct real_format *fmt ATTRIBUTE_UNUSED, 4226132718Skan long *buf, const REAL_VALUE_TYPE *r) 4227117395Skan{ 4228117395Skan unsigned long sign, exp, image_hi, image_lo; 422950397Sobrien 4230117395Skan sign = r->sign << 31; 423150397Sobrien 4232169689Skan switch (r->cl) 423350397Sobrien { 4234117395Skan case rvc_zero: 4235117395Skan image_hi = image_lo = 0; 4236117395Skan break; 423750397Sobrien 4238117395Skan case rvc_inf: 4239117395Skan case rvc_nan: 4240117395Skan image_hi = 0x7fffffff | sign; 4241117395Skan image_lo = 0xffffffff; 4242117395Skan break; 424350397Sobrien 4244117395Skan case rvc_normal: 4245117395Skan if (HOST_BITS_PER_LONG == 64) 4246117395Skan { 4247117395Skan image_hi = r->sig[SIGSZ-1]; 4248117395Skan image_lo = (image_hi >> (64 - 56)) & 0xffffffff; 4249117395Skan image_hi = (image_hi >> (64 - 56 + 1) >> 31) & 0xffffff; 4250117395Skan } 4251117395Skan else 4252117395Skan { 4253117395Skan image_hi = r->sig[SIGSZ-1]; 4254117395Skan image_lo = r->sig[SIGSZ-2]; 4255117395Skan image_lo = (image_lo >> 8) | (image_hi << 24); 4256117395Skan image_hi >>= 8; 4257117395Skan } 425818334Speter 4259169689Skan exp = ((REAL_EXP (r) / 4) + 64) << 24; 4260117395Skan image_hi |= sign | exp; 4261117395Skan break; 426218334Speter 4263117395Skan default: 4264169689Skan gcc_unreachable (); 4265117395Skan } 426618334Speter 4267117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 4268117395Skan buf[0] = image_hi, buf[1] = image_lo; 426918334Speter else 4270117395Skan buf[0] = image_lo, buf[1] = image_hi; 427118334Speter} 427218334Speter 427318334Speterstatic void 4274132718Skandecode_i370_double (const struct real_format *fmt ATTRIBUTE_UNUSED, 4275132718Skan REAL_VALUE_TYPE *r, const long *buf) 427618334Speter{ 4277117395Skan unsigned long sign, image_hi, image_lo; 4278117395Skan int exp; 427918334Speter 4280117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 4281117395Skan image_hi = buf[0], image_lo = buf[1]; 428218334Speter else 4283117395Skan image_lo = buf[0], image_hi = buf[1]; 428418334Speter 4285117395Skan sign = (image_hi >> 31) & 1; 4286117395Skan exp = (image_hi >> 24) & 0x7f; 4287117395Skan image_hi &= 0xffffff; 4288117395Skan image_lo &= 0xffffffff; 428918334Speter 4290117395Skan memset (r, 0, sizeof (*r)); 429118334Speter 4292117395Skan if (exp || image_hi || image_lo) 429318334Speter { 4294169689Skan r->cl = rvc_normal; 4295117395Skan r->sign = sign; 4296169689Skan SET_REAL_EXP (r, (exp - 64) * 4 + (SIGNIFICAND_BITS - 56)); 4297117395Skan 4298117395Skan if (HOST_BITS_PER_LONG == 32) 429918334Speter { 4300117395Skan r->sig[0] = image_lo; 4301117395Skan r->sig[1] = image_hi; 430218334Speter } 4303117395Skan else 4304117395Skan r->sig[0] = image_lo | (image_hi << 31 << 1); 4305117395Skan 4306117395Skan normalize (r); 430718334Speter } 430818334Speter} 430918334Speter 4310117395Skanconst struct real_format i370_single_format = 4311117395Skan { 4312117395Skan encode_i370_single, 4313117395Skan decode_i370_single, 4314117395Skan 16, 4315117395Skan 4, 4316117395Skan 6, 4317132718Skan 6, 4318117395Skan -64, 4319117395Skan 63, 4320132718Skan 31, 4321169689Skan 31, 4322117395Skan false, 4323117395Skan false, 4324117395Skan false, /* ??? The encoding does allow for "unnormals". */ 4325117395Skan false, /* ??? The encoding does allow for "unnormals". */ 4326117395Skan false 4327117395Skan }; 432818334Speter 4329117395Skanconst struct real_format i370_double_format = 4330117395Skan { 4331117395Skan encode_i370_double, 4332117395Skan decode_i370_double, 4333117395Skan 16, 4334117395Skan 4, 4335117395Skan 14, 4336132718Skan 14, 4337117395Skan -64, 4338117395Skan 63, 4339132718Skan 63, 4340169689Skan 63, 4341117395Skan false, 4342117395Skan false, 4343117395Skan false, /* ??? The encoding does allow for "unnormals". */ 4344117395Skan false, /* ??? The encoding does allow for "unnormals". */ 4345117395Skan false 4346117395Skan }; 4347117395Skan 4348169689Skan/* Encode real R into a single precision DFP value in BUF. */ 4349169689Skanstatic void 4350169689Skanencode_decimal_single (const struct real_format *fmt ATTRIBUTE_UNUSED, 4351169689Skan long *buf ATTRIBUTE_UNUSED, 4352169689Skan const REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED) 4353169689Skan{ 4354169689Skan encode_decimal32 (fmt, buf, r); 4355169689Skan} 4356169689Skan 4357169689Skan/* Decode a single precision DFP value in BUF into a real R. */ 4358169689Skanstatic void 4359169689Skandecode_decimal_single (const struct real_format *fmt ATTRIBUTE_UNUSED, 4360169689Skan REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED, 4361169689Skan const long *buf ATTRIBUTE_UNUSED) 4362169689Skan{ 4363169689Skan decode_decimal32 (fmt, r, buf); 4364169689Skan} 4365169689Skan 4366169689Skan/* Encode real R into a double precision DFP value in BUF. */ 4367169689Skanstatic void 4368169689Skanencode_decimal_double (const struct real_format *fmt ATTRIBUTE_UNUSED, 4369169689Skan long *buf ATTRIBUTE_UNUSED, 4370169689Skan const REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED) 4371169689Skan{ 4372169689Skan encode_decimal64 (fmt, buf, r); 4373169689Skan} 4374169689Skan 4375169689Skan/* Decode a double precision DFP value in BUF into a real R. */ 4376169689Skanstatic void 4377169689Skandecode_decimal_double (const struct real_format *fmt ATTRIBUTE_UNUSED, 4378169689Skan REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED, 4379169689Skan const long *buf ATTRIBUTE_UNUSED) 4380169689Skan{ 4381169689Skan decode_decimal64 (fmt, r, buf); 4382169689Skan} 4383169689Skan 4384169689Skan/* Encode real R into a quad precision DFP value in BUF. */ 4385169689Skanstatic void 4386169689Skanencode_decimal_quad (const struct real_format *fmt ATTRIBUTE_UNUSED, 4387169689Skan long *buf ATTRIBUTE_UNUSED, 4388169689Skan const REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED) 4389169689Skan{ 4390169689Skan encode_decimal128 (fmt, buf, r); 4391169689Skan} 4392169689Skan 4393169689Skan/* Decode a quad precision DFP value in BUF into a real R. */ 4394169689Skanstatic void 4395169689Skandecode_decimal_quad (const struct real_format *fmt ATTRIBUTE_UNUSED, 4396169689Skan REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED, 4397169689Skan const long *buf ATTRIBUTE_UNUSED) 4398169689Skan{ 4399169689Skan decode_decimal128 (fmt, r, buf); 4400169689Skan} 4401169689Skan 4402169689Skan/* Single precision decimal floating point (IEEE 754R). */ 4403169689Skanconst struct real_format decimal_single_format = 4404169689Skan { 4405169689Skan encode_decimal_single, 4406169689Skan decode_decimal_single, 4407169689Skan 10, 4408169689Skan 1, /* log10 */ 4409169689Skan 7, 4410169689Skan 7, 4411169689Skan -95, 4412169689Skan 96, 4413169689Skan 31, 4414169689Skan 31, 4415169689Skan true, 4416169689Skan true, 4417169689Skan true, 4418169689Skan true, 4419169689Skan true 4420169689Skan }; 4421169689Skan 4422169689Skan/* Double precision decimal floating point (IEEE 754R). */ 4423169689Skanconst struct real_format decimal_double_format = 4424169689Skan { 4425169689Skan encode_decimal_double, 4426169689Skan decode_decimal_double, 4427169689Skan 10, 4428169689Skan 1, /* log10 */ 4429169689Skan 16, 4430169689Skan 16, 4431169689Skan -383, 4432169689Skan 384, 4433169689Skan 63, 4434169689Skan 63, 4435169689Skan true, 4436169689Skan true, 4437169689Skan true, 4438169689Skan true, 4439169689Skan true 4440169689Skan }; 4441169689Skan 4442169689Skan/* Quad precision decimal floating point (IEEE 754R). */ 4443169689Skanconst struct real_format decimal_quad_format = 4444169689Skan { 4445169689Skan encode_decimal_quad, 4446169689Skan decode_decimal_quad, 4447169689Skan 10, 4448169689Skan 1, /* log10 */ 4449169689Skan 34, 4450169689Skan 34, 4451169689Skan -6143, 4452169689Skan 6144, 4453169689Skan 127, 4454169689Skan 127, 4455169689Skan true, 4456169689Skan true, 4457169689Skan true, 4458169689Skan true, 4459169689Skan true 4460169689Skan }; 4461169689Skan 4462117395Skan/* The "twos-complement" c4x format is officially defined as 446318334Speter 4464117395Skan x = s(~s).f * 2**e 4465117395Skan 4466117395Skan This is rather misleading. One must remember that F is signed. 4467117395Skan A better description would be 4468117395Skan 4469117395Skan x = -1**s * ((s + 1 + .f) * 2**e 4470117395Skan 4471117395Skan So if we have a (4 bit) fraction of .1000 with a sign bit of 1, 4472117395Skan that's -1 * (1+1+(-.5)) == -1.5. I think. 4473117395Skan 4474117395Skan The constructions here are taken from Tables 5-1 and 5-2 of the 4475117395Skan TMS320C4x User's Guide wherein step-by-step instructions for 4476117395Skan conversion from IEEE are presented. That's close enough to our 4477117395Skan internal representation so as to make things easy. 4478117395Skan 4479117395Skan See http://www-s.ti.com/sc/psheets/spru063c/spru063c.pdf */ 4480117395Skan 4481132718Skanstatic void encode_c4x_single (const struct real_format *fmt, 4482132718Skan long *, const REAL_VALUE_TYPE *); 4483132718Skanstatic void decode_c4x_single (const struct real_format *, 4484132718Skan REAL_VALUE_TYPE *, const long *); 4485132718Skanstatic void encode_c4x_extended (const struct real_format *fmt, 4486132718Skan long *, const REAL_VALUE_TYPE *); 4487132718Skanstatic void decode_c4x_extended (const struct real_format *, 4488132718Skan REAL_VALUE_TYPE *, const long *); 4489117395Skan 449052284Sobrienstatic void 4491132718Skanencode_c4x_single (const struct real_format *fmt ATTRIBUTE_UNUSED, 4492132718Skan long *buf, const REAL_VALUE_TYPE *r) 449318334Speter{ 4494117395Skan unsigned long image, exp, sig; 4495132718Skan 4496169689Skan switch (r->cl) 4497117395Skan { 4498117395Skan case rvc_zero: 4499117395Skan exp = -128; 4500117395Skan sig = 0; 4501117395Skan break; 450218334Speter 4503117395Skan case rvc_inf: 4504117395Skan case rvc_nan: 4505117395Skan exp = 127; 4506117395Skan sig = 0x800000 - r->sign; 4507117395Skan break; 4508117395Skan 4509117395Skan case rvc_normal: 4510169689Skan exp = REAL_EXP (r) - 1; 4511117395Skan sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff; 4512117395Skan if (r->sign) 451318334Speter { 4514117395Skan if (sig) 4515117395Skan sig = -sig; 451618334Speter else 4517117395Skan exp--; 4518117395Skan sig |= 0x800000; 451918334Speter } 4520117395Skan break; 4521117395Skan 4522117395Skan default: 4523169689Skan gcc_unreachable (); 452418334Speter } 452518334Speter 4526117395Skan image = ((exp & 0xff) << 24) | (sig & 0xffffff); 4527117395Skan buf[0] = image; 452818334Speter} 452918334Speter 453052284Sobrienstatic void 4531132718Skandecode_c4x_single (const struct real_format *fmt ATTRIBUTE_UNUSED, 4532132718Skan REAL_VALUE_TYPE *r, const long *buf) 453318334Speter{ 4534117395Skan unsigned long image = buf[0]; 4535117395Skan unsigned long sig; 4536117395Skan int exp, sf; 453718334Speter 4538117395Skan exp = (((image >> 24) & 0xff) ^ 0x80) - 0x80; 4539117395Skan sf = ((image & 0xffffff) ^ 0x800000) - 0x800000; 4540117395Skan 4541117395Skan memset (r, 0, sizeof (*r)); 4542117395Skan 4543117395Skan if (exp != -128) 454418334Speter { 4545169689Skan r->cl = rvc_normal; 4546117395Skan 4547117395Skan sig = sf & 0x7fffff; 4548117395Skan if (sf < 0) 454918334Speter { 4550117395Skan r->sign = 1; 4551117395Skan if (sig) 4552117395Skan sig = -sig; 455318334Speter else 4554117395Skan exp++; 455518334Speter } 4556117395Skan sig = (sig << (HOST_BITS_PER_LONG - 24)) | SIG_MSB; 4557117395Skan 4558169689Skan SET_REAL_EXP (r, exp + 1); 4559117395Skan r->sig[SIGSZ-1] = sig; 456018334Speter } 4561117395Skan} 4562117395Skan 4563117395Skanstatic void 4564132718Skanencode_c4x_extended (const struct real_format *fmt ATTRIBUTE_UNUSED, 4565132718Skan long *buf, const REAL_VALUE_TYPE *r) 4566117395Skan{ 4567117395Skan unsigned long exp, sig; 4568132718Skan 4569169689Skan switch (r->cl) 457018334Speter { 4571117395Skan case rvc_zero: 4572117395Skan exp = -128; 4573117395Skan sig = 0; 4574117395Skan break; 457518334Speter 4576117395Skan case rvc_inf: 4577117395Skan case rvc_nan: 4578117395Skan exp = 127; 4579117395Skan sig = 0x80000000 - r->sign; 4580117395Skan break; 4581117395Skan 4582117395Skan case rvc_normal: 4583169689Skan exp = REAL_EXP (r) - 1; 4584117395Skan 4585117395Skan sig = r->sig[SIGSZ-1]; 4586117395Skan if (HOST_BITS_PER_LONG == 64) 4587117395Skan sig = sig >> 1 >> 31; 4588117395Skan sig &= 0x7fffffff; 4589117395Skan 4590117395Skan if (r->sign) 459118334Speter { 4592117395Skan if (sig) 4593117395Skan sig = -sig; 459418334Speter else 4595117395Skan exp--; 4596117395Skan sig |= 0x80000000; 459718334Speter } 4598117395Skan break; 4599117395Skan 4600117395Skan default: 4601169689Skan gcc_unreachable (); 460218334Speter } 460318334Speter 4604117395Skan exp = (exp & 0xff) << 24; 4605117395Skan sig &= 0xffffffff; 460618334Speter 4607117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 4608117395Skan buf[0] = exp, buf[1] = sig; 4609117395Skan else 4610117395Skan buf[0] = sig, buf[0] = exp; 4611117395Skan} 461218334Speter 461352284Sobrienstatic void 4614132718Skandecode_c4x_extended (const struct real_format *fmt ATTRIBUTE_UNUSED, 4615132718Skan REAL_VALUE_TYPE *r, const long *buf) 461618334Speter{ 4617117395Skan unsigned long sig; 4618117395Skan int exp, sf; 461918334Speter 4620117395Skan if (FLOAT_WORDS_BIG_ENDIAN) 4621117395Skan exp = buf[0], sf = buf[1]; 4622117395Skan else 4623117395Skan sf = buf[0], exp = buf[1]; 462418334Speter 4625117395Skan exp = (((exp >> 24) & 0xff) & 0x80) - 0x80; 4626117395Skan sf = ((sf & 0xffffffff) ^ 0x80000000) - 0x80000000; 462718334Speter 4628117395Skan memset (r, 0, sizeof (*r)); 462918334Speter 4630117395Skan if (exp != -128) 463118334Speter { 4632169689Skan r->cl = rvc_normal; 463318334Speter 4634117395Skan sig = sf & 0x7fffffff; 4635117395Skan if (sf < 0) 463618334Speter { 4637117395Skan r->sign = 1; 4638117395Skan if (sig) 4639117395Skan sig = -sig; 4640117395Skan else 4641117395Skan exp++; 464218334Speter } 4643117395Skan if (HOST_BITS_PER_LONG == 64) 4644117395Skan sig = sig << 1 << 31; 4645117395Skan sig |= SIG_MSB; 4646117395Skan 4647169689Skan SET_REAL_EXP (r, exp + 1); 4648117395Skan r->sig[SIGSZ-1] = sig; 464918334Speter } 4650117395Skan} 465118334Speter 4652132718Skanconst struct real_format c4x_single_format = 4653117395Skan { 4654117395Skan encode_c4x_single, 4655117395Skan decode_c4x_single, 4656117395Skan 2, 4657117395Skan 1, 4658117395Skan 24, 4659132718Skan 24, 4660117395Skan -126, 4661117395Skan 128, 4662169689Skan 23, 4663132718Skan -1, 4664117395Skan false, 4665117395Skan false, 4666117395Skan false, 4667117395Skan false, 4668117395Skan false 4669117395Skan }; 467018334Speter 4671132718Skanconst struct real_format c4x_extended_format = 4672117395Skan { 4673117395Skan encode_c4x_extended, 4674117395Skan decode_c4x_extended, 4675117395Skan 2, 4676117395Skan 1, 4677117395Skan 32, 4678132718Skan 32, 4679117395Skan -126, 4680117395Skan 128, 4681169689Skan 31, 4682132718Skan -1, 4683117395Skan false, 4684117395Skan false, 4685117395Skan false, 4686117395Skan false, 4687117395Skan false 4688117395Skan }; 468918334Speter 469018334Speter 4691117395Skan/* A synthetic "format" for internal arithmetic. It's the size of the 4692117395Skan internal significand minus the two bits needed for proper rounding. 4693117395Skan The encode and decode routines exist only to satisfy our paranoia 4694117395Skan harness. */ 469518334Speter 4696132718Skanstatic void encode_internal (const struct real_format *fmt, 4697132718Skan long *, const REAL_VALUE_TYPE *); 4698132718Skanstatic void decode_internal (const struct real_format *, 4699132718Skan REAL_VALUE_TYPE *, const long *); 4700117395Skan 4701117395Skanstatic void 4702132718Skanencode_internal (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf, 4703132718Skan const REAL_VALUE_TYPE *r) 470418334Speter{ 4705117395Skan memcpy (buf, r, sizeof (*r)); 4706117395Skan} 470718334Speter 4708117395Skanstatic void 4709132718Skandecode_internal (const struct real_format *fmt ATTRIBUTE_UNUSED, 4710132718Skan REAL_VALUE_TYPE *r, const long *buf) 4711117395Skan{ 4712117395Skan memcpy (r, buf, sizeof (*r)); 4713117395Skan} 471450397Sobrien 4715132718Skanconst struct real_format real_internal_format = 471618334Speter { 4717117395Skan encode_internal, 4718117395Skan decode_internal, 4719117395Skan 2, 4720117395Skan 1, 4721117395Skan SIGNIFICAND_BITS - 2, 4722132718Skan SIGNIFICAND_BITS - 2, 4723117395Skan -MAX_EXP, 4724117395Skan MAX_EXP, 4725132718Skan -1, 4726169689Skan -1, 4727117395Skan true, 4728117395Skan true, 4729117395Skan false, 4730117395Skan true, 4731132718Skan true 4732117395Skan }; 4733117395Skan 4734132718Skan/* Calculate the square root of X in mode MODE, and store the result 4735132718Skan in R. Return TRUE if the operation does not raise an exception. 4736132718Skan For details see "High Precision Division and Square Root", 4737132718Skan Alan H. Karp and Peter Markstein, HP Lab Report 93-93-42, June 4738132718Skan 1993. http://www.hpl.hp.com/techreports/93/HPL-93-42.pdf. */ 473952284Sobrien 4740132718Skanbool 4741132718Skanreal_sqrt (REAL_VALUE_TYPE *r, enum machine_mode mode, 4742132718Skan const REAL_VALUE_TYPE *x) 4743117395Skan{ 4744132718Skan static REAL_VALUE_TYPE halfthree; 4745132718Skan static bool init = false; 4746132718Skan REAL_VALUE_TYPE h, t, i; 4747132718Skan int iter, exp; 474850397Sobrien 4749132718Skan /* sqrt(-0.0) is -0.0. */ 4750132718Skan if (real_isnegzero (x)) 4751132718Skan { 4752132718Skan *r = *x; 4753132718Skan return false; 4754132718Skan } 4755132718Skan 4756132718Skan /* Negative arguments return NaN. */ 4757132718Skan if (real_isneg (x)) 4758132718Skan { 4759132718Skan get_canonical_qnan (r, 0); 4760132718Skan return false; 4761132718Skan } 4762132718Skan 4763132718Skan /* Infinity and NaN return themselves. */ 4764132718Skan if (real_isinf (x) || real_isnan (x)) 4765132718Skan { 4766132718Skan *r = *x; 4767132718Skan return false; 4768132718Skan } 4769132718Skan 4770132718Skan if (!init) 4771132718Skan { 4772132718Skan do_add (&halfthree, &dconst1, &dconsthalf, 0); 4773132718Skan init = true; 4774132718Skan } 4775132718Skan 4776132718Skan /* Initial guess for reciprocal sqrt, i. */ 4777132718Skan exp = real_exponent (x); 4778132718Skan real_ldexp (&i, &dconst1, -exp/2); 4779132718Skan 4780132718Skan /* Newton's iteration for reciprocal sqrt, i. */ 4781132718Skan for (iter = 0; iter < 16; iter++) 4782132718Skan { 4783132718Skan /* i(n+1) = i(n) * (1.5 - 0.5*i(n)*i(n)*x). */ 4784132718Skan do_multiply (&t, x, &i); 4785132718Skan do_multiply (&h, &t, &i); 4786132718Skan do_multiply (&t, &h, &dconsthalf); 4787132718Skan do_add (&h, &halfthree, &t, 1); 4788132718Skan do_multiply (&t, &i, &h); 4789132718Skan 4790132718Skan /* Check for early convergence. */ 4791132718Skan if (iter >= 6 && real_identical (&i, &t)) 4792132718Skan break; 4793132718Skan 4794132718Skan /* ??? Unroll loop to avoid copying. */ 4795132718Skan i = t; 4796132718Skan } 4797132718Skan 4798132718Skan /* Final iteration: r = i*x + 0.5*i*x*(1.0 - i*(i*x)). */ 4799132718Skan do_multiply (&t, x, &i); 4800132718Skan do_multiply (&h, &t, &i); 4801132718Skan do_add (&i, &dconst1, &h, 1); 4802132718Skan do_multiply (&h, &t, &i); 4803132718Skan do_multiply (&i, &dconsthalf, &h); 4804132718Skan do_add (&h, &t, &i, 0); 4805132718Skan 4806132718Skan /* ??? We need a Tuckerman test to get the last bit. */ 4807132718Skan 4808132718Skan real_convert (r, mode, &h); 4809132718Skan return true; 4810132718Skan} 4811132718Skan 4812132718Skan/* Calculate X raised to the integer exponent N in mode MODE and store 4813132718Skan the result in R. Return true if the result may be inexact due to 4814132718Skan loss of precision. The algorithm is the classic "left-to-right binary 4815132718Skan method" described in section 4.6.3 of Donald Knuth's "Seminumerical 4816132718Skan Algorithms", "The Art of Computer Programming", Volume 2. */ 4817132718Skan 4818132718Skanbool 4819132718Skanreal_powi (REAL_VALUE_TYPE *r, enum machine_mode mode, 4820132718Skan const REAL_VALUE_TYPE *x, HOST_WIDE_INT n) 4821132718Skan{ 4822132718Skan unsigned HOST_WIDE_INT bit; 4823132718Skan REAL_VALUE_TYPE t; 4824132718Skan bool inexact = false; 4825132718Skan bool init = false; 4826132718Skan bool neg; 4827132718Skan int i; 4828132718Skan 4829132718Skan if (n == 0) 4830132718Skan { 4831132718Skan *r = dconst1; 4832132718Skan return false; 4833132718Skan } 4834132718Skan else if (n < 0) 4835132718Skan { 4836132718Skan /* Don't worry about overflow, from now on n is unsigned. */ 4837132718Skan neg = true; 4838132718Skan n = -n; 4839132718Skan } 4840132718Skan else 4841132718Skan neg = false; 4842132718Skan 4843132718Skan t = *x; 4844132718Skan bit = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1); 4845132718Skan for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++) 4846132718Skan { 4847132718Skan if (init) 4848132718Skan { 4849132718Skan inexact |= do_multiply (&t, &t, &t); 4850132718Skan if (n & bit) 4851132718Skan inexact |= do_multiply (&t, &t, x); 4852132718Skan } 4853132718Skan else if (n & bit) 4854132718Skan init = true; 4855132718Skan bit >>= 1; 4856132718Skan } 4857132718Skan 4858132718Skan if (neg) 4859132718Skan inexact |= do_divide (&t, &dconst1, &t); 4860132718Skan 4861132718Skan real_convert (r, mode, &t); 4862132718Skan return inexact; 4863132718Skan} 4864132718Skan 4865132718Skan/* Round X to the nearest integer not larger in absolute value, i.e. 4866132718Skan towards zero, placing the result in R in mode MODE. */ 4867132718Skan 4868132718Skanvoid 4869132718Skanreal_trunc (REAL_VALUE_TYPE *r, enum machine_mode mode, 4870132718Skan const REAL_VALUE_TYPE *x) 4871132718Skan{ 4872132718Skan do_fix_trunc (r, x); 4873132718Skan if (mode != VOIDmode) 4874132718Skan real_convert (r, mode, r); 4875132718Skan} 4876132718Skan 4877132718Skan/* Round X to the largest integer not greater in value, i.e. round 4878132718Skan down, placing the result in R in mode MODE. */ 4879132718Skan 4880132718Skanvoid 4881132718Skanreal_floor (REAL_VALUE_TYPE *r, enum machine_mode mode, 4882132718Skan const REAL_VALUE_TYPE *x) 4883132718Skan{ 4884169689Skan REAL_VALUE_TYPE t; 4885169689Skan 4886169689Skan do_fix_trunc (&t, x); 4887169689Skan if (! real_identical (&t, x) && x->sign) 4888169689Skan do_add (&t, &t, &dconstm1, 0); 4889132718Skan if (mode != VOIDmode) 4890169689Skan real_convert (r, mode, &t); 4891169689Skan else 4892169689Skan *r = t; 4893132718Skan} 4894132718Skan 4895132718Skan/* Round X to the smallest integer not less then argument, i.e. round 4896132718Skan up, placing the result in R in mode MODE. */ 4897132718Skan 4898132718Skanvoid 4899132718Skanreal_ceil (REAL_VALUE_TYPE *r, enum machine_mode mode, 4900132718Skan const REAL_VALUE_TYPE *x) 4901132718Skan{ 4902169689Skan REAL_VALUE_TYPE t; 4903169689Skan 4904169689Skan do_fix_trunc (&t, x); 4905169689Skan if (! real_identical (&t, x) && ! x->sign) 4906169689Skan do_add (&t, &t, &dconst1, 0); 4907132718Skan if (mode != VOIDmode) 4908169689Skan real_convert (r, mode, &t); 4909169689Skan else 4910169689Skan *r = t; 4911169689Skan} 4912169689Skan 4913169689Skan/* Round X to the nearest integer, but round halfway cases away from 4914169689Skan zero. */ 4915169689Skan 4916169689Skanvoid 4917169689Skanreal_round (REAL_VALUE_TYPE *r, enum machine_mode mode, 4918169689Skan const REAL_VALUE_TYPE *x) 4919169689Skan{ 4920169689Skan do_add (r, x, &dconsthalf, x->sign); 4921169689Skan do_fix_trunc (r, r); 4922169689Skan if (mode != VOIDmode) 4923132718Skan real_convert (r, mode, r); 4924132718Skan} 4925169689Skan 4926169689Skan/* Set the sign of R to the sign of X. */ 4927169689Skan 4928169689Skanvoid 4929169689Skanreal_copysign (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *x) 4930169689Skan{ 4931169689Skan r->sign = x->sign; 4932169689Skan} 4933169689Skan 4934