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