* target-def.h (TARGET_ASM_OUTPUT_MI_THUNK): Default to NULL.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Oct 2002 23:35:40 +0000 (23:35 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Oct 2002 23:35:40 +0000 (23:35 +0000)
(TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Likewise.
(TARGET_ASM_OUT): Add them.
* target.h (asm_out): Add output_mi_thunk and
output_mi_vcall_thunk.
* config/alpha/alpha.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/arm/arm-protos.h (arm_output_mi_thunk): Declare.
* config/arm/arm.c (arm_output_mi_thunk): Define.
* config/arm/arm.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/cris/cris.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/frv/frv.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/i386/i386-protos.h (x86_output_mi_thunk): Adjust
prototype.
(x86_output_mi_vcall_thunk): Declare.
* config/i386/i386.c (override_options): Clear
output_mi_vcall_thunk in 64-bit mode.
(ix86_fntype_regparm): New function.
(ix86_return_pops_args): Use it.
(ia32_this_parameter): New function.
(x86_output_mi_vcall_thunk): New function.
(x86_output_mi_thunk): Use it
* config/i386/unix.h (TARGET_ASM_OUTPUT_MI_THUNK): Adjust.
(TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Define.
* config/i960/i960-protos.h (i960_output_mi_thunk): Declare.
* config/i960/i960.c (i960_output_mi_thunk): New function.
* config/i960/i960.h (ASM_OUTPUT_MI_THUNK): Adjust.
* config/ia64/ia64-protos.h (ia64_output_mi_thunk): Declare.
* config/ia64/ia64.c (ia64_output_mi_thunk): Define.
* config/ia64/ia64.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/m68k/m68k-protos.h (m68k_output_mi_thunk): New function.
* config/m68k/linux.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/m68k/netbsd-elf.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/mmix/mmix.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/pa/pa.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/rs6000/sysv4.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/s390/s390-protos.h (s390_output_mi_thunk): Declare.
* config/s390/s390.c (s390_output_mi_thunk): Define.
* config/s390/s390.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/sparc/sparc.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/stormy16/stormy16.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* config/vax/vax-protos.h (vax_output_mi_thunk): Declare.
* config/vax/vax.c (vax_output_mi_thunk): Define.
* config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Rename to ...
(TARGET_ASM_OUTPUT_MI_THUNK): ... this.
* doc/tm.texi: Adjust documentation.

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

38 files changed:
gcc/ChangeLog
gcc/config/alpha/alpha.h
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/cris/cris.h
gcc/config/frv/frv.h
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/unix.h
gcc/config/i960/i960-protos.h
gcc/config/i960/i960.c
gcc/config/i960/i960.h
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/m68k/linux.h
gcc/config/m68k/m68k-protos.h
gcc/config/m68k/m68k.c
gcc/config/m68k/netbsd-elf.h
gcc/config/mmix/mmix.h
gcc/config/pa/pa.h
gcc/config/rs6000/sysv4.h
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/sparc/sparc.h
gcc/config/stormy16/stormy16.h
gcc/config/vax/vax-protos.h
gcc/config/vax/vax.c
gcc/config/vax/vax.h
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/method.c
gcc/doc/tm.texi
gcc/target-def.h
gcc/target.h
gcc/testsuite/g++.dg/inherit/thunk1.C [new file with mode: 0644]

index 5ca6ddd..1fb2af1 100644 (file)
@@ -1,3 +1,64 @@
+2002-10-18  Mark Mitchell  <mark@codesourcery.com>
+
+       * target-def.h (TARGET_ASM_OUTPUT_MI_THUNK): Default to NULL.
+       (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Likewise.
+       (TARGET_ASM_OUT): Add them.
+       * target.h (asm_out): Add output_mi_thunk and
+       output_mi_vcall_thunk.
+       * config/alpha/alpha.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/arm/arm-protos.h (arm_output_mi_thunk): Declare.
+       * config/arm/arm.c (arm_output_mi_thunk): Define.
+       * config/arm/arm.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/cris/cris.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/frv/frv.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/i386/i386-protos.h (x86_output_mi_thunk): Adjust
+       prototype.
+       (x86_output_mi_vcall_thunk): Declare.
+       * config/i386/i386.c (override_options): Clear
+       output_mi_vcall_thunk in 64-bit mode.
+       (ix86_fntype_regparm): New function.
+       (ix86_return_pops_args): Use it.
+       (ia32_this_parameter): New function.
+       (x86_output_mi_vcall_thunk): New function.
+       (x86_output_mi_thunk): Use it
+       * config/i386/unix.h (TARGET_ASM_OUTPUT_MI_THUNK): Adjust.
+       (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Define.
+       * config/i960/i960-protos.h (i960_output_mi_thunk): Declare.
+       * config/i960/i960.c (i960_output_mi_thunk): New function.
+       * config/i960/i960.h (ASM_OUTPUT_MI_THUNK): Adjust.
+       * config/ia64/ia64-protos.h (ia64_output_mi_thunk): Declare.
+       * config/ia64/ia64.c (ia64_output_mi_thunk): Define.
+       * config/ia64/ia64.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/m68k/m68k-protos.h (m68k_output_mi_thunk): New function.
+       * config/m68k/linux.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/m68k/netbsd-elf.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/mmix/mmix.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/pa/pa.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/rs6000/sysv4.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/s390/s390-protos.h (s390_output_mi_thunk): Declare.
+       * config/s390/s390.c (s390_output_mi_thunk): Define.
+       * config/s390/s390.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/sparc/sparc.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/stormy16/stormy16.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * config/vax/vax-protos.h (vax_output_mi_thunk): Declare.
+       * config/vax/vax.c (vax_output_mi_thunk): Define.
+       * config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+       (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+       * doc/tm.texi: Adjust documentation.
+       
 2002-10-18  Jason Thorpe  <thorpej@wasabisystems.com>
 
        * config/netbsd.h (NETBSD_ENABLE_EXECUTE_STACK): Define 
index 0b70284..461dc95 100644 (file)
@@ -2141,5 +2141,4 @@ do {                                                      \
 
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-  alpha_output_mi_thunk_osf (FILE, THUNK_FNDECL, DELTA, FUNCTION)
+#define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
index b4e65c2..eac8dbb 100644 (file)
@@ -1,5 +1,5 @@
 /* Prototypes for exported functions defined in arm.c and pe.c
-   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by Richard Earnshaw (rearnsha@arm.com)
    Minor hacks by Nick Clifton (nickc@cygnus.com)
 
@@ -194,6 +194,7 @@ extern int  arm_dllexport_p                 PARAMS ((tree));
 extern int  arm_dllimport_p            PARAMS ((tree));
 extern void arm_mark_dllexport                 PARAMS ((tree));
 extern void arm_mark_dllimport                 PARAMS ((tree));
+extern void arm_output_mi_thunk         PARAMS ((FILE *, tree, int, tree));
 #endif
 
 extern void arm_init_builtins          PARAMS ((void));
index 23b9043..6971a53 100644 (file)
@@ -11130,3 +11130,38 @@ arm_encode_section_info (decl, first)
     }
 }
 #endif /* !ARM_PE */
+
+void
+arm_output_mi_thunk (file, thunk, delta, function)
+     FILE *file;
+     tree thunk ATTRIBUTE_UNUSED;
+     int delta;
+     tree function;
+{
+  int mi_delta = delta;
+  const char *const mi_op = mi_delta < 0 ? "sub" : "add";
+  int shift = 0;
+  int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)))
+                    ? 1 : 0);
+  if (mi_delta < 0)
+    mi_delta = - mi_delta;
+  while (mi_delta != 0)
+    {
+      if ((mi_delta & (3 << shift)) == 0)
+        shift += 2;
+      else
+        {
+          asm_fprintf (file, "\t%s\t%r, %r, #%d\n",
+                       mi_op, this_regno, this_regno,
+                       mi_delta & (0xff << shift));
+          mi_delta &= ~(0xff << shift);
+          shift += 8;
+        }
+    }
+  fputs ("\tb\t", file);
+  assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
+  if (NEED_PLT_RELOC)
+    fputs ("(PLT)", file);
+  fputc ('\n', file);
+}
+
index 3b3e38a..b4f6e70 100644 (file)
@@ -2697,36 +2697,7 @@ extern int making_const_table;
      
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)               \
-  do                                                                           \
-    {                                                                          \
-      int mi_delta = (DELTA);                                                  \
-      const char *const mi_op = mi_delta < 0 ? "sub" : "add";                  \
-      int shift = 0;                                                           \
-      int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION)))   \
-                       ? 1 : 0);                                               \
-      if (mi_delta < 0)                                                                \
-        mi_delta = - mi_delta;                                                 \
-      while (mi_delta != 0)                                                    \
-        {                                                                      \
-          if ((mi_delta & (3 << shift)) == 0)                                  \
-           shift += 2;                                                         \
-          else                                                                 \
-           {                                                                   \
-             asm_fprintf (FILE, "\t%s\t%r, %r, #%d\n",                         \
-                          mi_op, this_regno, this_regno,                       \
-                          mi_delta & (0xff << shift));                         \
-             mi_delta &= ~(0xff << shift);                                     \
-             shift += 8;                                                       \
-           }                                                                   \
-        }                                                                      \
-      fputs ("\tb\t", FILE);                                                   \
-      assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));           \
-      if (NEED_PLT_RELOC)                                                      \
-        fputs ("(PLT)", FILE);                                                 \
-      fputc ('\n', FILE);                                                      \
-    }                                                                          \
-  while (0)
+#define TARGET_ASM_OUTPUT_MI_THUNK arm_output_mi_thunk
 
 /* A C expression whose value is RTL representing the value of the return
    address for the frame COUNT steps up from the current frame.  */
