aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/config/i386/i386.md4
-rw-r--r--gcc/config/rs6000/rs6000.c31
-rw-r--r--gcc/config/rs6000/rs6000.h2
-rw-r--r--gcc/config/rs6000/rs6000.md72
-rw-r--r--gcc/doc/md.texi10
-rw-r--r--gcc/function.c3
7 files changed, 128 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index de9323b5..54cc32c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,22 @@
2005-06-30 Jakub Jelinek <jakub@redhat.com>
+ * 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.
+
* config/rs6000/rs6000.h (FIRST_PSEUDO_REGISTER): Increment.
(DWARF_FRAME_REGISTERS, DWARF_REG_TO_UNWIND_COLUMN): Adjust, so
that addition of sfp doesn't change these.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 84be8f9..0231565 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -19640,7 +19640,8 @@
(define_expand "stack_protect_test"
[(match_operand 0 "memory_operand" "")
- (match_operand 1 "memory_operand" "")]
+ (match_operand 1 "memory_operand" "")
+ (match_operand 2 "" "")]
""
{
rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
@@ -19652,6 +19653,7 @@
emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
else
emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
+ emit_jump_insn (gen_beq (operands[2]));
DONE;
})
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 68cd2b7..2c71ab1 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -728,7 +728,7 @@ static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
enum machine_mode);
static int get_vsel_insn (enum machine_mode);
static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx);
-
+static tree rs6000_stack_protect_fail (void);
const int INSN_NOT_AVAILABLE = -1;
static enum machine_mode rs6000_eh_return_filter_mode (void);
@@ -973,6 +973,9 @@ static const char alt_reg_names[][8] =
#define TARGET_DEFAULT_TARGET_FLAGS \
(TARGET_DEFAULT | MASK_SCHED_PROLOG)
+#undef TARGET_STACK_PROTECT_FAIL
+#define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
+
/* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
The PowerPC architecture requires only weak consistency among
processors--that is, memory accesses between processors need not be
@@ -10591,6 +10594,19 @@ rs6000_generate_compare (enum rtx_code code)
gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
+ else if (GET_CODE (rs6000_compare_op1) == UNSPEC
+ && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
+ {
+ rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
+ comp_mode = CCEQmode;
+ compare_result = gen_reg_rtx (CCEQmode);
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_protect_testdi (compare_result,
+ rs6000_compare_op0, op1));
+ else
+ emit_insn (gen_stack_protect_testsi (compare_result,
+ rs6000_compare_op0, op1));
+ }
else
emit_insn (gen_rtx_SET (VOIDmode, compare_result,
gen_rtx_COMPARE (comp_mode,
@@ -18373,4 +18389,17 @@ invalid_arg_for_unprototyped_fn (tree typelist, tree funcdecl, tree val)
: NULL;
}
+/* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
+ setup by using __stack_chk_fail_local hidden function instead of
+ calling __stack_chk_fail directly. Otherwise it is better to call
+ __stack_chk_fail directly. */
+
+static tree
+rs6000_stack_protect_fail (void)
+{
+ return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
+ ? default_hidden_stack_protect_fail ()
+ : default_external_stack_protect_fail ();
+}
+
#include "gt-rs6000.h"
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 725e9d3..f615c8d 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1233,7 +1233,7 @@ extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */
On the RS/6000, we grow upwards, from the area after the outgoing
arguments. */
-#define FRAME_GROWS_DOWNWARD 0
+#define FRAME_GROWS_DOWNWARD (flag_stack_protect != 0)
/* Size of the outgoing register save area */
#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \
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"
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index a44c34c..84be6e4 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -4112,13 +4112,11 @@ If this pattern is not defined, then a plain move pattern is generated.
This pattern, if defined, compares a @code{Pmode} value from the
memory in operand 1 with the memory in operand 0 without leaving the
-value in a register afterward. Further, it initializes the data
-structures in the target as if the normal @code{cmp@var{mode}}
-pattern had been emitted. If the pattern does not @code{FAIL}, then
-the rtl expanders will be invoking either the @code{beq} or @code{bne}
-pattern to make use of the comparison.
+value in a register afterward and branches to operand 2 if the values
+weren't equal.
-If this pattern is not defined, then a plain compare pattern is used.
+If this pattern is not defined, then a plain compare pattern and
+conditional branch pattern is used.
@end table
diff --git a/gcc/function.c b/gcc/function.c
index d514560..9727e6d 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -3995,11 +3995,10 @@ stack_protect_epilogue (void)
switch (HAVE_stack_protect_test != 0)
{
case 1:
- tmp = gen_stack_protect_test (x, y);
+ tmp = gen_stack_protect_test (x, y, label);
if (tmp)
{
emit_insn (tmp);
- emit_jump_insn (bcc_gen_fctn[EQ] (label));
break;
}
/* FALLTHRU */