Commit 39250081 by Roman Zippel Committed by Roman Zippel

m68k.c (strict_low_part_peephole_ok): Don't leave the basic block.

	* 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
parent 67595cbb
2007-09-24 Roman Zippel <zippel@linux-m68k.org> 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 * config/m68k/m68k.c (notice_update_cc): Recognize fp compare
(moved from fp compare patterns). (moved from fp compare patterns).
...@@ -3963,14 +3963,18 @@ bool ...@@ -3963,14 +3963,18 @@ bool
strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn, strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn,
rtx target) rtx target)
{ {
rtx p; rtx p = first_insn;
p = prev_nonnote_insn (first_insn); while ((p = PREV_INSN (p)))
while (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 it isn't an insn, then give up. */
if (GET_CODE (p) != INSN) if (!INSN_P (p))
return false; return false;
if (reg_set_p (target, p)) if (reg_set_p (target, p))
...@@ -4000,8 +4004,6 @@ strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn, ...@@ -4000,8 +4004,6 @@ strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn,
else else
return false; return false;
} }
p = prev_nonnote_insn (p);
} }
return false; return false;
......
...@@ -900,13 +900,22 @@ ...@@ -900,13 +900,22 @@
} }
}) })
;; General case of fullword move. The register constraints ;; General case of fullword move.
;; force integer constants in range for a moveq to be reloaded (define_insn "*movsi_m68k"
;; if they are headed for memory.
(define_insn ""
;; Notes: make sure no alternative allows g vs g. ;; Notes: make sure no alternative allows g vs g.
;; We don't allow f-regs since fixed point cannot go in them. ;; We don't allow f-regs since fixed point cannot go in them.
[(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<") [(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"))] (match_operand:SI 1 "general_src_operand" "damSKT,n,i"))]
"!TARGET_COLDFIRE" "!TARGET_COLDFIRE"
...@@ -7292,153 +7301,163 @@ ...@@ -7292,153 +7301,163 @@
;; and then is moved into an FP register. ;; and then is moved into an FP register.
;; But it is mainly intended to test the support for these optimizations. ;; 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 (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
(set (match_operand:DF 0 "register_operand" "=f") (set (match_operand:DF 0 "register_operand" "")
(match_operand:DF 1 "register_operand" "ad"))] (match_operand:DF 1 "register_operand" ""))]
"FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" "FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
{ [(set (mem:SI (reg:SI SP_REG)) (match_dup 1))
rtx xoperands[2]; (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 2))
xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); (set (match_dup 0) (mem:DF (post_inc:SI (reg:SI SP_REG))))]
output_asm_insn ("move%.l %1,%@", xoperands); "split_di(operands + 1, 1, operands + 1, operands + 2);")
output_asm_insn ("move%.l %1,%-", operands);
return "fmove%.d %+,%0";
})
;; Optimize a stack-adjust followed by a push of an argument. ;; Optimize a stack-adjust followed by a push of an argument.
;; This is said to happen frequently with -msoft-float ;; This is said to happen frequently with -msoft-float
;; when there are consecutive library calls. ;; 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) [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
(match_operand:SI 0 "const_int_operand" "n"))) (match_operand:SI 0 "const_int_operand" "")))
(set (match_operand:SF 1 "push_operand" "=m") (set (match_operand:SF 1 "push_operand" "")
(match_operand:SF 2 "general_operand" "rmfF"))] (match_operand:SF 2 "general_operand" ""))]
"INTVAL (operands[0]) >= 4 "INTVAL (operands[0]) > 4
&& ! reg_mentioned_p (stack_pointer_rtx, operands[2])" && !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) operands[0] = GEN_INT (INTVAL (operands[0]) - 4);
{ operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
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,%@";
}) })
;; Speed up stack adjust followed by a fullword fixedpoint push. ;; 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) [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
(match_operand:SI 0 "const_int_operand" "n"))) (match_operand:SI 0 "const_int_operand" "")))
(set (match_operand:SI 1 "push_operand" "=m") (set (match_operand:SI 1 "push_operand" "")
(match_operand:SI 2 "general_operand" "g"))] (match_operand:SI 2 "general_operand" ""))]
"INTVAL (operands[0]) >= 4 "INTVAL (operands[0]) > 4
&& ! reg_mentioned_p (stack_pointer_rtx, operands[2])" && !reg_mentioned_p (stack_pointer_rtx, operands[2])
{ && !(CONST_INT_P (operands[2]) && INTVAL (operands[2]) != 0
if (INTVAL (operands[0]) > 4) && IN_RANGE (INTVAL (operands[2]), -0x8000, 0x7fff)
{ && !valid_mov3q_const (INTVAL (operands[2])))"
rtx xoperands[2]; [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
xoperands[0] = stack_pointer_rtx; (set (match_dup 1) (match_dup 2))]
xoperands[1] = GEN_INT (INTVAL (operands[0]) - 4); {
if (INTVAL (xoperands[1]) <= 8) operands[0] = GEN_INT (INTVAL (operands[0]) - 4);
{ operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
if (!TARGET_COLDFIRE) })
output_asm_insn ("addq%.w %1,%0", xoperands);
else ;; Speed up pushing a single byte/two bytes but leaving four bytes of space
output_asm_insn ("addq%.l %1,%0", xoperands); ;; (which differs slightly between m680x0 and ColdFire).
}
else if (TUNE_CPU32 && INTVAL (xoperands[1]) <= 16) (define_peephole2
{ [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 8); (set (match_operand:QI 0 "memory_operand" "")
output_asm_insn ("addq%.w #8,%0\;addq%.w %1,%0", xoperands); (match_operand:QI 1 "register_operand" ""))]
} "!reg_mentioned_p (stack_pointer_rtx, operands[1])
else if (INTVAL (xoperands[1]) <= 0x7FFF) && GET_CODE (XEXP (operands[0], 0)) == PLUS
{ && rtx_equal_p (XEXP (XEXP (operands[0], 0), 0), stack_pointer_rtx)
if (TUNE_68040) && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1))
output_asm_insn ("add%.w %1,%0", xoperands); && INTVAL (XEXP (XEXP (operands[0], 0), 1)) == 3"
else if (MOTOROLA) [(set (match_dup 0) (match_dup 1))]
output_asm_insn ("lea (%c1,%0),%0", xoperands); {
else rtx addr = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
output_asm_insn ("lea %0@(%c1),%0", xoperands); operands[0] = adjust_automodify_address (operands[0], SImode, addr, -3);
} operands[1] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
else })
output_asm_insn ("add%.l %1,%0", xoperands);
} (define_peephole2
if (operands[2] == const0_rtx) [(set (match_operand:QI 0 "push_operand" "")
return "clr%.l %@"; (match_operand:QI 1 "register_operand" ""))
return "move%.l %2,%@"; (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))]
;; Speed up pushing a single byte but leaving four bytes of space. {
operands[0] = adjust_automodify_address (operands[0], SImode,
(define_peephole XEXP (operands[0], 0), -3);
[(set (mem:QI (pre_dec:SI (reg:SI SP_REG))) operands[1] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
(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:HI 0 "push_operand" "")
rtx xoperands[4]; (match_operand:HI 1 "register_operand" ""))
(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))]
if (GET_CODE (operands[1]) == REG) "!reg_mentioned_p (stack_pointer_rtx, operands[1])"
return "move%.l %1,%-"; [(set (match_dup 0) (match_dup 1))]
{
xoperands[1] = operands[1]; operands[0] = adjust_automodify_address (operands[0], SImode,
xoperands[2] XEXP (operands[0], 0), -2);
= gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, 3)); operands[1] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
xoperands[3] = stack_pointer_rtx; })
if (!TARGET_COLDFIRE)
output_asm_insn ("subq%.w #4,%3\;move%.b %1,%2", xoperands); ;; Optimize a series of strict_low_part assignments
else
output_asm_insn ("subq%.l #4,%3\;move%.b %1,%2", xoperands); (define_peephole2
return ""; [(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 (define_peephole2
[(set (match_operand:SI 0 "register_operand" "=d") [(set (match_operand:SI 0 "register_operand" "")
(const_int 0)) (const_int 0))
(set (strict_low_part (subreg:HI (match_dup 0) 2)) (set (strict_low_part (match_operand:QI 1 "register_operand" ""))
(match_operand:HI 1 "general_operand" "rmn"))] (match_operand:QI 2 "general_operand" ""))]
"strict_low_part_peephole_ok (HImode, prev_nonnote_insn (insn), operands[0])" "REGNO (operands[0]) == REGNO (operands[1])
{ && strict_low_part_peephole_ok (QImode, insn, operands[0])"
if (GET_CODE (operands[1]) == CONST_INT) [(set (strict_low_part (match_dup 1)) (match_dup 2))]
{ "")
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";
})
;; dbCC peepholes ;; dbCC peepholes
;; ;;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment