* function.c (stack_protect_epilogue): Pass label to
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Jun 2005 14:30:21 +0000 (14:30 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Jun 2005 14:30:21 +0000 (14:30 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101468 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/doc/md.texi
gcc/function.c

index de9323b..54cc32c 100644 (file)
@@ -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.
index 84be8f9..0231565 100644 (file)
 
 (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);
     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;
 })
 
index 68cd2b7..2c71ab1 100644 (file)
@@ -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"
index 725e9d3..f615c8d 100644 (file)
@@ -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                       \
index 6d0e581..f7a9df1 100644 (file)
@@ -59,6 +59,8 @@
    (UNSPEC_ISYNC               37)
    (UNSPEC_POPCNTB             38)
    (UNSPEC_FRES                        39)
+   (UNSPEC_SP_SET              40)
+   (UNSPEC_SP_TEST             41)
   ])
 
 ;;
   ""
   "{ 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")])
+
 \f
 ;; Here are the actual compare insns.
 (define_insn "*cmp<mode>_internal1"
index a44c34c..84be6e4 100644 (file)
@@ -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
 
index d514560..9727e6d 100644 (file)
@@ -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 */