OSDN Git Service

2012-02-24 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / recog.c
index ae05204..8f04179 100644 (file)
@@ -925,10 +925,7 @@ next_insn_tests_no_inequality (rtx insn)
    it has.
 
    The main use of this function is as a predicate in match_operand
-   expressions in the machine description.
-
-   For an explanation of this function's behavior for registers of
-   class NO_REGS, see the comment for `register_operand'.  */
+   expressions in the machine description.  */
 
 int
 general_operand (rtx op, enum machine_mode mode)
@@ -998,9 +995,8 @@ general_operand (rtx op, enum machine_mode mode)
     }
 
   if (code == REG)
-    /* A register whose class is NO_REGS is not a general operand.  */
     return (REGNO (op) >= FIRST_PSEUDO_REGISTER
-           || REGNO_REG_CLASS (REGNO (op)) != NO_REGS);
+           || in_hard_reg_set_p (operand_reg_set, GET_MODE (op), REGNO (op)));
 
   if (code == MEM)
     {
@@ -1033,15 +1029,7 @@ address_operand (rtx op, enum machine_mode mode)
    If MODE is VOIDmode, accept a register in any mode.
 
    The main use of this function is as a predicate in match_operand
-   expressions in the machine description.
-
-   As a special exception, registers whose class is NO_REGS are
-   not accepted by `register_operand'.  The reason for this change
-   is to allow the representation of special architecture artifacts
-   (such as a condition code register) without extending the rtl
-   definitions.  Since registers of class NO_REGS cannot be used
-   as registers in any case where register classes are examined,
-   it is most consistent to keep this function from accepting them.  */
+   expressions in the machine description.  */
 
 int
 register_operand (rtx op, enum machine_mode mode)
@@ -1080,11 +1068,10 @@ register_operand (rtx op, enum machine_mode mode)
       op = sub;
     }
 
-  /* We don't consider registers whose class is NO_REGS
-     to be a register operand.  */
   return (REG_P (op)
          && (REGNO (op) >= FIRST_PSEUDO_REGISTER
-             || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
+             || in_hard_reg_set_p (operand_reg_set,
+                                   GET_MODE (op), REGNO (op))));
 }
 
 /* Return 1 for a register in Pmode; ignore the tested mode.  */
@@ -1203,11 +1190,10 @@ nonmemory_operand (rtx op, enum machine_mode mode)
       op = SUBREG_REG (op);
     }
 
-  /* We don't consider registers whose class is NO_REGS
-     to be a register operand.  */
   return (REG_P (op)
          && (REGNO (op) >= FIRST_PSEUDO_REGISTER
-             || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
+             || in_hard_reg_set_p (operand_reg_set,
+                                   GET_MODE (op), REGNO (op))));
 }
 
 /* Return 1 if OP is a valid operand that stands for pushing a
@@ -2281,7 +2267,8 @@ preprocess_constraints (void)
                case 'p':
                  op_alt[j].is_address = 1;
                  op_alt[j].cl = reg_class_subunion[(int) op_alt[j].cl]
-                     [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
+                     [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
+                                            ADDRESS, SCRATCH)];
                  break;
 
                case 'g':
@@ -2302,8 +2289,8 @@ preprocess_constraints (void)
                      op_alt[j].cl
                        = (reg_class_subunion
                           [(int) op_alt[j].cl]
-                          [(int) base_reg_class (VOIDmode, ADDRESS,
-                                                 SCRATCH)]);
+                          [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
+                                                 ADDRESS, SCRATCH)]);
                      break;
                    }
 
@@ -3051,6 +3038,7 @@ peep2_find_free_register (int from, int to, const char *class_str,
   static int search_ofs;
   enum reg_class cl;
   HARD_REG_SET live;
+  df_ref *def_rec;
   int i;
 
   gcc_assert (from < MAX_INSNS_PER_PEEP2 + 1);
@@ -3064,12 +3052,14 @@ peep2_find_free_register (int from, int to, const char *class_str,
 
   while (from != to)
     {
-      HARD_REG_SET this_live;
+      gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
+
+      /* Don't use registers set or clobbered by the insn.  */
+      for (def_rec = DF_INSN_DEFS (peep2_insn_data[from].insn);
+          *def_rec; def_rec++)
+       SET_HARD_REG_BIT (live, DF_REF_REGNO (*def_rec));
 
       from = peep2_buf_position (from + 1);
-      gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
-      REG_SET_TO_HARD_REG_SET (this_live, peep2_insn_data[from].live_before);
-      IOR_HARD_REG_SET (live, this_live);
     }
 
   cl = (class_str[0] == 'r' ? GENERAL_REGS