m68k.c (strict_low_part_peephole_ok): Don't leave the basic block.
authorRoman Zippel <zippel@linux-m68k.org>
Mon, 24 Sep 2007 21:02:40 +0000 (21:02 +0000)
committerRoman Zippel <zippel@gcc.gnu.org>
Mon, 24 Sep 2007 21:02:40 +0000 (21:02 +0000)
* config/m68k/m68k.c (strict_low_part_peephole_ok): Don't leave
the basic block.
* config/m68k/m68k.md (movsi_m68k): Allow certain constant when
reload is completed.
(peephole pattern): Convert most of them to RTL peephole pattern.

From-SVN: r128728

gcc/ChangeLog
gcc/config/m68k/m68k.c
gcc/config/m68k/m68k.md

index c092fec34fe258b11f036d6a6fd09df0fb2b1418..100a62cbdb2f891c53cdc3a9cc0c57ae94473b63 100644 (file)
@@ -1,3 +1,11 @@
+2007-09-24  Roman Zippel <zippel@linux-m68k.org> 
+       * config/m68k/m68k.c (strict_low_part_peephole_ok): Don't leave
+       the basic block.
+       * config/m68k/m68k.md (movsi_m68k): Allow certain constant when
+       reload is completed.
+       (peephole pattern): Convert most of them to RTL peephole pattern.
+
 2007-09-24  Roman Zippel <zippel@linux-m68k.org> 
 
        * config/m68k/m68k.c (notice_update_cc): Recognize fp compare
index 1f6b4f9fde7a7b198b6d7ae51d62c66f5228fe65..1df869fdf40eda13c6defd70e27b055607ea203f 100644 (file)
@@ -3963,14 +3963,18 @@ bool
 strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn,
                              rtx target)
 {
-  rtx p;
+  rtx p = first_insn;
 
-  p = prev_nonnote_insn (first_insn);
-
-  while (p)
+  while ((p = PREV_INSN (p)))
     {
+      if (NOTE_INSN_BASIC_BLOCK_P (p))
+       return false;
+
+      if (NOTE_P (p))
+       continue;
+
       /* If it isn't an insn, then give up.  */
-      if (GET_CODE (p) != INSN)
+      if (!INSN_P (p))
        return false;
 
       if (reg_set_p (target, p))
@@ -4000,8 +4004,6 @@ strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn,
          else
            return false;
        }
-
-      p = prev_nonnote_insn (p);
     }
 
   return false;
index b6ce6a8df0ea5c3562f5db4e63a1f840c04c8120..68053b33b707c3ac266ea06f282fe9a978ccba60 100644 (file)
     }
 })
 
-;; General case of fullword move.  The register constraints
-;; force integer constants in range for a moveq to be reloaded
-;; if they are headed for memory.
-(define_insn ""
+;; General case of fullword move.
+(define_insn "*movsi_m68k"
   ;; Notes: make sure no alternative allows g vs g.
   ;; We don't allow f-regs since fixed point cannot go in them.
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
+        (match_operand:SI 1 "general_src_operand" "damSnT,n,i"))]
+  "!TARGET_COLDFIRE && reload_completed"
+{
+  return output_move_simode (operands);
+})
+
+;; Before reload is completed the register constraints
+;; force integer constants in range for a moveq to be reloaded
+;; if they are headed for memory.
+(define_insn "*movsi_m68k2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
         (match_operand:SI 1 "general_src_operand" "damSKT,n,i"))]
 
 ;; and then is moved into an FP register.
 ;; But it is mainly intended to test the support for these optimizations.
 
