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>
* 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
(moved from fp compare patterns).
......@@ -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;
......
......@@ -900,13 +900,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.
(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"))]
"!TARGET_COLDFIRE"
......@@ -7292,153 +7301,163 @@
;; 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
;;
......
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