Commit 6dad5a56 by Richard Henderson Committed by Richard Henderson

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
parent 59f96879
2002-03-27 Richard Henderson <rth@redhat.com> 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, * config/sparc/freebsd.h, config/sparc/linux.h, config/sparc/linux64.h,
config/sparc/netbsd-elf.h, config/sparc/pbd.h, config/sparc/sol2.h, config/sparc/netbsd-elf.h, config/sparc/pbd.h, config/sparc/sol2.h,
config/sparc/vxsim.h (LOCAL_LABEL_PREFIX): Define. config/sparc/vxsim.h (LOCAL_LABEL_PREFIX): Define.
......
...@@ -1144,7 +1144,8 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p) ...@@ -1144,7 +1144,8 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
rtx nextarg; rtx nextarg;
int sibcall_p; 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; int narg;
addr = XEXP (addr, 0); addr = XEXP (addr, 0);
...@@ -1171,61 +1172,36 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p) ...@@ -1171,61 +1172,36 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
return; return;
} }
if (sibcall_p) indirect_p = ! symbolic_operand (addr, VOIDmode);
if (sibcall_p || (TARGET_CONST_GP && !indirect_p))
gp_save = NULL_RTX; gp_save = NULL_RTX;
else else
gp_save = ia64_gp_save_reg (setjmp_operand (addr, VOIDmode)); 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 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)); dest = force_reg (DImode, gen_rtx_MEM (DImode, addr));
emit_move_insn (pic_offset_table_rtx, emit_move_insn (pic_offset_table_rtx,
gen_rtx_MEM (DImode, plus_constant (addr, 8))); 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 else
{ dest = addr;
if (sibcall_p)
emit_call_insn (gen_sibcall_pic (addr, narg_rtx, b0, pfs));
else
{
emit_move_insn (gp_save, pic_offset_table_rtx);
if (! retval) if (sibcall_p)
insn = gen_call_pic (addr, narg_rtx, b0); insn = gen_sibcall_pic (dest, narg_rtx, b0, pfs);
else else if (! retval)
insn = gen_call_value_pic (retval, addr, narg_rtx, b0); insn = gen_call_pic (dest, narg_rtx, b0);
emit_call_insn (insn); 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. */ /* Begin the assembly file. */
......
/* 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 ();
}
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