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 /gcc/config | |
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
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/constraints.md | 12 | ||||
-rw-r--r-- | gcc/config/i386/predicates.md | 32 |
2 files changed, 26 insertions, 18 deletions
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" |