]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
sparc.c (sparc_output_mi_thunk): New implementation using rtl instead of fprintf.
authorRichard Henderson <rth@gcc.gnu.org>
Sun, 26 May 2002 02:42:21 +0000 (19:42 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 26 May 2002 02:42:21 +0000 (19:42 -0700)
        * config/sparc/sparc.c (sparc_output_mi_thunk): New implementation
        using rtl instead of fprintf.
        * config/sparc/sparc.h (ASM_OUTPUT_MI_THUNK): Use it.
        * config/sparc/sparc-protos.h: Update.
* g++.dg/opt/thunk1.C: New.

From-SVN: r53883

gcc/ChangeLog
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h

index 0a877a4db4cda8d92025864d3e5a21411482adc9..8531a6bd706eba3c0ee87adc4b5433df70fd3e39 100644 (file)
@@ -1,3 +1,11 @@
+2002-05-25  Richard Henderson  <rth@redhat.com>
+
+       PR target/6788
+       * config/sparc/sparc.c (sparc_output_mi_thunk): New implementation
+       using rtl instead of fprintf.
+       * config/sparc/sparc.h (ASM_OUTPUT_MI_THUNK): Use it.
+       * config/sparc/sparc-protos.h: Update.
+
 2002-05-25  Marek Michalkiewicz  <marekm@amelek.gda.pl>
 
        * config/avr/avr.c (avr_handle_progmem_attribute): Handle TYPE_DECL.
@@ -7,8 +15,8 @@
 
 2002-05-24  Roman Lechtchinsky  <rl@cs.tu-berlin.de>
 
-        * config/alpha/unicosmk.h (REAL_VALUE_TO_TARGET_SINGLE,
-        REAL_VALUE_TO_TARGET_DOUBLE): Define for native builds.
+       * config/alpha/unicosmk.h (REAL_VALUE_TO_TARGET_SINGLE,
+       REAL_VALUE_TO_TARGET_DOUBLE): Define for native builds.
 
 2002-05-24  Jakub Jelinek  <jakub@redhat.com>
 
@@ -184,7 +192,7 @@ Sat May 18 23:09:19 CEST 2002  Jan Hubicka  <jh@suse.cz>
 
 2002-05-18  Aldy Hernandez  <aldyh@redhat.com>
 
-        * config/rs6000/altivec.h: Cleanups.
+       * config/rs6000/altivec.h: Cleanups.
 
 2002-05-17  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 
@@ -214,7 +222,7 @@ Sat May 18 23:09:19 CEST 2002  Jan Hubicka  <jh@suse.cz>
 
        * config/ia64/sysv4.h (DO_SELECT_SECTION): Factored out of
        SELECT_SECTION.
-        (UNIQUE_SECTION): Define to get small data correctly.
+       (UNIQUE_SECTION): Define to get small data correctly.
 
        * varasm.c (resolve_unique_section): Add third parameter
        flag_function_or_data_sections and use it instead of
index fd372ded33cae4440b6068b7fee64d4987631bf6..7de8940c08ccd4affb9f8e81cedbb2f31e019653 100644 (file)
@@ -123,4 +123,6 @@ extern rtx gen_df_reg PARAMS ((rtx, int));
 extern int sparc_extra_constraint_check PARAMS ((rtx, int, int));
 #endif /* RTX_CODE */
 
+extern void sparc_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
+
 #endif /* __SPARC_PROTOS_H__ */
index 91c64aedf9889707c5abda59f7da054b0985c9bd..6ef28141ce4043e5030c0bd4a2dbe733d7a1731b 100644 (file)
@@ -9001,3 +9001,70 @@ sparc_extra_constraint_check (op, c, strict)
 
   return reload_ok_mem;
 }
+
+/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
+   Used for C++ multiple inheritance.  */
+
+void
+sparc_output_mi_thunk (file, thunk_fndecl, delta, function)
+     FILE *file;
+     tree thunk_fndecl ATTRIBUTE_UNUSED;
+     HOST_WIDE_INT delta;
+     tree function;
+{
+  rtx this, insn, funexp, delta_rtx, tmp;
+
+  reload_completed = 1;
+  no_new_pseudos = 1;
+  current_function_uses_only_leaf_regs = 1;
+
+  emit_note (NULL, NOTE_INSN_PROLOGUE_END);
+
+  /* Find the "this" pointer.  Normally in %o0, but in ARCH64 if the function
+     returns a structure, the structure return pointer is there instead.  */
+  if (TARGET_ARCH64 && aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
+    this = gen_rtx_REG (Pmode, SPARC_INCOMING_INT_ARG_FIRST + 1);
+  else
+    this = gen_rtx_REG (Pmode, SPARC_INCOMING_INT_ARG_FIRST);
+
+  /* Add DELTA.  When possible use a plain add, otherwise load it into
+     a register first.  */
+  delta_rtx = GEN_INT (delta);
+  if (!SPARC_SIMM13_P (delta))
+    {
+      rtx scratch = gen_rtx_REG (Pmode, 1);
+      if (TARGET_ARCH64)
+       sparc_emit_set_const64 (scratch, delta_rtx);
+      else
+       sparc_emit_set_const32 (scratch, delta_rtx);
+      delta_rtx = scratch;
+    }
+
+  tmp = gen_rtx_PLUS (Pmode, this, delta_rtx);
+  emit_insn (gen_rtx_SET (VOIDmode, 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);
+  insn = emit_call_insn (gen_sibcall (funexp));
+  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 ();
+  shorten_branches (insn);
+  final_start_function (insn, file, 1);
+  final (insn, file, 1, 0);
+  final_end_function ();
+
+  reload_completed = 0;
+  no_new_pseudos = 0;
+}
index 8ff5d719382d5ea2fbb46d5e77a30d0ac75e614f..7821537ccce5228807a5d2056f55259dc4e3dff0 100644 (file)
@@ -2908,24 +2908,8 @@ 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)       \
-do {                                                                   \
-  int reg = 0;                                                         \
-                                                                       \
-  if (TARGET_ARCH64                                                    \
-      && aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))))         \
-    reg = 1;                                                           \
-  if ((DELTA) >= 4096 || (DELTA) < -4096)                              \
-    fprintf (FILE, "\tset\t%d, %%g1\n\tadd\t%%o%d, %%g1, %%o%d\n",     \
-            (int)(DELTA), reg, reg);                                   \
-  else                                                                 \
-    fprintf (FILE, "\tadd\t%%o%d, %d, %%o%d\n", reg, (int)(DELTA), reg);\
-  fprintf (FILE, "\tor\t%%o7, %%g0, %%g1\n");                          \
-  fprintf (FILE, "\tcall\t");                                          \
-  assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0));       \
-  fprintf (FILE, ", 0\n");                                             \
-  fprintf (FILE, "\t or\t%%g1, %%g0, %%o7\n");                         \
-} while (0)
+#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
+  sparc_output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
 
 #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
   ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_')