9 #define P_ARITH ((PREV_OP == dec_i) || (PREV_OP == inc_i) || (PREV_OP == sub_i_i_i))
11 jit_emit_lwz(NATIVECODE, r1, 0, r1);
12 jit_emit_lwz(NATIVECODE, r0, 8, r1);
14 jit_emit_call_func(NATIVECODE, (void *)Parrot_ppc_jit_restore_nonvolatile_registers);
16 jit_emit_mtlr(NATIVECODE, r0);
17 jit_emit_lmw(NATIVECODE, r13, -PPC_JIT_GP_REGISTER_SAVE_SPACE, r1);
19 jit_emit_blr(NATIVECODE);
23 ; preferred no-op on ppc
24 jit_emit_ori(NATIVECODE, r0, r0, 0);
29 jit_emit_mov_ri_i(NATIVECODE, MAP[1], *INT_CONST[2]);
32 jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
33 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
39 jit_emit_fctiwz (NATIVECODE, FSR2, MAP[2]);
42 jit_emit_mov_rm_n(NATIVECODE, FSR1, ROFFS_NUM(2));
43 jit_emit_fctiwz (NATIVECODE, FSR2, FSR1);
46 jit_emit_add_rri_i(NATIVECODE, ISR1, 0, -4);
47 jit_emit_stfiwx (NATIVECODE, FSR2, ISR1, r1); /* -> -4(sp) */
48 jit_emit_lwz (NATIVECODE, MAP[1], -4, r1);
51 jit_emit_add_rri_i(NATIVECODE, ISR1, 0, ROFFS_INT(1));
52 jit_emit_stfiwx (NATIVECODE, FSR2, ISR1, r13); /* -> offs(base) */
57 static double xx = 4503601774854144.0; /* 0x4330000080000000L; */
58 jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
59 jit_emit_xoris( NATIVECODE, ISR1, ISR1, 0x8000);
60 /* use redzone for intermediate */
61 jit_emit_stw( NATIVECODE, ISR1, -4, r1);
62 jit_emit_addis( NATIVECODE, ISR1, r31, 0x4330);
63 jit_emit_stw( NATIVECODE, ISR1, -8, r1);
64 jit_emit_lfd( NATIVECODE, FSR1, -8, r1);
65 /* we should keep this magic const in a preserved eg eg. f31 */
66 jit_emit_mov_ri_i(NATIVECODE, ISR2, &xx);
67 jit_emit_lfd( NATIVECODE, FSR2, 0, ISR2);
69 jit_emit_fsub_rrr(NATIVECODE, MAP[1], FSR1, FSR2);
72 jit_emit_fsub_rrr(NATIVECODE, FSR1, FSR1, FSR2);
73 jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR1);
78 static double xx = 4503601774854144.0; /* 0x4330000080000000L; */
80 jit_emit_xoris( NATIVECODE, ISR1, MAP[2], 0x8000);
83 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(2));
84 jit_emit_xoris( NATIVECODE, ISR1, ISR1, 0x8000);
86 /* use redzone for intermediate */
87 jit_emit_stw( NATIVECODE, ISR1, -4, r1);
88 jit_emit_addis( NATIVECODE, ISR1, r31, 0x4330);
89 jit_emit_stw( NATIVECODE, ISR1, -8, r1);
90 jit_emit_lfd( NATIVECODE, FSR1, -8, r1);
91 /* we should keep this magic const in a preserved eg f31 */
92 jit_emit_mov_ri_i(NATIVECODE, ISR2, &xx);
93 jit_emit_lfd( NATIVECODE, FSR2, 0, ISR2);
95 jit_emit_fsub_rrr(NATIVECODE, MAP[1], FSR1, FSR2);
98 jit_emit_fsub_rrr(NATIVECODE, FSR1, FSR1, FSR2);
99 jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR1);
105 jit_emit_mov_rr(NATIVECODE, MAP[1], r31);
108 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), r31);
112 TEMPLATE Parrot_set_x_x {
113 if (MAP[1] && MAP[2]) {
114 jit_emit_mov_rr(NATIVECODE, MAP[1], MAP[2]);
117 jit_emit_mov_rm_i(NATIVECODE, MAP[1], ROFFS_INT(2));
120 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), MAP[2]);
123 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(2));
124 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
133 Parrot_set_x_x s/INT/STR/`
137 Parrot_set_x_x s/INT/PMC/
141 if (MAP[1] && MAP[2]) {
142 jit_emit_mov_rr_n(NATIVECODE, MAP[1], MAP[2]);
145 jit_emit_mov_rm_n(NATIVECODE, MAP[1], ROFFS_NUM(2));
148 jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), MAP[2]);
151 jit_emit_mov_rm_n(NATIVECODE, FSR1, ROFFS_NUM(2));
152 jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR1);
158 jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[2]);
159 jit_emit_lfd(NATIVECODE, MAP[1], 0, ISR1);
162 jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[2]);
163 jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
164 jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR1);
169 if (MAP[1] && MAP[2]) {
170 jit_emit_<op>_rr<_N>(NATIVECODE, MAP[1], MAP[2]);
173 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(2));
174 jit_emit_<op>_rr<_N>(NATIVECODE, MAP[1], <s1>);
177 jit_emit_<op>_rr<_N>(NATIVECODE, <s1>, MAP[1]);
178 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
181 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(2));
182 jit_emit_<op>_rr<_N>(NATIVECODE, <s1>, <s1>);
183 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
188 unary_x_x s/<_N>/_i/ s/<t>/INT/ s/<s1>/ISR1/
192 unary_x_x s/<_N>/_n/ s/<t>/NUM/ s/<s1>/FSR1/
196 unary_i_i s/<op>/neg/
200 unary_n_n s/<op>/neg/
204 unary_n_n s/<op>/abs/
207 TEMPLATE binop_x_xc {
210 #ifdef jit_emit_<op>_rri<_N>
212 /* *if* immediate constant is small and there is a dedicated
213 * opcode, just use it
214 * _n variants don't have immediates, only _i
216 * This could be further improved, if there exists also
217 * a shifted opcode variant like 'oris'. But then this code
218 * should be factored out into jit_emit.h. This OTOH needs some
219 * convention about scratch register usage.
222 jit_emit_<op>_rri_i(NATIVECODE, MAP[1], MAP[1], im);
227 jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[2]);
228 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[1], <s1>);
232 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(1));
233 #ifdef jit_emit_<op>_rri<_N>
236 jit_emit_<op>_rri_i(NATIVECODE, <s1>, <s1>, im);
241 jit_emit_mov_ri<_N>(NATIVECODE, <s2>, <c>_CONST[2]);
242 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s1>, <s2>);
244 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
248 TEMPLATE binop_n_nc {
249 binop_x_xc s/<_N>/_n/ s/<t>/NUM/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<c>/&NUM/
252 TEMPLATE binop_i_ic {
253 binop_x_xc s/<_N>/_i/ s/<t>/INT/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<c>/*INT/
257 if (MAP[1] && MAP[2]) {
258 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[1], MAP[2]);
261 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(2));
262 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[1], <s1>);
265 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(1));
266 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s1>, MAP[2]);
267 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
270 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(1));
271 jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<T>(2));
272 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s1>, <s2>);
273 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
277 TEMPLATE binop_x_x_x {
278 if (MAP[1] && MAP[2] && MAP[3]) {
279 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[2], MAP[3]);
281 else if (MAP[1] && MAP[2]) {
282 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
283 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[2], <s1>);
285 else if (MAP[1] && MAP[3]) {
286 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(2));
287 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], <s1>, MAP[3]);
289 else if (MAP[2] && MAP[3]) {
290 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, MAP[2], MAP[3]);
291 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
294 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
295 jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<T>(2));
296 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], <s2>, <s1>);
299 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
300 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, MAP[2], <s1>);
301 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
304 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(2));
305 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s1>, MAP[3]);
306 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
309 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
310 jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<T>(2));
311 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s2>, <s1>);
312 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
316 TEMPLATE binop_x_xc_x {
317 if (MAP[1] && MAP[3]) {
318 jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[2]);
319 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], <s1>, MAP[3]);
322 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
323 jit_emit_mov_ri<_N>(NATIVECODE, <s2>, <c>_CONST[2]);
324 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], <s2>, <s1>);
327 jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[2]);
328 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s1>, MAP[3]);
329 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
332 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
333 jit_emit_mov_ri<_N>(NATIVECODE, <s2>, <c>_CONST[2]);
334 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s2>, <s1>);
335 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
339 TEMPLATE binop_i_ic_i {
340 binop_x_xc_x s/<_N>/_i/ s/<t>/INT/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<c>/*INT/
342 TEMPLATE binop_n_nc_n {
343 binop_x_xc_x s/<_N>/_n/ s/<t>/NUM/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<c>/&NUM/
346 TEMPLATE binop_x_x_xc {
347 if (MAP[1] && MAP[2]) {
348 #ifdef jit_emit_<op>_rri<_N>
349 /* common case - operands are MAPped */
350 int im = *INT_CONST[3];
352 jit_emit_<op>_rri_i(NATIVECODE, MAP[1], MAP[2], im);
357 jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[3]);
358 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[2], <s1>);
362 jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[3]);
363 jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<t>(2));
364 jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], <s2>, <s1>);
367 jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[3]);
368 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, MAP[2], <s1>);
369 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
372 jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[3]);
373 jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<t>(2));
374 jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s2>, <s1>);
375 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
379 TEMPLATE binop_i_i_ic {
380 binop_x_x_xc s/<_N>/_i/ s/<t>/INT/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<c>/*INT/
383 TEMPLATE binop_n_n_nc {
384 binop_x_x_xc s/<_N>/_n/ s/<t>/NUM/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<c>/&NUM/
388 binop_x_x s/<_N>/_i/ s/<op>/and/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
392 binop_x_x s/<_N>/_i/ s/<op>/or/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
396 binop_x_x s/<_N>/_i/ s/<op>/xor/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
400 binop_x_x s/<_N>/_i/ s/<op>/shr/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
404 binop_x_x s/<_N>/_i/ s/<op>/shl/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
408 binop_x_x s/<_N>/_i/ s/<op>/lsr/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
412 binop_x_x s/<_N>/_i/ s/<op>/add/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
416 binop_x_x s/<_N>/_i/ s/<op>/sub/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
420 binop_x_x s/<_N>/_i/ s/<op>/mul/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
424 binop_x_x s/<_N>/_i/ s/<op>/div/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
428 binop_x_x s/<_N>/_i/ s/<op>/cmod/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
432 binop_i_ic s/<op>/and/
436 binop_i_ic s/<op>/or/
440 binop_i_ic s/<op>/xor/
444 binop_i_ic s/<op>/shr/
448 binop_i_ic s/<op>/shl/
452 binop_i_ic s/<op>/lsr/
456 binop_i_ic s/<op>/add/
460 binop_i_ic s/<op>/sub/
464 binop_i_ic s/<op>/mul/
468 binop_i_ic s/<op>/div/
472 binop_i_ic s/<op>/cmod/
476 binop_n_nc s/<op>/add/
480 binop_n_nc s/<op>/sub/
484 binop_n_nc s/<op>/mul/
488 binop_n_nc s/<op>/div/
492 binop_x_x s/<_N>/_n/ s/<op>/add/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
496 binop_x_x s/<_N>/_n/ s/<op>/div/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
500 binop_x_x s/<_N>/_n/ s/<op>/mul/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
504 binop_x_x s/<_N>/_n/ s/<op>/sub/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
508 binop_x_x_x s/<_N>/_i/ s/<op>/and/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
512 binop_x_x_x s/<_N>/_i/ s/<op>/or/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
516 binop_x_x_x s/<_N>/_i/ s/<op>/xor/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
520 binop_x_x_x s/<_N>/_i/ s/<op>/add/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
524 binop_x_x_x s/<_N>/_i/ s/<op>/sub/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
528 binop_x_x_x s/<_N>/_i/ s/<op>/mul/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
532 binop_x_x_x s/<_N>/_i/ s/<op>/div/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
536 binop_x_x_x s/<_N>/_i/ s/<op>/cmod/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
540 binop_i_i_ic s/<op>/and/
544 binop_i_i_ic s/<op>/or/
548 binop_i_i_ic s/<op>/xor/
552 binop_i_i_ic s/<op>/shr/
556 binop_i_i_ic s/<op>/shl/
560 binop_i_i_ic s/<op>/lsr/
564 binop_i_i_ic s/<op>/add/
568 binop_i_i_ic s/<op>/sub/
572 binop_i_i_ic s/<op>/mul/
576 binop_i_i_ic s/<op>/div/
580 binop_i_i_ic s/<op>/cmod/
584 binop_n_n_nc s/<op>/add/
588 binop_n_n_nc s/<op>/sub/
592 binop_n_n_nc s/<op>/mul/
596 binop_n_n_nc s/<op>/div/
600 binop_i_ic_i s/<op>/and/
604 binop_i_ic_i s/<op>/or/
608 binop_i_ic_i s/<op>/xor/
612 binop_i_ic_i s/<op>/shr/
616 binop_i_ic_i s/<op>/lsr/
620 binop_i_ic_i s/<op>/shl/
624 binop_i_ic_i s/<op>/add/
628 binop_i_ic_i s/<op>/sub/
632 binop_i_ic_i s/<op>/mul/
636 binop_i_ic_i s/<op>/div/
640 binop_i_ic_i s/<op>/cmod/
644 binop_n_nc_n s/<op>/add/
648 binop_n_nc_n s/<op>/sub/
652 binop_n_nc_n s/<op>/mul/
656 binop_n_nc_n s/<op>/div/
660 binop_x_x_x s/<_N>/_n/ s/<op>/add/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
664 binop_x_x_x s/<_N>/_n/ s/<op>/sub/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
668 binop_x_x_x s/<_N>/_n/ s/<op>/mul/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
672 binop_x_x_x s/<_N>/_n/ s/<op>/div/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
675 Parrot_rot_i_i_ic_ic {
676 int rc = *INT_CONST[3];
677 int bw = *INT_CONST[4];
680 if (MAP[1] && MAP[2]) {
681 jit_emit_rot_rri(NATIVECODE, MAP[1], MAP[2], rc);
684 jit_emit_mov_rm_i(NATIVECODE, ISR2, ROFFS_INT(2));
685 jit_emit_rot_rri(NATIVECODE, MAP[1], ISR2, rc);
688 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
689 jit_emit_rot_rri(NATIVECODE, ISR1, MAP[2], rc);
690 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
693 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
694 jit_emit_mov_rm_i(NATIVECODE, ISR2, ROFFS_INT(2));
695 jit_emit_rot_rri(NATIVECODE, ISR1, ISR2, rc);
696 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
701 ; actually this covers islt too, by passing the bit
702 TEMPLATE iseq_i_x_x {
703 if (MAP[2] && MAP[3]) {
704 jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], MAP[3]);
707 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
708 jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], <s1>);
711 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(2));
712 jit_emit_cmp_rr<_N>(NATIVECODE, <s1>, MAP[3]);
715 jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<t>(2));
716 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
717 jit_emit_cmp_rr<_N>(NATIVECODE, <s2>, <s1>);
719 jit_emit_mfcr(NATIVECODE, ISR1);
720 /* bits 0 LT, 1 GT, 2 EQ */
721 /* see also extrwi */
723 jit_emit_rlwinm(NATIVECODE, MAP[1], ISR1, <b>, 31, 31);
726 jit_emit_rlwinm(NATIVECODE, ISR1, ISR1, <b>, 31, 31);
727 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
731 TEMPLATE isle_i_x_x {
732 if (MAP[2] && MAP[3]) {
733 jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], MAP[3]);
736 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
737 jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], <s1>);
740 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(2));
741 jit_emit_cmp_rr<_N>(NATIVECODE, <s1>, MAP[3]);
744 jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<t>(2));
745 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
746 jit_emit_cmp_rr<_N>(NATIVECODE, <s2>, <s1>);
748 jit_emit_mfcr(NATIVECODE, ISR1);
749 /* bits 0 LT, 1 GT, 2 EQ */
750 /* this is LT or LE - get LT */
751 jit_emit_rlwinm(NATIVECODE, ISR2, ISR1, 1, 31, 31);
752 /* get EQ and or the bits into destination */
753 jit_emit_rlwinm(NATIVECODE, ISR1, ISR1, 3, 31, 31);
755 jit_emit_or_rrr(NATIVECODE, MAP[1], ISR1, ISR2);
758 jit_emit_or_rrr(NATIVECODE, ISR1, ISR1, ISR2);
759 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
764 if (MAP[2] && MAP[3]) {
765 jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], MAP[3]);
768 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
769 jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], <s1>);
772 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(2));
773 jit_emit_cmp_rr<_N>(NATIVECODE, <s1>, MAP[3]);
776 jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<t>(2));
777 jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
778 jit_emit_cmp_rr<_N>(NATIVECODE, <s2>, <s1>);
780 jit_emit_mfcr(NATIVECODE, ISR1);
781 /* bits 0 LT, 1 GT, 2 EQ */
783 jit_emit_rlwinm(NATIVECODE, ISR2, ISR1, 1, 31, 31);
785 jit_emit_xori (NATIVECODE, ISR2, ISR2, 1);
786 /* sub 1 -> -1 / 0 */
787 jit_emit_subi (NATIVECODE, ISR2, ISR2, 1);
788 /* get GT or the bits into destination */
789 jit_emit_rlwinm(NATIVECODE, ISR1, ISR1, 2, 31, 31);
791 jit_emit_or_rrr(NATIVECODE, MAP[1], ISR1, ISR2);
794 jit_emit_or_rrr(NATIVECODE, ISR1, ISR1, ISR2);
795 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
799 iseq_i_x_x s/<s1>/ISR1/ s/<s2>/ISR2/ s/<t>/INT/ s/<_N>/_i/ s/<b>/3/
803 iseq_i_x_x s/<s1>/FSR1/ s/<s2>/FSR2/ s/<t>/NUM/ s/<_N>/_n/ s/<b>/3/
807 iseq_i_x_x s/<s1>/ISR1/ s/<s2>/ISR2/ s/<t>/INT/ s/<_N>/_i/ s/<b>/1/
811 iseq_i_x_x s/<s1>/FSR1/ s/<s2>/FSR2/ s/<t>/NUM/ s/<_N>/_n/ s/<b>/1/
815 isle_i_x_x s/<s1>/ISR1/ s/<s2>/ISR2/ s/<t>/INT/ s/<_N>/_i/
819 isle_i_x_x s/<s1>/FSR1/ s/<s2>/FSR2/ s/<t>/NUM/ s/<_N>/_n/
823 cmp_i_x_x s/<s1>/ISR1/ s/<s2>/ISR2/ s/<t>/INT/ s/<_N>/_i/
827 cmp_i_x_x s/<s1>/FSR1/ s/<s2>/FSR2/ s/<t>/NUM/ s/<_N>/_n/
832 jit_emit_add_rri_i (NATIVECODE, MAP[1], MAP[1], 1);
835 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
836 jit_emit_add_rri_i (NATIVECODE, ISR1, ISR1, 1);
837 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
843 jit_emit_add_rri_i (NATIVECODE, MAP[1], MAP[1], -1);
846 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
847 jit_emit_add_rri_i (NATIVECODE, ISR1, ISR1, -1);
848 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
853 static const double one = 1.0;
854 jit_emit_mov_ri_i(NATIVECODE, ISR1, &one);
855 jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
857 jit_emit_fadd_rrr(NATIVECODE, MAP[1], MAP[1], FSR1);
860 jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(1));
861 jit_emit_fadd_rrr(NATIVECODE, FSR2, FSR2, FSR1);
862 jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR2);
867 static const double one = 1.0;
868 jit_emit_mov_ri_i(NATIVECODE, ISR1, &one);
869 jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
871 jit_emit_fsub_rrr(NATIVECODE, MAP[1], MAP[1], FSR1);
874 jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(1));
875 jit_emit_fsub_rrr(NATIVECODE, FSR2, FSR2, FSR1);
876 jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR2);
881 TEMPLATE Parrot_unaryop_x {
883 jit_emit_<op>_rr<_N>(NATIVECODE, MAP[1], MAP[1]);
886 jit_emit_mov_rm<_N>(NATIVECODE, SCRATCH1, ROFFS_INT(1));
887 jit_emit_<op>_rr<_N>(NATIVECODE, SCRATCH1, SCRATCH1);
888 jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_INT(1), SCRATCH1);
892 ; a recursive template
893 TEMPLATE Parrot_unaryop_i {
894 Parrot_unaryop_x s/<_N>/_i/ s/SCRATCH1/ISR1/
897 TEMPLATE Parrot_unaryop_n {
898 Parrot_unaryop_x s/<_N>/_n/ s/INT/NUM/ s/SCRATCH1/FSR1/
902 Parrot_unaryop_i s/<op>/neg/
906 Parrot_unaryop_n s/<op>/neg/
910 Parrot_unaryop_n s/<op>/abs/
915 jit_emit_srawi(NATIVECODE, ISR1, MAP[1], 31);
916 jit_emit_add_rrr(NATIVECODE, ISR2, ISR1, MAP[1]);
917 jit_emit_xor_rrr(NATIVECODE, MAP[1], ISR2, ISR1);
920 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
921 jit_emit_srawi(NATIVECODE, ISR2, ISR1, 31);
922 jit_emit_add_rrr(NATIVECODE, ISR1, ISR2, ISR1);
923 jit_emit_xor_rrr(NATIVECODE, ISR1, ISR1, ISR2);
924 jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
929 TEMPLATE Parrot_ifunless_i_ic {
930 if (P_ARITH && MAP[1]) {
931 /* set the Rc bit of prev for the sake of +50% more MOPS */
935 jit_emit_cmp_ri(NATIVECODE, MAP[1], 0);
938 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
939 jit_emit_cmp_ri(NATIVECODE, ISR1, 0);
941 jit_emit_bc(jit_info, <COND>, *INT_CONST[2]);
945 Parrot_ifunless_i_ic s/<COND>/BNE/
949 Parrot_ifunless_i_ic s/<COND>/BEQ/
952 TEMPLATE Parrot_ifunless_n_ic {
953 static const double zero = 0.0;
954 jit_emit_mov_ri_i(NATIVECODE, ISR1, &zero);
955 jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
957 jit_emit_cmp_rr_n(NATIVECODE, MAP[1], FSR1);
960 jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(1));
961 jit_emit_cmp_rr_n(NATIVECODE, FSR2, FSR1);
963 jit_emit_bc(jit_info, <COND>, *INT_CONST[2]);
967 Parrot_ifunless_n_ic s/<COND>/BNE/
971 Parrot_ifunless_n_ic s/<COND>/BEQ/
974 TEMPLATE Parrot_branch_i_i_ic {
975 ; First, emit the compare op:
976 if (MAP[1] && MAP[2]) {
977 jit_emit_cmp_rr_i(NATIVECODE, MAP[1], MAP[2]);
980 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(2));
981 jit_emit_cmp_rr_i(NATIVECODE, MAP[1], ISR1);
984 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
985 jit_emit_cmp_rr_i(NATIVECODE, ISR1, MAP[2]);
988 jit_emit_mov_rm_i(NATIVECODE, ISR2, ROFFS_INT(1));
989 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(2));
990 jit_emit_cmp_rr_i(NATIVECODE, ISR2, ISR1);
992 ; Now the branch. XXX: need to handle large displacements.
993 jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
996 TEMPLATE Parrot_branch_i_ic_ic {
997 jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
1000 jit_emit_cmp_rr_i(NATIVECODE, MAP[1], ISR1);
1003 jit_emit_mov_rm_i(NATIVECODE, ISR2, ROFFS_INT(1));
1004 jit_emit_cmp_rr_i(NATIVECODE, ISR2, ISR1);
1006 ; Now the branch. XXX: need to handle large displacements.
1007 jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
1011 TEMPLATE Parrot_branch_ic_i_ic {
1012 jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[1]);
1015 jit_emit_cmp_rr_i(NATIVECODE, ISR1, MAP[2]);
1018 jit_emit_mov_rm_i(NATIVECODE, ISR2, ROFFS_INT(2));
1019 jit_emit_cmp_rr_i(NATIVECODE, ISR1, ISR2);
1021 ; Now the branch. XXX: need to handle large displacements.
1022 jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
1026 Parrot_branch_i_i_ic s/<CON>/BEQ/
1030 Parrot_branch_i_ic_ic s/<CON>/BEQ/
1034 Parrot_branch_ic_i_ic s/<CON>/BEQ/
1039 Parrot_branch_i_i_ic s/<CON>/BLT/
1043 Parrot_branch_i_ic_ic s/<CON>/BLT/
1047 Parrot_branch_ic_i_ic s/<CON>/BLT/
1051 Parrot_branch_i_i_ic s/<CON>/BLE/
1055 Parrot_branch_i_ic_ic s/<CON>/BLE/
1059 Parrot_branch_ic_i_ic s/<CON>/BLE/
1064 Parrot_branch_i_i_ic s/<CON>/BNE/
1068 Parrot_branch_i_ic_ic s/<CON>/BNE/
1072 Parrot_branch_ic_i_ic s/<CON>/BNE/
1076 TEMPLATE Parrot_branch_n_n_ic {
1077 if (MAP[1] && MAP[2]) {
1078 jit_emit_cmp_rr_n(NATIVECODE, MAP[1], MAP[2]);
1081 jit_emit_mov_rm_n(NATIVECODE, FSR1, ROFFS_NUM(2));
1082 jit_emit_cmp_rr_n(NATIVECODE, MAP[1], FSR1);
1085 jit_emit_mov_rm_n(NATIVECODE, FSR1, ROFFS_NUM(1));
1086 jit_emit_cmp_rr_n(NATIVECODE, FSR1, MAP[2]);
1089 jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(1));
1090 jit_emit_mov_rm_n(NATIVECODE, FSR1, ROFFS_NUM(2));
1091 jit_emit_cmp_rr_n(NATIVECODE, FSR2, FSR1);
1093 jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
1096 TEMPLATE Parrot_branch_n_nc_ic {
1097 jit_emit_mov_ri_n(NATIVECODE, FSR1, &NUM_CONST[2]);
1099 jit_emit_cmp_rr_n(NATIVECODE, MAP[1], FSR1);
1102 jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(1));
1103 jit_emit_cmp_rr_n(NATIVECODE, FSR2, FSR1);
1105 jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
1108 TEMPLATE Parrot_branch_nc_n_ic {
1110 jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[1]);
1111 jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
1112 jit_emit_cmp_rr_n(NATIVECODE, FSR1, MAP[2]);
1115 jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(2));
1116 jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[1]);
1117 jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
1118 jit_emit_cmp_rr_n(NATIVECODE, FSR1, FSR2);
1120 jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
1124 Parrot_branch_n_n_ic s/<CON>/BEQ/
1128 Parrot_branch_n_nc_ic s/<CON>/BEQ/
1132 Parrot_branch_nc_n_ic s/<CON>/BEQ/
1137 Parrot_branch_n_n_ic s/<CON>/BLT/
1141 Parrot_branch_n_nc_ic s/<CON>/BLT/
1145 Parrot_branch_nc_n_ic s/<CON>/BLT/
1150 Parrot_branch_n_n_ic s/<CON>/BLE/
1154 Parrot_branch_n_nc_ic s/<CON>/BLE/
1158 Parrot_branch_nc_n_ic s/<CON>/BLE/
1162 Parrot_branch_n_n_ic s/<CON>/BNE/
1166 Parrot_branch_n_nc_ic s/<CON>/BNE/
1170 Parrot_branch_nc_n_ic s/<CON>/BLE/
1175 jit_emit_bx(jit_info, 0, *INT_CONST[1]);
1179 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
1180 jit_emit_mtlr(NATIVECODE, ISR1);
1181 jit_emit_blr(NATIVECODE);
1184 TEMPLATE Parrot_set_or_clone_s_sc {
1185 ; string_copy(Interp *interp, STRING *s)
1186 jit_emit_mov_rr(NATIVECODE, r3, r16);
1187 jit_emit_mov_ri_i(NATIVECODE, r4, CONST(2)->u.string);
1189 jit_emit_call_func(NATIVECODE, (void*) string_copy);
1191 jit_emit_mov_mr_i(NATIVECODE, ROFFS_STR(1), r3);
1195 Parrot_set_or_clone_s_sc
1199 Parrot_set_or_clone_s_sc
1203 jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_STR(2));
1204 jit_emit_mov_mr_i(NATIVECODE, ROFFS_STR(1), ISR1);
1208 jit_emit_mov_rr(NATIVECODE, r3, r16);
1209 jit_emit_mov_rm_i(NATIVECODE, r4, ROFFS_STR(2));
1211 jit_emit_call_func(NATIVECODE, (void*) string_copy);
1213 jit_emit_mov_mr_i(NATIVECODE,ROFFS_STR(1), r3);
1217 jit_emit_mov_ri_i(NATIVECODE, ISR1, CONST(2)->u.key);
1218 jit_emit_mov_mr_i(NATIVECODE, ROFFS_PMC(1), ISR1);
1221 ; the following 4 ops don't branch but are translated as cpfp
1222 ; which adds unneeded overhead - convert to normal ops
1223 ; or just JIT (TODO) the 2 easy ones
1224 Parrot_set_args_pc {
1225 if (jit_info->code_type == JIT_CODE_FILE) {
1226 jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
1227 jit_emit_stw(NATIVECODE, ISR1, offsetof(Interp, current_args), r16);
1230 jit_set_args_pc(jit_info, interp,
1231 jit_info->flags & JIT_CODE_RECURSIVE);
1235 extern Parrot_set_returns_pc {
1236 if (jit_info->code_type == JIT_CODE_FILE)
1237 Parrot_jit_normal_op(jit_info, interp);
1239 jit_set_returns_pc(jit_info, interp,
1240 jit_info->flags & JIT_CODE_RECURSIVE);
1244 extern Parrot_returncc {
1245 if (jit_info->code_type == JIT_CODE_FILE)
1246 Parrot_jit_restart_op(jit_info, interp);
1248 /* fetch args[n+1] -> retval */
1249 if (!(jit_info->flags & JIT_CODE_RECURSIVE)) {
1250 jit_emit_lwz(jit_info->native_ptr, r1, 0, r1);
1251 jit_emit_lwz(jit_info->native_ptr, r3, 4 + jit_info->n_args * 4, r5);
1252 jit_emit_lwz(jit_info->native_ptr, r31, -4, r1);
1253 jit_emit_lwz(jit_info->native_ptr, r0, 8, r1); /* get link reg */
1254 jit_emit_mtlr(jit_info->native_ptr, r0); /* move to link reg */
1256 jit_emit_blr(jit_info->native_ptr);
1260 Parrot_pic_callr___pc {
1261 PackFile_Constant **constants = CONTEXT(interp)->constants;
1262 PMC *sig_result = constants[CUR_OPCODE[1]]->u.key;
1263 opcode_t *params = jit_info->optimizer->sections->begin;
1264 PMC *sig_params = constants[params[1]]->u.key;
1265 int op_i = SIG_ELEMS(sig_params) + 2;
1266 int offset = jit_info->arena.op_map[op_i].offset;
1267 int here = NATIVECODE - jit_info->arena.start;
1270 /* TODO preserve necessary regs */
1271 assert(*CUR_OPCODE == PARROT_OP_get_results_pc);
1273 if (!SIG_ELEMS(sig_result))
1275 /* skip result - save rest */
1282 _emit_bx(NATIVECODE, 1, offset);
1284 jit_restore_regs_call(jit_info, interp, skip);
1287 extern Parrot_get_params_pc {
1288 if (jit_info->code_type == JIT_CODE_FILE)
1289 Parrot_jit_normal_op(jit_info, interp);
1290 else if (!(jit_info->flags & JIT_CODE_RECURSIVE)) {
1291 jit_get_params_pc(jit_info, interp);
1295 Parrot_get_results_pc {
1296 if (jit_info->code_type == JIT_CODE_FILE) {
1297 jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
1298 jit_emit_lwz(NATIVECODE, ISR2, offsetof(Interp, ctx.state), r16);
1299 jit_emit_stw(NATIVECODE, ISR1,
1300 offsetof(parrot_context_t, current_results), ISR2);
1303 PackFile_Constant **constants = CONTEXT(interp)->constants;
1304 PMC *sig_result = constants[CUR_OPCODE[1]]->u.key;
1306 if (!SIG_ELEMS(sig_result))
1309 /* result is r3 TODO Nums */
1310 jit_emit_mov_rr(NATIVECODE, MAP(2), r3);