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 #ifndef ESP_FLOAT
112 #define ESP_FLOAT 0.000001
113 #endif
114 #ifndef ESP_DOUBLE
115 #define ESP_DOUBLE 0.000001
116 #endif
117 #define CHECK_ARRAY(ARRAY, TYPE, FMT)                   \
118 static int                                              \
119 __attribute__((noinline, unused))                       \
120 checkV##ARRAY (const TYPE *v, const TYPE *e, int n)     \
121 {                                                       \
122   int i;                                                \
123   int err = 0;                                          \
124                                                         \
125   for (i = 0; i < n; i++)                               \
126     if (v[i] != e[i])                                   \
127       {                                                 \
128         err++;                                          \
129         PRINTF ("%i: " FMT " != " FMT "\n",             \
130                 i, v[i], e[i]);                 \
131       }                                                 \
132   return err;                                           \
133 }
134 
135 CHECK_ARRAY(c, char, "0x%hhx")
136 CHECK_ARRAY(s, short, "0x%hx")
137 CHECK_ARRAY(i, int, "0x%x")
138 CHECK_ARRAY(l, long long, "0x%llx")
139 CHECK_ARRAY(uc, unsigned char, "0x%hhx")
140 CHECK_ARRAY(us, unsigned short, "0x%hx")
141 CHECK_ARRAY(ui, unsigned int, "0x%x")
142 CHECK_ARRAY(ul, unsigned long long, "0x%llx")
143 
144 
145 
146 #define CHECK_FP_ARRAY(ARRAY, TYPE, ESP, FMT)                   \
147 static int                                              \
148 __attribute__((noinline, unused))                       \
149 checkV##ARRAY (const TYPE *v, const TYPE *e, int n)     \
150 {                                                       \
151   int i;                                                \
152   int err = 0;                                          \
153                                                         \
154   for (i = 0; i < n; i++)                               \
155     if (v[i] > (e[i] + (ESP)) || v[i] < (e[i] - (ESP))) \
156     if (e[i] != v[i])                                   \
157       {                                                 \
158         err++;                                          \
159         PRINTF ("%i: " FMT " != " FMT "\n",             \
160                 i, v[i], e[i]);                 \
161       }                                                 \
162   return err;                                           \
163 }
164 
165 CHECK_FP_ARRAY (d, double, ESP_DOUBLE, "%f")
166 CHECK_FP_ARRAY (f, float, ESP_FLOAT, "%f")
167 
168 #ifdef NEED_IEEE754_FLOAT
169 union ieee754_float
170 {
171    float d;
172    struct
173    {
174       unsigned long frac : 23;
175       unsigned exp : 8;
176       unsigned sign : 1;
177    } bits __attribute__((packed));
178 };
179 #endif
180 
181 #ifdef NEED_IEEE754_DOUBLE
182 union ieee754_double
183 {
184    double d;
185    struct
186    {
187       unsigned long frac1 : 32;
188       unsigned long frac0 : 20;
189       unsigned exp : 11;
190       unsigned sign : 1;
191    } bits __attribute__((packed));
192 };
193 #endif
194 
195 #define CHECK_FP_EXP(UINON_TYPE, VALUE_TYPE, ESP, FMT)		\
196 static int							\
197 __attribute__((noinline, unused))				\
198 check_fp_##UINON_TYPE (UINON_TYPE u, const VALUE_TYPE *v)	\
199 {								\
200   int i;							\
201   int err = 0;							\
202 								\
203   for (i = 0; i < ARRAY_SIZE (u.a); i++)			\
204     if (u.a[i] > (v[i] + (ESP)) || u.a[i] < (v[i] - (ESP)))	\
205       {								\
206 	err++;							\
207 	PRINTF ("%i: " FMT " != " FMT "\n",			\
208 		i, v[i], u.a[i]);				\
209       }								\
210   return err;							\
211 }
212 
213 CHECK_FP_EXP (union128, float, ESP_FLOAT, "%f")
214 #ifdef __SSE2__
215 CHECK_FP_EXP (union128d, double, ESP_DOUBLE, "%f")
216 #endif
217