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
This commit is contained in:
Paul Koning 2018-10-12 17:12:38 -04:00 committed by Paul Koning
parent e41ec71bd9
commit fe65151b14
3 changed files with 95 additions and 2 deletions

View 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

View File

@ -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.

View File

@ -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"