diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-06-30 16:30:21 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-06-30 16:30:21 +0200 |
commit | 3aebbe5f49f9b9ccda66fc1eb907603e84813878 (patch) | |
tree | 4043695a51d7d9562a87d61e43938fa5c73948dc /gcc | |
parent | 7d5175e1e494e0a514019347723b7afc34a459db (diff) | |
download | gcc-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/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 4 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 31 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 72 | ||||
-rw-r--r-- | gcc/doc/md.texi | 10 | ||||
-rw-r--r-- | gcc/function.c | 3 |
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 */ |