(blockage insn): Renamed from profiler.

(epilogue insn): Don't provide this if a return insn will suffice.
	(m88k_end_epilogue): If the last insn isn't a barrier, print a return.
(compare word insns): New insns and define_split
	patterns to take advantage of recent fold_truthop change.
	(superoptimizer sequences): New define_split patterns.
	(add/sub with carry): New insns.
	(add/sub DImode, ffssi2): Clobber the condition code register.

From-SVN: r1383
This commit is contained in:
Tom Wood 1992-07-02 10:29:02 +00:00
parent c8b9d354bb
commit e4689f195c

View File

@ -28,7 +28,7 @@
(define_expand "m88k_sccs_id"
[(match_operand:SI 0 "" "")]
""
"{ static char sccs_id[] = \"@(#)m88k.md 2.2.3.13 29 Jun 1992 16:41:06\";
"{ static char sccs_id[] = \"@(#)m88k.md 2.2.6.5 01 Jul 1992 18:47:08\";
FAIL; }")
;; Attribute specifications
@ -210,6 +210,129 @@
;(define_function_unit "writeback" 1 1 (eq_attr "type" "store") 0 1)
;(define_function_unit "memory" 1 3 (eq_attr "type" "store") 1 2)
;; Superoptimizer sequences
;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; }
;; subu.co r5,r2,r3
;; addu.cio r6,r4,r0
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "register_operand" "r")
(geu:SI (match_operand:SI 2 "register_operand" "r")
(match_operand:SI 3 "register_operand" "r"))))]
""
[(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
(set (match_dup 0)
(plus:SI (match_dup 1)
(unspec:SI [(const_int 0)
(reg:CC 0)] 0)))]
"")
;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; }
;; subu.co r5,r3,r2
;; addu.cio r6,r4,r0
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "register_operand" "r")
(leu:SI (match_operand:SI 3 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r"))))]
""
[(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
(set (match_dup 0)
(plus:SI (match_dup 1)
(unspec:SI [(const_int 0)
(reg:CC 0)] 0)))]
"")
;; eq0+: { r = (v0 == 0) + v1; }
;; subu.co r4,r0,r2
;; addu.cio r5,r3,r0
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "register_operand" "r")
(eq:SI (match_operand:SI 2 "register_operand" "r")
(const_int 0))))]
""
[(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
(set (match_dup 0)
(plus:SI (match_dup 1)
(unspec:SI [(const_int 0)
(reg:CC 0)] 0)))]
"")
;; ltu-: { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); }
;; subu.co r5,r2,r3
;; subu.cio r6,r4,r0
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r")
(match_operand:SI 3 "register_operand" "r"))
(match_operand:SI 1 "register_operand" "r")))]
""
[(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
(set (match_dup 0)
(minus:SI (match_dup 1)
(unspec:SI [(const_int 0)
(reg:CC 0)] 1)))]
"")
;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); }
;; subu.co r5,r3,r2
;; subu.cio r6,r4,r0
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r"))
(match_operand:SI 1 "register_operand" "r")))]
""
[(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
(set (match_dup 0)
(minus:SI (match_dup 1)
(unspec:SI [(const_int 0)
(reg:CC 0)] 1)))]
"")
;; ne0-: { r = v1 - (v0 != 0); }
;; subu.co r4,r0,r2
;; subu.cio r5,r3,r0
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r")
(const_int 0))
(match_operand:SI 1 "register_operand" "r")))]
""
[(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
(set (match_dup 0)
(minus:SI (match_dup 1)
(unspec:SI [(const_int 0)
(reg:CC 0)] 1)))]
"")
;; ges0-: { r = v1 - ((signed_word) v0 >= 0); }
;; addu.co r4,r2,r2
;; subu.cio r5,r3,r0
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "register_operand" "r")
(xor:SI (lshiftrt:SI
(match_operand:SI 2 "register_operand" "r")
(const_int 31))
(const_int 1))))]
""
[(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0))
(set (match_dup 0)
(minus:SI (match_dup 1)
(unspec:SI [(const_int 0)
(reg:CC 0)] 1)))]
"")
;; This rich set of complex patterns are mostly due to Torbjorn Granlund
;; (tege@sics.se). They've changed since then, so don't complain to him
;; if they don't work right.
@ -313,6 +436,277 @@
}"
[(set_attr "type" "marith")]) ; arith,bit,marith. length is 1 or 2.
;; Improve logical operations on compare words
;;
;; We define all logical operations on CCmode values to preserve the pairwise
;; relationship of the compare bits. This allows a future branch prediction
;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt.
;;
;; Opportunities arise when conditional expressions using && and || are made
;; unconditional. When these are used to branch, the sequence is
;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}. When these are used to create
;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or
;; cmp/cmp/ext/ext/{and,or} for -1 or 0.
;;
;; When the extracted conditions are the same, the define_split patterns
;; below change extu/extu/{and,or} into {and,or}/extu. If the reversed
;; conditions match, one compare word can be complimented, resulting in
;; {and.c,or.c}/extu. These changes are done for ext/ext/{and,or} as well.
;; If the conditions don't line up, one can be rotated. To keep the pairwise
;; relationship, it may be necessary to both rotate and compliment. Rotating
;; makes branching cheaper, but doesn't help (or hurt) creating a value, so
;; we don't do this for ext/ext/{and,or}.
;;
;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined
;; into an alternate form of bb0 and bb1.
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (neg:SI
(match_operator 1 "relop"
[(match_operand:CC 2 "register_operand" "%r")
(const_int 0)]))
(neg:SI
(match_operator 3 "relop"
[(match_operand:CC 4 "register_operand" "r")
(const_int 0)]))))
(clobber (match_operand:SI 5 "register_operand" "=r"))]
""
[(set (match_dup 5)
(ior:CC (match_dup 4)
(match_dup 2)))
(set (match_dup 0)
(neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
"operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
; /* The conditions match. */
else if (GET_CODE (operands[1])
== reverse_condition (GET_CODE (operands[3])))
/* Reverse the condition by complimenting the compare word. */
operands[4] = gen_rtx (NOT, CCmode, operands[4]);
else
{
/* Make the condition pairs line up by rotating the compare word. */
int cv1 = condition_value (operands[1]);
int cv2 = condition_value (operands[3]);
operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
gen_rtx (CONST_INT, VOIDmode,
((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
/* Reverse the condition if needed. */
if ((cv1 & 1) != (cv2 & 1))
operands[4] = gen_rtx (NOT, CCmode, operands[4]);
}")
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (match_operator 1 "relop"
[(match_operand:CC 2 "register_operand" "%r")
(const_int 0)])
(match_operator 3 "relop"
[(match_operand:CC 4 "register_operand" "r")
(const_int 0)])))
(clobber (match_operand:SI 5 "register_operand" "=r"))]
"GET_CODE (operands[1]) == GET_CODE (operands[3])
|| GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
[(set (match_dup 5)
(ior:CC (match_dup 4)
(match_dup 2)))
(set (match_dup 0)
(match_op_dup 1 [(match_dup 5) (const_int 0)]))]
"operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
/* Reverse the condition by complimenting the compare word. */
if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (neg:SI
(match_operator 1 "relop"
[(match_operand:CC 2 "register_operand" "%r")
(const_int 0)]))
(neg:SI
(match_operator 3 "relop"
[(match_operand:CC 4 "register_operand" "r")
(const_int 0)]))))
(clobber (match_operand:SI 5 "register_operand" "=r"))]
""
[(set (match_dup 5)
(and:CC (match_dup 4)
(match_dup 2)))
(set (match_dup 0)
(neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
"operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
; /* The conditions match. */
else if (GET_CODE (operands[1])
== reverse_condition (GET_CODE (operands[3])))
/* Reverse the condition by complimenting the compare word. */
operands[4] = gen_rtx (NOT, CCmode, operands[4]);
else
{
/* Make the condition pairs line up by rotating the compare word. */
int cv1 = condition_value (operands[1]);
int cv2 = condition_value (operands[3]);
operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
gen_rtx (CONST_INT, VOIDmode,
((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
/* Reverse the condition if needed. */
if ((cv1 & 1) != (cv2 & 1))
operands[4] = gen_rtx (NOT, CCmode, operands[4]);
}")
(define_split
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (match_operator 1 "relop"
[(match_operand:CC 2 "register_operand" "%r")
(const_int 0)])
(match_operator 3 "relop"
[(match_operand:CC 4 "register_operand" "r")
(const_int 0)])))
(clobber (match_operand:SI 5 "register_operand" "=r"))]
"GET_CODE (operands[1]) == GET_CODE (operands[3])
|| GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
[(set (match_dup 5)
(and:CC (match_dup 4)
(match_dup 2)))
(set (match_dup 0)
(match_op_dup 1 [(match_dup 5) (const_int 0)]))]
"operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
/* Reverse the condition by complimenting the compare word. */
if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
;; Logical operations on compare words.
(define_insn ""
[(set (match_operand:CC 0 "register_operand" "=r")
(and:CC (not:CC (match_operand:CC 1 "register_operand" "r"))
(match_operand:CC 2 "register_operand" "r")))]
""
"and.c %0,%2,%1")
(define_insn ""
[(set (match_operand:CC 0 "register_operand" "=r")
(and:CC (match_operand:CC 1 "register_operand" "%r")
(match_operand:CC 2 "register_operand" "r")))]
""
"and %0,%1,%2")
(define_insn ""
[(set (match_operand:CC 0 "register_operand" "=r")
(ior:CC (not:CC (match_operand:CC 1 "register_operand" "r"))
(match_operand:CC 2 "register_operand" "r")))]
""
"or.c %0,%2,%1")
(define_insn ""
[(set (match_operand:CC 0 "register_operand" "=r")
(ior:CC (match_operand:CC 1 "register_operand" "%r")
(match_operand:CC 2 "register_operand" "r")))]
""
"or %0,%1,%2")
(define_insn ""
[(set (match_operand:CC 0 "register_operand" "=r")
(rotate:CC (match_operand:CC 1 "register_operand" "r")
(match_operand:CC 2 "int5_operand" "")))]
""
"rot %0,%1,%2"
[(set_attr "type" "bit")])
;; rotate/and[.c] and rotate/ior[.c]
(define_insn ""
[(set (match_operand:CC 0 "register_operand" "=r")
(ior:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
(match_operand:CC 2 "int5_operand" ""))
(match_operand:CC 3 "register_operand" "r")))
(clobber (match_scratch:CC 4 "=r"))]
""
"#")
(define_split
[(set (match_operand:CC 0 "register_operand" "=r")
(ior:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
(match_operand:CC 2 "int5_operand" ""))
(match_operand:CC 3 "register_operand" "r")))
(clobber (match_operand:CC 4 "register_operand" "=r"))]
""
[(set (match_dup 4)
(rotate:CC (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(ior:CC (match_dup 4) (match_dup 3)))]
"")
(define_insn ""
[(set (match_operand:CC 0 "register_operand" "=r")
(ior:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
(match_operand:CC 2 "int5_operand" "")))
(match_operand:CC 3 "register_operand" "r")))
(clobber (match_scratch:CC 4 "=r"))]
""
"#")
(define_split
[(set (match_operand:CC 0 "register_operand" "=r")
(ior:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
(match_operand:CC 2 "int5_operand" "")))
(match_operand:CC 3 "register_operand" "r")))
(clobber (match_operand:CC 4 "register_operand" "=r"))]
""
[(set (match_dup 4)
(rotate:CC (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(ior:CC (not:CC (match_dup 4)) (match_dup 3)))]
"")
(define_insn ""
[(set (match_operand:CC 0 "register_operand" "=r")
(and:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
(match_operand:CC 2 "int5_operand" ""))
(match_operand:CC 3 "register_operand" "r")))
(clobber (match_scratch:CC 4 "=r"))]
""
"#")
(define_split
[(set (match_operand:CC 0 "register_operand" "=r")
(and:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
(match_operand:CC 2 "int5_operand" ""))
(match_operand:CC 3 "register_operand" "r")))
(clobber (match_operand:CC 4 "register_operand" "=r"))]
""
[(set (match_dup 4)
(rotate:CC (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(ior:CC (match_dup 4) (match_dup 3)))]
"")
(define_insn ""
[(set (match_operand:CC 0 "register_operand" "=r")
(and:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
(match_operand:CC 2 "int5_operand" "")))
(match_operand:CC 3 "register_operand" "r")))
(clobber (match_scratch:CC 4 "=r"))]
""
"#")
(define_split
[(set (match_operand:CC 0 "register_operand" "=r")
(and:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
(match_operand:CC 2 "int5_operand" "")))
(match_operand:CC 3 "register_operand" "r")))
(clobber (match_operand:CC 4 "register_operand" "=r"))]
""
[(set (match_dup 4)
(rotate:CC (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(and:CC (not:CC (match_dup 4)) (match_dup 3)))]
"")
;; Recognize bcnd instructions for integer values. This is distinguished
;; from a conditional branch instruction (below) with SImode instead of
;; CCmode.
@ -1008,6 +1402,35 @@
return \"bb1%. %R3%C0,%1,%P2%P3\";
}"
[(set_attr "type" "branch")])
;; Branch conditional on scc values. These arise from manipulations on
;; compare words above.
(define_insn ""
[(set (pc)
(if_then_else
(ne (match_operator 0 "relop"
[(match_operand:CC 1 "register_operand" "r")
(const_int 0)])
(const_int 0))
(match_operand 2 "pc_or_label_ref" "")
(match_operand 3 "pc_or_label_ref" "")))]
""
"bb1%. %R3%C0,%1,%P2%P3"
[(set_attr "type" "branch")])
(define_insn ""
[(set (pc)
(if_then_else
(eq (match_operator 0 "relop"
[(match_operand:CC 1 "register_operand" "r")
(const_int 0)])
(const_int 0))
(match_operand 2 "pc_or_label_ref" "")
(match_operand 3 "pc_or_label_ref" "")))]
""
"bb0%. %R3%C0,%1,%P2%P3"
[(set_attr "type" "branch")])
(define_insn "locate1"
[(set (match_operand:SI 0 "register_operand" "r")
@ -1713,7 +2136,8 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
(zero_extend:DI
(match_operand:SI 2 "register_operand" "r"))))]
(match_operand:SI 2 "register_operand" "r"))))
(clobber (reg:CC 0))]
""
"addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0"
[(set_attr "type" "marith")])
@ -1722,7 +2146,8 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (zero_extend:DI
(match_operand:SI 1 "register_operand" "r"))
(match_operand:DI 2 "register_operand" "r")))]
(match_operand:DI 2 "register_operand" "r")))
(clobber (reg:CC 0))]
""
"addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2"
[(set_attr "type" "marith")])
@ -1730,10 +2155,37 @@
(define_insn "adddi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "%r")
(match_operand:DI 2 "register_operand" "r")))]
(match_operand:DI 2 "register_operand" "r")))
(clobber (reg:CC 0))]
""
"addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2"
[(set_attr "type" "marith")])
;; Add with carry insns.
(define_insn ""
[(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "r")
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")))
(set (reg:CC 0)
(unspec:CC [(match_dup 1) (match_dup 2)] 0))])]
""
"addu.co %r0,%r1,%r2")
(define_insn ""
[(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
(match_operand:SI 1 "reg_or_0_operand" "rO")]
0))]
""
"addu.co %#r0,%r0,%r1")
(define_insn ""
[(set (match_operand:SI 0 "reg_or_0_operand" "r")
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
(unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
(reg:CC 0)] 0)))]
""
"addu.ci %r0,%r1,%r2")
;;- subtract instructions
@ -1804,7 +2256,8 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(minus:DI (match_operand:DI 1 "register_operand" "r")
(zero_extend:DI
(match_operand:SI 2 "register_operand" "r"))))]
(match_operand:SI 2 "register_operand" "r"))))
(clobber (reg:CC 0))]
""
"subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0"
[(set_attr "type" "marith")])
@ -1813,7 +2266,8 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(minus:DI (zero_extend:DI
(match_operand:SI 1 "register_operand" "r"))
(match_operand:DI 2 "register_operand" "r")))]
(match_operand:DI 2 "register_operand" "r")))
(clobber (reg:CC 0))]
""
"subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2"
[(set_attr "type" "marith")])
@ -1821,10 +2275,37 @@
(define_insn "subdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(minus:DI (match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "register_operand" "r")))]
(match_operand:DI 2 "register_operand" "r")))
(clobber (reg:CC 0))]
""
"subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2"
[(set_attr "type" "marith")])
;; Subtract with carry insns.
(define_insn ""
[(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "r")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")))
(set (reg:CC 0)
(unspec:CC [(match_dup 1) (match_dup 2)] 1))])]
""
"subu.co %r0,%r1,%r2")
(define_insn ""
[(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
(match_operand:SI 1 "reg_or_0_operand" "rO")]
1))]
""
"subu.co %#r0,%r0,%r1")
(define_insn ""
[(set (match_operand:SI 0 "reg_or_0_operand" "r")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
(unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
(reg:CC 0)] 1)))]
""
"subu.ci %r0,%r1,%r2")
;;- multiply instructions
;;
@ -2790,6 +3271,7 @@
(define_insn "ffssi2"
[(set (match_operand:SI 0 "register_operand" "=r,&r")
(ffs:SI (match_operand:SI 1 "register_operand" "0,r")))
(clobber (reg:CC 0))
(clobber (match_scratch:SI 2 "=r,X"))]
""
"@
@ -3087,7 +3569,7 @@
(define_insn "return"
[(return)]
"null_epilogue ()"
"null_prologue ()"
"jmp%. %#r1"
[(set_attr "type" "jump")])
@ -3098,10 +3580,10 @@
(define_expand "epilogue"
[(set (pc) (reg:SI 1))]
""
"! null_prologue ()"
"m88k_expand_epilogue ();")
(define_insn "profiler"
(define_insn "blockage"
[(unspec_volatile [(const_int 0)] 0)]
""
""