aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-10-24 02:16:36 -0700
committerRichard Henderson <rth@gcc.gnu.org>2002-10-24 02:16:36 -0700
commit5f13cfc6176adc33d11114023cc41b5e61e6b250 (patch)
tree2acf2c8bbca1bdab17f88e1a4ed8b42132120fc7
parent3bd216f20128fabe1659826cc5717f2f4c7f8f71 (diff)
downloadgcc-5f13cfc6176adc33d11114023cc41b5e61e6b250.zip
gcc-5f13cfc6176adc33d11114023cc41b5e61e6b250.tar.gz
gcc-5f13cfc6176adc33d11114023cc41b5e61e6b250.tar.bz2
ia64.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): True.
* config/ia64/ia64.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): True. (ia64_output_mi_thunk): Rewrite to use rtl, and to handle the vcall offset. * g++.dg/inherit/thunk1.C: Enable for ia64. From-SVN: r58491
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/ia64/ia64.c112
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/inherit/thunk1.C2
4 files changed, 95 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7f36895..17bac5c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2002-10-24 Richard Henderson <rth@redhat.com>
+ * config/ia64/ia64.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): True.
+ (ia64_output_mi_thunk): Rewrite to use rtl, and to handle the
+ vcall offset.
+
+2002-10-24 Richard Henderson <rth@redhat.com>
+
PR opt/7944
* reload.c (find_reloads_toplev): Mode of X is not important
when simplifying subregs of constants.
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index a238507..63a6258 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -250,7 +250,7 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK ia64_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -8167,40 +8167,96 @@ ia64_aix_select_rtx_section (mode, x, align)
flag_pic = save_pic;
}
+/* Output the assembler code for a thunk function. THUNK_DECL is the
+ declaration for the thunk function itself, FUNCTION is the decl for
+ the target function. DELTA is an immediate constant offset to be
+ added to THIS. If VCALL_OFFSET is non-zero, the word at
+ *(*this + vcall_offset) should be added to THIS. */
+
static void
ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
FILE *file;
tree thunk ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
+ HOST_WIDE_INT vcall_offset;
tree function;
{
- if (CONST_OK_FOR_I (delta))
- {
- fprintf (file, "\tadds r32 = ");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, (delta));
- fprintf (file, ", r32\n");
- }
- else
- {
- if (CONST_OK_FOR_J (delta))
- {
- fprintf (file, "\taddl r2 = ");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, (delta));
- fprintf (file, ", r0\n");
- }
- else
- {
- fprintf (file, "\tmovl r2 = ");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, (delta));
- fprintf (file, "\n");
- }
- fprintf (file, "\t;;\n");
- fprintf (file, "\tadd r32 = r2, r32\n");
- }
- fprintf (file, "\tbr ");
- assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
- fprintf (file, "\n");
+ rtx this, insn, funexp;
+
+ /* Set things up as ia64_expand_prologue might. */
+ last_scratch_gr_reg = 15;
+
+ memset (&current_frame_info, 0, sizeof (current_frame_info));
+ current_frame_info.spill_cfa_off = -16;
+ current_frame_info.n_input_regs = 1;
+ current_frame_info.need_regstk = (TARGET_REG_NAMES != 0);
+
+ if (!TARGET_REG_NAMES)
+ reg_names[IN_REG (0)] = ia64_reg_numbers[0];
+
+ /* Mark the end of the (empty) prologue. */
+ emit_note (NULL, NOTE_INSN_PROLOGUE_END);
+
+ this = gen_rtx_REG (Pmode, IN_REG (0));
+
+ /* Apply the constant offset, if required. */
+ if (delta)
+ {
+ rtx delta_rtx = GEN_INT (delta);
+
+ if (!CONST_OK_FOR_I (delta))
+ {
+ rtx tmp = gen_rtx_REG (Pmode, 2);
+ emit_move_insn (tmp, delta_rtx);
+ delta_rtx = tmp;
+ }
+ emit_insn (gen_adddi3 (this, this, delta_rtx));
+ }
+
+ /* Apply the offset from the vtable, if required. */
+ if (vcall_offset)
+ {
+ rtx vcall_offset_rtx = GEN_INT (vcall_offset);
+ rtx tmp = gen_rtx_REG (Pmode, 2);
+
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
+
+ if (!CONST_OK_FOR_J (vcall_offset))
+ {
+ rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
+ emit_move_insn (tmp2, vcall_offset_rtx);
+ vcall_offset_rtx = tmp2;
+ }
+ emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
+
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
+
+ emit_insn (gen_adddi3 (this, this, tmp));
+ }
+
+ /* Generate a tail call to the target function. */
+ if (! TREE_USED (function))
+ {
+ assemble_external (function);
+ TREE_USED (function) = 1;
+ }
+ funexp = XEXP (DECL_RTL (function), 0);
+ funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
+ ia64_expand_call (NULL_RTX, funexp, NULL_RTX, 1);
+ insn = get_last_insn ();
+ SIBLING_CALL_P (insn) = 1;
+ emit_barrier ();
+
+ /* Run just enough of rest_of_compilation to get the insns emitted.
+ There's not really enough bulk here to make other passes such as
+ instruction scheduling worth while. Note that use_thunk calls
+ assemble_start_function and assemble_end_function. */
+ insn = get_insns ();
+ emit_all_insn_group_barriers (NULL, insn);
+ shorten_branches (insn);
+ final_start_function (insn, file, 1);
+ final (insn, file, 1, 0);
+ final_end_function ();
}
#include "gt-ia64.h"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fc2c7c2..9823511 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2002-10-24 Richard Henderson <rth@redhat.com>
+
+ * g++.dg/inherit/thunk1.C: Enable for ia64.
+
2002-10-23 Mark Mitchell <mark@codesourcery.com>
PR c++/8067
diff --git a/gcc/testsuite/g++.dg/inherit/thunk1.C b/gcc/testsuite/g++.dg/inherit/thunk1.C
index 8fd411b..4426419 100644
--- a/gcc/testsuite/g++.dg/inherit/thunk1.C
+++ b/gcc/testsuite/g++.dg/inherit/thunk1.C
@@ -1,4 +1,4 @@
-// { dg-do run { target i?86-*-* x86_64-*-* s390*-*-* alpha*-*-* } }
+// { dg-do run { target i?86-*-* x86_64-*-* s390*-*-* alpha*-*-* ia64-*-* } }
#include <stdarg.h>