Hi, [...] > > > > Looks good otherwise, but I'd be interested in other suggestions for > > the option name. I kept misreading "raloc" as a typo for "reloc". > > Well how about raaddr? (Return-Address Address) > > Still not tested, but how about this version instead? > I will help to test it later(but maybe tomorrow to later), I think this will can not pass the compiling, have tried it with the 4.4-200903..., some of the macros are not defined, such as RETURN_ADDR_REGNUM(not sure in the latest version of gcc). Regards, Wu Zhangjin > gcc/ > 2009-10-26 David Daney <ddaney@xxxxxxxxxxxxxxxxxx> > > * doc/invoke.texi (mmcount-raaddr): Document new command line > option. > * config/mips/mips.opt (mmcount-raaddr): New option. > * config/mips/mips-protos.h (mips_function_profiler): Declare new > function. > * config/mips/mips.c (struct mips_frame_info): Add ra_fp_offset > member. > (mips_for_each_saved_gpr_and_fpr): Set ra_fp_offset. > (mips_function_profiler): Moved from FUNCTION_PROFILER, and > rewritten. > * config/mips/mips.h (FUNCTION_PROFILER): Body of macro moved to > mips_function_profiler. > > gcc/testsuite/ > 2009-10-26 David Daney <ddaney@xxxxxxxxxxxxxxxxxx> > > * gcc.target/mips/mips.exp (mips_option_groups): Add > mcount-raaddr. > * gcc.target/mips/mmcount-raaddr-1.c: New test. > * gcc.target/mips/mmcount-raaddr-2.c: New test. > * gcc.target/mips/mmcount-raaddr-3.c: New test. > > plain text document attachment (mcount.patch) > Index: gcc/doc/invoke.texi > =================================================================== > --- gcc/doc/invoke.texi (revision 153502) > +++ gcc/doc/invoke.texi (working copy) > @@ -709,7 +709,7 @@ Objective-C and Objective-C++ Dialects}. > -mbranch-cost=@var{num} -mbranch-likely -mno-branch-likely @gol > -mfp-exceptions -mno-fp-exceptions @gol > -mvr4130-align -mno-vr4130-align -msynci -mno-synci @gol > --mrelax-pic-calls -mno-relax-pic-calls} > +-mrelax-pic-calls -mno-relax-pic-calls -mmcount-raaddr} > > @emph{MMIX Options} > @gccoptlist{-mlibfuncs -mno-libfuncs -mepsilon -mno-epsilon -mabi=gnu @gol > @@ -14192,6 +14192,19 @@ an assembler and a linker that supports > directive and @code{-mexplicit-relocs} is in effect. With > @code{-mno-explicit-relocs}, this optimization can be performed by the > assembler and the linker alone without help from the compiler. > + > +@item -mmcount-raaddr > +@itemx -mno-mcount-raaddr > +@opindex mmcount-raaddr > +@opindex mno-mcount-raaddr > +Emit (do not emit) code to pass the address of the return address save > +location to @code{_mcount}. The default is @option{-mno-mcount-raaddr}. > + > +@option{-mmcount-raaddr} can be used in conjunction with @option{-pg} > +and a specially coded @code{_mcount} function to record function exit > +by replacing the saved return address with a pointer to the function > +exit profiling function. > + > @end table > > @node MMIX Options > Index: gcc/testsuite/gcc.target/mips/mips.exp > =================================================================== > --- gcc/testsuite/gcc.target/mips/mips.exp (revision 153502) > +++ gcc/testsuite/gcc.target/mips/mips.exp (working copy) > @@ -263,6 +263,7 @@ foreach option { > sym32 > synci > relax-pic-calls > + mcount-raaddr > } { > lappend mips_option_groups $option "-m(no-|)$option" > } > Index: gcc/testsuite/gcc.target/mips/mmcount-raaddr-1.c > =================================================================== > --- gcc/testsuite/gcc.target/mips/mmcount-raaddr-1.c (revision 0) > +++ gcc/testsuite/gcc.target/mips/mmcount-raaddr-1.c (revision 0) > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -pg -mmcount-raaddr -march=mips64 -mabi=64 -mno-abicalls -msym32" } */ > +/* { dg-final { scan-assembler "\tmove\t\\\$12,\\\$0" } } */ > +int bazl(int i) > +{ > + return i + 2; > +} > Index: gcc/testsuite/gcc.target/mips/mmcount-raaddr-2.c > =================================================================== > --- gcc/testsuite/gcc.target/mips/mmcount-raaddr-2.c (revision 0) > +++ gcc/testsuite/gcc.target/mips/mmcount-raaddr-2.c (revision 0) > @@ -0,0 +1,8 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -pg -mmcount-raaddr -march=mips64 -mabi=64 -mno-abicalls -msym32" } */ > +/* { dg-final { scan-assembler "\tdaddiu\t\\\$12,\\\$sp,8" } } */ > +int foo (int); > +int bar (int i) > +{ > + return foo (i) + 2; > +} > Index: gcc/testsuite/gcc.target/mips/mmcount-raaddr-3.c > =================================================================== > --- gcc/testsuite/gcc.target/mips/mmcount-raaddr-3.c (revision 0) > +++ gcc/testsuite/gcc.target/mips/mmcount-raaddr-3.c (revision 0) > @@ -0,0 +1,10 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -pg -mmcount-raaddr -march=mips64 -mabi=64 -mno-abicalls -msym32" } */ > +/* { dg-final { scan-assembler "\tdli\t\\\$12,200008" } } */ > +/* { dg-final { scan-assembler "\tdaddu\t\\\$12,\\\$12,\\\$sp" } } */ > +int foo (int *); > +int bar(int i) > +{ > + int big[50000]; > + return foo (big) + 2; > +} > Index: gcc/config/mips/mips.opt > =================================================================== > --- gcc/config/mips/mips.opt (revision 153502) > +++ gcc/config/mips/mips.opt (working copy) > @@ -208,6 +208,10 @@ mlong64 > Target Report RejectNegative Mask(LONG64) > Use a 64-bit long type > > +mmcount-raaddr > +Target Report Var(TARGET_MCOUNT_RAADDR) > +Pass the address of the ra save location to _mcount in $12 > + > mmemcpy > Target Report Mask(MEMCPY) > Don't optimize block moves > Index: gcc/config/mips/mips-protos.h > =================================================================== > --- gcc/config/mips/mips-protos.h (revision 153502) > +++ gcc/config/mips/mips-protos.h (working copy) > @@ -344,5 +344,6 @@ extern bool mips_eh_uses (unsigned int); > extern bool mips_epilogue_uses (unsigned int); > extern void mips_final_prescan_insn (rtx, rtx *, int); > extern int mips_trampoline_code_size (void); > +extern void mips_function_profiler (FILE *); > > #endif /* ! GCC_MIPS_PROTOS_H */ > Index: gcc/config/mips/mips.c > =================================================================== > --- gcc/config/mips/mips.c (revision 153502) > +++ gcc/config/mips/mips.c (working copy) > @@ -319,6 +319,9 @@ struct GTY(()) mips_frame_info { > HOST_WIDE_INT acc_sp_offset; > HOST_WIDE_INT cop0_sp_offset; > > + /* Similar, but the value passed to _mcount. */ > + HOST_WIDE_INT ra_fp_offset; > + > /* The offset of arg_pointer_rtx from the bottom of the frame. */ > HOST_WIDE_INT arg_pointer_offset; > > @@ -9616,6 +9619,9 @@ mips_for_each_saved_gpr_and_fpr (HOST_WI > for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--) > if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) > { > + /* Record the ra offset for use by mips_function_profiler. */ > + if (regno == RETURN_ADDR_REGNUM) > + cfun->machine->frame.ra_fp_offset = offset + sp_offset; > mips_save_restore_reg (word_mode, regno, offset, fn); > offset -= UNITS_PER_WORD; > } > @@ -16088,6 +16094,74 @@ mips_trampoline_init (rtx m_tramp, tree > emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE))); > emit_insn (gen_clear_cache (addr, end_addr)); > } > + > +/* Implement FUNCTION_PROFILER. */ > + > +void mips_function_profiler (FILE *file) > +{ > + if (TARGET_MIPS16) > + sorry ("mips16 function profiling"); > + if (TARGET_LONG_CALLS) > + { > + /* For TARGET_LONG_CALLS use $3 for the address of _mcount. */ > + if (Pmode == DImode) > + fprintf (file, "\tdla\t%s,_mcount\n", reg_names[3]); > + else > + fprintf (file, "\tla\t%s,_mcount\n", reg_names[3]); > + } > + mips_push_asm_switch (&mips_noat); > + fprintf (file, "\tmove\t%s,%s\t\t# save current return address\n", > + reg_names[AT_REGNUM], reg_names[RETURN_ADDR_REGNUM]); > + /* _mcount treats $2 as the static chain register. */ > + if (cfun->static_chain_decl != NULL) > + fprintf (file, "\tmove\t%s,%s\n", reg_names[2], > + reg_names[STATIC_CHAIN_REGNUM]); > + if (TARGET_MCOUNT_RAADDR) > + { > + /* If TARGET_MCOUNT_RAADDR load $12 with the address of the ra save > + location. */ > + if (cfun->machine->frame.ra_fp_offset == 0) > + /* ra not saved, pass zero. */ > + fprintf (file, "\tmove\t%s,%s\t\t# address of ra\n", > + reg_names[12], reg_names[0]); > + else if (SMALL_OPERAND (cfun->machine->frame.ra_fp_offset)) > + fprintf (file, > + "\t%s\t%s,%s," HOST_WIDE_INT_PRINT_DEC "\t\t# address of ra\n", > + Pmode == DImode ? "daddiu" : "addiu", > + reg_names[12], reg_names[STACK_POINTER_REGNUM], > + cfun->machine->frame.ra_fp_offset); > + else > + { > + fprintf (file, > + "\t%s\t%s," HOST_WIDE_INT_PRINT_DEC "\n", > + Pmode == DImode ? "dli" : "li", > + reg_names[12], > + cfun->machine->frame.ra_fp_offset); > + fprintf (file, "\t%s\t%s,%s,%s\t\t# address of ra\n", > + Pmode == DImode ? "daddu" : "addu", > + reg_names[12], reg_names[12], > + reg_names[STACK_POINTER_REGNUM]); > + } > + } > + if (!TARGET_NEWABI) > + { > + fprintf (file, > + "\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from stack\n", > + TARGET_64BIT ? "dsubu" : "subu", > + reg_names[STACK_POINTER_REGNUM], > + reg_names[STACK_POINTER_REGNUM], > + Pmode == DImode ? 16 : 8); > + } > + if (TARGET_LONG_CALLS) > + fprintf (file, "\tjalr\t%s\n", reg_names[3]); > + else > + fprintf (file, "\tjal\t_mcount\n"); > + mips_pop_asm_switch (&mips_noat); > + /* _mcount treats $2 as the static chain register. */ > + if (cfun->static_chain_decl != NULL) > + fprintf (file, "\tmove\t%s,%s\n", reg_names[STATIC_CHAIN_REGNUM], > + reg_names[2]); > +} > > /* Initialize the GCC target structure. */ > #undef TARGET_ASM_ALIGNED_HI_OP > Index: gcc/config/mips/mips.h > =================================================================== > --- gcc/config/mips/mips.h (revision 153502) > +++ gcc/config/mips/mips.h (working copy) > @@ -2372,44 +2372,7 @@ typedef struct mips_args { > /* Output assembler code to FILE to increment profiler label # LABELNO > for profiling a function entry. */ > > -#define FUNCTION_PROFILER(FILE, LABELNO) \ > -{ \ > - if (TARGET_MIPS16) \ > - sorry ("mips16 function profiling"); \ > - if (TARGET_LONG_CALLS) \ > - { \ > - /* For TARGET_LONG_CALLS use $3 for the address of _mcount. */ \ > - if (Pmode == DImode) \ > - fprintf (FILE, "\tdla\t%s,_mcount\n", reg_names[GP_REG_FIRST + 3]); \ > - else \ > - fprintf (FILE, "\tla\t%s,_mcount\n", reg_names[GP_REG_FIRST + 3]); \ > - } \ > - mips_push_asm_switch (&mips_noat); \ > - fprintf (FILE, "\tmove\t%s,%s\t\t# save current return address\n", \ > - reg_names[AT_REGNUM], reg_names[RETURN_ADDR_REGNUM]); \ > - /* _mcount treats $2 as the static chain register. */ \ > - if (cfun->static_chain_decl != NULL) \ > - fprintf (FILE, "\tmove\t%s,%s\n", reg_names[2], \ > - reg_names[STATIC_CHAIN_REGNUM]); \ > - if (!TARGET_NEWABI) \ > - { \ > - fprintf (FILE, \ > - "\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from stack\n", \ > - TARGET_64BIT ? "dsubu" : "subu", \ > - reg_names[STACK_POINTER_REGNUM], \ > - reg_names[STACK_POINTER_REGNUM], \ > - Pmode == DImode ? 16 : 8); \ > - } \ > - if (TARGET_LONG_CALLS) \ > - fprintf (FILE, "\tjalr\t%s\n", reg_names[GP_REG_FIRST + 3]); \ > - else \ > - fprintf (FILE, "\tjal\t_mcount\n"); \ > - mips_pop_asm_switch (&mips_noat); \ > - /* _mcount treats $2 as the static chain register. */ \ > - if (cfun->static_chain_decl != NULL) \ > - fprintf (FILE, "\tmove\t%s,%s\n", reg_names[STATIC_CHAIN_REGNUM], \ > - reg_names[2]); \ > -} > +#define FUNCTION_PROFILER(FILE, LABELNO) mips_function_profiler ((FILE)) > > /* The profiler preserves all interesting registers, including $31. */ > #define MIPS_SAVE_REG_FOR_PROFILING_P(REGNO) false