From: Richard Henderson Date: Sun, 26 May 2002 02:42:21 +0000 (-0700) Subject: sparc.c (sparc_output_mi_thunk): New implementation using rtl instead of fprintf. X-Git-Tag: releases/gcc-3.1.1~266 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bdd85dbdd738b9d68416c0d2d43d42e7d1a2eba3;p=thirdparty%2Fgcc.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. * g++.dg/opt/thunk1.C: New. From-SVN: r53883 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a877a4db4cd..8531a6bd706e 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 Marek Michalkiewicz * config/avr/avr.c (avr_handle_progmem_attribute): Handle TYPE_DECL. @@ -7,8 +15,8 @@ 2002-05-24 Roman Lechtchinsky - * 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 @@ -184,7 +192,7 @@ Sat May 18 23:09:19 CEST 2002 Jan Hubicka 2002-05-18 Aldy Hernandez - * config/rs6000/altivec.h: Cleanups. + * config/rs6000/altivec.h: Cleanups. 2002-05-17 Rainer Orth @@ -214,7 +222,7 @@ Sat May 18 23:09:19 CEST 2002 Jan Hubicka * 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 diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index fd372ded33ca..7de8940c08cc 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -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__ */ diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 91c64aedf988..6ef28141ce40 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -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; +} diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 8ff5d719382d..7821537ccce5 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -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) == '_')