This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] S/390: stack_protect_set/test
- From: Andreas Krebbel <krebbel1 at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 4 Jul 2005 10:24:38 +0200
- Subject: [PATCH] S/390: stack_protect_set/test
Hi,
the attached patch defines the stack_protect_set/test expanders for S/390.
This is necessary in order to use the stack smashing protector.
Implementing the patterns is easy for S/390 because we have a mem/mem
compare as well as a mem/mem move.
The only reason we need the stack_protect_test pattern at all is that combine
can't merge the insns which would be generated without having such an expander
in place. The problem is that the accesses to the stack guard value have to be
declared volatile what prevents combine from doing any optimizations.
The stack_protect_set pattern should not be necesssary. Storing the stack guard
value to stack in my tests always produced a single mvc instruction which is fine.
But it is probably safer to encapsulate the SET with an unspec to prevent the
optimizers from replacing it with something using a register.
Bootstrapped on s390 and s390x with flag_stack_protect forced to 1 - no testsuite
regressions.
OK for mainline?
Bye,
-Andreas-
2005-07-04 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390/s390.c (print_operand): New output modifier 'G' added.
* config/s390/s390.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 insn definitions.
Index: gcc-4.1/gcc/config/s390/s390.c
===================================================================
--- gcc-4.1.orig/gcc/config/s390/s390.c 2005-06-30 16:30:30.000000000 +0200
+++ gcc-4.1/gcc/config/s390/s390.c 2005-06-30 16:30:35.000000000 +0200
@@ -3802,6 +3802,7 @@ print_operand_address (FILE *file, rtx a
'C': print opcode suffix for branch condition.
'D': print opcode suffix for inverse branch condition.
'J': print tls_load/tls_gdcall/tls_ldcall suffix
+ 'G': print the size of the operand in bytes.
'O': print only the displacement of a memory reference.
'R': print only the base register of a memory reference.
'S': print S-type memory reference (base+displacement).
@@ -3848,6 +3849,10 @@ print_operand (FILE *file, rtx x, int co
gcc_unreachable ();
return;
+ case 'G':
+ fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
+ return;
+
case 'O':
{
struct s390_address ad;
Index: gcc-4.1/gcc/config/s390/s390.md
===================================================================
--- gcc-4.1.orig/gcc/config/s390/s390.md 2005-06-30 16:30:30.000000000 +0200
+++ gcc-4.1/gcc/config/s390/s390.md 2005-07-04 09:47:46.000000000 +0200
@@ -122,7 +122,11 @@
(UNSPEC_TLS_LOAD 512)
; String Functions
- (UNSPEC_SRST 600)
+ (UNSPEC_SRST 600)
+
+ ; Stack Smashing Protector
+ (UNSPEC_SP_SET 700)
+ (UNSPEC_SP_TEST 701)
])
;;
@@ -7078,3 +7082,52 @@
DONE;
})
+;
+; Stack Protector Patterns
+;
+
+(define_expand "stack_protect_set"
+ [(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_set<mode>"
+ [(set (match_operand:DSI 0 "memory_operand" "=Q")
+ (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
+ ""
+ "mvc\t%O0(%G0,%R0),%S1"
+ [(set_attr "op_type" "SS")])
+
+(define_expand "stack_protect_test"
+ [(set (reg:CC CC_REGNUM)
+ (compare (match_operand 0 "memory_operand" "")
+ (match_operand 1 "memory_operand" "")))]
+ ""
+{
+ s390_compare_op0 = operands[0];
+ s390_compare_op1 = operands[1];
+ s390_compare_emitted = gen_rtx_REG (CCZmode, CC_REGNUM);
+
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
+ else
+ emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
+
+ DONE;
+})
+
+(define_insn "stack_protect_test<mode>"
+ [(set (reg:CCZ CC_REGNUM)
+ (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
+ (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
+ ""
+ "clc\t%O0(%G0,%R0),%S1"
+ [(set_attr "op_type" "SS")])