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 #define ESP_FLOAT 0.000001 112 #define ESP_DOUBLE 0.000001 113 #define CHECK_ARRAY(ARRAY, TYPE, FMT) \ 114 static int \ 115 __attribute__((noinline, unused)) \ 116 checkV##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 131 CHECK_ARRAY(c, char, "0x%hhx") 132 CHECK_ARRAY(s, short, "0x%hx") 133 CHECK_ARRAY(i, int, "0x%x") 134 CHECK_ARRAY(l, long long, "0x%llx") 135 CHECK_ARRAY(uc, unsigned char, "0x%hhx") 136 CHECK_ARRAY(us, unsigned short, "0x%hx") 137 CHECK_ARRAY(ui, unsigned int, "0x%x") 138 CHECK_ARRAY(ul, unsigned long long, "0x%llx") 139 140 141 142 #define CHECK_FP_ARRAY(ARRAY, TYPE, ESP, FMT) \ 143 static int \ 144 __attribute__((noinline, unused)) \ 145 checkV##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 161 CHECK_FP_ARRAY (d, double, ESP_DOUBLE, "%f") 162 CHECK_FP_ARRAY (f, float, ESP_FLOAT, "%f") 163 164 #ifdef NEED_IEEE754_FLOAT 165 union 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 178 union 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) \ 192 static int \ 193 __attribute__((noinline, unused)) \ 194 check_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 209 CHECK_FP_EXP (union128, float, ESP_FLOAT, "%f") 210 #ifdef __SSE2__ 211 CHECK_FP_EXP (union128d, double, ESP_DOUBLE, "%f") 212 #endif 213