git subrepo pull --force deps/lightrec
[pcsx_rearmed.git] / deps / lightning / check / carg.c
1 #include <lightning.h>
2 #include <stdio.h>
3
4 /*   Simple test for arguments handling, that also shows how to use
5  * arguments to store values.
6  *   Register arguments, if available, are very fast, but are also
7  * very volatile on some ports, because some ports will do C calls
8  * to implement division, remainder, sometimes multiplication, or
9  * some float operations.
10  *   Arguments in registers should be fetched in the prolog of the
11  * function, and if they must be saved, they should be saved in
12  * the prolog.
13  *   The predicate macro "jit_arg_register_p(arg)" allows knowing if
14  * an argument lives in a register, where it is known for being a very
15  * fast to read/write temporary storage.
16  */
17
18 #define W               jit_word_t
19 #define F               jit_float32_t
20 #define D               jit_float64_t
21
22 jit_state_t              *_jit;
23
24 void
25 cw(W a1, W  a2, W  a3, W  a4, W  a5, W  a6, W  a7, W  a8,
26    W a9, W a10, W a11, W a12, W a13, W a14, W a15, W a16)
27 {
28     if ( a1 !=  1 ||  a2 !=  2 ||  a3 !=  3 ||  a4 !=  4 ||
29          a5 !=  5 ||  a6 !=  6 ||  a7 !=  7 ||  a8 !=  8 ||
30          a9 !=  9 || a10 != 10 || a11 != 11 || a12 != 12 ||
31         a13 != 13 || a14 != 14 || a15 != 15 || a16 != 16)
32         abort();
33 }
34
35 void
36 cf(F a1, F  a2, F  a3, F  a4, F  a5, F  a6, F  a7, F  a8,
37    F a9, F a10, F a11, F a12, F a13, F a14, F a15, F a16)
38 {
39     if ( a1 !=  1 ||  a2 !=  2 ||  a3 !=  3 ||  a4 !=  4 ||
40          a5 !=  5 ||  a6 !=  6 ||  a7 !=  7 ||  a8 !=  8 ||
41          a9 !=  9 || a10 != 10 || a11 != 11 || a12 != 12 ||
42         a13 != 13 || a14 != 14 || a15 != 15 || a16 != 16)
43         abort();
44 }
45
46 void
47 cd(D a1, D  a2, D  a3, D  a4, D  a5, D  a6, D  a7, D  a8,
48    D a9, D a10, D a11, D a12, D a13, D a14, D a15, D a16)
49 {
50     if ( a1 !=  1 ||  a2 !=  2 ||  a3 !=  3 ||  a4 !=  4 ||
51          a5 !=  5 ||  a6 !=  6 ||  a7 !=  7 ||  a8 !=  8 ||
52          a9 !=  9 || a10 != 10 || a11 != 11 || a12 != 12 ||
53         a13 != 13 || a14 != 14 || a15 != 15 || a16 != 16)
54         abort();
55 }
56
57 int
58 main(int argc, char *argv[])
59 {
60     void                (*code)(void);
61     jit_node_t          *jmp, *pass, *fail;
62     jit_node_t           *jw, *jf, *jd;
63     jit_int32_t           s1,   s2,   s3,   s4,   s5,   s6,   s7,   s8,
64                           s9,  s10,  s11,  s12,  s13,  s14,  s15,  s16;
65     jit_node_t           *a1,  *a2,  *a3,  *a4,  *a5,  *a6,  *a7,  *a8,
66                          *a9, *a10, *a11, *a12, *a13, *a14, *a15, *a16;
67
68     init_jit(argv[0]);
69     _jit = jit_new_state();
70
71     /* jump to "main" label */
72     jmp = jit_jmpi();
73
74     /* Create jit function that
75      * o Receives 16 word arguments
76      * o Save in the stack any register argument. Also force register
77      *   arguments to be clobbered to properly make the test
78      * o Calls a C function that receives 16 word arguments, with
79      *   values different from the ones received by this function
80      * o Reload from stack any register argument
81      * o Validated all arguments were not modified in the known
82      *   cases it could have been clobbered
83      */
84     jw = jit_label();
85     jit_name("jw");
86     jit_note(__FILE__, __LINE__);
87     jit_prolog();
88     a1  = jit_arg();
89     a2  = jit_arg();
90     a3  = jit_arg();
91     a4  = jit_arg();
92     a5  = jit_arg();
93     a6  = jit_arg();
94     a7  = jit_arg();
95     a8  = jit_arg();
96     a9  = jit_arg();
97     a10 = jit_arg();
98     a11 = jit_arg();
99     a12 = jit_arg();
100     a13 = jit_arg();
101     a14 = jit_arg();
102     a15 = jit_arg();
103     a16 = jit_arg();
104 #define SAVE_ARG(N)                                                     \
105     do {                                                                \
106         if (jit_arg_register_p(a##N)) {                                 \
107             s##N = jit_allocai(sizeof(W));                              \
108             jit_getarg(JIT_R0, a##N);                                   \
109             jit_stxi(s##N, JIT_FP, JIT_R0);                             \
110             jit_putargi(-1, a##N);                                      \
111         }                                                               \
112     } while (0)
113     SAVE_ARG(1);
114     SAVE_ARG(2);
115     SAVE_ARG(3);
116     SAVE_ARG(4);
117     SAVE_ARG(5);
118     SAVE_ARG(6);
119     SAVE_ARG(7);
120     SAVE_ARG(8);
121     SAVE_ARG(9);
122     SAVE_ARG(10);
123     SAVE_ARG(11);
124     SAVE_ARG(12);
125     SAVE_ARG(13);
126     SAVE_ARG(14);
127     SAVE_ARG(15);
128     SAVE_ARG(16);
129 #undef SAVE_ARG
130     jit_prepare();
131     {
132         jit_pushargi(1);
133         jit_pushargi(2);
134         jit_pushargi(3);
135         jit_pushargi(4);
136         jit_pushargi(5);
137         jit_pushargi(6);
138         jit_pushargi(7);
139         jit_pushargi(8);
140         jit_pushargi(9);
141         jit_pushargi(10);
142         jit_pushargi(11);
143         jit_pushargi(12);
144         jit_pushargi(13);
145         jit_pushargi(14);
146         jit_pushargi(15);
147         jit_pushargi(16);
148     }
149     jit_finishi(cw);
150 #define LOAD_ARG(N)                                                     \
151     do {                                                                \
152         if (jit_arg_register_p(a##N)) {                                 \
153             jit_ldxi(JIT_R0, JIT_FP, s##N);                             \
154             jit_putargr(JIT_R0, a##N);                                  \
155         }                                                               \
156     } while (0)
157     LOAD_ARG(1);
158     LOAD_ARG(2);
159     LOAD_ARG(3);
160     LOAD_ARG(4);
161     LOAD_ARG(5);
162     LOAD_ARG(6);
163     LOAD_ARG(7);
164     LOAD_ARG(8);
165     LOAD_ARG(9);
166     LOAD_ARG(10);
167     LOAD_ARG(11);
168     LOAD_ARG(12);
169     LOAD_ARG(13);
170     LOAD_ARG(14);
171     LOAD_ARG(15);
172     LOAD_ARG(16);
173 #undef LOAD_ARG
174     pass = jit_forward();
175     fail = jit_forward();
176 #define CHECK_ARG(N)                                                    \
177     do {                                                                \
178         jit_getarg(JIT_R0, a##N);                                       \
179         jit_patch_at(jit_bnei(JIT_R0, 17 - N), fail);                   \
180     } while (0)
181     CHECK_ARG(1);
182     CHECK_ARG(2);
183     CHECK_ARG(3);
184     CHECK_ARG(4);
185     CHECK_ARG(5);
186     CHECK_ARG(6);
187     CHECK_ARG(7);
188     CHECK_ARG(8);
189     CHECK_ARG(9);
190     CHECK_ARG(10);
191     CHECK_ARG(11);
192     CHECK_ARG(12);
193     CHECK_ARG(13);
194     CHECK_ARG(14);
195     CHECK_ARG(15);
196     CHECK_ARG(16);
197 #undef CHECK_ARG
198     jit_patch_at(jit_jmpi(), pass);
199     jit_link(fail);
200     jit_calli(abort);
201     jit_link(pass);
202     jit_ret();
203     jit_epilog();
204
205     /* Create jit function that
206      * o Receives 16 float arguments
207      * o Save in the stack any register argument. Also force register
208      *   arguments to be clobbered to properly make the test
209      * o Calls a C function that receives 16 float arguments, with
210      *   values different from the ones received by this function
211      * o Reload from stack any register argument
212      * o Validated all arguments were not modified in the known
213      *   cases it could have been clobbered
214      */
215     jf = jit_label();
216     jit_name("jf");
217     jit_note(__FILE__, __LINE__);
218     jit_prolog();
219     a1  = jit_arg_f();
220     a2  = jit_arg_f();
221     a3  = jit_arg_f();
222     a4  = jit_arg_f();
223     a5  = jit_arg_f();
224     a6  = jit_arg_f();
225     a7  = jit_arg_f();
226     a8  = jit_arg_f();
227     a9  = jit_arg_f();
228     a10 = jit_arg_f();
229     a11 = jit_arg_f();
230     a12 = jit_arg_f();
231     a13 = jit_arg_f();
232     a14 = jit_arg_f();
233     a15 = jit_arg_f();
234     a16 = jit_arg_f();
235 #define SAVE_ARG(N)                                                     \
236     do {                                                                \
237         if (jit_arg_register_p(a##N)) {                                 \
238             s##N = jit_allocai(sizeof(F));                              \
239             jit_getarg_f(JIT_F0, a##N);                                 \
240             jit_stxi_f(s##N, JIT_FP, JIT_F0);                           \
241             jit_putargi_f(-1, a##N);                                    \
242         }                                                               \
243     } while (0)
244     SAVE_ARG(1);
245     SAVE_ARG(2);
246     SAVE_ARG(3);
247     SAVE_ARG(4);
248     SAVE_ARG(5);
249     SAVE_ARG(6);
250     SAVE_ARG(7);
251     SAVE_ARG(8);
252     SAVE_ARG(9);
253     SAVE_ARG(10);
254     SAVE_ARG(11);
255     SAVE_ARG(12);
256     SAVE_ARG(13);
257     SAVE_ARG(14);
258     SAVE_ARG(15);
259     SAVE_ARG(16);
260 #undef SAVE_ARG
261     jit_prepare();
262     {
263         jit_pushargi_f(1);
264         jit_pushargi_f(2);
265         jit_pushargi_f(3);
266         jit_pushargi_f(4);
267         jit_pushargi_f(5);
268         jit_pushargi_f(6);
269         jit_pushargi_f(7);
270         jit_pushargi_f(8);
271         jit_pushargi_f(9);
272         jit_pushargi_f(10);
273         jit_pushargi_f(11);
274         jit_pushargi_f(12);
275         jit_pushargi_f(13);
276         jit_pushargi_f(14);
277         jit_pushargi_f(15);
278         jit_pushargi_f(16);
279     }
280     jit_finishi(cf);
281 #define LOAD_ARG(N)                                                     \
282     do {                                                                \
283         if (jit_arg_register_p(a##N)) {                                 \
284             jit_ldxi_f(JIT_F0, JIT_FP, s##N);                           \
285             jit_putargr_f(JIT_F0, a##N);                                \
286         }                                                               \
287     } while (0)
288     LOAD_ARG(1);
289     LOAD_ARG(2);
290     LOAD_ARG(3);
291     LOAD_ARG(4);
292     LOAD_ARG(5);
293     LOAD_ARG(6);
294     LOAD_ARG(7);
295     LOAD_ARG(8);
296     LOAD_ARG(9);
297     LOAD_ARG(10);
298     LOAD_ARG(11);
299     LOAD_ARG(12);
300     LOAD_ARG(13);
301     LOAD_ARG(14);
302     LOAD_ARG(15);
303     LOAD_ARG(16);
304 #undef LOAD_ARG
305     pass = jit_forward();
306     fail = jit_forward();
307 #define CHECK_ARG(N)                                                    \
308     do {                                                                \
309         jit_getarg_f(JIT_F0, a##N);                                     \
310         jit_patch_at(jit_bnei_f(JIT_F0, 17 - N), fail);                 \
311     } while (0)
312     CHECK_ARG(1);
313     CHECK_ARG(2);
314     CHECK_ARG(3);
315     CHECK_ARG(4);
316     CHECK_ARG(5);
317     CHECK_ARG(6);
318     CHECK_ARG(7);
319     CHECK_ARG(8);
320     CHECK_ARG(9);
321     CHECK_ARG(10);
322     CHECK_ARG(11);
323     CHECK_ARG(12);
324     CHECK_ARG(13);
325     CHECK_ARG(14);
326     CHECK_ARG(15);
327     CHECK_ARG(16);
328 #undef CHECK_ARG
329     jit_patch_at(jit_jmpi(), pass);
330     jit_link(fail);
331     jit_calli(abort);
332     jit_link(pass);
333     jit_ret();
334     jit_epilog();
335
336     /* Create jit function that
337      * o Receives 16 double arguments
338      * o Save in the stack any register argument. Also force register
339      *   arguments to be clobbered to properly make the test
340      * o Calls a C function that receives 16 double arguments, with
341      *   values different from the ones received by this function
342      * o Reload from stack any register argument
343      * o Validated all arguments were not modified in the known
344      *   cases it could have been clobbered
345      */
346     jd = jit_label();
347     jit_name("jd");
348     jit_note(__FILE__, __LINE__);
349     jit_prolog();
350     a1  = jit_arg_d();
351     a2  = jit_arg_d();
352     a3  = jit_arg_d();
353     a4  = jit_arg_d();
354     a5  = jit_arg_d();
355     a6  = jit_arg_d();
356     a7  = jit_arg_d();
357     a8  = jit_arg_d();
358     a9  = jit_arg_d();
359     a10 = jit_arg_d();
360     a11 = jit_arg_d();
361     a12 = jit_arg_d();
362     a13 = jit_arg_d();
363     a14 = jit_arg_d();
364     a15 = jit_arg_d();
365     a16 = jit_arg_d();
366 #define SAVE_ARG(N)                                                     \
367     do {                                                                \
368         if (jit_arg_register_p(a##N)) {                                 \
369             s##N = jit_allocai(sizeof(D));                              \
370             jit_getarg_d(JIT_F0, a##N);                                 \
371             jit_stxi_d(s##N, JIT_FP, JIT_F0);                           \
372             jit_putargi_d(-1, a##N);                                    \
373         }                                                               \
374     } while (0)
375     SAVE_ARG(1);
376     SAVE_ARG(2);
377     SAVE_ARG(3);
378     SAVE_ARG(4);
379     SAVE_ARG(5);
380     SAVE_ARG(6);
381     SAVE_ARG(7);
382     SAVE_ARG(8);
383     SAVE_ARG(9);
384     SAVE_ARG(10);
385     SAVE_ARG(11);
386     SAVE_ARG(12);
387     SAVE_ARG(13);
388     SAVE_ARG(14);
389     SAVE_ARG(15);
390     SAVE_ARG(16);
391 #undef SAVE_ARG
392     jit_prepare();
393     {
394         jit_pushargi_d(1);
395         jit_pushargi_d(2);
396         jit_pushargi_d(3);
397         jit_pushargi_d(4);
398         jit_pushargi_d(5);
399         jit_pushargi_d(6);
400         jit_pushargi_d(7);
401         jit_pushargi_d(8);
402         jit_pushargi_d(9);
403         jit_pushargi_d(10);
404         jit_pushargi_d(11);
405         jit_pushargi_d(12);
406         jit_pushargi_d(13);
407         jit_pushargi_d(14);
408         jit_pushargi_d(15);
409         jit_pushargi_d(16);
410     }
411     jit_finishi(cd);
412 #define LOAD_ARG(N)                                                     \
413     do {                                                                \
414         if (jit_arg_register_p(a##N)) {                                 \
415             jit_ldxi_d(JIT_F0, JIT_FP, s##N);                           \
416             jit_putargr_d(JIT_F0, a##N);                                \
417         }                                                               \
418     } while (0)
419     LOAD_ARG(1);
420     LOAD_ARG(2);
421     LOAD_ARG(3);
422     LOAD_ARG(4);
423     LOAD_ARG(5);
424     LOAD_ARG(6);
425     LOAD_ARG(7);
426     LOAD_ARG(8);
427     LOAD_ARG(9);
428     LOAD_ARG(10);
429     LOAD_ARG(11);
430     LOAD_ARG(12);
431     LOAD_ARG(13);
432     LOAD_ARG(14);
433     LOAD_ARG(15);
434     LOAD_ARG(16);
435 #undef LOAD_ARG
436     pass = jit_forward();
437     fail = jit_forward();
438 #define CHECK_ARG(N)                                                    \
439     do {                                                                \
440         jit_getarg_d(JIT_F0, a##N);                                     \
441         jit_patch_at(jit_bnei_d(JIT_F0, 17 - N), fail);                 \
442     } while (0)
443     CHECK_ARG(1);
444     CHECK_ARG(2);
445     CHECK_ARG(3);
446     CHECK_ARG(4);
447     CHECK_ARG(5);
448     CHECK_ARG(6);
449     CHECK_ARG(7);
450     CHECK_ARG(8);
451     CHECK_ARG(9);
452     CHECK_ARG(10);
453     CHECK_ARG(11);
454     CHECK_ARG(12);
455     CHECK_ARG(13);
456     CHECK_ARG(14);
457     CHECK_ARG(15);
458     CHECK_ARG(16);
459 #undef CHECK_ARG
460     jit_patch_at(jit_jmpi(), pass);
461     jit_link(fail);
462     jit_calli(abort);
463     jit_link(pass);
464     jit_ret();
465     jit_epilog();
466
467     /* Create a jit function that calls the 3 previous ones.
468      * o First call the function that receives 16 word arguments
469      * o Then call the function that receives 16 float arguments
470      * o Finally call the function that receives 16 double arguments
471      */
472     jit_patch(jmp);
473     jit_name("main");
474     jit_note(__FILE__, __LINE__);
475     jit_prolog();
476     jit_prepare();
477     {
478         jit_pushargi(16);
479         jit_pushargi(15);
480         jit_pushargi(14);
481         jit_pushargi(13);
482         jit_pushargi(12);
483         jit_pushargi(11);
484         jit_pushargi(10);
485         jit_pushargi(9);
486         jit_pushargi(8);
487         jit_pushargi(7);
488         jit_pushargi(6);
489         jit_pushargi(5);
490         jit_pushargi(4);
491         jit_pushargi(3);
492         jit_pushargi(2);
493         jit_pushargi(1);
494     }
495     jit_patch_at(jit_finishi(NULL), jw);
496
497     jit_prepare();
498     {
499         jit_pushargi_f(16);
500         jit_pushargi_f(15);
501         jit_pushargi_f(14);
502         jit_pushargi_f(13);
503         jit_pushargi_f(12);
504         jit_pushargi_f(11);
505         jit_pushargi_f(10);
506         jit_pushargi_f(9);
507         jit_pushargi_f(8);
508         jit_pushargi_f(7);
509         jit_pushargi_f(6);
510         jit_pushargi_f(5);
511         jit_pushargi_f(4);
512         jit_pushargi_f(3);
513         jit_pushargi_f(2);
514         jit_pushargi_f(1);
515     }
516     jit_patch_at(jit_finishi(NULL), jf);
517
518     jit_prepare();
519     {
520         jit_pushargi_d(16);
521         jit_pushargi_d(15);
522         jit_pushargi_d(14);
523         jit_pushargi_d(13);
524         jit_pushargi_d(12);
525         jit_pushargi_d(11);
526         jit_pushargi_d(10);
527         jit_pushargi_d(9);
528         jit_pushargi_d(8);
529         jit_pushargi_d(7);
530         jit_pushargi_d(6);
531         jit_pushargi_d(5);
532         jit_pushargi_d(4);
533         jit_pushargi_d(3);
534         jit_pushargi_d(2);
535         jit_pushargi_d(1);
536     }
537     jit_patch_at(jit_finishi(NULL), jd);
538     jit_ret();
539     jit_epilog();
540
541     code = jit_emit();
542     jit_clear_state();
543
544     (*code)();
545
546     jit_destroy_state();
547     finish_jit();
548     return (0);
549 }