1 #include <stdio.h>
2 
3 #define NO_WARN_X86_INTRINSICS 1
4 
5 #ifdef __ALTIVEC__
6 #include <xmmintrin.h>
7 
8 #ifdef __VSX_SSE2__
9 #include <emmintrin.h>
10 
11 typedef union
12 {
13   __m128i x;
14   char a[16];
15 } union128i_b;
16 
17 typedef union
18 {
19   __m128i x;
20   unsigned char a[16];
21 } union128i_ub;
22 
23 typedef union
24 {
25   __m128i x;
26   short a[8];
27 } union128i_w;
28 
29 typedef union
30 {
31   __m128i x;
32   unsigned short a[8];
33 } union128i_uw;
34 
35 typedef union
36 {
37   __m128i x;
38   int a[4];
39 } union128i_d;
40 
41 typedef union
42 {
43   __m128i x;
44   unsigned int a[4];
45 } union128i_ud;
46 
47 #if __VSX__
48 typedef union
49 {
50   __m128i x;
51   long long a[2];
52 } union128i_q;
53 
54 typedef union
55 {
56   __m128i x;
57   unsigned long long a[2];
58 } union128i_uq;
59 
60 
61 typedef union
62 {
63   __m128d x;
64   double a[2];
65 } union128d;
66 #endif
67 
68 #endif
69 typedef union
70 {
71   __m128  x;
72   float a[4];
73   int i[4];
74 } union128;
75 
76 #ifndef ARRAY_SIZE
77 #define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
78 #endif
79 
80 #ifdef DEBUG
81 #define PRINTF printf
82 #else
83 #define PRINTF(...)
84 #endif
85 
86 #define CHECK_EXP(UINON_TYPE, VALUE_TYPE, FMT)		\
87 static int						\
88 __attribute__((noinline, unused))			\
89 check_##UINON_TYPE (UINON_TYPE u, const VALUE_TYPE *v)	\
90 {							\
91   int i;						\
92   int err = 0;						\
93 							\
94   for (i = 0; i < ARRAY_SIZE (u.a); i++)		\
95     if (u.a[i] != v[i])					\
96       {							\
97 	err++;						\
98 	PRINTF ("%i: " FMT " != " FMT "\n",		\
99 		i, v[i], u.a[i]);			\
100       }							\
101   return err;						\
102 }
103 
104 #ifdef __VSX_SSE2__
105 CHECK_EXP (union128i_b, char, "%d")
106 CHECK_EXP (union128i_ub, unsigned char, "%d")
107 CHECK_EXP (union128i_w, short, "%d")
108 CHECK_EXP (union128i_uw, unsigned short, "%d")
109 CHECK_EXP (union128i_d, int, "0x%x")
110 CHECK_EXP (union128i_ud, unsigned int, "0x%x")
111 #ifdef __VSX__
112 CHECK_EXP (union128i_q, long long, "0x%llx")
113 CHECK_EXP (union128i_uq, unsigned long long, "0x%llx")
114 CHECK_EXP (union128d, double, "%f")
115 #endif
116 #endif
117 
118 CHECK_EXP (union128, float, "%f")
119 
120 #define ESP_FLOAT 0.000001
121 #define ESP_DOUBLE 0.000001
122 #define CHECK_ARRAY(ARRAY, TYPE, FMT)                   \
123 static int                                              \
124 __attribute__((noinline, unused))                       \
125 checkV##ARRAY (const TYPE *v, const TYPE *e, int n)     \
126 {                                                       \
127   int i;                                                \
128   int err = 0;                                          \
129                                                         \
130   for (i = 0; i < n; i++)                               \
131     if (v[i] != e[i])                                   \
132       {                                                 \
133         err++;                                          \
134         PRINTF ("%i: " FMT " != " FMT "\n",             \
135                 i, v[i], e[i]);                 \
136       }                                                 \
137   return err;                                           \
138 }
139 
140 CHECK_ARRAY(c, char, "0x%hhx")
141 CHECK_ARRAY(s, short, "0x%hx")
142 CHECK_ARRAY(i, int, "0x%x")
143 CHECK_ARRAY(l, long long, "0x%llx")
144 CHECK_ARRAY(uc, unsigned char, "0x%hhx")
145 CHECK_ARRAY(us, unsigned short, "0x%hx")
146 CHECK_ARRAY(ui, unsigned int, "0x%x")
147 CHECK_ARRAY(ul, unsigned long long, "0x%llx")
148 
149 
150 
151 #define CHECK_FP_ARRAY(ARRAY, TYPE, ESP, FMT)                   \
152 static int                                              \
153 __attribute__((noinline, unused))                       \
154 checkV##ARRAY (const TYPE *v, const TYPE *e, int n)     \
155 {                                                       \
156   int i;                                                \
157   int err = 0;                                          \
158                                                         \
159   for (i = 0; i < n; i++)                               \
160     if (v[i] > (e[i] + (ESP)) || v[i] < (e[i] - (ESP))) \
161     if (e[i] != v[i])                                   \
162       {                                                 \
163         err++;                                          \
164         PRINTF ("%i: " FMT " != " FMT "\n",             \
165                 i, v[i], e[i]);                 \
166       }                                                 \
167   return err;                                           \
168 }
169 
170 CHECK_FP_ARRAY (d, double, ESP_DOUBLE, "%f")
171 CHECK_FP_ARRAY (f, float, ESP_FLOAT, "%f")
172 
173 #ifdef NEED_IEEE754_FLOAT
174 union ieee754_float
175 {
176    float d;
177    struct
178    {
179       unsigned long frac : 23;
180       unsigned exp : 8;
181       unsigned sign : 1;
182    } bits __attribute__((packed));
183 };
184 #endif
185 
186 #ifdef NEED_IEEE754_DOUBLE
187 union ieee754_double
188 {
189    double d;
190    struct
191    {
192       unsigned long frac1 : 32;
193       unsigned long frac0 : 20;
194       unsigned exp : 11;
195       unsigned sign : 1;
196    } bits __attribute__((packed));
197 };
198 #endif
199 
200 #define CHECK_FP_EXP(UINON_TYPE, VALUE_TYPE, ESP, FMT)		\
201 static int							\
202 __attribute__((noinline, unused))				\
203 check_fp_##UINON_TYPE (UINON_TYPE u, const VALUE_TYPE *v)	\
204 {								\
205   int i;							\
206   int err = 0;							\
207 								\
208   for (i = 0; i < ARRAY_SIZE (u.a); i++)			\
209     if (u.a[i] > (v[i] + (ESP)) || u.a[i] < (v[i] - (ESP)))	\
210       {								\
211 	err++;							\
212 	PRINTF ("%i: " FMT " != " FMT "\n",			\
213 		i, v[i], u.a[i]);				\
214       }								\
215   return err;							\
216 }
217 
218 CHECK_FP_EXP (union128, float, ESP_FLOAT, "%f")
219 #ifdef __VSX_SSE2__
220 CHECK_FP_EXP (union128d, double, ESP_DOUBLE, "%f")
221 #endif
222 #endif /* __ALTIVEC__ */
223