diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-12-18 11:50:26 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2024-12-18 11:50:26 +0100 |
commit | 35c4a383d6d8f7a9a094d364201daf0d098e4f42 (patch) | |
tree | 3effd0285aae9c24528c30ce4712c70536220968 /gcc | |
parent | 74d6a676034b3ab20c387f12f19f5597e4f1c9fa (diff) | |
download | gcc-35c4a383d6d8f7a9a094d364201daf0d098e4f42.zip gcc-35c4a383d6d8f7a9a094d364201daf0d098e4f42.tar.gz gcc-35c4a383d6d8f7a9a094d364201daf0d098e4f42.tar.bz2 |
inline-asm: Add - constraint modifier support for toplevel extended asm [PR41045]
The following patch adds - constraint modifier support (only in toplevel asms),
which one can use to allow i, s and n constraint to accept SYMBOL_REFs
even with -fpic.
So, the recommended way mark toplevel asm as defining some symbol
would be ":" constraint (usually with cc modifier in the pattern), while
to mark toplevel asm as using some symbol (again, either function or
variable), one would use "-s" constraint again with address of that function
or variable.
2024-12-18 Jakub Jelinek <jakub@redhat.com>
PR c/41045
gcc/
* stmt.cc (parse_output_constraint, parse_input_constraint): Handle
- modifier.
* recog.h (raw_constraint_p): Declare.
* recog.cc (raw_constraint_p): New variable.
(asm_operand_ok, constrain_operands): Handle - modifier.
* common.md (i, s, n): For raw_constraint_p don't require
LEGITIMATE_PIC_OPERAND_P.
* doc/md.texi: Document - constraint modifier.
gcc/c/
* c-typeck.cc (build_asm_expr): Reject - constraint modifier inside
of a function.
gcc/cp/
* semantics.cc (finish_asm_stmt): Reject - constraint modifier inside
of a function.
gcc/testsuite/
* c-c++-common/toplevel-asm-4.c: Add missing %cc2 use in template, add
bar, x, &y operands with "-i" and "-s" constraints.
(x, y): New variables.
(bar): Declare.
* c-c++-common/toplevel-asm-7.c: New test.
* c-c++-common/toplevel-asm-8.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c/c-typeck.cc | 10 | ||||
-rw-r--r-- | gcc/common.md | 6 | ||||
-rw-r--r-- | gcc/cp/semantics.cc | 10 | ||||
-rw-r--r-- | gcc/doc/md.texi | 22 | ||||
-rw-r--r-- | gcc/recog.cc | 19 | ||||
-rw-r--r-- | gcc/recog.h | 3 | ||||
-rw-r--r-- | gcc/stmt.cc | 4 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/toplevel-asm-4.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/toplevel-asm-7.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/toplevel-asm-8.c | 13 |
10 files changed, 100 insertions, 7 deletions
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 7be645f..9756eda 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -12332,6 +12332,11 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, } } } + else if (output != error_mark_node && strstr (constraint, "-")) + { + error_at (loc, "%<-%> modifier used inside of a function"); + output = error_mark_node; + } TREE_VALUE (tail) = output; } @@ -12417,6 +12422,11 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, } } } + else if (input != error_mark_node && strstr (constraint, "-")) + { + error_at (loc, "%<-%> modifier used inside of a function"); + input = error_mark_node; + } TREE_VALUE (tail) = input; } diff --git a/gcc/common.md b/gcc/common.md index 6a2d453..3cefa93 100644 --- a/gcc/common.md +++ b/gcc/common.md @@ -92,13 +92,13 @@ (define_constraint "i" "Matches a general integer constant." (and (match_test "CONSTANT_P (op)") - (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)"))) + (match_test "!flag_pic || raw_constraint_p || LEGITIMATE_PIC_OPERAND_P (op)"))) (define_constraint "s" "Matches a symbolic integer constant." (and (match_test "CONSTANT_P (op)") (match_test "!CONST_SCALAR_INT_P (op)") - (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)"))) + (match_test "!flag_pic || raw_constraint_p || LEGITIMATE_PIC_OPERAND_P (op)"))) (define_constraint ":" "Defines a symbol." @@ -108,7 +108,7 @@ (define_constraint "n" "Matches a non-symbolic integer constant." (and (match_test "CONST_SCALAR_INT_P (op)") - (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)"))) + (match_test "!flag_pic || raw_constraint_p || LEGITIMATE_PIC_OPERAND_P (op)"))) (define_constraint "E" "Matches a floating-point constant." diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 948eb89..9912c5e 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -2255,6 +2255,11 @@ finish_asm_stmt (location_t loc, int volatile_p, tree string, } } } + else if (operand != error_mark_node && strstr (constraint, "-")) + { + error_at (loc, "%<-%> modifier used inside of a function"); + operand = error_mark_node; + } TREE_VALUE (t) = operand; } @@ -2383,6 +2388,11 @@ finish_asm_stmt (location_t loc, int volatile_p, tree string, } } } + else if (operand != error_mark_node && strstr (constraint, "-")) + { + error_at (loc, "%<-%> modifier used inside of a function"); + operand = error_mark_node; + } TREE_VALUE (t) = operand; } diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 0ed1bc1..0457bb5 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -1889,6 +1889,28 @@ register preferences. @dots{}) @end smallexample @end ifset + +@cindex @samp{-} in constraint +@item - +Says that the selected following constraints within the same alternative +should be matched differently. Normally in PIC code symbolic operands +in constraints like @samp{i}, @samp{s} or @samp{n} are not allowed at all +or severely restricted. The @samp{-} modifier, which is only allowed +outside of functions, allows symbolic operands even in PIC code. This +modifier is usually used together with the @code{cc} operand modifier. + +@smallexample +extern void foo (void), bar (void); +int v; +extern int w; +asm (".globl %cc0, %cc2; .text; %cc0: call %cc1; ret; .data; %cc2: .word %cc3" + :: ":" (foo), "-s" (&bar), ":" (&w), "-i" (&v)); +@end smallexample + +This asm declaration tells the compiler it defines function @code{foo} and +variable @code{w} and uses function @code{bar} and variable @code{v}. This +will compile even with PIC, but it is up to the user to ensure it will +assemble correctly and have the expected behavior. @end table @node Machine Constraints diff --git a/gcc/recog.cc b/gcc/recog.cc index d1811f3..f4f1a6b 100644 --- a/gcc/recog.cc +++ b/gcc/recog.cc @@ -86,6 +86,9 @@ static operand_alternative asm_op_alt[MAX_RECOG_OPERANDS int which_alternative; +/* True for inline asm operands with - constraint modifier. */ +bool raw_constraint_p; + /* Nonzero after end of reload pass. Set to 1 or 0 by toplev.cc. Controls the significance of (SUBREG (MEM)). */ @@ -2287,6 +2290,7 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints) switch (c) { case ',': + raw_constraint_p = false; constraint++; continue; @@ -2337,6 +2341,11 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints) result = 1; break; + case '-': + raw_constraint_p = true; + constraint++; + continue; + case '<': case '>': /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed @@ -2394,8 +2403,12 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints) constraint++; while (--len && *constraint && *constraint != ','); if (len) - return 0; + { + raw_constraint_p = false; + return 0; + } } + raw_constraint_p = false; /* For operands without < or > constraints reject side-effects. */ if (AUTO_INC_DEC && !incdec_ok && result && MEM_P (op)) @@ -3189,6 +3202,9 @@ constrain_operands (int strict, alternative_mask alternatives) case ',': c = '\0'; break; + case '-': + raw_constraint_p = true; + break; case '#': /* Ignore rest of this alternative as far as @@ -3344,6 +3360,7 @@ constrain_operands (int strict, alternative_mask alternatives) } while (p += len, c); + raw_constraint_p = false; constraints[opno] = p; /* If this operand did not win somehow, this alternative loses. */ diff --git a/gcc/recog.h b/gcc/recog.h index 17ccdb6..b37af08 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -362,6 +362,9 @@ private: matched. */ extern int which_alternative; +/* True for inline asm operands with - constraint modifier. */ +extern bool raw_constraint_p; + /* The following vectors hold the results from insn_extract. */ struct recog_data_d diff --git a/gcc/stmt.cc b/gcc/stmt.cc index 6789eee..8ee4333 100644 --- a/gcc/stmt.cc +++ b/gcc/stmt.cc @@ -268,7 +268,7 @@ parse_output_constraint (const char **constraint_p, int operand_num, case 'E': case 'F': case 'G': case 'H': case 's': case 'i': case 'n': case 'I': case 'J': case 'K': case 'L': case 'M': - case 'N': case 'O': case 'P': case ',': + case 'N': case 'O': case 'P': case ',': case '-': break; case '0': case '1': case '2': case '3': case '4': @@ -363,7 +363,7 @@ parse_input_constraint (const char **constraint_p, int input_num, case 'E': case 'F': case 'G': case 'H': case 's': case 'i': case 'n': case 'I': case 'J': case 'K': case 'L': case 'M': - case 'N': case 'O': case 'P': case ',': + case 'N': case 'O': case 'P': case ',': case '-': break; case ':': diff --git a/gcc/testsuite/c-c++-common/toplevel-asm-4.c b/gcc/testsuite/c-c++-common/toplevel-asm-4.c index 2f100a6..392eef5 100644 --- a/gcc/testsuite/c-c++-common/toplevel-asm-4.c +++ b/gcc/testsuite/c-c++-common/toplevel-asm-4.c @@ -3,6 +3,8 @@ /* { dg-options "-O0" } */ extern int v[42], w; +int x[42], y; void foo (void); +void bar (void) {} -asm ("# %cc0: %cc1:" :: ":" (foo), ":" (v), ":" (&w)); +asm ("# %cc0: %cc1: %cc2: %cc3 %cc4 %cc5" :: ":" (foo), ":" (v), ":" (&w), "-i" (bar), "-s" (x), "-s" (&y)); diff --git a/gcc/testsuite/c-c++-common/toplevel-asm-7.c b/gcc/testsuite/c-c++-common/toplevel-asm-7.c new file mode 100644 index 0000000..ed2603f --- /dev/null +++ b/gcc/testsuite/c-c++-common/toplevel-asm-7.c @@ -0,0 +1,16 @@ +/* PR c/41045 */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-fpic" { target fpic } } */ + +struct S { char a; long long b; int c; }; +enum E { E0, E1 = sizeof (struct S) + 15 }; +int v[42]; +void foo (void) {} + +asm ("# %0 %1 %2 %cc3 %cc4 %% %=" + :: "i" (sizeof (struct S)), + "i" (__builtin_offsetof (struct S, c)), + "i" (E1), + "-s" (foo), + "-i" (v)); diff --git a/gcc/testsuite/c-c++-common/toplevel-asm-8.c b/gcc/testsuite/c-c++-common/toplevel-asm-8.c new file mode 100644 index 0000000..3b8f471 --- /dev/null +++ b/gcc/testsuite/c-c++-common/toplevel-asm-8.c @@ -0,0 +1,13 @@ +/* PR c/41045 */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +void +foo (void) +{ + int m; + asm ("" : "=-m" (m)); /* { dg-error "'-' modifier used inside of a function" } */ + asm ("" : : "-m" (m)); /* { dg-error "'-' modifier used inside of a function" } */ + asm ("" : : "-i" (32)); /* { dg-error "'-' modifier used inside of a function" } */ + asm ("" : : "-s" (foo)); /* { dg-error "'-' modifier used inside of a function" } */ +} |