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  long long a[2];
41} union128i_q;
42
43typedef union
44{
45  __m128d x;
46  double a[2];
47} union128d;
48#endif
49
50typedef union
51{
52  __m128  x;
53  float a[4];
54} union128;
55
56#ifndef ARRAY_SIZE
57#define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
58#endif
59
60#ifdef DEBUG
61#define PRINTF printf
62#else
63#define PRINTF(...)
64#endif
65
66#define CHECK_EXP(UINON_TYPE, VALUE_TYPE, FMT)		\
67static int						\
68__attribute__((noinline, unused))			\
69check_##UINON_TYPE (UINON_TYPE u, const VALUE_TYPE *v)	\
70{							\
71  int i;						\
72  int err = 0;						\
73							\
74  for (i = 0; i < ARRAY_SIZE (u.a); i++)		\
75    if (u.a[i] != v[i])					\
76      {							\
77	err++;						\
78	PRINTF ("%i: " FMT " != " FMT "\n",		\
79		i, v[i], u.a[i]);			\
80      }							\
81  return err;						\
82}
83
84#ifdef __SSE2__
85CHECK_EXP (union128i_b, char, "%d")
86CHECK_EXP (union128i_ub, unsigned char, "%d")
87CHECK_EXP (union128i_w, short, "%d")
88CHECK_EXP (union128i_uw, unsigned short, "%d")
89CHECK_EXP (union128i_d, int, "0x%x")
90CHECK_EXP (union128i_q, long long, "0x%llx")
91CHECK_EXP (union128d, double, "%f")
92#endif
93
94CHECK_EXP (union128, float, "%f")
95
96#define ESP_FLOAT 0.000001
97#define ESP_DOUBLE 0.000001
98#define CHECK_ARRAY(ARRAY, TYPE, FMT)                   \
99static int                                              \
100__attribute__((noinline, unused))                       \
101checkV##ARRAY (const TYPE *v, const TYPE *e, int n)     \
102{                                                       \
103  int i;                                                \
104  int err = 0;                                          \
105                                                        \
106  for (i = 0; i < n; i++)                               \
107    if (v[i] != e[i])                                   \
108      {                                                 \
109        err++;                                          \
110        PRINTF ("%i: " FMT " != " FMT "\n",             \
111                i, v[i], e[i]);                 \
112      }                                                 \
113  return err;                                           \
114}
115
116CHECK_ARRAY(i, int, "0x%x")
117CHECK_ARRAY(l, long long, "0x%llx")
118
119#define CHECK_FP_ARRAY(ARRAY, TYPE, ESP, FMT)                   \
120static int                                              \
121__attribute__((noinline, unused))                       \
122checkV##ARRAY (const TYPE *v, const TYPE *e, int n)     \
123{                                                       \
124  int i;                                                \
125  int err = 0;                                          \
126                                                        \
127  for (i = 0; i < n; i++)                               \
128    if (v[i] > (e[i] + (ESP)) || v[i] < (e[i] - (ESP))) \
129    if (e[i] != v[i])                                   \
130      {                                                 \
131        err++;                                          \
132        PRINTF ("%i: " FMT " != " FMT "\n",             \
133                i, v[i], e[i]);                 \
134      }                                                 \
135  return err;                                           \
136}
137
138CHECK_FP_ARRAY (d, double, ESP_DOUBLE, "%f")
139CHECK_FP_ARRAY (f, float, ESP_FLOAT, "%f")
140
141#ifdef NEED_IEEE754_FLOAT
142union ieee754_float
143{
144   float d;
145   struct
146   {
147      unsigned long frac : 23;
148      unsigned exp : 8;
149      unsigned sign : 1;
150   } bits __attribute__((packed));
151};
152#endif
153
154#ifdef NEED_IEEE754_DOUBLE
155union ieee754_double
156{
157   double d;
158   struct
159   {
160      unsigned long frac1 : 32;
161      unsigned long frac0 : 20;
162      unsigned exp : 11;
163      unsigned sign : 1;
164   } bits __attribute__((packed));
165};
166#endif
167