Commit d87e83b9 by Stephane Carrez Committed by Stephane Carrez

m68hc11.md (move peephole2): New peepholes to optimize sequences of moves.

	* config/m68hc11/m68hc11.md (move peephole2): New peepholes to optimize
	sequences of moves.
	(add peepholes): New peepholes to optimize sequences adding small
	constants.
	(bset peepholes): New peepholes to transform an OR in a bset form
	(bclr peepholes): Likewise for bclr form.
	(cmp peepholes): New peepholes to avoid register copies when comparing.

From-SVN: r78787
parent d5111c9c
2004-03-02 Stephane Carrez <stcarrez@nerim.fr> 2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
* config/m68hc11/m68hc11.md (move peephole2): New peepholes to optimize
sequences of moves.
(add peepholes): New peepholes to optimize sequences adding small
constants.
(bset peepholes): New peepholes to transform an OR in a bset form
(bclr peepholes): Likewise for bclr form.
(cmp peepholes): New peepholes to avoid register copies when comparing.
2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
* config/m68hc11/m68hc11.md ("*pushdi_internal"): New insn and split * config/m68hc11/m68hc11.md ("*pushdi_internal"): New insn and split
to separate push from moves. to separate push from moves.
("*pushdf_internal"): Likewise. ("*pushdf_internal"): Likewise.
......
...@@ -6907,6 +6907,61 @@ ...@@ -6907,6 +6907,61 @@
gen_rtx_POST_INC (HImode, gen_rtx_POST_INC (HImode,
gen_rtx_REG (HImode, HARD_SP_REGNUM)));") gen_rtx_REG (HImode, HARD_SP_REGNUM)));")
;; Replace: "pshx; tfr d,x; stx 0,sp" into "pshd; tfr d,x"
(define_peephole2
[(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
(match_operand:HI 0 "hard_reg_operand" ""))
(set (match_dup 0)
(match_operand:HI 1 "hard_reg_operand" ""))
(set (mem:HI (reg:HI SP_REGNUM))
(match_dup 0))]
"TARGET_M6812"
[(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
(match_dup 1))
(set (match_dup 0) (match_dup 1))]
"")
;;
;; Change: "ldd 0,sp; pulx" into "puld"
;; This sequence usually appears at end a functions.
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
(mem:HI (reg:HI SP_REGNUM)))
(use (match_dup 0))
(set (match_operand:HI 1 "hard_reg_operand" "")
(mem:HI (post_inc:HI (reg:HI SP_REGNUM))))]
"peep2_reg_dead_p (2, operands[1])"
[(set (match_dup 0) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))
(use (match_dup 0))]
"")
;; Replace: "pshx; clr 0,sp; clr 1,sp" by "clr 1,-sp; clr 1,-sp"
;; Appears to allocate local variables.
(define_peephole2
[(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
(match_operand:HI 0 "hard_reg_operand" ""))
(set (mem:QI (plus:HI (reg:HI SP_REGNUM) (const_int 1)))
(const_int 0))
(set (mem:QI (reg:HI SP_REGNUM))
(const_int 0))]
"TARGET_M6812"
[(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
(const_int 0))]
"")
;; Likewise for HI mode
(define_peephole2
[(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
(match_operand:HI 0 "hard_reg_operand" ""))
(set (mem:HI (reg:HI SP_REGNUM))
(const_int 0))]
"TARGET_M6812"
[(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM)))
(const_int 0))]
"")
;;--------------------------------------------------------------------
;;-
;;--------------------------------------------------------------------
;; ;;
;; Optimize memory<->memory moves when the value is also loaded in ;; Optimize memory<->memory moves when the value is also loaded in
;; a register. ;; a register.
...@@ -6971,6 +7026,36 @@ ...@@ -6971,6 +7026,36 @@
"") "")
;; ;;
;; Replace: "ldx #N; xgdx; addd <var>; xgdx" by "ldab #N; ldx <var>; abx"
;;
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
(match_operand:HI 1 "const_int_operand" ""))
(set (match_dup 0)
(plus:HI (match_dup 0)
(match_operand:HI 2 "general_operand" "")))
(match_scratch:QI 3 "d")]
"TARGET_M6811 && (INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 0x0ff)"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0) (match_dup 2))
(set (match_dup 0) (plus:HI (zero_extend:HI (match_dup 3)) (match_dup 0)))]
"operands[4] = m68hc11_gen_lowpart (QImode, operands[1]);")
;;
;; Replace: "ldx #N; xgdx; addd <var>; xgdx" by "ldab #N; ldx <var>; abx"
;;
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
(match_operand:HI 1 "const_int_operand" ""))
(set (match_dup 0)
(plus:HI (match_dup 0)
(match_operand:HI 2 "general_operand" "")))]
"TARGET_M6812"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))]
"")
;;
;; Optimize an address register increment and a compare to use ;; Optimize an address register increment and a compare to use
;; a PRE_INC or PRE_DEC addressing mode (disabled on the tst insn ;; a PRE_INC or PRE_DEC addressing mode (disabled on the tst insn
;; before reload, but can be enabled after). ;; before reload, but can be enabled after).
...@@ -7062,6 +7147,31 @@ ...@@ -7062,6 +7147,31 @@
"") "")
;; ;;
;;
;;
(define_peephole2
[(parallel
[(set (match_operand:SI 0 "hard_reg_operand" "")
(ashift:SI (match_operand:SI 1 "general_operand" "")
(const_int 1)))
(clobber (match_scratch:HI 2 ""))])
(set (match_operand:HI 3 "nonimmediate_operand" "") (reg:HI D_REGNUM))
(set (match_operand:HI 4 "nonimmediate_operand" "") (reg:HI X_REGNUM))]
"!X_REG_P (operands[1])
&& peep2_reg_dead_p (2, gen_rtx (REG, HImode, D_REGNUM))
&& peep2_reg_dead_p (3, gen_rtx (REG, HImode, X_REGNUM))"
[(set (reg:HI D_REGNUM) (match_dup 5))
(set (reg:HI D_REGNUM) (ashift:HI (reg:HI D_REGNUM) (const_int 1)))
(set (match_dup 3) (reg:HI D_REGNUM))
(set (reg:HI D_REGNUM) (match_dup 6))
(parallel [(set (reg:HI D_REGNUM)
(rotate:HI (reg:HI D_REGNUM) (const_int 1)))
(clobber (reg:HI CC_REGNUM))])
(set (match_dup 4) (reg:HI D_REGNUM))]
"operands[5] = m68hc11_gen_lowpart (HImode, operands[1]);
operands[6] = m68hc11_gen_highpart (HImode, operands[1]);")
;;
;; Replace a "ldd <mem>; psha; pshb" with a "ldx <mem>; pshx". ;; Replace a "ldd <mem>; psha; pshb" with a "ldx <mem>; pshx".
;; ;;
(define_peephole2 (define_peephole2
...@@ -7076,6 +7186,25 @@ ...@@ -7076,6 +7186,25 @@
"") "")
;; ;;
;; Remove one load when copying a value to/from memory and also
;; to a register. Take care not cloberring a possible register used
;; by operand 2.
;; Replace: "ldd 0,y; std 2,y; ldx 0,y" into "ldx 0,y; stx 2,y"
;;
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
(match_operand:HI 1 "general_operand" ""))
(set (match_operand:HI 2 "nonimmediate_operand" "") (match_dup 0))
(set (match_operand:HI 3 "hard_reg_operand" "") (match_dup 1))]
"peep2_reg_dead_p (2, operands[0])
&& !side_effects_p (operands[1])
&& !side_effects_p (operands[2])
&& !reg_mentioned_p (operands[3], operands[2])"
[(set (match_dup 3) (match_dup 1))
(set (match_dup 2) (match_dup 3))]
"")
;;
;; Replace a "ldd <mem>; addd #N; std <mem>" into a ;; Replace a "ldd <mem>; addd #N; std <mem>" into a
;; "ldx <mem>; leax; stx <mem>" if we have a free X/Y register ;; "ldx <mem>; leax; stx <mem>" if we have a free X/Y register
;; and the constant is small. ;; and the constant is small.
...@@ -7098,6 +7227,174 @@ ...@@ -7098,6 +7227,174 @@
"if (reg_mentioned_p (operands[4], operands[1])) FAIL; "if (reg_mentioned_p (operands[4], operands[1])) FAIL;
if (reg_mentioned_p (operands[4], operands[3])) FAIL;") if (reg_mentioned_p (operands[4], operands[3])) FAIL;")
;;--------------------------------------------------------------------
;;- Bset peephole2
;;--------------------------------------------------------------------
;; These peepholes try to replace some logical sequences by 'bset' and 'bclr'.
;;
;; Replace 'ldab <mem>; orab #N; stab <mem>' by 'bset <mem> #N'.
;; Register D must be dead and there must be no register side effects for mem.
;; The <mem> *can* be volatile this is why we must not use 'side_effects_p'.
;; The good side effect is that it makes the sequence atomic.
;;
(define_peephole2
[(set (match_operand:QI 0 "hard_reg_operand" "")
(match_operand:QI 1 "nonimmediate_operand" ""))
(set (match_dup 0) (ior:QI (match_dup 0)
(match_operand:QI 2 "const_int_operand" "")))
(set (match_dup 1) (match_dup 0))]
"(TARGET_M6812 || m68hc11_indirect_p (operands[1], QImode))
&& (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0)))
&& peep2_reg_dead_p (3, operands[0])"
[(set (match_dup 1) (ior:QI (match_dup 1) (match_dup 2)))]
"")
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
(match_operand:HI 1 "nonimmediate_operand" ""))
(set (match_dup 0) (ior:HI (match_dup 0)
(match_operand:HI 2 "const_int_operand" "")))
(set (match_dup 1) (match_dup 0))]
"(TARGET_M6812 || m68hc11_indirect_p (operands[1], HImode))
&& (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0)))
&& peep2_reg_dead_p (3, operands[0])"
[(set (match_dup 1) (ior:HI (match_dup 1) (match_dup 2)))]
"")
;;--------------------------------------------------------------------
;;- Bclr peephole2
;;--------------------------------------------------------------------
;; Replace 'ldab <mem>; andab #N; stab <mem>' by 'bclr <mem> #N'.
;; See Bset peephole2.
;;
(define_peephole2
[(set (match_operand:QI 0 "hard_reg_operand" "")
(match_operand:QI 1 "nonimmediate_operand" ""))
(set (match_dup 0) (and:QI (match_dup 0)
(match_operand:QI 2 "const_int_operand" "")))
(set (match_dup 1) (match_dup 0))]
"(TARGET_M6812 || m68hc11_indirect_p (operands[1], QImode))
&& (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0)))
&& peep2_reg_dead_p (3, operands[0])"
[(set (match_dup 1) (and:QI (match_dup 1) (match_dup 2)))]
"")
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
(match_operand:HI 1 "nonimmediate_operand" ""))
(set (match_dup 0) (and:HI (match_dup 0)
(match_operand:HI 2 "const_int_operand" "")))
(set (match_dup 1) (match_dup 0))]
"(TARGET_M6812 || m68hc11_indirect_p (operands[1], HImode))
&& (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0)))
&& peep2_reg_dead_p (3, operands[0])"
[(set (match_dup 1) (and:HI (match_dup 1) (match_dup 2)))]
"")
;;--------------------------------------------------------------------
;;- Compare peephole2
;;--------------------------------------------------------------------
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
(match_operand:HI 1 "hard_reg_operand" ""))
(set (match_dup 1) (plus:HI (match_dup 1)
(match_operand:HI 2 "const_int_operand" "")))
(set (cc0) (match_dup 0))]
"peep2_reg_dead_p (3, operands[0]) && !Z_REG_P (operands[1])"
[(set (match_dup 1) (plus:HI (match_dup 1) (match_dup 2)))
(set (cc0) (compare (match_dup 1) (match_dup 2)))]
"")
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
(match_operand:HI 1 "hard_reg_operand" ""))
(set (match_operand:HI 2 "hard_reg_operand" "")
(plus:HI (match_dup 2)
(match_operand:HI 3 "const_int_operand" "")))
(set (match_operand:HI 4 "memory_operand" "") (match_dup 2))
(set (cc0) (match_operand:HI 5 "hard_reg_operand" ""))]
"peep2_reg_dead_p (4, operands[5]) && !Z_REG_P (operands[2])
&& !reg_mentioned_p (operands[2], operands[4])
&& ((rtx_equal_p (operands[5], operands[0])
&& rtx_equal_p (operands[2], operands[1]))
|| (rtx_equal_p (operands[5], operands[1])
&& rtx_equal_p (operands[2], operands[0])))"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 2) (plus:HI (match_dup 2) (match_dup 3)))
(set (match_dup 4) (match_dup 2))
(set (cc0) (compare (match_dup 2) (match_dup 3)))]
"")
;;--------------------------------------------------------------------
;;- Load peephole2
;;--------------------------------------------------------------------
;;
;; Optimize initialization of 2 hard regs from the same memory location
;; Since we can't copy easily X, Y and D to each other, load the 2 registers
;; from the same memory location.
;;
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
(match_operand:HI 1 "memory_operand" ""))
(set (match_operand:HI 2 "hard_reg_operand" "") (match_dup 0))]
"TARGET_M6811
&& !side_effects_p (operands[1])
&& !reg_mentioned_p (operands[0], operands[1])"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2) (match_dup 1))]
"")
;; Replace "ldd #N; addd <op>" with "ldd <op>; addd #N".
;;
(define_peephole2
[(set (match_operand:HI 0 "nonimmediate_operand" "") (const_int 0))
(set (match_operand:HI 1 "nonimmediate_operand" "") (const_int 0))
(set (match_operand:HI 2 "nonimmediate_operand" "") (const_int 0))
(set (match_operand:HI 3 "nonimmediate_operand" "") (const_int 0))
(match_scratch:HI 4 "d")]
""
[(set (match_dup 4) (const_int 0))
(set (match_dup 0) (match_dup 4))
(set (match_dup 1) (match_dup 4))
(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 4))]
"")
;;
;; Replace "ldd #N; addd <op>" with "ldd <op>; addd #N".
;;
(define_peephole2
[(set (match_operand:HI 0 "nonimmediate_operand" "") (const_int 0))
(set (match_operand:HI 1 "nonimmediate_operand" "") (const_int 0))
(set (match_operand:HI 2 "nonimmediate_operand" "") (const_int 0))
(match_scratch:HI 3 "d")]
""
[(set (match_dup 3) (const_int 0))
(set (match_dup 0) (match_dup 3))
(set (match_dup 1) (match_dup 3))
(set (match_dup 2) (match_dup 3))]
"")
;;
;; Replace "ldd #N; addd <op>" with "ldd <op>; addd #N".
;;
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "") (const_int 0))
(set (match_operand:HI 1 "push_operand" "") (match_dup 0))
(set (match_operand:HI 2 "push_operand" "") (match_dup 0))
(set (match_operand:HI 3 "push_operand" "") (match_dup 0))
(match_scratch:HI 4 "x")]
"TARGET_M6811 && D_REG_P (operands[0]) && peep2_reg_dead_p (4, operands[0])"
[(set (match_dup 4) (const_int 0))
(set (match_dup 1) (match_dup 4))
(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 4))]
"")
;; ;;
;; This peephole catches the address computations generated by the reload ;; This peephole catches the address computations generated by the reload
;; pass. ;; pass.
...@@ -7367,3 +7664,41 @@ ...@@ -7367,3 +7664,41 @@
return \"sts\\t%t0\\n\\tld%0\\t%t0\"; return \"sts\\t%t0\\n\\tld%0\\t%t0\";
} }
") ")
(define_peephole
[(set (match_operand:HI 0 "hard_reg_operand" "")
(match_operand:HI 1 "memory_operand" ""))
(set (match_operand:HI 2 "hard_reg_operand" "") (match_dup 0))]
"TARGET_M6811
&& !side_effects_p (operands[1])
&& !reg_mentioned_p (operands[0], operands[1])"
"*
{
rtx ops[2];
ops[0] = operands[0];
ops[1] = operands[1];
m68hc11_gen_movhi (insn, ops);
ops[0] = operands[2];
m68hc11_gen_movhi (insn, ops);
return \"\";
}")
;; Peephole for Z register replacement.
;; Avoid to use _.tmp register when comparing D and X if we can compare
;; with soft register
(define_peephole
[(set (match_operand:HI 0 "hard_reg_operand" "") (reg:HI SOFT_XY_REGNUM))
(set (reg:HI SOFT_TMP_REGNUM) (match_dup 0))
(set (cc0) (compare (match_operand:HI 2 "hard_reg_operand" "")
(reg:HI SOFT_TMP_REGNUM)))]
"X_REG_P (operands[0]) || Y_REG_P (operands[0])"
"*
{
rtx ops[2];
ops[0] = operands[0];
ops[1] = operands[1];
m68hc11_gen_movhi (insn, ops);
return \"cp%2\\t%1\";
}")
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