"Moore, Catherine" <[email protected]> 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