public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Specifying explicit parallel to define_insn of a named pattern.
@ 2009-03-27  6:44 venkat
  2009-03-27 16:35 ` Ian Lance Taylor
  0 siblings, 1 reply; 4+ messages in thread
From: venkat @ 2009-03-27  6:44 UTC (permalink / raw)
  To: gcc-help

I am working on porting GCC to a 32 bit RISC (based on MIPS).

In the machine descriptions, I have specified the division operation as
shown below.

(-----Cut-----)
(define_insn_and_split "<div_mod_optab_name>si3"
  [(parallel[                       <== *(1)
   (set (match_operand:SI 0 "register_operand")
        (any_div_op:SI (match_operand:SI 1 "register_operand")
                       (match_operand:SI 2 "register_operand")))
   (clobber (reg:SI LO_REG_NUM))
   (clobber (reg:SI HI_REG_NUM))
   ])
]
  ""
  "#"
  "reload_completed"
  [(parallel[(set (match_dup 3)
                   (any_div_op:SI (match_dup 1)
                                  (match_dup 2)))
              (clobber (reg:SI HI_REG_NUM))])
   (set (match_dup 0)
        (match_dup 3))]                    
  "
    { test(); 
    operands[3] = gen_rtx_REG(SImode,LO_REG_NUM); }
  "    
)

(define_insn "*<div_mod_optab_name>si3"
  [(parallel[
   (set (match_operand:SI 0 "lo_register_operand" "=l")
                  (any_div_op:SI (match_operand:SI 1 "register_operand"
"=b")
                                 (match_operand:SI 2 "register_operand" "
b")))
   (clobber (reg:SI HI_REG_NUM))])]
  ""
  { 
    output_check_div_by_zero(operands);
    return "<div_mod_insn_name>\t%1,%2";
  }
(-----Cut-----)

When I specify parallel explicitly *(1) as shown above, the 'genemit'
program generates the function 'add_clobbers' as shown below.

(-----Cut-----)
void
add_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number) {
  switch (insn_code_number)
    {
    case 50:
      XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 31);
      break;

    case 49:
    case 48:
      XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 31);
      break;

    case 8:
      XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 32);
      XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 33);
      break;

    default:
      gcc_unreachable ();
    }
}
(-----Cut-----)

In the above case clobber expressions are not recognized for division
operations (signed and unsigned division). 

But, when I remove the explicit parallel from the machine description as
shown below, 

(-----Cut-----)
 (define_insn_and_split "<div_mod_optab_name>si3"
  [
   (set (match_operand:SI 0 "register_operand")
        (any_div_op:SI (match_operand:SI 1 "register_operand")
                       (match_operand:SI 2 "register_operand")))
   (clobber (reg:SI LO_REG_NUM))
   (clobber (reg:SI HI_REG_NUM))
   
]
  ""
  "#"
  "reload_completed"
  [(parallel[(set (match_dup 3)
                   (any_div_op:SI (match_dup 1)
                                  (match_dup 2)))
              (clobber (reg:SI HI_REG_NUM))])
   (set (match_dup 0)
        (match_dup 3))]                    
  "
    { test(); 
    operands[3] = gen_rtx_REG(SImode,LO_REG_NUM); }
  "    
)

(define_insn "*<div_mod_optab_name>si3"
  [(parallel[
   (set (match_operand:SI 0 "lo_register_operand" "=l")
                  (any_div_op:SI (match_operand:SI 1 "register_operand"
"=b")
                                 (match_operand:SI 2 "register_operand" "
b")))
   (clobber (reg:SI HI_REG_NUM))])]
  ""
  { 
    output_check_div_by_zero(operands);
    return "<div_mod_insn_name>\t%1,%2";
  }
(-----Cut-----)

The 'genemit' program generates 'add_clobbers' as shown below.

(-----Cut-----)
void
add_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number) {
  switch (insn_code_number)
    {
    case 50:
      XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 31);
      break;

    case 49:
    case 48:
      XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 31);
      break;

    case 10:                <== this was generated
for our division operation.
    case 9:
      XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 33);
      XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 32);
      break;

    case 8:
      XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 32);
      XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 33);
      break;

    default:
      gcc_unreachable ();
    }
}
(-----Cut-----)

The clobbers defined in the machine descriptions are now recognized. The
additional case constructs are generated (case 9 and 10).

I checked the source code of the gen_emit program, specifically the function
'gen_insn (rtx insn, int lineno)' function.

When the vector read from machine description for division is

(-----Snip-----)
  [
   (set (match_operand:SI 0 "register_operand")
        (any_div_op:SI (match_operand:SI 1 "register_operand")
                       (match_operand:SI 2 "register_operand")))
   (clobber (reg:SI LO_REG_NUM))
   (clobber (reg:SI HI_REG_NUM))
   
]
(-----Snip-----)

The check in <if (i != XVECLEN (insn, 1) - 1> returns 2. That means number
of expressions in the vector is 3.

But when the vector read from machine description for division is

(-----Snip-----)
  [ (parallel [
   (set (match_operand:SI 0 "register_operand")
        (any_div_op:SI (match_operand:SI 1 "register_operand")
                       (match_operand:SI 2 "register_operand")))
   (clobber (reg:SI LO_REG_NUM))
   (clobber (reg:SI HI_REG_NUM))
   ])
]
(-----Snip-----)

The check (if (i != XVECLEN (insn, 1) - 1) returns 0. That means number of
expressions in the vector is 1.

From seeing the source code, I believe the code for recognizing clobbers
will not work when we specify explicit parallel.

Please confirm my understanding.

Also I am also aware that GCC implicitly surrounds parallel when there are
multiple expressions in the template of 'define_insn'.

So specifying parallel at the start of 'define_insn' of a named pattern has
a different meaning? 

In my case I feel explicit parallel is not needed and can be removed.

Please confirm.

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

* Re: Specifying explicit parallel to define_insn of a named pattern.
  2009-03-27  6:44 Specifying explicit parallel to define_insn of a named pattern venkat
@ 2009-03-27 16:35 ` Ian Lance Taylor
  0 siblings, 0 replies; 4+ messages in thread
