From: Richard Henderson Date: Sun, 26 May 2002 02:03:35 +0000 (-0700) Subject: sparc.c (sparc_output_mi_thunk): New implementation using rtl instead of fprintf. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e133041bb61c6304eea47dca57fe48c3bd387ab8;p=gcc.git sparc.c (sparc_output_mi_thunk): New implementation using rtl instead of fprintf. * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9849c73315a..e76b87f6f03 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2002-05-25 Richard Henderson + + 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 * Makefile.in (C_COMMON_H): Fix. diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 427aaba1864..c759631d60c 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -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__ */ diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index fd1cd65d424..acc04d2e867 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -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; +} diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 8af36e3551c..12490d38a42 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -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) == '_')