https://gcc.gnu.org/g:74d6a676034b3ab20c387f12f19f5597e4f1c9fa

commit r15-6326-g74d6a676034b3ab20c387f12f19f5597e4f1c9fa
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Dec 18 11:49:11 2024 +0100

    inline-asm: Add support for cc operand modifier
    
    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-12-18  Jakub Jelinek  <ja...@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.

Diff:
---
 gcc/doc/extend.texi                         | 5 +++++
 gcc/doc/md.texi                             | 7 +++++++
 gcc/final.cc                                | 5 ++++-
 gcc/testsuite/c-c++-common/toplevel-asm-4.c | 5 ++---
 gcc/testsuite/c-c++-common/toplevel-asm-6.c | 9 +++++++++
 5 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index f045159963ed..773e487b8246 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -12141,6 +12141,11 @@ The following table shows the modifiers supported by 
all targets and their effec
 @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}
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 4a6509116840..0ed1bc121438 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -1510,6 +1510,13 @@ This constraint, allowed only in input operands, says 
the inline @code{asm}
 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
diff --git a/gcc/final.cc b/gcc/final.cc
index 184b71ccee66..ec7644c2535a 100644
--- a/gcc/final.cc
+++ b/gcc/final.cc
@@ -3493,7 +3493,10 @@ output_asm_insn (const char *templ, rtx *operands)
            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)
@@ -3507,7 +3510,7 @@ output_asm_insn (const char *templ, rtx *operands)
              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');
diff --git a/gcc/testsuite/c-c++-common/toplevel-asm-4.c 
b/gcc/testsuite/c-c++-common/toplevel-asm-4.c
index c9a2089fba53..2f100a65f426 100644
--- a/gcc/testsuite/c-c++-common/toplevel-asm-4.c
+++ b/gcc/testsuite/c-c++-common/toplevel-asm-4.c
@@ -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));
diff --git a/gcc/testsuite/c-c++-common/toplevel-asm-6.c 
b/gcc/testsuite/c-c++-common/toplevel-asm-6.c
new file mode 100644
index 000000000000..0b77ce584f4f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/toplevel-asm-6.c
@@ -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));

Reply via email to