re PR target/6054 (GCC 3.1 for ia64 fails to restore gp after indirect call in Linux kernel)
PR target/6054 * config/ia64/ia64.c (ia64_expand_call): Use pic patterns for TARGET_CONST_GP. Simplify conditions. * gcc.dg/20020326-1.c: New. From-SVN: r51444
This commit is contained in:
parent
59f9687974
commit
6dad5a5631
@ -1,3 +1,9 @@
|
||||
2002-03-27 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR target/6054
|
||||
* config/ia64/ia64.c (ia64_expand_call): Use pic patterns for
|
||||
TARGET_CONST_GP. Simplify conditions.
|
||||
|
||||
2002-03-27 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/sparc/freebsd.h, config/sparc/linux.h, config/sparc/linux64.h,
|
||||
|
@ -1144,7 +1144,8 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
|
||||
rtx nextarg;
|
||||
int sibcall_p;
|
||||
{
|
||||
rtx insn, b0, pfs, gp_save, narg_rtx;
|
||||
rtx insn, b0, pfs, gp_save, narg_rtx, dest;
|
||||
bool indirect_p;
|
||||
int narg;
|
||||
|
||||
addr = XEXP (addr, 0);
|
||||
@ -1171,61 +1172,36 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
|
||||
return;
|
||||
}
|
||||
|
||||
if (sibcall_p)
|
||||
indirect_p = ! symbolic_operand (addr, VOIDmode);
|
||||
|
||||
if (sibcall_p || (TARGET_CONST_GP && !indirect_p))
|
||||
gp_save = NULL_RTX;
|
||||
else
|
||||
gp_save = ia64_gp_save_reg (setjmp_operand (addr, VOIDmode));
|
||||
|
||||
if (gp_save)
|
||||
emit_move_insn (gp_save, pic_offset_table_rtx);
|
||||
|
||||
/* If this is an indirect call, then we have the address of a descriptor. */
|
||||
if (! symbolic_operand (addr, VOIDmode))
|
||||
if (indirect_p)
|
||||
{
|
||||
rtx dest;
|
||||
|
||||
if (! sibcall_p)
|
||||
emit_move_insn (gp_save, pic_offset_table_rtx);
|
||||
|
||||
dest = force_reg (DImode, gen_rtx_MEM (DImode, addr));
|
||||
emit_move_insn (pic_offset_table_rtx,
|
||||
gen_rtx_MEM (DImode, plus_constant (addr, 8)));
|
||||
|
||||
if (sibcall_p)
|
||||
insn = gen_sibcall_pic (dest, narg_rtx, b0, pfs);
|
||||
else if (! retval)
|
||||
insn = gen_call_pic (dest, narg_rtx, b0);
|
||||
else
|
||||
insn = gen_call_value_pic (retval, dest, narg_rtx, b0);
|
||||
emit_call_insn (insn);
|
||||
|
||||
if (! sibcall_p)
|
||||
emit_move_insn (pic_offset_table_rtx, gp_save);
|
||||
}
|
||||
else if (TARGET_CONST_GP)
|
||||
{
|
||||
if (sibcall_p)
|
||||
insn = gen_sibcall_nopic (addr, narg_rtx, b0, pfs);
|
||||
else if (! retval)
|
||||
insn = gen_call_nopic (addr, narg_rtx, b0);
|
||||
else
|
||||
insn = gen_call_value_nopic (retval, addr, narg_rtx, b0);
|
||||
emit_call_insn (insn);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sibcall_p)
|
||||
emit_call_insn (gen_sibcall_pic (addr, narg_rtx, b0, pfs));
|
||||
else
|
||||
{
|
||||
emit_move_insn (gp_save, pic_offset_table_rtx);
|
||||
dest = addr;
|
||||
|
||||
if (! retval)
|
||||
insn = gen_call_pic (addr, narg_rtx, b0);
|
||||
else
|
||||
insn = gen_call_value_pic (retval, addr, narg_rtx, b0);
|
||||
emit_call_insn (insn);
|
||||
if (sibcall_p)
|
||||
insn = gen_sibcall_pic (dest, narg_rtx, b0, pfs);
|
||||
else if (! retval)
|
||||
insn = gen_call_pic (dest, narg_rtx, b0);
|
||||
else
|
||||
insn = gen_call_value_pic (retval, dest, narg_rtx, b0);
|
||||
emit_call_insn (insn);
|
||||
|
||||
emit_move_insn (pic_offset_table_rtx, gp_save);
|
||||
}
|
||||
}
|
||||
if (gp_save)
|
||||
emit_move_insn (pic_offset_table_rtx, gp_save);
|
||||
}
|
||||
|
||||
/* Begin the assembly file. */
|
||||
|
11
gcc/testsuite/gcc.dg/20020326-1.c
Normal file
11
gcc/testsuite/gcc.dg/20020326-1.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* PR target/6054 */
|
||||
/* { dg-do compile { target ia64-*-* } } */
|
||||
/* { dg-options "-O -mconstant-gp" } */
|
||||
/* { dg-final { scan-assembler "mov r1 =" } } */
|
||||
|
||||
extern void direct (void);
|
||||
void foo(void (*indirect) (void))
|
||||
{
|
||||
indirect ();
|
||||
direct ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user