public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Few question regarding the implementation of splitting HImode patterns
@ 2008-05-23 18:56 Omar Torres
  2008-05-24  4:40 ` Mohamed Shafi
  0 siblings, 1 reply; 2+ messages in thread
From: Omar Torres @ 2008-05-23 18:56 UTC (permalink / raw)
  To: shafitvm; +Cc: gcc

Mohamed Shafi wrote:
> Hello Omar,
>
> I saw your mail to gcc mailing list regarding splitting of HImode
> patterns into QImode patterns. I am also involved in porting. My
> problem is similar to yours. But i have to split SImode patterns into
> HImode patterns.
>
> I am sure that you have modified your define_split patterns after
> receiving the suggestions from the mailing list. Could you just mail
> me the finalized define_split pattern of HImode.
>
> One thing that i noticed in your split pattern is that you are not
> handling cases where operand[0] is memory, i.e store patterns.  How
> are you handling this? Do you have a define_insn for this case?
>
> I hope you don't mind me asking these questions.
>
> Thank you for your time.
>
> Regards,
> Shafi
>
>

Hi Mohamed,
  I added the gcc mailing list to the threat.

My current implementation looks like this:
;; movhi
(define_expand "movhi"
   [(set (match_operand:HI 0 "nonimmediate_operand" "")
         (match_operand:HI 1 "general_operand"      ""))]
""
{
   if (c816_expand_move (HImode, operands)) {
       DONE;
   }
})

;; =&r creates an early clobber.
;; It prevent insn where the target register
;; is the same as the base register used for memory addressing...
;; This is needed so that the split produce correct code.
(define_insn "*movhi"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=&r,m")
         (match_operand:HI 1 "general_operand"      "g,r"))]
""
"#")

(define_split
   [(set (match_operand:HI 0 "nonimmediate_operand" "")
         (match_operand:HI 1 "general_operand"      ""))]
   "reload_completed"
[(set (match_dup 2) (match_dup 4))
  (set (match_dup 3) (match_dup 5))]
  "{
   gcc_assert (REG_P (operands[0]) || MEM_P (operands[0]));

#ifdef DEBUG_OVERLAP
   if (reg_overlap_mentioned_p(operands[0], operands[1])){
       fprintf (stderr, \"\nOperands Overlap:\n\");
       debug_rtx (curr_insn);
   }
#endif

   if (REG_P (operands[0])) {
       operands[2] = gen_highpart(QImode, operands[0]);
       operands[3] = gen_lowpart (QImode, operands[0]);
   }
   else if (MEM_P (operands[0])) {
       operands[2] = adjust_address (operands[0], QImode, 0);
       operands[3] = adjust_address (operands[0], QImode, 1);
   }

   if (MEM_P (operands[1])) {// || CONST == GET_CODE (operands[1])) {
       operands[4] = adjust_address (operands[1], QImode, 0);
       operands[5] = adjust_address (operands[1], QImode, 1);
   }
   else if (LABEL_REF == GET_CODE (operands[1])
          || SYMBOL_REF == GET_CODE (operands[1])) {//
       operands[4] = simplify_gen_subreg(QImode, operands[1], HImode, 0);
       operands[5] = simplify_gen_subreg(QImode, operands[1], HImode, 1);
   }
   else if (CONST_INT == GET_CODE (operands[1])
          || REG_P (operands[1])) {
       operands[4] = simplify_gen_subreg(QImode, operands[1], HImode, 0);
       operands[5] = simplify_gen_subreg(QImode, operands[1], HImode, 1);
   }
   else {
       error(\"Unrecognized code in operands[1]\");
       fputs(\"\nrtx code is: \", stderr);
       debug_rtx(curr_insn);
       abort();
   }
  }")


The purpose of the expand is to load Label or Symbol references into
base registers for index addressing. I decided to use the expand since
the force_reg() was failing when I called from the split.

The c816_expand_move() is implemented as follows:
bool
c816_expand_move (enum machine_mode mode, rtx *operands) {
   if (!no_new_pseudos) {
     int i;
     for (i = 0; i < 2; i++) {
       if (MEM_P (operands[i]) || CONST == GET_CODE (operands[i])) {
	rtx base = XEXP (operands[i],0);
	if (CONST == GET_CODE(base)) {
	  base = XEXP (base,0);
	}
	if (PLUS == GET_CODE (base)) {
	  rtx off = XEXP (base,1);
	  base = XEXP (base,0);
	  if (SYMBOL_REF == GET_CODE (base)
	      || LABEL_REF == GET_CODE (base)) {
	    rtx newreg = force_reg (Pmode, base);
	    operands[i] = gen_rtx_MEM (mode,
				       gen_rtx_PLUS (Pmode,
						     newreg,
						     off));
	  }
	}
	else if (SYMBOL_REF == GET_CODE (base)
		 || LABEL_REF == GET_CODE(base)) {
	  rtx newreg = force_reg (Pmode, base);
	  operands[i] = gen_rtx_MEM (mode, newreg);
	}
       }// if MEM_P
     }// for
   }// if !no_new_pseudos
   return false;
}

In your case, you might want to look at other gcc ports for 16-bit
machines. One I have look from time to time is the MSP430 port
(http://mspgcc.sourceforge.net/).

Hope this helps.
Good Luck,
-Omar

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Few question regarding the implementation of splitting HImode patterns
  2008-05-23 18:56 Few question regarding the implementation of splitting HImode patterns Omar Torres
@ 2008-05-24  4:40 ` Mohamed Shafi
  0 siblings, 0 replies; 2+ messages in thread
