diff options
author | Uros Bizjak <uros@gcc.gnu.org> | 2009-11-03 08:53:05 +0100 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2009-11-03 08:53:05 +0100 |
commit | 55a19d494b903ffdf754217d3ff5bc66d1ad1954 (patch) | |
tree | 98edb715c3d959ea46c8fc662edb84967cd18a61 | |
parent | b511afdd35b357f589d446ce315aea5e2649d0cc (diff) | |
download | gcc-55a19d494b903ffdf754217d3ff5bc66d1ad1954.zip gcc-55a19d494b903ffdf754217d3ff5bc66d1ad1954.tar.gz gcc-55a19d494b903ffdf754217d3ff5bc66d1ad1954.tar.bz2 |
re PR target/41900 (call *%esp shouldn't be generated because of CPU errata)
PR target/41900
* config/i386/i386.h (ix86_arch_indices) <X86_ARCH_CALL_ESP>: New.
(TARGET_CALL_ESP): New define.
* config/i386/i386.c (initial_ix86_tune_features): Initialize
X86_ARCH_CALL_ESP.
* config/i386/i386.md
(*call_pop_1_esp, *call_1_esp, *call_value_pop_1_esp,
*call_value_1_esp): Rename from *call_pop_1, *call_1,
*call_value_pop_1 and *call_value_1. Depend on TARGET_CALL_ESP.
(*call_pop_1, *call_1, *call_value_pop_1, *call_value_1):
New patterns, use "lsm" as operand 1 constraint.
* config/i386/predicates.md (call_insn_operand): Depend on
index_register_operand for !TARGET_CALL_ESP to avoid %esp register.
testsuite/ChangeLog:
PR target/41900
* gcc.target/i386/pr41900.c: New test.
From-SVN: r153838
-rw-r--r-- | gcc/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 90 | ||||
-rw-r--r-- | gcc/config/i386/predicates.md | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr41900.c | 11 |
7 files changed, 118 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3b64aed..6ab0707 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2009-11-03 Uros Bizjak <ubizjak@gmail.com> + + PR target/41900 + * config/i386/i386.h (ix86_arch_indices) <X86_ARCH_CALL_ESP>: New. + (TARGET_CALL_ESP): New define. + * config/i386/i386.c (initial_ix86_tune_features): Initialize + X86_ARCH_CALL_ESP. + * config/i386/i386.md + (*call_pop_1_esp, *call_1_esp, *call_value_pop_1_esp, + *call_value_1_esp): Rename from *call_pop_1, *call_1, + *call_value_pop_1 and *call_value_1. Depend on TARGET_CALL_ESP. + (*call_pop_1, *call_1, *call_value_pop_1, *call_value_1): + New patterns, use "lsm" as operand 1 constraint. + * config/i386/predicates.md (call_insn_operand): Depend on + index_register_operand for !TARGET_CALL_ESP to avoid %esp register. + 2009-11-02 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> PR tree-optimization/41857 @@ -224,7 +240,7 @@ 2009-10-28 Rafael Avila de Espindola <espindola@google.com> * doc/invoke.texi: Rename -use-linker-plugin -fuse-linker-plugin. - + 2009-10-28 Rafael Avila de Espindola <espindola@google.com> * dbxout.c (dbxout_common_check): Accept non public trees. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5d6eb0f..c29a784 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1553,6 +1553,11 @@ static unsigned int initial_ix86_arch_features[X86_ARCH_LAST] = { /* X86_ARCH_BSWAP: Byteswap was added for 80486. */ ~m_386, + + /* X86_ARCH_CALL_ESP: P6 processors will jump to the address after + the decrement (so they will execute return address as code). See + Pentium Pro errata 70, Pentium 2 errata A33, Pentium 3 errata E17. */ + ~(m_386 | m_486 | m_PENT | m_PPRO), }; static const unsigned int x86_accumulate_outgoing_args diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 22187a9..b412604 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -400,6 +400,7 @@ enum ix86_arch_indices { X86_ARCH_CMPXCHG8B, X86_ARCH_XADD, X86_ARCH_BSWAP, + X86_ARCH_CALL_ESP, X86_ARCH_LAST }; @@ -411,6 +412,7 @@ extern unsigned char ix86_arch_features[X86_ARCH_LAST]; #define TARGET_CMPXCHG8B ix86_arch_features[X86_ARCH_CMPXCHG8B] #define TARGET_XADD ix86_arch_features[X86_ARCH_XADD] #define TARGET_BSWAP ix86_arch_features[X86_ARCH_BSWAP] +#define TARGET_CALL_ESP ix86_arch_features[X86_ARCH_CALL_ESP] #define TARGET_FISTTP (TARGET_SSE3 && TARGET_80387) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 408787b..dc605ab 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -14566,12 +14566,25 @@ } [(set_attr "type" "call")]) -(define_insn "*call_pop_1" +(define_insn "*call_pop_1_esp" [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) (match_operand:SI 1 "" "")) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand:SI 2 "immediate_operand" "i")))] - "!SIBLING_CALL_P (insn) && !TARGET_64BIT" + "!TARGET_64BIT && TARGET_CALL_ESP && !SIBLING_CALL_P (insn)" +{ + if (constant_call_address_operand (operands[0], Pmode)) + return "call\t%P0"; + return "call\t%A0"; +} + [(set_attr "type" "call")]) + +(define_insn "*call_pop_1" + [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm")) + (match_operand:SI 1 "" "")) + (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) + (match_operand:SI 2 "immediate_operand" "i")))] + "!TARGET_64BIT && !TARGET_CALL_ESP && !SIBLING_CALL_P (insn)" { if (constant_call_address_operand (operands[0], Pmode)) return "call\t%P0"; @@ -14584,7 +14597,7 @@ (match_operand:SI 1 "" "")) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand:SI 2 "immediate_operand" "i,i")))] - "SIBLING_CALL_P (insn) && !TARGET_64BIT" + "!TARGET_64BIT && SIBLING_CALL_P (insn)" "@ jmp\t%P0 jmp\t%A0" @@ -14622,10 +14635,21 @@ } [(set_attr "type" "call")]) -(define_insn "*call_1" +(define_insn "*call_1_esp" [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) (match_operand 1 "" ""))] - "!SIBLING_CALL_P (insn) && !TARGET_64BIT" + "!TARGET_64BIT && TARGET_CALL_ESP && !SIBLING_CALL_P (insn)" +{ + if (constant_call_address_operand (operands[0], Pmode)) + return "call\t%P0"; + return "call\t%A0"; +} + [(set_attr "type" "call")]) + +(define_insn "*call_1" + [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm")) + (match_operand 1 "" ""))] + "!TARGET_64BIT && !TARGET_CALL_ESP && !SIBLING_CALL_P (insn)" { if (constant_call_address_operand (operands[0], Pmode)) return "call\t%P0"; @@ -14636,7 +14660,7 @@ (define_insn "*sibcall_1" [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U")) (match_operand 1 "" ""))] - "SIBLING_CALL_P (insn) && !TARGET_64BIT" + "!TARGET_64BIT && SIBLING_CALL_P (insn)" "@ jmp\t%P0 jmp\t%A0" @@ -14645,7 +14669,7 @@ (define_insn "*call_1_rex64" [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) (match_operand 1 "" ""))] - "!SIBLING_CALL_P (insn) && TARGET_64BIT + "TARGET_64BIT && !SIBLING_CALL_P (insn) && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC" { if (constant_call_address_operand (operands[0], Pmode)) @@ -14670,7 +14694,7 @@ (clobber (reg:TI XMM15_REG)) (clobber (reg:DI SI_REG)) (clobber (reg:DI DI_REG))] - "!SIBLING_CALL_P (insn) && TARGET_64BIT" + "TARGET_64BIT && !SIBLING_CALL_P (insn)" { if (constant_call_address_operand (operands[0], Pmode)) return "call\t%P0"; @@ -14681,14 +14705,14 @@ (define_insn "*call_1_rex64_large" [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm")) (match_operand 1 "" ""))] - "!SIBLING_CALL_P (insn) && TARGET_64BIT" + "TARGET_64BIT && !SIBLING_CALL_P (insn)" "call\t%A0" [(set_attr "type" "call")]) (define_insn "*sibcall_1_rex64" [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U")) (match_operand 1 "" ""))] - "SIBLING_CALL_P (insn) && TARGET_64BIT" + "TARGET_64BIT && SIBLING_CALL_P (insn)" "@ jmp\t%P0 jmp\t%A0" @@ -21084,13 +21108,27 @@ } [(set_attr "type" "callv")]) -(define_insn "*call_value_pop_1" +(define_insn "*call_value_pop_1_esp" [(set (match_operand 0 "" "") (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) (match_operand:SI 2 "" ""))) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand:SI 3 "immediate_operand" "i")))] - "!SIBLING_CALL_P (insn) && !TARGET_64BIT" + "!TARGET_64BIT && TARGET_CALL_ESP && !SIBLING_CALL_P (insn)" +{ + if (constant_call_address_operand (operands[1], Pmode)) + return "call\t%P1"; + return "call\t%A1"; +} + [(set_attr "type" "callv")]) + +(define_insn "*call_value_pop_1" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm")) + (match_operand:SI 2 "" ""))) + (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) + (match_operand:SI 3 "immediate_operand" "i")))] + "!TARGET_64BIT && !TARGET_CALL_ESP && !SIBLING_CALL_P (insn)" { if (constant_call_address_operand (operands[1], Pmode)) return "call\t%P1"; @@ -21104,7 +21142,7 @@ (match_operand:SI 2 "" ""))) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand:SI 3 "immediate_operand" "i,i")))] - "SIBLING_CALL_P (insn) && !TARGET_64BIT" + "!TARGET_64BIT && SIBLING_CALL_P (insn)" "@ jmp\t%P1 jmp\t%A1" @@ -21153,7 +21191,7 @@ (clobber (reg:TI XMM15_REG)) (clobber (reg:DI SI_REG)) (clobber (reg:DI DI_REG))] - "!SIBLING_CALL_P (insn) && TARGET_64BIT" + "TARGET_64BIT && !SIBLING_CALL_P (insn)" { if (SIBLING_CALL_P (insn)) return "jmp\t%P1"; @@ -21162,11 +21200,23 @@ } [(set_attr "type" "callv")]) -(define_insn "*call_value_1" +(define_insn "*call_value_1_esp" [(set (match_operand 0 "" "") (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) (match_operand:SI 2 "" "")))] - "!SIBLING_CALL_P (insn) && !TARGET_64BIT" + "!TARGET_64BIT && TARGET_CALL_ESP && !SIBLING_CALL_P (insn)" +{ + if (constant_call_address_operand (operands[1], Pmode)) + return "call\t%P1"; + return "call\t%A1"; +} + [(set_attr "type" "callv")]) + +(define_insn "*call_value_1" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm")) + (match_operand:SI 2 "" "")))] + "!TARGET_64BIT && !TARGET_CALL_ESP && !SIBLING_CALL_P (insn)" { if (constant_call_address_operand (operands[1], Pmode)) return "call\t%P1"; @@ -21178,7 +21228,7 @@ [(set (match_operand 0 "" "") (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U")) (match_operand:SI 2 "" "")))] - "SIBLING_CALL_P (insn) && !TARGET_64BIT" + "!TARGET_64BIT && SIBLING_CALL_P (insn)" "@ jmp\t%P1 jmp\t%A1" @@ -21188,7 +21238,7 @@ [(set (match_operand 0 "" "") (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) (match_operand:DI 2 "" "")))] - "!SIBLING_CALL_P (insn) && TARGET_64BIT + "TARGET_64BIT && !SIBLING_CALL_P (insn) && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC" { if (constant_call_address_operand (operands[1], Pmode)) @@ -21226,7 +21276,7 @@ [(set (match_operand 0 "" "") (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm")) (match_operand:DI 2 "" "")))] - "!SIBLING_CALL_P (insn) && TARGET_64BIT" + "TARGET_64BIT && !SIBLING_CALL_P (insn)" "call\t%A1" [(set_attr "type" "callv")]) @@ -21234,7 +21284,7 @@ [(set (match_operand 0 "" "") (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U")) (match_operand:DI 2 "" "")))] - "SIBLING_CALL_P (insn) && TARGET_64BIT" + "TARGET_64BIT && SIBLING_CALL_P (insn)" "@ jmp\t%P1 jmp\t%A1" diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index f9a4744..dee6df9 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -561,7 +561,9 @@ ;; Test for a valid operand for a call instruction. (define_predicate "call_insn_operand" (ior (match_operand 0 "constant_call_address_operand") - (ior (match_operand 0 "register_no_elim_operand") + (ior (and (match_operand 0 "register_no_elim_operand") + (ior (match_test "TARGET_CALL_ESP") + (match_operand 0 "index_register_operand"))) (match_operand 0 "memory_operand")))) ;; Similarly, but for tail calls, in which we cannot allow memory references. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 26c04dc..672d36d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,12 +1,16 @@ - 2009-11-02 Andy Hutchinson <hutchinsonandy@gcc.gnu.org> +2009-11-03 Uros Bizjak <ubizjak@gmail.com> - *gcc.c-torture/execute/pr40668.c: Correct for 16bit int size. + PR target/41900 + * gcc.target/i386/pr41900.c: New test. + +2009-11-02 Andy Hutchinson <hutchinsonandy@gcc.gnu.org> + + * gcc.c-torture/execute/pr40668.c: Correct for 16bit int size. 2009-11-02 Dodji Seketeli <dodji@redhat.com> PR c++/41856 - * g++.dg/lookup/extern-c-redecl3.C: Make the test x86 - only. + * g++.dg/lookup/extern-c-redecl3.C: Make the test x86 only. * g++.dg/lookup/extern-c-redecl4.C: Likewise. 2009-11-02 Dodji Seketeli <dodji@redhat.com> @@ -151,7 +155,7 @@ 2009-10-29 Tobias Burnus <burnus@net-b.de> PR fortran/41777 - gfortran.dg/associated_target_3.f90: New testcase. + * gfortran.dg/associated_target_3.f90: New testcase. 2009-10-29 Rafael Avila de Espindola <espindola@google.com> @@ -339,8 +343,7 @@ * lib/target-supports.exp (check_profiling_available): Profiling is not, currently, available for the RX port. - (check_effective_target_hard_float): Add support for RX - target. + (check_effective_target_hard_float): Add support for RX target. * gcc.target/rx: New directory. * gcc.target/rx/builtins.c: New test file. * gcc.target/rx/interrupts.c: New test file. diff --git a/gcc/testsuite/gcc.target/i386/pr41900.c b/gcc/testsuite/gcc.target/i386/pr41900.c new file mode 100644 index 0000000..ac5f863 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr41900.c @@ -0,0 +1,11 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-O2 -fomit-frame-pointer -mpreferred-stack-boundary=2" } */ + +int main () +{ + unsigned code = 0xc3; + + ((void (*)(void)) &code) (); + return 0; +} |