-(define_peephole
+(define_peephole2
   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
-   (set (match_operand:DF 0 "register_operand" "=f")
-       (match_operand:DF 1 "register_operand" "ad"))]
-  "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
-{
-  rtx xoperands[2];
-  xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
-  output_asm_insn ("move%.l %1,%@", xoperands);
-  output_asm_insn ("move%.l %1,%-", operands);
-  return "fmove%.d %+,%0";
-})
+   (set (match_operand:DF 0 "register_operand" "")
+       (match_operand:DF 1 "register_operand" ""))]
+  "FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
+  [(set (mem:SI (reg:SI SP_REG)) (match_dup 1))
+   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 2))
+   (set (match_dup 0) (mem:DF (post_inc:SI (reg:SI SP_REG))))]
+  "split_di(operands + 1, 1, operands + 1, operands + 2);")
 
 ;; Optimize a stack-adjust followed by a push of an argument.
 ;; This is said to happen frequently with -msoft-float
 ;; when there are consecutive library calls.
 
-(define_peephole
+(define_peephole2
+  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
+   (set (match_operand:SF 0 "push_operand" "")
+       (match_operand:SF 1 "general_operand" ""))]
+  "!reg_mentioned_p (stack_pointer_rtx, operands[0])"
+  [(set (match_dup 0) (match_dup 1))]
+  "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);")
+
+(define_peephole2
   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
-                                (match_operand:SI 0 "const_int_operand" "n")))
-   (set (match_operand:SF 1 "push_operand" "=m")
-       (match_operand:SF 2 "general_operand" "rmfF"))]
-  "INTVAL (operands[0]) >= 4
-   && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
+                                (match_operand:SI 0 "const_int_operand" "")))
+   (set (match_operand:SF 1 "push_operand" "")
+       (match_operand:SF 2 "general_operand" ""))]
+  "INTVAL (operands[0]) > 4
+   && !reg_mentioned_p (stack_pointer_rtx, operands[2])"
+  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
+   (set (match_dup 1) (match_dup 2))]
 {
-  if (INTVAL (operands[0]) > 4)
-    {
-      rtx xoperands[2];
-      xoperands[0] = stack_pointer_rtx;
-      xoperands[1] = GEN_INT (INTVAL (operands[0]) - 4);
-      if (INTVAL (xoperands[1]) <= 8)
-       {
-         if (!TARGET_COLDFIRE)
-           output_asm_insn ("addq%.w %1,%0", xoperands);
-         else
-           output_asm_insn ("addq%.l %1,%0", xoperands);
-       }
-      else if (TUNE_CPU32 && INTVAL (xoperands[1]) <= 16)
-       {
-         xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 8);
-         output_asm_insn ("addq%.w #8,%0\;addq%.w %1,%0", xoperands);
-       }
-      else if (INTVAL (xoperands[1]) <= 0x7FFF)
-        {
-         if (TUNE_68040)
-           output_asm_insn ("add%.w %1,%0", xoperands);
-         else if (MOTOROLA)
-           output_asm_insn ("lea (%c1,%0),%0", xoperands);
-         else
-           output_asm_insn ("lea %0@(%c1),%0", xoperands);
-        }
-      else
-        output_asm_insn ("add%.l %1,%0", xoperands);
-    }
-  if (FP_REG_P (operands[2]))
-    return "fmove%.s %2,%@";
-  return "move%.l %2,%@";
+  operands[0] = GEN_INT (INTVAL (operands[0]) - 4);
+  operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
 })
 
 ;; Speed up stack adjust followed by a fullword fixedpoint push.
+;; Constant operands need special care, as replacing a "pea X.w" with
+;; "move.l #X,(%sp)" is often not a win.
 
-(define_peephole
+;; Already done by the previous csa pass, left as reference.
+(define_peephole2
+  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
+   (set (match_operand:SI 0 "push_operand" "")
+       (match_operand:SI 1 "general_operand" ""))]
+  "!reg_mentioned_p (stack_pointer_rtx, operands[1])"
+  [(set (match_dup 0) (match_dup 1))]
+  "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);")
+
+;; Try to use moveq, after stack push has been changed into a simple move.
+(define_peephole2
+  [(match_scratch:SI 2 "d")
+   (set (match_operand:SI 0 "memory_operand" "")
+       (match_operand:SI 1 "const_int_operand" ""))]
+  "GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
+   && INTVAL (operands[1]) != 0
+   && IN_RANGE (INTVAL (operands[1]), -0x80, 0x7f)
+   && !valid_mov3q_const (INTVAL (operands[1]))"
+  [(set (match_dup 2) (match_dup 1))
+   (set (match_dup 0) (match_dup 2))])
+
+;; This sequence adds an instruction, but is two bytes shorter.
+(define_peephole2
+  [(match_scratch:SI 2 "d")
+   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 12)))
+   (set (match_operand:SI 0 "push_operand" "")
+       (match_operand:SI 1 "const_int_operand" ""))]
+  "INTVAL (operands[1]) != 0
+   && IN_RANGE (INTVAL (operands[1]), -0x80, 0x7f)
+   && !valid_mov3q_const (INTVAL (operands[1]))"
+  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
+   (set (match_dup 2) (match_dup 1))
+   (set (match_dup 0) (match_dup 2))]
+  "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);")
+
+;; Changing pea X.w into a move.l is no real win here.
+(define_peephole2
   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
-                                (match_operand:SI 0 "const_int_operand" "n")))
-   (set (match_operand:SI 1 "push_operand" "=m")
-       (match_operand:SI 2 "general_operand" "g"))]
-  "INTVAL (operands[0]) >= 4
-   && ! reg_mentioned_p (stack_pointer_rtx, operands[2])"
-{
-  if (INTVAL (operands[0]) > 4)
-    {
-      rtx xoperands[2];
-      xoperands[0] = stack_pointer_rtx;
-      xoperands[1] = GEN_INT (INTVAL (operands[0]) - 4);
-      if (INTVAL (xoperands[1]) <= 8)
-       {
-         if (!TARGET_COLDFIRE)
-           output_asm_insn ("addq%.w %1,%0", xoperands);
-         else
-           output_asm_insn ("addq%.l %1,%0", xoperands);
-       }
-      else if (TUNE_CPU32 && INTVAL (xoperands[1]) <= 16)
-       {
-         xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 8);
-         output_asm_insn ("addq%.w #8,%0\;addq%.w %1,%0", xoperands);
-       }
-      else if (INTVAL (xoperands[1]) <= 0x7FFF)
-        {
-         if (TUNE_68040)
-           output_asm_insn ("add%.w %1,%0", xoperands);
-         else if (MOTOROLA)
-           output_asm_insn ("lea (%c1,%0),%0", xoperands);
-         else
-           output_asm_insn ("lea %0@(%c1),%0", xoperands);
-        }
-      else
-        output_asm_insn ("add%.l %1,%0", xoperands);
-    }
-  if (operands[2] == const0_rtx)
-    return "clr%.l %@";
-  return "move%.l %2,%@";
-})
-
-;; Speed up pushing a single byte but leaving four bytes of space.
-
-(define_peephole
-  [(set (mem:QI (pre_dec:SI (reg:SI SP_REG)))
-       (match_operand:QI 1 "general_operand" "dami"))
-   (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (const_int 2)))]
-  "! reg_mentioned_p (stack_pointer_rtx, operands[1])"
-{
-  rtx xoperands[4];
-
-  if (GET_CODE (operands[1]) == REG)
-    return "move%.l %1,%-";
-
-  xoperands[1] = operands[1];
-  xoperands[2]
-    = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, 3));
-  xoperands[3] = stack_pointer_rtx;
-  if (!TARGET_COLDFIRE)
-    output_asm_insn ("subq%.w #4,%3\;move%.b %1,%2", xoperands);
-  else
-    output_asm_insn ("subq%.l #4,%3\;move%.b %1,%2", xoperands);
-  return "";
-})
+                                (match_operand:SI 0 "const_int_operand" "")))
+   (set (match_operand:SI 1 "push_operand" "")
+       (match_operand:SI 2 "general_operand" ""))]
+  "INTVAL (operands[0]) > 4
+   && !reg_mentioned_p (stack_pointer_rtx, operands[2])
+   && !(CONST_INT_P (operands[2]) && INTVAL (operands[2]) != 0
+       && IN_RANGE (INTVAL (operands[2]), -0x8000, 0x7fff)
+       && !valid_mov3q_const (INTVAL (operands[2])))"
+  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
+   (set (match_dup 1) (match_dup 2))]
+{
+  operands[0] = GEN_INT (INTVAL (operands[0]) - 4);
+  operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
+})
+
+;; Speed up pushing a single byte/two bytes but leaving four bytes of space
+;; (which differs slightly between m680x0 and ColdFire).
+
+(define_peephole2
+  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
+   (set (match_operand:QI 0 "memory_operand" "")
+       (match_operand:QI 1 "register_operand" ""))]
+  "!reg_mentioned_p (stack_pointer_rtx, operands[1])
+   && GET_CODE (XEXP (operands[0], 0)) == PLUS
+   && rtx_equal_p (XEXP (XEXP (operands[0], 0), 0), stack_pointer_rtx)
+   && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1))
+   && INTVAL (XEXP (XEXP (operands[0], 0), 1)) == 3"
+  [(set (match_dup 0) (match_dup 1))]
+{
+  rtx addr = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
+  operands[0] = adjust_automodify_address (operands[0], SImode, addr, -3);
+  operands[1] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
+})
+
+(define_peephole2
+  [(set (match_operand:QI 0 "push_operand" "")
+       (match_operand:QI 1 "register_operand" ""))
+   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -3)))]
+  "!reg_mentioned_p (stack_pointer_rtx, operands[1])"
+  [(set (match_dup 0) (match_dup 1))]
+{
+  operands[0] = adjust_automodify_address (operands[0], SImode,
+                                          XEXP (operands[0], 0), -3);
+  operands[1] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
+})
+
+(define_peephole2
+  [(set (match_operand:HI 0 "push_operand" "")
+       (match_operand:HI 1 "register_operand" ""))
+   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))]
+  "!reg_mentioned_p (stack_pointer_rtx, operands[1])"
+  [(set (match_dup 0) (match_dup 1))]
+{
+  operands[0] = adjust_automodify_address (operands[0], SImode,
+                                          XEXP (operands[0], 0), -2);
+  operands[1] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
+})
+
+;; Optimize a series of strict_low_part assignments
+
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+       (const_int 0))
+   (set (strict_low_part (match_operand:HI 1 "register_operand" ""))
+       (match_operand:HI 2 "general_operand" ""))]
+  "REGNO (operands[0]) == REGNO (operands[1])
+   && strict_low_part_peephole_ok (HImode, insn, operands[0])"
+  [(set (strict_low_part (match_dup 1)) (match_dup 2))]
+  "")
 
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=d")
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
        (const_int 0))
-   (set (strict_low_part (subreg:HI (match_dup 0) 2))
-       (match_operand:HI 1 "general_operand" "rmn"))]
-  "strict_low_part_peephole_ok (HImode, prev_nonnote_insn (insn), operands[0])"
-{
-  if (GET_CODE (operands[1]) == CONST_INT)
-    {
-      if (operands[1] == const0_rtx
-         && (DATA_REG_P (operands[0])
-             || GET_CODE (operands[0]) == MEM)
-         /* clr insns on 68000 read before writing.  */
-         && ((TARGET_68010 || TARGET_COLDFIRE)
-             || !(GET_CODE (operands[0]) == MEM
-                  && MEM_VOLATILE_P (operands[0]))))
-       return "clr%.w %0";
-    }
-  return "move%.w %1,%0";
-})
+   (set (strict_low_part (match_operand:QI 1 "register_operand" ""))
+       (match_operand:QI 2 "general_operand" ""))]
+  "REGNO (operands[0]) == REGNO (operands[1])
+   && strict_low_part_peephole_ok (QImode, insn, operands[0])"
+  [(set (strict_low_part (match_dup 1)) (match_dup 2))]
+  "")
 
 ;; dbCC peepholes
 ;;