+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.
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);
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. */
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)));
}
}
;; 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%/"