aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2009-10-29 17:39:52 +0000
committerDavid Daney <daney@gcc.gnu.org>2009-10-29 17:39:52 +0000
commitc376dbfba163068f1caeb1b7749bb74366a5efad (patch)
tree60e94e291058dd033915cf8b9ec971575d6b5cae
parent2b7e2984ce29a528a8a280191947742a19624b0b (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.c59
-rw-r--r--gcc/config/mips/mips.h39
-rw-r--r--gcc/config/mips/mips.opt4
-rw-r--r--gcc/doc/invoke.texi23
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.target/mips/mips.exp1
-rw-r--r--gcc/testsuite/gcc.target/mips/mmcount-ra-address-1.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/mmcount-ra-address-2.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/mmcount-ra-address-3.c9
11 files changed, 135 insertions, 39 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8a2b539..7c6d211 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
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 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
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 9a21777..93d87cc 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
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e382b96..2617493 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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 != .
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..cf5b044
--- /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 -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
index 0000000..bef9dd9
--- /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 -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
index 0000000..59007e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/mmcount-ra-address-3.c
@@ -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;
+}