index ddf84e5..717f249 100644 (file)
@@ -1013,8 +1013,7 @@ struct cum_args {int regs;};
 #define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN, N) \
   cris_eligible_for_epilogue_delay (INSN)
 
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
- cris_asm_output_mi_thunk(FILE, THUNK_FNDECL, DELTA, FUNCTION)
+#define TARGET_ASM_OUTPUT_MI_THUNK cris_asm_output_mi_thunk
 
 
 /* Node: Profiling */
index f5fe93e..8fc43a4 100644 (file)
@@ -2110,8 +2110,7 @@ struct machine_function GTY(())
    frontend will generate a less efficient heavyweight thunk that calls
    FUNCTION instead of jumping to it.  The generic approach does not support
    varargs.  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-frv_asm_output_mi_thunk (FILE, THUNK_FNDECL, (long)DELTA, FUNCTION)
+#define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk
 
 \f
 /* Generating Code for Profiling.  */
index f0bdf22..c3b7c30 100644 (file)
@@ -211,7 +211,8 @@ extern tree ix86_handle_shared_attribute PARAMS ((tree *, tree, tree, int, bool
 extern unsigned int i386_pe_section_type_flags PARAMS ((tree, const char *,
                                                        int));
 extern void i386_pe_asm_named_section PARAMS ((const char *, unsigned int));
-extern void x86_output_mi_thunk PARAMS ((FILE *, int, tree));
+extern void x86_output_mi_thunk PARAMS ((FILE *, tree, int, tree));
+extern void x86_output_mi_vcall_thunk PARAMS ((FILE *, tree, int, int, tree));
 extern int x86_field_alignment PARAMS ((tree, int));
 #endif
 
index 1ea90ee..c962702 100644 (file)
@@ -750,6 +750,7 @@ static int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
 static int ia32_use_dfa_pipeline_interface PARAMS ((void));
 static int ia32_multipass_dfa_lookahead PARAMS ((void));
 static void ix86_init_mmx_sse_builtins PARAMS ((void));
+static rtx ia32_this_parameter PARAMS ((tree));
 
 struct ix86_address
 {
@@ -788,6 +789,7 @@ static unsigned int ix86_select_alt_pic_regnum PARAMS ((void));
 static int ix86_save_reg PARAMS ((unsigned int, int));
 static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
 static int ix86_comp_type_attributes PARAMS ((tree, tree));
+static int ix86_fntype_regparm PARAMS ((tree));
 const struct attribute_spec ix86_attribute_table[];
 static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
 static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
@@ -1295,6 +1297,10 @@ override_options ()
     internal_label_prefix_len = p - internal_label_prefix;
     *p = '\0';
   }
+
+  /* In 64-bit mode, we do not have support for vcall thunks.  */
+  if (TARGET_64BIT)
+    targetm.asm_out.output_mi_vcall_thunk = NULL;
 }
 \f
 void
@@ -1431,6 +1437,21 @@ ix86_comp_type_attributes (type1, type2)
   return 1;
 }
 \f
+/* Return the regparm value for a fuctio with the indicated TYPE.  */
+
+static int
+ix86_fntype_regparm (type)
+     tree type;
+{
+  tree attr;
+
+  attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
+  if (attr)
+    return TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
+  else
+    return ix86_regparm;
+}
+
 /* Value is the number of bytes of arguments automatically
    popped when returning from a subroutine call.
    FUNDECL is the declaration node of the function (as a tree),
@@ -1474,15 +1495,7 @@ ix86_return_pops_args (fundecl, funtype, size)
   if (aggregate_value_p (TREE_TYPE (funtype))
       && !TARGET_64BIT)
     {
-      int nregs = ix86_regparm;
-
-      if (funtype)
-       {
-         tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (funtype));
-
-         if (attr)
-           nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
-       }
+      int nregs = ix86_fntype_regparm (funtype);
 
       if (!nregs)
        return GET_MODE_SIZE (Pmode);
@@ -13860,27 +13873,51 @@ x86_order_regs_for_local_alloc ()
      reg_alloc_order [pos++] = 0;
 }
 
+/* Returns an expression indicating where the this parameter is
+   located on entry to the FUNCTION.  */
+
+static rtx
+ia32_this_parameter (function)
+     tree function;
+{
+  tree type = TREE_TYPE (function);
+
+  if (ix86_fntype_regparm (type) > 0)
+    {
+      tree parm;
+
+      parm = TYPE_ARG_TYPES (type);
+      /* Figure out whether or not the function has a variable number of
+        arguments.  */
+      for (; parm; parm = TREE_CHAIN (parm))\
+       if (TREE_VALUE (parm) == void_type_node)
+         break;
+      /* If not, the this parameter is in %eax.  */
+      if (parm)
+       return gen_rtx_REG (SImode, 0);
+    }
+
+  if (aggregate_value_p (TREE_TYPE (type)))
+    return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8));
+  else
+    return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
+}
+
+
 void
-x86_output_mi_thunk (file, delta, function)
+x86_output_mi_vcall_thunk (file, thunk, delta, vcall_index, function)
      FILE *file;
+     tree thunk ATTRIBUTE_UNUSED;
      int delta;
+     int vcall_index;
      tree function;
 {
-  tree parm;
   rtx xops[3];
 
-  if (ix86_regparm > 0)
-    parm = TYPE_ARG_TYPES (TREE_TYPE (function));
-  else
-    parm = NULL_TREE;
-  for (; parm; parm = TREE_CHAIN (parm))
-    if (TREE_VALUE (parm) == void_type_node)
-      break;
-
-  xops[0] = GEN_INT (delta);
   if (TARGET_64BIT)
     {
       int n = aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) != 0;
+      xops[0] = GEN_INT (delta);
       xops[1] = gen_rtx_REG (DImode, x86_64_int_parameter_registers[n]);
       output_asm_insn ("add{q} {%0, %1|%1, %0}", xops);
       if (flag_pic)
@@ -13898,13 +13935,49 @@ x86_output_mi_thunk (file, delta, function)
     }
   else
     {
-      if (parm)
-       xops[1] = gen_rtx_REG (SImode, 0);
-      else if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
-       xops[1] = gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8));
-      else
-       xops[1] = gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
-      output_asm_insn ("add{l} {%0, %1|%1, %0}", xops);
+      /* Adjust the this parameter by a fixed constant.  */
+      if (delta)
+       {
+         xops[0] = GEN_INT (delta);
+         xops[1] = ia32_this_parameter (function);
+         output_asm_insn ("add{l}\t{%0, %1|%1, %0}", xops);
+       }
+
+      /* Adjust the this parameter by a value stored in the vtable.  */
+      if (vcall_index)
+       {
+         rtx this_parm;
+
+         /* Put the this parameter into %eax.  */
+         this_parm = ia32_this_parameter (function);
+         if (!REG_P (this_parm))
+           {
+             xops[0] = this_parm;
+             xops[1] = gen_rtx_REG (Pmode, 0);
+             output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
+           }
+         /* Load the virtual table pointer into %edx.  */
+         if (ix86_fntype_regparm (TREE_TYPE (function)) > 2)
+           error ("virtual function `%D' cannot have more than two register parameters",
+                  function);
+         xops[0] = gen_rtx_MEM (Pmode, 
+                                gen_rtx_REG (Pmode, 0));
+         xops[1] = gen_rtx_REG (Pmode, 1);
+         output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
+         /* Adjust the this parameter.  */
+         xops[0] = gen_rtx_MEM (SImode, 
+                                plus_constant (gen_rtx_REG (Pmode, 1), 
+                                               vcall_index));
+         xops[1] = gen_rtx_REG (Pmode, 0);
+         output_asm_insn ("add{l}\t{%0, %1|%1, %0}", xops);
+         /* Put the this parameter back where it came from.  */
+         if (!REG_P (this_parm))
+           {
+             xops[0] = gen_rtx_REG (Pmode, 0);
+             xops[1] = ia32_this_parameter (function);
+             output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
+           }
+       }
 
       if (flag_pic)
        {
@@ -13928,13 +14001,24 @@ x86_output_mi_thunk (file, delta, function)
        }
       else
        {
-         fprintf (file, "\tjmp ");
+         fprintf (file, "\tjmp\t");
          assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
          fprintf (file, "\n");
        }
     }
 }
 
+void
+x86_output_mi_thunk (file, thunk, delta, function)
+     FILE *file;
+     tree thunk;
+     int delta;
+     tree function;
+{
+  x86_output_mi_vcall_thunk (file, thunk, delta, /*vcall_index=*/0, 
+                            function);
+}
+
 int
 x86_field_alignment (field, computed)
      tree field;
index 3ba1bd5..09493b0 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for Unix assembler syntax for the Intel 80386.
-   Copyright (C) 1988, 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1994, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -68,5 +68,5 @@ Boston, MA 02111-1307, USA.  */
 
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-    x86_output_mi_thunk (FILE, DELTA, FUNCTION);
+#define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
+#define TARGET_ASM_OUTPUT_MI_VCALL_THUNK x86_output_mi_vcall_thunk
index 7e2685d..b7b74dc 100644 (file)
@@ -86,6 +86,7 @@ extern void i960_setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *, enum machine
 extern tree i960_build_va_list PARAMS ((void));
 extern int i960_final_reg_parm_stack_space PARAMS ((int, tree));
 extern int i960_reg_parm_stack_space PARAMS ((tree));
+extern void i960_output_mi_thunk PARAMS ((FILE *, tree, int, tree));
 #endif /* TREE_CODE */
 
 extern int process_pragma PARAMS ((int(*)(void), void(*)(int), const char *));
index 4917ae2..fe38d45 100644 (file)
@@ -2824,3 +2824,25 @@ i960_scan_opcode (p)
       break;
     }
 }
+
+void
+i960_output_mi_thunk (file, thunk, delta, function)
+     FILE *file;
+     tree thunk ATTRIBUTE_UNUSED;
+     int delta;
+     tree function;
+{
+  int d = delta;
+  if (d < 0 && d > -32)                                                        
+    fprintf (file, "\tsubo %d,g0,g0\n", -d);                           
+  else if (d > 0 && d < 32)                                            
+    fprintf (file, "\taddo %d,g0,g0\n", d);                            
+  else                                                                 
+    {                                                                  
+      fprintf (file, "\tldconst %d,r5\n", d);                          
+      fprintf (file, "\taddo r5,g0,g0\n");                             
+    }                                                                  
+  fprintf (file, "\tbx ");                                             
+  assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));       
+  fprintf (file, "\n");                                                        
+}
index ee27398..11932e9 100644 (file)
@@ -1466,19 +1466,4 @@ extern int rtx_equal_function_value_matters;
 
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)       \
-do {                                                                   \
-  int d = (DELTA);                                                     \
-  if (d < 0 && d > -32)                                                        \
-    fprintf (FILE, "\tsubo %d,g0,g0\n", -d);                           \
-  else if (d > 0 && d < 32)                                            \
-    fprintf (FILE, "\taddo %d,g0,g0\n", d);                            \
-  else                                                                 \
-    {                                                                  \
-      fprintf (FILE, "\tldconst %d,r5\n", d);                          \
-      fprintf (FILE, "\taddo r5,g0,g0\n");                             \
-    }                                                                  \
-  fprintf (FILE, "\tbx ");                                             \
-  assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));       \
-  fprintf (FILE, "\n");                                                        \
-} while (0);
+#define ASM_OUTPUT_MI_THUNK i960_output_mi_thunk
index 0e0ef04..6efb266 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler for IA-64.
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -121,6 +121,7 @@ extern int ia64_function_arg_pass_by_reference PARAMS((CUMULATIVE_ARGS *,
                                                       tree, int));
 extern int ia64_return_in_memory PARAMS((tree));
 extern void ia64_asm_output_external PARAMS((FILE *, tree, const char *));
+extern void ia64_output_mi_thunk PARAMS((FILE *, tree, int, tree));
 #endif /* TREE_CODE */
 
 extern int ia64_register_move_cost PARAMS((enum machine_mode, enum reg_class,
index bcfcc32..5fa9927 100644 (file)
@@ -8159,4 +8159,39 @@ ia64_aix_select_rtx_section (mode, x, align)
   flag_pic = save_pic;
 }
 
+void
+ia64_output_mi_thunk (file, thunk, delta, function)
+     FILE *file;
+     tree thunk ATTRIBUTE_UNUSED;
+     int delta;
+     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");                                                        
+}
+
 #include "gt-ia64.h"
index 1d96eaf..e0d5248 100644 (file)
@@ -1431,35 +1431,7 @@ do {                                                                     \
 /* A C compound statement that outputs the assembler code for a thunk function,
    used to implement C++ virtual function calls with multiple inheritance.  */
 
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-do {                                                                   \
-  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");                                                        \
-} while (0)
+#define TARGET_ASM_OUTPUT_MI_THUNK ia64_output_mi_thunk
 
 /* Output part N of a function descriptor for DECL.  For ia64, both
    words are emitted with a single relocation, so ignore N > 0.  */
index 2778d27..ce2fbb0 100644 (file)
@@ -357,25 +357,4 @@ do {                                                                       \
 \f
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)       \
-do {                                                                   \
-  if (DELTA > 0 && DELTA <= 8)                                         \
-    asm_fprintf (FILE, "\taddq.l %I%d,4(%Rsp)\n", DELTA);              \
-  else if (DELTA < 0 && DELTA >= -8)                                   \
-    asm_fprintf (FILE, "\tsubq.l %I%d,4(%Rsp)\n", -DELTA);             \
-  else                                                                 \
-    asm_fprintf (FILE, "\tadd.l %I%d,4(%Rsp)\n", DELTA);               \
-                                                                       \
-  if (flag_pic)                                                                \
-    {                                                                  \
-      fprintf (FILE, "\tbra.l ");                                      \
-      assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));   \
-      fprintf (FILE, "@PLTPC\n");                                      \
-    }                                                                  \
-  else                                                                 \
-    {                                                                  \
-      fprintf (FILE, "\tjmp ");                                                \
-      assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));   \
-      fprintf (FILE, "\n");                                            \
-    }                                                                  \
-} while (0)
+#define TARGET_ASM_OUTPUT_MI_THUNK m68k_output_mi_thunk
index 6a132be..33accb9 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler.  Sun 68000/68020 version.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -64,6 +64,10 @@ extern int pcrel_address PARAMS ((rtx, enum machine_mode));
 extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
 #endif /* RTX_CODE */
 
