]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
m68hc11.md ("decrement_and_branch_until_zero"): New pattern for dbcc/ibcc generation...
authorStephane Carrez <stcarrez@nerim.fr>
Sat, 12 Apr 2003 21:22:49 +0000 (23:22 +0200)
committerStephane Carrez <ciceron@gcc.gnu.org>
Sat, 12 Apr 2003 21:22:49 +0000 (23:22 +0200)
* 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

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

index b29c50a4d8ce1ccd80b75ba0d0362e715f95a425..4f73a65c7363ea4f53d02578619551288b4eae76 100644 (file)
@@ -1,3 +1,16 @@
+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
index 6fd9d0e3ac919566fabb68a7765f4595c8573b53..1fb5a5e8ad8f61e2acafeaed435de8f15ba0c12c 100644 (file)
               (set (match_dup 0) (reg:HI D_REGNUM))])]
   "")
 
+;;--------------------------------------------------------------------
+;;-  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
 ;;--------------------------------------------------------------------
 ;;- 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.