Commit 8ec11fe9 by Jakub Jelinek Committed by Jakub Jelinek

sparc.h (sparc_compare_emitted): New extern.

	* config/sparc/sparc.h (sparc_compare_emitted): New extern.
	* config/sparc/sparc.c (sparc_compare_emitted): New variable.
	(gen_compare_reg): If sparc_compare_emitted is set, clear it
	and return its previous value.
	(emit_v9_brxx_insn): Assert sparc_compare_emitted is NULL.
	* config/sparc/sparc.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/sparc/linux.h (TARGET_THREAD_SSP_OFFSET): Define.
	* config/sparc/linux64.h (TARGET_THREAD_SSP_OFFSET): Define.

From-SVN: r101653
parent 9da4058c
2005-07-06 Jakub Jelinek <jakub@redhat.com>
* config/sparc/sparc.h (sparc_compare_emitted): New extern.
* config/sparc/sparc.c (sparc_compare_emitted): New variable.
(gen_compare_reg): If sparc_compare_emitted is set, clear it
and return its previous value.
(emit_v9_brxx_insn): Assert sparc_compare_emitted is NULL.
* config/sparc/sparc.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/sparc/linux.h (TARGET_THREAD_SSP_OFFSET): Define.
* config/sparc/linux64.h (TARGET_THREAD_SSP_OFFSET): Define.
2005-07-06 Jeff Law <law@redhat.com> 2005-07-06 Jeff Law <law@redhat.com>
* tree-ssa-dce.c (cfg_altered): New global. * tree-ssa-dce.c (cfg_altered): New global.
......
...@@ -229,3 +229,8 @@ do { \ ...@@ -229,3 +229,8 @@ do { \
#undef NEED_INDICATE_EXEC_STACK #undef NEED_INDICATE_EXEC_STACK
#define NEED_INDICATE_EXEC_STACK 1 #define NEED_INDICATE_EXEC_STACK 1
#ifdef TARGET_LIBC_PROVIDES_SSP
/* sparc glibc provides __stack_chk_guard in [%g7 + 0x14]. */
#define TARGET_THREAD_SSP_OFFSET 0x14
#endif
...@@ -363,3 +363,9 @@ do { \ ...@@ -363,3 +363,9 @@ do { \
#undef NEED_INDICATE_EXEC_STACK #undef NEED_INDICATE_EXEC_STACK
#define NEED_INDICATE_EXEC_STACK 1 #define NEED_INDICATE_EXEC_STACK 1
#ifdef TARGET_LIBC_PROVIDES_SSP
/* sparc glibc provides __stack_chk_guard in [%g7 + 0x14],
sparc64 glibc provides it at [%g7 + 0x28]. */
#define TARGET_THREAD_SSP_OFFSET (TARGET_ARCH64 ? 0x28 : 0x14)
#endif
...@@ -232,7 +232,7 @@ static GTY(()) int struct_value_alias_set; ...@@ -232,7 +232,7 @@ static GTY(()) int struct_value_alias_set;
/* Save the operands last given to a compare for use when we /* Save the operands last given to a compare for use when we
generate a scc or bcc insn. */ generate a scc or bcc insn. */
rtx sparc_compare_op0, sparc_compare_op1; rtx sparc_compare_op0, sparc_compare_op1, sparc_compare_emitted;
/* Vector to say how input registers are mapped to output registers. /* Vector to say how input registers are mapped to output registers.
HARD_FRAME_POINTER_REGNUM cannot be remapped by this function to HARD_FRAME_POINTER_REGNUM cannot be remapped by this function to
...@@ -1905,6 +1905,13 @@ gen_compare_reg (enum rtx_code code, rtx x, rtx y) ...@@ -1905,6 +1905,13 @@ gen_compare_reg (enum rtx_code code, rtx x, rtx y)
enum machine_mode mode = SELECT_CC_MODE (code, x, y); enum machine_mode mode = SELECT_CC_MODE (code, x, y);
rtx cc_reg; rtx cc_reg;
if (sparc_compare_emitted != NULL_RTX)
{
cc_reg = sparc_compare_emitted;
sparc_compare_emitted = NULL_RTX;
return cc_reg;
}
/* ??? We don't have movcc patterns so we cannot generate pseudo regs for the /* ??? We don't have movcc patterns so we cannot generate pseudo regs for the
fcc regs (cse can't tell they're really call clobbered regs and will fcc regs (cse can't tell they're really call clobbered regs and will
remove a duplicate comparison even if there is an intervening function remove a duplicate comparison even if there is an intervening function
...@@ -2071,6 +2078,7 @@ gen_v9_scc (enum rtx_code compare_code, register rtx *operands) ...@@ -2071,6 +2078,7 @@ gen_v9_scc (enum rtx_code compare_code, register rtx *operands)
void void
emit_v9_brxx_insn (enum rtx_code code, rtx op0, rtx label) emit_v9_brxx_insn (enum rtx_code code, rtx op0, rtx label)
{ {
gcc_assert (sparc_compare_emitted == NULL_RTX);
emit_jump_insn (gen_rtx_SET (VOIDmode, emit_jump_insn (gen_rtx_SET (VOIDmode,
pc_rtx, pc_rtx,
gen_rtx_IF_THEN_ELSE (VOIDmode, gen_rtx_IF_THEN_ELSE (VOIDmode,
......
...@@ -1584,6 +1584,7 @@ function_arg_padding ((MODE), (TYPE)) ...@@ -1584,6 +1584,7 @@ function_arg_padding ((MODE), (TYPE))
extern GTY(()) rtx sparc_compare_op0; extern GTY(()) rtx sparc_compare_op0;
extern GTY(()) rtx sparc_compare_op1; extern GTY(()) rtx sparc_compare_op1;
extern GTY(()) rtx sparc_compare_emitted;
/* Generate the special assembly code needed to tell the assembler whatever /* Generate the special assembly code needed to tell the assembler whatever
......
...@@ -57,6 +57,9 @@ ...@@ -57,6 +57,9 @@
(UNSPEC_ALIGNDATA 48) (UNSPEC_ALIGNDATA 48)
(UNSPEC_ALIGNADDR 49) (UNSPEC_ALIGNADDR 49)
(UNSPEC_PDIST 50) (UNSPEC_PDIST 50)
(UNSPEC_SP_SET 60)
(UNSPEC_SP_TEST 61)
]) ])
(define_constants (define_constants
...@@ -8155,6 +8158,96 @@ ...@@ -8155,6 +8158,96 @@
[(set_attr "type" "store")]) [(set_attr "type" "store")])
;; Stack protector instructions.
(define_expand "stack_protect_set"
[(match_operand 0 "memory_operand" "")
(match_operand 1 "memory_operand" "")]
""
{
#ifdef TARGET_THREAD_SSP_OFFSET
rtx tlsreg = gen_rtx_REG (Pmode, 7);
rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
operands[1] = gen_rtx_MEM (Pmode, addr);
#endif
if (TARGET_ARCH64)
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_ARCH32"
"ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
[(set_attr "type" "multi")
(set_attr "length" "3")])
(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_ARCH64"
"ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
[(set_attr "type" "multi")
(set_attr "length" "3")])
(define_expand "stack_protect_test"
[(match_operand 0 "memory_operand" "")
(match_operand 1 "memory_operand" "")
(match_operand 2 "" "")]
""
{
#ifdef TARGET_THREAD_SSP_OFFSET
rtx tlsreg = gen_rtx_REG (Pmode, 7);
rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
operands[1] = gen_rtx_MEM (Pmode, addr);
#endif
if (TARGET_ARCH64)
{
rtx temp = gen_reg_rtx (Pmode);
emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
sparc_compare_op0 = temp;
sparc_compare_op1 = const0_rtx;
}
else
{
emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
sparc_compare_op0 = operands[0];
sparc_compare_op1 = operands[1];
sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
}
emit_jump_insn (gen_beq (operands[2]));
DONE;
})
(define_insn "stack_protect_testsi"
[(set (reg:CC 100)
(unspec:CC [(match_operand:SI 0 "memory_operand" "m")
(match_operand:SI 1 "memory_operand" "m")]
UNSPEC_SP_TEST))
(clobber (match_scratch:SI 2 "=&r"))
(set (match_scratch:SI 3 "=r") (const_int 0))]
"TARGET_ARCH32"
"ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
[(set_attr "type" "multi")
(set_attr "length" "4")])
(define_insn "stack_protect_testdi"
[(set (match_operand:DI 0 "register_operand" "=&r")
(unspec:DI [(match_operand:DI 1 "memory_operand" "m")
(match_operand:DI 2 "memory_operand" "m")]
UNSPEC_SP_TEST))
(set (match_scratch:DI 3 "=r") (const_int 0))]
"TARGET_ARCH64"
"ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
[(set_attr "type" "multi")
(set_attr "length" "4")])
;; Vector instructions. ;; Vector instructions.
(define_insn "addv2si3" (define_insn "addv2si3"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment