invoke.texi (mmcount-ra-address): Document new command line option.
authorDavid Daney <ddaney@caviumnetworks.com>
Thu, 29 Oct 2009 17:39:52 +0000 (17:39 +0000)
committerDavid Daney <daney@gcc.gnu.org>
Thu, 29 Oct 2009 17:39:52 +0000 (17:39 +0000)
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

gcc/ChangeLog
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/mips.exp
gcc/testsuite/gcc.target/mips/mmcount-ra-address-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/mmcount-ra-address-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/mmcount-ra-address-3.c [new file with mode: 0644]

index 8a2b539..7c6d211 100644 (file)
@@ -1,3 +1,18 @@
+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  Steve Ellcey  <sje@cup.hp.com>
 
        PR middle-end/37565
index 429a621..716b7ac 100644 (file)
@@ -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 6af8d03..c8c1dca 100644 (file)
@@ -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]);
+}
 \f
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
index 50bc4ea..2829708 100644 (file)
@@ -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
index 8462e46..188d5e1 100644 (file)
@@ -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
index 9a21777..93d87cc 100644 (file)
@@ -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
@@ -14208,6 +14208,27 @@ 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
+Emit (do not emit) code that allows @code{_mcount} to modify the
+colling 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
index e382b96..2617493 100644 (file)
@@ -1,3 +1,11 @@
+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.
+
 2009-10-29  Michael Matz  <matz@suse.de>
 
        * gcc.target/i386/sse-recip.c: Use fabsf instead of != .
index aef473f..02e031c 100644 (file)
@@ -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 (file)
index 0000000..cf5b044
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -pg -mmcount-ra-address -mabi=64" } */
+/* { 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 (file)
index 0000000..bef9dd9
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -pg -mmcount-ra-address -mabi=64" } */
+/* { dg-final { scan-assembler "\tdla\t\\\$12,8\\(\\\$sp\\)" } } */
+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 (file)
index 0000000..59007e6
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -pg -mmcount-ra-address -mabi=64" } */
+/* { dg-final { scan-assembler "\tdla\t\\\$12,200008\\(\\\$sp\\)" } } */
+int foo (int *);
+int bar(int i)
+{
+  int big[50000];
+  return foo (big) + 2;
+}