]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
real.h: Don't define REAL_INFINITY or REAL_IS_NOT_DOUBLE.
authorZack Weinberg <zack@gcc.gnu.org>
Sat, 23 Mar 2002 01:10:56 +0000 (01:10 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Sat, 23 Mar 2002 01:10:56 +0000 (01:10 +0000)
* 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

38 files changed:
gcc/ChangeLog
gcc/ch/ChangeLog
gcc/ch/grant.c
gcc/config/1750a/1750a-protos.h
gcc/config/1750a/1750a.c
gcc/config/a29k/a29k.c
gcc/config/a29k/a29k.md
gcc/config/arm/arm.c
gcc/config/arm/arm.md
gcc/config/convex/convex.c
gcc/config/convex/convex.h
gcc/config/dsp16xx/dsp16xx.c
gcc/config/dsp16xx/dsp16xx.md
gcc/config/i370/i370.h
gcc/config/i860/i860.c
gcc/config/m88k/m88k.c
gcc/config/m88k/m88k.md
gcc/config/ns32k/merlin.h
gcc/config/ns32k/ns32k.c
gcc/config/pdp11/pdp11.c
gcc/config/pdp11/pdp11.h
gcc/config/romp/romp.c
gcc/config/s390/s390.h
gcc/config/vax/vax.c
gcc/config/we32k/we32k.h
gcc/config/xtensa/xtensa.c
gcc/cp/ChangeLog
gcc/cp/error.c
gcc/doc/rtl.texi
gcc/doc/tm.texi
gcc/emit-rtl.c
gcc/fold-const.c
gcc/libgcc2.c
gcc/print-rtl.c
gcc/real.c
gcc/real.h
gcc/simplify-rtx.c
gcc/varasm.c

index 1616ef618f74b62449e04d1ad612d747cd689ee3..287ddeb12d8df80294806b160ade2c75017b4961 100644 (file)
@@ -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.
 
 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.
 
index df0d0f580aebbb0a9017884eb08157fc37634349..5dafdbb353f7c70f435edf21df44d0e33000bf36 100644 (file)
@@ -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,
index f143aec47086d5ac2c9b2d7e87c7ce56b60c7b26..48973e0851c42902d2608ce256242877276960c6 100644 (file)
@@ -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;
 
index aa2b41fbea02953e0163186c03d25b3690d32626..c437f00f3e176bdb30df8d715b4115f2b9853b21 100644 (file)
@@ -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));
index 099f7c73818b0d19ea68bd7bdbe91acbcd05b728..c8b6a796efc2db967fe508f255a38501182e3585 100644 (file)
@@ -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:
index 3291bab5b245fc12233a48fa98d17fc8d8494bdd..bd08c38c78697d0764835e141ca3566ac75c9ea7 100644 (file)
@@ -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
index 596aa4707e5d50d1816180fde983d16585ce033b..d4e4f34595f245ef3f306f33f2d5fecf41aa263e 100644 (file)
 (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))]
   "
index f07a281f4a3691aeaa86694647f1666b788e1a84..814c84d9888d4b2fafd60e694dab14b7c4dc0693 100644 (file)
@@ -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]);
            }
index cdab5c66ff80743c214928c36ca56fcb25f3f476..9ea7d0c8a06d21beb208f5fcc4e624effad42444 100644 (file)
       {
       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:
       {
        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:
index bee0f173076d4de19cf86249fb8324e37234b57f..74af45ec2a5754da2755a317417a53ac9b392964 100644 (file)
@@ -515,12 +515,12 @@ expand_movstr_call (operands)
                     TYPE_MODE (sizetype));
 }
 \f
-#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')
index 7ed4e4539d92b0dc12ddf1b6b76143868ca03470..d50f60b0fd2d8ff2624bffe56485ffa269dfad24 100644 (file)
@@ -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) \
index 674a3f08eba2edcaa50d72e849be4e6f749f909d..7f5cc0b06c42009821637508287e42c7fda69b03 100644 (file)
@@ -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
index 7cea24a1ac5f38c515791bc3b56b42570bf2087e..31247ba38f81e6d31f03c21b2b54f0ad41124ef0 100644 (file)
   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 */
     {
index 112758c7ad00a0340ae930a188d889ad03a41e0b..adcaca675d78b329d6d0df0acd4cb46025c78185 100644 (file)
@@ -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;                                                          \
index 5538baffae7d6e8449e952d26c1348e3d57f4da1..18493976615d5b935907510fd88ccd1e758a9b2f 100644 (file)
@@ -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;
 }
 \f
 /* This function generates the assembly code for function entry.
index d53bffdfffb18b315356be8415aa490367bf4c08..80f3ff44b4792920699eace994b208eb3cfcc116 100644 (file)
@@ -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 */
index 75b9d2c50100e25b16ab4c9c5413696ea6f0bba6..24a66f86ec8ecfb52775a5addcd246f5d6bb5e24 100644 (file)
   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))