+#ifdef TREE_CODE
+extern void m68k_output_mi_thunk PARAMS ((FILE *, tree, int, tree));
+#endif /* TREE_CODE */
+
 extern int flags_in_68881 PARAMS ((void));
 extern int use_return_insn PARAMS ((void));
 extern void override_options PARAMS ((void));
index fc635fb..8a1a729 100644 (file)
@@ -3835,3 +3835,31 @@ m68k_svr3_asm_out_constructor (symbol, priority)
   output_asm_insn (output_move_simode (xop), xop);
 }
 #endif
+
+void
+m68k_output_mi_thunk (file, thunk, delta, function)
+     FILE *file;
+     tree thunk ATTRIBUTE_UNUSED;
+     int delta;
+     tree function;
+{
+  if (delta > 0 && delta <= 8)                                         
+    asm_fprintf (file, "\taddq.l %I%d,4(%Rsp)\n", delta);              
+  else if (delta < 0 && delta >= -8)                                   
+    asm_fprintf (file, "\tsubq.l %I%d,4(%Rsp)\n", -delta);             
+  else                                                                 
+    asm_fprintf (file, "\tadd.l %I%d,4(%Rsp)\n", delta);               
+                                                                       
+  if (flag_pic)                                                                
+    {                                                                  
+      fprintf (file, "\tbra.l ");                                      
+      assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));   
+      fprintf (file, "@PLTPC\n");                                      
+    }                                                                  
+  else                                                                 
+    {                                                                  
+      fprintf (file, "\tjmp ");                                                
+      assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));   
+      fprintf (file, "\n");                                            
+    }                                                                  
+}
index 078cd14..107bdeb 100644 (file)
@@ -425,31 +425,7 @@ while (0)
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
 
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)       \
-do                                                                     \
-  {                                                                    \
-    if (DELTA > 0 && DELTA <= 8)                                       \
-      asm_fprintf (FILE, "\taddq.l %I%d,4(%Rsp)\n", DELTA);            \
-    else if (DELTA < 0 && DELTA >= -8)                                 \
-      asm_fprintf (FILE, "\tsubq.l %I%d,4(%Rsp)\n", -DELTA);           \
-    else                                                               \
-      asm_fprintf (FILE, "\tadd.l %I%d,4(%Rsp)\n", DELTA);             \
-                                                                       \
-    if (flag_pic)                                                      \
-      {                                                                        \
-       fprintf (FILE, "\tbra.l ");                                     \
-       assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));  \
-       fprintf (FILE, "@PLTPC\n");                                     \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       fprintf (FILE, "\tjmp ");                                       \
-       assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));  \
-       fprintf (FILE, "\n");                                           \
-      }                                                                        \
-  }                                                                    \
-while (0)
-
+#define TARGET_ASM_OUTPUT_MI_THUNK m68k_output_mi_thunk
 
 /* Output assembler code for a block containing the constant parts
    of a trampoline, leaving space for the variable parts.  */
index e3d22d6..8001f0a 100644 (file)
@@ -795,8 +795,7 @@ typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
 #define EPILOGUE_USES(REGNO) \
  ((REGNO) == MMIX_INCOMING_RETURN_ADDRESS_REGNUM)
 
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)       \
- mmix_asm_output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
+#define TARGET_ASM_OUTPUT_MI_THUNK mmix_asm_output_mi_thunk
 
 
 /* Node: Profiling */
index e284210..003838c 100644 (file)
@@ -897,8 +897,7 @@ extern GTY(()) rtx hppa_compare_op0;
 extern GTY(()) rtx hppa_compare_op1;
 extern enum cmp_type hppa_branch_type;
 
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-  pa_asm_output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
+#define TARGET_ASM_OUTPUT_MI_THUNK pa_asm_output_mi_thunk
 
 /* On HPPA, we emit profiling code as rtl via PROFILE_HOOK rather than
    as assembly via FUNCTION_PROFILER.  Just output a local label.
index 56aa702..d393c8e 100644 (file)
@@ -667,8 +667,7 @@ extern int rs6000_pic_labelno;
     FUNCTION instead of jumping to it.  The generic approach does not support
     varargs.  */
 
-#define        ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-  output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
+#define        TARGET_ASM_OUTPUT_MI_THUNK output_mi_thunk
 
 /* The USER_LABEL_PREFIX stuff is affected by the -fleading-underscore
    flag.  The LOCAL_LABEL_PREFIX variable is used by dbxelf.h.  */
index aaf25d0..a906d44 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler, for IBM S/390.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
    Contributed by Hartmut Penner (hpenner@de.ibm.com)
 
 This file is part of GNU CC.
@@ -86,6 +86,7 @@ extern tree s390_build_va_list PARAMS ((void));
 extern rtx s390_function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
 extern void s390_va_start PARAMS ((tree, rtx));
 extern rtx s390_va_arg PARAMS ((tree, tree));
+extern void s390_output_mi_thunk PARAMS ((FILE *, tree, int, tree));
 #endif /* RTX_CODE */
 #endif /* TREE_CODE */
 
index b785b0b..f7404bc 100644 (file)
@@ -5582,3 +5582,78 @@ s390_encode_section_info (decl, first)
        }
     }
 }
