From e21f958766601f20c29dda516c84e8240e01cbdc Mon Sep 17 00:00:00 2001 From: uros Date: Wed, 23 Dec 2015 09:49:28 +0000 Subject: [PATCH] [PATCH] Allow indirect call via GOT for 64-bit Pmode x32 From: H.J. Lu 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231923 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 +++++++ gcc/config/i386/constraints.md | 12 +++++--- gcc/config/i386/predicates.md | 32 ++++++++++++---------- gcc/testsuite/ChangeLog | 8 ++++++ gcc/testsuite/gcc.target/i386/pr66232-10.c | 13 +++++++++ gcc/testsuite/gcc.target/i386/pr66232-11.c | 14 ++++++++++ gcc/testsuite/gcc.target/i386/pr66232-12.c | 13 +++++++++ gcc/testsuite/gcc.target/i386/pr66232-13.c | 13 +++++++++ 8 files changed, 97 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-10.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-11.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-12.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-13.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 032e2da59951..05c6460466d5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-12-23 H.J. Lu + + 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 PR c/68473 diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 2861d8dfdd2a..b46d32b57281 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 96d946c63d36..17249e766bad 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 1ee6af033e6d..524b9b02e146 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-12-23 H.J. Lu + + 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 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 000000000000..c4e9157ac13c --- /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 000000000000..05794af83ece --- /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 000000000000..313b9e4d8946 --- /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 000000000000..50a12cf91fdf --- /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" } } */ -- 2.47.2