2 * Copyright (C) 2013-2019 Free Software Foundation, Inc.
4 * This file is part of GNU lightning.
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
17 * Paulo Cesar Pereira de Andrade
20 #define jit_arg_reg_p(i) ((i) >= 0 && (i) < 6)
22 # define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 5)
25 # define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 16)
26 # define BIAS(n) ((n) + 2047)
32 typedef jit_pointer_t jit_va_list_t;
37 #define patch(instr, node) _patch(_jit, instr, node)
38 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
41 # include "jit_sparc-cpu.c"
42 # include "jit_sparc-fpu.c"
48 jit_register_t _rvs[] = {
51 { rc(gpr) | 0x02, "%g2" },
52 { rc(gpr) | 0x03, "%g3" },
53 { rc(gpr) | 0x04, "%g4" },
57 { rc(arg) | rc(gpr) | 0x08, "%o0" },
58 { rc(arg) | rc(gpr) | 0x09, "%o1" },
59 { rc(arg) | rc(gpr) | 0x0a, "%o2" },
60 { rc(arg) | rc(gpr) | 0x0b, "%o3" },
61 { rc(arg) | rc(gpr) | 0x0c, "%o4" },
62 { rc(arg) | rc(gpr) | 0x0d, "%o5" },
63 { rc(sav) | 0x0e, "%sp" },
65 { rc(sav) | rc(gpr) | 0x10, "%l0" },
66 { rc(sav) | rc(gpr) | 0x11, "%l1" },
67 { rc(sav) | rc(gpr) | 0x12, "%l2" },
68 { rc(sav) | rc(gpr) | 0x13, "%l3" },
69 { rc(sav) | rc(gpr) | 0x14, "%l4" },
70 { rc(sav) | rc(gpr) | 0x15, "%l5" },
71 { rc(sav) | rc(gpr) | 0x16, "%l6" },
72 { rc(sav) | rc(gpr) | 0x17, "%l7" },
79 { rc(sav) | 0x1e, "%fp" },
82 { rc(fpr) | 0x00, "%f0" },
84 { rc(fpr) | 0x02, "%f2" },
86 { rc(fpr) | 0x04, "%f4" },
88 { rc(fpr) | 0x06, "%f6" },
90 { rc(fpr) | 0x08, "%f8" },
92 { rc(fpr) | 0x0a, "%f10" },
94 { rc(fpr) | 0x0c, "%f12" },
96 { rc(fpr) | 0x0e, "%f14" },
99 { rc(fpr) | rc(dbl) | 0x3e, "%f62" },
100 { rc(fpr) | rc(dbl) | 0x3c, "%f60" },
101 { rc(fpr) | rc(dbl) | 0x3a, "%f58" },
102 { rc(fpr) | rc(dbl) | 0x38, "%f56" },
103 { rc(fpr) | rc(dbl) | 0x36, "%f54" },
104 { rc(fpr) | rc(dbl) | 0x34, "%f52" },
105 { rc(fpr) | rc(dbl) | 0x32, "%f50" },
106 { rc(fpr) | rc(dbl) | 0x30, "%f48" },
107 { rc(fpr) | rc(dbl) | 0x2e, "%f46" },
108 { rc(fpr) | rc(dbl) | 0x2c, "%f44" },
109 { rc(fpr) | rc(dbl) | 0x2a, "%f42" },
110 { rc(fpr) | rc(dbl) | 0x28, "%f40" },
111 { rc(fpr) | rc(dbl) | 0x26, "%f38" },
112 { rc(fpr) | rc(dbl) | 0x24, "%f36" },
113 { rc(fpr) | rc(dbl) | 0x22, "%f34" },
114 { rc(fpr) | rc(dbl) | 0x20, "%f32" },
116 { rc(arg)|rc(fpr)|rc(sng)|0x1e, "%f30" },
118 { rc(arg)|rc(fpr)|rc(sng)|0x1c, "%f28" },
120 { rc(arg)|rc(fpr)|rc(sng)|0x1a, "%f26" },
122 { rc(arg)|rc(fpr)|rc(sng)|0x18, "%f24" },
124 { rc(arg)|rc(fpr)|rc(sng)|0x16, "%f22" },
126 { rc(arg)|rc(fpr)|rc(sng)|0x14, "%f20" },
128 { rc(arg)|rc(fpr)|rc(sng)|0x12, "%f18" },
130 { rc(arg)|rc(fpr)|rc(sng)|0x10, "%f16" },
132 { rc(arg)|rc(fpr)|rc(sng)|0x0e, "%f14" },
134 { rc(arg)|rc(fpr)|rc(sng)|0x0c, "%f12" },
136 { rc(arg)|rc(fpr)|rc(sng)|0x0a, "%f10" },
138 { rc(arg)|rc(fpr)|rc(sng)|0x08, "%f8" },
140 { rc(arg)|rc(fpr)|rc(sng)|0x06, "%f6" },
142 { rc(arg)|rc(fpr)|rc(sng)|0x04, "%f4" },
144 { rc(arg)|rc(fpr)|rc(sng)|0x02, "%f2" },
146 { rc(arg)|rc(fpr)|rc(sng)|0x00, "%f0" },
148 { _NOREG, "<none>" },
160 _jit_init(jit_state_t *_jit)
162 _jitc->reglen = jit_size(_rvs) - 1;
163 # if __WORDSIZE == 64
169 _jit_prolog(jit_state_t *_jit)
175 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
176 jit_regset_set_ui(&_jitc->regsav, 0);
177 offset = _jitc->functions.offset;
178 if (offset >= _jitc->functions.length) {
179 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
180 _jitc->functions.length * sizeof(jit_function_t),
181 (_jitc->functions.length + 16) * sizeof(jit_function_t));
182 _jitc->functions.length += 16;
184 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
185 _jitc->function->self.size = stack_framesize;
186 _jitc->function->self.argi = _jitc->function->self.argf =
187 _jitc->function->self.aoff = _jitc->function->self.alen = 0;
188 /* float conversion */
189 # if __WORDSIZE == 32
190 _jitc->function->self.aoff = -8;
192 /* extra slots in case qmul is called */
193 _jitc->function->self.aoff = -24;
195 _jitc->function->self.call = jit_call_default;
196 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
197 _jitc->reglen * sizeof(jit_int32_t));
199 /* _no_link here does not mean the jit_link() call can be removed
201 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
203 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
204 jit_link(_jitc->function->prolog);
205 _jitc->function->prolog->w.w = offset;
206 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
208 * v: offset in blocks vector
209 * w: offset in functions vector
211 _jitc->function->epilog->w.w = offset;
213 jit_regset_new(&_jitc->function->regset);
217 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
219 assert(_jitc->function);
221 case 0: case 1: break;
222 case 2: _jitc->function->self.aoff &= -2; break;
223 case 3: case 4: _jitc->function->self.aoff &= -4; break;
224 default: _jitc->function->self.aoff &= -8; break;
226 _jitc->function->self.aoff -= length;
227 if (!_jitc->realize) {
228 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
231 return (BIAS(_jitc->function->self.aoff));
235 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
238 assert(_jitc->function);
239 jit_inc_synth_ww(allocar, u, v);
240 if (!_jitc->function->allocar) {
241 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
242 _jitc->function->allocar = 1;
244 reg = jit_get_reg(jit_class_gpr);
246 jit_andi(reg, reg, -16);
247 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
249 jit_addr(_SP, _SP, reg);
250 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
256 _jit_ret(jit_state_t *_jit)
259 assert(_jitc->function);
263 jit_patch_at(instr, _jitc->function->epilog);
268 _jit_retr(jit_state_t *_jit, jit_int32_t u)
270 jit_inc_synth_w(retr, u);
272 jit_movr(JIT_RET, u);
279 _jit_reti(jit_state_t *_jit, jit_word_t u)
281 jit_inc_synth_w(reti, u);
282 jit_movi(JIT_RET, u);
288 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
290 jit_inc_synth_w(retr_f, u);
292 jit_movr_f(JIT_FRET, u);
300 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
302 jit_inc_synth_f(reti_f, u);
303 jit_movi_f(JIT_FRET, u);
309 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
311 jit_inc_synth_w(retr_d, u);
313 jit_movr_d(JIT_FRET, u);
321 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
323 jit_inc_synth_d(reti_d, u);
324 jit_movi_d(JIT_FRET, u);
330 _jit_epilog(jit_state_t *_jit)
332 assert(_jitc->function);
333 assert(_jitc->function->epilog->next == NULL);
334 jit_link(_jitc->function->epilog);
335 _jitc->function = NULL;
339 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
341 # if __WORDSIZE == 32
342 if (u->code == jit_code_arg || u->code == jit_code_arg_f)
343 return (jit_arg_reg_p(u->u.w));
344 assert(u->code == jit_code_arg_d);
345 return (jit_arg_d_reg_p(u->u.w));
347 if (u->code == jit_code_arg)
348 return (jit_arg_reg_p(u->u.w));
349 assert(u->code == jit_code_arg_d || u->code == jit_code_arg_f);
350 return (jit_arg_d_reg_p(u->u.w));
355 _jit_ellipsis(jit_state_t *_jit)
357 jit_inc_synth(ellipsis);
358 if (_jitc->prepare) {
360 assert(!(_jitc->function->call.call & jit_call_varargs));
361 _jitc->function->call.call |= jit_call_varargs;
365 assert(!(_jitc->function->self.call & jit_call_varargs));
366 _jitc->function->self.call |= jit_call_varargs;
368 _jitc->function->vagp = _jitc->function->self.argi;
374 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
376 jit_inc_synth_w(va_push, u);
382 _jit_arg(jit_state_t *_jit)
386 assert(_jitc->function);
387 if (jit_arg_reg_p(_jitc->function->self.argi))
388 offset = _jitc->function->self.argi++;
390 # if __WORDSIZE == 64
391 if (jit_arg_d_reg_p(_jitc->function->self.argi))
392 ++_jitc->function->self.argi;
394 offset = BIAS(_jitc->function->self.size);
395 _jitc->function->self.size += sizeof(jit_word_t);
397 node = jit_new_node_ww(jit_code_arg, offset,
398 ++_jitc->function->self.argn);
404 _jit_arg_f(jit_state_t *_jit)
408 # if __WORDSIZE == 64
411 assert(_jitc->function);
412 # if __WORDSIZE == 32
413 if (jit_arg_reg_p(_jitc->function->self.argi))
414 offset = _jitc->function->self.argi++;
416 offset = _jitc->function->self.size;
417 _jitc->function->self.size += sizeof(jit_word_t);
420 inc = !jit_arg_reg_p(_jitc->function->self.argi);
421 if (jit_arg_d_reg_p(_jitc->function->self.argi))
422 offset = _jitc->function->self.argi++;
424 offset = BIAS(_jitc->function->self.size);
426 _jitc->function->self.size += sizeof(jit_word_t);
428 node = jit_new_node_ww(jit_code_arg_f, offset,
429 ++_jitc->function->self.argn);
435 _jit_arg_d(jit_state_t *_jit)
439 # if __WORDSIZE == 64
442 assert(_jitc->function);
443 # if __WORDSIZE == 32
444 if (jit_arg_d_reg_p(_jitc->function->self.argi)) {
445 offset = _jitc->function->self.argi;
446 _jitc->function->self.argi += 2;
448 else if (jit_arg_reg_p(_jitc->function->self.argi)) {
449 offset = _jitc->function->self.argi++;
450 _jitc->function->self.size += sizeof(jit_float32_t);
453 offset = _jitc->function->self.size;
454 _jitc->function->self.size += sizeof(jit_float64_t);
457 inc = !jit_arg_reg_p(_jitc->function->self.argi);
458 if (jit_arg_d_reg_p(_jitc->function->self.argi))
459 offset = _jitc->function->self.argi++;
461 offset = BIAS(_jitc->function->self.size);
463 _jitc->function->self.size += sizeof(jit_word_t);
465 node = jit_new_node_ww(jit_code_arg_d, offset,
466 ++_jitc->function->self.argn);
472 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
474 assert(v->code == jit_code_arg);
475 jit_inc_synth_wp(getarg_c, u, v);
476 if (jit_arg_reg_p(v->u.w))
477 jit_extr_c(u, _I0 + v->u.w);
479 jit_ldxi_c(u, JIT_FP,
480 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t));
485 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
487 assert(v->code == jit_code_arg);
488 jit_inc_synth_wp(getarg_uc, u, v);
489 if (jit_arg_reg_p(v->u.w))
490 jit_extr_uc(u, _I0 + v->u.w);
492 jit_ldxi_uc(u, JIT_FP,
493 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t));
498 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
500 assert(v->code == jit_code_arg);
501 jit_inc_synth_wp(getarg_s, u, v);
502 if (jit_arg_reg_p(v->u.w))
503 jit_extr_s(u, _I0 + v->u.w);
505 jit_ldxi_s(u, JIT_FP,
506 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t));
511 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
513 assert(v->code == jit_code_arg);
514 jit_inc_synth_wp(getarg_us, u, v);
515 if (jit_arg_reg_p(v->u.w))
516 jit_extr_us(u, _I0 + v->u.w);
518 jit_ldxi_us(u, JIT_FP,
519 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t));
524 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
526 assert(v->code == jit_code_arg);
527 jit_inc_synth_wp(getarg_i, u, v);
528 if (jit_arg_reg_p(v->u.w)) {
529 # if __WORDSIZE == 64
530 jit_extr_i(u, _I0 + v->u.w);
532 jit_movr(u, _I0 + v->u.w);
536 jit_ldxi_i(u, JIT_FP,
537 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t));
541 # if __WORDSIZE == 64
543 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
545 assert(v->code == jit_code_arg);
546 jit_inc_synth_wp(getarg_i, u, v);
547 if (jit_arg_reg_p(v->u.w))
548 jit_extr_ui(u, _I0 + v->u.w);
550 jit_ldxi_ui(u, JIT_FP,
551 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t));
556 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
558 assert(v->code == jit_code_arg);
559 jit_inc_synth_wp(getarg_i, u, v);
560 if (jit_arg_reg_p(v->u.w))
561 jit_movr(u, _I0 + v->u.w);
563 jit_ldxi_l(u, JIT_FP, v->u.w);
569 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
571 assert(v->code == jit_code_arg);
572 jit_inc_synth_wp(putargr, u, v);
573 if (jit_arg_reg_p(v->u.w))
574 jit_movr(_I0 + v->u.w, u);
576 jit_stxi(v->u.w, JIT_FP, u);
581 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
584 assert(v->code == jit_code_arg);
585 jit_inc_synth_wp(putargi, u, v);
586 if (jit_arg_reg_p(v->u.w))
587 jit_movi(_I0 + v->u.w, u);
589 regno = jit_get_reg(jit_class_gpr);
591 jit_stxi(v->u.w, JIT_FP, regno);
592 jit_unget_reg(regno);
598 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
600 assert(v->code == jit_code_arg_f);
601 assert(_jitc->function);
602 jit_inc_synth_wp(getarg_f, u, v);
603 # if __WORDSIZE == 32
604 if (jit_arg_reg_p(v->u.w)) {
605 jit_stxi_i(-4, JIT_FP, _I0 + v->u.w);
606 jit_ldxi_f(u, JIT_FP, -4);
609 if (jit_arg_d_reg_p(v->u.w)) {
610 jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */
611 jit_movr_f(u, (_F0 - (v->u.w << 1)) - 1);
615 jit_ldxi_f(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) -
616 sizeof(jit_float32_t));
621 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
623 assert(v->code == jit_code_arg_f);
624 jit_inc_synth_wp(putargr_f, u, v);
625 # if __WORDSIZE == 32
626 if (jit_arg_reg_p(v->u.w)) {
627 jit_stxi_f(-4, JIT_FP, u);
628 jit_ldxi_i(_I0 + v->u.w, JIT_FP, -4);
631 if (jit_arg_d_reg_p(v->u.w)) {
632 jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */
633 jit_movr_f((_F0 - (v->u.w << 1)) - 1, u);
637 jit_stxi_f(v->u.w + (__WORDSIZE >> 3) -
638 sizeof(jit_float32_t), JIT_FP, u);
643 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
646 assert(v->code == jit_code_arg_f);
647 jit_inc_synth_fp(putargi_f, u, v);
648 # if __WORDSIZE == 32
649 regno = jit_get_reg(jit_class_fpr);
650 jit_movi_f(regno, u);
651 if (jit_arg_reg_p(v->u.w)) {
652 jit_stxi_f(-4, JIT_FP, regno);
653 jit_ldxi_i(_I0 + v->u.w, JIT_FP, -4);
656 jit_stxi_f(v->u.w, JIT_FP, regno);
657 jit_unget_reg(regno);
659 if (jit_arg_d_reg_p(v->u.w)) {
660 jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */
661 jit_movi_f((_F0 - (v->u.w << 1)) - 1, u);
664 regno = jit_get_reg(jit_class_fpr | jit_class_sng);
665 jit_movi_f(regno, u);
666 jit_stxi_f(v->u.w + (__WORDSIZE >> 3) -
667 sizeof(jit_float32_t), JIT_FP, regno);
668 jit_unget_reg(regno);
675 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
677 assert(v->code == jit_code_arg_d);
678 assert(_jitc->function);
679 jit_inc_synth_wp(getarg_d, u, v);
680 if (jit_arg_d_reg_p(v->u.w)) {
681 # if __WORDSIZE == 32
682 jit_stxi(-8, JIT_FP, _I0 + v->u.w);
683 jit_stxi(-4, JIT_FP, _I0 + v->u.w + 1);
684 jit_ldxi_d(u, JIT_FP, -8);
686 jit_movr_d(u, _F0 - (v->u.w << 1));
689 # if __WORDSIZE == 32
690 else if (jit_arg_reg_p(v->u.w)) {
691 jit_stxi(-8, JIT_FP, _I0 + v->u.w);
692 jit_ldxi_f(u, JIT_FP, -8);
693 jit_ldxi_f(u + 1, JIT_FP, stack_framesize);
697 # if __WORDSIZE == 32
698 jit_ldxi_f(u, JIT_FP, v->u.w);
699 jit_ldxi_f(u + 1, JIT_FP, v->u.w + 4);
701 jit_ldxi_d(u, JIT_FP, v->u.w);
708 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
711 assert(v->code == jit_code_arg_d);
712 jit_inc_synth_wp(putargr_d, u, v);
713 # if __WORDSIZE == 32
714 if (jit_arg_d_reg_p(v->u.w)) {
715 jit_stxi_d(-8, JIT_FP, u);
716 jit_ldxi(_I0 + v->u.w, JIT_FP, -8);
717 jit_ldxi(_I0 + v->u.w + 1, JIT_FP, -4);
719 else if (jit_arg_reg_p(v->u.w)) {
720 regno = jit_get_reg(jit_class_gpr);
721 jit_stxi_d(-8, JIT_FP, u);
722 jit_ldxi(_I0 + v->u.w, JIT_FP, -8);
723 jit_ldxi(regno, JIT_FP, -4);
724 jit_stxi(stack_framesize, JIT_FP, regno);
725 jit_unget_reg(regno);
727 else if ((v->u.w & 7) == 0)
728 jit_stxi_d(v->u.w, JIT_FP, u);
730 jit_stxi_d(-8, JIT_FP, u);
731 regno = jit_get_reg(jit_class_gpr);
732 jit_ldxi(regno, JIT_FP, -8);
733 jit_stxi(v->u.w, JIT_FP, regno);
734 jit_ldxi(regno, JIT_FP, -4);
735 jit_stxi(v->u.w + 4, JIT_FP, regno);
736 jit_unget_reg(regno);
739 if (jit_arg_d_reg_p(v->u.w))
740 jit_movr_d(_F0 - (v->u.w << 1), u);
742 jit_stxi_d(v->u.w, JIT_FP, u);
748 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
750 # if __WORDSIZE == 32
754 assert(v->code == jit_code_arg_d);
755 jit_inc_synth_dp(putargi_d, u, v);
756 # if __WORDSIZE == 32
757 regno = jit_get_reg(jit_class_fpr);
758 jit_movi_d(regno, u);
759 if (jit_arg_d_reg_p(v->u.w)) {
760 jit_stxi_d(-8, JIT_FP, regno);
761 jit_ldxi(_I0 + v->u.w, JIT_FP, -8);
762 jit_ldxi(_I0 + v->u.w + 1, JIT_FP, -4);
764 else if (jit_arg_reg_p(v->u.w)) {
765 gpr = jit_get_reg(jit_class_gpr);
766 jit_stxi_d(-8, JIT_FP, regno);
767 jit_ldxi(_I0 + v->u.w, JIT_FP, -8);
768 jit_ldxi(gpr, JIT_FP, -4);
769 jit_stxi(stack_framesize, JIT_FP, gpr);
772 else if ((v->u.w & 7) == 0)
773 jit_stxi_d(v->u.w, JIT_FP, regno);
775 jit_stxi_d(-8, JIT_FP, regno);
776 gpr = jit_get_reg(jit_class_gpr);
777 jit_ldxi(gpr, JIT_FP, -8);
778 jit_stxi(v->u.w, JIT_FP, gpr);
779 jit_ldxi(gpr, JIT_FP, -4);
780 jit_stxi(v->u.w + 4, JIT_FP, gpr);
783 jit_unget_reg(regno);
785 if (jit_arg_d_reg_p(v->u.w))
786 jit_movi_d(_F0 - (v->u.w << 1), u);
788 regno = jit_get_reg(jit_class_fpr | jit_class_dbl);
789 jit_movi_d(regno, u);
790 jit_stxi_d(v->u.w, JIT_FP, regno);
791 jit_unget_reg(regno);
798 _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
800 jit_inc_synth_w(pushargr, u);
802 if (jit_arg_reg_p(_jitc->function->call.argi)) {
803 jit_movr(_O0 + _jitc->function->call.argi, u);
804 ++_jitc->function->call.argi;
807 # if __WORDSIZE == 64
808 if (jit_arg_d_reg_p(_jitc->function->call.argi))
809 ++_jitc->function->call.argi;
811 jit_stxi(BIAS(_jitc->function->call.size + stack_framesize),
813 _jitc->function->call.size += sizeof(jit_word_t);
819 _jit_pushargi(jit_state_t *_jit, jit_word_t u)
822 jit_inc_synth_w(pushargi, u);
824 if (jit_arg_reg_p(_jitc->function->call.argi)) {
825 jit_movi(_O0 + _jitc->function->call.argi, u);
826 ++_jitc->function->call.argi;
829 # if __WORDSIZE == 64
830 if (jit_arg_d_reg_p(_jitc->function->call.argi))
831 ++_jitc->function->call.argi;
833 regno = jit_get_reg(jit_class_gpr);
835 jit_stxi(BIAS(_jitc->function->call.size + stack_framesize),
837 jit_unget_reg(regno);
838 _jitc->function->call.size += sizeof(jit_word_t);
844 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
846 jit_inc_synth_w(pushargr_f, u);
848 # if __WORDSIZE == 32
849 if (jit_arg_reg_p(_jitc->function->call.argi)) {
850 jit_stxi_f(-8, JIT_FP, u);
851 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
852 ++_jitc->function->call.argi;
855 jit_stxi_f(_jitc->function->call.size + stack_framesize,
857 _jitc->function->call.size += sizeof(jit_float32_t);
860 if ((_jitc->function->call.call & jit_call_varargs) &&
861 jit_arg_reg_p(_jitc->function->call.argi)) {
862 jit_stxi_f(BIAS(-8), JIT_FP, u);
863 jit_ldxi_i(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
864 ++_jitc->function->call.argi;
866 else if (!(_jitc->function->call.call & jit_call_varargs) &&
867 jit_arg_d_reg_p(_jitc->function->call.argi)) {
868 /* pair of registers is live */
869 jit_live(_F0 - (_jitc->function->call.argi << 1));
870 jit_movr_f((_F0 - (_jitc->function->call.argi << 1)) - 1, u);
871 if (!jit_arg_reg_p(_jitc->function->call.argi))
872 _jitc->function->call.size += sizeof(jit_float64_t);
873 ++_jitc->function->call.argi;
876 jit_stxi_f(BIAS(_jitc->function->call.size + stack_framesize + 4),
878 _jitc->function->call.size += sizeof(jit_float64_t);
885 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
888 jit_inc_synth_f(pushargi_f, u);
890 # if __WORDSIZE == 32
891 regno = jit_get_reg(jit_class_fpr);
892 jit_movi_f(regno, u);
893 if (jit_arg_reg_p(_jitc->function->call.argi)) {
894 jit_stxi_f(-8, JIT_FP, regno);
895 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
896 _jitc->function->call.argi++;
899 jit_stxi_f(_jitc->function->call.size + stack_framesize,
901 _jitc->function->call.size += sizeof(jit_float32_t);
903 jit_unget_reg(regno);
905 if ((_jitc->function->call.call & jit_call_varargs) &&
906 jit_arg_reg_p(_jitc->function->call.argi)) {
907 regno = jit_get_reg(jit_class_fpr | jit_class_sng);
908 jit_movi_f(regno, u);
909 jit_stxi_f(BIAS(-8), JIT_FP, regno);
910 jit_ldxi_i(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
911 ++_jitc->function->call.argi;
912 jit_unget_reg(regno);
914 else if (!(_jitc->function->call.call & jit_call_varargs) &&
915 jit_arg_d_reg_p(_jitc->function->call.argi)) {
916 /* pair of registers is live */
917 jit_live(_F0 - (_jitc->function->call.argi << 1));
918 jit_movi_f((_F0 - (_jitc->function->call.argi << 1)) - 1, u);
919 if (!jit_arg_reg_p(_jitc->function->call.argi))
920 _jitc->function->call.size += sizeof(jit_float64_t);
921 ++_jitc->function->call.argi;
924 regno = jit_get_reg(jit_class_fpr | jit_class_sng);
925 jit_movi_f(regno, u);
926 jit_stxi_f(BIAS(_jitc->function->call.size + stack_framesize + 4),
928 jit_unget_reg(regno);
929 _jitc->function->call.size += sizeof(jit_float64_t);
936 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
938 jit_inc_synth_w(pushargr_d, u);
940 # if __WORDSIZE == 32
941 if (jit_arg_d_reg_p(_jitc->function->call.argi)) {
942 jit_stxi_d(BIAS(-8), JIT_FP, u);
943 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
944 jit_ldxi(_O0 + _jitc->function->call.argi + 1, JIT_FP, -4);
945 _jitc->function->call.argi += 2;
947 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
948 jit_stxi_f(-8, JIT_FP, u);
949 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
950 ++_jitc->function->call.argi;
951 jit_stxi_f(stack_framesize, JIT_SP, u + 1);
952 _jitc->function->call.size += sizeof(jit_float32_t);
955 jit_stxi_f(_jitc->function->call.size + stack_framesize,
957 jit_stxi_f(_jitc->function->call.size + stack_framesize + 4,
959 _jitc->function->call.size += sizeof(jit_float64_t);
962 if ((_jitc->function->call.call & jit_call_varargs) &&
963 jit_arg_reg_p(_jitc->function->call.argi)) {
964 jit_stxi_d(BIAS(-8), JIT_FP, u);
965 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
966 ++_jitc->function->call.argi;
968 else if (!(_jitc->function->call.call & jit_call_varargs) &&
969 jit_arg_d_reg_p(_jitc->function->call.argi)) {
970 jit_movr_d(_F0 - (_jitc->function->call.argi << 1), u);
971 if (!jit_arg_reg_p(_jitc->function->call.argi))
972 _jitc->function->call.size += sizeof(jit_float64_t);
973 ++_jitc->function->call.argi;
976 jit_stxi_d(BIAS(_jitc->function->call.size + stack_framesize),
978 _jitc->function->call.size += sizeof(jit_float64_t);
985 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
988 jit_inc_synth_d(pushargi_d, u);
990 # if __WORDSIZE == 32
991 regno = jit_get_reg(jit_class_fpr);
992 jit_movi_d(regno, u);
993 if (jit_arg_d_reg_p(_jitc->function->call.argi)) {
994 jit_stxi_d(BIAS(-8), JIT_FP, regno);
995 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
996 jit_ldxi(_O0 + _jitc->function->call.argi + 1, JIT_FP, -4);
997 _jitc->function->call.argi += 2;
999 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
1000 jit_stxi_f(-8, JIT_FP, regno);
1001 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
1002 ++_jitc->function->call.argi;
1003 jit_stxi_f(stack_framesize, JIT_SP, u + 1);
1004 _jitc->function->call.size += sizeof(jit_float32_t);
1007 jit_stxi_f(_jitc->function->call.size + stack_framesize,
1009 jit_stxi_f(_jitc->function->call.size + stack_framesize + 4,
1011 _jitc->function->call.size += sizeof(jit_float64_t);
1013 jit_unget_reg(regno);
1015 if ((_jitc->function->call.call & jit_call_varargs) &&
1016 jit_arg_reg_p(_jitc->function->call.argi)) {
1017 regno = jit_get_reg(jit_class_fpr | jit_class_dbl);
1018 jit_movi_d(regno, u);
1019 jit_stxi_d(BIAS(-8), JIT_FP, regno);
1020 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
1021 ++_jitc->function->call.argi;
1022 jit_unget_reg(regno);
1024 else if (!(_jitc->function->call.call & jit_call_varargs) &&
1025 jit_arg_d_reg_p(_jitc->function->call.argi)) {
1026 jit_movi_d(_F0 - (_jitc->function->call.argi << 1), u);
1027 if (!jit_arg_reg_p(_jitc->function->call.argi))
1028 _jitc->function->call.size += sizeof(jit_float64_t);
1029 ++_jitc->function->call.argi;
1032 regno = jit_get_reg(jit_class_fpr | jit_class_dbl);
1033 jit_movi_d(regno, u);
1034 jit_stxi_d(BIAS(_jitc->function->call.size + stack_framesize),
1036 jit_unget_reg(regno);
1037 _jitc->function->call.size += sizeof(jit_float64_t);
1044 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
1048 spec = jit_class(_rvs[regno].spec);
1049 if ((spec & (jit_class_arg|jit_class_gpr)) ==
1050 (jit_class_arg|jit_class_gpr)) {
1052 if (regno >= 0 && regno < node->v.w)
1055 # if __WORDSIZE == 64
1056 if ((spec & (jit_class_arg|jit_class_fpr)) ==
1057 (jit_class_arg|jit_class_fpr)) {
1058 regno = _F0 - (regno >> 1);
1059 if (regno >= 0 && regno < node->v.w)
1068 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
1071 assert(_jitc->function);
1072 jit_inc_synth_w(finishr, r0);
1073 if (_jitc->function->self.alen < _jitc->function->call.size)
1074 _jitc->function->self.alen = _jitc->function->call.size;
1075 call = jit_callr(r0);
1076 call->v.w = _jitc->function->self.argi;
1077 call->w.w = _jitc->function->self.argf;
1078 _jitc->function->call.argi = _jitc->function->call.argf =
1079 _jitc->function->call.size = 0;
1085 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
1088 assert(_jitc->function);
1089 jit_inc_synth_w(finishi, (jit_word_t)i0);
1090 if (_jitc->function->self.alen < _jitc->function->call.size)
1091 _jitc->function->self.alen = _jitc->function->call.size;
1092 node = jit_calli(i0);
1093 node->v.w = _jitc->function->call.argi;
1094 node->w.w = _jitc->function->call.argf;
1095 _jitc->function->call.argi = _jitc->function->call.argf =
1096 _jitc->function->call.size = 0;
1103 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
1105 jit_inc_synth_w(retval_c, r0);
1106 jit_extr_c(r0, _O0);
1111 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
1113 jit_inc_synth_w(retval_uc, r0);
1114 jit_extr_uc(r0, _O0);
1119 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
1121 jit_inc_synth_w(retval_s, r0);
1122 jit_extr_s(r0, _O0);
1127 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
1129 jit_inc_synth_w(retval_us, r0);
1130 jit_extr_us(r0, _O0);
1135 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
1137 jit_inc_synth_w(retval_i, r0);
1138 # if __WORDSIZE == 32
1142 jit_extr_i(r0, _O0);
1147 # if __WORDSIZE == 64
1149 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
1151 jit_inc_synth_w(retval_i, r0);
1153 jit_extr_ui(r0, _O0);
1158 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
1160 jit_inc_synth_w(retval_i, r0);
1168 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
1170 jit_inc_synth_w(retval_f, r0);
1172 jit_movr_f(r0, JIT_FRET);
1177 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
1179 jit_inc_synth_w(retval_d, r0);
1181 jit_movr_d(r0, JIT_FRET);
1186 _emit_code(jit_state_t *_jit)
1196 #if DEVEL_DISASSEMBLER
1199 jit_int32_t patch_offset;
1201 #if DEVEL_DISASSEMBLER
1205 _jitc->function = NULL;
1207 jit_reglive_setup();
1211 undo.patch_offset = 0;
1213 #define case_rr(name, type) \
1214 case jit_code_##name##r##type: \
1215 name##r##type(rn(node->u.w), rn(node->v.w)); \
1217 #define case_rw(name, type) \
1218 case jit_code_##name##i##type: \
1219 name##i##type(rn(node->u.w), node->v.w); \
1221 #define case_wr(name, type) \
1222 case jit_code_##name##i##type: \
1223 name##i##type(node->u.w, rn(node->v.w)); \
1225 #define case_rf(name) \
1226 case jit_code_##name##i##type: \
1227 assert(node->flag & jit_flag_data); \
1228 name##_f(rn(node->u.w), \
1229 (jit_float32_t *)node->v.n->u.w); \
1231 #define case_rd(name) \
1232 case jit_code_##name##i_d: \
1233 assert(node->flag & jit_flag_data); \
1234 name##_d(rn(node->u.w), \
1235 (jit_float64_t *)node->v.n->u.w); \
1237 #define case_rrr(name, type) \
1238 case jit_code_##name##r##type: \
1239 name##r##type(rn(node->u.w), \
1240 rn(node->v.w), rn(node->w.w)); \
1242 #define case_rrrr(name, type) \
1243 case jit_code_##name##r##type: \
1244 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
1245 rn(node->v.w), rn(node->w.w)); \
1247 #define case_rrw(name, type) \
1248 case jit_code_##name##i##type: \
1249 name##i##type(rn(node->u.w), \
1250 rn(node->v.w), node->w.w); \
1252 #define case_rrrw(name, type) \
1253 case jit_code_##name##i##type: \
1254 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
1255 rn(node->v.w), node->w.w); \
1257 #define case_rrf(name, type, size) \
1258 case jit_code_##name##i##type: \
1259 assert(node->flag & jit_flag_data); \
1260 name##i##type(rn(node->u.w), rn(node->v.w), \
1261 (jit_float##size##_t *)node->w.n->u.w); \
1263 #define case_wrr(name, type) \
1264 case jit_code_##name##i##type: \
1265 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1267 #define case_brr(name, type) \
1268 case jit_code_##name##r##type: \
1270 assert(temp->code == jit_code_label || \
1271 temp->code == jit_code_epilog); \
1272 if (temp->flag & jit_flag_patch) \
1273 name##r##type(temp->u.w, rn(node->v.w), \
1276 word = name##r##type(_jit->pc.w, \
1277 rn(node->v.w), rn(node->w.w)); \
1278 patch(word, node); \
1281 #define case_brw(name, type) \
1282 case jit_code_##name##i##type: \
1284 assert(temp->code == jit_code_label || \
1285 temp->code == jit_code_epilog); \
1286 if (temp->flag & jit_flag_patch) \
1287 name##i##type(temp->u.w, \
1288 rn(node->v.w), node->w.w); \
1290 word = name##i##type(_jit->pc.w, \
1291 rn(node->v.w), node->w.w); \
1292 patch(word, node); \
1295 #define case_brf(name, type, size) \
1296 case jit_code_##name##i##type: \
1298 assert(temp->code == jit_code_label || \
1299 temp->code == jit_code_epilog); \
1300 if (temp->flag & jit_flag_patch) \
1301 name##i##type(temp->u.w, rn(node->v.w), \
1302 (jit_float##size##_t *)node->w.n->u.w); \
1304 word = name##i##type(_jit->pc.w, rn(node->v.w), \
1305 (jit_float##size##_t *)node->w.n->u.w); \
1306 patch(word, node); \
1309 #if DEVEL_DISASSEMBLER
1312 for (node = _jitc->head; node; node = node->next) {
1313 if (_jit->pc.uc >= _jitc->code.end)
1316 #if DEVEL_DISASSEMBLER
1317 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1320 value = jit_classify(node->code);
1321 jit_regarg_set(node, value);
1322 switch (node->code) {
1323 case jit_code_align:
1324 assert(!(node->u.w & (node->u.w - 1)) &&
1325 node->u.w <= sizeof(jit_word_t));
1326 if (node->u.w == sizeof(jit_word_t) &&
1327 (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
1328 nop(sizeof(jit_word_t) - word);
1330 case jit_code_note: case jit_code_name:
1331 node->u.w = _jit->pc.w;
1333 case jit_code_label:
1334 if ((node->link || (node->flag & jit_flag_use)) &&
1335 (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
1336 nop(sizeof(jit_word_t) - word);
1337 /* remember label is defined */
1338 node->flag |= jit_flag_patch;
1339 node->u.w = _jit->pc.w;
1358 case_rrrr(qmul, _u);
1359 case_rrrw(qmul, _u);
1366 case_rrrr(qdiv, _u);
1367 case_rrrw(qdiv, _u);
1384 case_rr(trunc, _f_i);
1385 case_rr(trunc, _d_i);
1386 #if __WORDSIZE == 64
1387 case_rr(trunc, _f_l);
1388 case_rr(trunc, _d_l);
1420 #if __WORDSIZE == 64
1436 #if __WORDSIZE == 64
1448 #if __WORDSIZE == 64
1458 #if __WORDSIZE == 64
1464 #if __WORDSIZE == 64
1467 case_rr(bswap, _us);
1468 case_rr(bswap, _ui);
1469 #if __WORDSIZE == 64
1470 case_rr(bswap, _ul);
1476 #if __WORDSIZE == 64
1484 if (node->flag & jit_flag_node) {
1486 if (temp->code == jit_code_data ||
1487 (temp->code == jit_code_label &&
1488 (temp->flag & jit_flag_patch)))
1489 movi(rn(node->u.w), temp->u.w);
1491 assert(temp->code == jit_code_label ||
1492 temp->code == jit_code_epilog);
1493 word = movi_p(rn(node->u.w), node->v.w);
1498 movi(rn(node->u.w), node->v.w);
1524 case_brr(boadd, _u);
1525 case_brw(boadd, _u);
1528 case_brr(bxadd, _u);
1529 case_brw(bxadd, _u);
1532 case_brr(bosub, _u);
1533 case_brw(bosub, _u);
1536 case_brr(bxsub, _u);
1537 case_brw(bxsub, _u);
1543 case_rrf(add, _f, 32);
1545 case_rrf(sub, _f, 32);
1546 case_rrf(rsb, _f, 32);
1548 case_rrf(mul, _f, 32);
1550 case_rrf(div, _f, 32);
1557 case_rrf(lt, _f, 32);
1559 case_rrf(le, _f, 32);
1561 case_rrf(eq, _f, 32);
1563 case_rrf(ge, _f, 32);
1565 case_rrf(gt, _f, 32);
1567 case_rrf(ne, _f, 32);
1569 case_rrf(unlt, _f, 32);
1571 case_rrf(unle, _f, 32);
1573 case_rrf(uneq, _f, 32);
1575 case_rrf(unge, _f, 32);
1577 case_rrf(ungt, _f, 32);
1579 case_rrf(ltgt, _f, 32);
1581 case_rrf(ord, _f, 32);
1582 case_rrr(unord, _f);
1583 case_rrf(unord, _f, 32);
1593 case jit_code_movi_f:
1594 assert(node->flag & jit_flag_data);
1595 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1598 case_brf(blt, _f, 32);
1600 case_brf(ble, _f, 32);
1602 case_brf(beq, _f, 32);
1604 case_brf(bge, _f, 32);
1606 case_brf(bgt, _f, 32);
1608 case_brf(bne, _f, 32);
1609 case_brr(bunlt, _f);
1610 case_brf(bunlt, _f, 32);
1611 case_brr(bunle, _f);
1612 case_brf(bunle, _f, 32);
1613 case_brr(buneq, _f);
1614 case_brf(buneq, _f, 32);
1615 case_brr(bunge, _f);
1616 case_brf(bunge, _f, 32);
1617 case_brr(bungt, _f);
1618 case_brf(bungt, _f, 32);
1619 case_brr(bltgt, _f);
1620 case_brf(bltgt, _f, 32);
1622 case_brf(bord, _f, 32);
1623 case_brr(bunord, _f);
1624 case_brf(bunord, _f, 32);
1626 case_rrf(add, _d, 64);
1628 case_rrf(sub, _d, 64);
1629 case_rrf(rsb, _d, 64);
1631 case_rrf(mul, _d, 64);
1633 case_rrf(div, _d, 64);
1640 case_rrf(lt, _d, 64);
1642 case_rrf(le, _d, 64);
1644 case_rrf(eq, _d, 64);
1646 case_rrf(ge, _d, 64);
1648 case_rrf(gt, _d, 64);
1650 case_rrf(ne, _d, 64);
1652 case_rrf(unlt, _d, 64);
1654 case_rrf(unle, _d, 64);
1656 case_rrf(uneq, _d, 64);
1658 case_rrf(unge, _d, 64);
1660 case_rrf(ungt, _d, 64);
1662 case_rrf(ltgt, _d, 64);
1664 case_rrf(ord, _d, 64);
1665 case_rrr(unord, _d);
1666 case_rrf(unord, _d, 64);
1676 case jit_code_movi_d:
1677 assert(node->flag & jit_flag_data);
1678 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1681 case_brf(blt, _d, 64);
1683 case_brf(ble, _d, 64);
1685 case_brf(beq, _d, 64);
1687 case_brf(bge, _d, 64);
1689 case_brf(bgt, _d, 64);
1691 case_brf(bne, _d, 64);
1692 case_brr(bunlt, _d);
1693 case_brf(bunlt, _d, 64);
1694 case_brr(bunle, _d);
1695 case_brf(bunle, _d, 64);
1696 case_brr(buneq, _d);
1697 case_brf(buneq, _d, 64);
1698 case_brr(bunge, _d);
1699 case_brf(bunge, _d, 64);
1700 case_brr(bungt, _d);
1701 case_brf(bungt, _d, 64);
1702 case_brr(bltgt, _d);
1703 case_brf(bltgt, _d, 64);
1705 case_brf(bord, _d, 64);
1706 case_brr(bunord, _d);
1707 case_brf(bunord, _d, 64);
1709 jmpr(rn(node->u.w));
1712 if (node->flag & jit_flag_node) {
1714 assert(temp->code == jit_code_label ||
1715 temp->code == jit_code_epilog);
1716 if (temp->flag & jit_flag_patch)
1719 word = jmpi_p(_jit->pc.w);
1726 case jit_code_callr:
1727 callr(rn(node->u.w));
1729 case jit_code_calli:
1730 if (node->flag & jit_flag_node) {
1732 assert(temp->code == jit_code_label ||
1733 temp->code == jit_code_epilog);
1734 word = calli_p(temp->u.w);
1735 if (!(temp->flag & jit_flag_patch))
1741 case jit_code_prolog:
1742 _jitc->function = _jitc->functions.ptr + node->w.w;
1744 undo.word = _jit->pc.w;
1745 #if DEVEL_DISASSEMBLER
1748 undo.patch_offset = _jitc->patches.offset;
1753 case jit_code_epilog:
1754 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1756 for (temp = undo.node->next;
1757 temp != node; temp = temp->next) {
1758 if (temp->code == jit_code_label ||
1759 temp->code == jit_code_epilog)
1760 temp->flag &= ~jit_flag_patch;
1762 temp->flag &= ~jit_flag_patch;
1764 _jit->pc.w = undo.word;
1765 #if DEVEL_DISASSEMBLER
1768 _jitc->patches.offset = undo.patch_offset;
1769 goto restart_function;
1771 /* remember label is defined */
1772 node->flag |= jit_flag_patch;
1773 node->u.w = _jit->pc.w;
1775 _jitc->function = NULL;
1777 case jit_code_va_start:
1778 vastart(rn(node->u.w));
1780 case jit_code_va_arg:
1781 vaarg(rn(node->u.w), rn(node->v.w));
1783 case jit_code_va_arg_d:
1784 vaarg_d(rn(node->u.w), rn(node->v.w));
1786 case jit_code_live: case jit_code_ellipsis:
1787 case jit_code_va_push:
1788 case jit_code_allocai: case jit_code_allocar:
1790 case jit_code_arg_f: case jit_code_arg_d:
1791 case jit_code_va_end:
1793 case jit_code_retr: case jit_code_reti:
1794 case jit_code_retr_f: case jit_code_reti_f:
1795 case jit_code_retr_d: case jit_code_reti_d:
1796 case jit_code_getarg_c: case jit_code_getarg_uc:
1797 case jit_code_getarg_s: case jit_code_getarg_us:
1798 case jit_code_getarg_i:
1799 #if __WORDSIZE == 64
1800 case jit_code_getarg_ui: case jit_code_getarg_l:
1802 case jit_code_getarg_f: case jit_code_getarg_d:
1803 case jit_code_putargr: case jit_code_putargi:
1804 case jit_code_putargr_f: case jit_code_putargi_f:
1805 case jit_code_putargr_d: case jit_code_putargi_d:
1806 case jit_code_pushargr: case jit_code_pushargi:
1807 case jit_code_pushargr_f: case jit_code_pushargi_f:
1808 case jit_code_pushargr_d: case jit_code_pushargi_d:
1809 case jit_code_retval_c: case jit_code_retval_uc:
1810 case jit_code_retval_s: case jit_code_retval_us:
1811 case jit_code_retval_i:
1812 #if __WORDSIZE == 64
1813 case jit_code_retval_ui: case jit_code_retval_l:
1815 case jit_code_retval_f: case jit_code_retval_d:
1816 case jit_code_prepare:
1817 case jit_code_finishr: case jit_code_finishi:
1822 # if __WORDSIZE == 64
1823 if (jit_carry != _NOREG) {
1824 switch (node->code) {
1826 case jit_code_addcr: case jit_code_addci:
1827 case jit_code_addxr: case jit_code_addxi:
1828 case jit_code_subcr: case jit_code_subci:
1829 case jit_code_subxr: case jit_code_subxi:
1832 jit_unget_reg(jit_carry);
1838 jit_regarg_clr(node, value);
1839 # if __WORDSIZE == 64
1840 if (jit_regset_cmp_ui(&_jitc->regarg, 0) != 0) {
1841 assert(jit_regset_scan1(&_jitc->regarg, 0) == jit_carry);
1842 assert(jit_regset_scan1(&_jitc->regarg, jit_carry + 1) == ULONG_MAX);
1844 assert(_jitc->synth == 0);
1846 assert(_jitc->regarg == 0 && _jitc->synth == 0);
1864 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1865 node = _jitc->patches.ptr[offset].node;
1866 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1867 patch_at(_jitc->patches.ptr[offset].inst, word);
1870 jit_flush(_jit->code.ptr, _jit->pc.uc);
1872 return (_jit->code.ptr);
1876 # include "jit_sparc-cpu.c"
1877 # include "jit_sparc-fpu.c"
1881 jit_flush(void *fptr, void *tptr)
1886 _emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0)
1888 ldxi(rn(r0), rn(r1), i0);
1892 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1)
1894 stxi(i0, rn(r0), rn(r1));
1898 _emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0)
1900 ldxi_d(rn(r0), rn(r1), i0);
1904 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1)
1906 stxi_d(i0, rn(r0), rn(r1));
1910 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
1914 assert(node->flag & jit_flag_node);
1915 if (node->code == jit_code_movi)
1916 flag = node->v.n->flag;
1918 flag = node->u.n->flag;
1919 assert(!(flag & jit_flag_patch));
1920 if (_jitc->patches.offset >= _jitc->patches.length) {
1921 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
1922 _jitc->patches.length * sizeof(jit_patch_t),
1923 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
1924 memset(_jitc->patches.ptr + _jitc->patches.length, 0,
1925 1024 * sizeof(jit_patch_t));
1926 _jitc->patches.length += 1024;
1928 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
1929 _jitc->patches.ptr[_jitc->patches.offset].node = node;
1930 ++_jitc->patches.offset;