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.