Message ID | ZytIn0tLL78UOCgE@tucnak |
---|---|
State | New |
Headers | show |
Series | inline-asm: Add support for cc operand modifier | expand |
On Wed, 6 Nov 2024, Jakub Jelinek wrote: > Hi! > > As mentioned in the "inline asm: Add new constraint for symbol definitions" > patch description, while the c operand modifier is documented to: > Require a constant operand and print the constant expression with no punctuation. > it actually doesn't do that with -fpic at least on some targets and > has been behaving that way for at least 3 decades. > It prints the operand using output_addr_const if CONSTANT_ADDRESS_P is true, > but CONSTANT_ADDRESS_P can do all sorts of target specific checks. > And if it is false, it falls back to output_operand (operands[opnum], 'c'); > which will on various targets just result in an error that it is invalid > modifier letter (weird because it is documented), on others like x86 or > alpha will handle the operand in some weird way if it is a comparison > and otherwise complain the argument isn't a comparison, on others like > arm perhaps do what the user wanted. > > As I wrote, we are pretty much out of modifier letters because some targets > use a lot of them, and almost out of % punctuation chars (I think ` is left) > but right now punctuation chars aren't normally followed by operand number > anyway. > > So, the following patch takes one of the generic letters (c) and adds an > extra modifier char after it, I chose cc, which behaves like c but just > always uses output_addr_const instead of falling back to the machine > dependent code. IMO quite reasonable. Thus OK if there are no complaints. Thanks, Richard. > 2024-11-06 Jakub Jelinek <jakub@redhat.com> > > * final.cc (output_asm_insn): Add support for cc operand modifier. > * doc/extend.texi (Generic Operand Modifiers): Document cc operand > modifier. > * doc/md.texi (@samp{:} in constraint): Mention the cc operand > modifier and add small example. > > * c-c++-common/toplevel-asm-4.c: Don't use -fno-pie option. > Use cc modifier instead of c. > (v, w): Add extern keyword. > * c-c++-common/toplevel-asm-6.c: New test. > > --- gcc/final.cc.jj 2024-11-06 10:23:21.214728021 +0100 > +++ gcc/final.cc 2024-11-06 11:02:40.406413277 +0100 > @@ -3492,7 +3492,10 @@ output_asm_insn (const char *templ, rtx > int letter = *p++; > unsigned long opnum; > char *endptr; > + int letter2 = 0; > > + if (letter == 'c' && *p == 'c') > + letter2 = *p++; > opnum = strtoul (p, &endptr, 10); > > if (endptr == p) > @@ -3506,7 +3509,7 @@ output_asm_insn (const char *templ, rtx > output_address (VOIDmode, operands[opnum]); > else if (letter == 'c') > { > - if (CONSTANT_ADDRESS_P (operands[opnum])) > + if (letter2 == 'c' || CONSTANT_ADDRESS_P (operands[opnum])) > output_addr_const (asm_out_file, operands[opnum]); > else > output_operand (operands[opnum], 'c'); > --- gcc/doc/extend.texi.jj 2024-11-06 10:23:21.220727937 +0100 > +++ gcc/doc/extend.texi 2024-11-06 11:09:46.433407349 +0100 > @@ -12113,6 +12113,11 @@ The following table shows the modifiers > @item @code{c} > @tab Require a constant operand and print the constant expression with no punctuation. > @tab @code{%c0} > +@item @code{cc} > +@tab Like @samp{%c} except try harder to print it with no punctuation. > +@samp{%c} can e.g.@: fail to print constant addresses in position independent code on > +some architectures. > +@tab @code{%cc0} > @item @code{n} > @tab Like @samp{%c} except that the value of the constant is negated before printing. > @tab @code{%n0} > --- gcc/doc/md.texi.jj 2024-11-06 10:30:09.884948601 +0100 > +++ gcc/doc/md.texi 2024-11-06 11:12:51.893792814 +0100 > @@ -1510,6 +1510,13 @@ This constraint, allowed only in input o > pattern defines specific function or variable symbol. The constraint > shouldn't be mixed with other constraints on the same operand and > the operand should be address of a function or non-automatic variable. > +Best used with the @samp{cc} modifier when printing the operand, so that > +even in position independent code it prints as a label. > + > +@smallexample > +void foo (void); > +asm (".globl %cc0; %cc0: ret" : : ":" (foo)); > +@end smallexample > > @cindex other register constraints > @cindex extensible constraints > --- gcc/testsuite/c-c++-common/toplevel-asm-4.c.jj 2024-11-06 10:30:09.888948544 +0100 > +++ gcc/testsuite/c-c++-common/toplevel-asm-4.c 2024-11-06 11:14:14.553627513 +0100 > @@ -1,9 +1,8 @@ > /* PR c/41045 */ > /* { dg-do compile } */ > /* { dg-options "-O0" } */ > -/* { dg-additional-options "-fno-pie" { target pie } } */ > > -int v[42], w; > +extern int v[42], w; > void foo (void); > > -asm ("# %c0: %c1:" :: ":" (foo), ":" (v), ":" (&w)); > +asm ("# %cc0: %cc1:" :: ":" (foo), ":" (v), ":" (&w)); > --- gcc/testsuite/c-c++-common/toplevel-asm-6.c.jj 2024-11-06 11:13:44.342053423 +0100 > +++ gcc/testsuite/c-c++-common/toplevel-asm-6.c 2024-11-06 11:14:27.548444315 +0100 > @@ -0,0 +1,9 @@ > +/* PR c/41045 */ > +/* { dg-do compile } */ > +/* { dg-options "-O0" } */ > +/* { dg-additional-options "-fPIC" { target fpic } } */ > + > +extern int v[42], w; > +void foo (void); > + > +asm ("# %cc0: %cc1:" :: ":" (foo), ":" (v), ":" (&w)); > > Jakub > >
--- gcc/final.cc.jj 2024-11-06 10:23:21.214728021 +0100 +++ gcc/final.cc 2024-11-06 11:02:40.406413277 +0100 @@ -3492,7 +3492,10 @@ output_asm_insn (const char *templ, rtx int letter = *p++; unsigned long opnum; char *endptr; + int letter2 = 0; + if (letter == 'c' && *p == 'c') + letter2 = *p++; opnum = strtoul (p, &endptr, 10); if (endptr == p) @@ -3506,7 +3509,7 @@ output_asm_insn (const char *templ, rtx output_address (VOIDmode, operands[opnum]); else if (letter == 'c') { - if (CONSTANT_ADDRESS_P (operands[opnum])) + if (letter2 == 'c' || CONSTANT_ADDRESS_P (operands[opnum])) output_addr_const (asm_out_file, operands[opnum]); else output_operand (operands[opnum], 'c'); --- gcc/doc/extend.texi.jj 2024-11-06 10:23:21.220727937 +0100 +++ gcc/doc/extend.texi 2024-11-06 11:09:46.433407349 +0100 @@ -12113,6 +12113,11 @@ The following table shows the modifiers @item @code{c} @tab Require a constant operand and print the constant expression with no punctuation. @tab @code{%c0} +@item @code{cc} +@tab Like @samp{%c} except try harder to print it with no punctuation. +@samp{%c} can e.g.@: fail to print constant addresses in position independent code on +some architectures. +@tab @code{%cc0} @item @code{n} @tab Like @samp{%c} except that the value of the constant is negated before printing. @tab @code{%n0} --- gcc/doc/md.texi.jj 2024-11-06 10:30:09.884948601 +0100 +++ gcc/doc/md.texi 2024-11-06 11:12:51.893792814 +0100 @@ -1510,6 +1510,13 @@ This constraint, allowed only in input o pattern defines specific function or variable symbol. The constraint shouldn't be mixed with other constraints on the same operand and the operand should be address of a function or non-automatic variable. +Best used with the @samp{cc} modifier when printing the operand, so that +even in position independent code it prints as a label. + +@smallexample +void foo (void); +asm (".globl %cc0; %cc0: ret" : : ":" (foo)); +@end smallexample @cindex other register constraints @cindex extensible constraints --- gcc/testsuite/c-c++-common/toplevel-asm-4.c.jj 2024-11-06 10:30:09.888948544 +0100 +++ gcc/testsuite/c-c++-common/toplevel-asm-4.c 2024-11-06 11:14:14.553627513 +0100 @@ -1,9 +1,8 @@ /* PR c/41045 */ /* { dg-do compile } */ /* { dg-options "-O0" } */ -/* { dg-additional-options "-fno-pie" { target pie } } */ -int v[42], w; +extern int v[42], w; void foo (void); -asm ("# %c0: %c1:" :: ":" (foo), ":" (v), ":" (&w)); +asm ("# %cc0: %cc1:" :: ":" (foo), ":" (v), ":" (&w)); --- gcc/testsuite/c-c++-common/toplevel-asm-6.c.jj 2024-11-06 11:13:44.342053423 +0100 +++ gcc/testsuite/c-c++-common/toplevel-asm-6.c 2024-11-06 11:14:27.548444315 +0100 @@ -0,0 +1,9 @@ +/* PR c/41045 */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-fPIC" { target fpic } } */ + +extern int v[42], w; +void foo (void); + +asm ("# %cc0: %cc1:" :: ":" (foo), ":" (v), ":" (&w));