diff mbox series

inline-asm: Add support for cc operand modifier

Message ID ZytIn0tLL78UOCgE@tucnak
State New
Headers show
Series inline-asm: Add support for cc operand modifier | expand

Commit Message

Jakub Jelinek Nov. 6, 2024, 10:44 a.m. UTC
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.

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.


	Jakub

Comments

Richard Biener Nov. 6, 2024, 2:07 p.m. UTC | #1
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
> 
>
diff mbox series

Patch

--- 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));