From: Mohamed Shafi @ 2008-05-24  4:40 UTC (permalink / raw)
  To: Omar Torres; +Cc: gcc

On Sat, May 24, 2008 at 12:26 AM, Omar Torres <gcc.omar@gmail.com> wrote:
> Mohamed Shafi wrote:
>> Hello Omar,
>>
>> I saw your mail to gcc mailing list regarding splitting of HImode
>> patterns into QImode patterns. I am also involved in porting. My
>> problem is similar to yours. But i have to split SImode patterns into
>> HImode patterns.
>>
>> I am sure that you have modified your define_split patterns after
>> receiving the suggestions from the mailing list. Could you just mail
>> me the finalized define_split pattern of HImode.
>>
>> One thing that i noticed in your split pattern is that you are not
>> handling cases where operand[0] is memory, i.e store patterns.  How
>> are you handling this? Do you have a define_insn for this case?
>>
>> I hope you don't mind me asking these questions.
>>
>> Thank you for your time.
>>
>> Regards,
>> Shafi
>>
>>
>
> Hi Mohamed,
>  I added the gcc mailing list to the threat.
>
> My current implementation looks like this:
> ;; movhi
> (define_expand "movhi"
>   [(set (match_operand:HI 0 "nonimmediate_operand" "")
>         (match_operand:HI 1 "general_operand"      ""))]
> ""
> {
>   if (c816_expand_move (HImode, operands)) {
>       DONE;
>   }
> })
>
> ;; =&r creates an early clobber.
> ;; It prevent insn where the target register
> ;; is the same as the base register used for memory addressing...
> ;; This is needed so that the split produce correct code.
> (define_insn "*movhi"
>   [(set (match_operand:HI 0 "nonimmediate_operand" "=&r,m")
>         (match_operand:HI 1 "general_operand"      "g,r"))]
> ""
> "#")
>
> (define_split
>   [(set (match_operand:HI 0 "nonimmediate_operand" "")
>         (match_operand:HI 1 "general_operand"      ""))]
>   "reload_completed"
> [(set (match_dup 2) (match_dup 4))
>  (set (match_dup 3) (match_dup 5))]
>  "{
>   gcc_assert (REG_P (operands[0]) || MEM_P (operands[0]));
>
> #ifdef DEBUG_OVERLAP
>   if (reg_overlap_mentioned_p(operands[0], operands[1])){
>       fprintf (stderr, \"\nOperands Overlap:\n\");
>       debug_rtx (curr_insn);
>   }
> #endif
>
>   if (REG_P (operands[0])) {
>       operands[2] = gen_highpart(QImode, operands[0]);
>       operands[3] = gen_lowpart (QImode, operands[0]);
>   }
>   else if (MEM_P (operands[0])) {
>       operands[2] = adjust_address (operands[0], QImode, 0);
>       operands[3] = adjust_address (operands[0], QImode, 1);
>   }
>
>   if (MEM_P (operands[1])) {// || CONST == GET_CODE (operands[1])) {
>       operands[4] = adjust_address (operands[1], QImode, 0);
>       operands[5] = adjust_address (operands[1], QImode, 1);
>   }
>   else if (LABEL_REF == GET_CODE (operands[1])
>          || SYMBOL_REF == GET_CODE (operands[1])) {//
>       operands[4] = simplify_gen_subreg(QImode, operands[1], HImode, 0);
>       operands[5] = simplify_gen_subreg(QImode, operands[1], HImode, 1);
>   }
>   else if (CONST_INT == GET_CODE (operands[1])
>          || REG_P (operands[1])) {
>       operands[4] = simplify_gen_subreg(QImode, operands[1], HImode, 0);
>       operands[5] = simplify_gen_subreg(QImode, operands[1], HImode, 1);
>   }
>   else {
>       error(\"Unrecognized code in operands[1]\");
>       fputs(\"\nrtx code is: \", stderr);
>       debug_rtx(curr_insn);
>       abort();
>   }
>  }")
>
>
> The purpose of the expand is to load Label or Symbol references into
> base registers for index addressing. I decided to use the expand since
> the force_reg() was failing when I called from the split.
>
    Thank you for your reply.
    I think you can do this in GO_IF_LEGITIMATE_ADDRESS macro. There
just return false if you find the above addressing modes or rather
return tru only for the addressing modes you want to use. That way gcc
will automatically load the symbol ref to registers.


Regards,
Shafi

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-05-24  4:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-23 18:56 Few question regarding the implementation of splitting HImode patterns Omar Torres
2008-05-24  4:40 ` Mohamed Shafi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).