1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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 "../../gcc.dg/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;
}
|