Commit ce6a6c00 by Michael Meissner Committed by Michael Meissner

Add prefixed insn support for stack_protect_setdi & stack_protect_testdi

2019-11-11  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/predicates.md (prefixed_memory): New predicate.
	* config/rs6000/rs6000.md (stack_protect_setdi): Deal with either
	address being a prefixed load/store.
	(stack_protect_testdi): Deal with either address being a prefixed
	load.

From-SVN: r278069
parent 48042bd4
2019-11-11 Michael Meissner <meissner@linux.ibm.com>
* config/rs6000/predicates.md (prefixed_memory): New predicate.
* config/rs6000/rs6000.md (stack_protect_setdi): Deal with either
address being a prefixed load/store.
(stack_protect_testdi): Deal with either address being a prefixed
load.
2019-11-11 Jakub Jelinek <jakub@redhat.com> 2019-11-11 Jakub Jelinek <jakub@redhat.com>
PR bootstrap/92433 PR bootstrap/92433
...@@ -1828,3 +1828,10 @@ ...@@ -1828,3 +1828,10 @@
(define_predicate "pcrel_local_or_external_address" (define_predicate "pcrel_local_or_external_address"
(ior (match_operand 0 "pcrel_local_address") (ior (match_operand 0 "pcrel_local_address")
(match_operand 0 "pcrel_external_address"))) (match_operand 0 "pcrel_external_address")))
;; Return true if the operand is a memory address that uses a prefixed address.
(define_predicate "prefixed_memory"
(match_code "mem")
{
return address_is_prefixed (XEXP (op, 0), mode, NON_PREFIXED_DEFAULT);
})
...@@ -11536,14 +11536,44 @@ ...@@ -11536,14 +11536,44 @@
[(set_attr "type" "three") [(set_attr "type" "three")
(set_attr "length" "12")]) (set_attr "length" "12")])
;; We can't use the prefixed attribute here because there are two memory
;; instructions. We can't split the insn due to the fact that this operation
;; needs to be done in one piece.
(define_insn "stack_protect_setdi" (define_insn "stack_protect_setdi"
[(set (match_operand:DI 0 "memory_operand" "=Y") [(set (match_operand:DI 0 "memory_operand" "=Y")
(unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET)) (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
(set (match_scratch:DI 2 "=&r") (const_int 0))] (set (match_scratch:DI 2 "=&r") (const_int 0))]
"TARGET_64BIT" "TARGET_64BIT"
"ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0" {
if (prefixed_memory (operands[1], DImode))
output_asm_insn ("pld %2,%1", operands);
else
output_asm_insn ("ld%U1%X1 %2,%1", operands);
if (prefixed_memory (operands[0], DImode))
output_asm_insn ("pstd %2,%0", operands);
else
output_asm_insn ("std%U0%X0 %2,%0", operands);
return "li %2,0";
}
[(set_attr "type" "three") [(set_attr "type" "three")
(set_attr "length" "12")])
;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
;; the LI 0 at the end.
(set_attr "prefixed" "no")
(set_attr "num_insns" "3")
(set (attr "length")
(cond [(and (match_operand 0 "prefixed_memory")
(match_operand 1 "prefixed_memory"))
(const_int 24)
(ior (match_operand 0 "prefixed_memory")
(match_operand 1 "prefixed_memory"))
(const_int 20)]
(const_int 12)))])
(define_expand "stack_protect_test" (define_expand "stack_protect_test"
[(match_operand 0 "memory_operand") [(match_operand 0 "memory_operand")
...@@ -11582,6 +11612,9 @@ ...@@ -11582,6 +11612,9 @@
lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0" lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
[(set_attr "length" "16,20")]) [(set_attr "length" "16,20")])
;; We can't use the prefixed attribute here because there are two memory
;; instructions. We can't split the insn due to the fact that this operation
;; needs to be done in one piece.
(define_insn "stack_protect_testdi" (define_insn "stack_protect_testdi"
[(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
(unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y") (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
...@@ -11590,10 +11623,45 @@ ...@@ -11590,10 +11623,45 @@
(set (match_scratch:DI 4 "=r,r") (const_int 0)) (set (match_scratch:DI 4 "=r,r") (const_int 0))
(clobber (match_scratch:DI 3 "=&r,&r"))] (clobber (match_scratch:DI 3 "=&r,&r"))]
"TARGET_64BIT" "TARGET_64BIT"
"@ {
ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 if (prefixed_memory (operands[1], DImode))
ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0" output_asm_insn ("pld %3,%1", operands);
[(set_attr "length" "16,20")]) else
output_asm_insn ("ld%U1%X1 %3,%1", operands);
if (prefixed_memory (operands[2], DImode))
output_asm_insn ("pld %4,%2", operands);
else
output_asm_insn ("ld%U2%X2 %4,%2", operands);
if (which_alternative == 0)
output_asm_insn ("xor. %3,%3,%4", operands);
else
output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
return "li %4,0";
}
;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
;; 8 bytes to do the test.
[(set_attr "prefixed" "no")
(set_attr "num_insns" "4,5")
(set (attr "length")
(cond [(and (match_operand 1 "prefixed_memory")
(match_operand 2 "prefixed_memory"))
(if_then_else (eq_attr "alternative" "0")
(const_int 28)
(const_int 32))
(ior (match_operand 1 "prefixed_memory")
(match_operand 2 "prefixed_memory"))
(if_then_else (eq_attr "alternative" "0")
(const_int 20)
(const_int 24))]
(if_then_else (eq_attr "alternative" "0")
(const_int 16)
(const_int 20))))])
;; Here are the actual compare insns. ;; Here are the actual compare insns.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment