diff options
author | David Daney <ddaney@caviumnetworks.com> | 2009-10-29 17:39:52 +0000 |
---|---|---|
committer | David Daney <daney@gcc.gnu.org> | 2009-10-29 17:39:52 +0000 |
commit | c376dbfba163068f1caeb1b7749bb74366a5efad (patch) | |
tree | 60e94e291058dd033915cf8b9ec971575d6b5cae /gcc/config/mips/mips.c | |
parent | 2b7e2984ce29a528a8a280191947742a19624b0b (diff) | |
download | gcc-c376dbfba163068f1caeb1b7749bb74366a5efad.zip gcc-c376dbfba163068f1caeb1b7749bb74366a5efad.tar.gz gcc-c376dbfba163068f1caeb1b7749bb74366a5efad.tar.bz2 |
invoke.texi (mmcount-ra-address): Document new command line option.
2009-10-29 David Daney <ddaney@caviumnetworks.com>
* doc/invoke.texi (mmcount-ra-address): Document new command line
option.
* config/mips/mips.opt (mmcount-ra-address): 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.
2009-10-29 David Daney <ddaney@caviumnetworks.com>
* gcc.target/mips/mips.exp (mips_option_groups): Add
mcount-ra-address.
* gcc.target/mips/mmcount-ra-address-1.c: New test.
* gcc.target/mips/mmcount-ra-address-2.c: New test.
* gcc.target/mips/mmcount-ra-address-3.c: New test.
From-SVN: r153717
Diffstat (limited to 'gcc/config/mips/mips.c')
-rw-r--r-- | gcc/config/mips/mips.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 6af8d03..c8c1dca 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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; @@ -9666,6 +9669,9 @@ mips_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset, 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; } @@ -16138,6 +16144,59 @@ mips_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) 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_RA_ADDRESS) + { + /* If TARGET_MCOUNT_RA_ADDRESS 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\n", reg_names[12], reg_names[0]); + else + fprintf (file, "\t%s\t%s," HOST_WIDE_INT_PRINT_DEC "(%s)\n", + Pmode == DImode ? "dla" : "la", reg_names[12], + cfun->machine->frame.ra_fp_offset, + 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 |