This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix -fpic/-fPIC virtual thunks on s390 -m31
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Ulrich Weigand <weigand at immd1 dot informatik dot uni-erlangen dot de>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 20 Jun 2003 18:31:35 +0200
- Subject: [PATCH] Fix -fpic/-fPIC virtual thunks on s390 -m31
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
s390 31-bit .plt slots require %r12 to be loaded with .plt's shared library
_GLOBAL_OFFSET_TABLE_. As we cannot load that (%r12 is call-saved and we
don't return back into the thunk (we would have to copy arguments otherwise
and we don't know how many there are), we cannot use .plt.
The following patch changes 31-bit thunks calling to non-local functions
in -fpic/-fPIC to load the function pointer from .got instead.
For -fpic it uses:
basr %r1,0
.L4:
a %r1,.L5-.L4(%r1)
l %r1,the_function@GOT12(%r1)
br %r1
.align 4
.L5:
.long _GLOBAL_OFFSET_TABLE_-.L4
and for -fPIC:
basr %r1,0
.L6:
l %r0,.L7-4-.L6(%r1)
a %r1,.L7-.L6(%r1)
ar %r1,%r0
l %r1,0(%r1)
br %r1
.align 4
.long the_function@GOT
.L7:
.long _GLOBAL_OFFSET_TABLE_-.L6
Ok to commit (or are different sequences better)?
3.3 has the same bug.
2003-06-20 Jakub Jelinek <jakub@redhat.com>
* config/s390/s390.c (s390_output_mi_thunk): Avoid .plt in -m31
mode, as it requires pic register loaded.
--- gcc/config/s390/s390.c.jj 2003-05-17 04:59:02.000000000 -0400
+++ gcc/config/s390/s390.c 2003-06-20 12:05:21.000000000 -0400
@@ -6483,13 +6483,16 @@ s390_output_mi_thunk (file, thunk, delta
HOST_WIDE_INT vcall_offset;
tree function;
{
- rtx op[9];
+ rtx op[10];
+ int nonlocal = 0;
/* Operand 0 is the target function. */
op[0] = XEXP (DECL_RTL (function), 0);
if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
{
- op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]), 113);
+ nonlocal = 1;
+ op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
+ TARGET_64BIT ? 113 : flag_pic == 2 ? 112 : 110);
op[0] = gen_rtx_CONST (Pmode, op[0]);
}
@@ -6514,6 +6517,9 @@ s390_output_mi_thunk (file, thunk, delta
op[7] = NULL_RTX;
op[8] = NULL_RTX;
+ /* Operand 9 can be used for temporary register. */
+ op[9] = NULL_RTX;
+
/* Generate code. */
if (TARGET_64BIT)
{
@@ -6644,14 +6650,39 @@ s390_output_mi_thunk (file, thunk, delta
/* Jump to target. */
op[8] = gen_label_rtx ();
+
if (!flag_pic)
output_asm_insn ("l\t%4,%8-%5(%4)", op);
- else
+ else if (!nonlocal)
output_asm_insn ("a\t%4,%8-%5(%4)", op);
+ /* We cannot call through .plt, since .plt requires %r12 loaded. */
+ else if (flag_pic == 1)
+ {
+ output_asm_insn ("a\t%4,%8-%5(%4)", op);
+ output_asm_insn ("l\t%4,%0(%4)", op);
+ }
+ else if (flag_pic == 2)
+ {
+ op[9] = gen_rtx_REG (Pmode, 0);
+ output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
+ output_asm_insn ("a\t%4,%8-%5(%4)", op);
+ output_asm_insn ("ar\t%4,%9", op);
+ output_asm_insn ("l\t%4,0(%4)", op);
+ }
+
output_asm_insn ("br\t%4", op);
/* Output literal pool. */
output_asm_insn (".align\t4", op);
+
+ if (nonlocal && flag_pic == 2)
+ output_asm_insn (".long\t%0", op);
+ if (nonlocal)
+ {
+ op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
+ }
+
(*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (op[8]));
if (!flag_pic)
output_asm_insn (".long\t%0", op);
Jakub