summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-27 10:34:14 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-27 10:34:14 +0000
commit1c8a3b468a6c3346e54aef4b6b78b578e7037d55 (patch)
treed54d94353c2c82dd02ebc94714b3af184e829fe3
parentea81ed57ae700bdb2b5c681c8a7f4ec64b65f7b0 (diff)
downloadgcc-1c8a3b468a6c3346e54aef4b6b78b578e7037d55.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@51444 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/ia64/ia64.c62
-rw-r--r--gcc/testsuite/gcc.dg/20020326-1.c11
3 files changed, 36 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 80df83c3e22..79b9d502043 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
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/netbsd-elf.h, config/sparc/pbd.h, config/sparc/sol2.h,
config/sparc/vxsim.h (LOCAL_LABEL_PREFIX): Define.
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 ();
+}