OSDN Git Service

Undo June 11th change
[pf3gnuchains/gcc-fork.git] / gcc / regmove.c
index 81a9870..ee56db5 100644 (file)
@@ -47,6 +47,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 static int optimize_reg_copy_1 PROTO((rtx, rtx, rtx));
 static void optimize_reg_copy_2        PROTO((rtx, rtx, rtx));
 static void optimize_reg_copy_3        PROTO((rtx, rtx, rtx));
+static rtx gen_add3_insn       PROTO((rtx, rtx, rtx));
 
 struct match {
   int with[MAX_RECOG_OPERANDS];
@@ -65,6 +66,23 @@ static int reg_is_remote_constant_p PROTO((rtx, rtx, rtx));
 static int stable_but_for_p PROTO((rtx, rtx, rtx));
 static int loop_depth;
 
+/* Generate and return an insn body to add r1 and c,
+   storing the result in r0.  */
+static rtx
+gen_add3_insn (r0, r1, c)
+     rtx r0, r1, c;
+{
+  int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
+
+    if (icode == CODE_FOR_nothing
+      || ! (*insn_operand_predicate[icode][0]) (r0, insn_operand_mode[icode][0])
+      || ! (*insn_operand_predicate[icode][1]) (r1, insn_operand_mode[icode][1])
+      || ! (*insn_operand_predicate[icode][2]) (c, insn_operand_mode[icode][2]))
+    return NULL_RTX;
+
+  return (GEN_FCN (icode) (r0, r1, c));
+}
+
 #ifdef AUTO_INC_DEC
 
 /* INC_INSN is an instruction that adds INCREMENT to REG.
@@ -570,8 +588,24 @@ reg_is_remote_constant_p (reg, insn, first)
   return 0;
 }
 
+/* INSN is adding a CONST_INT to a REG.  We search backwards looking for
+   another add immediate instruction with the same source and dest registers,
+   and if we find one, we change INSN to an increment, and return 1.  If
+   no changes are made, we return 0.
+
+   This changes
+     (set (reg100) (plus reg1 offset1))
+     ...
+     (set (reg100) (plus reg1 offset2))
+   to
+     (set (reg100) (plus reg1 offset1))
+     ...
+     (set (reg100) (plus reg100 offset2-offset1))  */
+
+/* ??? What does this comment mean?  */
 /* cse disrupts preincrement / postdecrement squences when it finds a
    hard register as ultimate source, like the frame pointer.  */
+
 int
 fixup_match_2 (insn, dst, src, offset, regmove_dump_file)
      rtx insn, dst, src, offset;
@@ -623,8 +657,9 @@ fixup_match_2 (insn, dst, src, offset, regmove_dump_file)
         {
          HOST_WIDE_INT newconst
            = INTVAL (offset) - INTVAL (XEXP (SET_SRC (pset), 1));
-         if (validate_change (insn, &PATTERN (insn),
-                              gen_addsi3 (dst, dst, GEN_INT (newconst)), 0))
+         rtx add = gen_add3_insn (dst, dst, GEN_INT (newconst));
+
+         if (add && validate_change (insn, &PATTERN (insn), add, 0))
            {
              /* Remove the death note for DST from DST_DEATH.  */
              if (dst_death)
@@ -1143,6 +1178,11 @@ regmove_optimize (f, nregs, regmove_dump_file)
 #endif /* REGISTER_CONSTRAINTS */
 }
 
+/* Returns the INSN_CODE for INSN if its pattern has matching constraints for
+   any operand.  Returns -1 if INSN can't be recognized, or if the alternative
+   can't be determined.
+
+   Initialize the info in MATCHP based on the constraints.  */
 
 static int
 find_matches (insn, matchp)
@@ -1711,7 +1751,10 @@ stable_but_for_p (x, src, dst)
     }
 }
 
-/* Test if regmove seems profitable for this target.  */
+/* Test if regmove seems profitable for this target.  Regmove is useful only
+   if some common patterns are two address, i.e. require matching constraints,
+   so we check that condition here.  */
+
 int
 regmove_profitable_p ()
 {