public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
  • [parent not found: <96110ea5dd4d3d54eb97d0bb708a5bd81c7a50b5.1256135456.git.wuzhangjin@gmail.com>]
  • * [PATCH] MIPS: Add option to pass return address location to _mcount
    @ 2009-10-29  9:04 Wu Zhangjin
      2009-10-29 16:33 ` David Daney
      0 siblings, 1 reply; 18+ messages in thread
    From: Wu Zhangjin @ 2009-10-29  9:04 UTC (permalink / raw)
      To: Richard Sandiford, David Daney, GCC Patches
      Cc: linux-mips, Adam Nemet, rostedt, Ralf Baechle, Nicholas Mc Guire,
    	Wu Zhangjin, David Daney
    
    From: Wu Zhangjin <wuzhangjin@gmail.com>
    
    When we pass -pg -mmcount-ra-address, the address of the return address
    relative to sp is passed in $12 to _mcount.  If the return address is not
    saved, $12 will be zero. this will work as registers are never saved with an
    offset of zero.  $12 is a temporary register that is not part of the ABI.
    
    $12 is also used by libffi closure support, but its use there will not
    interfere with _mcount.
    
    2009-10-23  David Daney  <ddaney@caviumnetworks.com>
    
            * doc/invoke.texi (mmcount-ra-address): Document new command line option.
            * config/mips/mips.opt (config/mips/mips.opt): 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.
    
    Tested-by: Wu Zhangjin <wuzhangjin@gmail.com>
    Signed-off-by: David Daney <ddaney@caviumnetworks.com>
    ---
     gcc/config/mips/mips-protos.h                      |    1 +
     gcc/config/mips/mips.c                             |   67 +++++++++++++++++++-
     gcc/config/mips/mips.h                             |   39 +-----------
     gcc/config/mips/mips.opt                           |    4 +
     gcc/doc/invoke.texi                                |   22 ++++++-
     gcc/testsuite/gcc.target/mips/mips.exp             |    1 +
     .../gcc.target/mips/mmcount-ra-address-1.c         |    7 ++
     .../gcc.target/mips/mmcount-ra-address-2.c         |    8 +++
     .../gcc.target/mips/mmcount-ra-address-3.c         |   10 +++
     9 files changed, 119 insertions(+), 40 deletions(-)
     create mode 100644 gcc/testsuite/gcc.target/mips/mmcount-ra-address-1.c
     create mode 100644 gcc/testsuite/gcc.target/mips/mmcount-ra-address-2.c
     create mode 100644 gcc/testsuite/gcc.target/mips/mmcount-ra-address-3.c
    
    diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
    index 429a621..716b7ac 100644
    --- a/gcc/config/mips/mips-protos.h
    +++ b/gcc/config/mips/mips-protos.h
    @@ -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 */
    diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
    index f82091a..a1229be 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;
     
    @@ -9619,6 +9622,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 (crtl->profile && 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;
           }
    @@ -16091,7 +16097,66 @@ 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));
     }
    -\f
    +
    +/* 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 if (SMALL_OPERAND (cfun->machine->frame.ra_fp_offset))
    +	fprintf (file,
    +		 "\t%s\t%s,%s," HOST_WIDE_INT_PRINT_DEC "\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 "(%s)",
    +                 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
     #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
    diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
    index 50bc4ea..2829708 100644
    --- a/gcc/config/mips/mips.h
    +++ b/gcc/config/mips/mips.h
    @@ -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
    diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
    index 8462e46..188d5e1 100644
    --- a/gcc/config/mips/mips.opt
    +++ b/gcc/config/mips/mips.opt
    @@ -208,6 +208,10 @@ mlong64
     Target Report RejectNegative Mask(LONG64)
     Use a 64-bit long type
     
    +mmcount-ra-address
    +Target Report Var(TARGET_MCOUNT_RA_ADDRESS)
    +Pass the address of the ra save location to _mcount in $12
    +
     mmemcpy
     Target Report Mask(MEMCPY)
     Don't optimize block moves
    diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
    index 4a9ffbf..0e1490e 100644
    --- a/gcc/doc/invoke.texi
    +++ b/gcc/doc/invoke.texi
    @@ -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-ra-address}
     
     @emph{MMIX Options}
     @gccoptlist{-mlibfuncs  -mno-libfuncs  -mepsilon  -mno-epsilon  -mabi=gnu @gol
    @@ -14207,6 +14207,26 @@ an assembler and a linker that supports the @code{.reloc} assembly
     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-ra-address
    +@itemx -mno-mcount-ra-address
    +@opindex mmcount-ra-address
    +@opindex mno-mcount-ra-address
    +Allow (do not allow) @code{_mcount} to modify the calling function's
    +return address.  When enabled, this option extends the usual @code{_mcount}
    +interface with a new @var{ra-address} parameter, which has type
    +@code{intptr_t *} and is passed in register @code{$12}.  @code{_mcount}
    +can then modify the return address by doing both of the following:
    +@itemize
    +@item
    +Returning the new address in register @code{$31}.
    +@item
    +Storing the new address in @code{*@var{ra-address}},
    +if @var{ra-address} is nonnull.
    +@end itemize
    +
    +The default is @option{-mno-mcount-ra-address}.
    +
     @end table
     
     @node MMIX Options
    diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
    index aef473f..02e031c 100644
    --- a/gcc/testsuite/gcc.target/mips/mips.exp
    +++ b/gcc/testsuite/gcc.target/mips/mips.exp
    @@ -263,6 +263,7 @@ foreach option {
         sym32
         synci
         relax-pic-calls
    +    mcount-ra-address
     } {
         lappend mips_option_groups $option "-m(no-|)$option"
     }
    diff --git a/gcc/testsuite/gcc.target/mips/mmcount-ra-address-1.c b/gcc/testsuite/gcc.target/mips/mmcount-ra-address-1.c
    new file mode 100644
    index 0000000..2af802d
    --- /dev/null
    +++ b/gcc/testsuite/gcc.target/mips/mmcount-ra-address-1.c
    @@ -0,0 +1,7 @@
    +/* { dg-do compile } */
    +/* { dg-options "-O2 -pg -mmcount-ra-address -march=mips64 -mabi=64 -mno-abicalls -msym32" } */
    +/* { dg-final { scan-assembler "\tmove\t\\\$12,\\\$0" } } */
    +int bazl(int i)
    +{
    +  return i + 2;
    +}
    diff --git a/gcc/testsuite/gcc.target/mips/mmcount-ra-address-2.c b/gcc/testsuite/gcc.target/mips/mmcount-ra-address-2.c
    new file mode 100644
    index 0000000..d1935c8
    --- /dev/null
    +++ b/gcc/testsuite/gcc.target/mips/mmcount-ra-address-2.c
    @@ -0,0 +1,8 @@
    +/* { dg-do compile } */
    +/* { dg-options "-O2 -pg -mmcount-ra-address -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;
    +}
    diff --git a/gcc/testsuite/gcc.target/mips/mmcount-ra-address-3.c b/gcc/testsuite/gcc.target/mips/mmcount-ra-address-3.c
    new file mode 100644
    index 0000000..0798e04
    --- /dev/null
    +++ b/gcc/testsuite/gcc.target/mips/mmcount-ra-address-3.c
    @@ -0,0 +1,10 @@
    +/* { dg-do compile } */
    +/* { dg-options "-O2 -pg -mmcount-ra-address -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;
    +}
    -- 
    1.6.2.1
    
    ^ permalink raw reply	[flat|nested] 18+ messages in thread

    end of thread, other threads:[~2009-11-03 21:26 UTC | newest]
    
    Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
    -- links below jump to the message on this page --
         [not found] <028867b99ec532b84963a35e7d552becc783cafc.1256135456.git.wuzhangjin@gmail.com>
         [not found] ` <2f73eae542c47ac5bbb9f7280e6c0271d193e90d.1256135456.git.wuzhangjin@gmail.com>
         [not found]   ` <3f0d3515f74a58f4cfd11e61b62a129fdc21e3a7.1256135456.git.wuzhangjin@gmail.com>
         [not found]     ` <ea8aa927fbd184b54941e4c2ae0be8ea0b4f6b8a.1256135456.git.wuzhangjin@gmail.com>
         [not found]       ` <1256138686.18347.3039.camel@gandalf.stny.rr.com>
         [not found]         ` <1256233679.23653.7.camel@falcon>
         [not found]           ` <4AE0A5BE.8000601@caviumnetworks.com>
         [not found]             ` <87y6n36plp.fsf@firetop.home>
    2009-10-23 23:25               ` [PATCH] MIPS: Add option to pass return address location to _mcount. Was: [PATCH -v4 4/9] tracing: add static function tracer support for MIPS David Daney
    2009-10-24  9:32                 ` Richard Sandiford
    2009-10-24 16:52                   ` Wu Zhangjin
    2009-10-26 19:12                   ` [PATCH] MIPS: Add option to pass return address location to _mcount David Daney
    2009-10-27  1:19                     ` Wu Zhangjin
    2009-10-27 21:38                     ` Richard Sandiford
    2009-10-28 18:26                       ` David Daney
    2009-10-28 19:22                         ` Richard Sandiford
    2009-10-29  8:14                       ` Wu Zhangjin
    2009-10-29 16:35                         ` David Daney
    2009-10-29 18:15                       ` David Daney
    2009-11-03 21:26                         ` Richard Sandiford
         [not found]     ` <96110ea5dd4d3d54eb97d0bb708a5bd81c7a50b5.1256135456.git.wuzhangjin@gmail.com>
         [not found]       ` <af3ec1b5cd06b6f6a461c9fa7d09a51fabccb08d.1256135456.git.wuzhangjin@gmail.com>
         [not found]         ` <a6f2959a69b6a77dd32cc36a5c8202f97d524f1e.1256135456.git.wuzhangjin@gmail.com>
         [not found]           ` <53bdfdd95ec4fa00d4cc505bb5972cf21243a14d.1256135456.git.wuzhangjin@gmail.com>
         [not found]             ` <26008418.post@talk.nabble.com>
    2009-10-25 11:20               ` [PATCH -v4 9/9] tracing: add function graph tracer support for MIPS Wu Zhangjin
    2009-10-25 14:10                 ` Patrik Kluba
    2009-10-25 14:52                   ` Wu Zhangjin
    2009-10-25 16:00                 ` Richard Sandiford
    2009-10-29  9:04 [PATCH] MIPS: Add option to pass return address location to _mcount Wu Zhangjin
    2009-10-29 16:33 ` David Daney
    

    This is a public inbox, see mirroring instructions
    for how to clone and mirror all data and code used for this inbox;
    as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).