+
+void
+s390_output_mi_thunk (file, thunk, delta, function)
+     FILE *file;
+     tree thunk ATTRIBUTE_UNUSED;
+     int delta;
+     tree function;
+{
+  if (TARGET_64BIT)                                                           
+    {                                                                         
+      if (flag_pic)                                                           
+        {                                                                     
+          fprintf (file, "\tlarl  1,0f\n");                                   
+          fprintf (file, "\tagf   %d,0(1)\n",                                 
+                   aggregate_value_p (TREE_TYPE                               
+                                      (TREE_TYPE (function))) ? 3 :2 );       
+          fprintf (file, "\tlarl  1,");                                       
+          assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));      
+          fprintf (file, "@GOTENT\n");                                        
+          fprintf (file, "\tlg    1,0(1)\n");                                 
+          fprintf (file, "\tbr    1\n");                                      
+          fprintf (file, "0:\t.long  ");                                     
+          fprintf (file, HOST_WIDE_INT_PRINT_DEC, (delta));                   
+          fprintf (file, "\n");                                                      
+        }                                                                     
+      else                                                                    
+        {                                                                     
+          fprintf (file, "\tlarl  1,0f\n");                                   
+          fprintf (file, "\tagf   %d,0(1)\n",                                 
+          aggregate_value_p (TREE_TYPE                                        
+                             (TREE_TYPE (function))) ? 3 :2 );                
+          fprintf (file, "\tjg  ");                                           
+          assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));      
+          fprintf (file, "\n");                                               
+          fprintf (file, "0:\t.long  ");                                     
+          fprintf (file, HOST_WIDE_INT_PRINT_DEC, (delta));                   
+          fprintf (file, "\n");                                                      
+        }                                                                     
+    }                                                                         
+  else                                                                        
+    {                                                                         
+      if (flag_pic)                                                           
+        {                                                                     
+          fprintf (file, "\tbras  1,0f\n");                                   
+          fprintf (file, "\t.long _GLOBAL_OFFSET_TABLE_-.\n");                
+          fprintf (file, "\t.long  ");                                        
+          assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));      
+          fprintf (file, "@GOT\n");                                           
+          fprintf (file, "\t.long  ");                                       
+          fprintf (file, HOST_WIDE_INT_PRINT_DEC, (delta));                   
+          fprintf (file, "\n");                                                      
+          fprintf (file, "0:\tal  %d,8(1)\n",                                 
+                   aggregate_value_p (TREE_TYPE                               
+                                      (TREE_TYPE (function))) ? 3 : 2 );      
+          fprintf (file, "\tl     0,4(1)\n");                                 
+          fprintf (file, "\tal    1,0(1)\n");                                 
+          fprintf (file, "\talr   1,0\n");                                    
+          fprintf (file, "\tl     1,0(1)\n");                                 
+          fprintf (file, "\tbr    1\n");                                      
+        } else {                                                              
+          fprintf (file, "\tbras  1,0f\n");                                   
+          fprintf (file, "\t.long  ");                                        
+          assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));      
+          fprintf (file, "-.\n");                                             
+          fprintf (file, "\t.long  ");                                       
+          fprintf (file, HOST_WIDE_INT_PRINT_DEC, (delta));                   
+          fprintf (file, "\n");                                                      
+          fprintf (file, "0:\tal  %d,4(1)\n",                                 
+                   aggregate_value_p (TREE_TYPE                               
+                                      (TREE_TYPE (function))) ? 3 : 2 );      
+          fprintf (file, "\tal    1,0(1)\n");                                 
+          fprintf (file, "\tbr    1\n");                                      
+       }                                                                      
+    }                                                                         
+}
index 7bc1e0a..e767aeb 100644 (file)
@@ -856,76 +856,7 @@ CUMULATIVE_ARGS;
 
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)              \
-do {                                                                          \
-  if (TARGET_64BIT)                                                           \
-    {                                                                         \
-      if (flag_pic)                                                           \
-        {                                                                     \
-          fprintf (FILE, "\tlarl  1,0f\n");                                   \
-          fprintf (FILE, "\tagf   %d,0(1)\n",                                 \
-                   aggregate_value_p (TREE_TYPE                               \
-                                      (TREE_TYPE (FUNCTION))) ? 3 :2 );       \
-          fprintf (FILE, "\tlarl  1,");                                       \
-          assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));      \
-          fprintf (FILE, "@GOTENT\n");                                        \
-          fprintf (FILE, "\tlg    1,0(1)\n");                                 \
-          fprintf (FILE, "\tbr    1\n");                                      \
-          fprintf (FILE, "0:\t.long  ");                                     \
-          fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA));                   \
-          fprintf (FILE, "\n");                                                      \
-        }                                                                     \
-      else                                                                    \
-        {                                                                     \
-          fprintf (FILE, "\tlarl  1,0f\n");                                   \
-          fprintf (FILE, "\tagf   %d,0(1)\n",                                 \
-          aggregate_value_p (TREE_TYPE                                        \
-                             (TREE_TYPE (FUNCTION))) ? 3 :2 );                \
-          fprintf (FILE, "\tjg  ");                                           \
-          assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));      \
-          fprintf (FILE, "\n");                                               \
-          fprintf (FILE, "0:\t.long  ");                                     \
-          fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA));                   \
-          fprintf (FILE, "\n");                                                      \
-        }                                                                     \
-    }                                                                         \
-  else                                                                        \
-    {                                                                         \
-      if (flag_pic)                                                           \
-        {                                                                     \
-          fprintf (FILE, "\tbras  1,0f\n");                                   \
-          fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_-.\n");                \
-          fprintf (FILE, "\t.long  ");                                        \
-          assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));      \
-          fprintf (FILE, "@GOT\n");                                           \
-          fprintf (FILE, "\t.long  ");                                       \
-          fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA));                   \
-          fprintf (FILE, "\n");                                                      \
-          fprintf (FILE, "0:\tal  %d,8(1)\n",                                 \
-                   aggregate_value_p (TREE_TYPE                               \
-                                      (TREE_TYPE (FUNCTION))) ? 3 : 2 );      \
-          fprintf (FILE, "\tl     0,4(1)\n");                                 \
-          fprintf (FILE, "\tal    1,0(1)\n");                                 \
-          fprintf (FILE, "\talr   1,0\n");                                    \
-          fprintf (FILE, "\tl     1,0(1)\n");                                 \
-          fprintf (FILE, "\tbr    1\n");                                      \
-        } else {                                                              \
-          fprintf (FILE, "\tbras  1,0f\n");                                   \
-          fprintf (FILE, "\t.long  ");                                        \
-          assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));      \
-          fprintf (FILE, "-.\n");                                             \
-          fprintf (FILE, "\t.long  ");                                       \
-          fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, (DELTA));                   \
-          fprintf (FILE, "\n");                                                      \
-          fprintf (FILE, "0:\tal  %d,4(1)\n",                                 \
-                   aggregate_value_p (TREE_TYPE                               \
-                                      (TREE_TYPE (FUNCTION))) ? 3 : 2 );      \
-          fprintf (FILE, "\tal    1,0(1)\n");                                 \
-          fprintf (FILE, "\tbr    1\n");                                      \
-       }                                                                      \
-    }                                                                         \
-} while (0)
-
+#define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
 
 /* Addressing modes, and classification of registers for them.  */
 
index b793fd7..8c3f70d 100644 (file)
@@ -2869,8 +2869,7 @@ do {                                                                      \
 
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-  sparc_output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
+#define TARGET_ASM_OUTPUT_MI_THUNK sparc_output_mi_thunk
 
 #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
   ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_')
index 147da5c..8034f89 100644 (file)
@@ -1624,8 +1624,7 @@ enum reg_class
    frontend will generate a less efficient heavyweight thunk that calls
    FUNCTION instead of jumping to it.  The generic approach does not support
    varargs.  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)       \
-  xstormy16_asm_output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
+#define TARGET_ASM_OUTPUT_MI_THUNK xstormy16_asm_output_mi_thunk
 
 \f
 /* Generating Code for Profiling.  */
index 059994f..928a2ab 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler.  VAX version.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -36,6 +36,7 @@ extern int check_float_value PARAMS ((enum machine_mode, REAL_VALUE_TYPE *, int)
 
 #ifdef TREE_CODE
 extern void vms_check_external PARAMS ((tree, const char *, int));
+extern void vax_output_mi_thunk PARAMS ((FILE *, tree, int, tree));
 #endif /* TREE_CODE */
 
 extern void vms_flush_pending_externals PARAMS ((FILE *));
index ba091dc..3571881 100644 (file)
@@ -992,3 +992,17 @@ reg_was_0_p (insn, op)
          /* Make sure the reg hasn't been clobbered.  */
          && ! reg_set_between_p (op, XEXP (link, 0), insn));
 }
+
+void
+vax_output_mi_thunk (file, thunk, delta, function)
+     FILE *file;
+     tree thunk ATTRIBUTE_UNUSED;
+     int delta;
+     tree function;
+{
+  fprintf (file, "\t.word 0x0ffc\n");                                  
+  asm_fprintf (file, "\taddl2 $%d,4(%Rap)\n", delta);                  
+  fprintf (file, "\tjmp ");                                            
+  assemble_name (file,  XSTR (XEXP (DECL_RTL (function), 0), 0));      
+  fprintf (file, "+2\n");                                              
+}
index 68d5fa3..4484486 100644 (file)
@@ -1161,14 +1161,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
        addl2   $DELTA, 4(ap)   #adjust first argument
        jmp     FUNCTION+2      #jump beyond FUNCTION's entry mask
  */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)       \
