+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.
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>
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>
* 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
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__ */
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;
+}
/* 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) == '_')