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