"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

Reply via email to