From: Richard Henderson Date: Thu, 24 Oct 2002 09:16:36 +0000 (-0700) Subject: ia64.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): True. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5f13cfc6176adc33d11114023cc41b5e61e6b250;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f368957a55..17bac5c6473 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-10-24 Richard Henderson + + * 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 PR opt/7944 diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index a238507c922..63a6258d7a9 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 (¤t_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 fc2c7c2c302..9823511e05d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-10-24 Richard Henderson + + * g++.dg/inherit/thunk1.C: Enable for ia64. + 2002-10-23 Mark Mitchell PR c++/8067 diff --git a/gcc/testsuite/g++.dg/inherit/thunk1.C b/gcc/testsuite/g++.dg/inherit/thunk1.C index 8fd411b2a5a..4426419e9da 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