diff mbox series

[pdp11] fix problem with doloop_end

Message ID 8330C554-3D61-426D-B89A-D912ECDC2F9B@comcast.net
State New
Headers show
Series [pdp11] fix problem with doloop_end | expand

Commit Message

Paul Koning Oct. 12, 2018, 9:15 p.m. UTC
For some newlib sources, pdp11 doloop_end was creating problems because it was handed a QImode operand when it only wants HImode.  This patch cures that, and also adds addqi3 and subqi3 patterns to help with that case.

Committed.

	paul

ChangeLog:

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.

 ;; 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 mbox series

Patch

Index: config/pdp11/predicates.md
===================================================================
--- config/pdp11/predicates.md	(revision 265131)
+++ config/pdp11/predicates.md	(revision 265132)
@@ -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"
Index: config/pdp11/pdp11.md
===================================================================
--- config/pdp11/pdp11.md	(revision 265131)
+++ config/pdp11/pdp11.md	(revision 265132)
@@ -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