-do {                                                                   \
-  fprintf (FILE, "\t.word 0x0ffc\n");                                  \
-  asm_fprintf (FILE, "\taddl2 $%d,4(%Rap)\n", DELTA);                  \
-  fprintf (FILE, "\tjmp ");                                            \
-  assemble_name (FILE,  XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));      \
-  fprintf (FILE, "+2\n");                                              \
-} while (0)
+#define ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
 
 /* Print an instruction operand X on file FILE.
    CODE is the code from the %-spec that requested printing this operand;
index 9d5a5bc..8da7362 100644 (file)
@@ -1,5 +1,11 @@
 2002-10-18  Mark Mitchell  <mark@codesourcery.com>
 
+       * Make-lang.in (method.o): Depend on TARGET_H.
+       * method.c (target.h): Include it.
+       (use_thunk): Use target hooks.  Use vcall thunks, if available.
+
+2002-10-18  Mark Mitchell  <mark@codesourcery.com>
+
        * class.c (base_derived_from): Make sure return value is a bool.
 
 2002-10-18  Mark Mitchell  <mark@codesourcery.com>
index 0ec886d..42656e7 100644 (file)
@@ -246,7 +246,7 @@ cp/friend.o: cp/friend.c $(CXX_TREE_H) flags.h $(RTL_H) toplev.h $(EXPR_H)
 cp/init.o: cp/init.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
   $(GGC_H) except.h
 cp/method.o: cp/method.c $(CXX_TREE_H) toplev.h $(GGC_H) $(RTL_H) $(EXPR_H) \
-  $(TM_P_H)
+  $(TM_P_H) $(TARGET_H)
 cp/cvt.o: cp/cvt.c $(CXX_TREE_H) cp/decl.h flags.h toplev.h convert.h
 cp/search.o: cp/search.c $(CXX_TREE_H) stack.h flags.h toplev.h $(RTL_H)
 cp/tree.o: cp/tree.c $(CXX_TREE_H) flags.h toplev.h $(GGC_H) $(RTL_H) \
index 6f3e0e7..5d14f57 100644 (file)
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "ggc.h"
 #include "tm_p.h"
+#include "target.h"
 
 /* Various flags to control the mangling process.  */
 
@@ -408,8 +409,8 @@ use_thunk (thunk_fndecl, emit_p)
   BLOCK_VARS (DECL_INITIAL (thunk_fndecl)) 
     = DECL_ARGUMENTS (thunk_fndecl);
 
-#ifdef ASM_OUTPUT_MI_THUNK
-  if (!vcall_offset)
+  if (targetm.asm_out.output_mi_vcall_thunk
+      || (targetm.asm_out.output_mi_thunk && !vcall_offset))
     {
       const char *fnname;
       current_function_decl = thunk_fndecl;
@@ -419,18 +420,29 @@ use_thunk (thunk_fndecl, emit_p)
       init_function_start (thunk_fndecl, input_filename, lineno);
       current_function_is_thunk = 1;
       assemble_start_function (thunk_fndecl, fnname);
-      ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function);
+      if (targetm.asm_out.output_mi_vcall_thunk)
+       {
+         int vcall_value = (vcall_offset
+                            ? tree_low_cst (vcall_offset, /*pos=*/0)
+                            : 0);
+         targetm.asm_out.output_mi_vcall_thunk (asm_out_file, 
+                                                thunk_fndecl, delta, 
+                                                vcall_value,
+                                                function);
+       }
+      else
+       targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl, 
+                                        delta, function);
       assemble_end_function (thunk_fndecl, fnname);
       current_function_decl = 0;
       cfun = 0;
       TREE_ASM_WRITTEN (thunk_fndecl) = 1;
     }
   else
