This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[m68k 09/13] Convert some text peepholes
- From: zippel at linux-m68k dot org
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 30 Jan 2007 12:26:24 +0100
- Subject: [m68k 09/13] Convert some text peepholes
- References: <20070130112615.782382000@linux-m68k.org>
Hi,
This converts many of the current text peepholes into rtl peepholes
(only peepholes involving cc0 are left). The primary reason for doing
this is that these cause corrupt frame information, as they manipulate
the stack pointer. I also adjusted the conditions, so they actually
match again.
2007-01-30 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: convert text peepholes into rtl peepholes
* config/m68k/m68k.h (REGNO_OK_FOR_FP_P): remove
(FP_REG_P): use FP_REGNO_P directly without reg_renumber
---
gcc/config/m68k/m68k.c | 18 ++-
gcc/config/m68k/m68k.h | 6 -
gcc/config/m68k/m68k.md | 219 ++++++++++++++++++------------------------------
3 files changed, 97 insertions(+), 146 deletions(-)
Index: egcs/gcc/config/m68k/m68k.h
===================================================================
--- egcs.orig/gcc/config/m68k/m68k.h
+++ egcs/gcc/config/m68k/m68k.h
@@ -766,10 +766,6 @@ __transfer_from_trampoline () \
(DATA_REGNO_P (REGNO) \
|| DATA_REGNO_P (reg_renumber[REGNO]))
-#define REGNO_OK_FOR_FP_P(REGNO) \
- (FP_REGNO_P (REGNO) \
- || FP_REGNO_P (reg_renumber[REGNO]))
-
/* Now macros that check whether X is a register and also,
strictly, whether it is in a specified class.
@@ -781,7 +777,7 @@ __transfer_from_trampoline () \
#define DATA_REG_P(X) (REG_P (X) && REGNO_OK_FOR_DATA_P (REGNO (X)))
/* 1 if X is an fp register. */
-#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X)))
+#define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (X))
/* 1 if X is an address register */
#define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))
Index: egcs/gcc/config/m68k/m68k.md
===================================================================
--- egcs.orig/gcc/config/m68k/m68k.md
+++ egcs/gcc/config/m68k/m68k.md
@@ -653,13 +653,22 @@
}
})
-;; 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.
+;; General case of fullword move.
(define_insn ""
;; 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" "daymSnT,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 ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
(match_operand:SI 1 "general_src_operand" "daymSKT,n,i"))]
"!TARGET_COLDFIRE"
@@ -6634,153 +6643,97 @@
;; 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 (mem:SF (pre_dec:SI (reg:SI SP_REG)))
+ (match_operand:SF 0 "general_operand" ""))]
+ "!reg_mentioned_p (stack_pointer_rtx, operands[0])"
+ [(set (mem:SF (reg:SI SP_REG)) (match_dup 0))]
+ "")
+
+(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])"
-{
- 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,%@";
-})
+ (match_operand:SI 0 "const_int_operand" "")))
+ (set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
+ (match_operand:SF 1 "general_operand" ""))]
+ "INTVAL (operands[0]) > 4
+ && !reg_mentioned_p (stack_pointer_rtx, operands[1])"
+ [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
+ (set (mem:SF (reg:SI SP_REG)) (match_dup 1))]
+ "operands[0] = GEN_INT (INTVAL (operands[0]) - 4);")
;; 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) (const_int 4)))
+ (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
+ (match_operand:SI 0 "general_operand" ""))]
+ "!reg_mentioned_p (stack_pointer_rtx, operands[0])"
+ [(set (mem:SI (reg:SI SP_REG)) (match_dup 0))]
+ "")
+
+(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,%@";
-})
+ (match_operand:SI 0 "const_int_operand" "")))
+ (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
+ (match_operand:SI 1 "general_operand" ""))]
+ "INTVAL (operands[0]) > 4
+ && !reg_mentioned_p (stack_pointer_rtx, operands[1])"
+ [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
+ (set (mem:SI (reg:SI SP_REG)) (match_dup 1))]
+ "operands[0] = GEN_INT (INTVAL (operands[0]) - 4);")
;; 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,%-";
+(define_peephole2
+ [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
+ (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int 3)))
+ (match_operand:QI 0 "register_operand" ""))]
+ "!reg_mentioned_p (stack_pointer_rtx, operands[0])"
+ [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]
+ "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+
+(define_peephole2
+ [(set (mem:HI (pre_dec:SI (reg:SI SP_REG)))
+ (match_operand:HI 0 "register_operand" ""))
+ (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))]
+ "!reg_mentioned_p (stack_pointer_rtx, operands[0])"
+ [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]
+ "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
- 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 "";
-})
+(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
;;
Index: egcs/gcc/config/m68k/m68k.c
===================================================================
--- egcs.orig/gcc/config/m68k/m68k.c
+++ egcs/gcc/config/m68k/m68k.c
@@ -2484,7 +2484,7 @@ force_mode (enum machine_mode mode, rtx
static int
fp_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- return reg_renumber && FP_REG_P (op);
+ return FP_REG_P (op);
}
/* Emit insns to move operands[1] into operands[0].
@@ -3438,14 +3438,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))
@@ -3475,8 +3479,6 @@ strict_low_part_peephole_ok (enum machin
else
return false;
}
-
- p = prev_nonnote_insn (p);
}
return false;
--