From b216cd4ae3bd06a171b0b2db41d79d4b6f818008 Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Sat, 23 Mar 2002 01:10:56 +0000 Subject: real.h: Don't define REAL_INFINITY or REAL_IS_NOT_DOUBLE. * real.h: Don't define REAL_INFINITY or REAL_IS_NOT_DOUBLE. Always make REAL_VALUE_TYPE a struct containing an array of HOST_WIDE_INT, not a double. Tidy up the code deciding how big it is. Don't declare or use union real_extract. * emit-rtl.c (init_emit_once), varasm.c (immed_real_const_1, decode_rtx_const, output_constant_pool), config/a29k/a29k.c (print_operand), config/arm/arm.c (output_move_double), config/arm/arm.md (consttable_4, consttable_8), config/romp/romp.c (output_fpops), config/s390/s390.h (ASM_OUTPUT_SPECIAL_POOL_ENTRY), config/xtensa/xtensa.c (xtensa_output_literal): Don't use union real_extract. * config/dsp16xx/dsp16xx.c (print_operand), config/i860/i860.c (sfmode_constant_to_ulong), config/ns32k/merlin.h (PRINT_OPERAND), config/ns32k/ns32k.c (print_operand), config/pdp11/pdp11.h (PRINT_OPERAND), config/we32k/we32k.h (PRINT_OPERAND): Don't use local version of union real_extract. * config/convex/convex.c (check_float_value), config/vax/vax.c (vax_float_literal), config/m88k/m88k.md (divdf3), config/dsp16xx/dsp16xx.md (fixuns_trunchfhi2), config/pdp11/pdp11.c (output_move_quad): Don't do host arithmetic on target floating point quantities. * config/a29k/a29k.md, config/dsp16xx/dsp16xx.c (output_dsp16xx_float_const): Don't test HOST_FLOAT_FORMAT. * fold-const.c (fold), simplify-rtx.c (simplify_binary_real): Use MODE_HAS_INFINITIES rather than #ifdef REAL_INFINITY. * real.c (earith): Test INFINITY rather than REAL_INFINITY; NANS implies INFINITY, so can drop #ifdef NANS inside #ifndef INFINITY. * print-rtl.c (print_rtx): Disable code which needs floating-point emulator. * libgcc2.c: Include float.h and use DBL_MANT_DIG, FLT_MANT_DIG, to define DF_SIZE and SF_SIZE, rather than depending on HOST_FLOAT_FORMAT to be defined properly. * ch/grant.c, cp/error.c: Always use REAL_VALUE_TO_DECIMAL; don't test REAL_IS_NOT_DOUBLE. * config/1750a/1750a.c (get_double, float_label): Delete. (print_operand): Delete huge commented-out chunk. Use REAL_VALUE_TO_DECIMAL. * config/1750a/1750a-protos.h: Delete prototypes of deleted functions. * config/convex/convex.h: Always set TARGET_FLOAT_FORMAT to IEEE_FLOAT_FORMAT. * config/i370/i370.h (PRINT_OPERAND [TARGET_HLASM version]): Use REAL_VALUE_TO_DECIMAL as ELF version does. * config/m88k/m88k.c (real_power_of_2_operand, legitimize_operand): Take the REAL_VALUE_TYPE and/or union real_extract out of the union; run the input through REAL_VALUE_TO_TARGET_DOUBLE, then plug the pair of longwords from that into the union. * config/pdp11/pdp11.c (output_move_double): Rearrange parentheses to make automatic indenter happy. * doc/tm.texi (Cross-compilation): Rename node to "Floating Point" and rewrite to describe current situation. Also adjust documentation of REAL_VALUE_TO_TARGET_SINGLE and friends to match code. * doc/rtl.texi: Adjust cross reference. From-SVN: r51210 --- gcc/config/1750a/1750a-protos.h | 2 - gcc/config/1750a/1750a.c | 96 +++-------------------------------------- gcc/config/a29k/a29k.c | 31 +++++++------ gcc/config/a29k/a29k.md | 2 +- gcc/config/arm/arm.c | 6 +-- gcc/config/arm/arm.md | 12 +++--- gcc/config/convex/convex.c | 40 ++++++++--------- gcc/config/convex/convex.h | 5 +-- gcc/config/dsp16xx/dsp16xx.c | 21 ++++----- gcc/config/dsp16xx/dsp16xx.md | 2 +- gcc/config/i370/i370.h | 21 +++++---- gcc/config/i860/i860.c | 9 ++-- gcc/config/m88k/m88k.c | 14 +++--- gcc/config/m88k/m88k.md | 8 ++-- gcc/config/ns32k/merlin.h | 26 ++++++----- gcc/config/ns32k/ns32k.c | 38 ++++++++-------- gcc/config/pdp11/pdp11.c | 14 +++--- gcc/config/pdp11/pdp11.h | 8 ++-- gcc/config/romp/romp.c | 7 ++- gcc/config/s390/s390.h | 4 +- gcc/config/vax/vax.c | 23 +++++----- gcc/config/we32k/we32k.h | 11 +++-- gcc/config/xtensa/xtensa.c | 14 +++--- 23 files changed, 170 insertions(+), 244 deletions(-) (limited to 'gcc/config') diff --git a/gcc/config/1750a/1750a-protos.h b/gcc/config/1750a/1750a-protos.h index aa2b41f..c437f00 100644 --- a/gcc/config/1750a/1750a-protos.h +++ b/gcc/config/1750a/1750a-protos.h @@ -26,7 +26,6 @@ extern struct rtx_def *function_arg PARAMS ((int, enum machine_mode, tree, int)) extern const char *movcnt_regno_adjust PARAMS ((rtx *)); extern const char *mod_regno_adjust PARAMS ((const char *, rtx *)); extern void notice_update_cc PARAMS ((rtx)); -extern double get_double PARAMS ((rtx)); extern int memop_valid PARAMS ((rtx)); extern int mov_memory_operand PARAMS ((rtx, enum machine_mode)); extern int small_nonneg_const PARAMS ((rtx, enum machine_mode)); @@ -38,7 +37,6 @@ extern void print_operand PARAMS ((FILE *, rtx, int)); extern void print_operand_address PARAMS ((FILE *, rtx)); #endif /* RTX_CODE */ -extern char *float_label PARAMS ((int, double)); extern const char *branch_or_jump PARAMS ((const char *, int)); extern int find_jmplbl PARAMS ((int)); extern int one_bit_set_p PARAMS ((int)); diff --git a/gcc/config/1750a/1750a.c b/gcc/config/1750a/1750a.c index 099f7c7..c8b6a79 100644 --- a/gcc/config/1750a/1750a.c +++ b/gcc/config/1750a/1750a.c @@ -239,44 +239,6 @@ function_arg (cum, mode, type, named) return (rtx) 0; } - -double -get_double (x) - rtx x; -{ - union - { - double d; - long i[2]; - } - du; - - du.i[0] = CONST_DOUBLE_LOW (x); - du.i[1] = CONST_DOUBLE_HIGH (x); - return du.d; -} - -char * -float_label (code, value) - int code; - double value; -{ - static char label[32]; - char *p; - - label[0] = code; - p = label + 1; - sprintf (p, "%f", value); - while (*p) - { - *p = (*p == '+') ? 'p' : - (*p == '-') ? 'm' : *p; - p++; - } - return xstrdup (label); -} - - const char * movcnt_regno_adjust (op) rtx *op; @@ -588,59 +550,15 @@ print_operand (file, x, letter) break; case CONST_DOUBLE: -/* { - double value = get_double (x); - char fltstr[32]; - sprintf (fltstr, "%f", value); + { + REAL_VALUE_TYPE r; + char buf[30]; - if (letter == 'D' || letter == 'E') - { - int i, found = 0; - for (i = 0; i <= datalbl_ndx; i++) - if (strcmp (fltstr, datalbl[i].value) == 0) - { - found = 1; - break; - } - if (!found) - { - strcpy (datalbl[i = ++datalbl_ndx].value, fltstr); - datalbl[i].name = float_label (letter, value); - datalbl[i].size = (letter == 'E') ? 3 : 2; - check_section (Konst); - fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name, - (letter == 'E' ? "ef" : "f"), fltstr); - check_section (Normal); - } - } - else if (letter == 'F' || letter == 'G') - { - int i, found = 0; - for (i = 0; i <= datalbl_ndx; i++) - if (strcmp (fltstr, datalbl[i].value) == 0) - { - found = 1; - break; - } - if (!found) - { - fprintf (stderr, - "float value %f not found upon label reference\n", value); - strcpy (datalbl[i = ++datalbl_ndx].value, fltstr); - datalbl[i].name = float_label (letter, value); - datalbl[i].size = (letter == 'G') ? 3 : 2; - check_section (Konst); - fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name, - (letter == 'G' ? "ef" : "f"), fltstr); - check_section (Normal); - } - fprintf (file, "%s ;P_O 'F'", datalbl[i].name); - } - else - fprintf (file, " %s ;P_O cst_dbl ", fltstr); + REAL_VALUE_FROM_CONST_DOUBLE (r, x); + REAL_VALUE_TO_DECIMAL (r, "%f", buf); + + fputs (buf, file); } - */ - fprintf (file, "%f", get_double (x)); break; case CONST_INT: diff --git a/gcc/config/a29k/a29k.c b/gcc/config/a29k/a29k.c index 3291bab..bd08c38 100644 --- a/gcc/config/a29k/a29k.c +++ b/gcc/config/a29k/a29k.c @@ -1143,10 +1143,13 @@ print_operand (file, x, code) case 'L': if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode) { - union real_extract u; + REAL_VALUE_TYPE r; + char s[30]; - memcpy ((char *) &u, (char *) &CONST_DOUBLE_LOW (x), sizeof u); - fprintf (file, "$double1(%.20e)", u.d); + REAL_VALUE_FROM_CONST_DOUBLE (r, x); + REAL_VALUE_TO_DECIMAL (r, "%.20e", s); + + fprintf (file, "$double1(%s)", s); } else if (GET_CODE (x) == REG) fprintf (file, "%s", reg_names[REGNO (x) + 1]); @@ -1204,26 +1207,30 @@ print_operand (file, x, code) else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == SUBREG && GET_CODE (SUBREG_REG (XEXP (x, 0))) == CONST_DOUBLE) { - union real_extract u; + REAL_VALUE_TYPE r; + char s[30]; if (GET_MODE (SUBREG_REG (XEXP (x, 0))) == SFmode) fprintf (file, "$float"); else fprintf (file, "$double%d", - (SUBREG_BYTE (XEXP (x, 0)) / GET_MODE_SIZE (GET_MODE (x)))); - memcpy ((char *) &u, - (char *) &CONST_DOUBLE_LOW (SUBREG_REG (XEXP (x, 0))), sizeof u); - fprintf (file, "(%.20e)", u.d); + (SUBREG_BYTE (XEXP (x, 0)) / GET_MODE_SIZE (GET_MODE (x)))); + + REAL_VALUE_FROM_CONST_DOUBLE (r, x); + REAL_VALUE_TO_DECIMAL (r, "%.20e", s); + fprintf (file, "(%s)", s); } else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) { - union real_extract u; + REAL_VALUE_TYPE r; + char s[30]; - memcpy ((char *) &u, (char *) &CONST_DOUBLE_LOW (x), sizeof u); - fprintf (file, "$%s(%.20e)", - GET_MODE (x) == SFmode ? "float" : "double0", u.d); + REAL_VALUE_FROM_CONST_DOUBLE (r, x); + REAL_VALUE_TO_DECIMAL (r, "%.20e", s); + fprintf (file, "$%s(%s)", + GET_MODE (x) == SFmode ? "float" : "double0", s); } else diff --git a/gcc/config/a29k/a29k.md b/gcc/config/a29k/a29k.md index 596aa47..d4e4f34 100644 --- a/gcc/config/a29k/a29k.md +++ b/gcc/config/a29k/a29k.md @@ -2005,7 +2005,7 @@ (define_split [(set (match_operand:SF 0 "register_operand" "") (match_operand:SF 1 "float_const_operand" ""))] - "HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT" + "" [(set (match_dup 0) (match_dup 1))] " diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index f07a281..814c84d 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -6534,11 +6534,11 @@ output_move_double (operands) { if (GET_MODE (operands[1]) == DFmode) { + REAL_VALUE_TYPE r; long l[2]; - union real_extract u; - memcpy (&u, &CONST_DOUBLE_LOW (operands[1]), sizeof (u)); - REAL_VALUE_TO_TARGET_DOUBLE (u.d, l); + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + REAL_VALUE_TO_TARGET_DOUBLE (r, l); otherops[1] = GEN_INT (l[1]); operands[1] = GEN_INT (l[0]); } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index cdab5c6..9ea7d0c 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -9079,9 +9079,9 @@ { case MODE_FLOAT: { - union real_extract u; - memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u); - assemble_real (u.d, GET_MODE (operands[0]), BITS_PER_WORD); + REAL_VALUE_TYPE r; + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]); + assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD); break; } default: @@ -9103,9 +9103,9 @@ { case MODE_FLOAT: { - union real_extract u; - memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u); - assemble_real (u.d, GET_MODE (operands[0]), BITS_PER_WORD); + REAL_VALUE_TYPE r; + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]); + assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD); break; } default: diff --git a/gcc/config/convex/convex.c b/gcc/config/convex/convex.c index bee0f17..74af45e 100644 --- a/gcc/config/convex/convex.c +++ b/gcc/config/convex/convex.c @@ -515,12 +515,12 @@ expand_movstr_call (operands) TYPE_MODE (sizetype)); } -#if _IEEE_FLOAT_ -#define MAX_FLOAT 3.4028234663852886e+38 -#define MIN_FLOAT 1.1754943508222875e-38 +#if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT +#define MAX_FLOAT "3.4028234663852886e+38" +#define MIN_FLOAT "1.1754943508222875e-38" #else -#define MAX_FLOAT 1.7014117331926443e+38 -#define MIN_FLOAT 2.9387358770557188e-39 +#define MAX_FLOAT "1.7014117331926443e+38" +#define MIN_FLOAT "2.9387358770557188e-39" #endif int @@ -530,28 +530,35 @@ check_float_value (mode, dp, overflow) int overflow; { REAL_VALUE_TYPE d = *dp; + REAL_VALUE_TYPE maxfloat = REAL_VALUE_ATOF (MAX_FLOAT, mode); + REAL_VALUE_TYPE minfloat = REAL_VALUE_ATOF (MIN_FLOAT, mode); + REAL_VALUE_TYPE neg_maxfloat = REAL_VALUE_NEGATE (maxfloat); + REAL_VALUE_TYPE neg_minfloat = REAL_VALUE_NEGATE (minfloat); if (overflow) { - *dp = MAX_FLOAT; + *dp = maxfloat; return 1; } if (mode == SFmode) { - if (d > MAX_FLOAT) + if (REAL_VALUES_LESS (maxfloat, d)) { - *dp = MAX_FLOAT; + *dp = maxfloat; return 1; } - else if (d < -MAX_FLOAT) + else if (REAL_VALUES_LESS (d, neg_maxfloat)) { - *dp = -MAX_FLOAT; + *dp = neg_maxfloat; return 1; } - else if ((d > 0 && d < MIN_FLOAT) || (d < 0 && d > -MIN_FLOAT)) + else if ((REAL_VALUES_LESS (dconst0, d) + && REAL_VALUES_LESS (d, minfloat)) + || (REAL_VALUES_LESS (d, dconst0) + && REAL_VALUES_LESS (neg_minfloat, d))) { - *dp = 0.0; + *dp = dconst0; return 1; } } @@ -628,16 +635,7 @@ print_operand (file, x, code) REAL_VALUE_FROM_CONST_DOUBLE (d, x); switch (GET_MODE (x)) { case DFmode: -#if 0 /* doesn't work, produces dfloats */ REAL_VALUE_TO_TARGET_DOUBLE (d, u); -#else - { - union { double d; int i[2]; } t; - t.d = d; - u[0] = t.i[0]; - u[1] = t.i[1]; - } -#endif if (code == 'u') fprintf (file, "#%#lx", u[0]); else if (code == 'v') diff --git a/gcc/config/convex/convex.h b/gcc/config/convex/convex.h index 7ed4e45..d50f60b 100644 --- a/gcc/config/convex/convex.h +++ b/gcc/config/convex/convex.h @@ -1073,9 +1073,8 @@ enum reg_class { #define BRANCH_COST 0 -/* Convex uses VAX or IEEE floats. - Follow the host format. */ -#define TARGET_FLOAT_FORMAT HOST_FLOAT_FORMAT +/* Convex uses VAX or IEEE floats. Default to IEEE. */ +#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT /* Check a `double' value for validity for a particular machine mode. */ #define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \ diff --git a/gcc/config/dsp16xx/dsp16xx.c b/gcc/config/dsp16xx/dsp16xx.c index 674a3f0..7f5cc0b 100644 --- a/gcc/config/dsp16xx/dsp16xx.c +++ b/gcc/config/dsp16xx/dsp16xx.c @@ -1870,16 +1870,15 @@ print_operand(file, op, letter) fprintf (file, HOST_WIDE_INT_PRINT_HEX, (val >> 16) & 0xffff); else output_addr_const(file, op); - } + } else if (code == CONST_DOUBLE && GET_MODE(op) != DImode) - { - union { double d; int i[2]; } u; - union { float f; int i; } u1; - u.i[0] = CONST_DOUBLE_LOW (op); - u.i[1] = CONST_DOUBLE_HIGH (op); - u1.f = u.d; - fprintf (file, "0x%x", u1.i); - } + { + long l; + REAL_VALUE_TYPE r; + REAL_VALUE_FROM_CONST_DOUBLE (r, op); + REAL_VALUE_TO_TARGET_SINGLE (r, l); + fprintf (file, "0x%x", l); + } else if (code == CONST) { rtx addr = XEXP (op, 0); @@ -1977,7 +1976,6 @@ output_dsp16xx_float_const (operands) { rtx src = operands[1]; -#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT REAL_VALUE_TYPE d; long value; @@ -1986,9 +1984,6 @@ output_dsp16xx_float_const (operands) operands[1] = GEN_INT (value); output_asm_insn ("%u0=%U1\n\t%w0=%H1", operands); -#else - fatal_error ("inline float constants not supported on this host"); -#endif } static int diff --git a/gcc/config/dsp16xx/dsp16xx.md b/gcc/config/dsp16xx/dsp16xx.md index 7cea24a..31247ba 100644 --- a/gcc/config/dsp16xx/dsp16xx.md +++ b/gcc/config/dsp16xx/dsp16xx.md @@ -1935,7 +1935,7 @@ rtx reg3 = gen_reg_rtx (HImode); rtx label1 = gen_label_rtx (); rtx label2 = gen_label_rtx (); - REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31); + REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, 31); if (reg1) /* turn off complaints about unreached code */ { diff --git a/gcc/config/i370/i370.h b/gcc/config/i370/i370.h index 112758c..adcaca6 100644 --- a/gcc/config/i370/i370.h +++ b/gcc/config/i370/i370.h @@ -1374,21 +1374,26 @@ enum reg_class } \ else \ { \ - /* hack alert -- this prints wildly incorrect values */ \ - /* when run in cross-compiler mode. See ELF section */ \ - /* for suggested fix */ \ - union { double d; int i[2]; } u; \ - u.i[0] = CONST_DOUBLE_LOW (XV); \ - u.i[1] = CONST_DOUBLE_HIGH (XV); \ + char buf[50]; \ + REAL_VALUE_TYPE rval; \ + REAL_VALUE_FROM_CONST_DOUBLE(rval, XV); \ + REAL_VALUE_TO_DECIMAL (rval, HOST_WIDE_INT_PRINT_DEC, buf); \ if (GET_MODE (XV) == SFmode) \ { \ mvs_page_lit += 4; \ - fprintf (FILE, "=E'%.9G'", u.d); \ + fprintf (FILE, "=E'%s'", buf); \ } \ else \ + if (GET_MODE (XV) == DFmode) \ { \ mvs_page_lit += 8; \ - fprintf (FILE, "=D'%.18G'", u.d); \ + fprintf (FILE, "=D'%s'", buf); \ + } \ + else /* VOIDmode !?!? strange but true ... */ \ + { \ + mvs_page_lit += 8; \ + fprintf (FILE, "=XL8'%08X%08X'", \ + CONST_DOUBLE_HIGH (XV), CONST_DOUBLE_LOW (XV)); \ } \ } \ break; \ diff --git a/gcc/config/i860/i860.c b/gcc/config/i860/i860.c index 5538baf..1849397 100644 --- a/gcc/config/i860/i860.c +++ b/gcc/config/i860/i860.c @@ -1549,17 +1549,14 @@ sfmode_constant_to_ulong (x) rtx x; { REAL_VALUE_TYPE d; - union { float f; unsigned long i; } u2; + unsigned long l; if (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != SFmode) abort (); -#if TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT - error IEEE emulation needed -#endif REAL_VALUE_FROM_CONST_DOUBLE (d, x); - u2.f = d; - return u2.i; + REAL_VALUE_TO_TARGET_SINGLE (d, l); + return l; } /* This function generates the assembly code for function entry. diff --git a/gcc/config/m88k/m88k.c b/gcc/config/m88k/m88k.c index d53bffd..80f3ff4 100644 --- a/gcc/config/m88k/m88k.c +++ b/gcc/config/m88k/m88k.c @@ -1123,9 +1123,9 @@ real_power_of_2_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED; { + REAL_VALUE_TYPE d; union { - REAL_VALUE_TYPE d; - int i[sizeof (REAL_VALUE_TYPE) / sizeof (int)]; + long l[2]; struct { /* IEEE double precision format */ unsigned sign : 1; unsigned exponent : 11; @@ -1147,8 +1147,8 @@ real_power_of_2_operand (op, mode) if (GET_CODE (op) != CONST_DOUBLE) return 0; - u.i[0] = CONST_DOUBLE_LOW (op); - u.i[1] = CONST_DOUBLE_HIGH (op); + REAL_VALUE_FROM_CONST_DOUBLE (d, op); + REAL_VALUE_TO_TARGET_DOUBLE (d, u.l); if (u.s.mantissa1 != 0 || u.s.mantissa2 != 0 /* not a power of two */ || u.s.exponent == 0 /* constant 0.0 */ @@ -1169,8 +1169,9 @@ legitimize_operand (op, mode) enum machine_mode mode; { rtx temp; + REAL_VALUE_TYPE r; union { - union real_extract r; + long l[2]; struct { /* IEEE double precision format */ unsigned sign : 1; unsigned exponent : 11; @@ -1191,7 +1192,8 @@ legitimize_operand (op, mode) if (GET_CODE (op) == CONST_DOUBLE) { - memcpy (&u.r, &CONST_DOUBLE_LOW (op), sizeof u); + REAL_VALUE_FROM_CONST_DOUBLE (r, op); + REAL_VALUE_TO_TARGET_DOUBLE (r, u.l); if (u.d.exponent != 0x7ff /* NaN */ && u.d.mantissa2 == 0 /* Mantissa fits */ && (u.s.exponent1 == 0x8 || u.s.exponent1 == 0x7) /* Exponent fits */ diff --git a/gcc/config/m88k/m88k.md b/gcc/config/m88k/m88k.md index 75b9d2c..24a66f8 100644 --- a/gcc/config/m88k/m88k.md +++ b/gcc/config/m88k/m88k.md @@ -3053,10 +3053,12 @@ operands[1] = legitimize_operand (operands[1], DFmode); if (real_power_of_2_operand (operands[2], DFmode)) { - union real_extract u; - memcpy (&u, &CONST_DOUBLE_LOW (operands[2]), sizeof u); + REAL_VALUE_TYPE r; + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); + if (!exact_real_inverse (DFmode, &r)) + abort (); emit_insn (gen_muldf3 (operands[0], operands[1], - CONST_DOUBLE_FROM_REAL_VALUE (1.0/u.d, DFmode))); + CONST_DOUBLE_FROM_REAL_VALUE (r, DFmode))); DONE; } else if (! register_operand (operands[2], DFmode)) diff --git a/gcc/config/ns32k/merlin.h b/gcc/config/ns32k/merlin.h index a3b41ba..f38870d 100644 --- a/gcc/config/ns32k/merlin.h +++ b/gcc/config/ns32k/merlin.h @@ -64,8 +64,8 @@ Boston, MA 02111-1307, USA. */ #ifdef UTEK_ASM #undef PRINT_OPERAND -#define PRINT_OPERAND(FILE, X, CODE) \ -{ if (CODE == '$') putc('$', FILE); \ +#define PRINT_OPERAND(FILE, X, CODE) do { \ + if (CODE == '$') putc('$', FILE); \ else if (CODE == '?'); \ else if (GET_CODE (X) == CONST_INT) \ fprintf(FILE, "$%d", INTVAL(X)); \ @@ -116,14 +116,20 @@ Boston, MA 02111-1307, USA. */ } \ } \ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode) \ - if (GET_MODE (X) == DFmode) \ - { union { double d; int i[2]; } u; \ - u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ - fprintf (FILE, "$0d%.20e", u.d); } \ - else { union { double d; int i[2]; } u; \ - u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ - fprintf (FILE, "$0f%.20e", u.d); } \ - else output_addr_const (FILE, X); } + { \ + char buf[50]; \ + REAL_VALUE_TYPE rval; \ + REAL_VALUE_FROM_CONST_DOUBLE(rval, XV); \ + REAL_VALUE_TO_DECIMAL (rval, "%.20e", buf); \ + if (GET_MODE (XV) == SFmode) \ + fprintf (FILE, "$0e%s", buf); \ + else if (GET_MODE (XV) == DFmode) \ + fprintf (FILE, "$0d%s", buf); \ + else \ + abort(); \ + } \ + else output_addr_const (FILE, X); \ +} while (0) #endif /* UTEK_ASM */ diff --git a/gcc/config/ns32k/ns32k.c b/gcc/config/ns32k/ns32k.c index 9feef5e..8c980c5 100644 --- a/gcc/config/ns32k/ns32k.c +++ b/gcc/config/ns32k/ns32k.c @@ -1119,40 +1119,36 @@ print_operand (file, x, code) } else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode) { + REAL_VALUE_TYPE r; + + REAL_VALUE_FROM_CONST_DOUBLE (r, x); + PUT_IMMEDIATE_PREFIX (file); if (GET_MODE (x) == DFmode) { - union { double d; int i[2]; } u; - u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x); - PUT_IMMEDIATE_PREFIX (file); #ifdef SEQUENT_ASM /* Sequent likes its floating point constants as integers */ - fprintf (file, "0Dx%08x%08x", u.i[1], u.i[0]); + fprintf (file, "0Dx%08x%08x", + CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x)); #else + char s[30]; + REAL_VALUE_TO_DECIMAL (r, "%.20e", s); #ifdef ENCORE_ASM - fprintf (file, "0f%.20e", u.d); + fprintf (file, "0f%s", s); #else - fprintf (file, "0d%.20e", u.d); + fprintf (file, "0d%s", s); #endif #endif } else - { - union { double d; int i[2]; } u; - u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x); - PUT_IMMEDIATE_PREFIX (file); + { #ifdef SEQUENT_ASM - /* We have no way of winning if we can't get the bits - for a sequent floating point number. */ -#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT - abort (); -#endif - { - union { float f; long l; } uu; - uu.f = u.d; - fprintf (file, "0Fx%08lx", uu.l); - } + long l; + REAL_VALUE_TO_TARGET_SINGLE (r, l); + fprintf (file, "0Fx%08lx", l); #else - fprintf (file, "0f%.20e", u.d); + char s[30]; + REAL_VALUE_TO_DECIMAL (r, "%.20e", s); + fprintf (file, "0f%s", s); #endif } } diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index cff6fbf..3643db6 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -400,10 +400,11 @@ output_move_double (operands) if (REG_P (operands[1])) optype1 = REGOP; - else if (CONSTANT_P (operands[1])) + else if (CONSTANT_P (operands[1]) #if 0 - || GET_CODE (operands[1]) == CONST_DOUBLE) + || GET_CODE (operands[1]) == CONST_DOUBLE #endif + ) optype1 = CNSTOP; else if (offsettable_memref_p (operands[1])) optype1 = OFFSOP; @@ -620,11 +621,10 @@ output_move_quad (operands) { if (GET_CODE(operands[1]) == CONST_DOUBLE) { - union { double d; int i[2]; } u; - u.i[0] = CONST_DOUBLE_LOW (operands[1]); - u.i[1] = CONST_DOUBLE_HIGH (operands[1]); - - if (u.d == 0.0) + REAL_VALUE_TYPE r; + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + + if (REAL_VALUES_EQUAL (r, dconst0)) return "{clrd|clrf} %0"; } diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h index 53888ee..99bb7fe 100644 --- a/gcc/config/pdp11/pdp11.h +++ b/gcc/config/pdp11/pdp11.h @@ -1140,9 +1140,11 @@ fprintf (FILE, "$help$: . = .+8 ; space for tmp moves!\n") \ else if (GET_CODE (X) == MEM) \ output_address (XEXP (X, 0)); \ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != SImode) \ - { union { double d; int i[2]; } u; \ - u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ - fprintf (FILE, "#%.20e", u.d); } \ + { REAL_VALUE_TYPE r; \ + char buf[30]; \ + REAL_VALUE_FROM_CONST_DOUBLE (r, X); \ + REAL_VALUE_TO_DECIMAL (r, "%.20e", buf); \ + fprintf (FILE, "#%s", buf); } \ else { putc ('$', FILE); output_addr_const_pdp11 (FILE, X); }} /* Print a memory address as an operand to reference that memory location. */ diff --git a/gcc/config/romp/romp.c b/gcc/config/romp/romp.c index 7f984e8..a4813be 100644 --- a/gcc/config/romp/romp.c +++ b/gcc/config/romp/romp.c @@ -1962,10 +1962,9 @@ output_fpops (file) size_so_far += 4; if (GET_CODE (immed[i]) == CONST_DOUBLE) { - union real_extract u; - - memcpy (&u, &CONST_DOUBLE_LOW (immed[i]), sizeof u); - assemble_real (u.d, GET_MODE (immed[i]), + REAL_VALUE_TYPE r; + REAL_VALUE_FROM_CONST_DOUBLE (r, immed[i]); + assemble_real (r, GET_MODE (immed[i]), GET_MODE_ALIGNMENT (GET_MODE (immed[i]))); } else diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 96d91fa..1ab431e 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -1386,8 +1386,8 @@ extern int s390_nr_constants; if (GET_CODE (EXP) != CONST_DOUBLE) \ abort (); \ \ - memcpy ((char *) &u, (char *) &CONST_DOUBLE_LOW (EXP), sizeof u); \ - assemble_real (u.d, MODE, ALIGN); \ + REAL_VALUE_FROM_CONST_DOUBLE (r, EXP); \ + assemble_real (r, MODE, ALIGN); \ break; \ \ case MODE_INT: \ diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 8be850a..9665609 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -374,10 +374,8 @@ vax_float_literal(c) register rtx c; { register enum machine_mode mode; -#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT + REAL_VALUE_TYPE r, s; int i; - union {double d; int i[2];} val; -#endif if (GET_CODE (c) != CONST_DOUBLE) return 0; @@ -389,15 +387,20 @@ vax_float_literal(c) || c == const_tiny_rtx[(int) mode][2]) return 1; -#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT + REAL_VALUE_FROM_CONST_DOUBLE (r, c); - val.i[0] = CONST_DOUBLE_LOW (c); - val.i[1] = CONST_DOUBLE_HIGH (c); + for (i = 0; i < 7; i++) + { + int x = 1 << i; + REAL_VALUE_FROM_INT (s, x, 0, mode); - for (i = 0; i < 7; i ++) - if (val.d == 1 << i || val.d == 1 / (1 << i)) - return 1; -#endif + if (REAL_VALUES_EQUAL (r, s)) + return 1; + if (!exact_real_inverse (mode, &s)) + abort (); + if (REAL_VALUES_EQUAL (r, s)) + return 1; + } return 0; } diff --git a/gcc/config/we32k/we32k.h b/gcc/config/we32k/we32k.h index eec05ab..1bf6805 100644 --- a/gcc/config/we32k/we32k.h +++ b/gcc/config/we32k/we32k.h @@ -847,13 +847,12 @@ do { \ output_address (XEXP (X, 0)); \ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \ { \ - union { double d; long l[2]; } dtem; \ - union { float f; long l; } ftem; \ + REAL_VALUE_TYPE r; \ + long l; \ \ - dtem.l[0] = CONST_DOUBLE_LOW (X); \ - dtem.l[1] = CONST_DOUBLE_HIGH (X); \ - ftem.f = dtem.d; \ - fprintf(FILE, "&0x%lx", ftem.l); \ + REAL_VALUE_FROM_CONST_DOUBLE (r, X); \ + REAL_VALUE_TO_TARGET_SINGLE (r, l); \ + fprintf (FILE, "&0x%lx", l); \ } \ else { putc ('&', FILE); output_addr_const (FILE, X); }} diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index e24525b..a791da0 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -2078,7 +2078,7 @@ xtensa_output_literal (file, x, mode, labelno) int labelno; { long value_long[2]; - union real_extract u; + REAL_VALUE_TYPE r; int size; fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno); @@ -2089,18 +2089,18 @@ xtensa_output_literal (file, x, mode, labelno) if (GET_CODE (x) != CONST_DOUBLE) abort (); - memcpy ((char *) &u, (char *) &CONST_DOUBLE_LOW (x), sizeof u); + REAL_VALUE_FROM_CONST_DOUBLE (r, x); switch (mode) { case SFmode: - REAL_VALUE_TO_TARGET_SINGLE (u.d, value_long[0]); - fprintf (file, "0x%08lx\t\t# %.12g (float)\n", value_long[0], u.d); + REAL_VALUE_TO_TARGET_SINGLE (r, value_long[0]); + fprintf (file, "0x%08lx\n", value_long[0]); break; case DFmode: - REAL_VALUE_TO_TARGET_DOUBLE (u.d, value_long); - fprintf (file, "0x%08lx, 0x%08lx # %.20g (double)\n", - value_long[0], value_long[1], u.d); + REAL_VALUE_TO_TARGET_DOUBLE (r, value_long); + fprintf (file, "0x%08lx, 0x%08lx\n", + value_long[0], value_long[1]); break; default: -- cgit v1.1