1#include <stdio.h>
2#include <xmmintrin.h>
3
4#ifdef __SSE2__
5#include <emmintrin.h>
6
7typedef union
8{
9  __m128i x;
10  char a[16];
11} union128i_b;
12
13typedef union
14{
15  __m128i x;
16  unsigned char a[16];
17} union128i_ub;
18
19typedef union
20{
21  __m128i x;
22  short a[8];
23} union128i_w;
24
25typedef union
26{
27  __m128i x;
28  unsigned short a[8];
29} union128i_uw;
30
31typedef union
32{
33  __m128i x;
34  int a[4];
35} union128i_d;
36
37typedef union
38{
39  __m128i x;
40  unsigned int a[4];
41} union128i_ud;
42
43typedef union
44{
45  __m128i x;
46  long long a[2];
47} union128i_q;
48
49typedef union
50{
51  __m128i x;
52  unsigned long long a[2];
53} union128i_uq;
54
55
56typedef union
57{
58  __m128d x;
59  double a[2];
60} union128d;
61#endif
62
63typedef 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)		\
80static int						\
81__attribute__((noinline, unused))			\
82check_##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__
98CHECK_EXP (union128i_b, char, "%d")
99CHECK_EXP (union128i_ub, unsigned char, "%d")
100CHECK_EXP (union128i_w, short, "%d")
101CHECK_EXP (union128i_uw, unsigned short, "%d")
102CHECK_EXP (union128i_d, int, "0x%x")
103CHECK_EXP (union128i_ud, unsigned int, "0x%x")
104CHECK_EXP (union128i_q, long long, "0x%llx")
105CHECK_EXP (union128i_uq, unsigned long long, "0x%llx")
106CHECK_EXP (union128d, double, "%f")
107#endif
108
109CHECK_EXP (union128, float, "%f")
110
111#define ESP_FLOAT 0.000001
112#define ESP_DOUBLE 0.000001
113#define CHECK_ARRAY(ARRAY, TYPE, FMT)                   \
114static int                                              \
115__attribute__((noinline, unused))                       \
116checkV##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
131CHECK_ARRAY(c, char, "0x%hhx")
132CHECK_ARRAY(s, short, "0x%hx")
133CHECK_ARRAY(i, int, "0x%x")
134CHECK_ARRAY(l, long long, "0x%llx")
135CHECK_ARRAY(uc, unsigned char, "0x%hhx")
136CHECK_ARRAY(us, unsigned short, "0x%hx")
137CHECK_ARRAY(ui, unsigned int, "0x%x")
138CHECK_ARRAY(ul, unsigned long long, "0x%llx")
139
140
141
142#define CHECK_FP_ARRAY(ARRAY, TYPE, ESP, FMT)                   \
143static int                                              \
144__attribute__((noinline, unused))                       \
145checkV##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
161CHECK_FP_ARRAY (d, double, ESP_DOUBLE, "%f")
162CHECK_FP_ARRAY (f, float, ESP_FLOAT, "%f")
163
164#ifdef NEED_IEEE754_FLOAT
165union 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
178union 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)		\
192static int							\
193__attribute__((noinline, unused))				\
194check_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
209CHECK_FP_EXP (union128, float, ESP_FLOAT, "%f")
210#ifdef __SSE2__
211CHECK_FP_EXP (union128d, double, ESP_DOUBLE, "%f")
212#endif
213