Commit | Line | Data |
---|---|---|
4a71579b PC |
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); | |
79bfeef6 PC |
61 | jit_node_t *jmp, *pass, *fail; |
62 | jit_node_t *jw, *jf, *jd; | |
4a71579b PC |
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(); | |
79bfeef6 | 175 | fail = jit_forward(); |
4a71579b PC |
176 | #define CHECK_ARG(N) \ |
177 | do { \ | |
178 | jit_getarg(JIT_R0, a##N); \ | |
79bfeef6 | 179 | jit_patch_at(jit_bnei(JIT_R0, 17 - N), fail); \ |
4a71579b PC |
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 | |
79bfeef6 PC |
198 | jit_patch_at(jit_jmpi(), pass); |
199 | jit_link(fail); | |
4a71579b PC |
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(); | |
79bfeef6 | 306 | fail = jit_forward(); |
4a71579b PC |
307 | #define CHECK_ARG(N) \ |
308 | do { \ | |
309 | jit_getarg_f(JIT_F0, a##N); \ | |
79bfeef6 | 310 | jit_patch_at(jit_bnei_f(JIT_F0, 17 - N), fail); \ |
4a71579b PC |
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 | |
79bfeef6 PC |
329 | jit_patch_at(jit_jmpi(), pass); |
330 | jit_link(fail); | |
4a71579b PC |
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(); | |
79bfeef6 | 437 | fail = jit_forward(); |
4a71579b PC |
438 | #define CHECK_ARG(N) \ |
439 | do { \ | |
440 | jit_getarg_d(JIT_F0, a##N); \ | |
79bfeef6 | 441 | jit_patch_at(jit_bnei_d(JIT_F0, 17 - N), fail); \ |
4a71579b PC |
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 | |
79bfeef6 PC |
460 | jit_patch_at(jit_jmpi(), pass); |
461 | jit_link(fail); | |
4a71579b PC |
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); | |
79bfeef6 | 496 | |
4a71579b PC |
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); | |
79bfeef6 | 517 | |
4a71579b PC |
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 | } |