* gcc.dg/i386-cpuid.h (bit_CMOV): Define.
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Feb 2004 17:12:20 +0000 (17:12 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Feb 2004 17:12:20 +0000 (17:12 +0000)
(i386_cpuid): No need to test if cpuid is available on AMD64.
Fix assembly, so that it works onboth i386 and AMD64.
* gcc.dg/i386-sse-6.c: Include stdio.h, stdlib.h and string.h.
(vecInLong): Fix s[] member type to unsigned int.
(vecInWord): Remove type.
(mmx_tests, sse_tests, dump64_16, dump64_32, dump64_64): Remove.
(a64, b64, c64, d64, e64): Remove.
(main): Pass if CPU has no MMX, SSE, SSE2 or CMOV support.
Remove unused variable.  Remove initialization of removed variables.
Don't call mmx_tests nor sse_tests.
(reference_mmx, reference_sse): Remove.
(check): Add return stmt.
* gcc.dg/i386-sse-7.c: New test.
* gcc.dg/i386-mmx-4.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@77955 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/i386-cpuid.h
gcc/testsuite/gcc.dg/i386-mmx-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/i386-sse-6.c
gcc/testsuite/gcc.dg/i386-sse-7.c [new file with mode: 0644]

index 2f5a956..7529302 100644 (file)
@@ -1,3 +1,21 @@
+2004-02-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.dg/i386-cpuid.h (bit_CMOV): Define.
+       (i386_cpuid): No need to test if cpuid is available on AMD64.
+       Fix assembly, so that it works onboth i386 and AMD64.
+       * gcc.dg/i386-sse-6.c: Include stdio.h, stdlib.h and string.h.
+       (vecInLong): Fix s[] member type to unsigned int.
+       (vecInWord): Remove type.
+       (mmx_tests, sse_tests, dump64_16, dump64_32, dump64_64): Remove.
+       (a64, b64, c64, d64, e64): Remove.
+       (main): Pass if CPU has no MMX, SSE, SSE2 or CMOV support.
+       Remove unused variable.  Remove initialization of removed variables.
+       Don't call mmx_tests nor sse_tests.
+       (reference_mmx, reference_sse): Remove.
+       (check): Add return stmt.
+       * gcc.dg/i386-sse-7.c: New test.
+       * gcc.dg/i386-mmx-4.c: New test.
+
 2004-02-17  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
 
        * g++.dg/tc1/dr176.C: Add missing semicolon (typo).
index f8e72db..dc300e4 100644 (file)
@@ -2,6 +2,7 @@
    Used by 20020523-2.c and i386-sse-6.c, and possibly others.  */
 /* Plagarized from 20020523-2.c.  */
 
+#define bit_CMOV (1 << 15)
 #define bit_MMX (1 << 23)
 #define bit_SSE (1 << 25)
 #define bit_SSE2 (1 << 26)
@@ -17,27 +18,39 @@ i386_cpuid (void)
 {
   int fl1, fl2;
 
-  /* See if we can use cpuid.  */
+#ifndef __x86_64__
+  /* See if we can use cpuid.  On AMD64 we always can.  */
   __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
           "pushl %0; popfl; pushfl; popl %0; popfl"
           : "=&r" (fl1), "=&r" (fl2)
           : "i" (0x00200000));
   if (((fl1 ^ fl2) & 0x00200000) == 0)
     return (0);
+#endif
 
   /* Host supports cpuid.  See if cpuid gives capabilities, try
      CPUID(0).  Preserve %ebx and %ecx; cpuid insn clobbers these, we
      don't need their CPUID values here, and %ebx may be the PIC
      register.  */
-  __asm__ ("push %%ecx ; push %%ebx ; cpuid ; pop %%ebx ; pop %%ecx"
+#ifdef __x86_64__
+  __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
+          : "=a" (fl1) : "0" (0) : "rdx", "cc");
+#else
+  __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
           : "=a" (fl1) : "0" (0) : "edx", "cc");
+#endif
   if (fl1 == 0)
     return (0);
 
   /* Invoke CPUID(1), return %edx; caller can examine bits to
      determine what's supported.  */
-  __asm__ ("push %%ecx ; push %%ebx ; cpuid ; pop %%ebx ; pop %%ecx" : "=d" (fl2) : "a" (1) : "cc");
+#ifdef __x86_64__
+  __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
+          : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
+#else
+  __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
+          : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
+#endif
 
   return fl2;
 }
