*** empty log message ***
authorRichard Stallman <rms@gnu.org>
Mon, 22 Jun 1992 03:40:10 +0000 (03:40 +0000)
committerRichard Stallman <rms@gnu.org>
Mon, 22 Jun 1992 03:40:10 +0000 (03:40 +0000)
From-SVN: r1232

gcc/cse.c
gcc/fold-const.c
gcc/real.h
gcc/reload1.c

index e945768f1fdf396ba1fccc031c1dd7c560c5c00d..aaff89243992460a45f38887f15472df268ddf4c 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -2921,7 +2921,7 @@ simplify_unary_operation (code, mode, op, op_mode)
          break;
 
        case FLOAT_TRUNCATE:
-         d = (double) REAL_VALUE_TRUNCATE (mode, d);
+         d = (double) real_value_truncate (mode, d);
          break;
 
        case FLOAT_EXTEND:
@@ -3061,8 +3061,8 @@ simplify_binary_operation (code, mode, op0, op1)
 
       REAL_VALUE_FROM_CONST_DOUBLE (f0, op0);
       REAL_VALUE_FROM_CONST_DOUBLE (f1, op1);
-      f0 = REAL_VALUE_TRUNCATE (mode, f0);
-      f1 = REAL_VALUE_TRUNCATE (mode, f1);
+      f0 = real_value_truncate (mode, f0);
+      f1 = real_value_truncate (mode, f1);
 
 #ifdef REAL_ARITHMETIC
       REAL_ARITHMETIC (value, code, f0, f1);
@@ -3097,7 +3097,7 @@ simplify_binary_operation (code, mode, op0, op1)
 #endif
 
       set_float_handler (0);
-      value = REAL_VALUE_TRUNCATE (mode, value);
+      value = real_value_truncate (mode, value);
       return immed_real_const_1 (value, mode);
     }
 
index 0bc6db3e55ef6c3103756cedf8b91f7e9ae5f619..a8a3f370727ab7bea18bc6d81eda879e52c379da 100644 (file)
@@ -699,6 +699,35 @@ div_and_round_double (code, uns,
   add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
 }
 \f
+/* Effectively truncate a real value to represent
+   the nearest possible value in a narrower mode.
+   The result is actually represented in the same data type as the argument,
+   but its value is usually different.  */
+
+REAL_VALUE_TYPE
+real_value_truncate (mode, arg)
+     enum machine_mode mode;
+     REAL_VALUE_TYPE arg;
+{
+#ifdef __STDC__
+  /* Make sure the value is actually stored in memory before we turn off
+     the handler.  */
+  volatile
+#endif
+    REAL_VALUE_TYPE value;
+  jmp_buf handler;
+
+  if (setjmp (handler))
+    {
+      error ("floating overflow");
+      return dconst0;
+    }
+  set_float_handler (handler);
+  value = REAL_VALUE_TRUNCATE (mode, arg);
+  set_float_handler (0);
+  return value;
+}
+
 #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
 
 /* Check for infinity in an IEEE double precision number.  */
@@ -1215,7 +1244,7 @@ const_binop (code, arg1, arg2)
        }
 #endif /* no REAL_ARITHMETIC */
       t = build_real (TREE_TYPE (arg1),
-                     REAL_VALUE_TRUNCATE (TYPE_MODE (TREE_TYPE (arg1)), value));
+                     real_value_truncate (TYPE_MODE (TREE_TYPE (arg1)), value));
       set_float_handler (0);
       return t;
     }
@@ -1423,7 +1452,7 @@ fold_convert (t, arg1)
            }
          set_float_handler (float_error);
 
