"Moore, Catherine" <catherine_mo...@mentor.com> writes: > Index: config/mips/micromips.md > =================================================================== > --- config/mips/micromips.md (revision 196341) > +++ config/mips/micromips.md (working copy) > @@ -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 "const_int_operand")))])]
Since this is a generic pattern (not depending on UNSPECs, etc.), I think we should use a specific predicate instead of const_int_operand. >From the suggestion in the thread about addition, this would be a "uw5", i.e. uw5_operand. > Index: config/mips/mips.c > =================================================================== > --- config/mips/mips.c (revision 196341) > +++ config/mips/mips.c (working copy) > @@ -11364,6 +11364,7 @@ > 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 ()) > { > @@ -11453,6 +11454,14 @@ > mips_for_each_saved_gpr_and_fpr (frame->total_size - step2, > mips_restore_reg); > > + /* Check if we can use JRADDIUSP. */ > + use_jraddiusp_p = (TARGET_MICROMIPS > + && !crtl->calls_eh_return > + && !sibcall_p > + && step2 > 0 > + && (step2 & 3) == 0 > + && step2 <= (31 << 2)); > + > if (cfun->machine->interrupt_handler_p) > { > HOST_WIDE_INT offset; > @@ -11480,8 +11489,9 @@ > mips_emit_move (gen_rtx_REG (word_mode, K0_REG_NUM), mem); > offset -= UNITS_PER_WORD; > > - /* If we don't use shadow register set, we need to update SP. */ > - if (!cfun->machine->use_shadow_register_set_p) > + /* If we don't use shadow register set or the microMIPS > + JRADDIUSP insn, we need to update SP. */ > + if (!cfun->machine->use_shadow_register_set_p && !use_jraddiusp_p) > mips_deallocate_stack (stack_pointer_rtx, GEN_INT (step2), 0); > else > /* The choice of position is somewhat arbitrary in this case. */ We shouldn't use JRADDIUSP in an interrupt handler, so I think it would be better to move the use_jraddiusp_p condition into the else branch and drop the hunk above. > @@ -11492,11 +11502,14 @@ > gen_rtx_REG (SImode, K0_REG_NUM))); > } > else > - /* Deallocate the final bit of the frame. */ > - mips_deallocate_stack (stack_pointer_rtx, GEN_INT (step2), 0); > + /* Deallocate the final bit of the frame unless using the microMIPS > + JRADDIUSP insn. */ > + if (!use_jraddiusp_p) > + 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); We still need to emit the CFA restores somewhere. Something like: else if (TARGET_MICROMIPS && !crtl->calls_eh_return && !sibcall_p && step2 > 0 && mips_unsigned_immediate_p (step2, 5, 2)) { /* We can deallocate the stack and jump to $31 using JRADDIUSP. Emit the CFA restores immediately before the deallocation. */ use_jraddisup_p = true; mips_epilogue_emit_cfa_restores (); } else /* Deallocate the final bit of the frame. */ mips_deallocate_stack (stack_pointer_rtx, GEN_INT (step2), 0); where mips_unsigned_immediate_p comes from the other thread. Thanks, Richard