Merge pull request #377 from pcercuei/libretro
[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;
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 #define CHECK_ARG(N)                                                    \
176     do {                                                                \
177         jit_getarg(JIT_R0, a##N);                                       \
178         jit_patch_at(jit_beqi(JIT_R0, 17 - N), pass);                   \
179     } while (0)
180     CHECK_ARG(1);
181     CHECK_ARG(2);
182     CHECK_ARG(3);
183     CHECK_ARG(4);
184     CHECK_ARG(5);
185     CHECK_ARG(6);
186     CHECK_ARG(7);
187     CHECK_ARG(8);
188     CHECK_ARG(9);
189     CHECK_ARG(10);
190     CHECK_ARG(11);
191     CHECK_ARG(12);
192     CHECK_ARG(13);
193     CHECK_ARG(14);
194     CHECK_ARG(15);
195     CHECK_ARG(16);
196 #undef CHECK_ARG
197     jit_calli(abort);
198     jit_link(pass);
199     jit_ret();
200     jit_epilog();
201
202     /* Create jit function that
203      * o Receives 16 float arguments
204      * o Save in the stack any register argument. Also force register
205      *   arguments to be clobbered to properly make the test
206      * o Calls a C function that receives 16 float arguments, with
207      *   values different from the ones received by this function
208      * o Reload from stack any register argument
209      * o Validated all arguments were not modified in the known
210      *   cases it could have been clobbered
211      */
212     jf = jit_label();
213     jit_name("jf");
214     jit_note(__FILE__, __LINE__);
215     jit_prolog();
216     a1  = jit_arg_f();
217     a2  = jit_arg_f();
218     a3  = jit_arg_f();
219     a4  = jit_arg_f();
220     a5  = jit_arg_f();
221     a6  = jit_arg_f();
222     a7  = jit_arg_f();
223     a8  = jit_arg_f();
224     a9  = jit_arg_f();
225     a10 = jit_arg_f();
226     a11 = jit_arg_f();
227     a12 = jit_arg_f();
228     a13 = jit_arg_f();
229     a14 = jit_arg_f();
230     a15 = jit_arg_f();
231     a16 = jit_arg_f();
232 #define SAVE_ARG(N)                                                     \
233     do {                                                                \
234         if (jit_arg_register_p(a##N)) {                                 \
235             s##N = jit_allocai(sizeof(F));                              \
236             jit_getarg_f(JIT_F0, a##N);                                 \
237             jit_stxi_f(s##N, JIT_FP, JIT_F0);                           \
238             jit_putargi_f(-1, a##N);                                    \
239         }                                                               \
240     } while (0)
241     SAVE_ARG(1);
242     SAVE_ARG(2);
243     SAVE_ARG(3);
244     SAVE_ARG(4);
245     SAVE_ARG(5);
246     SAVE_ARG(6);
247     SAVE_ARG(7);
248     SAVE_ARG(8);
249     SAVE_ARG(9);
250     SAVE_ARG(10);
251     SAVE_ARG(11);
252     SAVE_ARG(12);
253     SAVE_ARG(13);
254     SAVE_ARG(14);
255     SAVE_ARG(15);
256     SAVE_ARG(16);
257 #undef SAVE_ARG
258     jit_prepare();
259     {
260         jit_pushargi_f(1);
261         jit_pushargi_f(2);
262         jit_pushargi_f(3);
263         jit_pushargi_f(4);
264         jit_pushargi_f(5);
265         jit_pushargi_f(6);
266         jit_pushargi_f(7);
267         jit_pushargi_f(8);
268         jit_pushargi_f(9);
269         jit_pushargi_f(10);
270         jit_pushargi_f(11);
271         jit_pushargi_f(12);
272         jit_pushargi_f(13);
273         jit_pushargi_f(14);
274         jit_pushargi_f(15);
275         jit_pushargi_f(16);
276     }
277     jit_finishi(cf);
278 #define LOAD_ARG(N)                                                     \
279     do {                                                                \
280         if (jit_arg_register_p(a##N)) {                                 \
281             jit_ldxi_f(JIT_F0, JIT_FP, s##N);                           \
282             jit_putargr_f(JIT_F0, a##N);                                \
283         }                                                               \
284     } while (0)
285     LOAD_ARG(1);
286     LOAD_ARG(2);
287     LOAD_ARG(3);
288     LOAD_ARG(4);
289     LOAD_ARG(5);
290     LOAD_ARG(6);
291     LOAD_ARG(7);
292     LOAD_ARG(8);
293     LOAD_ARG(9);
294     LOAD_ARG(10);
295     LOAD_ARG(11);
296     LOAD_ARG(12);
297     LOAD_ARG(13);
298     LOAD_ARG(14);
299     LOAD_ARG(15);
300     LOAD_ARG(16);
301 #undef LOAD_ARG
302     pass = jit_forward();
303 #define CHECK_ARG(N)                                                    \
304     do {                                                                \
305         jit_getarg_f(JIT_F0, a##N);                                     \
306         jit_patch_at(jit_beqi_f(JIT_F0, 17 - N), pass);                 \
307     } while (0)
308     CHECK_ARG(1);
309     CHECK_ARG(2);
310     CHECK_ARG(3);
311     CHECK_ARG(4);
312     CHECK_ARG(5);
313     CHECK_ARG(6);
314     CHECK_ARG(7);
315     CHECK_ARG(8);
316     CHECK_ARG(9);
317     CHECK_ARG(10);
318     CHECK_ARG(11);
319     CHECK_ARG(12);
320     CHECK_ARG(13);
321     CHECK_ARG(14);
322     CHECK_ARG(15);
323     CHECK_ARG(16);
324 #undef CHECK_ARG
325     jit_calli(abort);
326     jit_link(pass);
327     jit_ret();
328     jit_epilog();
329
330     /* Create jit function that
331      * o Receives 16 double arguments
332      * o Save in the stack any register argument. Also force register
333      *   arguments to be clobbered to properly make the test
334      * o Calls a C function that receives 16 double arguments, with
335      *   values different from the ones received by this function
336      * o Reload from stack any register argument
337      * o Validated all arguments were not modified in the known
338      *   cases it could have been clobbered
339      */
340     jd = jit_label();
341     jit_name("jd");
342     jit_note(__FILE__, __LINE__);
343     jit_prolog();
344     a1  = jit_arg_d();
345     a2  = jit_arg_d();
346     a3  = jit_arg_d();
347     a4  = jit_arg_d();
348     a5  = jit_arg_d();
349     a6  = jit_arg_d();
350     a7  = jit_arg_d();
351     a8  = jit_arg_d();
352     a9  = jit_arg_d();
353     a10 = jit_arg_d();
354     a11 = jit_arg_d();
355     a12 = jit_arg_d();
356     a13 = jit_arg_d();
357     a14 = jit_arg_d();
358     a15 = jit_arg_d();
359     a16 = jit_arg_d();
360 #define SAVE_ARG(N)                                                     \
361     do {                                                                \
362         if (jit_arg_register_p(a##N)) {                                 \
363             s##N = jit_allocai(sizeof(D));                              \
364             jit_getarg_d(JIT_F0, a##N);                                 \
365             jit_stxi_d(s##N, JIT_FP, JIT_F0);                           \
366             jit_putargi_d(-1, a##N);                                    \
367         }                                                               \
368     } while (0)
369     SAVE_ARG(1);
370     SAVE_ARG(2);
371     SAVE_ARG(3);
372     SAVE_ARG(4);
373     SAVE_ARG(5);
374     SAVE_ARG(6);
375     SAVE_ARG(7);
376     SAVE_ARG(8);
377     SAVE_ARG(9);
378     SAVE_ARG(10);
379     SAVE_ARG(11);
380     SAVE_ARG(12);
381     SAVE_ARG(13);
382     SAVE_ARG(14);
383     SAVE_ARG(15);
384     SAVE_ARG(16);
385 #undef SAVE_ARG
386     jit_prepare();
387     {
388         jit_pushargi_d(1);
389         jit_pushargi_d(2);
390         jit_pushargi_d(3);
391         jit_pushargi_d(4);
392         jit_pushargi_d(5);
393         jit_pushargi_d(6);
394         jit_pushargi_d(7);
395         jit_pushargi_d(8);
396         jit_pushargi_d(9);
397         jit_pushargi_d(10);
398         jit_pushargi_d(11);
399         jit_pushargi_d(12);
400         jit_pushargi_d(13);
401         jit_pushargi_d(14);
402         jit_pushargi_d(15);
403         jit_pushargi_d(16);
404     }
405     jit_finishi(cd);
406 #define LOAD_ARG(N)                                                     \
407     do {                                                                \
408         if (jit_arg_register_p(a##N)) {                                 \
409             jit_ldxi_d(JIT_F0, JIT_FP, s##N);                           \
410             jit_putargr_d(JIT_F0, a##N);                                \
411         }                                                               \
412     } while (0)
413     LOAD_ARG(1);
414     LOAD_ARG(2);
415     LOAD_ARG(3);
416     LOAD_ARG(4);
417     LOAD_ARG(5);
418     LOAD_ARG(6);
419     LOAD_ARG(7);
420     LOAD_ARG(8);
421     LOAD_ARG(9);
422     LOAD_ARG(10);
423     LOAD_ARG(11);
424     LOAD_ARG(12);
425     LOAD_ARG(13);
426     LOAD_ARG(14);
427     LOAD_ARG(15);
428     LOAD_ARG(16);
429 #undef LOAD_ARG
430     pass = jit_forward();
431 #define CHECK_ARG(N)                                                    \
432     do {                                                                \
433         jit_getarg_d(JIT_F0, a##N);                                     \
434         jit_patch_at(jit_beqi_d(JIT_F0, 17 - N), pass);                 \
435     } while (0)
436     CHECK_ARG(1);
437     CHECK_ARG(2);
438     CHECK_ARG(3);
439     CHECK_ARG(4);
440     CHECK_ARG(5);
441     CHECK_ARG(6);
442     CHECK_ARG(7);
443     CHECK_ARG(8);
444     CHECK_ARG(9);
445     CHECK_ARG(10);
446     CHECK_ARG(11);
447     CHECK_ARG(12);
448     CHECK_ARG(13);
449     CHECK_ARG(14);
450     CHECK_ARG(15);
451     CHECK_ARG(16);
452 #undef CHECK_ARG
453     jit_calli(abort);
454     jit_link(pass);
455     jit_ret();
456     jit_epilog();
457
458     /* Create a jit function that calls the 3 previous ones.
459      * o First call the function that receives 16 word arguments
460      * o Then call the function that receives 16 float arguments
461      * o Finally call the function that receives 16 double arguments
462      */
463     jit_patch(jmp);
464     jit_name("main");
465     jit_note(__FILE__, __LINE__);
466     jit_prolog();
467     jit_prepare();
468     {
469         jit_pushargi(16);
470         jit_pushargi(15);
471         jit_pushargi(14);
472         jit_pushargi(13);
473         jit_pushargi(12);
474         jit_pushargi(11);
475         jit_pushargi(10);
476         jit_pushargi(9);
477         jit_pushargi(8);
478         jit_pushargi(7);
479         jit_pushargi(6);
480         jit_pushargi(5);
481         jit_pushargi(4);
482         jit_pushargi(3);
483         jit_pushargi(2);
484         jit_pushargi(1);
485     }
486     jit_patch_at(jit_finishi(NULL), jw);
487     jit_prepare();
488     {
489         jit_pushargi_f(16);
490         jit_pushargi_f(15);
491         jit_pushargi_f(14);
492         jit_pushargi_f(13);
493         jit_pushargi_f(12);
494         jit_pushargi_f(11);
495         jit_pushargi_f(10);
496         jit_pushargi_f(9);
497         jit_pushargi_f(8);
498         jit_pushargi_f(7);
499         jit_pushargi_f(6);
500         jit_pushargi_f(5);
501         jit_pushargi_f(4);
502         jit_pushargi_f(3);
503         jit_pushargi_f(2);
504         jit_pushargi_f(1);
505     }
506     jit_patch_at(jit_finishi(NULL), jf);
507     jit_prepare();
508     {
509         jit_pushargi_d(16);
510         jit_pushargi_d(15);
511         jit_pushargi_d(14);
512         jit_pushargi_d(13);
513         jit_pushargi_d(12);
514         jit_pushargi_d(11);
515         jit_pushargi_d(10);
516         jit_pushargi_d(9);
517         jit_pushargi_d(8);
518         jit_pushargi_d(7);
519         jit_pushargi_d(6);
520         jit_pushargi_d(5);
521         jit_pushargi_d(4);
522         jit_pushargi_d(3);
523         jit_pushargi_d(2);
524         jit_pushargi_d(1);
525     }
526     jit_patch_at(jit_finishi(NULL), jd);
527     jit_ret();
528     jit_epilog();
529
530     code = jit_emit();
531     jit_clear_state();
532
533     (*code)();
534
535     jit_destroy_state();
536     finish_jit();
537     return (0);
538 }