1 #include <stdio.h> 2 3 #define NO_WARN_X86_INTRINSICS 1 4 5 #ifdef __ALTIVEC__ 6 #include <xmmintrin.h> 7 8 #ifdef __VSX_SSE2__ 9 #include <emmintrin.h> 10 11 typedef union 12 { 13 __m128i x; 14 char a[16]; 15 } union128i_b; 16 17 typedef union 18 { 19 __m128i x; 20 unsigned char a[16]; 21 } union128i_ub; 22 23 typedef union 24 { 25 __m128i x; 26 short a[8]; 27 } union128i_w; 28 29 typedef union 30 { 31 __m128i x; 32 unsigned short a[8]; 33 } union128i_uw; 34 35 typedef union 36 { 37 __m128i x; 38 int a[4]; 39 } union128i_d; 40 41 typedef union 42 { 43 __m128i x; 44 unsigned int a[4]; 45 } union128i_ud; 46 47 #if __VSX__ 48 typedef union 49 { 50 __m128i x; 51 long long a[2]; 52 } union128i_q; 53 54 typedef union 55 { 56 __m128i x; 57 unsigned long long a[2]; 58 } union128i_uq; 59 60 61 typedef union 62 { 63 __m128d x; 64 double a[2]; 65 } union128d; 66 #endif 67 68 #endif 69 typedef union 70 { 71 __m128 x; 72 float a[4]; 73 int i[4]; 74 } union128; 75 76 #ifndef ARRAY_SIZE 77 #define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0])) 78 #endif 79 80 #ifdef DEBUG 81 #define PRINTF printf 82 #else 83 #define PRINTF(...) 84 #endif 85 86 #define CHECK_EXP(UINON_TYPE, VALUE_TYPE, FMT) \ 87 static int \ 88 __attribute__((noinline, unused)) \ 89 check_##UINON_TYPE (UINON_TYPE u, const VALUE_TYPE *v) \ 90 { \ 91 int i; \ 92 int err = 0; \ 93 \ 94 for (i = 0; i < ARRAY_SIZE (u.a); i++) \ 95 if (u.a[i] != v[i]) \ 96 { \ 97 err++; \ 98 PRINTF ("%i: " FMT " != " FMT "\n", \ 99 i, v[i], u.a[i]); \ 100 } \ 101 return err; \ 102 } 103 104 #ifdef __VSX_SSE2__ 105 CHECK_EXP (union128i_b, char, "%d") 106 CHECK_EXP (union128i_ub, unsigned char, "%d") 107 CHECK_EXP (union128i_w, short, "%d") 108 CHECK_EXP (union128i_uw, unsigned short, "%d") 109 CHECK_EXP (union128i_d, int, "0x%x") 110 CHECK_EXP (union128i_ud, unsigned int, "0x%x") 111 #ifdef __VSX__ 112 CHECK_EXP (union128i_q, long long, "0x%llx") 113 CHECK_EXP (union128i_uq, unsigned long long, "0x%llx") 114 CHECK_EXP (union128d, double, "%f") 115 #endif 116 #endif 117 118 CHECK_EXP (union128, float, "%f") 119 120 #define ESP_FLOAT 0.000001 121 #define ESP_DOUBLE 0.000001 122 #define CHECK_ARRAY(ARRAY, TYPE, FMT) \ 123 static int \ 124 __attribute__((noinline, unused)) \ 125 checkV##ARRAY (const TYPE *v, const TYPE *e, int n) \ 126 { \ 127 int i; \ 128 int err = 0; \ 129 \ 130 for (i = 0; i < n; i++) \ 131 if (v[i] != e[i]) \ 132 { \ 133 err++; \ 134 PRINTF ("%i: " FMT " != " FMT "\n", \ 135 i, v[i], e[i]); \ 136 } \ 137 return err; \ 138 } 139 140 CHECK_ARRAY(c, char, "0x%hhx") 141 CHECK_ARRAY(s, short, "0x%hx") 142 CHECK_ARRAY(i, int, "0x%x") 143 CHECK_ARRAY(l, long long, "0x%llx") 144 CHECK_ARRAY(uc, unsigned char, "0x%hhx") 145 CHECK_ARRAY(us, unsigned short, "0x%hx") 146 CHECK_ARRAY(ui, unsigned int, "0x%x") 147 CHECK_ARRAY(ul, unsigned long long, "0x%llx") 148 149 150 151 #define CHECK_FP_ARRAY(ARRAY, TYPE, ESP, FMT) \ 152 static int \ 153 __attribute__((noinline, unused)) \ 154 checkV##ARRAY (const TYPE *v, const TYPE *e, int n) \ 155 { \ 156 int i; \ 157 int err = 0; \ 158 \ 159 for (i = 0; i < n; i++) \ 160 if (v[i] > (e[i] + (ESP)) || v[i] < (e[i] - (ESP))) \ 161 if (e[i] != v[i]) \ 162 { \ 163 err++; \ 164 PRINTF ("%i: " FMT " != " FMT "\n", \ 165 i, v[i], e[i]); \ 166 } \ 167 return err; \ 168 } 169 170 CHECK_FP_ARRAY (d, double, ESP_DOUBLE, "%f") 171 CHECK_FP_ARRAY (f, float, ESP_FLOAT, "%f") 172 173 #ifdef NEED_IEEE754_FLOAT 174 union ieee754_float 175 { 176 float d; 177 struct 178 { 179 unsigned long frac : 23; 180 unsigned exp : 8; 181 unsigned sign : 1; 182 } bits __attribute__((packed)); 183 }; 184 #endif 185 186 #ifdef NEED_IEEE754_DOUBLE 187 union ieee754_double 188 { 189 double d; 190 struct 191 { 192 unsigned long frac1 : 32; 193 unsigned long frac0 : 20; 194 unsigned exp : 11; 195 unsigned sign : 1; 196 } bits __attribute__((packed)); 197 }; 198 #endif 199 200 #define CHECK_FP_EXP(UINON_TYPE, VALUE_TYPE, ESP, FMT) \ 201 static int \ 202 __attribute__((noinline, unused)) \ 203 check_fp_##UINON_TYPE (UINON_TYPE u, const VALUE_TYPE *v) \ 204 { \ 205 int i; \ 206 int err = 0; \ 207 \ 208 for (i = 0; i < ARRAY_SIZE (u.a); i++) \ 209 if (u.a[i] > (v[i] + (ESP)) || u.a[i] < (v[i] - (ESP))) \ 210 { \ 211 err++; \ 212 PRINTF ("%i: " FMT " != " FMT "\n", \ 213 i, v[i], u.a[i]); \ 214 } \ 215 return err; \ 216 } 217 218 CHECK_FP_EXP (union128, float, ESP_FLOAT, "%f") 219 #ifdef __VSX_SSE2__ 220 CHECK_FP_EXP (union128d, double, ESP_DOUBLE, "%f") 221 #endif 222 #endif /* __ALTIVEC__ */ 223