> -----Original Message-----
> From: Richard Sandiford <[email protected]>
> Sent: 29 September 2026 22:46
> To: Tamar Christina <[email protected]>
> Cc: [email protected]; nd <[email protected]>; [email protected];
> Richard Earnshaw <[email protected]>;
> [email protected]
> Subject: Re: [patch][gcc 1/5]middle-end: support multi-character output
> operand modifiers
> 
> 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.

Right, so I understand correctly, we invert the control/validation here.
We ask the backend to immediately validate the multi character string
as we parse it, rather than require the backend to "dequeue" it.

Yeah I can see that being better. Will do.

Thanks,
Tamar

> 
> Thanks,
> Richard

Reply via email to