diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-07-06 09:49:05 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-07-06 09:49:05 +0200 |
commit | 8ec11fe9b8b04468e81549ca68d5e70912b8f6dc (patch) | |
tree | 8ca6fd41c47572b47720e13f43cf054b3a1a38b9 /gcc | |
parent | 9da4058c1454b279f0b5791100105bf7a6734e9d (diff) | |
download | gcc-8ec11fe9b8b04468e81549ca68d5e70912b8f6dc.tar.gz |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/config/sparc/linux.h | 5 | ||||
-rw-r--r-- | gcc/config/sparc/linux64.h | 6 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 10 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 1 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 93 |
6 files changed, 129 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fa01f3162eb..4343b436a5b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +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> * tree-ssa-dce.c (cfg_altered): New global. diff --git a/gcc/config/sparc/linux.h b/gcc/config/sparc/linux.h index 2e10987ae70..87a043e53cf 100644 --- a/gcc/config/sparc/linux.h +++ b/gcc/config/sparc/linux.h @@ -229,3 +229,8 @@ do { \ #undef NEED_INDICATE_EXEC_STACK #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 diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h index a331dfc626c..82860fea24e 100644 --- a/gcc/config/sparc/linux64.h +++ b/gcc/config/sparc/linux64.h @@ -363,3 +363,9 @@ do { \ #undef NEED_INDICATE_EXEC_STACK #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 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 69bde4b3b70..b0cde28b143 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -232,7 +232,7 @@ static GTY(()) int struct_value_alias_set; /* Save the operands last given to a compare for use when we 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. 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) enum machine_mode mode = SELECT_CC_MODE (code, x, y); 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 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 @@ -2071,6 +2078,7 @@ gen_v9_scc (enum rtx_code compare_code, register rtx *operands) void 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, pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode, diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 95fd760de57..35b8dd5cccb 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1584,6 +1584,7 @@ function_arg_padding ((MODE), (TYPE)) extern GTY(()) rtx sparc_compare_op0; extern GTY(()) rtx sparc_compare_op1; +extern GTY(()) rtx sparc_compare_emitted; /* Generate the special assembly code needed to tell the assembler whatever diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 933551559e6..ee601d03dde 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -57,6 +57,9 @@ (UNSPEC_ALIGNDATA 48) (UNSPEC_ALIGNADDR 49) (UNSPEC_PDIST 50) + + (UNSPEC_SP_SET 60) + (UNSPEC_SP_TEST 61) ]) (define_constants @@ -8155,6 +8158,96 @@ [(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. (define_insn "addv2si3" |