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