diff options
author | H.J. Lu <hongjiu.lu@intel.com> | 2015-12-23 09:49:28 +0000 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2015-12-23 10:49:28 +0100 |
commit | fa87d16dcf766d1754837e71d5a1abc97a9e0c8b (patch) | |
tree | fc9c5459806e88a34d0c675bdf00a8da5ccebb46 | |
parent | fc9ca1a0a1632f1cd0884bbc434b00e8be09a4b5 (diff) | |
download | gcc-fa87d16dcf766d1754837e71d5a1abc97a9e0c8b.zip gcc-fa87d16dcf766d1754837e71d5a1abc97a9e0c8b.tar.gz gcc-fa87d16dcf766d1754837e71d5a1abc97a9e0c8b.tar.bz2 |
[PATCH] Allow indirect call via GOT for 64-bit Pmode x32
From: H.J. Lu <hongjiu.lu@intel.com>
Since Pmode is 64-bit with -maddress-mode=long for x32, indirect call
via GOT slot doesn't need zero_extend. This patch enables indirect call
via GOT for x32 with 64-bit Pmode.
gcc/
PR target/66232
* config/i386/constraints.md (Bs): Allow GOT slot for x32 with
64-bit Pmode.
(Bw): Likewise.
(Bz): Likewise.
* config/i386/predicates.md (call_insn_operand): Likewise.
(sibcall_insn_operand): Likewise.
gcc/testsuite/
PR target/66232
* gcc.target/i386/pr66232-10.c: New test.
* gcc.target/i386/pr66232-11.c: Likewise.
* gcc.target/i386/pr66232-12.c: Likewise.
* gcc.target/i386/pr66232-13.c: Likewise.
From-SVN: r231923
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/i386/constraints.md | 12 | ||||
-rw-r--r-- | gcc/config/i386/predicates.md | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr66232-10.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr66232-11.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr66232-12.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr66232-13.c | 13 |
8 files changed, 97 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 032e2da..05c6460 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-12-23 H.J. Lu <hongjiu.lu@intel.com> + + PR target/66232 + * config/i386/constraints.md (Bs): Allow GOT slot for x32 with + 64-bit Pmode. + (Bw): Likewise. + (Bz): Likewise. + * config/i386/predicates.md (call_insn_operand): Likewise. + (sibcall_insn_operand): Likewise. + 2015-12-22 David Malcolm <dmalcolm@redhat.com> PR c/68473 diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 2861d8d..b46d32b 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -162,13 +162,17 @@ (define_constraint "Bs" "@internal Sibcall memory operand." - (and (not (match_test "TARGET_X32")) - (match_operand 0 "sibcall_memory_operand"))) + (ior (and (not (match_test "TARGET_X32")) + (match_operand 0 "sibcall_memory_operand")) + (and (match_test "TARGET_X32 && Pmode == DImode") + (match_operand 0 "GOT_memory_operand")))) (define_constraint "Bw" "@internal Call memory operand." - (and (not (match_test "TARGET_X32")) - (match_operand 0 "memory_operand"))) + (ior (and (not (match_test "TARGET_X32")) + (match_operand 0 "memory_operand")) + (and (match_test "TARGET_X32 && Pmode == DImode") + (match_operand 0 "GOT_memory_operand")))) (define_constraint "Bz" "@internal Constant call address operand." diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 96d946c..17249e7 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -620,32 +620,36 @@ return false; }) +;; Return true if OP is a GOT memory operand. +(define_predicate "GOT_memory_operand" + (match_operand 0 "memory_operand") +{ + op = XEXP (op, 0); + return (GET_CODE (op) == CONST + && GET_CODE (XEXP (op, 0)) == UNSPEC + && XINT (XEXP (op, 0), 1) == UNSPEC_GOTPCREL); +}) + ;; Test for a valid operand for a call instruction. ;; Allow constant call address operands in Pmode only. (define_special_predicate "call_insn_operand" (ior (match_test "constant_call_address_operand (op, mode == VOIDmode ? mode : Pmode)") (match_operand 0 "call_register_no_elim_operand") - (and (not (match_test "TARGET_X32")) - (match_operand 0 "memory_operand")))) + (ior (and (not (match_test "TARGET_X32")) + (match_operand 0 "sibcall_memory_operand")) + (and (match_test "TARGET_X32 && Pmode == DImode") + (match_operand 0 "GOT_memory_operand"))))) ;; Similarly, but for tail calls, in which we cannot allow memory references. (define_special_predicate "sibcall_insn_operand" (ior (match_test "constant_call_address_operand (op, mode == VOIDmode ? mode : Pmode)") (match_operand 0 "register_no_elim_operand") - (and (not (match_test "TARGET_X32")) - (match_operand 0 "sibcall_memory_operand")))) - -;; Return true if OP is a GOT memory operand. -(define_predicate "GOT_memory_operand" - (match_operand 0 "memory_operand") -{ - op = XEXP (op, 0); - return (GET_CODE (op) == CONST - && GET_CODE (XEXP (op, 0)) == UNSPEC - && XINT (XEXP (op, 0), 1) == UNSPEC_GOTPCREL); -}) + (ior (and (not (match_test "TARGET_X32")) + (match_operand 0 "sibcall_memory_operand")) + (and (match_test "TARGET_X32 && Pmode == DImode") + (match_operand 0 "GOT_memory_operand"))))) ;; Return true if OP is a 32-bit GOT symbol operand. (define_predicate "GOT32_symbol_operand" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1ee6af0..524b9b0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-12-23 H.J. Lu <hongjiu.lu@intel.com> + + PR target/66232 + * gcc.target/i386/pr66232-10.c: New test. + * gcc.target/i386/pr66232-11.c: Likewise. + * gcc.target/i386/pr66232-12.c: Likewise. + * gcc.target/i386/pr66232-13.c: Likewise. + 2015-12-22 David Malcolm <dmalcolm@redhat.com> PR c/68473 diff --git a/gcc/testsuite/gcc.target/i386/pr66232-10.c b/gcc/testsuite/gcc.target/i386/pr66232-10.c new file mode 100644 index 0000000..c4e9157 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-10.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -fpic -fno-plt -maddress-mode=long" } */ + +extern void bar (void); + +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-11.c b/gcc/testsuite/gcc.target/i386/pr66232-11.c new file mode 100644 index 0000000..05794af --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-11.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -fpic -fno-plt -maddress-mode=long" } */ + +extern void bar (void); + +int +foo (void) +{ + bar (); + return 0; +} + +/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-12.c b/gcc/testsuite/gcc.target/i386/pr66232-12.c new file mode 100644 index 0000000..313b9e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-12.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -fpic -fno-plt -maddress-mode=long" } */ + +extern int bar (void); + +int +foo (void) +{ + return bar (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-13.c b/gcc/testsuite/gcc.target/i386/pr66232-13.c new file mode 100644 index 0000000..50a12cf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-13.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -fpic -fno-plt -maddress-mode=long" } */ + +extern int bar (void); + +int +foo (void) +{ + return bar () + 1; +} + +/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" } } */ |