aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPaul Koning <ni1d@arrl.net>2018-10-12 17:12:38 -0400
committerPaul Koning <pkoning@gcc.gnu.org>2018-10-12 17:12:38 -0400
commitfe65151b14f5f43213ffac7f20303bfbd6a2d1c8 (patch)
treefeb364af1ee93a10984f1ea9825e7c227a927dc0 /gcc
parente41ec71bd97a1a8eaef40695c7ae9b7f4b1fc819 (diff)
downloadgcc-fe65151b14f5f43213ffac7f20303bfbd6a2d1c8.zip
gcc-fe65151b14f5f43213ffac7f20303bfbd6a2d1c8.tar.gz
gcc-fe65151b14f5f43213ffac7f20303bfbd6a2d1c8.tar.bz2
pdp11.md (doloop_end): New expander.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/pdp11/pdp11.md81
-rw-r--r--gcc/config/pdp11/predicates.md8
3 files changed, 95 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 465de40..75ab456 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md
index a41e1590..773715d 100644
--- a/gcc/config/pdp11/pdp11.md
+++ b/gcc/config/pdp11/pdp11.md
@@ -251,9 +251,28 @@
;; 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")
@@ -1067,6 +1086,35 @@
}"
[(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")])
+
;;- subtract instructions
;; we don't have to care for constant second
@@ -1226,6 +1274,35 @@
}"
[(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.
diff --git a/gcc/config/pdp11/predicates.md b/gcc/config/pdp11/predicates.md
index eed711f..d17e129 100644
--- a/gcc/config/pdp11/predicates.md
+++ b/gcc/config/pdp11/predicates.md
@@ -30,6 +30,14 @@
(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"