-         t = build_real (type, REAL_VALUE_TRUNCATE (TYPE_MODE (type),
+         t = build_real (type, real_value_truncate (TYPE_MODE (type),
                                                     TREE_REAL_CST (arg1)));
          set_float_handler (0);
          return t;
index 571eb5d453cca61a0d467e550fcfa874cfb3437f..e191944cb2d3facb415b79255bba876f8cf95148 100644 (file)
@@ -154,6 +154,9 @@ extern double (atof) ();
    for the most common case where the host and target have objects of the same
    size and where `float' is SFmode.  */
 
+/* Don't use REAL_VALUE_TRUNCATE directly--always call real_value_truncate.  */
+extern REAL_VALUE_TYPE real_value_truncate ();
+
 #ifndef REAL_VALUE_TRUNCATE
 #define REAL_VALUE_TRUNCATE(mode, x) \
  (GET_MODE_BITSIZE (mode) == sizeof (float) * HOST_BITS_PER_CHAR       \
index 526e7db13289f2d73e8afcfb37d853f9aadb59dd..4cf074c196389b5146ed2aa266da224a5ae67ac2 100644 (file)
@@ -319,6 +319,7 @@ static void reload_as_needed ();
 static int modes_equiv_for_class_p ();
 static void alter_reg ();
 static void delete_dead_insn ();
+static void spill_failure ();
 static int new_spill_reg();
 static void set_label_offsets ();
 static int eliminate_regs_in_insn ();
@@ -477,9 +478,12 @@ init_reload ()
    DUMPFILE is the global-reg debugging dump file stream, or 0.
    If it is nonzero, messages are written to it to describe
    which registers are seized as reload regs, which pseudo regs
-   are spilled from them, and where the pseudo regs are reallocated to.  */
+   are spilled from them, and where the pseudo regs are reallocated to.
 
-void
+   Return value is nonzero if reload failed
+   and we must not do any more for this function.  */
+
+int
 reload (first, global, dumpfile)
      rtx first;
      int global;
@@ -497,6 +501,9 @@ reload (first, global, dumpfile)
   enum reg_class caller_save_spill_class = NO_REGS;
   int caller_save_group_size = 1;
 
+  /* Nonzero means we couldn't get enough spill regs.  */
+  int failure = 0;
+
   /* The basic block number currently being processed for INSN.  */
   int this_block;
 
@@ -777,12 +784,19 @@ reload (first, global, dumpfile)
         they must be the same size and equally restrictive for that class,
         otherwise we can't handle the complexity.  */
       enum machine_mode group_mode[N_REG_CLASSES];
+      /* Record the insn where each maximum need is first found.  */
+      rtx max_needs_insn[N_REG_CLASSES];
+      rtx max_groups_insn[N_REG_CLASSES];
+      rtx max_nongroups_insn[N_REG_CLASSES];
       rtx x;
 
       something_changed = 0;
       bzero (max_needs, sizeof max_needs);
       bzero (max_groups, sizeof max_groups);
       bzero (max_nongroups, sizeof max_nongroups);
+      bzero (max_needs_insn, sizeof max_needs_insn);
+      bzero (max_groups_insn, sizeof max_groups_insn);
+      bzero (max_nongroups_insn, sizeof max_nongroups_insn);
       bzero (group_size, sizeof group_size);
       for (i = 0; i < N_REG_CLASSES; i++)
        group_mode[i] = VOIDmode;
@@ -1271,12 +1285,21 @@ reload (first, global, dumpfile)
              for (i = 0; i < N_REG_CLASSES; i++)
                {
                  if (max_needs[i] < insn_needs[i])
-                   max_needs[i] = insn_needs[i];
+                   {
+                     max_needs[i] = insn_needs[i];
+                     max_needs_insn[i] = insn;
+                   }
                  if (max_groups[i] < insn_groups[i])
-                   max_groups[i] = insn_groups[i];
+                   {
+                     max_groups[i] = insn_groups[i];
+                     max_groups_insn[i] = insn;
+                   }
                  if (insn_total_groups > 0)
                    if (max_nongroups[i] < insn_needs[i])
-                     max_nongroups[i] = insn_needs[i];
+                     {
+                       max_nongroups[i] = insn_needs[i];
+                       max_nongroups_insn[i] = insn;
+                     }
                }
            }
          /* Note that there is a continue statement above.  */
@@ -1567,9 +1590,17 @@ reload (first, global, dumpfile)
                  /* I should be the index in potential_reload_regs
                     of the new reload reg we have found.  */
 
-                 something_changed
-                   |= new_spill_reg (i, class, max_needs, 0,
-                                     global, dumpfile);
+                 if (i >= FIRST_PSEUDO_REGISTER)
+                   {
+                     /* There are no groups left to spill.  */
+                     spill_failure (max_groups_insn[class]);
+                     failure = 1;
+                     goto failed;
+                   }
+                 else
+                   something_changed
+                     |= new_spill_reg (i, class, max_needs, 0,
+                                       global, dumpfile);
                }
              else
                {
@@ -1600,9 +1631,17 @@ reload (first, global, dumpfile)
                                  for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
                                    if (potential_reload_regs[idx] == j + k)
                                      break;
-                                 something_changed
-                                   |= new_spill_reg (idx, class, max_needs, 0,
-                                                     global, dumpfile);
+                                   if (i >= FIRST_PSEUDO_REGISTER)
+                                     {
+                                       /* There are no groups left.  */
+                                       spill_failure (max_groups_insn[class]);
+                                       failure = 1;
+                                       goto failed;
+                                     }
+                                   else
+                                     something_changed
+                                       |= new_spill_reg (idx, class, max_needs, 0,
+                                                         global, dumpfile);
                                }
 
                              /* We have found one that will complete a group,
@@ -1648,9 +1687,18 @@ reload (first, global, dumpfile)
              /* I should be the index in potential_reload_regs
                 of the new reload reg we have found.  */
 
-             something_changed
-               |= new_spill_reg (i, class, max_needs, max_nongroups,
-                                 global, dumpfile);
+             if (i >= FIRST_PSEUDO_REGISTER)
+               {
+                 /* There are no possible registers left to spill.  */
+                 spill_failure (max_needs[class] > 0 ? max_needs_insn[class]
+                                : max_nongroups_insn[class]);
+                 failure = 1;
+                 goto failed;
+               }
+             else
+               something_changed
+                 |= new_spill_reg (i, class, max_needs, max_nongroups,
+                                   global, dumpfile);
            }
        }
     }
@@ -1706,6 +1754,10 @@ reload (first, global, dumpfile)
 
   reload_in_progress = 0;
 
+  /* Come here (with failure set nonzero) if we can't get enough spill regs
+     and we decide not to abort about it.  */
+ failed:
+
   /* Now eliminate all pseudo regs by modifying them into
      their equivalent memory references.
      The REG-rtx's for the pseudos are modified in place,
@@ -1766,6 +1818,8 @@ reload (first, global, dumpfile)
   /* Indicate that we no longer have known memory locations or constants.  */
   reg_equiv_constant = 0;
   reg_equiv_memory_loc = 0;
+
+  return failure;
 }
 \f
 /* Nonzero if, after spilling reg REGNO for non-groups,
@@ -1917,6 +1971,19 @@ modes_equiv_for_class_p (allocate_mode, other_mode, class)
   return 1;
 }
 
+/* Handle the failure to find a register to spill.
+   INSN should be one of the insns which needed this particular spill reg.  */
+
+static void
+spill_failure (insn)
+     rtx insn;
+{
+  if (asm_noperands (PATTERN (insn)) >= 0)
+    error_for_asm (insn, "`asm' needs too many reloads");
+  else
+    abort ();
+}
+
 /* Add a new register to the tables of available spill-registers
     (as well as spilling all pseudos allocated to the register).
    I is the index of this register in potential_reload_regs.