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