Commit fa87d16d by H.J. Lu Committed by Uros Bizjak

[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
parent fc9ca1a0
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
......@@ -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."
......
......@@ -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"
......
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
......
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment