1 #if !defined(SIMDE_TESTS_H)
2 #define SIMDE_TESTS_H
3
4 #define SIMDE_NO_CHECK_IMMEDIATE_CONSTANT
5
6 #include "../simde/simde-common.h"
7
8 #include <time.h>
9 #include <stdlib.h>
10 #include <math.h>
11 #include <inttypes.h>
12 #include <stdarg.h>
13
14 typedef enum SimdeTestVecPos {
15 SIMDE_TEST_VEC_POS_FIRST = 1,
16 SIMDE_TEST_VEC_POS_MIDDLE = 0,
17 SIMDE_TEST_VEC_POS_LAST = -1
18 } SimdeTestVecPos;
19
20 HEDLEY_DIAGNOSTIC_PUSH
21 SIMDE_DIAGNOSTIC_DISABLE_VLA_
22 SIMDE_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION_
23 SIMDE_DIAGNOSTIC_DISABLE_PADDED_
24 SIMDE_DIAGNOSTIC_DISABLE_ZERO_AS_NULL_POINTER_CONSTANT_
25 SIMDE_DIAGNOSTIC_DISABLE_CAST_FUNCTION_TYPE_
26 SIMDE_DIAGNOSTIC_DISABLE_NON_CONSTANT_AGGREGATE_INITIALIZER_
27 SIMDE_DIAGNOSTIC_DISABLE_C99_EXTENSIONS_
28 SIMDE_DIAGNOSTIC_DISABLE_NO_EMMS_INSTRUCTION_
29 SIMDE_DIAGNOSTIC_DISABLE_CPP98_COMPAT_PEDANTIC_
30 SIMDE_DIAGNOSTIC_DISABLE_ANNEX_K_
31 SIMDE_DIAGNOSTIC_DISABLE_DISABLED_MACRO_EXPANSION_
32
33 #if \
34 HEDLEY_HAS_BUILTIN(__builtin_abort) || \
35 HEDLEY_GCC_VERSION_CHECK(3,4,6) || \
36 HEDLEY_ARM_VERSION_CHECK(4,1,0)
37 #define simde_abort() __builtin_abort()
38 #elif defined(SIMDE_HAVE_STDLIB_H)
39 #define simde_abort() abort()
40 #endif
41
42 #define SIMDE_TEST_ASSERT_CONTINUE 0
43 #define SIMDE_TEST_ASSERT_TRAP 1
44 #define SIMDE_TEST_ASSERT_ABORT 2
45 #if !defined(SIMDE_TEST_ASSERT_FAILURE)
46 #if defined(SIMDE_TEST_BARE)
47 #define SIMDE_TEST_ASSERT_FAILURE SIMDE_TEST_ASSERT_CONTINUE
48 #else
49 #define SIMDE_TEST_ASSERT_FAILURE SIMDE_TEST_ASSERT_ABORT
50 #endif
51 #endif
52
53 #if !defined(SIMDE_TEST_ASSERT_ABORT) && !defined(SIMDE_TEST_ASSERT_CONTINUE) && !defined(SIMDE_TEST_ASSERT_TRAP)
54 #if defined(SIMDE_TEST_BARE)
55 #define SIMDE_TEST_ASSERT_CONTINUE
56 #else
57 #define SIMDE_TEST_ASSERT_ABORT
58 #endif
59 #endif
60
61 #if SIMDE_TEST_ASSERT_FAILURE == SIMDE_TEST_ASSERT_ABORT
62 #define SIMDE_TEST_ASSERT_RETURN(value) ((void) 0)
63 #else
64 #define SIMDE_TEST_ASSERT_RETURN(value) return value
65 #endif
66
67 #if defined(SIMDE_TEST_BARE)
68 #define SIMDE_CODEGEN_FP stderr
69 #else
70 #define SIMDE_CODEGEN_FP stdout
71 #endif
72
73 #if SIMDE_TEST_ASSERT_FAILURE == 2
74 HEDLEY_NO_RETURN
75 #endif
76 HEDLEY_PRINTF_FORMAT(1, 2)
77 static void
simde_test_debug_printf_(const char * format,...)78 simde_test_debug_printf_(const char* format, ...) {
79 va_list ap;
80
81 va_start(ap, format);
82 vfprintf(stderr, format, ap);
83 va_end(ap);
84 fflush(stderr);
85
86 /* Debug trap is great for local development where you can attach a
87 * debugger, but processes exiting with a SIGTRAP seem to be rather
88 * confusing for CI. */
89 #if SIMDE_TEST_ASSERT_FAILURE == 1
90 simde_trap();
91 #elif SIMDE_TEST_ASSERT_FAILURE == 2
92 simde_abort();
93 #endif
94 }
95
96 HEDLEY_PRINTF_FORMAT(3, 4)
97 static void
simde_test_codegen_snprintf_(char * str,size_t size,const char * format,...)98 simde_test_codegen_snprintf_(char* str, size_t size, const char* format, ...) {
99 va_list ap;
100 int w;
101
102 va_start(ap, format);
103 w = vsnprintf(str, size, format, ap);
104 va_end(ap);
105
106 if (w > HEDLEY_STATIC_CAST(int, size)) {
107 simde_test_debug_printf_("Not enough space to write value (given %zu bytes, need %d bytes)\n", size, w + 1);
108 }
109 }
110
111 static void
simde_test_codegen_f32(size_t buf_len,char buf[HEDLEY_ARRAY_PARAM (buf_len)],simde_float32 value)112 simde_test_codegen_f32(size_t buf_len, char buf[HEDLEY_ARRAY_PARAM(buf_len)], simde_float32 value) {
113 if (simde_math_isnan(value)) {
114 simde_test_codegen_snprintf_(buf, buf_len, " SIMDE_MATH_NANF");
115 } else if (simde_math_isinf(value)) {
116 simde_test_codegen_snprintf_(buf, buf_len, "%5cSIMDE_MATH_INFINITYF", value < 0 ? '-' : ' ');
117 } else {
118 simde_test_codegen_snprintf_(buf, buf_len, "SIMDE_FLOAT32_C(%9.2f)", HEDLEY_STATIC_CAST(double, value));
119 }
120 }
121
122 static void
simde_test_codegen_f64(size_t buf_len,char buf[HEDLEY_ARRAY_PARAM (buf_len)],simde_float64 value)123 simde_test_codegen_f64(size_t buf_len, char buf[HEDLEY_ARRAY_PARAM(buf_len)], simde_float64 value) {
124 if (simde_math_isnan(value)) {
125 simde_test_codegen_snprintf_(buf, buf_len, " SIMDE_MATH_NAN");
126 } else if (simde_math_isinf(value)) {
127 simde_test_codegen_snprintf_(buf, buf_len, "%7cSIMDE_MATH_INFINITY", value < 0 ? '-' : ' ');
128 } else {
129 simde_test_codegen_snprintf_(buf, buf_len, "SIMDE_FLOAT64_C(%9.2f)", HEDLEY_STATIC_CAST(double, value));
130 }
131 }
132
133 static void
simde_test_codegen_i8(size_t buf_len,char buf[HEDLEY_ARRAY_PARAM (buf_len)],int8_t value)134 simde_test_codegen_i8(size_t buf_len, char buf[HEDLEY_ARRAY_PARAM(buf_len)], int8_t value) {
135 if (value == INT8_MIN) {
136 simde_test_codegen_snprintf_(buf, buf_len, " INT8_MIN");
137 } else if (value == INT8_MAX) {
138 simde_test_codegen_snprintf_(buf, buf_len, " INT8_MAX");
139 } else {
140 simde_test_codegen_snprintf_(buf, buf_len, "%cINT8_C(%4" PRId8 ")", (value < 0) ? '-' : ' ', HEDLEY_STATIC_CAST(int8_t, (value < 0) ? -value : value));
141 }
142 }
143
144 static void
simde_test_codegen_i16(size_t buf_len,char buf[HEDLEY_ARRAY_PARAM (buf_len)],int16_t value)145 simde_test_codegen_i16(size_t buf_len, char buf[HEDLEY_ARRAY_PARAM(buf_len)], int16_t value) {
146 if (value == INT16_MIN) {
147 simde_test_codegen_snprintf_(buf, buf_len, "%15s", "INT16_MIN");
148 } else if (value == INT16_MAX) {
149 simde_test_codegen_snprintf_(buf, buf_len, "%15s", "INT16_MAX");
150 } else {
151 simde_test_codegen_snprintf_(buf, buf_len, "%cINT16_C(%6" PRId16 ")", (value < 0) ? '-' : ' ', HEDLEY_STATIC_CAST(int16_t, (value < 0) ? -value : value));
152 }
153 }
154
155 static void
simde_test_codegen_i32(size_t buf_len,char buf[HEDLEY_ARRAY_PARAM (buf_len)],int32_t value)156 simde_test_codegen_i32(size_t buf_len, char buf[HEDLEY_ARRAY_PARAM(buf_len)], int32_t value) {
157 if (value == INT32_MIN) {
158 simde_test_codegen_snprintf_(buf, buf_len, "%20s", "INT32_MIN");
159 } else if (value == INT32_MAX) {
160 simde_test_codegen_snprintf_(buf, buf_len, "%20s", "INT32_MAX");
161 } else {
162 simde_test_codegen_snprintf_(buf, buf_len, "%cINT32_C(%12" PRId32 ")", (value < 0) ? '-' : ' ', HEDLEY_STATIC_CAST(int32_t, (value < 0) ? -value : value));
163 }
164 }
165
166 static void
simde_test_codegen_i64(size_t buf_len,char buf[HEDLEY_ARRAY_PARAM (buf_len)],int64_t value)167 simde_test_codegen_i64(size_t buf_len, char buf[HEDLEY_ARRAY_PARAM(buf_len)], int64_t value) {
168 if (value == INT64_MIN) {
169 simde_test_codegen_snprintf_(buf, buf_len, "%29s", "INT64_MIN");
170 } else if (value == INT64_MAX) {
171 simde_test_codegen_snprintf_(buf, buf_len, "%29s", "INT64_MAX");
172 } else {
173 simde_test_codegen_snprintf_(buf, buf_len, "%cINT64_C(%20" PRId64 ")", (value < 0) ? '-' : ' ', HEDLEY_STATIC_CAST(int64_t, (value < 0) ? -value : value));
174 }
175 }
176
177 static void
simde_test_codegen_u8(size_t buf_len,char buf[HEDLEY_ARRAY_PARAM (buf_len)],uint8_t value)178 simde_test_codegen_u8(size_t buf_len, char buf[HEDLEY_ARRAY_PARAM(buf_len)], uint8_t value) {
179 if (value == UINT8_MAX) {
180 simde_test_codegen_snprintf_(buf, buf_len, " UINT8_MAX");
181 } else {
182 simde_test_codegen_snprintf_(buf, buf_len, "UINT8_C(%3" PRIu8 ")", value);
183 }
184 }
185
186 static void
simde_test_codegen_u16(size_t buf_len,char buf[HEDLEY_ARRAY_PARAM (buf_len)],uint16_t value)187 simde_test_codegen_u16(size_t buf_len, char buf[HEDLEY_ARRAY_PARAM(buf_len)], uint16_t value) {
188 if (value == UINT16_MAX) {
189 simde_test_codegen_snprintf_(buf, buf_len, "%15s", "UINT16_MAX");
190 } else {
191 simde_test_codegen_snprintf_(buf, buf_len, "UINT16_C(%5" PRIu16 ")", value);
192 }
193 }
194
195 static void
simde_test_codegen_u32(size_t buf_len,char buf[HEDLEY_ARRAY_PARAM (buf_len)],uint32_t value)196 simde_test_codegen_u32(size_t buf_len, char buf[HEDLEY_ARRAY_PARAM(buf_len)], uint32_t value) {
197 if (value == UINT32_MAX) {
198 simde_test_codegen_snprintf_(buf, buf_len, "%20s", "UINT32_MAX");
199 } else {
200 simde_test_codegen_snprintf_(buf, buf_len, "UINT32_C(%10" PRIu32 ")", value);
201 }
202 }
203
204 static void
simde_test_codegen_u64(size_t buf_len,char buf[HEDLEY_ARRAY_PARAM (buf_len)],uint64_t value)205 simde_test_codegen_u64(size_t buf_len, char buf[HEDLEY_ARRAY_PARAM(buf_len)], uint64_t value) {
206 if (value == UINT64_MAX) {
207 simde_test_codegen_snprintf_(buf, buf_len, "%29s", "UINT64_MAX");
208 } else {
209 simde_test_codegen_snprintf_(buf, buf_len, "UINT64_C(%20" PRIu64 ")", value);
210 }
211 }
212
213 static void
simde_test_codegen_write_indent(int indent)214 simde_test_codegen_write_indent(int indent) {
215 for (int i = 0 ; i < indent ; i++) {
216 fputs(" ", SIMDE_CODEGEN_FP);
217 }
218 }
219
simde_test_codegen_rand(void)220 static int simde_test_codegen_rand(void) {
221 /* Single-threaded programs are so nice */
222 static int is_init = 0;
223 if (HEDLEY_UNLIKELY(!is_init)) {
224 FILE* fp = fopen("/dev/urandom", "r");
225 if (fp == NULL)
226 fp = fopen("/dev/random", "r");
227
228 if (fp != NULL) {
229 unsigned int seed;
230 size_t nread = fread(&seed, sizeof(seed), 1, fp);
231 fclose(fp);
232 if (nread == 1) {
233 srand(seed);
234 is_init = 1;
235 }
236 }
237
238 if (!is_init) {
239 srand(HEDLEY_STATIC_CAST(unsigned int, time(NULL)));
240 is_init = 1;
241 }
242 }
243
244 return rand();
245 }
246
247 static void
simde_test_codegen_random_memory(size_t buf_len,uint8_t buf[HEDLEY_ARRAY_PARAM (buf_len)])248 simde_test_codegen_random_memory(size_t buf_len, uint8_t buf[HEDLEY_ARRAY_PARAM(buf_len)]) {
249 for (size_t i = 0 ; i < buf_len ; i++) {
250 buf[i] = HEDLEY_STATIC_CAST(uint8_t, simde_test_codegen_rand() & 0xff);
251 }
252 }
253
254 static simde_float32
simde_test_codegen_random_f32(simde_float32 min,simde_float32 max)255 simde_test_codegen_random_f32(simde_float32 min, simde_float32 max) {
256 simde_float32 v = (HEDLEY_STATIC_CAST(simde_float32, simde_test_codegen_rand()) / (HEDLEY_STATIC_CAST(simde_float32, RAND_MAX) / (max - min))) + min;
257 return simde_math_roundf(v * SIMDE_FLOAT32_C(100.0)) / SIMDE_FLOAT32_C(100.0);
258 }
259
260 static simde_float64
simde_test_codegen_random_f64(simde_float64 min,simde_float64 max)261 simde_test_codegen_random_f64(simde_float64 min, simde_float64 max) {
262 simde_float64 v = (HEDLEY_STATIC_CAST(simde_float64, simde_test_codegen_rand()) / (HEDLEY_STATIC_CAST(simde_float64, RAND_MAX) / (max - min))) + min;
263 return simde_math_round(v * SIMDE_FLOAT64_C(100.0)) / SIMDE_FLOAT64_C(100.0);
264 }
265
266 typedef enum SimdeTestVecFloatMask {
267 SIMDE_TEST_VEC_FLOAT_DEFAULT = 0,
268 SIMDE_TEST_VEC_FLOAT_PAIR = 1,
269 SIMDE_TEST_VEC_FLOAT_NAN = 2,
270 SIMDE_TEST_VEC_FLOAT_EQUAL = 4,
271 SIMDE_TEST_VEC_FLOAT_ROUND = 8
272 }
273 #if \
274 (HEDLEY_HAS_ATTRIBUTE(flag_enum) && !defined(HEDLEY_IBM_VERSION)) && \
275 (!defined(__cplusplus) || SIMDE_DETECT_CLANG_VERSION_CHECK(5,0,0))
276 __attribute__((__flag_enum__))
277 #endif
278 SimdeTestVecFloatType;
279
280 /* This is a bit messy, sorry. And I haven't really tested with
281 * anything greater than 4-element vectors, there is no input
282 * validation, etc. I'm not going to lose any sleep since it's
283 * just a test harness, but you probably shouldn't use this API
284 * directly since there is a good chance it will change. */
285
286 static void
simde_test_codegen_calc_pair(int pairwise,size_t test_sets,size_t vectors_per_set,size_t elements_per_vector,size_t pos,size_t * a,size_t * b)287 simde_test_codegen_calc_pair(int pairwise, size_t test_sets, size_t vectors_per_set, size_t elements_per_vector, size_t pos, size_t* a, size_t* b) {
288 (void) test_sets; // <- for validating ranges
289
290 if (pairwise) {
291 *a = (((pos * 2) + 0) % elements_per_vector) + ((((pos * 2) + 0) / elements_per_vector) * elements_per_vector);
292 *b = (((pos * 2) + 1) % elements_per_vector) + ((((pos * 2) + 1) / elements_per_vector) * elements_per_vector);
293 } else {
294 size_t elements_per_set = elements_per_vector * vectors_per_set;
295 size_t set_num = pos / elements_per_vector;
296 size_t pos_in_set = pos % elements_per_vector;
297
298 *a = (elements_per_set * set_num) + pos_in_set;
299 *b = *a + elements_per_vector;
300 }
301 }
302
303 static void
simde_test_codegen_float_set_value_(size_t element_size,size_t pos,void * values,simde_float32 f32_val,simde_float64 f64_val)304 simde_test_codegen_float_set_value_(size_t element_size, size_t pos, void* values, simde_float32 f32_val, simde_float64 f64_val) {
305 switch (element_size) {
306 case sizeof(simde_float32):
307 HEDLEY_REINTERPRET_CAST(simde_float32*, values)[pos] = f32_val;
308 break;
309 case sizeof(simde_float64):
310 HEDLEY_REINTERPRET_CAST(simde_float64*, values)[pos] = f64_val;
311 break;
312 }
313 }
314
315 static void
simde_test_codegen_random_vfX_full_(size_t test_sets,size_t vectors_per_set,size_t elements_per_vector,size_t elem_size,void * values,simde_float64 min,simde_float64 max,SimdeTestVecFloatType vec_type)316 simde_test_codegen_random_vfX_full_(
317 size_t test_sets, size_t vectors_per_set, size_t elements_per_vector,
318 size_t elem_size, void* values,
319 simde_float64 min, simde_float64 max,
320 SimdeTestVecFloatType vec_type) {
321 for (size_t i = 0 ; i < (test_sets * vectors_per_set * elements_per_vector) ; i++) {
322 simde_float64 v = simde_test_codegen_random_f64(min, max);
323 if (vec_type & SIMDE_TEST_VEC_FLOAT_ROUND) {
324 if (simde_test_codegen_rand() & 7) {
325 do {
326 v = HEDLEY_STATIC_CAST(simde_float64, HEDLEY_STATIC_CAST(int64_t, v));
327 if (simde_test_codegen_rand() & 7)
328 v += 0.5;
329 } while (v > max || v < min);
330 }
331 }
332 simde_test_codegen_float_set_value_(elem_size, i, values, HEDLEY_STATIC_CAST(simde_float32, v), v);
333 }
334
335 int pairwise = !!(vec_type & SIMDE_TEST_VEC_FLOAT_PAIR);
336 size_t pos = 0;
337 size_t a, b;
338
339 if (vec_type & SIMDE_TEST_VEC_FLOAT_NAN) {
340 simde_test_codegen_calc_pair(pairwise, test_sets, vectors_per_set, elements_per_vector, pos++, &a, &b);
341 simde_test_codegen_float_set_value_(elem_size, a, values, SIMDE_MATH_NANF, SIMDE_MATH_NAN);
342
343 simde_test_codegen_calc_pair(pairwise, test_sets, vectors_per_set, elements_per_vector, pos++, &a, &b);
344 simde_test_codegen_float_set_value_(elem_size, b, values, SIMDE_MATH_NANF, SIMDE_MATH_NAN);
345
346 simde_test_codegen_calc_pair(pairwise, test_sets, vectors_per_set, elements_per_vector, pos++, &a, &b);
347 simde_test_codegen_float_set_value_(elem_size, a, values, SIMDE_MATH_NANF, SIMDE_MATH_NAN);
348 simde_test_codegen_float_set_value_(elem_size, b, values, SIMDE_MATH_NANF, SIMDE_MATH_NAN);
349 }
350
351 if (vec_type & SIMDE_TEST_VEC_FLOAT_EQUAL) {
352 simde_test_codegen_calc_pair(pairwise, test_sets, vectors_per_set, elements_per_vector, pos++, &a, &b);
353 simde_float64 v = simde_test_codegen_random_f64(min, max);
354 simde_test_codegen_float_set_value_(elem_size, a, values, HEDLEY_STATIC_CAST(simde_float32, v), v);
355 simde_test_codegen_float_set_value_(elem_size, b, values, HEDLEY_STATIC_CAST(simde_float32, v), v);
356 }
357 }
358
359 static void
simde_test_codegen_random_vf32_full(size_t test_sets,size_t vectors_per_set,size_t elements_per_vector,simde_float32 values[HEDLEY_ARRAY_PARAM (test_sets * vectors_per_set * elements_per_vector)],simde_float32 min,simde_float32 max,SimdeTestVecFloatType vec_type)360 simde_test_codegen_random_vf32_full(
361 size_t test_sets, size_t vectors_per_set, size_t elements_per_vector,
362 simde_float32 values[HEDLEY_ARRAY_PARAM(test_sets * vectors_per_set * elements_per_vector)],
363 simde_float32 min, simde_float32 max,
364 SimdeTestVecFloatType vec_type) {
365 simde_test_codegen_random_vfX_full_(test_sets, vectors_per_set, elements_per_vector,
366 sizeof(simde_float32), values,
367 HEDLEY_STATIC_CAST(simde_float64, min), HEDLEY_STATIC_CAST(simde_float64, max),
368 vec_type);
369 }
370
371 static void
simde_test_codegen_random_vf64_full(size_t test_sets,size_t vectors_per_set,size_t elements_per_vector,simde_float64 values[HEDLEY_ARRAY_PARAM (test_sets * vectors_per_set * elements_per_vector)],simde_float64 min,simde_float64 max,SimdeTestVecFloatType vec_type)372 simde_test_codegen_random_vf64_full(
373 size_t test_sets, size_t vectors_per_set, size_t elements_per_vector,
374 simde_float64 values[HEDLEY_ARRAY_PARAM(test_sets * vectors_per_set * elements_per_vector)],
375 simde_float64 min, simde_float64 max,
376 SimdeTestVecFloatType vec_type) {
377 simde_test_codegen_random_vfX_full_(test_sets, vectors_per_set, elements_per_vector,
378 sizeof(simde_float64), values,
379 min, max,
380 vec_type);
381 }
382
383 static void
simde_test_codegen_random_vf32(size_t elem_count,simde_float32 values[HEDLEY_ARRAY_PARAM (elem_count)],simde_float32 min,simde_float32 max)384 simde_test_codegen_random_vf32(size_t elem_count, simde_float32 values[HEDLEY_ARRAY_PARAM(elem_count)], simde_float32 min, simde_float32 max) {
385 for (size_t i = 0 ; i < elem_count ; i++) {
386 values[i] = simde_test_codegen_random_f32(min, max);
387 }
388 }
389
390 static void
simde_test_codegen_random_vf64(size_t elem_count,simde_float64 values[HEDLEY_ARRAY_PARAM (elem_count)],simde_float64 min,simde_float64 max)391 simde_test_codegen_random_vf64(size_t elem_count, simde_float64 values[HEDLEY_ARRAY_PARAM(elem_count)], simde_float64 min, simde_float64 max) {
392 for (size_t i = 0 ; i < elem_count ; i++) {
393 values[i] = simde_test_codegen_random_f64(min, max);
394 }
395 }
396
397 #define SIMDE_TEST_CODEGEN_GENERATE_RANDOM_INT_FUNC_(T, symbol_identifier) \
398 static T simde_test_codegen_random_##symbol_identifier(void) { \
399 T r; \
400 simde_test_codegen_random_memory(sizeof(r), HEDLEY_REINTERPRET_CAST(uint8_t*, &r)); \
401 return r; \
402 }
403
SIMDE_TEST_CODEGEN_GENERATE_RANDOM_INT_FUNC_(int8_t,i8)404 SIMDE_TEST_CODEGEN_GENERATE_RANDOM_INT_FUNC_(int8_t, i8)
405 SIMDE_TEST_CODEGEN_GENERATE_RANDOM_INT_FUNC_(int16_t, i16)
406 SIMDE_TEST_CODEGEN_GENERATE_RANDOM_INT_FUNC_(int32_t, i32)
407 SIMDE_TEST_CODEGEN_GENERATE_RANDOM_INT_FUNC_(int64_t, i64)
408 SIMDE_TEST_CODEGEN_GENERATE_RANDOM_INT_FUNC_(uint8_t, u8)
409 SIMDE_TEST_CODEGEN_GENERATE_RANDOM_INT_FUNC_(uint16_t, u16)
410 SIMDE_TEST_CODEGEN_GENERATE_RANDOM_INT_FUNC_(uint32_t, u32)
411 SIMDE_TEST_CODEGEN_GENERATE_RANDOM_INT_FUNC_(uint64_t, u64)
412
413 #define SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(T, symbol_identifier, elements_per_line) \
414 static void \
415 simde_test_codegen_write_v##symbol_identifier(int indent, size_t elem_count, T values[HEDLEY_ARRAY_PARAM(elem_count)], SimdeTestVecPos pos) { \
416 switch (pos) { \
417 case SIMDE_TEST_VEC_POS_FIRST: \
418 simde_test_codegen_write_indent(indent); \
419 indent++; \
420 fputs("{ ", SIMDE_CODEGEN_FP); \
421 break; \
422 case SIMDE_TEST_VEC_POS_MIDDLE: \
423 case SIMDE_TEST_VEC_POS_LAST: \
424 indent++; \
425 simde_test_codegen_write_indent(indent); \
426 break; \
427 } \
428 \
429 fputs("{ ", SIMDE_CODEGEN_FP); \
430 for (size_t i = 0 ; i < elem_count ; i++) { \
431 if (i != 0) { \
432 fputc(',', SIMDE_CODEGEN_FP); \
433 if ((i % elements_per_line) == 0) { \
434 fputc('\n', SIMDE_CODEGEN_FP); \
435 simde_test_codegen_write_indent(indent + 1); \
436 } else { \
437 fputc(' ', SIMDE_CODEGEN_FP); \
438 } \
439 } \
440 \
441 char buf[53]; \
442 simde_test_codegen_##symbol_identifier(sizeof(buf), buf, values[i]); \
443 fputs(buf, SIMDE_CODEGEN_FP); \
444 } \
445 fputs(" }", SIMDE_CODEGEN_FP); \
446 \
447 switch (pos) { \
448 case SIMDE_TEST_VEC_POS_FIRST: \
449 case SIMDE_TEST_VEC_POS_MIDDLE: \
450 fputc(',', SIMDE_CODEGEN_FP); \
451 break; \
452 case SIMDE_TEST_VEC_POS_LAST: \
453 fputs(" },", SIMDE_CODEGEN_FP); \
454 break; \
455 } \
456 \
457 fputc('\n', SIMDE_CODEGEN_FP); \
458 }
459
460 SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(simde_float32, f32, 4)
461 SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(simde_float64, f64, 4)
462 SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(int8_t, i8, 8)
463 SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(int16_t, i16, 8)
464 SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(int32_t, i32, 8)
465 SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(int64_t, i64, 4)
466 SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(uint8_t, u8, 8)
467 SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(uint16_t, u16, 8)
468 SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(uint32_t, u32, 8)
469 SIMDE_TEST_CODEGEN_GENERATE_WRITE_VECTOR_FUNC_(uint64_t, u64, 4)
470
471 #define SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(T, symbol_identifier) \
472 static void \
473 simde_test_codegen_write_##symbol_identifier(int indent, T value, SimdeTestVecPos pos) { \
474 switch (pos) { \
475 case SIMDE_TEST_VEC_POS_FIRST: \
476 simde_test_codegen_write_indent(indent); \
477 indent++; \
478 fputs("{ ", SIMDE_CODEGEN_FP); \
479 break; \
480 case SIMDE_TEST_VEC_POS_MIDDLE: \
481 case SIMDE_TEST_VEC_POS_LAST: \
482 indent++; \
483 simde_test_codegen_write_indent(indent); \
484 break; \
485 } \
486 \
487 { \
488 char buf[53]; \
489 simde_test_codegen_##symbol_identifier(sizeof(buf), buf, value); \
490 fputs(buf, SIMDE_CODEGEN_FP); \
491 } \
492 \
493 switch (pos) { \
494 case SIMDE_TEST_VEC_POS_FIRST: \
495 case SIMDE_TEST_VEC_POS_MIDDLE: \
496 fputc(',', SIMDE_CODEGEN_FP); \
497 break; \
498 case SIMDE_TEST_VEC_POS_LAST: \
499 fputs(" },", SIMDE_CODEGEN_FP); \
500 break; \
501 } \
502 \
503 fputc('\n', SIMDE_CODEGEN_FP); \
504 }
505
506 SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(int8_t, i8)
507 SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(int16_t, i16)
508 SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(int32_t, i32)
509 SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(int64_t, i64)
510 SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(uint8_t, u8)
511 SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(uint16_t, u16)
512 SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(uint32_t, u32)
513 SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(uint64_t, u64)
514 SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(simde_float32, f32)
515 SIMDE_TEST_CODEGEN_WRITE_SCALAR_FUNC_(simde_float64, f64)
516
517 HEDLEY_DIAGNOSTIC_PUSH
518 SIMDE_DIAGNOSTIC_DISABLE_FLOAT_EQUAL_
519
520 static int
521 simde_test_equal_f32(simde_float32 a, simde_float32 b, simde_float32 slop) {
522 if (simde_math_isnan(a)) {
523 return simde_math_isnan(b);
524 } else if (simde_math_isinf(a)) {
525 return !((a < b) || (a > b));
526 } else {
527 simde_float32 lo = a - slop;
528 if (HEDLEY_UNLIKELY(lo == a))
529 lo = simde_math_nextafterf(a, -SIMDE_MATH_INFINITYF);
530
531 simde_float32 hi = a + slop;
532 if (HEDLEY_UNLIKELY(hi == a))
533 hi = simde_math_nextafterf(a, SIMDE_MATH_INFINITYF);
534
535 return ((b >= lo) && (b <= hi));
536 }
537 }
538
539 static int
simde_test_equal_f64(simde_float64 a,simde_float64 b,simde_float64 slop)540 simde_test_equal_f64(simde_float64 a, simde_float64 b, simde_float64 slop) {
541 if (simde_math_isnan(a)) {
542 return simde_math_isnan(b);
543 } else if (simde_math_isinf(a)) {
544 return !((a < b) || (a > b));
545 } else {
546 simde_float64 lo = a - slop;
547 if (HEDLEY_UNLIKELY(lo == a))
548 lo = simde_math_nextafter(a, -SIMDE_MATH_INFINITY);
549
550 simde_float64 hi = a + slop;
551 if (HEDLEY_UNLIKELY(hi == a))
552 hi = simde_math_nextafter(a, SIMDE_MATH_INFINITY);
553
554 return ((b >= lo) && (b <= hi));
555 }
556 }
557
558 HEDLEY_DIAGNOSTIC_POP
559
560 static float
simde_test_f32_precision_to_slop(int precision)561 simde_test_f32_precision_to_slop(int precision) {
562 return simde_math_powf(SIMDE_FLOAT32_C(10.0), -HEDLEY_STATIC_CAST(float, precision));
563 }
564
565 static double
simde_test_f64_precision_to_slop(int precision)566 simde_test_f64_precision_to_slop(int precision) {
567 return simde_math_pow(SIMDE_FLOAT64_C(10.0), -HEDLEY_STATIC_CAST(double, precision));
568 }
569
570 static int
simde_assert_equal_vf32_(size_t vec_len,simde_float32 const a[HEDLEY_ARRAY_PARAM (vec_len)],simde_float32 const b[HEDLEY_ARRAY_PARAM (vec_len)],simde_float32 slop,const char * filename,int line,const char * astr,const char * bstr)571 simde_assert_equal_vf32_(
572 size_t vec_len, simde_float32 const a[HEDLEY_ARRAY_PARAM(vec_len)], simde_float32 const b[HEDLEY_ARRAY_PARAM(vec_len)], simde_float32 slop,
573 const char* filename, int line, const char* astr, const char* bstr) {
574 for (size_t i = 0 ; i < vec_len ; i++) {
575 if (HEDLEY_UNLIKELY(!simde_test_equal_f32(a[i], b[i], slop))) {
576 simde_test_debug_printf_("%s:%d: assertion failed: %s[%zu] ~= %s[%zu] (%f ~= %f)\n",
577 filename, line, astr, i, bstr, i, HEDLEY_STATIC_CAST(double, a[i]), HEDLEY_STATIC_CAST(double, b[i]));
578 SIMDE_TEST_ASSERT_RETURN(1);
579 }
580 }
581 return 0;
582 }
583 #define simde_assert_equal_vf32(vec_len, a, b, precision) simde_assert_equal_vf32_(vec_len, a, b, simde_test_f32_precision_to_slop(precision), __FILE__, __LINE__, #a, #b)
584
585 static int
simde_assert_equal_f32_(simde_float32 a,simde_float32 b,simde_float32 slop,const char * filename,int line,const char * astr,const char * bstr)586 simde_assert_equal_f32_(simde_float32 a, simde_float32 b, simde_float32 slop,
587 const char* filename, int line, const char* astr, const char* bstr) {
588 if (HEDLEY_UNLIKELY(!simde_test_equal_f32(a, b, slop))) {
589 simde_test_debug_printf_("%s:%d: assertion failed: %s ~= %s (%f ~= %f)\n",
590 filename, line, astr, bstr, HEDLEY_STATIC_CAST(double, a), HEDLEY_STATIC_CAST(double, b));
591 SIMDE_TEST_ASSERT_RETURN(1);
592 }
593 return 0;
594 }
595 #define simde_assert_equal_f32(a, b, precision) simde_assert_equal_f32_(a, b, simde_test_f32_precision_to_slop(precision), __FILE__, __LINE__, #a, #b)
596
597 static int
simde_assert_equal_vf64_(size_t vec_len,simde_float64 const a[HEDLEY_ARRAY_PARAM (vec_len)],simde_float64 const b[HEDLEY_ARRAY_PARAM (vec_len)],simde_float64 slop,const char * filename,int line,const char * astr,const char * bstr)598 simde_assert_equal_vf64_(
599 size_t vec_len, simde_float64 const a[HEDLEY_ARRAY_PARAM(vec_len)], simde_float64 const b[HEDLEY_ARRAY_PARAM(vec_len)], simde_float64 slop,
600 const char* filename, int line, const char* astr, const char* bstr) {
601 for (size_t i = 0 ; i < vec_len ; i++) {
602 if (HEDLEY_UNLIKELY(!simde_test_equal_f64(a[i], b[i], slop))) {
603 simde_test_debug_printf_("%s:%d: assertion failed: %s[%zu] ~= %s[%zu] (%f ~= %f)\n",
604 filename, line, astr, i, bstr, i, HEDLEY_STATIC_CAST(double, a[i]), HEDLEY_STATIC_CAST(double, b[i]));
605 SIMDE_TEST_ASSERT_RETURN(1);
606 }
607 }
608 return 0;
609 }
610 #define simde_assert_equal_vf64(vec_len, a, b, precision) simde_assert_equal_vf64_(vec_len, a, b, simde_test_f64_precision_to_slop(precision), __FILE__, __LINE__, #a, #b)
611
612 static int
simde_assert_equal_f64_(simde_float64 a,simde_float64 b,simde_float64 slop,const char * filename,int line,const char * astr,const char * bstr)613 simde_assert_equal_f64_(simde_float64 a, simde_float64 b, simde_float64 slop,
614 const char* filename, int line, const char* astr, const char* bstr) {
615 if (HEDLEY_UNLIKELY(!simde_test_equal_f64(a, b, slop))) {
616 simde_test_debug_printf_("%s:%d: assertion failed: %s ~= %s (%f ~= %f)\n",
617 filename, line, astr, bstr, a, b);
618 SIMDE_TEST_ASSERT_RETURN(1);
619 }
620 return 0;
621 }
622 #define simde_assert_equal_f64(a, b, precision) simde_assert_equal_f64_(a, b, simde_test_f64_precision_to_slop(precision), __FILE__, __LINE__, #a, #b)
623
624 #define SIMDE_TEST_GENERATE_ASSERT_EQUAL_FUNC_(T, symbol_identifier, fmt) \
625 static int \
626 simde_assert_equal_v##symbol_identifier##_( \
627 size_t vec_len, const T a[HEDLEY_ARRAY_PARAM(vec_len)], const T b[HEDLEY_ARRAY_PARAM(vec_len)], \
628 const char* filename, int line, const char* astr, const char* bstr) { \
629 for (size_t i = 0 ; i < vec_len ; i++) { \
630 if (HEDLEY_UNLIKELY(a[i] != b[i])) { \
631 simde_test_debug_printf_("%s:%d: assertion failed: %s[%zu] == %s[%zu] (%" fmt " == %" fmt ")\n", \
632 filename, line, astr, i, bstr, i, a[i], b[i]); \
633 SIMDE_TEST_ASSERT_RETURN(1); \
634 } \
635 } \
636 return 0; \
637 } \
638 \
639 static int \
640 simde_assert_equal_##symbol_identifier##_(T a, T b, \
641 const char* filename, int line, const char* astr, const char* bstr) { \
642 if (HEDLEY_UNLIKELY(a != b)) { \
643 simde_test_debug_printf_("%s:%d: assertion failed: %s == %s (%" fmt " == %" fmt ")\n", \
644 filename, line, astr, bstr, a, b); \
645 SIMDE_TEST_ASSERT_RETURN(1); \
646 } \
647 return 0; \
648 } \
649 \
650 static int \
651 simde_assert_close_v##symbol_identifier##_( \
652 size_t vec_len, const T a[HEDLEY_ARRAY_PARAM(vec_len)], const T b[HEDLEY_ARRAY_PARAM(vec_len)], const T slop, \
653 const char* filename, int line, const char* astr, const char* bstr) { \
654 for (size_t i = 0 ; i < vec_len ; i++) { \
655 if (((a[i] + slop) < b[i]) || ((a[i] - slop) > b[i])) { \
656 simde_test_debug_printf_("%s:%d: assertion failed: %s[%zu] == %s[%zu] (%" fmt " == %" fmt ")\n", \
657 filename, line, astr, i, bstr, i, a[i], b[i]); \
658 SIMDE_TEST_ASSERT_RETURN(1); \
659 } \
660 } \
661 return 0; \
662 } \
663 \
664 static int \
665 simde_assert_close_##symbol_identifier##_(T a, T b, T slop, \
666 const char* filename, int line, const char* astr, const char* bstr) { \
667 if (((a + slop) < b) || ((a - slop) > b)) { \
668 simde_test_debug_printf_("%s:%d: assertion failed: %s == %s +/- %" fmt " (%" fmt " == %" fmt ")\n", \
669 filename, line, astr, bstr, slop, a, b); \
670 SIMDE_TEST_ASSERT_RETURN(1); \
671 } \
672 return 0; \
673 }
674
675 static int
simde_assert_equal_i_(int a,int b,const char * filename,int line,const char * astr,const char * bstr)676 simde_assert_equal_i_(int a, int b, const char* filename, int line, const char* astr, const char* bstr) {
677 if (HEDLEY_UNLIKELY(a != b)) {
678 simde_test_debug_printf_("%s:%d: assertion failed: %s == %s (%d == %d)\n",
679 filename, line, astr, bstr, a, b);
680 SIMDE_TEST_ASSERT_RETURN(1);
681 }
682 return 0;
683 }
684
685 SIMDE_TEST_GENERATE_ASSERT_EQUAL_FUNC_(int8_t, i8, PRId8)
686 SIMDE_TEST_GENERATE_ASSERT_EQUAL_FUNC_(int16_t, i16, PRId16)
687 SIMDE_TEST_GENERATE_ASSERT_EQUAL_FUNC_(int32_t, i32, PRId32)
688 SIMDE_TEST_GENERATE_ASSERT_EQUAL_FUNC_(int64_t, i64, PRId64)
689 SIMDE_TEST_GENERATE_ASSERT_EQUAL_FUNC_(uint8_t, u8, PRIu8)
690 SIMDE_TEST_GENERATE_ASSERT_EQUAL_FUNC_(uint16_t, u16, PRIu16)
691 SIMDE_TEST_GENERATE_ASSERT_EQUAL_FUNC_(uint32_t, u32, PRIu32)
692 SIMDE_TEST_GENERATE_ASSERT_EQUAL_FUNC_(uint64_t, u64, PRIu64)
693
694 #define simde_assert_equal_vi8(vec_len, a, b) do { if (simde_assert_equal_vi8_(vec_len, a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
695 #define simde_assert_equal_vi16(vec_len, a, b) do { if (simde_assert_equal_vi16_(vec_len, a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
696 #define simde_assert_equal_vi32(vec_len, a, b) do { if (simde_assert_equal_vi32_(vec_len, a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
697 #define simde_assert_equal_vi64(vec_len, a, b) do { if (simde_assert_equal_vi64_(vec_len, a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
698 #define simde_assert_equal_vu8(vec_len, a, b) do { if (simde_assert_equal_vu8_(vec_len, a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
699 #define simde_assert_equal_vu16(vec_len, a, b) do { if (simde_assert_equal_vu16_(vec_len, a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
700 #define simde_assert_equal_vu32(vec_len, a, b) do { if (simde_assert_equal_vu32_(vec_len, a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
701 #define simde_assert_equal_vu64(vec_len, a, b) do { if (simde_assert_equal_vu64_(vec_len, a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
702
703 #define simde_assert_equal_i8(a, b) do { if (simde_assert_equal_i8_(a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
704 #define simde_assert_equal_i16(a, b) do { if (simde_assert_equal_i16_(a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
705 #define simde_assert_equal_i32(a, b) do { if (simde_assert_equal_i32_(a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
706 #define simde_assert_equal_i64(a, b) do { if (simde_assert_equal_i64_(a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
707 #define simde_assert_equal_u8(a, b) do { if (simde_assert_equal_u8_(a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
708 #define simde_assert_equal_u16(a, b) do { if (simde_assert_equal_u16_(a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
709 #define simde_assert_equal_u32(a, b) do { if (simde_assert_equal_u32_(a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
710 #define simde_assert_equal_u64(a, b) do { if (simde_assert_equal_u64_(a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
711 #define simde_assert_equal_i(a, b) do { if (simde_assert_equal_i_(a, b, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
712
713 #define simde_assert_close_vi8(vec_len, a, b, slop) do { if (simde_assert_close_vi8_(vec_len, a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
714 #define simde_assert_close_vi16(vec_len, a, b, slop) do { if (simde_assert_close_vi16_(vec_len, a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
715 #define simde_assert_close_vi32(vec_len, a, b, slop) do { if (simde_assert_close_vi32_(vec_len, a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
716 #define simde_assert_close_vi64(vec_len, a, b, slop) do { if (simde_assert_close_vi64_(vec_len, a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
717 #define simde_assert_close_vu8(vec_len, a, b, slop) do { if (simde_assert_close_vu8_(vec_len, a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
718 #define simde_assert_close_vu16(vec_len, a, b, slop) do { if (simde_assert_close_vu16_(vec_len, a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
719 #define simde_assert_close_vu32(vec_len, a, b, slop) do { if (simde_assert_close_vu32_(vec_len, a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
720 #define simde_assert_close_vu64(vec_len, a, b, slop) do { if (simde_assert_close_vu64_(vec_len, a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
721
722 #define simde_assert_close_i8(a, b, slop) do { if (simde_assert_close_i8_(a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
723 #define simde_assert_close_i16(a, b, slop) do { if (simde_assert_close_i16_(a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
724 #define simde_assert_close_i32(a, b, slop) do { if (simde_assert_close_i32_(a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
725 #define simde_assert_close_i64(a, b, slop) do { if (simde_assert_close_i64_(a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
726 #define simde_assert_close_u8(a, b, slop) do { if (simde_assert_close_u8_(a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
727 #define simde_assert_close_u16(a, b, slop) do { if (simde_assert_close_u16_(a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
728 #define simde_assert_close_u32(a, b, slop) do { if (simde_assert_close_u32_(a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
729 #define simde_assert_close_u64(a, b, slop) do { if (simde_assert_close_u64_(a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
730 #define simde_assert_close_i(a, b, slop) do { if (simde_assert_close_i_(a, b, slop, __FILE__, __LINE__, #a, #b)) { return 1; } } while (0)
731
732 /* Since each test is compiled in 4 different versions (C/C++ and
733 * native/emul), we need to be able to generate different symbols
734 * depending on preprocessor macros. */
735 #if defined(SIMDE_NO_NATIVE)
736 #if defined(__cplusplus)
737 #define SIMDE_TEST_GENERATE_VARIANT_SYMBOL_CURRENT(name) HEDLEY_CONCAT(name,_emul_cpp)
738 #define SIMDE_TEST_GENERATE_VARIANT_NAME_CURRENT(name) #name "/emul/cpp"
739 #else
740 #define SIMDE_TEST_GENERATE_VARIANT_SYMBOL_CURRENT(name) HEDLEY_CONCAT(name,_emul_c)
741 #define SIMDE_TEST_GENERATE_VARIANT_NAME_CURRENT(name) #name "/emul/c"
742 #endif
743 #else
744 #if defined(__cplusplus)
745 #define SIMDE_TEST_GENERATE_VARIANT_SYMBOL_CURRENT(name) HEDLEY_CONCAT(name,_native_cpp)
746 #define SIMDE_TEST_GENERATE_VARIANT_NAME_CURRENT(name) #name "/native/cpp"
747 #else
748 #define SIMDE_TEST_GENERATE_VARIANT_SYMBOL_CURRENT(name) HEDLEY_CONCAT(name,_native_c)
749 #define SIMDE_TEST_GENERATE_VARIANT_NAME_CURRENT(name) #name "/native/c"
750 #endif
751 #endif
752
753 /* The bare version basically assumes you just want to run a single
754 * test suite. It doesn't use munit, or any other dependencies so
755 * it's easy to use with creduce. */
756 #if defined(SIMDE_TEST_BARE)
757 #define SIMDE_TEST_FUNC_LIST_BEGIN static const struct { int (* func)(void); const char* name; } test_suite_tests[] = {
758 #define SIMDE_TEST_FUNC_LIST_ENTRY(name) { test_simde_##name, #name },
759 #define SIMDE_TEST_FUNC_LIST_END };
760 #define SIMDE_MUNIT_TEST_ARGS void
761 #else
762 HEDLEY_DIAGNOSTIC_PUSH
763 SIMDE_DIAGNOSTIC_DISABLE_CPP98_COMPAT_PEDANTIC_
764 SIMDE_DIAGNOSTIC_DISABLE_OLD_STYLE_CAST_
765 SIMDE_DIAGNOSTIC_DISABLE_VARIADIC_MACROS_
766 SIMDE_DIAGNOSTIC_DISABLE_RESERVED_ID_MACRO_
767 #include "munit/munit.h"
768 HEDLEY_DIAGNOSTIC_POP
769
770 #if \
771 HEDLEY_HAS_ATTRIBUTE(unused) || \
772 HEDLEY_GCC_VERSION_CHECK(3,1,0)
773 #define SIMDE_MUNIT_TEST_ARGS __attribute__((__unused__)) const MunitParameter params[], __attribute__((__unused__)) void* data
774 #else
775 /* Compilers other than emscripten are fine with casting away
776 * arguments. */
777 #define SIMDE_MUNIT_TEST_ARGS void
778 #endif
779
780 #define SIMDE_TEST_FUNC_LIST_BEGIN static MunitTest test_suite_tests[] = {
781 #if defined(__cplusplus)
782 #define SIMDE_TEST_FUNC_LIST_ENTRY(name) { \
783 const_cast<char*>("/" SIMDE_TEST_GENERATE_VARIANT_NAME_CURRENT(name)), \
784 HEDLEY_REINTERPRET_CAST(MunitTestFunc, test_simde_##name), \
785 NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
786 #else
787 #define SIMDE_TEST_FUNC_LIST_ENTRY(name) { \
788 (char*) "/" SIMDE_TEST_GENERATE_VARIANT_NAME_CURRENT(name), \
789 HEDLEY_REINTERPRET_CAST(MunitTestFunc, test_simde_##name), \
790 NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
791 #endif
792 #define SIMDE_TEST_FUNC_LIST_END { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } };
793
794 #define SIMDE_TEST_SUITE_DECLARE_GETTERS(name) \
795 HEDLEY_C_DECL MunitSuite* HEDLEY_CONCAT(name, _native_c)(void); \
796 HEDLEY_C_DECL MunitSuite* HEDLEY_CONCAT(name, _emul_c)(void); \
797 HEDLEY_C_DECL MunitSuite* HEDLEY_CONCAT(name, _native_cpp)(void); \
798 HEDLEY_C_DECL MunitSuite* HEDLEY_CONCAT(name, _emul_cpp)(void);
799 #endif
800
801 #endif /* !defined(SIMDE_TESTS_H) */
802