1#include "shared.rsh"
2
3// Testing math library
4
5volatile float f1;
6volatile float2 f2;
7volatile float3 f3;
8volatile float4 f4;
9
10volatile int i1;
11volatile int2 i2;
12volatile int3 i3;
13volatile int4 i4;
14
15volatile uint ui1;
16volatile uint2 ui2;
17volatile uint3 ui3;
18volatile uint4 ui4;
19
20volatile short s1;
21volatile short2 s2;
22volatile short3 s3;
23volatile short4 s4;
24
25volatile ushort us1;
26volatile ushort2 us2;
27volatile ushort3 us3;
28volatile ushort4 us4;
29
30volatile char c1;
31volatile char2 c2;
32volatile char3 c3;
33volatile char4 c4;
34
35volatile uchar uc1;
36volatile uchar2 uc2;
37volatile uchar3 uc3;
38volatile uchar4 uc4;
39
40#define DECL_INT(prefix)            \
41volatile char prefix##_c_1 = 1;     \
42volatile char2 prefix##_c_2 = 1;    \
43volatile char3 prefix##_c_3 = 1;    \
44volatile char4 prefix##_c_4 = 1;    \
45volatile uchar prefix##_uc_1 = 1;   \
46volatile uchar2 prefix##_uc_2 = 1;  \
47volatile uchar3 prefix##_uc_3 = 1;  \
48volatile uchar4 prefix##_uc_4 = 1;  \
49volatile short prefix##_s_1 = 1;    \
50volatile short2 prefix##_s_2 = 1;   \
51volatile short3 prefix##_s_3 = 1;   \
52volatile short4 prefix##_s_4 = 1;   \
53volatile ushort prefix##_us_1 = 1;  \
54volatile ushort2 prefix##_us_2 = 1; \
55volatile ushort3 prefix##_us_3 = 1; \
56volatile ushort4 prefix##_us_4 = 1; \
57volatile int prefix##_i_1 = 1;      \
58volatile int2 prefix##_i_2 = 1;     \
59volatile int3 prefix##_i_3 = 1;     \
60volatile int4 prefix##_i_4 = 1;     \
61volatile uint prefix##_ui_1 = 1;    \
62volatile uint2 prefix##_ui_2 = 1;   \
63volatile uint3 prefix##_ui_3 = 1;   \
64volatile uint4 prefix##_ui_4 = 1;   \
65volatile long prefix##_l_1 = 1;     \
66volatile ulong prefix##_ul_1 = 1;
67
68DECL_INT(res)
69DECL_INT(src1)
70DECL_INT(src2)
71
72#define TEST_INT_OP_TYPE(op, type)                      \
73rsDebug("Testing " #op " for " #type "1", i++);         \
74res_##type##_1 = src1_##type##_1 op src2_##type##_1;    \
75rsDebug("Testing " #op " for " #type "2", i++);         \
76res_##type##_2 = src1_##type##_2 op src2_##type##_2;    \
77rsDebug("Testing " #op " for " #type "3", i++);         \
78res_##type##_3 = src1_##type##_3 op src2_##type##_3;    \
79rsDebug("Testing " #op " for " #type "4", i++);         \
80res_##type##_4 = src1_##type##_4 op src2_##type##_4;
81
82#define TEST_INT_OP(op)                     \
83TEST_INT_OP_TYPE(op, c)                     \
84TEST_INT_OP_TYPE(op, uc)                    \
85TEST_INT_OP_TYPE(op, s)                     \
86TEST_INT_OP_TYPE(op, us)                    \
87TEST_INT_OP_TYPE(op, i)                     \
88TEST_INT_OP_TYPE(op, ui)                    \
89rsDebug("Testing " #op " for l1", i++);     \
90res_l_1 = src1_l_1 op src2_l_1;             \
91rsDebug("Testing " #op " for ul1", i++);    \
92res_ul_1 = src1_ul_1 op src2_ul_1;
93
94#define TEST_XN_FUNC_YN(typeout, fnc, typein)   \
95    res_##typeout##_1 = fnc(src1_##typein##_1); \
96    res_##typeout##_2 = fnc(src1_##typein##_2); \
97    res_##typeout##_3 = fnc(src1_##typein##_3); \
98    res_##typeout##_4 = fnc(src1_##typein##_4);
99
100#define TEST_XN_FUNC_XN_XN(type, fnc)                       \
101    res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1); \
102    res_##type##_2 = fnc(src1_##type##_2, src2_##type##_2); \
103    res_##type##_3 = fnc(src1_##type##_3, src2_##type##_3); \
104    res_##type##_4 = fnc(src1_##type##_4, src2_##type##_4);
105
106#define TEST_X_FUNC_X_X_X(type, fnc)    \
107    res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1, src2_##type##_1);
108
109#define TEST_IN_FUNC_IN(fnc)        \
110    rsDebug("Testing " #fnc, 0);    \
111    TEST_XN_FUNC_YN(uc, fnc, uc)    \
112    TEST_XN_FUNC_YN(c, fnc, c)      \
113    TEST_XN_FUNC_YN(us, fnc, us)    \
114    TEST_XN_FUNC_YN(s, fnc, s)      \
115    TEST_XN_FUNC_YN(ui, fnc, ui)    \
116    TEST_XN_FUNC_YN(i, fnc, i)
117
118#define TEST_UIN_FUNC_IN(fnc)       \
119    rsDebug("Testing " #fnc, 0);    \
120    TEST_XN_FUNC_YN(uc, fnc, c)     \
121    TEST_XN_FUNC_YN(us, fnc, s)     \
122    TEST_XN_FUNC_YN(ui, fnc, i)     \
123
124#define TEST_IN_FUNC_IN_IN(fnc)     \
125    rsDebug("Testing " #fnc, 0);    \
126    TEST_XN_FUNC_XN_XN(uc, fnc)     \
127    TEST_XN_FUNC_XN_XN(c, fnc)      \
128    TEST_XN_FUNC_XN_XN(us, fnc)     \
129    TEST_XN_FUNC_XN_XN(s, fnc)      \
130    TEST_XN_FUNC_XN_XN(ui, fnc)     \
131    TEST_XN_FUNC_XN_XN(i, fnc)
132
133#define TEST_I_FUNC_I_I_I(fnc)      \
134    rsDebug("Testing " #fnc, 0);    \
135    TEST_X_FUNC_X_X_X(uc, fnc)      \
136    TEST_X_FUNC_X_X_X(c, fnc)       \
137    TEST_X_FUNC_X_X_X(us, fnc)      \
138    TEST_X_FUNC_X_X_X(s, fnc)       \
139    TEST_X_FUNC_X_X_X(ui, fnc)      \
140    TEST_X_FUNC_X_X_X(i, fnc)
141
142#define TEST_FN_FUNC_FN(fnc)        \
143    rsDebug("Testing " #fnc, 0);    \
144    f1 = fnc(f1);                   \
145    f2 = fnc(f2);                   \
146    f3 = fnc(f3);                   \
147    f4 = fnc(f4);
148
149#define TEST_FN_FUNC_FN_PFN(fnc)    \
150    rsDebug("Testing " #fnc, 0);    \
151    f1 = fnc(f1, (float*) &f1);     \
152    f2 = fnc(f2, (float2*) &f2);    \
153    f3 = fnc(f3, (float3*) &f3);    \
154    f4 = fnc(f4, (float4*) &f4);
155
156#define TEST_FN_FUNC_FN_FN(fnc)     \
157    rsDebug("Testing " #fnc, 0);    \
158    f1 = fnc(f1, f1);               \
159    f2 = fnc(f2, f2);               \
160    f3 = fnc(f3, f3);               \
161    f4 = fnc(f4, f4);
162
163#define TEST_F34_FUNC_F34_F34(fnc)  \
164    rsDebug("Testing " #fnc, 0);    \
165    f3 = fnc(f3, f3);               \
166    f4 = fnc(f4, f4);
167
168#define TEST_FN_FUNC_FN_F(fnc)      \
169    rsDebug("Testing " #fnc, 0);    \
170    f1 = fnc(f1, f1);               \
171    f2 = fnc(f2, f1);               \
172    f3 = fnc(f3, f1);               \
173    f4 = fnc(f4, f1);
174
175#define TEST_F_FUNC_FN(fnc)         \
176    rsDebug("Testing " #fnc, 0);    \
177    f1 = fnc(f1);                   \
178    f1 = fnc(f2);                   \
179    f1 = fnc(f3);                   \
180    f1 = fnc(f4);
181
182#define TEST_F_FUNC_FN_FN(fnc)      \
183    rsDebug("Testing " #fnc, 0);    \
184    f1 = fnc(f1, f1);               \
185    f1 = fnc(f2, f2);               \
186    f1 = fnc(f3, f3);               \
187    f1 = fnc(f4, f4);
188
189#define TEST_FN_FUNC_FN_IN(fnc)     \
190    rsDebug("Testing " #fnc, 0);    \
191    f1 = fnc(f1, i1);               \
192    f2 = fnc(f2, i2);               \
193    f3 = fnc(f3, i3);               \
194    f4 = fnc(f4, i4);
195
196#define TEST_FN_FUNC_FN_I(fnc)      \
197    rsDebug("Testing " #fnc, 0);    \
198    f1 = fnc(f1, i1);               \
199    f2 = fnc(f2, i1);               \
200    f3 = fnc(f3, i1);               \
201    f4 = fnc(f4, i1);
202
203#define TEST_FN_FUNC_FN_FN_FN(fnc)  \
204    rsDebug("Testing " #fnc, 0);    \
205    f1 = fnc(f1, f1, f1);           \
206    f2 = fnc(f2, f2, f2);           \
207    f3 = fnc(f3, f3, f3);           \
208    f4 = fnc(f4, f4, f4);
209
210#define TEST_FN_FUNC_FN_FN_F(fnc)   \
211    rsDebug("Testing " #fnc, 0);    \
212    f1 = fnc(f1, f1, f1);           \
213    f2 = fnc(f2, f1, f1);           \
214    f3 = fnc(f3, f1, f1);           \
215    f4 = fnc(f4, f1, f1);
216
217#define TEST_FN_FUNC_FN_PIN(fnc)    \
218    rsDebug("Testing " #fnc, 0);    \
219    f1 = fnc(f1, (int*) &i1);       \
220    f2 = fnc(f2, (int2*) &i2);      \
221    f3 = fnc(f3, (int3*) &i3);      \
222    f4 = fnc(f4, (int4*) &i4);
223
224#define TEST_FN_FUNC_FN_FN_PIN(fnc) \
225    rsDebug("Testing " #fnc, 0);    \
226    f1 = fnc(f1, f1, (int*) &i1);   \
227    f2 = fnc(f2, f2, (int2*) &i2);  \
228    f3 = fnc(f3, f3, (int3*) &i3);  \
229    f4 = fnc(f4, f4, (int4*) &i4);
230
231#define TEST_IN_FUNC_FN(fnc)        \
232    rsDebug("Testing " #fnc, 0);    \
233    i1 = fnc(f1);                   \
234    i2 = fnc(f2);                   \
235    i3 = fnc(f3);                   \
236    i4 = fnc(f4);
237
238static bool test_fp_math(uint32_t index) {
239    bool failed = false;
240    start();
241
242    TEST_FN_FUNC_FN(acos);
243    TEST_FN_FUNC_FN(acosh);
244    TEST_FN_FUNC_FN(acospi);
245    TEST_FN_FUNC_FN(asin);
246    TEST_FN_FUNC_FN(asinh);
247    TEST_FN_FUNC_FN(asinpi);
248    TEST_FN_FUNC_FN(atan);
249    TEST_FN_FUNC_FN_FN(atan2);
250    TEST_FN_FUNC_FN(atanh);
251    TEST_FN_FUNC_FN(atanpi);
252    TEST_FN_FUNC_FN_FN(atan2pi);
253    TEST_FN_FUNC_FN(cbrt);
254    TEST_FN_FUNC_FN(ceil);
255    TEST_FN_FUNC_FN_FN_FN(clamp);
256    TEST_FN_FUNC_FN_FN_F(clamp);
257    TEST_FN_FUNC_FN_FN(copysign);
258    TEST_FN_FUNC_FN(cos);
259    TEST_FN_FUNC_FN(cosh);
260    TEST_FN_FUNC_FN(cospi);
261    TEST_F34_FUNC_F34_F34(cross);
262    TEST_FN_FUNC_FN(degrees);
263    TEST_F_FUNC_FN_FN(distance);
264    TEST_F_FUNC_FN_FN(dot);
265    TEST_FN_FUNC_FN(erfc);
266    TEST_FN_FUNC_FN(erf);
267    TEST_FN_FUNC_FN(exp);
268    TEST_FN_FUNC_FN(exp2);
269    TEST_FN_FUNC_FN(exp10);
270    TEST_FN_FUNC_FN(expm1);
271    TEST_FN_FUNC_FN(fabs);
272    TEST_FN_FUNC_FN_FN(fdim);
273    TEST_FN_FUNC_FN(floor);
274    TEST_FN_FUNC_FN_FN_FN(fma);
275    TEST_FN_FUNC_FN_FN(fmax);
276    TEST_FN_FUNC_FN_F(fmax);
277    TEST_FN_FUNC_FN_FN(fmin);
278    TEST_FN_FUNC_FN_F(fmin);
279    TEST_FN_FUNC_FN_FN(fmod);
280    TEST_FN_FUNC_FN_PFN(fract);
281    TEST_FN_FUNC_FN_PIN(frexp);
282    TEST_FN_FUNC_FN_FN(hypot);
283    TEST_IN_FUNC_FN(ilogb);
284    TEST_FN_FUNC_FN_IN(ldexp);
285    TEST_FN_FUNC_FN_I(ldexp);
286    TEST_F_FUNC_FN(length);
287    TEST_FN_FUNC_FN(lgamma);
288    TEST_FN_FUNC_FN_PIN(lgamma);
289    TEST_FN_FUNC_FN(log);
290    TEST_FN_FUNC_FN(log2);
291    TEST_FN_FUNC_FN(log10);
292    TEST_FN_FUNC_FN(log1p);
293    TEST_FN_FUNC_FN(logb);
294    TEST_FN_FUNC_FN_FN_FN(mad);
295    TEST_FN_FUNC_FN_FN(max);
296    TEST_FN_FUNC_FN_F(max);
297    TEST_FN_FUNC_FN_FN(min);
298    TEST_FN_FUNC_FN_F(min);
299    TEST_FN_FUNC_FN_FN_FN(mix);
300    TEST_FN_FUNC_FN_FN_F(mix);
301    TEST_FN_FUNC_FN_PFN(modf);
302    // nan
303    TEST_FN_FUNC_FN_FN(nextafter);
304    TEST_FN_FUNC_FN(normalize);
305    TEST_FN_FUNC_FN_FN(pow);
306    TEST_FN_FUNC_FN_IN(pown);
307    TEST_FN_FUNC_FN_FN(powr);
308    TEST_FN_FUNC_FN(radians);
309    TEST_FN_FUNC_FN_FN(remainder);
310    TEST_FN_FUNC_FN_FN_PIN(remquo);
311    TEST_FN_FUNC_FN(rint);
312    TEST_FN_FUNC_FN_IN(rootn);
313    TEST_FN_FUNC_FN(round);
314    TEST_FN_FUNC_FN(rsqrt);
315    TEST_FN_FUNC_FN(sign);
316    TEST_FN_FUNC_FN(sin);
317    TEST_FN_FUNC_FN_PFN(sincos);
318    TEST_FN_FUNC_FN(sinh);
319    TEST_FN_FUNC_FN(sinpi);
320    TEST_FN_FUNC_FN(sqrt);
321    TEST_FN_FUNC_FN_FN(step);
322    TEST_FN_FUNC_FN_F(step);
323    TEST_FN_FUNC_FN(tan);
324    TEST_FN_FUNC_FN(tanh);
325    TEST_FN_FUNC_FN(tanpi);
326    TEST_FN_FUNC_FN(tgamma);
327    TEST_FN_FUNC_FN(trunc);
328
329    float time = end(index);
330
331    if (failed) {
332        rsDebug("test_fp_math FAILED", time);
333    }
334    else {
335        rsDebug("test_fp_math PASSED", time);
336    }
337
338    return failed;
339}
340
341static bool test_int_math(uint32_t index) {
342    bool failed = false;
343    start();
344
345    TEST_UIN_FUNC_IN(abs);
346    TEST_IN_FUNC_IN(clz);
347    TEST_IN_FUNC_IN_IN(min);
348    TEST_IN_FUNC_IN_IN(max);
349    TEST_I_FUNC_I_I_I(rsClamp);
350
351    float time = end(index);
352
353    if (failed) {
354        rsDebug("test_int_math FAILED", time);
355    }
356    else {
357        rsDebug("test_int_math PASSED", time);
358    }
359
360    return failed;
361}
362
363static bool test_basic_operators() {
364    bool failed = false;
365    int i = 0;
366
367    TEST_INT_OP(+);
368    TEST_INT_OP(-);
369    TEST_INT_OP(*);
370    TEST_INT_OP(/);
371    TEST_INT_OP(%);
372    TEST_INT_OP(<<);
373    TEST_INT_OP(>>);
374
375    if (failed) {
376        rsDebug("test_basic_operators FAILED", 0);
377    }
378    else {
379        rsDebug("test_basic_operators PASSED", 0);
380    }
381
382    return failed;
383}
384
385#define TEST_CVT(to, from, type)                        \
386rsDebug("Testing convert from " #from " to " #to, 0);   \
387to##1 = from##1;                                        \
388to##2 = convert_##type##2(from##2);                     \
389to##3 = convert_##type##3(from##3);                     \
390to##4 = convert_##type##4(from##4);
391
392#define TEST_CVT_MATRIX(to, type)   \
393TEST_CVT(to, c, type);              \
394TEST_CVT(to, uc, type);             \
395TEST_CVT(to, s, type);              \
396TEST_CVT(to, us, type);             \
397TEST_CVT(to, i, type);              \
398TEST_CVT(to, ui, type);             \
399TEST_CVT(to, f, type);              \
400
401static bool test_convert() {
402    bool failed = false;
403
404    TEST_CVT_MATRIX(c, char);
405    TEST_CVT_MATRIX(uc, uchar);
406    TEST_CVT_MATRIX(s, short);
407    TEST_CVT_MATRIX(us, ushort);
408    TEST_CVT_MATRIX(i, int);
409    TEST_CVT_MATRIX(ui, uint);
410    TEST_CVT_MATRIX(f, float);
411
412    if (failed) {
413        rsDebug("test_convert FAILED", 0);
414    }
415    else {
416        rsDebug("test_convert PASSED", 0);
417    }
418
419    return failed;
420}
421
422void math_test(uint32_t index, int test_num) {
423    bool failed = false;
424    failed |= test_convert();
425    failed |= test_fp_math(index);
426    failed |= test_int_math(index);
427    failed |= test_basic_operators();
428
429    if (failed) {
430        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
431    }
432    else {
433        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
434    }
435}
436
437