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)

Reply via email to