1/* { dg-do run } */
2/* { dg-options "-O2 -msse" } */
3/* { dg-require-effective-target sse } */
4
5#include "sse-check.h"
6
7#include <xmmintrin.h>
8#include <string.h>
9
10#define SHIFT (4)
11
12typedef union {
13  __m64 v;
14  unsigned char c[8];
15  unsigned short int s[4];
16  unsigned long long t;
17  unsigned int u[2];
18}vecInWord;
19
20void sse_tests (void) __attribute__((noinline));
21void dump64_16 (char *, char *, vecInWord);
22int check (const char *, const char *[]);
23
24char buf[8000];
25char comparison[8000];
26static int errors = 0;
27
28vecInWord c64, e64;
29__m64 m64_64;
30
31const char *reference_sse[] = {
32  "_mm_shuffle_pi16 0123 4567 89ab cdef \n",
33  ""
34};
35
36static void
37sse_test (void)
38{
39  e64.t  = 0x0123456789abcdefULL;
40
41  m64_64 = e64.v;
42
43  sse_tests();
44  check (buf, reference_sse);
45#ifdef DEBUG
46  printf ("sse testing:\n");
47  printf (buf);
48  printf ("\ncomparison:\n");
49  printf (comparison);
50#endif
51  buf[0] = '\0';
52
53  if (errors != 0)
54    abort ();
55}
56
57void __attribute__((noinline))
58sse_tests (void)
59{
60  /* pshufw */
61  c64.v = _mm_shuffle_pi16 (m64_64, 0x1b);
62  dump64_16 (buf, "_mm_shuffle_pi16", c64);
63}
64
65void
66dump64_16 (char *buf, char *name, vecInWord x)
67{
68  int i;
69  char *p = buf + strlen (buf);
70
71  sprintf (p, "%s ", name);
72  p += strlen (p);
73
74  for (i=0; i<4; i++)
75    {
76      sprintf (p, "%4.4x ", x.s[i]);
77      p += strlen (p);
78    }
79  strcat (p, "\n");
80}
81
82int
83check (const char *input, const char *reference[])
84{
85  int broken, i, j, len;
86  const char *p_input;
87  char *p_comparison;
88  int new_errors = 0;
89
90  p_comparison = &comparison[0];
91  p_input = input;
92
93  for (i = 0; *reference[i] != '\0'; i++)
94    {
95      broken = 0;
96      len = strlen (reference[i]);
97      for (j = 0; j < len; j++)
98	{
99	  /* Ignore the terminating NUL characters at the end of every string in 'reference[]'.  */
100	  if (!broken && *p_input != reference[i][j])
101	    {
102	      *p_comparison = '\0';
103	      strcat (p_comparison, " >>> ");
104	      p_comparison += strlen (p_comparison);
105	      new_errors++;
106	      broken = 1;
107	    }
108	  *p_comparison = *p_input;
109	  p_comparison++;
110	  p_input++;
111	}
112      if (broken)
113	{
114	  *p_comparison = '\0';
115	  strcat (p_comparison, "expected:\n");
116	  strcat (p_comparison, reference[i]);
117	  p_comparison += strlen (p_comparison);
118	}
119    }
120  *p_comparison = '\0';
121  strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ;
122  errors += new_errors;
123  return 0;
124}
125