aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2015-12-23 09:49:28 +0000
committerUros Bizjak <uros@gcc.gnu.org>2015-12-23 10:49:28 +0100
commitfa87d16dcf766d1754837e71d5a1abc97a9e0c8b (patch)
treefc9c5459806e88a34d0c675bdf00a8da5ccebb46 /gcc/config
parentfc9ca1a0a1632f1cd0884bbc434b00e8be09a4b5 (diff)
downloadgcc-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.md12
-rw-r--r--gcc/config/i386/predicates.md32
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"