On Wed, Oct 2, 2024 at 1:03 PM Jakub Jelinek <ja...@redhat.com> wrote:
>
> Hi!
>
> In the Cauldron IPA/LTO BoF we've discussed toplevel asms and it was
> discussed it would be nice to tell the compiler something about what
> the toplevel asm does.  Sure, I'm aware the kernel people said they
> aren't willing to use something like that, but perhaps other projects
> do.  And for kernel perhaps we should add some new option which allows
> some dumb parsing of the toplevel asms and gather something from that
> parsing.
>
> The following patch is just a small step towards that, namely, allow
> some subset of extended inline asm outside of functions.
> The patch is unfinished, LTO streaming (out/in) of the ASM_EXPRs isn't
> implemented, nor any cgraph/varpool changes to find out references etc.
>
> The patch allows something like:
>
> int a[2], b;
> enum { E1, E2, E3, E4, E5 };
> struct S { int a; char b; long long c; };
> asm (".section blah; .quad %P0, %P1, %P2, %P3, %P4; .previous"
>      : : "m" (a), "m" (b), "i" (42), "i" (E4), "i" (sizeof (struct S)));
>
> Even for non-LTO, that could be useful e.g. for getting enumerators from
> C/C++ as integers into the toplevel asm, or sizeof/offsetof etc.
>
> The restrictions I've implemented are:
> 1) asm qualifiers aren't still allowed, so asm goto or asm inline can't be
>    specified at toplevel, asm volatile has the volatile ignored for C++ with
>    a warning and is an error in C like before
> 2) I see good use for mainly input operands, output maybe to make it clear
>    that the inline asm may write some memory, I don't see a good use for
>    clobbers, so the patch doesn't allow those (and of course labels because
>    asm goto can't be specified)
> 3) the patch allows only constraints which don't allow registers, so
>    typically "m" or "i" or other memory or immediate constraints; for
>    memory, it requires that the operand is addressable and its address
>    could be used in static var initializer (so that no code actually
>    needs to be emitted for it), for others that they are constants usable
>    in the static var initializers
> 4) the patch disallows + (there is no reload of the operands, so I don't
>    see benefits of tying some operands together), nor % (who cares if
>    something is commutative in this case), or & (again, no code is emitted
>    around the asm), nor the 0-9 constraints
>
> Right now there is no way to tell the compiler that the inline asm defines
> some symbol, I wonder if we can find some unused constraint letter or
> sequence or other syntax to denote that.  Note, I think we want to be
> able to specify that an inline asm defines a function or variable and
> be able to provide the type etc. thereof.  So
> extern void foo (void);
> extern int var;
> asm ("%P0: ret" : : "defines" (foo));
> asm ("%P0: .quad 0" : : "defines" (var));
> where the exact "defines" part is TBD.
>
> Another question is whether all targets have something like x86 P print
> modifier which doesn't add any stuff around the printed expressions
> (perhaps there are targets which don't do that just for %0 etc.), or
> whether we want to add something that will be usable on all targets.

%P is very x86 specific, perhaps you should use %c instead?

The %c modifier is described in:

6.48.2.8 Generic Operand Modifiers
..................................

The following table shows the modifiers supported by all targets and
their effects:

Modifier    Description                                        Example
---------------------------------------------------------------------------
‘c’         Require a constant operand and print the           ‘%c0’
           constant expression with no punctuation.
...

E.g.:

void bar (void);
void foo (void)
{
  asm ("%c0" :  : "i"(bar));
}

generates:

#APP
# 5 "c.c" 1
       bar
# 0 "" 2
#NO_APP

Uros.

Reply via email to