* gcc.dg/20020919-1.c: New test.
authorHans-Peter Nilsson <hp@axis.com>
Mon, 23 Sep 2002 12:21:04 +0000 (12:21 +0000)
committerHans-Peter Nilsson <hp@gcc.gnu.org>
Mon, 23 Sep 2002 12:21:04 +0000 (12:21 +0000)
From-SVN: r57438

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20020919-1.c [new file with mode: 0644]

index 19d87b3..4f95845 100644 (file)
@@ -1,3 +1,7 @@
+2002-09-23  Hans-Peter Nilsson  <hp@axis.com>
+
+       * gcc.dg/20020919-1.c: New test.
+
 2002-09-23  Mark Mitchell  <mark@codesourcery.com>
 
        * g++.dg/abi/bitfield6.C: New test.
diff --git a/gcc/testsuite/gcc.dg/20020919-1.c b/gcc/testsuite/gcc.dg/20020919-1.c
new file mode 100644 (file)
index 0000000..daf8858
--- /dev/null
@@ -0,0 +1,245 @@
+/* Copyright (C) 2002  Free Software Foundation.
+   by Hans-Peter Nilsson  <hp@axis.com>
+
+   Making sure that asm clobbers conflicting with asm-declared input
+   operands are detected: ``You may not write a clobber description in a
+   way that overlaps with an input or output operand''.
+
+   You must be this tall ---> fit two long longs in asm-declared registers
+   to enter this amusement.  */
+
+/* { dg-do compile { target alpha-*-* cris-*-* i?86-*-* mmix-*-* powerpc-*-* rs6000-*-* } } */
+/* { dg-options "-O2" } */
+
+/* Constructed examples; input/output (same register), output, input, and
+   input and output (different registers).  */
+
+/* The long longs are used to test overlap overlap for multi-register
+   registers.  REG2 and REG4 must be the second halves (defined as
+   higher-numbered parts) of REG1 and REG3 respectively when two registers
+   are needed.  */
+
+#if defined (__alpha__)
+# define REG1 "$1"
+# define REG2 "$2"
+#elif defined (__CRIS__)
+# define REG1 "r10"
+# define REG2 "r11"
+# define REG3 "r12"
+# define REG4 "r13"
+# define REG5 "r9"
+#elif defined (__i386__)
+# define REG1 "%eax"
+# define REG2 "%edx"
+# define REG3 "%ecx"
+# define REG4 "%ebx"
+#elif defined (__MMIX__)
+# define REG1 "$8"
+# define REG2 "$9"
+#elif defined (__powerpc__) || defined (__PPC__) || defined (__ppc__) \
+       || defined (__POWERPC__) || defined (PPC) || defined (_IBMR2)
+# define REG1 "6"
+# define REG2 "7"
+# define REG3 "8"
+# define REG4 "9"
+#endif
+
+/* For readability of the tests.  */
+#ifdef REG3
+# define REG1a REG1
+# define REG1b REG2
+# define REG2a REG3
+# define REG2b REG4
+#else
+# define REG1a REG1
+# define REG1b REG1
+# define REG2a REG2
+# define REG2b REG2
+#endif
+
+/* REG5 is just another reg if there is one; the difference to REG4 is to
+   keep the original set of registers for CRIS.  */
+#ifndef REG5
+#define REG5 REG2b
+#endif
+
+void *
+foo (void *p)
+{
+  register void *q asm (REG1) = p;
+  asm ("foo1 %0" : "=r" (q) : "0" (q) : REG1); /* { dg-error "conflict" } */
+  return q;
+}
+
+void *
+nfoo (void *p)
+{
+  register void *q asm (REG1) = p;
+  asm ("foo1 %0" : "=r" (q) : "0" (q) : REG2);
+  return q;
+}
+
+long long
+foolla (long long llp)
+{
+  register long long ll asm (REG1a) = llp;
+  asm ("foo1a %0" : "=r" (ll) : "0" (ll) : REG1a); /* { dg-error "conflict" } */
+  return ll;
+}
+
+long long
+nfoolla (long long llp)
+{
+  register long long ll asm (REG1a) = llp;
+  asm ("foo1a %0" : "=r" (ll) : "0" (ll) : REG2a);
+  return ll;
+}
+
+long long
+foollb (long long llp)
+{
+  register long long ll asm (REG1a) = llp;
+  asm ("foo1b %0" : "=r" (ll) : "0" (ll) : REG1b); /* { dg-error "conflict" } */
+  return ll;
+}
+
+void *
+bar (void *p)
+{
+  register void *q asm (REG1);
+  register void *w asm (REG2) = p;
+  asm ("bar1 %1,%0" : "=r" (q) : "r" (w) : REG1); /* { dg-error "conflict" } */
+  return q;
+}
+
+long long
+barlla (long long llp)
+{
+  register long long ll asm (REG1a);
+  register long long mm asm (REG2a) = llp;
+  asm ("bar1a %1,%0" : "=r" (ll) : "r" (mm) : REG1b); /* { dg-error "conflict" } */
+  return ll;
+}
+
+long long
+barllb (long long llp)
+{
+  register long long ll asm (REG1a);
+  register long long mm asm (REG2a) = llp;
+  asm ("bar1b %1,%0" : "=r" (ll) : "r" (mm) : REG2b); /* { dg-error "conflict" } */
+  return ll;
+}
+
+void *
+foobar (void *p)
+{
+  register void *q asm (REG1);
+  register void *w asm (REG2) = p;
+  asm ("foobar1 %1,%0" : "=r" (q) : "r" (w) : REG2); /* { dg-error "conflict" } */
+  return q;
+}
+
+void *
+nfoobar (void *p)
+{
+  register void *q asm (REG1);
+  register void *w = p;
+  asm ("foobar1 %1,%0" : "=r" (q) : "r" (w) : REG2);
+  return q;
+}
+
+long long
+foobarlla (long long llp)
+{
+  register long long ll asm (REG1a);
+  register long long mm asm (REG2a) = llp;
+  asm ("foobar1a %1,%0" : "=r" (ll) : "r" (mm) : REG1b); /* { dg-error "conflict" } */
+  return ll;
+}
+
+long long
+nfoobarlla (long long llp)
+{
+  register long long ll asm (REG1a);
+  register long long mm = llp;
+  asm ("foobar1a %1,%0" : "=r" (ll) : "r" (mm) : REG2a);
+  return ll;
+}
+
+long long
+foobarllb (long long llp)
+{
+  register long long ll asm (REG1a);
+  register long long mm asm (REG2a) = llp;
+  asm ("foobar1b %1,%0" : "=r" (ll) : "r" (mm) : REG2b); /* { dg-error "conflict" } */
+  return ll;
+}
+
+long long
+nfoobarllb (long long llp)
+{
+  register long long ll asm (REG1a);
+  register long long mm = llp;
+  asm ("foobar1b %1,%0" : "=r" (ll) : "r" (mm) : REG2b);
+  return ll;
+}
+
+void *
+baz (void *p)
+{
+  register void *q asm (REG1);
+  register void *w asm (REG2) = p;
+  asm ("baz1 %1,%0" : "=r" (q) : "r" (w) : REG1, REG2); /* { dg-error "conflict" } */
+  return q;
+}
+
+void *
+nbaz (void *p)
+{
+  register void *q;
+  register void *w = p;
+  asm ("baz1 %1,%0" : "=r" (q) : "r" (w) : REG1, REG2);
+  return q;
+}
+
+void *
+nbaz2 (void *p)
+{
+  register void *q asm (REG1);
+  register void *w asm (REG2) = p;
+  asm ("baz1 %1,%0" : "=r" (q) : "r" (w));
+  return q;
+}
+
+long long
+bazlla (long long llp)
+{
+  register long long ll asm (REG1a);
+  register long long mm asm (REG2a) = llp;
+  asm ("baz1a %1,%0" : "=r" (ll) : "r" (mm) : REG1a, REG2a); /* { dg-error "conflict" } */
+  return ll;
+}
+
+long long
+bazllb (long long llp)
+{
+  register long long ll asm (REG1a);
+  register long long mm asm (REG2a) = llp;
+  asm ("baz2a %1,%0" : "=r" (ll) : "r" (mm) : REG1b, REG2b); /* { dg-error "conflict" } */
+  return ll;
+}
+
+/* Real-world example of bug.  */
+
+struct stat;
+int
+_dl_stat (const char *file_name, struct stat *buf)
+{
+  register long a asm (REG1) = (long) file_name;
+  register long b asm (REG2) = (long) buf;
+
+  asm volatile ("movu.w %1,$r9\n\tbreak 13" : "=r" (a) : "g" (106), "0" (a), "r" (b) : REG1, REG5); /* { dg-error "conflict" } */
+  if (a >= 0)
+    return (int) a;
+  return (int) -1;
+}