aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/mips/micromips.md13
-rw-r--r--gcc/config/mips/mips.c14
3 files changed, 33 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 285bc8e..8a153c9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+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.
diff --git a/gcc/config/mips/micromips.md b/gcc/config/mips/micromips.md
index 4b7a4a7..95af627 100644
--- a/gcc/config/mips/micromips.md
+++ b/gcc/config/mips/micromips.md
@@ -95,6 +95,19 @@
(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" "")
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index d1ba996..7545b60 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -11414,6 +11414,7 @@ mips_expand_epilogue (bool sibcall_p)
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 ())
{
@@ -11541,12 +11542,19 @@ mips_expand_epilogue (bool sibcall_p)
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. */
@@ -11596,12 +11604,16 @@ mips_expand_epilogue (bool sibcall_p)
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);
}
}