aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2005-06-30 16:30:21 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2005-06-30 16:30:21 +0200
commit3aebbe5f49f9b9ccda66fc1eb907603e84813878 (patch)
tree4043695a51d7d9562a87d61e43938fa5c73948dc /gcc/config/rs6000/rs6000.md
parent7d5175e1e494e0a514019347723b7afc34a459db (diff)
downloadgcc-3aebbe5f49f9b9ccda66fc1eb907603e84813878.zip
gcc-3aebbe5f49f9b9ccda66fc1eb907603e84813878.tar.gz
gcc-3aebbe5f49f9b9ccda66fc1eb907603e84813878.tar.bz2
function.c (stack_protect_epilogue): Pass label to stack_protect_test, assume it emitted also the conditional branch.
* function.c (stack_protect_epilogue): Pass label to stack_protect_test, assume it emitted also the conditional branch. * doc/md.texi (stack_protect_test): Adjust documentation. * config/i386/i386.md (stack_protect_test): Add third argument, emit beq with operands[2]. * config/rs6000/rs6000.h (FRAME_GROWS_DOWNWARD): Define to flag_stack_protect != 0. * config/rs6000/rs6000.md (UNSPEC_SP_SET, UNSPEC_SP_TEST): New constants. (stack_protect_set, stack_protect_test): New expanders. (stack_protect_setsi, stack_protect_setdi, stack_protect_testsi, stack_protect_testdi): New insns. * config/rs6000/rs6000.c (rs6000_stack_protect_fail): New function. (TARGET_STACK_PROTECT_FAIL): Define. (rs6000_generate_compare): Handle UNSPEC_SP_TEST. From-SVN: r101468
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r--gcc/config/rs6000/rs6000.md72
1 files changed, 72 insertions, 0 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 6d0e581..f7a9df1 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -59,6 +59,8 @@
(UNSPEC_ISYNC 37)
(UNSPEC_POPCNTB 38)
(UNSPEC_FRES 39)
+ (UNSPEC_SP_SET 40)
+ (UNSPEC_SP_TEST 41)
])
;;
@@ -10757,6 +10759,76 @@
""
"{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
+(define_expand "stack_protect_set"
+ [(match_operand 0 "memory_operand" "")
+ (match_operand 1 "memory_operand" "")]
+ ""
+{
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
+ else
+ emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn "stack_protect_setsi"
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
+ (set (match_scratch:SI 2 "=&r") (const_int 0))]
+ "TARGET_32BIT"
+ "{l%U1%X1|lwz%U1%X1} %2,%1\;{st%U0%X0|stw%U0%X0} %2,%0\;{lil|li} %2,0"
+ [(set_attr "type" "three")
+ (set_attr "length" "12")])
+
+(define_insn "stack_protect_setdi"
+ [(set (match_operand:DI 0 "memory_operand" "=m")
+ (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
+ (set (match_scratch:DI 2 "=&r") (const_int 0))]
+ "TARGET_64BIT"
+ "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;{lil|li} %2,0"
+ [(set_attr "type" "three")
+ (set_attr "length" "12")])
+
+(define_expand "stack_protect_test"
+ [(match_operand 0 "memory_operand" "")
+ (match_operand 1 "memory_operand" "")
+ (match_operand 2 "" "")]
+ ""
+{
+ rs6000_compare_op0 = operands[0];
+ rs6000_compare_op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]),
+ UNSPEC_SP_TEST);
+ rs6000_compare_fp_p = 0;
+ emit_jump_insn (gen_beq (operands[2]));
+ DONE;
+})
+
+(define_insn "stack_protect_testsi"
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
+ (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
+ (match_operand:SI 2 "memory_operand" "m,m")]
+ UNSPEC_SP_TEST))
+ (clobber (match_scratch:SI 3 "=r,r"))
+ (set (match_scratch:SI 4 "=&r,&r") (const_int 0))]
+ "TARGET_32BIT"
+ "@
+ {l%U1%X1|lwz%U1%X1} %3,%1\;{l%U2%X2|lwz%U2%X2} %4,%2\;xor. %3,%3,%4\;{lil|li} %4,0
+ {l%U1%X1|lwz%U1%X1} %3,%1\;{l%U2%X2|lwz%U2%X2} %4,%2\;{cmpl|cmplw} %0,%3,%4\;{lil|li} %3,0\;{lil|li} %4,0"
+ [(set_attr "length" "16,20")])
+
+(define_insn "stack_protect_testdi"
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
+ (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "m,m")
+ (match_operand:DI 2 "memory_operand" "m,m")]
+ UNSPEC_SP_TEST))
+ (clobber (match_scratch:DI 3 "=r,r"))
+ (set (match_scratch:DI 4 "=&r,&r") (const_int 0))]
+ "TARGET_64BIT"
+ "@
+ ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;{lil|li} %4,0
+ ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;{lil|li} %3,0\;{lil|li} %4,0"
+ [(set_attr "length" "16,20")])
+
;; Here are the actual compare insns.
(define_insn "*cmp<mode>_internal1"