[ColdFire 37/63] Use RTL for prologues and epilogues

Richard Sandiford richard@codesourcery.com
Wed Jan 10 11:50:00 GMT 2007


This patch is an update of:

    http://gcc.gnu.org/ml/gcc-patches/2005-12/msg01366.html

see there for rationale.  The changes from the original patch
are as follows:

  - It uses new predicates rather than separate HARD_FP_REG_P
    checks to request a particular type of register.

  - It avoids hard-coding (mem: ...)s into the output pattern
    as these MEMs will have no aliasing information.  (This would
    become important if we added scheduling descriptions later on.)
    Instead, it generates new forms of the original MEMs.

  - It stops the peepholes from emitting an addition of 0.

  - The current QImode peepholes use:

      [(set (mem:QI (pre_dec:SI (reg:SI SP_REG)))
            (match_operand:QI 0 "..." ""))
       (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (const_int 2)))]

    but given that we're generating an SImode access, I'm sure that
    that 2 was meant to be a 3.  The pattern should never match
    anyway because (minus ... (const_int ..)) isn't canonical.
    The patch fixes both problems.

  - The register form of the QImode peephole is a win on Coldfire
    too, so the patch continues to allow it there.

Richard


gcc/
200x-xx-xx  Paul Brook  <paul@codesourcery.com>
	    Richard Sandiford  <richard@codesourcery.com>

	* config/m68k/predicates.md (integer_register): New predicate.
	(float_register): Likewise.
	* config/m68k/m68k.md (UNSPEC_MOVEQ_MEM): New constant.
	(*movsi_smallconst): New pattern.
	Convert the first define_peephole to a define_peephole2.  Use
	float_register and integer_register than than separate REGNO
	checks.  Convert the second and third define_peepholes to
	define_peephole2s.  Convert the fourth define_peephole into two
	separate define_peephole2s, one for register sources and one for
	other types of source.  Fix the size of the separate stack
	adjustment and expect it to be a PLUS of a negative constant
	rather than a MINUS of a positive constant.

Index: gcc/config/m68k/predicates.md
===================================================================
--- gcc/config/m68k/predicates.md	2007-01-09 15:02:08.000000000 +0000
+++ gcc/config/m68k/predicates.md	2007-01-09 15:02:16.000000000 +0000
@@ -181,3 +181,15 @@ (define_predicate "post_inc_operand"
 (define_predicate "pre_dec_operand"
   (and (match_code "mem")
        (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")))
+
+;; A hard integer register
+
+(define_predicate "integer_register"
+  (and (match_code "reg")
+       (match_test "INT_REGNO_P (REGNO (op))")))
+
+;; A hard floating-point register
+
+(define_predicate "float_register"
+  (and (match_code "reg")
+       (match_test "FP_REGNO_P (REGNO (op))")))
Index: gcc/config/m68k/m68k.md
===================================================================
--- gcc/config/m68k/m68k.md	2007-01-09 15:02:15.000000000 +0000
+++ gcc/config/m68k/m68k.md	2007-01-09 15:02:16.000000000 +0000
@@ -114,7 +114,8 @@
 (define_constants
   [(UNSPEC_SIN 1)
    (UNSPEC_COS 2)
-   (UNSPEC_GOT 3)
+   (UNSPEC_MOVEQ_MEM 3)
+   (UNSPEC_GOT 4)
   ])
 
 ;; UNSPEC_VOLATILE usage:
@@ -685,6 +686,16 @@ (define_insn ""
   return output_move_simode (operands);
 })
 
+;; Move a constant suitable for moveq direct to memory.
+(define_insn "*movsi_smallconst"
+  [(set (match_operand:SI 0 "memory_operand" "=m")
+        (unspec:SI [(match_operand:SI 1 "const_int_operand" "")]
+		    UNSPEC_MOVEQ_MEM))]
+  "reload_completed && !TARGET_COLDFIRE"
+{
+  return output_move_simode (operands);
+})
+
 (define_insn "*movsi_cf"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g,U")
 	(match_operand:SI 1 "general_operand" "g,r<Q>,U"))]
@@ -6660,131 +6671,97 @@ (define_insn ""
 ;; 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 "float_register" "")
+	(match_operand:DF 1 "integer_register" ""))]
+  ""
+  [(set (mem:SI (reg:SI SP_REG)) (match_dup 2))
+   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 3))
+   (set (match_dup 0) (mem:DF (post_inc:SI (reg:SI SP_REG))))]
+{
+  operands[2] = simplify_gen_subreg (SImode, operands[1], DFmode, 4);
+  operands[3] = simplify_gen_subreg (SImode, operands[1], DFmode, 0);
 })
 
 ;; 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)
-				 (match_operand:SI 0 "const_int_operand" "n")))
-   (set (match_operand:SF 1 "push_operand" "=m")
-	(match_operand:SF 2 "general_operand" "rmfF"))]
+				 (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])"
-{
-  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,%@";
+   && !reg_mentioned_p (stack_pointer_rtx, operands[2])"
+  [(set (match_dup 3)
+	(match_dup 2))]
+{
+  if (INTVAL (operands[0]) != 4)
+    emit_insn (gen_add2_insn (stack_pointer_rtx,
+			      GEN_INT (INTVAL (operands[0]) - 4)));
+  operands[3] = replace_equiv_address (operands[1], stack_pointer_rtx);
 })
 
 ;; Speed up stack adjust followed by a fullword fixedpoint push.
 
-(define_peephole
+(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"))]
+				 (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])"
-{
-  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,%@";
+   && !reg_mentioned_p (stack_pointer_rtx, operands[2])"
+  [(set (match_dup 3)
+	(match_dup 2))]
+{
+  if (INTVAL (operands[0]) != 4)
+    emit_insn (gen_add2_insn (stack_pointer_rtx,
+			      GEN_INT (INTVAL (operands[0]) - 4)));
+  operands[3] = replace_equiv_address (operands[1], stack_pointer_rtx);
+
+  /* The 68k movsi pattern doesn't allow small constants to be moved
+     directly to memory.  */
+  if (!TARGET_COLDFIRE
+      && GET_CODE (operands[2]) == CONST_INT
+      && operands[2] != const0_rtx
+      && IN_RANGE (INTVAL (operands[2]), -0x80, 0x7f))
+    operands[2] = gen_rtx_UNSPEC (SImode, gen_rtvec (1, operands[2]),
+				  UNSPEC_MOVEQ_MEM);
 })
 
 ;; 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])"
+(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 2)
+	(match_dup 3))]
 {
-  rtx xoperands[4];
+  rtx addr;
 
-  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 "";
+  addr = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
+  operands[2] = adjust_automodify_address (operands[0], SImode, addr, -3);
+  operands[3] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
+})
+
+(define_peephole2
+  [(set (match_operand:QI 0 "push_operand" "")
+	(match_operand:QI 1 "general_operand" ""))
+   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -3)))]
+  ;; Disabled for coldfire because it isn't a size win.
+  "!TARGET_COLDFIRE
+   && !register_operand (operands[1], VOIDmode)
+   && !reg_mentioned_p (stack_pointer_rtx, operands[1])"
+  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
+   (set (match_dup 2)
+	(match_dup 1))]
+{
+  operands[2] = replace_equiv_address (operands[0],
+				       plus_constant (stack_pointer_rtx, 3));
 })
 
 (define_peephole



More information about the Gcc-patches mailing list