Setting insn mnemonic partly automagically

Georg-Johann Lay avr@gjlay.de
Sat Jun 22 11:00:54 GMT 2024


Am 22.06.24 um 10:46 schrieb Stefan Schulze Frielinghaus:
> On Fri, Jun 21, 2024 at 09:50:43PM +0200, Georg-Johann Lay wrote:
>>
>>
>> Am 17.06.24 um 21:13 schrieb Stefan Schulze Frielinghaus via Gcc:
>>> Hi all,
>>>
>>> I'm trying to add an alternative to an existing insn foobar:
>>>
>>> (define_insn "foobar"
>>>     [(set (match_operand ...)
>>>           (match_operand ...))]
>>>     ""
>>>     "@
>>>      foo
>>>      bar
>>>      #")
>>>
>>> Since the asm output depends on the operands in a non-trivial way which isn't
>>> easily solved via iterators, I went for a general C function and came up with:
>>>
>>> (define_insn "foobar"
>>>     [(set (match_operand ...)
>>>           (match_operand ...))]
>>>     ""
>>>     "@
>>>      foo
>>>      * return foobar_helper (operands[0], operands[1]);
>>>      bar
>>>      #"
>>>     [(set_attr_alternative "mnemonic" [(const_string "foo")
>>>                                        (const_string "specialcase")
>>>                                        (const_string "bar")
>>>                                        (const_string "unknown")])])
>>>
>>> If there exist a lot of alternatives, then setting the mnemonic attribute like
>>> this feels repetitive and is error prone.  Furthermore, if there exists no
>>> other insn with an output template containing foo/bar, then I would have to
>>> declare foo/bar via
>>>
>>> (define_attr "mnemonic" "...,foo,bar,..." (const_string "unknown"))
>>>
>>> which again is repetitive.  Thus, I'm wondering if there exists a more elegant
>>> way to achieve this?  Ultimately, I would like to set the mnemonic
>>> attribute only manually for the alternative which is implemented via C
>>> code and let the mnemonic attribute for the remaining alternatives be
>>> set automagically.  Not sure whether this is supported?
>>>
>>> If all fails, I have another idea how to solve this by utilizing PRINT_OPERAND.
>>> However, now I'm curious whether my current attempt is feasible or not.
>>>
>>> Cheers,
>>> Stefan
>>
>> It's a bit unclear to me what you are trying to do, as you are not only
>> adding an insn alternative, but also are adding insn attribute
>> "mnemonic", which the original insn did not have.
> 
> My take so far is that every insn has a mnemonic attribute which is set
> either explicitly or implicitly (assuming that the target requested this
> via define_attr "mnemonic" "...").  This is done in function
> gen_mnemonic_attr() from gensupport.cc.  Thus, something like
> 
> (define_insn "foobar"
>     [(set (match_operand ...)
>           (match_operand ...))]
>     ""
>     "@
>      foo
>      bar
>      #")
> 
> and
> 
> (define_insn "foobar"
>     [(set (match_operand ...)
>           (match_operand ...))]
>     ""
>     "@
>      foo
>      bar
>      #"
>     [(set_attr_alternative "mnemonic" [(const_string "foo")
>                                        (const_string "bar")
>                                        (const_string "unknown")])])
> 
> should be equivalent.
> 
> Of course, the implicit method fails if the pattern is generated via C
> statements which is way I set it manually in the initial example.  The
> initial example contained 3 alternatives plus 1 for the generated one.
> Setting it manually there might be feasible, however, for my actual
> problem I have an insn with 27 alternatives where I do not want to set
> and maintain it manually.  A side effect of setting the attribute
> implicitly is that each mnemonic is added automatically to the mnemonic
> hash table which I would have to do manually for my 27 alternatives
> which I would like to avoid, too.
> 
>>
>> Also, it's unclear how PRINT_OPERAND would help with setting the attribute.
> 
> For my particular problem I think one can also utilize PRINT_OPERAND
> which I should have elaborated a bit more but feared to make the example
> unnecessarily complicated.  The C code
> 
>    foobar_helper (operands[0], operands[1])
> 
> emits actually an extended mnemonic "specialcase$VAR\t%0,%1" where $VAR
> can be either A, B, or C.  The extended mnemonic is just syntactic sugar
> for the base mnemonic "specialcase\t%0,%1,$IMM" which is why we can lie
> and hard code the mnemonic attribute to specialcase since this won't
> effect scheduling.  Since the choice which extended mnemonic should be
> used depends only on operands[1] I thought about rewriting all this into
> 
> (define_insn "foobar"
>     [(set (match_operand ...)
>           (match_operand ...))]
>     ""
>     "@
>      foo
>      specialcase\t%0,%1,%X1
>      bar
>      #")
> 
> Obviously we have to sacrifice the usage of an extended mnemonic but
> more problematic is that we have to allocate one of those very few codes
> X just for this insn.  So this doesn't scale either if one has to come
> up with many different codes.  Furthermore, this only works in my very
> particular case since I can split the extended mnemonic into a base
> mnemonic and an immediate which only depends on one operand, i.e., it
> would fail if it depended on operands[0] and operands[1].
> 
> I hope this makes it a bit more clear, if not just let me know.
> 
> Cheers,
> Stefan

Maybe the following syntax for setting an attribute is a better
fit in your case?

   [(set (attr "length")
         (symbol_ref ("4 + reg_overlap_mentioned_p (operands[0], 
operands[1])")))

So you can hook in some function that spits out the attributes,
and it could also provide mnemonics.

Johann


More information about the Gcc mailing list