index a3b41baf260e7f89586d10d0549c531ad7f173fc..f38870dd3fc6808eba19f2531faea3d582711cef 100644 (file)
@@ -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 */
 
index 9feef5e00670ad8fce0571d7d1383f991246ed87..8c980c577b3373faa280b4eb50c62c9ccefee788 100644 (file)
@@ -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
        }
     }
index cff6fbf67928183952f65e2d3a1d1e1958a13926..3643db6d28154b90a5f82b85c50213a4391d5b4f 100644 (file)
@@ -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";
          }
              
index 53888ee03f812b87831bf9833b6033c992a9a07b..99bb7fe32d529af1240ef7f4f840cf4af46130aa 100644 (file)
@@ -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); }}
 \f
 /* Print a memory address as an operand to reference that memory location.  */
index 7f984e876d87d8fda8d59e5bd8095c72200898d3..a4813be29cdb4c73cbcee22ff2a2b409449f4422 100644 (file)
@@ -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
index 96d91fad457ef161cc6ad8a24829b6590b759b71..1ab431e1f41bf5fc205ce465f35cc4e97e565462 100644 (file)
@@ -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:                                                         \
index 8be850a0030223bd64a320af2e0f645183c45ddc..9665609df2a4c6ce58b93925fd813805222cdcf0 100644 (file)
@@ -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;
 }
 
index eec05ab32116ffb4479ef57d42d3e57ea31d911d..1bf6805d1e7138cdcb909085bc764b2fdc5ee990 100644 (file)
@@ -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); }}
 \f
index e24525bd1d6237b62462141328f917eff13335fa..a791da00fb75c529690b97545e5c5193e4312218 100644 (file)
@@ -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:
index 87679b8fce5495fc157fed51a5cb8b24f1517e3a..01a5f67c83b2e15218e3da4405d119c829758bac 100644 (file)
@@ -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
index 20352e01b54191874dc0b7326cbc5d2a3c163bfc..077181f7dd73bd4553ab62f82cfc6d9f9f29c019 100644 (file)
@@ -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;
 
index 58faea99f78e7ac16948ef6d412e45fb4fe67d72..10c81e47d65567ac8ec0fd03d759fcca5014bc68 100644 (file)
@@ -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
index 3f37cdb3e6003d896784072f490b0018d4fd31d4..ac44ee356406a6d6bd49581e3dcfd215b23ca2e0 100644 (file)
@@ -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
index d54bacab6b95c4ae6eed240ece3b9282e61bc88a..7f1e92b5f4d7e2c1d7a04d7bb97d21db71e711c4 100644 (file)
@@ -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);
 
index 39d18bb30fa3b6851791c743b90d844cf9aff164..b89b7804cd7604a94091978867a28ba297dba487 100644 (file)
@@ -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)
index 08bfc3438e37a16390858c07ccaa1ceb91b1b447..cab925665c2d4e774d6c215b5243b1dbc36f3f7e 100644 (file)
@@ -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)
index b819d143a340c88d89b7d916bfa97ec239d29369..496613bf949ae2ad5b50879a7d6a43357bf6b658 100644 (file)
@@ -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
index bac0690523007a6cd2586d10115ad36c786b6108..8674ee897d9a1cc479aa23f9b63bd9ecbbc71faa 100644 (file)
@@ -607,16 +607,9 @@ 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;
index e734b26548e8e207a44657fa0b93d22ca5dfeedc..d3cf780ef33a6e8beb8bd99addd7c5cc62823d4d 100644 (file)
@@ -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.  */
 
index 21012ce31a3a3d4e6af11ac59d30777d78ec781e..53f8293078e92a24019044f4f33cdc751cab6a1c 100644 (file)
@@ -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);
index 098757edd64e29438410801debfefd4da14dd8d7..ef9e87242cd4428e5241b45d9a30056c2ecdbfd7 100644 (file)
@@ -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;