* config/ia64/ia64.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): True.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 24 Oct 2002 09:16:36 +0000 (09:16 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 24 Oct 2002 09:16:36 +0000 (09:16 +0000)
        (ia64_output_mi_thunk): Rewrite to use rtl, and to handle the
        vcall offset.
        * g++.dg/inherit/thunk1.C: Enable for ia64.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@58491 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/ia64/ia64.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/thunk1.C

index 7f36895..17bac5c 100644 (file)
@@ -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.
index a238507..63a6258 100644 (file)
@@ -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;
 \f
@@ -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"
index fc2c7c2..9823511 100644 (file)
@@ -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
index 8fd411b..4426419 100644 (file)
@@ -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>