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