From: Richard Henderson Date: Wed, 27 Mar 2002 10:34:14 +0000 (-0800) Subject: re PR target/6054 (GCC 3.1 for ia64 fails to restore gp after indirect call in Linux... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6dad5a56316443a832b581d384e1596fad690be1;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 80df83c3e22..79b9d502043 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-03-27 Richard Henderson + + PR target/6054 + * config/ia64/ia64.c (ia64_expand_call): Use pic patterns for + TARGET_CONST_GP. Simplify conditions. + 2002-03-27 Richard Henderson * config/sparc/freebsd.h, config/sparc/linux.h, config/sparc/linux64.h, diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index de0c1c94141..c78d6319d82 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -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. */ diff --git a/gcc/testsuite/gcc.dg/20020326-1.c b/gcc/testsuite/gcc.dg/20020326-1.c new file mode 100644 index 00000000000..4a903bc91c4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20020326-1.c @@ -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 (); +}