On Fri, 22 Nov 2024, Jakub Jelinek wrote: > On Fri, Nov 22, 2024 at 12:01:21AM +0000, Joseph Myers wrote: > > On Mon, 18 Nov 2024, Jakub Jelinek wrote: > > > > > +@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 foo and > > > variable > > > +w and uses function bar and variable 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. > > > > That should be @code{foo}, @code{w}, @code{bar}, @code{v}. > > > > The C front-end changes in this patch are OK. > > Thanks, here is the adjusted patch.
The middle-end changes are OK. Richard. > 2024-11-21 Jakub Jelinek <ja...@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. > > --- gcc/stmt.cc.jj 2024-11-17 21:07:06.712510933 -1100 > +++ gcc/stmt.cc 2024-11-17 21:45:30.201294501 -1100 > @@ -269,7 +269,7 @@ parse_output_constraint (const char **co > 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': > @@ -364,7 +364,7 @@ parse_input_constraint (const char **con > 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 ':': > --- gcc/recog.h.jj 2024-08-15 09:23:26.981012468 -1100 > +++ gcc/recog.h 2024-11-17 22:26:47.190602347 -1100 > @@ -335,6 +335,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 > --- gcc/recog.cc.jj 2024-10-24 21:00:29.511767242 -1100 > +++ gcc/recog.cc 2024-11-17 23:16:00.654874432 -1100 > @@ -86,6 +86,9 @@ static operand_alternative asm_op_alt[MA > > 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)). */ > @@ -2300,6 +2303,7 @@ asm_operand_ok (rtx op, const char *cons > switch (c) > { > case ',': > + raw_constraint_p = false; > constraint++; > continue; > > @@ -2350,6 +2354,11 @@ asm_operand_ok (rtx op, const char *cons > result = 1; > break; > > + case '-': > + raw_constraint_p = true; > + constraint++; > + continue; > + > case '<': > case '>': > /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed > @@ -2407,8 +2416,12 @@ asm_operand_ok (rtx op, const char *cons > 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)) > @@ -3202,6 +3215,9 @@ constrain_operands (int strict, alternat > case ',': > c = '\0'; > break; > + case '-': > + raw_constraint_p = true; > + break; > > case '#': > /* Ignore rest of this alternative as far as > @@ -3357,6 +3373,7 @@ constrain_operands (int strict, alternat > } > while (p += len, c); > > + raw_constraint_p = false; > constraints[opno] = p; > /* If this operand did not win somehow, > this alternative loses. */ > --- gcc/common.md.jj 2024-11-17 21:07:06.712510933 -1100 > +++ gcc/common.md 2024-11-17 22:33:23.805858947 -1100 > @@ -92,13 +92,13 @@ (define_address_constraint "p" > (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 ":" > (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." > --- gcc/doc/md.texi.jj 2024-11-17 21:07:19.843326980 -1100 > +++ gcc/doc/md.texi 2024-11-17 23:43:12.301073998 -1100 > @@ -1889,6 +1889,28 @@ (define_insn "extendhisi2" > @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 > --- gcc/c/c-typeck.cc.jj 2024-11-17 21:07:06.000000000 -1100 > +++ gcc/c/c-typeck.cc 2024-11-17 22:17:13.935708652 -1100 > @@ -12281,6 +12281,11 @@ build_asm_expr (location_t loc, tree str > } > } > } > + 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; > } > @@ -12365,6 +12370,11 @@ build_asm_expr (location_t loc, tree str > } > } > } > + 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; > } > --- gcc/cp/semantics.cc.jj 2024-11-17 21:07:06.718510849 -1100 > +++ gcc/cp/semantics.cc 2024-11-17 22:24:24.469669093 -1100 > @@ -2255,6 +2255,11 @@ finish_asm_stmt (location_t loc, int vol > } > } > } > + 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; > } > @@ -2382,6 +2387,11 @@ finish_asm_stmt (location_t loc, int vol > } > } > } > + 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; > } > --- gcc/testsuite/c-c++-common/toplevel-asm-4.c.jj 2024-11-17 > 21:07:19.844326965 -1100 > +++ gcc/testsuite/c-c++-common/toplevel-asm-4.c 2024-11-17 > 23:41:10.340778042 -1100 > @@ -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)); > --- gcc/testsuite/c-c++-common/toplevel-asm-7.c.jj 2024-11-17 > 23:37:58.518458202 -1100 > +++ gcc/testsuite/c-c++-common/toplevel-asm-7.c 2024-11-17 > 23:39:01.531577774 -1100 > @@ -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)); > --- gcc/testsuite/c-c++-common/toplevel-asm-8.c.jj 2024-11-17 > 23:39:39.794043169 -1100 > +++ gcc/testsuite/c-c++-common/toplevel-asm-8.c 2024-11-17 > 23:51:53.656789127 -1100 > @@ -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" } */ > +} > > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)