+2013-04-02 Catherine Moore <clm@codesourcery.com>
+ Chao-ying Fu <fu@mips.com>
+
+ * config/mips/micromips.md (jraddiusp): New pattern.
+ * config/mips/mips.c (mips_expand_epilogue): Use the JRADDIUSP
+ instruction if possible.
+
2013-04-24 Alan Modra <amodra@gmail.com>
* config/rs6000/driver-rs6000.c (elf_dcachebsize): Fix comment pasto.
(set_attr "mode" "SI")
(set_attr "can_delay" "no")])
+;; For JRADDIUSP.
+(define_insn "jraddiusp"
+ [(parallel [(return)
+ (use (reg:SI 31))
+ (set (reg:SI 29)
+ (plus:SI (reg:SI 29)
+ (match_operand 0 "uw5_operand")))])]
+ "TARGET_MICROMIPS"
+ "jraddiusp\t%0"
+ [(set_attr "type" "trap")
+ (set_attr "can_delay" "no")
+ (set_attr "mode" "SI")])
+
;; For MOVEP.
(define_peephole2
[(set (match_operand:MOVEP1 0 "register_operand" "")
const struct mips_frame_info *frame;
HOST_WIDE_INT step1, step2;
rtx base, adjust, insn;
+ bool use_jraddiusp_p = false;
if (!sibcall_p && mips_can_use_return_insn ())
{
emit_insn (gen_cop0_move (gen_rtx_REG (SImode, COP0_STATUS_REG_NUM),
gen_rtx_REG (SImode, K0_REG_NUM)));
}
+ else if (TARGET_MICROMIPS
+ && !crtl->calls_eh_return
+ && !sibcall_p
+ && step2 > 0
+ && mips_unsigned_immediate_p (step2, 5, 2))
+ use_jraddiusp_p = true;
else
/* Deallocate the final bit of the frame. */
mips_deallocate_stack (stack_pointer_rtx, GEN_INT (step2), 0);
}
- gcc_assert (!mips_epilogue.cfa_restores);
+ if (!use_jraddiusp_p)
+ gcc_assert (!mips_epilogue.cfa_restores);
/* Add in the __builtin_eh_return stack adjustment. We need to
use a temporary in MIPS16 code. */
rtx reg = gen_rtx_REG (Pmode, GP_REG_FIRST + 7);
pat = gen_return_internal (reg);
}
+ else if (use_jraddiusp_p)
+ pat = gen_jraddiusp (GEN_INT (step2));
else
{
rtx reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
pat = gen_simple_return_internal (reg);
}
emit_jump_insn (pat);
+ if (use_jraddiusp_p)
+ mips_epilogue_set_cfa (stack_pointer_rtx, step2);
}
}