summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog78
-rw-r--r--gcc/ch/ChangeLog5
-rw-r--r--gcc/ch/grant.c4
-rw-r--r--gcc/config/1750a/1750a-protos.h2
-rw-r--r--gcc/config/1750a/1750a.c96
-rw-r--r--gcc/config/a29k/a29k.c31
-rw-r--r--gcc/config/a29k/a29k.md2
-rw-r--r--gcc/config/arm/arm.c6
-rw-r--r--gcc/config/arm/arm.md12
-rw-r--r--gcc/config/convex/convex.c40
-rw-r--r--gcc/config/convex/convex.h5
-rw-r--r--gcc/config/dsp16xx/dsp16xx.c21
-rw-r--r--gcc/config/dsp16xx/dsp16xx.md2
-rw-r--r--gcc/config/i370/i370.h21
-rw-r--r--gcc/config/i860/i860.c9
-rw-r--r--gcc/config/m88k/m88k.c14
-rw-r--r--gcc/config/m88k/m88k.md8
-rw-r--r--gcc/config/ns32k/merlin.h26
-rw-r--r--gcc/config/ns32k/ns32k.c38
-rw-r--r--gcc/config/pdp11/pdp11.c14
-rw-r--r--gcc/config/pdp11/pdp11.h8
-rw-r--r--gcc/config/romp/romp.c7
-rw-r--r--gcc/config/s390/s390.h4
-rw-r--r--gcc/config/vax/vax.c23
-rw-r--r--gcc/config/we32k/we32k.h11
-rw-r--r--gcc/config/xtensa/xtensa.c14
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/error.c4
-rw-r--r--gcc/doc/rtl.texi2
-rw-r--r--gcc/doc/tm.texi261
-rw-r--r--gcc/emit-rtl.c20
-rw-r--r--gcc/fold-const.c9
-rw-r--r--gcc/libgcc2.c30
-rw-r--r--gcc/print-rtl.c12
-rw-r--r--gcc/real.c9
-rw-r--r--gcc/real.h61
-rw-r--r--gcc/simplify-rtx.c6
-rw-r--r--gcc/varasm.c35
38 files changed, 415 insertions, 540 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1616ef618f7..287ddeb12d8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,69 @@
+2002-03-22 Zack Weinberg <zack@codesourcery.com>
+
+ * 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.
+
+ * 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.
+
2002-03-22 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa-protos.h (non_acc_reg_operand): Remove.
@@ -14,13 +80,13 @@
2002-03-22 Neil Booth <neil@daikokuya.demon.co.uk>
- * cpphash.h (struct cpp_reader): Remove mls_line and mls_col.
- * cpplex.c (unterminated): Delete.
- (parse_string): No string literal may extend over multiple
- lines. Suppress the error when preprocessing assembly.
+ * cpphash.h (struct cpp_reader): Remove mls_line and mls_col.
+ * cpplex.c (unterminated): Delete.
+ (parse_string): No string literal may extend over multiple
+ lines. Suppress the error when preprocessing assembly.
* cppmain.c (scan_translation_unit): Strings are single-line.
- * doc/cpp.texi: Update to match.
+ * doc/cpp.texi: Update to match.
2002-03-22 Jakub Jelinek <jakub@redhat.com>
@@ -495,7 +561,7 @@ Tue Mar 19 14:12:32 2002 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
2002-03-18 Mark Mitchell <mark@codesourcery.com>
- * calls.c (precompute_arguments): Do not assume that temporaries
+ * calls.c (precompute_arguments): Do not assume that temporaries
can be destroyed after expanding the argument.
(expand_call): Likewise.
diff --git a/gcc/ch/ChangeLog b/gcc/ch/ChangeLog
index df0d0f580ae..5dafdbb353f 100644
--- a/gcc/ch/ChangeLog
+++ b/gcc/ch/ChangeLog
@@ -1,3 +1,8 @@
+2002-03-22 Zack Weinberg <zack@codesourcery.com>
+
+ * grant.c: Always use REAL_VALUE_TO_DECIMAL; don't test
+ REAL_IS_NOT_DOUBLE.
+
2002-03-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* decl.c (chill_tree_code_type, chill_tree_code_length,
diff --git a/gcc/ch/grant.c b/gcc/ch/grant.c
index f143aec4708..48973e0851c 100644
--- a/gcc/ch/grant.c
+++ b/gcc/ch/grant.c
@@ -1851,11 +1851,7 @@ decode_constant (init)
return result;
case REAL_CST:
-#ifndef REAL_IS_NOT_DOUBLE
- sprintf (wrk, "%.20g", TREE_REAL_CST (val));
-#else
REAL_VALUE_TO_DECIMAL (TREE_REAL_CST (val), "%.20g", wrk);
-#endif
APPEND (result, wrk);
return result;
diff --git a/gcc/config/1750a/1750a-protos.h b/gcc/config/1750a/1750a-protos.h
index aa2b41fbea0..c437f00f3e1 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 099f7c73818..c8b6a796efc 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 3291bab5b24..bd08c38c786 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 596aa4707e5..d4e4f34595f 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 f07a281f4a3..814c84d9888 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 cdab5c66ff8..9ea7d0c8a06 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 bee0f173076..74af45ec2a5 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 7ed4e4539d9..d50f60b0fd2 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 674a3f08eba..7f5cc0b06c4 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 7cea24a1ac5..31247ba38f8 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 112758c7ad0..adcaca675d7 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 5538baffae7..18493976615 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 d53bffdfffb..80f3ff44b47 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 75b9d2c5010..24a66f86ec8 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 a3b41baf260..f38870dd3fc 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 9feef5e0067..8c980c577b3 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 cff6fbf6792..3643db6d281 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 53888ee03f8..99bb7fe32d5 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 7f984e876d8..a4813be29cd 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 96d91fad457..1ab431e1f41 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 8be850a0030..9665609df2a 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 eec05ab3211..1bf6805d1e7 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 e24525bd1d6..a791da00fb7 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:
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 87679b8fce5..01a5f67c83b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2002-03-22 Zack Weinberg <zack@codesourcery.com>
+
+ * error.c: Always use REAL_VALUE_TO_DECIMAL; don't test
+ REAL_IS_NOT_DOUBLE.
+
2002-03-22 Jeff Knaggs <jknaggs@redhat.com>
* typeck.c (expand_ptrmemfunc_cst): Scale idx down to an index
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 20352e01b54..077181f7dd7 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1507,9 +1507,6 @@ dump_expr (t, flags)
break;
case REAL_CST:
-#ifndef REAL_IS_NOT_DOUBLE
- sprintf (digit_buffer, "%g", TREE_REAL_CST (t));
-#else
{
const unsigned char *p = (const unsigned char *) &TREE_REAL_CST (t);
size_t i;
@@ -1517,7 +1514,6 @@ dump_expr (t, flags)
for (i = 0; i < sizeof TREE_REAL_CST (t); i++)
sprintf (digit_buffer + 2 + 2*i, "%02x", *p++);
}
-#endif
output_add_string (scratch_buffer, digit_buffer);
break;
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 58faea99f78..10c81e47d65 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -1204,7 +1204,7 @@ If @var{m} is @code{VOIDmode}, the bits of the value are stored in
If the constant is floating point (regardless of its precision), then
the number of integers used to store the value depends on the size of
-@code{REAL_VALUE_TYPE} (@pxref{Cross-compilation}). The integers
+@code{REAL_VALUE_TYPE} (@pxref{Floating Point}). The integers
represent a floating point number, but not precisely in the target
machine's or host machine's floating point format. To convert them to
the precise bit pattern used by the target machine, use the macro
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 3f37cdb3e60..ac44ee35640 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -46,7 +46,7 @@ through the macros defined in the @file{.h} file.
* PIC:: Macros for position independent code.
* Assembler Format:: Defining how to write insns and pseudo-ops to output.
* Debugging Info:: Defining the format of debugging output.
-* Cross-compilation:: Handling floating point for cross-compilers.
+* Floating Point:: Handling floating point for cross-compilers.
* Mode Switching:: Insertion of mode-switching instructions.
* Target Attributes:: Defining target-specific uses of @code{__attribute__}.
* Misc:: Everything else.
@@ -6051,12 +6051,14 @@ of @code{ASM_OUTPUT_DOUBLE} and the like:
@findex REAL_VALUE_TO_TARGET_DOUBLE
@findex REAL_VALUE_TO_TARGET_LONG_DOUBLE
These translate @var{x}, of type @code{REAL_VALUE_TYPE}, to the target's
-floating point representation, and store its bit pattern in the array of
-@code{long int} whose address is @var{l}. The number of elements in the
-output array is determined by the size of the desired target floating
-point data type: 32 bits of it go in each @code{long int} array
-element. Each array element holds 32 bits of the result, even if
-@code{long int} is wider than 32 bits on the host machine.
+floating point representation, and store its bit pattern in the variable
+@var{l}. For @code{REAL_VALUE_TO_TARGET_SINGLE}, this variable should
+be a simple @code{long int}. For the others, it should be an array of
+@code{long int}. The number of elements in this array is determined by
+the size of the desired target floating point data type: 32 bits of it
+go in each @code{long int} array element. Each array element holds 32
+bits of the result, even if @code{long int} is wider than 32 bits on the
+host machine.
The array element values are designed so that you can print them out
using @code{fprintf} in the order they should appear in the target
@@ -7753,167 +7755,126 @@ behavior is controlled by @code{OPTIMIZATION_OPTIONS} and
@code{OVERRIDE_OPTIONS}.
@end table
-@node Cross-compilation
+@node Floating Point
@section Cross Compilation and Floating Point
@cindex cross compilation and floating point
@cindex floating point and cross compilation
-While all modern machines use 2's complement representation for integers,
+While all modern machines use twos-complement representation for integers,
there are a variety of representations for floating point numbers. This
means that in a cross-compiler the representation of floating point numbers
in the compiled program may be different from that used in the machine
doing the compilation.
-@findex atof
Because different representation systems may offer different amounts of
-range and precision, the cross compiler cannot safely use the host
-machine's floating point arithmetic. Therefore, floating point constants
-must be represented in the target machine's format. This means that the
-cross compiler cannot use @code{atof} to parse a floating point constant;
-it must have its own special routine to use instead. Also, constant
-folding must emulate the target machine's arithmetic (or must not be done
-at all).
-
-The macros in the following table are provided by @file{real.h} for the
-compiler to use. All parts of the compiler which generate or optimize
+range and precision, all floating point constants must be represented in
+the target machine's format. Therefore, the cross compiler cannot
+safely use the host machine's floating point arithmetic; it must emulate
+the target's arithmetic. To ensure consistency, GCC always uses
+emulation to work with floating point values, even when the host and
+target floating point formats are identical.
+
+The following macros are provided by @file{real.h} for the compiler to
+use. All parts of the compiler which generate or optimize
floating-point calculations must use these macros. They may evaluate
their operands more than once, so operands must not have side effects.
-@table @code
-@findex REAL_VALUE_TYPE
-@item REAL_VALUE_TYPE
-A macro for the C data type to be used to hold a floating point value
-in the target machine's format. Typically this would be a
-@code{struct} containing an array of @code{int}.
-
-@findex REAL_VALUES_EQUAL
-@item REAL_VALUES_EQUAL (@var{x}, @var{y})
-A macro for a C expression which compares for equality the two values,
-@var{x} and @var{y}, both of type @code{REAL_VALUE_TYPE}.
-
-@findex REAL_VALUES_LESS
-@item REAL_VALUES_LESS (@var{x}, @var{y})
-A macro for a C expression which tests whether @var{x} is less than
-@var{y}, both values being of type @code{REAL_VALUE_TYPE} and
-interpreted as floating point numbers in the target machine's
-representation.
-
-@findex REAL_VALUE_LDEXP
+@defmac REAL_VALUE_TYPE
+The C data type to be used to hold a floating point value in the target
+machine's format. Typically this is a @code{struct} containing an
+array of @code{HOST_WIDE_INT}, but all code should treat it as an opaque
+quantity.
+@end defmac
+
+@deftypefn Macro int REAL_VALUES_EQUAL (REAL_VALUE_TYPE @var{x}, REAL_VALUE_TYPE @var{y})
+Compares for equality the two values, @var{x} and @var{y}. If the target
+floating point format supports negative zeroes and/or NaNs,
+@samp{REAL_VALUES_EQUAL (-0.0, 0.0)} is true, and
+@samp{REAL_VALUES_EQUAL (NaN, NaN)} is false.
+@end deftypefn
+
+@deftypefn Macro int REAL_VALUES_LESS (REAL_VALUE_TYPE @var{x}, REAL_VALUE_TYPE @var{y})
+Tests whether @var{x} is less than @var{y}.
+@end deftypefn
+
@findex ldexp
-@item REAL_VALUE_LDEXP (@var{x}, @var{scale})
-A macro for a C expression which performs the standard library
-function @code{ldexp}, but using the target machine's floating point
-representation. Both @var{x} and the value of the expression have
-type @code{REAL_VALUE_TYPE}. The second argument, @var{scale}, is an
-integer.
-
-@findex REAL_VALUE_FIX
-@item REAL_VALUE_FIX (@var{x})
-A macro whose definition is a C expression to convert the target-machine
-floating point value @var{x} to a signed integer. @var{x} has type
-@code{REAL_VALUE_TYPE}.
-
-@findex REAL_VALUE_UNSIGNED_FIX
-@item REAL_VALUE_UNSIGNED_FIX (@var{x})
-A macro whose definition is a C expression to convert the target-machine
-floating point value @var{x} to an unsigned integer. @var{x} has type
-@code{REAL_VALUE_TYPE}.
-
-@findex REAL_VALUE_RNDZINT
-@item REAL_VALUE_RNDZINT (@var{x})
-A macro whose definition is a C expression to round the target-machine
-floating point value @var{x} towards zero to an integer value (but still
-as a floating point number). @var{x} has type @code{REAL_VALUE_TYPE},
-and so does the value.
-
-@findex REAL_VALUE_UNSIGNED_RNDZINT
-@item REAL_VALUE_UNSIGNED_RNDZINT (@var{x})
-A macro whose definition is a C expression to round the target-machine
-floating point value @var{x} towards zero to an unsigned integer value
-(but still represented as a floating point number). @var{x} has type
-@code{REAL_VALUE_TYPE}, and so does the value.
-
-@findex REAL_VALUE_ATOF
-@item REAL_VALUE_ATOF (@var{string}, @var{mode})
-A macro for a C expression which converts @var{string}, an expression of
-type @code{char *}, into a floating point number in the target machine's
-representation for mode @var{mode}. The value has type
-@code{REAL_VALUE_TYPE}.
-
-@findex REAL_INFINITY
-@item REAL_INFINITY
-Define this macro if infinity is a possible floating point value, and
-therefore division by 0 is legitimate.
-
-@findex REAL_VALUE_ISINF
-@findex isinf
-@item REAL_VALUE_ISINF (@var{x})
-A macro for a C expression which determines whether @var{x}, a floating
-point value, is infinity. The value has type @code{int}.
-By default, this is defined to call @code{isinf}.
-
-@findex REAL_VALUE_ISNAN
-@findex isnan
-@item REAL_VALUE_ISNAN (@var{x})
-A macro for a C expression which determines whether @var{x}, a floating
-point value, is a ``nan'' (not-a-number). The value has type
-@code{int}. By default, this is defined to call @code{isnan}.
-
-@findex REAL_ARITHMETIC
-@item REAL_ARITHMETIC (@var{output}, @var{code}, @var{x}, @var{y})
-A macro for a C statement which calculates an arithmetic operation of
-the two floating point values @var{x} and @var{y}, both of type
-@code{REAL_VALUE_TYPE} in the target machine's representation, to
-produce a result of the same type and representation which is stored
-in @var{output} (which will be a variable).
-
-The operation to be performed is specified by @var{code}, a tree code
-which will always be one of the following: @code{PLUS_EXPR},
-@code{MINUS_EXPR}, @code{MULT_EXPR}, @code{RDIV_EXPR},
-@code{MAX_EXPR}, @code{MIN_EXPR}.
-
-@cindex overflow while constant folding
-If overflow happens, the macro expansion executes the statement
-@code{return 0;}, which indicates the inability to perform the
-arithmetic operation requested.
-
-@findex REAL_VALUE_NEGATE
-@item REAL_VALUE_NEGATE (@var{x})
-A macro for a C expression which returns the negative of the floating
-point value @var{x}. Both @var{x} and the value of the expression
-have type @code{REAL_VALUE_TYPE} and are in the target machine's
-floating point representation.
-
-There is no way for this macro to report overflow, since overflow
-can't happen in the negation operation.
-
-@findex REAL_VALUE_TRUNCATE
-@item REAL_VALUE_TRUNCATE (@var{mode}, @var{x})
-A macro for a C expression which converts the floating point value
-@var{x} to mode @var{mode}.
-
-Both @var{x} and the value of the expression are in the target machine's
-floating point representation and have type @code{REAL_VALUE_TYPE}.
-However, the value should have an appropriate bit pattern to be output
-properly as a floating constant whose precision accords with mode
-@var{mode}.
+@deftypefn Macro REAL_VALUE_TYPE REAL_VALUE_LDEXP (REAL_VALUE_TYPE @var{x}, int @var{scale})
+Multiplies @var{x} by 2 raised to the power @var{scale}.
+@end deftypefn
+
+@deftypefn Macro HOST_WIDE_INT REAL_VALUE_FIX (REAL_VALUE_TYPE @var{x})
+Truncates @var{x} to a signed integer, rounding toward zero.
+@end deftypefn
+
+@deftypefn Macro {unsigned HOST_WIDE_INT} REAL_VALUE_UNSIGNED_FIX (REAL_VALUE_TYPE @var{x})
+Truncates @var{x} to an unsigned integer, rounding toward zero. If
+@var{x} is negative, returns zero.
+@end deftypefn
+
+@deftypefn Macro REAL_VALUE_TYPE REAL_VALUE_RNDZINT (REAL_VALUE_TYPE @var{x})
+Rounds the target-machine floating point value @var{x} towards zero to an
+integer value, but leaves it represented as a floating point number.
+@end deftypefn
-There is no way for this macro to report overflow.
+@deftypefn Macro REAL_VALUE_TYPE REAL_VALUE_UNSIGNED_RNDZINT (REAL_VALUE_TYPE @var{x})
+Rounds the target-machine floating point value @var{x} towards zero to an
+unsigned integer value, but leaves it represented as a floating point
+number. If @var{x} is negative, returns (positive) zero.
+@end deftypefn
-@findex REAL_VALUE_TO_INT
-@item REAL_VALUE_TO_INT (@var{low}, @var{high}, @var{x})
-A macro for a C expression which converts a floating point value
-@var{x} into a double-precision integer which is then stored into
-@var{low} and @var{high}, two variables of type @var{int}.
+@deftypefn Macro REAL_VALUE_TYPE REAL_VALUE_ATOF (const char *@var{string}, enum machine_mode @var{mode})
+Converts @var{string} into a floating point number in the target machine's
+representation for mode @var{mode}. This routine can handle both
+decimal and hexadecimal floating point constants, using the syntax
+defined by the C language for both.
+@end deftypefn
-@item REAL_VALUE_FROM_INT (@var{x}, @var{low}, @var{high}, @var{mode})
+@deftypefn Macro int REAL_VALUE_ISINF (REAL_VALUE_TYPE @var{x})
+Determines whether @var{x} represents infinity (positive or negative).
+@end deftypefn
+
+@deftypefn Macro int REAL_VALUE_ISNAN (REAL_VALUE_TYPE @var{x})
+Determines whether @var{x} represents a ``NaN'' (not-a-number).
+@end deftypefn
+
+@deftypefn Macro void REAL_ARITHMETIC (REAL_VALUE_TYPE @var{output}, enum tree_code @var{code}, REAL_VALUE_TYPE @var{x}, REAL_VALUE_TYPE @var{y})
+Calculates an arithmetic operation on the two floating point values
+@var{x} and @var{y}, storing the result in @var{output} (which must be a
+variable).
+
+The operation to be performed is specified by @var{code}. Only the
+following codes are supported: @code{PLUS_EXPR}, @code{MINUS_EXPR},
+@code{MULT_EXPR}, @code{RDIV_EXPR}, @code{MAX_EXPR}, @code{MIN_EXPR}.
+
+If @code{REAL_ARITHMETIC} is asked to evaluate division by zero and the
+target's floating point format cannot represent infinity, it will call
+@code{abort}. Callers should check for this situation first, using
+@code{MODE_HAS_INFINITIES}. @xref{Storage Layout}.
+@end deftypefn
+
+@deftypefn Macro REAL_VALUE_TYPE REAL_VALUE_NEGATE (REAL_VALUE_TYPE @var{x})
+Returns the negative of the floating point value @var{x}.
+@end deftypefn
+
+@deftypefn Macro REAL_VALUE_TYPE REAL_VALUE_TRUNCATE (REAL_VALUE_TYPE @var{mode}, enum machine_mode @var{x})
+Truncates the floating point value @var{x} to fit in @var{mode}. The
+return value is still a full-size @code{REAL_VALUE_TYPE}, but it has an
+appropriate bit pattern to be output asa floating constant whose
+precision accords with mode @var{mode}.
+@end deftypefn
+
+@deftypefn Macro void REAL_VALUE_TO_INT (HOST_WIDE_INT @var{low}, HOST_WIDE_INT @var{high}, REAL_VALUE_TYPE @var{x})
+Converts a floating point value @var{x} into a double-precision integer
+which is then stored into @var{low} and @var{high}. If the value is not
+integral, it is truncated.
+@end deftypefn
+
+@deftypefn Macro void REAL_VALUE_FROM_INT (REAL_VALUE_TYPE @var{x}, HOST_WIDE_INT @var{low}, HOST_WIDE_INT @var{high}, enum machine_mode @var{mode})
@findex REAL_VALUE_FROM_INT
-A macro for a C expression which converts a double-precision integer
-found in @var{low} and @var{high}, two variables of type @var{int},
-into a floating point value which is then stored into @var{x}.
-The value is in the target machine's representation for mode @var{mode}
-and has the type @code{REAL_VALUE_TYPE}.
-@end table
+Converts a double-precision integer found in @var{low} and @var{high},
+into a floating point value which is then stored into @var{x}. The
+value is truncated to fit in mode @var{mode}.
+@end deftypefn
@node Mode Switching
@section Mode Switching Instructions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index d54bacab6b9..7f1e92b5f4d 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -4920,23 +4920,17 @@ init_emit_once (line_numbers)
for (i = 0; i <= 2; i++)
{
+ REAL_VALUE_TYPE *r =
+ (i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
+
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
{
rtx tem = rtx_alloc (CONST_DOUBLE);
- union real_extract u;
-
- /* Zero any holes in a structure. */
- memset ((char *) &u, 0, sizeof u);
- u.d = i == 0 ? dconst0 : i == 1 ? dconst1 : dconst2;
-
- /* Avoid trailing garbage in the rtx. */
- if (sizeof (u) < sizeof (HOST_WIDE_INT))
- CONST_DOUBLE_LOW (tem) = 0;
- if (sizeof (u) < 2 * sizeof (HOST_WIDE_INT))
- CONST_DOUBLE_HIGH (tem) = 0;
-
- memcpy (&CONST_DOUBLE_LOW (tem), &u, sizeof u);
+
+ /* Can't use CONST_DOUBLE_FROM_REAL_VALUE here; that uses the
+ tables we're setting up right now. */
+ memcpy (&CONST_DOUBLE_LOW (tem), r, sizeof (REAL_VALUE_TYPE));
CONST_DOUBLE_CHAIN (tem) = NULL_RTX;
PUT_MODE (tem, mode);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 39d18bb30fa..b89b7804cd7 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -5379,11 +5379,12 @@ fold (expr)
goto binary;
case RDIV_EXPR:
- /* In most cases, do nothing with a divide by zero. */
-#ifndef REAL_INFINITY
- if (TREE_CODE (arg1) == REAL_CST && real_zerop (arg1))
+ /* Don't touch a floating-point divide by zero unless the mode
+ of the constant can represent infinity. */
+ if (TREE_CODE (arg1) == REAL_CST
+ && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg1)))
+ && real_zerop (arg1))
return t;
-#endif
/* (-A) / (-B) -> A / B */
if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR)
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 08bfc3438e3..cab925665c2 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -1067,33 +1067,11 @@ __floatdidf (DWtype u)
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
#define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
-/* Define codes for all the float formats that we know of. Note
- that this is copied from real.h. */
+/* GCC guarantees this header exists at this point. */
+#include <float.h>
-#define UNKNOWN_FLOAT_FORMAT 0
-#define IEEE_FLOAT_FORMAT 1
-#define VAX_FLOAT_FORMAT 2
-#define IBM_FLOAT_FORMAT 3
-
-/* Default to IEEE float if not specified. Nearly all machines use it. */
-#ifndef HOST_FLOAT_FORMAT
-#define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
-#endif
-
-#if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
-#define DF_SIZE 53
-#define SF_SIZE 24
-#endif
-
-#if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
-#define DF_SIZE 56
-#define SF_SIZE 24
-#endif
-
-#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
-#define DF_SIZE 56
-#define SF_SIZE 24
-#endif
+#define DF_SIZE DBL_MANT_DIG
+#define SF_SIZE FLT_MANT_DIG
SFtype
__floatdisf (DWtype u)
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index b819d143a34..496613bf949 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -502,13 +502,19 @@ print_rtx (in_rtx)
fputc (']', outfile);
break;
-#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && MAX_LONG_DOUBLE_TYPE_SIZE == 64
+#if 0
+ /* It would be nice to do this, but it would require real.o to
+ be linked into the MD-generator programs. Maybe we should
+ do that. -zw 2002-03-03 */
case CONST_DOUBLE:
if (FLOAT_MODE_P (GET_MODE (in_rtx)))
{
- double val;
+ REAL_VALUE_TYPE val;
+ char s[30];
+
REAL_VALUE_FROM_CONST_DOUBLE (val, in_rtx);
- fprintf (outfile, " [%.16g]", val);
+ REAL_VALUE_TO_DECIMAL (val, "%.16g", s);
+ fprintf (outfile, " [%s]", s);
}
break;
#endif
diff --git a/gcc/real.c b/gcc/real.c
index bac06905230..8674ee897d9 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -607,17 +607,10 @@ earith (value, icode, r1, r2)
break;
case RDIV_EXPR:
-#ifndef REAL_INFINITY
+#ifndef INFINITY
if (ecmp (d2, ezero) == 0)
- {
-#ifdef NANS
- enan (v, eisneg (d1) ^ eisneg (d2));
- break;
-#else
abort ();
#endif
- }
-#endif
ediv (d2, d1, v); /* d1/d2 */
break;
diff --git a/gcc/real.h b/gcc/real.h
index e734b26548e..d3cf780ef33 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -43,10 +43,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define INTEL_EXTENDED_IEEE_FORMAT 0
#endif
-#if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
-#define REAL_INFINITY
-#endif
-
/* If FLOAT_WORDS_BIG_ENDIAN and HOST_FLOAT_WORDS_BIG_ENDIAN are not defined
in the header files, then this implies the word-endianness is the same as
for integers. */
@@ -79,43 +75,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* **** Start of software floating point emulator interface macros **** */
-/* Support 80-bit extended real XFmode if LONG_DOUBLE_TYPE_SIZE
- has been defined to be 96 in the tm.h machine file. */
-#if (MAX_LONG_DOUBLE_TYPE_SIZE == 96)
-#define REAL_IS_NOT_DOUBLE
-typedef struct {
- HOST_WIDE_INT r[(11 + sizeof (HOST_WIDE_INT))/(sizeof (HOST_WIDE_INT))];
-} realvaluetype;
-#define REAL_VALUE_TYPE realvaluetype
-
-#else /* no XFmode support */
-
-#if (MAX_LONG_DOUBLE_TYPE_SIZE == 128)
-
-#define REAL_IS_NOT_DOUBLE
-typedef struct {
- HOST_WIDE_INT r[(19 + sizeof (HOST_WIDE_INT))/(sizeof (HOST_WIDE_INT))];
-} realvaluetype;
-#define REAL_VALUE_TYPE realvaluetype
-
-#else /* not TFmode */
-
-#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
-/* If no XFmode support, then a REAL_VALUE_TYPE is 64 bits wide
- but it is not necessarily a host machine double. */
-#define REAL_IS_NOT_DOUBLE
+/* REAL_VALUE_TYPE is an array of the minimum number of HOST_WIDE_INTs
+ required to hold MAX_LONG_DOUBLE_TYPE_SIZE bits. */
+#define N (MAX_LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)
+#define S sizeof (HOST_WIDE_INT)
typedef struct {
- HOST_WIDE_INT r[(7 + sizeof (HOST_WIDE_INT))/(sizeof (HOST_WIDE_INT))];
-} realvaluetype;
-#define REAL_VALUE_TYPE realvaluetype
-#else
-/* If host and target formats are compatible, then a REAL_VALUE_TYPE
- is actually a host machine double. */
-#define REAL_VALUE_TYPE double
-#endif
-
-#endif /* no TFmode support */
-#endif /* no XFmode support */
+ HOST_WIDE_INT r[N/S + (N%S ? 1 : 0)]; /* round up */
+} REAL_VALUE_TYPE;
+#undef N
+#undef S
extern unsigned int significand_size PARAMS ((enum machine_mode));
@@ -246,15 +214,6 @@ extern REAL_VALUE_TYPE dconst1;
extern REAL_VALUE_TYPE dconst2;
extern REAL_VALUE_TYPE dconstm1;
-/* Union type used for extracting real values from CONST_DOUBLEs
- or putting them in. */
-
-union real_extract
-{
- REAL_VALUE_TYPE d;
- HOST_WIDE_INT i[sizeof (REAL_VALUE_TYPE) / sizeof (HOST_WIDE_INT)];
-};
-
/* Given a CONST_DOUBLE in FROM, store into TO the value it represents. */
/* Function to return a real value (not a tree node)
from a given integer constant. */
@@ -263,9 +222,7 @@ REAL_VALUE_TYPE real_value_from_int_cst PARAMS ((union tree_node *,
union tree_node *));
#define REAL_VALUE_FROM_CONST_DOUBLE(to, from) \
-do { union real_extract u; \
- memcpy (&u, &CONST_DOUBLE_LOW ((from)), sizeof u); \
- to = u.d; } while (0)
+ memcpy (&(to), &CONST_DOUBLE_LOW ((from)), sizeof (REAL_VALUE_TYPE))
/* Return a CONST_DOUBLE with value R and mode M. */
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 21012ce31a3..53f8293078e 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -763,13 +763,13 @@ simplify_binary_real (p)
f0 = real_value_truncate (args->mode, f0);
f1 = real_value_truncate (args->mode, f1);
-#ifndef REAL_INFINITY
- if (args->code == DIV && REAL_VALUES_EQUAL (f1, dconst0))
+ if (args->code == DIV
+ && !MODE_HAS_INFINITIES (args->mode)
+ && REAL_VALUES_EQUAL (f1, dconst0))
{
args->result = 0;
return;
}
-#endif
REAL_ARITHMETIC (value, rtx_to_tree_code (args->code), f0, f1);
value = real_value_truncate (args->mode, value);
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 098757edd64..ef9e87242cd 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2215,14 +2215,8 @@ immed_real_const_1 (d, mode)
REAL_VALUE_TYPE d;
enum machine_mode mode;
{
- union real_extract u;
rtx r;
- /* Get the desired `double' value as a sequence of ints
- since that is how they are stored in a CONST_DOUBLE. */
-
- u.d = d;
-
/* Detect special cases. Check for NaN first, because some ports
(specifically the i386) do not emit correct ieee-fp code by default, and
thus will generate a core dump here if we pass a NaN to REAL_VALUES_EQUAL
@@ -2234,10 +2228,10 @@ immed_real_const_1 (d, mode)
else if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_EQUAL (dconst2, d))
return CONST2_RTX (mode);
- if (sizeof u == sizeof (HOST_WIDE_INT))
- return immed_double_const (u.i[0], 0, mode);
- if (sizeof u == 2 * sizeof (HOST_WIDE_INT))
- return immed_double_const (u.i[0], u.i[1], mode);
+ if (sizeof (REAL_VALUE_TYPE) == sizeof (HOST_WIDE_INT))
+ return immed_double_const (d.r[0], 0, mode);
+ if (sizeof (REAL_VALUE_TYPE) == 2 * sizeof (HOST_WIDE_INT))
+ return immed_double_const (d.r[0], d.r[1], mode);
/* The rest of this function handles the case where
a float value requires more than 2 ints of space.
@@ -2247,7 +2241,7 @@ immed_real_const_1 (d, mode)
If one is found, return it. */
if (cfun != 0)
for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
- if (! memcmp ((char *) &CONST_DOUBLE_LOW (r), (char *) &u, sizeof u)
+ if (! memcmp ((char *) &CONST_DOUBLE_LOW (r), (char *) &d, sizeof d)
&& GET_MODE (r) == mode)
return r;
@@ -2259,7 +2253,7 @@ immed_real_const_1 (d, mode)
freed memory. */
r = rtx_alloc (CONST_DOUBLE);
PUT_MODE (r, mode);
- memcpy ((char *) &CONST_DOUBLE_LOW (r), (char *) &u, sizeof u);
+ memcpy ((char *) &CONST_DOUBLE_LOW (r), (char *) &d, sizeof d);
/* If we aren't inside a function, don't put r on the
const_double_chain. */
@@ -2383,7 +2377,7 @@ struct rtx_const
ENUM_BITFIELD(kind) kind : 16;
ENUM_BITFIELD(machine_mode) mode : 16;
union {
- union real_extract du;
+ REAL_VALUE_TYPE du;
struct addr_const addr;
struct {HOST_WIDE_INT high, low;} di;
@@ -3571,8 +3565,7 @@ decode_rtx_const (mode, x, value)
if (GET_MODE (x) != VOIDmode)
{
value->mode = GET_MODE (x);
- memcpy ((char *) &value->un.du,
- (char *) &CONST_DOUBLE_LOW (x), sizeof value->un.du);
+ REAL_VALUE_FROM_CONST_DOUBLE (value->un.du, x);
}
else
{
@@ -3962,7 +3955,7 @@ output_constant_pool (fnname, fndecl)
{
struct pool_constant *pool;
rtx x;
- union real_extract u;
+ REAL_VALUE_TYPE r;
/* It is possible for gcc to call force_const_mem and then to later
discard the instructions which refer to the constant. In such a
@@ -4040,8 +4033,8 @@ output_constant_pool (fnname, fndecl)
if (GET_CODE (x) != CONST_DOUBLE)
abort ();
- memcpy ((char *) &u, (char *) &CONST_DOUBLE_LOW (x), sizeof u);
- assemble_real (u.d, pool->mode, pool->align);
+ REAL_VALUE_FROM_CONST_DOUBLE (r, x);
+ assemble_real (r, pool->mode, pool->align);
break;
case MODE_INT:
@@ -4062,10 +4055,8 @@ output_constant_pool (fnname, fndecl)
for (i = 0; i < units; i++)
{
elt = CONST_VECTOR_ELT (x, i);
- memcpy ((char *) &u,
- (char *) &CONST_DOUBLE_LOW (elt),
- sizeof u);
- assemble_real (u.d, GET_MODE_INNER (pool->mode), pool->align);
+ REAL_VALUE_FROM_CONST_DOUBLE (r, elt);
+ assemble_real (r, GET_MODE_INNER (pool->mode), pool->align);
}
}
break;
OpenPOWER on IntegriCloud