]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR inline-asm/20314 (Bogus differ in number of alternatives error)
authorJakub Jelinek <jakub@redhat.com>
Thu, 10 Mar 2005 00:12:31 +0000 (01:12 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 10 Mar 2005 00:12:31 +0000 (01:12 +0100)
PR inline-asm/20314
* gimplify.c (gimplify_asm_expr): Handle input/output constraints
with multiple alternatives.

* stmt.c (parse_output_constraint): Fix a typo.

* gcc.dg/torture/pr20314-1.c: New test.
* gcc.dg/torture/pr20314-2.c: New test.

From-SVN: r96222

gcc/ChangeLog
gcc/gimplify.c
gcc/stmt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr20314-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr20314-2.c [new file with mode: 0644]

index 830d535fefed536a19a3416175078a993b51c369..a55928f06bbe2c003b057fff7c7898afcb34a350 100644 (file)
@@ -1,3 +1,11 @@
+2005-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR inline-asm/20314
+       * gimplify.c (gimplify_asm_expr): Handle input/output constraints
+       with multiple alternatives.
+
+       * stmt.c (parse_output_constraint): Fix a typo.
+
 2005-03-09  Bob Wilson  <bob.wilson@acm.org>
 
        * config/xtensa/xtensa.h (TRAMPOLINE_TEMPLATE): Use "no-transform"
index 93724a9e403a42da8aaa8a5b0e7df361d03aa385..341ca7baa3f5070adfc937f113443399640311a4 100644 (file)
@@ -3330,16 +3330,81 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
          char *p = xstrdup (constraint);
          p[0] = '=';
          TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
-         free (p);
 
          /* And add a matching input constraint.  */
          if (allows_reg)
            {
              sprintf (buf, "%d", i);
-             input = build_string (strlen (buf), buf);
+
+             /* If there are multiple alternatives in the constraint,
+                handle each of them individually.  Those that allow register
+                will be replaced with operand number, the others will stay
+                unchanged.  */
+             if (strchr (p, ',') != NULL)
+               {
+                 size_t len = 0, buflen = strlen (buf);
+                 char *beg, *end, *str, *dst;
+
+                 for (beg = p + 1;;)
+                   {
+                     end = strchr (beg, ',');
+                     if (end == NULL)
+                       end = strchr (beg, '\0');
+                     if ((size_t) (end - beg) < buflen)
+                       len += buflen + 1;
+                     else
+                       len += end - beg + 1;
+                     if (*end)
+                       beg = end + 1;
+                     else
+                       break;
+                   }
+
+                 str = alloca (len);
+                 for (beg = p + 1, dst = str;;)
+                   {
+                     const char *tem;
+                     bool mem_p, reg_p, inout_p;
+
+                     end = strchr (beg, ',');
+                     if (end)
+                       *end = '\0';
+                     beg[-1] = '=';
+                     tem = beg - 1;
+                     parse_output_constraint (&tem, i, 0, 0,
+                                              &mem_p, &reg_p, &inout_p);
+                     if (dst != str)
+                       *dst++ = ',';
+                     if (reg_p)
+                       {
+                         memcpy (dst, buf, buflen);
+                         dst += buflen;
+                       }
+                     else
+                       {
+                         if (end)
+                           len = end - beg;
+                         else
+                           len = strlen (beg);
+                         memcpy (dst, beg, len);
+                         dst += len;
+                       }
+                     if (end)
+                       beg = end + 1;
+                     else
+                       break;
+                   }
+                 *dst = '\0';
+                 input = build_string (dst - str, str);
+               }
+             else
+               input = build_string (strlen (buf), buf);
            }
          else
            input = build_string (constraint_len - 1, constraint + 1);
+
+         free (p);
+
          input = build_tree_list (build_tree_list (NULL_TREE, input),
                                   unshare_expr (TREE_VALUE (link)));
          ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
index 64e070b5a0a707bf5d578cd0c3a0455500e445a5..a23c23c0a6e47d0539a779593e90ae0a996d8d8e 100644 (file)
@@ -323,7 +323,7 @@ parse_output_constraint (const char **constraint_p, int operand_num,
   *is_inout = (*p == '+');
 
   /* Canonicalize the output constraint so that it begins with `='.  */
-  if (p != constraint || is_inout)
+  if (p != constraint || *is_inout)
     {
       char *buf;
       size_t c_len = strlen (constraint);
index 2f2a43171e8b34481f79674bc004cd44a3a05dda..53daac00c963c800f4d5f1e75e211670f790cc3c 100644 (file)
@@ -1,3 +1,9 @@
+2005-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR inline-asm/20314
+       * gcc.dg/torture/pr20314-1.c: New test.
+       * gcc.dg/torture/pr20314-2.c: New test.
+
 2005-03-09  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * gcc.dg/20050309-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr20314-1.c b/gcc/testsuite/gcc.dg/torture/pr20314-1.c
new file mode 100644 (file)
index 0000000..8a69c2d
--- /dev/null
@@ -0,0 +1,56 @@
+/* PR inline-asm/20314 */
+/* { dg-do compile { target i?86-*-* x86_64-*-* powerpc*-*-* ia64-*-* } } */
+
+int
+f1 (void)
+{
+  int x = 4, y;
+  __asm__ volatile ("" : "+r,r" (x), "=r,r" (y)
+                      : "%r,r" (x), "m,r" (8), "r,r" (2));
+  return x;
+}
+
+int
+f2 (void)
+{
+  int x = 4, y;
+  __asm__ volatile ("" : "=r,r" (x), "=r,r" (y)
+                      : "%0,0" (x), "m,r" (8), "r,r" (2));
+  return x;
+}
+
+int
+f3 (void)
+{
+  int x = 4, y;
+  __asm__ volatile ("" : "+r,r" (x), "=r,r" (y)
+                      : "%m,r" (8), "r,r" (2));
+  return x;
+}
+
+int
+f4 (void)
+{
+  int x = 4, y;
+  __asm__ volatile ("" : "+r" (x), "=r" (y)
+                      : "r" (x), "r" (8), "r" (2));
+  return x;
+}
+
+int
+f5 (void)
+{
+  int x = 4, y;
+  __asm__ volatile ("" : "=r" (x), "=r" (y)
+                      : "0" (x), "r" (8), "r" (2));
+  return x;
+}
+
+int
+f6 (void)
+{
+  int x = 4, y;
+  __asm__ volatile ("" : "+r" (x), "=r" (y)
+                      : "r" (8), "r" (2));
+  return x;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr20314-2.c b/gcc/testsuite/gcc.dg/torture/pr20314-2.c
new file mode 100644 (file)
index 0000000..ad1b8f9
--- /dev/null
@@ -0,0 +1,47 @@
+/* PR inline-asm/20314 */
+/* { dg-do compile { target { x86_64-*-* && lp64 } } } */
+/* { dg-do compile { target ia64-*-* powerpc*-*-* } } */
+
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void
+f1 (void)
+{
+  __asm__ volatile (""
+                   : [a] "+r" (a), [b] "+r" (b), [c] "+r" (c), [d] "+r" (d),
+                     [e] "+r" (e), [f] "+r" (f), [g] "+r" (g), [h] "+r" (h),
+                     [i] "+r" (i), [j] "+r" (j), [k] "+r" (k), [l] "+r" (l));
+}
+
+void
+f2 (void)
+{
+  __asm__ volatile (""
+                   : [a] "+r,m" (a), [b] "+r,m" (b), [c] "+r,m" (c), [d] "+r,m" (d),
+                     [e] "+r,m" (e), [f] "+r,m" (f), [g] "+r,m" (g), [h] "+r,m" (h),
+                     [i] "+r,m" (i), [j] "+r,m" (j), [k] "+r,m" (k), [l] "+r,m" (l));
+}
+
+void
+f3 (void)
+{
+  __asm__ volatile (""
+                   : [a] "=r" (a), [b] "=r" (b), [c] "=r" (c), [d] "=r" (d),
+                     [e] "=r" (e), [f] "=r" (f), [g] "=r" (g), [h] "=r" (h),
+                     [i] "=r" (i), [j] "=r" (j), [k] "=r" (k), [l] "=r" (l)
+                   : "[a]" (a), "[b]" (b), "[c]" (c), "[d]" (d),
+                     "[e]" (e), "[f]" (f), "[g]" (g), "[h]" (h),
+                     "[i]" (i), "[j]" (j), "[k]" (k), "[l]" (l));
+}
+
+void
+f4 (void)
+{
+  __asm__ volatile (""
+                   : [a] "=r,m" (a), [b] "=r,m" (b), [c] "=r,m" (c), [d] "=r,m" (d),
+                     [e] "=r,m" (e), [f] "=r,m" (f), [g] "=r,m" (g), [h] "=r,m" (h),
+                     [i] "=r,m" (i), [j] "=r,m" (j), [k] "=r,m" (k), [l] "=r,m" (l)
+                   : "[a],m" (a), "[b],m" (b), "[c],m" (c), "[d],m" (d),
+                     "[e],m" (e), "[f],m" (f), "[g],m" (g), "[h],m" (h),
+                     "[i],m" (i), "[j],m" (j), "[k],m" (k), "[l],m" (l));
+}