This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH SH2A]: Add movml instruction


"Naveen H. S" <Naveen.S@kpitcummins.com> wrote:
> Modification of prologue and epilogue for interrupt routines was the
> only solution I found to implement these multiple transfers. I have 
> tried peepholes, instructions etc which did not give expected results.
> Please let me know whether they can be implemented in any other way.

Although there were another ways to do it, if the purpose
is simply to generate movml for interrupt handlers when
possible, modification of {pro,epi}logue would be best.

> @@ -7347,10 +7365,27 @@ sh_expand_epilogue (bool sibcall_p)
>  	 delay slot. RTE switches banks before the ds instruction.  */
>        if (current_function_interrupt)
>  	{
> -	  for (i = LAST_BANKED_REG; i >= FIRST_BANKED_REG; i--)
> +	  for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
>  	    if (TEST_HARD_REG_BIT (live_regs_mask, i))
> -	      pop (i);
> -
> +	      {
> +		if (TARGET_SH2A && !flag_schedule_insns_after_reload)

Why is !flag_schedule_insns_after_reload checked here?
Does sched2 pass make some problem with movml?

> +		  {
> +		    next_reg++;
> +		    if (i == LAST_BANKED_REG)
> +		      {
> +			if (next_reg == 8)
> +			emit_insn (gen_movml_pop (GEN_INT (next_reg), GEN_INT (next_reg)));
> +			else
> +			  {
> +			    for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
> +			      if (TEST_HARD_REG_BIT (live_regs_mask, i))
> +				pop (i);
> +			  }
> +		      }
> +		  }
> +		else 
> +		  pop (i);
> +	      }

Also now there is no need to modify the order of registers.
Perhaps it would be better to write something like:

	* config/sh/sh.c (push_regs): Emit movml for interrupt
	handler when possible.
	...

   if (interrupt_handler)
     {
       bool use_movml = false;

       if (TARGET_SH2A)
	 {
	   unsigned int count = 0;

	   for (i = LAST_BANKED_REG; i >= FIRST_BANKED_REG; i--)
	     if (TEST_HARD_REG_BIT (*mask, i))
	       count++;

	   /* We can use movml insn when all banked registers are
	      pushed.  */
	   if (count == LAST_BANKED_REG - FIRST_BANKED_REG)
	     use_movml = true;
	 }

       if (use_movml)
	 emit_insn (gen_movml_push ()));
       else
	 for (i = LAST_BANKED_REG; i >= FIRST_BANKED_REG; i--)
	   if (TEST_HARD_REG_BIT (*mask, i))
	     push (i);
     }

> +  (UNSPEC_HIGH_REG	47)
...
> +(define_insn "movml_push"
> +  [(unspec [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_HIGH_REG)]
...
> +(define_insn "movml_pop"
> +  [(set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) 
> +			  (match_operand:SI 0 "immediate_operand" "i")))
> +   (unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_HIGH_REG)]

I guess that some optimization passes can remove these insns
which have no accurate register/memory uses.
Looks unique const_int will be used as operands for these insns,
right?  If so, it would be better to use normal rtls which describe
the semantic of those movml insns accurately, like as the peepholes
in your previous patch.

Regards,
	kaz


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]