OSDN Git Service

* config/m68hc11/m68hc11.md (move peephole2): New peepholes to optimize
authorciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Mar 2004 22:16:15 +0000 (22:16 +0000)
committerciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Mar 2004 22:16:15 +0000 (22:16 +0000)
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

gcc/ChangeLog
gcc/config/m68hc11/m68hc11.md

index 534f1fb..a1782ba 100644 (file)
@@ -1,5 +1,15 @@
 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
        to separate push from moves.
        ("*pushdf_internal"): Likewise.
index 4140733..08d03cb 100644 (file)
                          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.
   "")
 
 ;;
+;; 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
 ;; a PRE_INC or PRE_DEC addressing mode (disabled on the tst insn
 ;; before reload, but can be enabled after).
   "")
 
 ;;
+;;
+;;
+(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".
 ;;
 (define_peephole2
   "")
 
 ;;
+;; 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
 ;; "ldx <mem>; leax; stx <mem>" if we have a free X/Y register
 ;; and the constant is small.
   "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 <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
 ;; pass. 
   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\";
+}")