150397Sobrien/* Definitions of floating-point access for GNU compiler. 2132718Skan Copyright (C) 1989, 1991, 1994, 1996, 1997, 1998, 1999, 3169689Skan 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 418334Speter 5117395Skan This file is part of GCC. 618334Speter 7117395Skan GCC is free software; you can redistribute it and/or modify it under 8117395Skan the terms of the GNU General Public License as published by the Free 9117395Skan Software Foundation; either version 2, or (at your option) any later 10117395Skan version. 1118334Speter 12117395Skan GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13117395Skan WARRANTY; without even the implied warranty of MERCHANTABILITY or 14117395Skan FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15117395Skan for more details. 1618334Speter 17117395Skan You should have received a copy of the GNU General Public License 18117395Skan along with GCC; see the file COPYING. If not, write to the Free 19169689Skan Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan 02110-1301, USA. */ 2118334Speter 2290075Sobrien#ifndef GCC_REAL_H 2390075Sobrien#define GCC_REAL_H 2418334Speter 25117395Skan#include "machmode.h" 2618334Speter 27117395Skan/* An expanded form of the represented number. */ 2818334Speter 29117395Skan/* Enumerate the special cases of numbers that we encounter. */ 30117395Skanenum real_value_class { 31117395Skan rvc_zero, 32117395Skan rvc_normal, 33117395Skan rvc_inf, 34117395Skan rvc_nan 35117395Skan}; 3618334Speter 37117395Skan#define SIGNIFICAND_BITS (128 + HOST_BITS_PER_LONG) 38169689Skan#define EXP_BITS (32 - 6) 39117395Skan#define MAX_EXP ((1 << (EXP_BITS - 1)) - 1) 40117395Skan#define SIGSZ (SIGNIFICAND_BITS / HOST_BITS_PER_LONG) 41117395Skan#define SIG_MSB ((unsigned long)1 << (HOST_BITS_PER_LONG - 1)) 4218334Speter 43117395Skanstruct real_value GTY(()) 44117395Skan{ 45169689Skan /* Use the same underlying type for all bit-fields, so as to make 46169689Skan sure they're packed together, otherwise REAL_VALUE_TYPE_SIZE will 47169689Skan be miscomputed. */ 48169689Skan unsigned int /* ENUM_BITFIELD (real_value_class) */ cl : 2; 49169689Skan unsigned int decimal : 1; 50117395Skan unsigned int sign : 1; 51132718Skan unsigned int signalling : 1; 52132718Skan unsigned int canonical : 1; 53169689Skan unsigned int uexp : EXP_BITS; 54117395Skan unsigned long sig[SIGSZ]; 55117395Skan}; 5690075Sobrien 57169689Skan#define REAL_EXP(REAL) \ 58169689Skan ((int)((REAL)->uexp ^ (unsigned int)(1 << (EXP_BITS - 1))) \ 59169689Skan - (1 << (EXP_BITS - 1))) 60169689Skan#define SET_REAL_EXP(REAL, EXP) \ 61169689Skan ((REAL)->uexp = ((unsigned int)(EXP) & (unsigned int)((1 << EXP_BITS) - 1))) 62169689Skan 63117395Skan/* Various headers condition prototypes on #ifdef REAL_VALUE_TYPE, so it 64117395Skan needs to be a macro. We do need to continue to have a structure tag 65117395Skan so that other headers can forward declare it. */ 66117395Skan#define REAL_VALUE_TYPE struct real_value 6718334Speter 68117395Skan/* We store a REAL_VALUE_TYPE into an rtx, and we do this by putting it in 69117395Skan consecutive "w" slots. Moreover, we've got to compute the number of "w" 70117395Skan slots at preprocessor time, which means we can't use sizeof. Guess. */ 7118334Speter 72117395Skan#define REAL_VALUE_TYPE_SIZE (SIGNIFICAND_BITS + 32) 73117395Skan#define REAL_WIDTH \ 74117395Skan (REAL_VALUE_TYPE_SIZE/HOST_BITS_PER_WIDE_INT \ 75117395Skan + (REAL_VALUE_TYPE_SIZE%HOST_BITS_PER_WIDE_INT ? 1 : 0)) /* round up */ 7618334Speter 77117395Skan/* Verify the guess. */ 78117395Skanextern char test_real_width 79117395Skan [sizeof(REAL_VALUE_TYPE) <= REAL_WIDTH*sizeof(HOST_WIDE_INT) ? 1 : -1]; 80117395Skan 81117395Skan/* Calculate the format for CONST_DOUBLE. We need as many slots as 82117395Skan are necessary to overlay a REAL_VALUE_TYPE on them. This could be 83117395Skan as many as four (32-bit HOST_WIDE_INT, 128-bit REAL_VALUE_TYPE). 84117395Skan 85117395Skan A number of places assume that there are always at least two 'w' 86117395Skan slots in a CONST_DOUBLE, so we provide them even if one would suffice. */ 87117395Skan 88117395Skan#if REAL_WIDTH == 1 89117395Skan# define CONST_DOUBLE_FORMAT "ww" 9018334Speter#else 91117395Skan# if REAL_WIDTH == 2 92117395Skan# define CONST_DOUBLE_FORMAT "ww" 93117395Skan# else 94117395Skan# if REAL_WIDTH == 3 95117395Skan# define CONST_DOUBLE_FORMAT "www" 96117395Skan# else 97117395Skan# if REAL_WIDTH == 4 98117395Skan# define CONST_DOUBLE_FORMAT "wwww" 99117395Skan# else 100117395Skan# if REAL_WIDTH == 5 101117395Skan# define CONST_DOUBLE_FORMAT "wwwww" 102117395Skan# else 103117395Skan# if REAL_WIDTH == 6 104117395Skan# define CONST_DOUBLE_FORMAT "wwwwww" 105117395Skan# else 106117395Skan #error "REAL_WIDTH > 6 not supported" 107117395Skan# endif 108117395Skan# endif 109117395Skan# endif 110117395Skan# endif 111117395Skan# endif 11218334Speter#endif 11318334Speter 11418334Speter 115117395Skan/* Describes the properties of the specific target format in use. */ 116117395Skanstruct real_format 117117395Skan{ 118117395Skan /* Move to and from the target bytes. */ 119132718Skan void (*encode) (const struct real_format *, long *, 120132718Skan const REAL_VALUE_TYPE *); 121132718Skan void (*decode) (const struct real_format *, REAL_VALUE_TYPE *, 122132718Skan const long *); 12318334Speter 124117395Skan /* The radix of the exponent and digits of the significand. */ 125117395Skan int b; 12618334Speter 127117395Skan /* log2(b). */ 128117395Skan int log2_b; 12918334Speter 130117395Skan /* Size of the significand in digits of radix B. */ 131117395Skan int p; 13218334Speter 133132718Skan /* Size of the significant of a NaN, in digits of radix B. */ 134132718Skan int pnan; 135132718Skan 136117395Skan /* The minimum negative integer, x, such that b**(x-1) is normalized. */ 137117395Skan int emin; 13818334Speter 139117395Skan /* The maximum integer, x, such that b**(x-1) is representable. */ 140117395Skan int emax; 14118334Speter 142169689Skan /* The bit position of the sign bit, for determining whether a value 143169689Skan is positive/negative, or -1 for a complex encoding. */ 144169689Skan int signbit_ro; 145132718Skan 146169689Skan /* The bit position of the sign bit, for changing the sign of a number, 147169689Skan or -1 for a complex encoding. */ 148169689Skan int signbit_rw; 149169689Skan 150117395Skan /* Properties of the format. */ 151117395Skan bool has_nans; 152117395Skan bool has_inf; 153117395Skan bool has_denorm; 154117395Skan bool has_signed_zero; 155117395Skan bool qnan_msb_set; 156117395Skan}; 15718334Speter 15818334Speter 159169689Skan/* The target format used for each floating point mode. 160169689Skan Float modes are followed by decimal float modes, with entries for 161169689Skan float modes indexed by (MODE - first float mode), and entries for 162169689Skan decimal float modes indexed by (MODE - first decimal float mode) + 163169689Skan the number of float modes. */ 164132718Skanextern const struct real_format * 165169689Skan real_format_for_mode[MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1 166169689Skan + MAX_MODE_DECIMAL_FLOAT - MIN_MODE_DECIMAL_FLOAT + 1]; 16718334Speter 168169689Skan#define REAL_MODE_FORMAT(MODE) \ 169169689Skan (real_format_for_mode[DECIMAL_FLOAT_MODE_P (MODE) \ 170169689Skan ? ((MODE - MIN_MODE_DECIMAL_FLOAT) \ 171169689Skan + (MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1)) \ 172169689Skan : (MODE - MIN_MODE_FLOAT)]) 173117395Skan 174169689Skan/* The following macro determines whether the floating point format is 175169689Skan composite, i.e. may contain non-consecutive mantissa bits, in which 176169689Skan case compile-time FP overflow may not model run-time overflow. */ 177169689Skan#define REAL_MODE_FORMAT_COMPOSITE_P(MODE) \ 178169689Skan ((REAL_MODE_FORMAT(MODE))->pnan < (REAL_MODE_FORMAT (MODE))->p) 179169689Skan 18090075Sobrien/* Declare functions in real.c. */ 18118334Speter 182117395Skan/* Binary or unary arithmetic on tree_code. */ 183169689Skanextern bool real_arithmetic (REAL_VALUE_TYPE *, int, const REAL_VALUE_TYPE *, 184132718Skan const REAL_VALUE_TYPE *); 18518334Speter 186117395Skan/* Compare reals by tree_code. */ 187132718Skanextern bool real_compare (int, const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); 18818334Speter 189117395Skan/* Determine whether a floating-point value X is infinite. */ 190132718Skanextern bool real_isinf (const REAL_VALUE_TYPE *); 19118334Speter 192117395Skan/* Determine whether a floating-point value X is a NaN. */ 193132718Skanextern bool real_isnan (const REAL_VALUE_TYPE *); 19418334Speter 195117395Skan/* Determine whether a floating-point value X is negative. */ 196132718Skanextern bool real_isneg (const REAL_VALUE_TYPE *); 19752284Sobrien 198117395Skan/* Determine whether a floating-point value X is minus zero. */ 199132718Skanextern bool real_isnegzero (const REAL_VALUE_TYPE *); 20018334Speter 201117395Skan/* Compare two floating-point objects for bitwise identity. */ 202132718Skanextern bool real_identical (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); 20318334Speter 204117395Skan/* Extend or truncate to a new mode. */ 205132718Skanextern void real_convert (REAL_VALUE_TYPE *, enum machine_mode, 206132718Skan const REAL_VALUE_TYPE *); 20718334Speter 208117395Skan/* Return true if truncating to NEW is exact. */ 209132718Skanextern bool exact_real_truncate (enum machine_mode, const REAL_VALUE_TYPE *); 21018334Speter 211117395Skan/* Render R as a decimal floating point constant. */ 212132718Skanextern void real_to_decimal (char *, const REAL_VALUE_TYPE *, size_t, 213132718Skan size_t, int); 21418334Speter 215117395Skan/* Render R as a hexadecimal floating point constant. */ 216132718Skanextern void real_to_hexadecimal (char *, const REAL_VALUE_TYPE *, 217132718Skan size_t, size_t, int); 21818334Speter 219117395Skan/* Render R as an integer. */ 220132718Skanextern HOST_WIDE_INT real_to_integer (const REAL_VALUE_TYPE *); 221132718Skanextern void real_to_integer2 (HOST_WIDE_INT *, HOST_WIDE_INT *, 222132718Skan const REAL_VALUE_TYPE *); 22318334Speter 224117395Skan/* Initialize R from a decimal or hexadecimal string. */ 225132718Skanextern void real_from_string (REAL_VALUE_TYPE *, const char *); 226169689Skan/* Wrapper to allow different internal representation for decimal floats. */ 227169689Skanextern void real_from_string3 (REAL_VALUE_TYPE *, const char *, enum machine_mode); 22850397Sobrien 229117395Skan/* Initialize R from an integer pair HIGH/LOW. */ 230132718Skanextern void real_from_integer (REAL_VALUE_TYPE *, enum machine_mode, 231132718Skan unsigned HOST_WIDE_INT, HOST_WIDE_INT, int); 23250397Sobrien 233132718Skanextern long real_to_target_fmt (long *, const REAL_VALUE_TYPE *, 234132718Skan const struct real_format *); 235132718Skanextern long real_to_target (long *, const REAL_VALUE_TYPE *, enum machine_mode); 23618334Speter 237132718Skanextern void real_from_target_fmt (REAL_VALUE_TYPE *, const long *, 238132718Skan const struct real_format *); 239132718Skanextern void real_from_target (REAL_VALUE_TYPE *, const long *, 240132718Skan enum machine_mode); 24118334Speter 242132718Skanextern void real_inf (REAL_VALUE_TYPE *); 24318334Speter 244132718Skanextern bool real_nan (REAL_VALUE_TYPE *, const char *, int, enum machine_mode); 24518334Speter 246132718Skanextern void real_maxval (REAL_VALUE_TYPE *, int, enum machine_mode); 24718334Speter 248132718Skanextern void real_2expN (REAL_VALUE_TYPE *, int); 24918334Speter 250132718Skanextern unsigned int real_hash (const REAL_VALUE_TYPE *); 25118334Speter 252132718Skan 253117395Skan/* Target formats defined in real.c. */ 254117395Skanextern const struct real_format ieee_single_format; 255132718Skanextern const struct real_format mips_single_format; 256117395Skanextern const struct real_format ieee_double_format; 257132718Skanextern const struct real_format mips_double_format; 258117395Skanextern const struct real_format ieee_extended_motorola_format; 259117395Skanextern const struct real_format ieee_extended_intel_96_format; 260117395Skanextern const struct real_format ieee_extended_intel_96_round_53_format; 261117395Skanextern const struct real_format ieee_extended_intel_128_format; 262117395Skanextern const struct real_format ibm_extended_format; 263132718Skanextern const struct real_format mips_extended_format; 264117395Skanextern const struct real_format ieee_quad_format; 265132718Skanextern const struct real_format mips_quad_format; 266117395Skanextern const struct real_format vax_f_format; 267117395Skanextern const struct real_format vax_d_format; 268117395Skanextern const struct real_format vax_g_format; 269117395Skanextern const struct real_format i370_single_format; 270117395Skanextern const struct real_format i370_double_format; 271117395Skanextern const struct real_format c4x_single_format; 272117395Skanextern const struct real_format c4x_extended_format; 273117395Skanextern const struct real_format real_internal_format; 274169689Skanextern const struct real_format decimal_single_format; 275169689Skanextern const struct real_format decimal_double_format; 276169689Skanextern const struct real_format decimal_quad_format; 27718334Speter 27818334Speter 279117395Skan/* ====================================================================== */ 280117395Skan/* Crap. */ 28118334Speter 282117395Skan#define REAL_ARITHMETIC(value, code, d1, d2) \ 283117395Skan real_arithmetic (&(value), code, &(d1), &(d2)) 28418334Speter 285117395Skan#define REAL_VALUES_IDENTICAL(x, y) real_identical (&(x), &(y)) 286117395Skan#define REAL_VALUES_EQUAL(x, y) real_compare (EQ_EXPR, &(x), &(y)) 287117395Skan#define REAL_VALUES_LESS(x, y) real_compare (LT_EXPR, &(x), &(y)) 28818334Speter 289117395Skan/* Determine whether a floating-point value X is infinite. */ 290117395Skan#define REAL_VALUE_ISINF(x) real_isinf (&(x)) 29118334Speter 292117395Skan/* Determine whether a floating-point value X is a NaN. */ 293117395Skan#define REAL_VALUE_ISNAN(x) real_isnan (&(x)) 29450397Sobrien 295117395Skan/* Determine whether a floating-point value X is negative. */ 296117395Skan#define REAL_VALUE_NEGATIVE(x) real_isneg (&(x)) 29718334Speter 298117395Skan/* Determine whether a floating-point value X is minus zero. */ 299117395Skan#define REAL_VALUE_MINUS_ZERO(x) real_isnegzero (&(x)) 30018334Speter 301117395Skan/* IN is a REAL_VALUE_TYPE. OUT is an array of longs. */ 302117395Skan#define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT) \ 303117395Skan real_to_target (OUT, &(IN), \ 304117395Skan mode_for_size (LONG_DOUBLE_TYPE_SIZE, MODE_FLOAT, 0)) 30518334Speter 306117395Skan#define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \ 307117395Skan real_to_target (OUT, &(IN), mode_for_size (64, MODE_FLOAT, 0)) 30818334Speter 309117395Skan/* IN is a REAL_VALUE_TYPE. OUT is a long. */ 310117395Skan#define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) \ 311117395Skan ((OUT) = real_to_target (NULL, &(IN), mode_for_size (32, MODE_FLOAT, 0))) 31218334Speter 313117395Skan#define REAL_VALUE_FROM_INT(r, lo, hi, mode) \ 314117395Skan real_from_integer (&(r), mode, lo, hi, 0) 31518334Speter 316117395Skan#define REAL_VALUE_FROM_UNSIGNED_INT(r, lo, hi, mode) \ 317117395Skan real_from_integer (&(r), mode, lo, hi, 1) 31818334Speter 319169689Skan/* Real values to IEEE 754R decimal floats. */ 320169689Skan 321169689Skan/* IN is a REAL_VALUE_TYPE. OUT is an array of longs. */ 322169689Skan#define REAL_VALUE_TO_TARGET_DECIMAL128(IN, OUT) \ 323169689Skan real_to_target (OUT, &(IN), mode_for_size (128, MODE_DECIMAL_FLOAT, 0)) 324169689Skan 325169689Skan#define REAL_VALUE_TO_TARGET_DECIMAL64(IN, OUT) \ 326169689Skan real_to_target (OUT, &(IN), mode_for_size (64, MODE_DECIMAL_FLOAT, 0)) 327169689Skan 328169689Skan/* IN is a REAL_VALUE_TYPE. OUT is a long. */ 329169689Skan#define REAL_VALUE_TO_TARGET_DECIMAL32(IN, OUT) \ 330169689Skan ((OUT) = real_to_target (NULL, &(IN), mode_for_size (32, MODE_DECIMAL_FLOAT, 0))) 331169689Skan 332132718Skanextern REAL_VALUE_TYPE real_value_truncate (enum machine_mode, 333132718Skan REAL_VALUE_TYPE); 33418334Speter 335117395Skan#define REAL_VALUE_TO_INT(plow, phigh, r) \ 336117395Skan real_to_integer2 (plow, phigh, &(r)) 33752284Sobrien 338132718Skanextern REAL_VALUE_TYPE real_arithmetic2 (int, const REAL_VALUE_TYPE *, 339132718Skan const REAL_VALUE_TYPE *); 34018334Speter 341117395Skan#define REAL_VALUE_NEGATE(X) \ 342117395Skan real_arithmetic2 (NEGATE_EXPR, &(X), NULL) 34318334Speter 344117395Skan#define REAL_VALUE_ABS(X) \ 345117395Skan real_arithmetic2 (ABS_EXPR, &(X), NULL) 34618334Speter 347132718Skanextern int significand_size (enum machine_mode); 34818334Speter 349132718Skanextern REAL_VALUE_TYPE real_from_string2 (const char *, enum machine_mode); 35018334Speter 351117395Skan#define REAL_VALUE_ATOF(s, m) \ 352117395Skan real_from_string2 (s, m) 35318334Speter 354117395Skan#define CONST_DOUBLE_ATOF(s, m) \ 355117395Skan CONST_DOUBLE_FROM_REAL_VALUE (real_from_string2 (s, m), m) 35618334Speter 357117395Skan#define REAL_VALUE_FIX(r) \ 358117395Skan real_to_integer (&(r)) 359117395Skan 360117395Skan/* ??? Not quite right. */ 361117395Skan#define REAL_VALUE_UNSIGNED_FIX(r) \ 362117395Skan real_to_integer (&(r)) 363117395Skan 364117395Skan/* ??? These were added for Paranoia support. */ 365117395Skan 366117395Skan/* Return floor log2(R). */ 367132718Skanextern int real_exponent (const REAL_VALUE_TYPE *); 368117395Skan 369117395Skan/* R = A * 2**EXP. */ 370132718Skanextern void real_ldexp (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int); 371117395Skan 372117395Skan/* **** End of software floating point emulator interface macros **** */ 37318334Speter 374132718Skan/* Constant real values 0, 1, 2, 3, 10, -1, -2, 0.5 and 1/3. */ 37518334Speter 37618334Speterextern REAL_VALUE_TYPE dconst0; 37718334Speterextern REAL_VALUE_TYPE dconst1; 37818334Speterextern REAL_VALUE_TYPE dconst2; 379132718Skanextern REAL_VALUE_TYPE dconst3; 380132718Skanextern REAL_VALUE_TYPE dconst10; 38118334Speterextern REAL_VALUE_TYPE dconstm1; 382132718Skanextern REAL_VALUE_TYPE dconstm2; 383132718Skanextern REAL_VALUE_TYPE dconsthalf; 384132718Skanextern REAL_VALUE_TYPE dconstthird; 385132718Skanextern REAL_VALUE_TYPE dconstpi; 386132718Skanextern REAL_VALUE_TYPE dconste; 38718334Speter 38818334Speter/* Function to return a real value (not a tree node) 38918334Speter from a given integer constant. */ 390132718SkanREAL_VALUE_TYPE real_value_from_int_cst (tree, tree); 39118334Speter 392117395Skan/* Given a CONST_DOUBLE in FROM, store into TO the value it represents. */ 393117395Skan#define REAL_VALUE_FROM_CONST_DOUBLE(to, from) \ 394169689Skan ((to) = *CONST_DOUBLE_REAL_VALUE (from)) 39518334Speter 39618334Speter/* Return a CONST_DOUBLE with value R and mode M. */ 397117395Skan#define CONST_DOUBLE_FROM_REAL_VALUE(r, m) \ 398117395Skan const_double_from_real_value (r, m) 399132718Skanextern rtx const_double_from_real_value (REAL_VALUE_TYPE, enum machine_mode); 40018334Speter 401117395Skan/* Replace R by 1/R in the given machine mode, if the result is exact. */ 402132718Skanextern bool exact_real_inverse (enum machine_mode, REAL_VALUE_TYPE *); 40318334Speter 404117395Skan/* In tree.c: wrap up a REAL_VALUE_TYPE in a tree node. */ 405132718Skanextern tree build_real (tree, REAL_VALUE_TYPE); 40618334Speter 407132718Skan/* Calculate R as the square root of X in the given machine mode. */ 408132718Skanextern bool real_sqrt (REAL_VALUE_TYPE *, enum machine_mode, 409132718Skan const REAL_VALUE_TYPE *); 41018334Speter 411132718Skan/* Calculate R as X raised to the integer exponent N in mode MODE. */ 412132718Skanextern bool real_powi (REAL_VALUE_TYPE *, enum machine_mode, 413132718Skan const REAL_VALUE_TYPE *, HOST_WIDE_INT); 414132718Skan 415132718Skan/* Standard round to integer value functions. */ 416132718Skanextern void real_trunc (REAL_VALUE_TYPE *, enum machine_mode, 417132718Skan const REAL_VALUE_TYPE *); 418132718Skanextern void real_floor (REAL_VALUE_TYPE *, enum machine_mode, 419132718Skan const REAL_VALUE_TYPE *); 420132718Skanextern void real_ceil (REAL_VALUE_TYPE *, enum machine_mode, 421132718Skan const REAL_VALUE_TYPE *); 422169689Skanextern void real_round (REAL_VALUE_TYPE *, enum machine_mode, 423169689Skan const REAL_VALUE_TYPE *); 424132718Skan 425169689Skan/* Set the sign of R to the sign of X. */ 426169689Skanextern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); 427169689Skan 42890075Sobrien#endif /* ! GCC_REAL_H */ 429