pdp11.md (doloop_end): New expander.
authorPaul Koning <ni1d@arrl.net>
Fri, 12 Oct 2018 21:12:38 +0000 (17:12 -0400)
committerPaul Koning <pkoning@gcc.gnu.org>
Fri, 12 Oct 2018 21:12:38 +0000 (17:12 -0400)
    * config/pdp11/pdp11.md (doloop_end): New expander.
    (doloop_end_insn): renamed from "doloop_end".
    (addqi3): New pattern.
    (subqi3): New pattern.
    * config/pdp11/predicates.md (incdec_operand): New predicate.

From-SVN: r265132

gcc/ChangeLog
gcc/config/pdp11/pdp11.md
gcc/config/pdp11/predicates.md

index 465de40d61e9da81154826c526a16867aeb04383..75ab456362bda69f0d010851d8cfffa6e9e6f7e5 100644 (file)
@@ -1,3 +1,11 @@
+2018-10-12  Paul Koning  <ni1d@arrl.net>
+
+       * config/pdp11/pdp11.md (doloop_end): New expander.
+       (doloop_end_insn): renamed from "doloop_end".
+       (addqi3): New pattern.
+       (subqi3): New pattern.
+       * config/pdp11/predicates.md (incdec_operand): New predicate.
+
 2018-10-12  Yury Gribov  <tetra2005@gmail.com>
 
        PR middle-end/81376
index a41e159012ebfae1be0dc51d3688190a9391c26d..773715d7030e9357ef2b4821450d3ea43495ccdc 100644 (file)
 
 ;; sob instruction
 ;;
-;; Do a define_expand because some alternatives clobber CC.
+;; This expander has to check for mode match because the doloop pass
+;; in gcc that invokes it does not do so, i.e., it may attempt to apply
+;; this pattern even if the count operand is QI or SI mode.
+(define_expand "doloop_end"
+  [(parallel [(set (pc)
+                  (if_then_else
+                   (ne (match_operand:HI 0 "nonimmediate_operand" "+r,!m")
+                       (const_int 1))
+                   (label_ref (match_operand 1 "" ""))
+                   (pc)))
+             (set (match_dup 0)
+                  (plus:HI (match_dup 0)
+                        (const_int -1)))])]
+  "TARGET_40_PLUS"
+  "{
+    if (GET_MODE (operands[0]) != HImode)
+      FAIL;
+  }")
+
+;; Do a define_split because some alternatives clobber CC.
 ;; Some don't, but it isn't all that interesting to cover that case.
-(define_insn_and_split "doloop_end"
+(define_insn_and_split "doloop_end_insn"
   [(set (pc)
        (if_then_else
         (ne (match_operand:HI 0 "nonimmediate_operand" "+r,!m")
 }"
   [(set_attr "length" "2,4,4,6")])
 
+(define_insn_and_split "addqi3"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=rR,Q")
+       (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
+                (match_operand:QI 2 "incdec_operand" "LM,LM")))]
+  ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+                  (plus:QI (match_dup 1) (match_dup 2)))
+             (clobber (reg:CC CC_REGNUM))])]
+  ""
+  [(set_attr "length" "2,4")])
+
+;; Inc/dec sets V if overflow from the operation
+(define_insn "*addqi3<cc_ccnz>"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=rR,Q")
+       (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
+                (match_operand:QI 2 "incdec_operand" "LM,LM")))
+   (clobber (reg:CC CC_REGNUM))]
+  "reload_completed"
+  "*
+{
+  if (INTVAL(operands[2]) == 1)
+    return \"incb\t%0\";
+  else
+    return \"decb\t%0\";
+}"
+  [(set_attr "length" "2,4")])
+
 \f
 ;;- subtract instructions
 ;; we don't have to care for constant second 
 }"
   [(set_attr "length" "2,4,4,6")])
 
+(define_insn_and_split "subqi3"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=rR,Q")
+       (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
+                (match_operand:QI 2 "incdec_operand" "LM,LM")))]
+  ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+                  (plus:QI (match_dup 1) (match_dup 2)))
+             (clobber (reg:CC CC_REGNUM))])]
+  ""
+  [(set_attr "length" "2,4")])
+
+;; Inc/dec sets V if overflow from the operation
+(define_insn "*subqi3<cc_ccnz>"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=rR,Q")
+       (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
+                (match_operand:QI 2 "incdec_operand" "LM,LM")))
+   (clobber (reg:CC CC_REGNUM))]
+  "reload_completed"
+  "*
+{
+  if (INTVAL(operands[2]) == -1)
+    return \"incb\t%0\";
+  else
+    return \"decb\t%0\";
+}"
+  [(set_attr "length" "2,4")])
+
 ;;;;- and instructions
 ;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn.
 
index eed711f7281b76af47256787f3bcad816ec19af6..d17e1299c330df4b3c8db4f7b0ad0f9ecad3828e 100644 (file)
   (and (match_code "const_int")
        (match_test "(unsigned) INTVAL (op) < 4")))
 
+;; Accept integer arguments +1 and -1, for which add and sub can be
+;; done as inc or dec instructions.  This matches the rule for the
+;; L and M constraints.
+(define_predicate "incdec_operand"
+  (and (match_code "const_int")
+       (ior (match_test "INTVAL (op) == -1")
+           (match_test "INTVAL (op) == 1"))))
+
 ;; Accept anything general_operand accepts, except that registers must
 ;; be FPU registers.
 (define_predicate "float_operand"