From: Ian Lance Taylor @ 2009-03-27 16:35 UTC (permalink / raw)
  To: venkat; +Cc: gcc-help

"venkat" <venkat@acmet.com> writes:

> (define_insn_and_split "<div_mod_optab_name>si3"
>   [(parallel[                       <== *(1)
>    (set (match_operand:SI 0 "register_operand")
>         (any_div_op:SI (match_operand:SI 1 "register_operand")
>                        (match_operand:SI 2 "register_operand")))
>    (clobber (reg:SI LO_REG_NUM))
>    (clobber (reg:SI HI_REG_NUM))
>    ])
> ]

There is an implicit parallel in define_insn_and_split.  Don't add your
own.  I quote the documentation:

    If the vector has only one element, that element is the template for
    the instruction pattern.  If the vector has multiple elements, then
    the instruction pattern is a @code{parallel} expression containing
    the elements described.

Ian

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

* Re: Specifying explicit parallel to define_insn of a named pattern
@ 2009-03-31  5:48 ganesh gopalasubramanian
  0 siblings, 0 replies; 4+ messages in thread
From: ganesh gopalasubramanian @ 2009-03-31  5:48 UTC (permalink / raw)
  To: iant; +Cc: gcc-help

>There is an implicit parallel in define_insn_and_split.  Don't add your
>own.  I quote the documentation:
>
>    If the vector has only one element, that element is the template for
>    the instruction pattern.  If the vector has multiple elements, then
>    the instruction pattern is a @code{parallel} expression containing
>    the elements described.
>
>Ian
>

Hi Ian,

Does the use of 'parallel' depends on the use of 'define_insn'. That
is, whether it is used for matching an RTL template or for generating
an instruction?

>> (define_insn_and_split "<div_mod_optab_name>si3"
>>   [(parallel[                       <== *(1)
>>    (set (match_operand:SI 0 "register_operand")
>>         (any_div_op:SI (match_operand:SI 1 "register_operand")
>>                        (match_operand:SI 2 "register_operand")))
>>    (clobber (reg:SI LO_REG_NUM))
>>    (clobber (reg:SI HI_REG_NUM))
>>    ])
>> ]
>
>There is an implicit parallel in define_insn_and_split.  Don't add your
>own.  I quote the documentation:
>
>    If the vector has only one element, that element is the template for
>    the instruction pattern.  If the vector has multiple elements, then
>    the instruction pattern is a @code{parallel} expression containing
>    the elements described.
>
>Ian
>

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

* Re: Specifying explicit parallel to define_insn of a named pattern.
       [not found] <7238340b0903302236o14f0b740y7fb3178d41050fd6@mail.gmail.com>
@ 2009-03-31  5:48 ` Ian Lance Taylor
  0 siblings, 0 replies; 4+ messages in thread
From: Ian Lance Taylor @ 2009-03-31  5:48 UTC (permalink / raw)
  To: ganesh gopalasubramanian; +Cc: gcc-help

ganesh gopalasubramanian <gganeshgcc@gmail.com> writes:

> Does the use of 'parallel' depends on the use of 'define_insn'. That is,
> whether it is used for matching an RTL template or for generating an
> instruction?

No.  It's there either way.

Ian

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

end of thread, other threads:[~2009-03-31  5:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-27  6:44 Specifying explicit parallel to define_insn of a named pattern venkat
2009-03-27 16:35 ` Ian Lance Taylor
     [not found] <7238340b0903302236o14f0b740y7fb3178d41050fd6@mail.gmail.com>
2009-03-31  5:48 ` Ian Lance Taylor
2009-03-31  5:48 ganesh gopalasubramanian

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).