From: ciceron Date: Tue, 2 Mar 2004 22:16:15 +0000 (+0000) Subject: * config/m68hc11/m68hc11.md (move peephole2): New peepholes to optimize X-Git-Tag: upstream/4.9.2~72587 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=db25945d888377526c243eb72e768eea6ea8be42;p=platform%2Fupstream%2Flinaro-gcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@78787 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 534f1fb..a1782ba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2004-03-02 Stephane Carrez + * 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 + * config/m68hc11/m68hc11.md ("*pushdi_internal"): New insn and split to separate push from moves. ("*pushdf_internal"): Likewise. diff --git a/gcc/config/m68hc11/m68hc11.md b/gcc/config/m68hc11/m68hc11.md index 4140733..08d03cb 100644 --- a/gcc/config/m68hc11/m68hc11.md +++ b/gcc/config/m68hc11/m68hc11.md @@ -6907,6 +6907,61 @@ gen_rtx_POST_INC (HImode, 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 ;; a register. @@ -6971,6 +7026,36 @@ "") ;; +;; Replace: "ldx #N; xgdx; addd ; xgdx" by "ldab #N; ldx ; 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 ; xgdx" by "ldab #N; ldx ; 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 ;; a PRE_INC or PRE_DEC addressing mode (disabled on the tst insn ;; before reload, but can be enabled after). @@ -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 ; psha; pshb" with a "ldx ; pshx". ;; (define_peephole2 @@ -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 ; addd #N; std " into a ;; "ldx ; leax; stx " if we have a free X/Y register ;; and the constant is small. @@ -7098,6 +7227,174 @@ "if (reg_mentioned_p (operands[4], operands[1])) 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 ; orab #N; stab ' by 'bset #N'. +;; Register D must be dead and there must be no register side effects for mem. +;; The *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 ; andab #N; stab ' by 'bclr #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 " with "ldd ; 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 " with "ldd ; 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 " with "ldd ; 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 ;; pass. @@ -7367,3 +7664,41 @@ 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\"; +}")