]> gcc.gnu.org Git - gcc.git/commitdiff
sparc.c (sparc_output_mi_thunk): New implementation using rtl instead of fprintf.
authorRichard Henderson <rth@redhat.com>
Sun, 26 May 2002 02:03:35 +0000 (19:03 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 26 May 2002 02:03:35 +0000 (19:03 -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.

From-SVN: r53880

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

index 9849c73315aa9c5bcc23b870fcfdaa22f04af4c4..e76b87f6f0315349519d514b3f057150c8a65e22 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  Neil Booth  <neil@daikokuya.demon.co.uk>
 
        * Makefile.in (C_COMMON_H): Fix.
index 427aaba18640bd4108df1e77c60549b57c480179..c759631d60cb4092660c4b1184da6e8ba9364963 100644 (file)
@@ -124,4 +124,6 @@ extern int sparc_extra_constraint_check PARAMS ((rtx, int, int));
 extern int sparc_rtx_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
 #endif /* RTX_CODE */
 
+extern void sparc_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
+
 #endif /* __SPARC_PROTOS_H__ */
index fd1cd65d424e952107c9b10e4763d922f9e6bd9a..acc04d2e8676f25d23f528a1f9353c41df7a4df9 100644 (file)
@@ -8474,3 +8474,70 @@ sparc_encode_section_info (decl, first)
   if (TARGET_CM_EMBMEDANY && TREE_CODE (decl) == FUNCTION_DECL)
     SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
 }
+
+/* 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 8af36e3551c4821869291a231dfb0c94e7de39a7..12490d38a4232cea59e1838823a2c7066b169a93 100644 (file)
@@ -2874,24 +2874,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) == '_')
This page took 0.082041 seconds and 5 git commands to generate.