-
diff --git a/gcc/testsuite/gcc.dg/i386-mmx-4.c b/gcc/testsuite/gcc.dg/i386-mmx-4.c
new file mode 100644 (file)
index 0000000..071baf7
--- /dev/null
@@ -0,0 +1,245 @@
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mmmx" } */
+#include <mmintrin.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "i386-cpuid.h"
+
+#ifndef NOINLINE
+#define NOINLINE __attribute__ ((noinline))
+#endif
+
+#define SHIFT (4)
+
+typedef union {
+  __m64 v;
+  unsigned char c[8];
+  unsigned short int s[4];
+  unsigned long long t;
+  unsigned int u[2];
+}vecInWord;
+
+void mmx_tests (void) NOINLINE;
+void dump64_16 (char *, char *, vecInWord);
+void dump64_32 (char *, char *, vecInWord);
+void dump64_64 (char *, char *, vecInWord);
+int check (const char *, const char *[]);
+
+char buf[8000];
+char comparison[8000];
+static int errors = 0;
+
+vecInWord a64, b64, c64, d64, e64;
+__m64 m64_16, s64, m64_32, m64_64;
+
+const char *reference_mmx[] = {
+  "_mm_srai_pi16 0012 0012 0012 0012 \n",
+  "_mm_sra_pi16 0012 0012 0012 0012 \n",
+  "_mm_srai_pi32 00123456 00123456 \n",
+  "_mm_sra_pi32 00123456 00123456 \n",
+  "_mm_srli_pi16 0012 0012 0012 0012 \n",
+  "_mm_srl_pi16 0012 0012 0012 0012 \n",
+  "_mm_srli_pi32 00123456 00123456 \n",
+  "_mm_srl_pi32 00123456 00123456 \n",
+  "_mm_srli_si64 00123456789abcde\n",
+  "_mm_srl_si64 00123456789abcde\n",
+  "_mm_slli_pi16 1230 1230 1230 1230 \n",
+  "_mm_sll_pi16 1230 1230 1230 1230 \n",
+  "_mm_slli_pi32 12345670 12345670 \n",
+  "_mm_sll_pi32 12345670 12345670 \n",
+  "_mm_slli_si64 123456789abcdef0\n",
+  "_mm_sll_si64 123456789abcdef0\n",
+  ""
+};
+
+int main()
+{
+  unsigned long cpu_facilities;
+
+  cpu_facilities = i386_cpuid ();
+
+  if ((cpu_facilities & bit_MMX) == 0)
+    exit (0);
+
+  d64.u[0]  = 0x01234567;
+  d64.u[1]  = 0x01234567;
+
+  m64_32 = d64.v;
+
+  e64.t  = 0x0123456789abcdefULL;
+
+  m64_64 = e64.v;
+
+  a64.s[0] = 0x0123;
+  a64.s[1] = 0x0123;
+  a64.s[2] = 0x0123;
+  a64.s[3] = 0x0123;
+
+  m64_16 = a64.v;
+
+  b64.s[0] = SHIFT;
+  b64.s[1] = 0;
+  b64.s[2] = 0;
+  b64.s[3] = 0;
+
+  s64 = b64.v;
+
+  if (cpu_facilities & bit_MMX)
+    {
+      mmx_tests();
+      check (buf, reference_mmx);
+#ifdef DEBUG
+      printf ("mmx testing:\n");
+      printf (buf);
+      printf ("\ncomparison:\n");
+      printf (comparison);
+#endif
+      buf[0] = '\0';
+    }
+
+  if (errors != 0)
+    abort ();
+  exit (0);
+}
+
+void NOINLINE
+mmx_tests (void)
+{
+  /* psraw */
+  c64.v = _mm_srai_pi16 (m64_16, SHIFT);
+  dump64_16 (buf, "_mm_srai_pi16", c64);
+  c64.v  = _mm_sra_pi16 (m64_16, s64);
+  dump64_16 (buf, "_mm_sra_pi16", c64);
+
+  /* psrad */
+  c64.v  = _mm_srai_pi32 (m64_32, SHIFT);
+  dump64_32 (buf, "_mm_srai_pi32", c64);
+  c64.v = _mm_sra_pi32 (m64_32, s64);
+  dump64_32 (buf, "_mm_sra_pi32", c64);
+
+  /* psrlw */
+  c64.v = _mm_srli_pi16 (m64_16, SHIFT);
+  dump64_16 (buf, "_mm_srli_pi16", c64);
+  c64.v = _mm_srl_pi16 (m64_16, s64);
+  dump64_16 (buf, "_mm_srl_pi16", c64);
+
+  /* psrld */
+  c64.v = _mm_srli_pi32 (m64_32, SHIFT);
+  dump64_32 (buf, "_mm_srli_pi32", c64);
+  c64.v = _mm_srl_pi32 (m64_32, s64);
+  dump64_32 (buf, "_mm_srl_pi32", c64);
+
+  /* psrlq */
+  c64.v = _mm_srli_si64 (m64_64, SHIFT);
+  dump64_64 (buf, "_mm_srli_si64", c64);
+  c64.v = _mm_srl_si64 (m64_64, s64);
+  dump64_64 (buf, "_mm_srl_si64", c64);
+
+  /* psllw */
+  c64.v = _mm_slli_pi16 (m64_16, SHIFT);
+  dump64_16 (buf, "_mm_slli_pi16", c64);
+  c64.v = _mm_sll_pi16 (m64_16, s64);
+  dump64_16 (buf, "_mm_sll_pi16", c64);
+
+  /* pslld */
+  c64.v = _mm_slli_pi32 (m64_32, SHIFT);
+  dump64_32 (buf, "_mm_slli_pi32", c64);
+  c64.v = _mm_sll_pi32 (m64_32, s64);
+  dump64_32 (buf, "_mm_sll_pi32", c64);
+
+  /* psllq */
+  c64.v = _mm_slli_si64 (m64_64, SHIFT);
+  dump64_64 (buf, "_mm_slli_si64", c64);
+  c64.v = _mm_sll_si64 (m64_64, s64);
+  dump64_64 (buf, "_mm_sll_si64", c64);
+}
+
+void
+dump64_16 (char *buf, char *name, vecInWord x)
+{
+  int i;
+  char *p = buf + strlen (buf);
+
+  sprintf (p, "%s ", name);
+  p += strlen (p);
+
+  for (i=0; i<4; i++)
+    {
+      sprintf (p, "%4.4x ", x.s[i]);
+      p += strlen (p);
+    }
+  strcat (p, "\n");
+}
+
+void
+dump64_32 (char *buf, char *name, vecInWord x)
+{
+  int i;
+  char *p = buf + strlen (buf);
+
+  sprintf (p, "%s ", name);
+  p += strlen (p);
+
+  for (i=0; i<2; i++)
+    {
+      sprintf (p, "%8.8x ", x.u[i]);
+      p += strlen (p);
+    }
+  strcat (p, "\n");
+}
+
+void
+dump64_64 (char *buf, char *name, vecInWord x)
+{
+  char *p = buf + strlen (buf);
+
+  sprintf (p, "%s ", name);
+  p += strlen (p);
+
+  sprintf (p, "%16.16llx\n", x.t);
+}
+
+int
+check (const char *input, const char *reference[])
+{
+  int broken, i, j, len;
+  const char *p_input;
+  char *p_comparison;
+  int new_errors = 0;
+
+  p_comparison = &comparison[0];
+  p_input = input;
+
+  for (i = 0; *reference[i] != '\0'; i++)
+    {
+      broken = 0;
+      len = strlen (reference[i]);
+      for (j = 0; j < len; j++)
+       {
+         /* Ignore the terminating NUL characters at the end of every string in 'reference[]'.  */
+         if (!broken && *p_input != reference[i][j])
+           {
+             *p_comparison = '\0';
+             strcat (p_comparison, " >>> ");
+             p_comparison += strlen (p_comparison);
+             new_errors++;
+             broken = 1;
+           }
+         *p_comparison = *p_input;
+         p_comparison++;
+         p_input++;
+       }
+      if (broken)
+       {
+         *p_comparison = '\0';
+         strcat (p_comparison, "expected:\n");
+         strcat (p_comparison, reference[i]);
+         p_comparison += strlen (p_comparison);
+       }
+    }
+  *p_comparison = '\0';
+  strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ;
+  errors += new_errors;
+  return 0;
+}
index ca18132..6642891 100644 (file)
@@ -1,6 +1,9 @@
 /* { dg-do run { target i?86-*-* x86_64-*-* } } */
 /* { dg-options "-O2 -msse2" } */
 #include <xmmintrin.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include "i386-cpuid.h"
 
 #ifndef NOINLINE
 
 typedef union {
   __m128i v;
-  unsigned long s[4];
+  unsigned int s[4];
   unsigned short int t[8];
   unsigned long long u[2];
   unsigned char c[16];
 }vecInLong;
 