-#endif /* ASM_OUTPUT_MI_THUNK */
     {
-      /* If we don't have the necessary macro for efficient thunks, generate
-        a thunk function that just makes a call to the real function.
-        Unfortunately, this doesn't work for varargs.  */
+      /* If we don't have the necessary code for efficient thunks,
+        generate a thunk function that just makes a call to the real
+        function.  Unfortunately, this doesn't work for varargs.  */
 
       tree a, t;
 
index c2dfd39..74231e2 100644 (file)
@@ -4151,9 +4151,11 @@ outputting the insns in this list, usually by calling
 You need not define this macro if you did not define
 @code{DELAY_SLOTS_FOR_EPILOGUE}.
 
-@findex ASM_OUTPUT_MI_THUNK
-@item ASM_OUTPUT_MI_THUNK (@var{file}, @var{thunk_fndecl}, @var{delta}, @var{function})
-A C compound statement that outputs the assembler code for a thunk
+@end table
+
+@findex TARGET_ASM_OUTPUT_MI_THUNK
+@deftypefn {Target Hook} void TARGET_ASM_OUTPUT_MI_THUNK (FILE *@var{file}, tree @var{thunk_fndecl}, int @var{delta}, tree @var{function})
+A function that outputs the assembler code for a thunk
 function, used to implement C++ virtual function calls with multiple
 inheritance.  The thunk acts as a wrapper around a virtual function,
 adjusting the implicit object parameter before handing control off to
@@ -4184,7 +4186,24 @@ If you do not define this macro, the target-independent code in the C++
 front end will generate a less efficient heavyweight thunk that calls
 @var{function} instead of jumping to it.  The generic approach does
 not support varargs.
-@end table
+@end deftypefn
+
+@findex TARGET_ASM_OUTPUT_MI_VCALL_THUNK
+@deftypefn {Target Hook} void TARGET_ASM_OUTPUT_MI_VCALL_THUNK (FILE *@var{file}, tree @var{thunk_fndecl}, int @var{delta}, int @var{vcall_offset}, tree @var{function})
+A function like @code{TARGET_ASM_OUTPUT_MI_THUNK}, except that if
+@var{vcall_offset} is non-zero, an additional adjustment should be made
+after adding @code{delta}.  In particular, if @var{p} is the
+adjusted pointer, the following adjustment should be made:
+
+@example
+p += (*((ptrdiff_t **)p))[vcall_offset/sizeof(ptrdiff_t)]
+@end example
+
+@noindent
+If this function is defined, it will always be used in place of
+@code{TARGET_ASM_OUTPUT_MI_THUNK}.
+
+@end deftypefn
 
 @node Profiling
 @subsection Generating Code for Profiling
index fbb75f0..b5a0345 100644 (file)
@@ -103,6 +103,14 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 # endif
 #endif
 
+#ifndef TARGET_ASM_OUTPUT_MI_THUNK
+#define TARGET_ASM_OUTPUT_MI_THUNK NULL
+#endif
+
+#ifndef TARGET_ASM_OUTPUT_MI_VCALL_THUNK
+#define TARGET_ASM_OUTPUT_MI_VCALL_THUNK NULL
+#endif
+
 #if defined(TARGET_ASM_CONSTRUCTOR) && defined(TARGET_ASM_DESTRUCTOR)
 #define TARGET_HAVE_CTORS_DTORS true
 #else
@@ -173,7 +181,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
                        TARGET_ASM_SELECT_RTX_SECTION,          \
                        TARGET_ASM_UNIQUE_SECTION,              \
                        TARGET_ASM_CONSTRUCTOR,                 \
-                       TARGET_ASM_DESTRUCTOR}
+                       TARGET_ASM_DESTRUCTOR,                  \
+                        TARGET_ASM_OUTPUT_MI_THUNK,             \
+                        TARGET_ASM_OUTPUT_MI_VCALL_THUNK }
 
 /* Scheduler hooks.  All of these default to null pointers, which
    haifa-sched.c looks for and handles.  */
index 130f387..b05a87d 100644 (file)
@@ -119,6 +119,13 @@ struct gcc_target
 
     /* Output a destructor for a symbol with a given priority.  */
     void (* destructor) PARAMS ((rtx, int));
+
+    /* Output the assembler code for a thunk function.  */
+    void (* output_mi_thunk) PARAMS ((FILE *, tree, int, tree));
+
+    /* Output the assembler code for a thunk function with a vcall
+       offset.  */
+    void (* output_mi_vcall_thunk) PARAMS ((FILE *, tree, int, int, tree));
   } asm_out;
 
   /* Functions relating to instruction scheduling.  */
diff --git a/gcc/testsuite/g++.dg/inherit/thunk1.C b/gcc/testsuite/g++.dg/inherit/thunk1.C
new file mode 100644 (file)
index 0000000..f393197
--- /dev/null
@@ -0,0 +1,41 @@
+// { dg-do run }
+
+#include <stdarg.h>
+
+extern "C" void abort ();
+
+struct A {
+  virtual void f (int, ...) {}
+  int i;
+};
+
+struct B : virtual public A {
+};
+
+struct C : public B {
+  C ();
+  virtual void f (int, ...);
+};
+
+extern C* cp;
+
+C::C () { cp = this; }
+
+void C::f (int i, ...) {
+  if (this != cp)
+    abort ();
+  va_list ap;
+  if (i != 3)
+    abort ();
+  va_start (ap, i);
+  if (va_arg (ap, int) != 7)
+    abort ();
+  va_end (ap);
+}
+
+C* cp = new C;
+
+int main () 
+{
+  cp->f (3, 7);
+}