aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2008-06-01 10:01:51 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2008-06-01 10:01:51 +0000
commit2f7e2abbd1a97bcc0a8442c8e7358fb01ef7ffa8 (patch)
treebc06c6ca241f81979ec4350f6069f050b6141e41 /gcc
parentc41c1387d39f345a301dde4c414d379319d6ccc1 (diff)
downloadgcc-2f7e2abbd1a97bcc0a8442c8e7358fb01ef7ffa8.zip
gcc-2f7e2abbd1a97bcc0a8442c8e7358fb01ef7ffa8.tar.gz
gcc-2f7e2abbd1a97bcc0a8442c8e7358fb01ef7ffa8.tar.bz2
mips-protos.h (mips_expand_before_return): Declare.
gcc/ * config/mips/mips-protos.h (mips_expand_before_return): Declare. * config/mips/mips.c (mips_expand_before_return): New function. (mips_expand_epilogue): Call it. * config/mips/mips.md (return): Turn into a define_expand. (*return): New insn. From-SVN: r136252
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.c19
-rw-r--r--gcc/config/mips/mips.md7
4 files changed, 34 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e990443..624d338 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2008-06-01 Richard Sandiford <rdsandiford@googlemail.com>
+ * config/mips/mips-protos.h (mips_expand_before_return): Declare.
+ * config/mips/mips.c (mips_expand_before_return): New function.
+ (mips_expand_epilogue): Call it.
+ * config/mips/mips.md (return): Turn into a define_expand.
+ (*return): New insn.
+
+2008-06-01 Richard Sandiford <rdsandiford@googlemail.com>
+
* rtl.h (emit_clobber, gen_clobber, emit_use, gen_use): Declare.
* emit-rtl.c (emit_clobber, gen_clobber, emit_use, gen_use): New
functions. Do not emit uses and clobbers of CONCATs; individually
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index db65aab..1bf0ee9 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -257,6 +257,7 @@ extern HOST_WIDE_INT mips_initial_elimination_offset (int, int);
extern rtx mips_return_addr (int, rtx);
extern enum mips_loadgp_style mips_current_loadgp_style (void);
extern void mips_expand_prologue (void);
+extern void mips_expand_before_return (void);
extern void mips_expand_epilogue (bool);
extern bool mips_can_use_return_insn (void);
extern rtx mips_function_value (const_tree, enum machine_mode);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index b12e2e2..246600d 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -8633,6 +8633,24 @@ mips_restore_reg (rtx reg, rtx mem)
mips_emit_move (reg, mem);
}
+/* Emit any instructions needed before a return. */
+
+void
+mips_expand_before_return (void)
+{
+ /* When using a call-clobbered gp, we start out with unified call
+ insns that include instructions to restore the gp. We then split
+ these unified calls after reload. These split calls explicitly
+ clobber gp, so there is no need to define
+ PIC_OFFSET_TABLE_REG_CALL_CLOBBERED.
+
+ For consistency, we should also insert an explicit clobber of $28
+ before return insns, so that the post-reload optimizers know that
+ the register is not live on exit. */
+ if (TARGET_CALL_CLOBBERED_GP)
+ emit_clobber (pic_offset_table_rtx);
+}
+
/* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P
says which. */
@@ -8775,6 +8793,7 @@ mips_expand_epilogue (bool sibcall_p)
regno = GP_REG_FIRST + 7;
else
regno = GP_REG_FIRST + 31;
+ mips_expand_before_return ();
emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, regno)));
}
}
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 921e416..55e1cd0 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -5739,7 +5739,12 @@
;; Trivial return. Make it look like a normal return insn as that
;; allows jump optimizations to work better.
-(define_insn "return"
+(define_expand "return"
+ [(return)]
+ "mips_can_use_return_insn ()"
+ { mips_expand_before_return (); })
+
+(define_insn "*return"
[(return)]
"mips_can_use_return_insn ()"
"%*j\t$31%/"