Richard Sandiford <[email protected]> writes:
> Tamar Christina <[email protected]> writes:
>> Today output operand modifiers are limited to a single character, as in
>> %w0 or %c1. That works, but it makes the modifier namespace very small
>> and encourages target ports either to use cryptic letters or to fall back
>> to C output blocks for cases that are really just target-specific
>> printing.
>>
>> This patch adds a longer spelling for the same mechanism:
>>
>> %[name]0
>>
>> The bracketed spelling is intentionally familiar rather than completely new:
>> extended asm already uses %[Value] to refer to an operand with a
> symbolic name,
>> as in:
>>
>> asm ("add %[out], %[in], %[imm]"
>> : [out] "=r" (out)
>> : [in] "r" (in), [imm] "I" (1));
>>
>> That existing form keeps its meaning. A bare %[Value] is still resolved by
>> the front end as a symbolic operand reference. The new print-operand form is
>> recognized when the closing bracket is followed by an operand number, as in
>> %[name]0.
>>
>> The modifier syntax can also be combined with symbolic operand names.
> In user
>> asm, %[modifier:Value] means "print operand Value using the multi-character
>> modifier named modifier". The front end resolves Value to an operand number,
>> so final output sees the same thing it would have seen for
> %[modifier:N]. For
>> example:
>>
>> asm ("mov %[w:out], %[w:in]"
>> : [out] "=r" (out)
>> : [in] "r" (in));
>>
>> is resolved as if the template had used %[w]0 and %[w]1.
>>
>> GCC parses the bracketed modifier name, interns it, and passes
> PRINT_OPERAND an
>> opaque integer code for it. Old-style modifiers keep their existing
> values, so
>> existing target hooks continue to see 'w', 'c', etc. for the single-character
>> forms. Backends that want to handle the new form can call
>> output_operand_modifier_name (code) to recover "name".
>>
>> For example, a machine description can now write something like:
>>
>> "extract\t%[lowpart]0, %1"
>>
>> or if preferred
>>
>> "extract\t%[lowpart:0], %1"
>>
>> and the target's PRINT_OPERAND hook can handle "lowpart" as a named modifier.
>> The parser also allows comma-separated nonempty components in the
> brackets, but
>> deliberately leaves the interpretation of those components to the target.
>>
>> The patch also records whether an extended modifier came from user asm
> or from
>> an internal machine-description output template. Targets can use
>> output_operand_modifier_user_p (code) to reject internal-only names in
>> user-facing asm while still using the clearer names internally.
>>
>> This addresses Richard Earnshaw's suggestion by keeping the target hook
>> interface as an int code and mapping the longer spelling onto values outside
>> the single-character range. Targets that do not opt in do not need a
> new hook
>> or a new parser path, and existing hard-coded character uses continue
> to work.
>>
>> It also addresses Richard Sandiford's feedback by giving the new
> %[...] syntax
>> its own namespace rather than automatically exposing every single-letter
>> modifier through the new spelling. The user-asm bit lets a target
> decide which
>> named modifiers are public and which are only for compiler-generated
> templates.
>> The comma-separated spelling is accepted as a target-defined modifier string,
>> so a port can later treat, say, %[gpr,zero]0 as a composition of
>> target-specific printing choices without requiring more middle-end syntax.
>>
>> Bootstrapped Regtested on aarch64-none-linux-gnu,
>> arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
>> -m32, -m64 and no issues.
>>
>> OK for master?
>>
>> Thanks,
>> Tamar
>
> Thanks for doing this. It mostly looks good to me FWIW, but some
> comments below:
Sorry, one other thing: in the original thread, there was a discussion
about whether we should have a new target hook to show that the target
supports multicharacter modifiers. Without that, I think we'd have to
audit each port's print_operand hook to make sure that it gives a
sensible error message for invalid modifiers.
For example, it looks like i386's:
default:
output_operand_lossage ("invalid operand code '%c'", code);
would not print a sensible error message for multicharacter modifiers.
So I think there is still value in a hook. Rather than allocate codes
automatically, how about a hook that takes:
- the modifier string
- whether the modifier occurs in an asm
and
- returns a code >= UCHAR_MAX + 1 (encapsulated in some kind of
public constant) if the modifier is valid
- returns zero otherwise
? Target-independent code could then either pass the returned value to
print_operand or report an error.
This also has the advantage that we could report the error in stmt.cc,
rather than waiting until final. That in turn would mean that we'd
check asms that are compiled out in the current TU, just like we would
for other badly formed asm strings.
Thanks,
Richard