Commit 0ae32ec0 by Stephane Carrez Committed by Stephane Carrez

m68hc11.md ("decrement_and_branch_until_zero"): New pattern for dbcc/ibcc generation for 68HC12.

	* config/m68hc11/m68hc11.md ("decrement_and_branch_until_zero"): New
	pattern for dbcc/ibcc generation for 68HC12.
	("doloop_end"): New pattern.
	("m68hc12_dbcc_dec_hi"): New pattern for dbeq/dbne.
	("m68hc12_dbcc_inc_hi"): New pattern for ibeq/ibne.
	("m68hc12_dbcc_dec_qi"): New pattern.
	("m68hc12_dbcc_inc_qi"): New pattern.
	(split): Add split for the above when we can't use dbcc/ibcc due to
	reloading.
	(peephole2): Add peephole2 to generate the above when possible.

From-SVN: r65527
parent 4440f5b5
2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
* config/m68hc11/m68hc11.md ("decrement_and_branch_until_zero"): New
pattern for dbcc/ibcc generation for 68HC12.
("doloop_end"): New pattern.
("m68hc12_dbcc_dec_hi"): New pattern for dbeq/dbne.
("m68hc12_dbcc_inc_hi"): New pattern for ibeq/ibne.
("m68hc12_dbcc_dec_qi"): New pattern.
("m68hc12_dbcc_inc_qi"): New pattern.
(split): Add split for the above when we can't use dbcc/ibcc due to
reloading.
(peephole2): Add peephole2 to generate the above when possible.
2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
* config/m68hc11/m68hc11.md ("bitcmpqi" split): No need to test the
mode of operand 0.
(peephole2 optimize const load): Likewise for operand 2.
......
......@@ -5937,6 +5937,210 @@
"")
;;--------------------------------------------------------------------
;;- 68HC12 Decrement/Increment and branch
;;--------------------------------------------------------------------
;; These patterns are used by loop optimization as well as peephole2
;; They must handle reloading themselves and the scratch register
;; is used for that. Even if we accept memory operand, we must not
;; accept them on the predicate because it might create too many reloads.
;; (specially on HC12 due to its auto-incdec addressing modes).
;;
(define_expand "decrement_and_branch_until_zero"
[(parallel [(set (pc)
(if_then_else
(ne (plus:HI (match_operand:HI 0 "register_operand" "")
(const_int 0))
(const_int 1))
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_dup 0)
(plus:HI (match_dup 0)
(const_int -1)))
(clobber (match_scratch:HI 2 ""))])]
"TARGET_M6812"
"")
(define_expand "doloop_end"
[(use (match_operand 0 "" "")) ; loop pseudo
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
"TARGET_M6812"
"
{
/* Reject non-constant loops as it generates bigger code due to
the handling of the loop register. We can do better by using
the peephole2 dbcc/ibcc patterns. */
if (INTVAL (operands[1]) == 0)
{
FAIL;
}
if (GET_MODE (operands[0]) == HImode)
{
emit_jump_insn (gen_m68hc12_dbcc_dec_hi (operands[0],
gen_rtx (NE, HImode),
operands[4]));
DONE;
}
if (GET_MODE (operands[0]) == QImode)
{
emit_jump_insn (gen_m68hc12_dbcc_dec_qi (operands[0],
gen_rtx (NE, QImode),
operands[4]));
DONE;
}
FAIL;
}")
;; Decrement-and-branch insns.
(define_insn "m68hc12_dbcc_dec_hi"
[(set (pc)
(if_then_else
(match_operator 1 "m68hc11_eq_compare_operator"
[(match_operand:HI 0 "register_operand" "+dxy,m*u*z")
(const_int 1)])
(label_ref (match_operand 2 "" ""))
(pc)))
(set (match_dup 0)
(plus:HI (match_dup 0) (const_int -1)))
(clobber (match_scratch:HI 3 "=X,dxy"))]
"TARGET_M6812"
"*
{
if (!H_REG_P (operands[0]))
return \"#\";
CC_STATUS_INIT;
if (GET_CODE (operands[1]) == EQ)
return \"dbeq\\t%0,%l2\";
else
return \"dbne\\t%0,%l2\";
}")
;; Decrement-and-branch insns.
(define_insn "m68hc12_dbcc_inc_hi"
[(set (pc)
(if_then_else
(match_operator 1 "m68hc11_eq_compare_operator"
[(match_operand:HI 0 "register_operand" "+dxy,m*u*z")
(const_int -1)])
(label_ref (match_operand 2 "" ""))
(pc)))
(set (match_dup 0)
(plus:HI (match_dup 0) (const_int 1)))
(clobber (match_scratch:HI 3 "=X,dxy"))]
"TARGET_M6812"
"*
{
if (!H_REG_P (operands[0]))
return \"#\";
CC_STATUS_INIT;
if (GET_CODE (operands[1]) == EQ)
return \"ibeq\\t%0,%l2\";
else
return \"ibeq\\t%0,%l2\";
}")
;; Decrement-and-branch (QImode).
(define_insn "m68hc12_dbcc_dec_qi"
[(set (pc)
(if_then_else
(match_operator 1 "m68hc11_eq_compare_operator"
[(match_operand:QI 0 "register_operand" "+d,m*u*A")
(const_int 1)])
(label_ref (match_operand 2 "" ""))
(pc)))
(set (match_dup 0)
(plus:QI (match_dup 0) (const_int -1)))
(clobber (match_scratch:QI 3 "=X,d"))]
"TARGET_M6812"
"*
{
if (!D_REG_P (operands[0]))
return \"#\";
CC_STATUS_INIT;
if (GET_CODE (operands[1]) == EQ)
return \"dbeq\\tb,%l2\";
else
return \"dbne\\tb,%l2\";
}")
;; Increment-and-branch (QImode).
(define_insn "m68hc12_dbcc_inc_qi"
[(set (pc)
(if_then_else
(match_operator 1 "m68hc11_eq_compare_operator"
[(match_operand:QI 0 "register_operand" "+d,m*u*A")
(const_int -1)])
(label_ref (match_operand 2 "" ""))
(pc)))
(set (match_dup 0)
(plus:QI (match_dup 0) (const_int 1)))
(clobber (match_scratch:QI 3 "=X,d"))]
"TARGET_M6812"
"*
{
if (!D_REG_P (operands[0]))
return \"#\";
CC_STATUS_INIT;
if (GET_CODE (operands[1]) == EQ)
return \"ibeq\\tb,%l2\";
else
return \"ibeq\\tb,%l2\";
}")
;; Split the above to handle the case where operand 0 is in memory
;; (a register that couldn't get a hard register)
(define_split
[(set (pc)
(if_then_else
(match_operator 3 "m68hc11_eq_compare_operator"
[(match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "const_int_operand" "")])
(label_ref (match_operand 4 "" ""))
(pc)))
(set (match_dup 0)
(plus:HI (match_dup 0) (match_operand 2 "const_int_operand" "")))
(clobber (match_operand:HI 5 "hard_reg_operand" ""))]
"TARGET_M6812 && reload_completed"
[(set (match_dup 5) (match_dup 0))
(set (match_dup 5) (plus:HI (match_dup 5) (match_dup 2)))
(set (match_dup 0) (match_dup 5))
(set (pc)
(if_then_else (match_op_dup 3
[(match_dup 5) (const_int 0)])
(label_ref (match_dup 4)) (pc)))]
"")
;; Split the above to handle the case where operand 0 is in memory
;; (a register that couldn't get a hard register)
(define_split
[(set (pc)
(if_then_else
(match_operator 3 "m68hc11_eq_compare_operator"
[(match_operand:QI 0 "general_operand" "")
(match_operand:QI 1 "const_int_operand" "")])
(label_ref (match_operand 4 "" ""))
(pc)))
(set (match_dup 0)
(plus:QI (match_dup 0) (match_operand 2 "const_int_operand" "")))
(clobber (match_operand:QI 5 "hard_reg_operand" ""))]
"TARGET_M6812 && reload_completed"
[(set (match_dup 5) (match_dup 0))
(set (match_dup 5) (plus:QI (match_dup 5) (match_dup 2)))
(set (match_dup 0) (match_dup 5))
(set (pc)
(if_then_else (match_op_dup 3
[(match_dup 5) (const_int 0)])
(label_ref (match_dup 4)) (pc)))]
"")
;;--------------------------------------------------------------------
;;- Jumps and transfers
;;--------------------------------------------------------------------
(define_insn "jump"
......@@ -6665,6 +6869,62 @@
;;- Peepholes
;;--------------------------------------------------------------------
;;--------------------------------------------------------------------
;;- 68HC12 dbcc/ibcc peepholes
;;--------------------------------------------------------------------
;;
;; Replace: "addd #-1; bne L1" into "dbne d,L1"
;; "addd #-1; beq L1" into "dbeq d,L1"
;; "addd #1; bne L1" into "ibne d,L1"
;; "addd #1; beq L1" into "ibeq d,L1"
;;
(define_peephole2
[(set (match_operand:HI 0 "hard_reg_operand" "")
(plus:HI (match_dup 0)
(match_operand:HI 1 "const_int_operand" "")))
(set (pc)
(if_then_else (match_operator 2 "m68hc11_eq_compare_operator"
[(match_dup 0)
(const_int 0)])
(label_ref (match_operand 3 "" "")) (pc)))]
"TARGET_M6812 && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1)"
[(parallel [
(set (pc) (if_then_else (match_op_dup 2 [(match_dup 0) (match_dup 5)])
(label_ref (match_dup 3)) (pc)))
(set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))
(clobber (match_dup 4))])]
"operands[4] = gen_rtx_SCRATCH(HImode);
operands[5] = GEN_INT (-INTVAL (operands[1]));")
;;
;; Replace: "addb #-1; bne L1" into "dbne b,L1"
;; "addb #-1; beq L1" into "dbeq b,L1"
;;
(define_peephole2
[(set (match_operand:QI 0 "hard_reg_operand" "")
(plus:QI (match_dup 0)
(match_operand:QI 1 "const_int_operand" "")))
(set (pc)
(if_then_else (match_operator 2 "m68hc11_eq_compare_operator"
[(match_dup 0)
(const_int 0)])
(label_ref (match_operand 3 "" "")) (pc)))]
"TARGET_M6812 && D_REG_P (operands[0])
&& (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1)"
[(parallel [
(set (pc) (if_then_else (match_op_dup 2 [(match_dup 0) (match_dup 5)])
(label_ref (match_dup 3)) (pc)))
(set (match_dup 0) (plus:QI (match_dup 0) (match_dup 1)))
(clobber (match_dup 4))])]
"operands[4] = gen_rtx_SCRATCH(QImode);
operands[5] = GEN_INT (-INTVAL (operands[1]));")
;;--------------------------------------------------------------------
;;- Move peephole2
;;--------------------------------------------------------------------
;;
;; Replace "leas 2,sp" with a "pulx" or a "puly".
;; On 68HC12, this is one cycle slower but one byte smaller.
......
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