-typedef union {
-  __m64 v;
-  unsigned char c[8];
-  unsigned short int s[4];
-  unsigned long long t;
-  unsigned int u[2];
-}vecInWord;
-
-void mmx_tests (void) NOINLINE;
-void sse_tests (void) NOINLINE;
 void sse2_tests (void) NOINLINE;
-void dump64_16 (char *, char *, vecInWord);
-void dump64_32 (char *, char *, vecInWord);
-void dump64_64 (char *, char *, vecInWord);
 void dump128_16 (char *, char *, vecInLong);
 void dump128_32 (char *, char *, vecInLong);
 void dump128_64 (char *, char *, vecInLong);
@@ -42,35 +32,9 @@ char comparison[8000];
 static int errors = 0;
 
 vecInLong a128, b128, c128, d128, e128, f128;
-vecInWord a64, b64, c64, d64, e64;
 __m128i m128_16, m128_32, s128, m128_64, m128_128;
 __m64 m64_16, s64, m64_32, m64_64;
 
-const char *reference_mmx[] = {
-  "_mm_srai_pi16 0012 0012 0012 0012 \n",
-  "_mm_sra_pi16 0012 0012 0012 0012 \n",
-  "_mm_srai_pi32 00123456 00123456 \n",
-  "_mm_sra_pi32 00123456 00123456 \n",
-  "_mm_srli_pi16 0012 0012 0012 0012 \n",
-  "_mm_srl_pi16 0012 0012 0012 0012 \n",
-  "_mm_srli_pi32 00123456 00123456 \n",
-  "_mm_srl_pi32 00123456 00123456 \n",
-  "_mm_srli_si64 00123456789abcde\n",
-  "_mm_srl_si64 00123456789abcde\n",
-  "_mm_slli_pi16 1230 1230 1230 1230 \n",
-  "_mm_sll_pi16 1230 1230 1230 1230 \n",
-  "_mm_slli_pi32 12345670 12345670 \n",
-  "_mm_sll_pi32 12345670 12345670 \n",
-  "_mm_slli_si64 123456789abcdef0\n",
-  "_mm_sll_si64 123456789abcdef0\n",
-  ""
-};
-
-const char *reference_sse[] = {
-  "_mm_shuffle_pi16 0123 4567 89ab cdef \n",
-  ""
-};
-
 const char *reference_sse2[] = {
   "_mm_srai_epi16 0012 0012 0012 0012 0012 0012 0012 0012 \n",
   "_mm_sra_epi16 0012 0012 0012 0012 0012 0012 0012 0012 \n",
@@ -98,12 +62,13 @@ const char *reference_sse2[] = {
 
 int main()
 {
-  unsigned long *p;
   unsigned long cpu_facilities;
 
   cpu_facilities = i386_cpuid ();
 
-  if (!cpu_facilities) /* If host has no vector support, pass.  */
+  if ((cpu_facilities & (bit_MMX | bit_SSE | bit_SSE2 | bit_CMOV))
+      != (bit_MMX | bit_SSE | bit_SSE2 | bit_CMOV))
+    /* If host has no vector support, pass.  */
     exit (0);
 
   a128.s[0] = 0x01234567;
@@ -136,22 +101,6 @@ int main()
 
   m128_128 = e128.v;
 
-  d64.u[0]  = 0x01234567;
-  d64.u[1]  = 0x01234567;
-
-  m64_32 = d64.v;
-
-  e64.t  = 0x0123456789abcdefULL;
-
-  m64_64 = e64.v;
-
-  a64.s[0] = 0x0123;
-  a64.s[1] = 0x0123;
-  a64.s[2] = 0x0123;
-  a64.s[3] = 0x0123;
-
-  m64_16 = a64.v;
-
   b128.s[0] = SHIFT;
   b128.s[1] = 0;
   b128.s[2] = 0;
@@ -159,39 +108,6 @@ int main()
 
   s128 = b128.v;
 
-  b64.s[0] = SHIFT;
-  b64.s[1] = 0;
-  b64.s[2] = 0;
-  b64.s[3] = 0;
-
-  s64 = b64.v;
-
-  if (cpu_facilities & bit_MMX)
-    {
-      mmx_tests();
-      check (buf, reference_mmx);
-#ifdef DEBUG
-      printf ("mmx testing:\n");
-      printf (buf);
-      printf ("\ncomparison:\n");
-      printf (comparison);
-#endif
-      buf[0] = '\0';
-    }
-
-  if (cpu_facilities & bit_SSE)
-    {
-      sse_tests();
-      check (buf, reference_sse);
-#ifdef DEBUG
-      printf ("sse testing:\n");
-      printf (buf);
-      printf ("\ncomparison:\n");
-      printf (comparison);
-#endif
-      buf[0] = '\0';
-    }
-
   if (cpu_facilities & bit_SSE2)
     {
       sse2_tests();
@@ -211,66 +127,6 @@ int main()
 }
 
 void NOINLINE
-mmx_tests (void)
-{
-  /* psraw */
-  c64.v = _mm_srai_pi16 (m64_16, SHIFT);
-  dump64_16 (buf, "_mm_srai_pi16", c64);
-  c64.v  = _mm_sra_pi16 (m64_16, s64);
-  dump64_16 (buf, "_mm_sra_pi16", c64);
-
-  /* psrad */
-  c64.v  = _mm_srai_pi32 (m64_32, SHIFT);
-  dump64_32 (buf, "_mm_srai_pi32", c64);
-  c64.v = _mm_sra_pi32 (m64_32, s64);
-  dump64_32 (buf, "_mm_sra_pi32", c64);
-
-  /* psrlw */
-  c64.v = _mm_srli_pi16 (m64_16, SHIFT);
-  dump64_16 (buf, "_mm_srli_pi16", c64);
-  c64.v = _mm_srl_pi16 (m64_16, s64);
-  dump64_16 (buf, "_mm_srl_pi16", c64);
-
-  /* psrld */
-  c64.v = _mm_srli_pi32 (m64_32, SHIFT);
-  dump64_32 (buf, "_mm_srli_pi32", c64);
-  c64.v = _mm_srl_pi32 (m64_32, s64);
-  dump64_32 (buf, "_mm_srl_pi32", c64);
-
-  /* psrlq */
-  c64.v = _mm_srli_si64 (m64_64, SHIFT);
-  dump64_64 (buf, "_mm_srli_si64", c64);
-  c64.v = _mm_srl_si64 (m64_64, s64);
-  dump64_64 (buf, "_mm_srl_si64", c64);
-
-  /* psllw */
-  c64.v = _mm_slli_pi16 (m64_16, SHIFT);
-  dump64_16 (buf, "_mm_slli_pi16", c64);
-  c64.v = _mm_sll_pi16 (m64_16, s64);
-  dump64_16 (buf, "_mm_sll_pi16", c64);
-
-  /* pslld */
-  c64.v = _mm_slli_pi32 (m64_32, SHIFT);
-  dump64_32 (buf, "_mm_slli_pi32", c64);
-  c64.v = _mm_sll_pi32 (m64_32, s64);
-  dump64_32 (buf, "_mm_sll_pi32", c64);
-
-  /* psllq */
-  c64.v = _mm_slli_si64 (m64_64, SHIFT);
-  dump64_64 (buf, "_mm_slli_si64", c64);
-  c64.v = _mm_sll_si64 (m64_64, s64);
-  dump64_64 (buf, "_mm_sll_si64", c64);
-}
-
-void NOINLINE
-sse_tests (void)
-{
-  /* pshufw */
-  c64.v = _mm_shuffle_pi16 (m64_64, 0x1b);
-  dump64_16 (buf, "_mm_shuffle_pi16", c64);
-}
-
-void NOINLINE
 sse2_tests (void)
 {
   /* psraw */
@@ -345,52 +201,6 @@ sse2_tests (void)
 }
 
 void
-dump64_16 (char *buf, char *name, vecInWord x)
-{
-  int i;
-  char *p = buf + strlen (buf);
-
-  sprintf (p, "%s ", name);
-  p += strlen (p);
-
-  for (i=0; i<4; i++)
-    {
-      sprintf (p, "%4.4x ", x.s[i]);
-      p += strlen (p);
-    }
-  strcat (p, "\n");
-}
-
-void
-dump64_32 (char *buf, char *name, vecInWord x)
-{
-  int i;
-  char *p = buf + strlen (buf);
-
-  sprintf (p, "%s ", name);
-  p += strlen (p);
-
-  for (i=0; i<2; i++)
-    {
-      sprintf (p, "%8.8x ", x.u[i]);
-      p += strlen (p);
-    }
-  strcat (p, "\n");
-}
-
-void
-dump64_64 (char *buf, char *name, vecInWord x)
-{
-  int i;
-  char *p = buf + strlen (buf);
-
-  sprintf (p, "%s ", name);
-  p += strlen (p);
-
-  sprintf (p, "%16.16llx\n", x.t);
-}
-
-void
 dump128_16 (char *buf, char *name, vecInLong x)
 {
   int i;
@@ -502,4 +312,5 @@ check (const char *input, const char *reference[])
   *p_comparison = '\0';
   strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ;
   errors += new_errors;
+  return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/i386-sse-7.c b/gcc/testsuite/gcc.dg/i386-sse-7.c
new file mode 100644 (file)
index 0000000..62e06e9
--- /dev/null
@@ -0,0 +1,139 @@
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -msse" } */
+#include <xmmintrin.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "i386-cpuid.h"
+
+#ifndef NOINLINE
+#define NOINLINE __attribute__ ((noinline))
+#endif
+
+#define SHIFT (4)
+
+typedef union {
+  __m64 v;
+  unsigned char c[8];
+  unsigned short int s[4];
+  unsigned long long t;
+  unsigned int u[2];
+}vecInWord;
+
+void sse_tests (void) NOINLINE;
+void dump64_16 (char *, char *, vecInWord);
+int check (const char *, const char *[]);
+
+char buf[8000];
+char comparison[8000];
+static int errors = 0;
+
+vecInWord c64, e64;
+__m64 m64_64;
+
+const char *reference_sse[] = {
+  "_mm_shuffle_pi16 0123 4567 89ab cdef \n",
+  ""
+};
+
+int main()
+{
+  unsigned long cpu_facilities;
+
+  cpu_facilities = i386_cpuid ();
+
+  if ((cpu_facilities & (bit_MMX | bit_SSE | bit_CMOV))
+      != (bit_MMX | bit_SSE | bit_CMOV))
+    /* If host has no vector support, pass.  */
+    exit (0);
+
+  e64.t  = 0x0123456789abcdefULL;
+
+  m64_64 = e64.v;
+
+  if (cpu_facilities & bit_SSE)
+    {
+      sse_tests();
+      check (buf, reference_sse);
+#ifdef DEBUG
+      printf ("sse testing:\n");
+      printf (buf);
+      printf ("\ncomparison:\n");
+      printf (comparison);
+#endif
+      buf[0] = '\0';
+    }
+
+  if (errors != 0)
+    abort ();
+  exit (0);
+}
+
+void NOINLINE
+sse_tests (void)
+{
+  /* pshufw */
+  c64.v = _mm_shuffle_pi16 (m64_64, 0x1b);
+  dump64_16 (buf, "_mm_shuffle_pi16", c64);
+}
+
+void
+dump64_16 (char *buf, char *name, vecInWord x)
+{
+  int i;
+  char *p = buf + strlen (buf);
+
+  sprintf (p, "%s ", name);
+  p += strlen (p);
+
+  for (i=0; i<4; i++)
+    {
+      sprintf (p, "%4.4x ", x.s[i]);
+      p += strlen (p);
+    }
+  strcat (p, "\n");
+}
+
+int
+check (const char *input, const char *reference[])
+{
+  int broken, i, j, len;
+  const char *p_input;
+  char *p_comparison;
+  int new_errors = 0;
+
+  p_comparison = &comparison[0];
+  p_input = input;
+
+  for (i = 0; *reference[i] != '\0'; i++)
+    {
+      broken = 0;
+      len = strlen (reference[i]);
+      for (j = 0; j < len; j++)
+       {
+         /* Ignore the terminating NUL characters at the end of every string in 'reference[]'.  */
+         if (!broken && *p_input != reference[i][j])
+           {
+             *p_comparison = '\0';
+             strcat (p_comparison, " >>> ");
+             p_comparison += strlen (p_comparison);
+             new_errors++;
+             broken = 1;
+           }
+         *p_comparison = *p_input;
+         p_comparison++;
+         p_input++;
+       }
+      if (broken)
+       {
+         *p_comparison = '\0';
+         strcat (p_comparison, "expected:\n");
+         strcat (p_comparison, reference[i]);
+         p_comparison += strlen (p_comparison);
+       }
+    }
+  *p_comparison = '\0';
+  strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ;
+  errors += new_errors;
+  return 0;
+}