2 * Copyright (C) 2013-2023 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 /* Handling SIGILL should not be done by Lightning, but can either use
21 * sample, or use another approach to set jit_cpu.lzcnt
30 #define jit_arg_reg_p(i) ((i) >= 0 && (i) < 6)
32 # define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 5)
35 # define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 16)
36 # define BIAS(n) ((n) + 2047)
42 typedef jit_pointer_t jit_va_list_t;
47 #define patch(instr, node) _patch(_jit, instr, node)
48 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
51 # include "jit_sparc-cpu.c"
52 # include "jit_sparc-fpu.c"
53 # include "jit_fallback.c"
60 jit_register_t _rvs[] = {
63 { rc(gpr) | 0x02, "%g2" },
64 { rc(gpr) | 0x03, "%g3" },
65 { rc(gpr) | 0x04, "%g4" },
69 { rc(arg) | rc(gpr) | 0x08, "%o0" },
70 { rc(arg) | rc(gpr) | 0x09, "%o1" },
71 { rc(arg) | rc(gpr) | 0x0a, "%o2" },
72 { rc(arg) | rc(gpr) | 0x0b, "%o3" },
73 { rc(arg) | rc(gpr) | 0x0c, "%o4" },
74 { rc(arg) | rc(gpr) | 0x0d, "%o5" },
75 { rc(sav) | 0x0e, "%sp" },
77 { rc(sav) | rc(gpr) | 0x10, "%l0" },
78 { rc(sav) | rc(gpr) | 0x11, "%l1" },
79 { rc(sav) | rc(gpr) | 0x12, "%l2" },
80 { rc(sav) | rc(gpr) | 0x13, "%l3" },
81 { rc(sav) | rc(gpr) | 0x14, "%l4" },
82 { rc(sav) | rc(gpr) | 0x15, "%l5" },
83 { rc(sav) | rc(gpr) | 0x16, "%l6" },
84 { rc(sav) | rc(gpr) | 0x17, "%l7" },
91 { rc(sav) | 0x1e, "%fp" },
94 { rc(fpr) | 0x00, "%f0" },
96 { rc(fpr) | 0x02, "%f2" },
98 { rc(fpr) | 0x04, "%f4" },
100 { rc(fpr) | 0x06, "%f6" },
102 { rc(fpr) | 0x08, "%f8" },
104 { rc(fpr) | 0x0a, "%f10" },
106 { rc(fpr) | 0x0c, "%f12" },
108 { rc(fpr) | 0x0e, "%f14" },
111 { rc(fpr) | rc(dbl) | 0x3e, "%f62" },
112 { rc(fpr) | rc(dbl) | 0x3c, "%f60" },
113 { rc(fpr) | rc(dbl) | 0x3a, "%f58" },
114 { rc(fpr) | rc(dbl) | 0x38, "%f56" },
115 { rc(fpr) | rc(dbl) | 0x36, "%f54" },
116 { rc(fpr) | rc(dbl) | 0x34, "%f52" },
117 { rc(fpr) | rc(dbl) | 0x32, "%f50" },
118 { rc(fpr) | rc(dbl) | 0x30, "%f48" },
119 { rc(fpr) | rc(dbl) | 0x2e, "%f46" },
120 { rc(fpr) | rc(dbl) | 0x2c, "%f44" },
121 { rc(fpr) | rc(dbl) | 0x2a, "%f42" },
122 { rc(fpr) | rc(dbl) | 0x28, "%f40" },
123 { rc(fpr) | rc(dbl) | 0x26, "%f38" },
124 { rc(fpr) | rc(dbl) | 0x24, "%f36" },
125 { rc(fpr) | rc(dbl) | 0x22, "%f34" },
126 { rc(fpr) | rc(dbl) | 0x20, "%f32" },
128 { rc(arg)|rc(fpr)|rc(sng)|0x1e, "%f30" },
130 { rc(arg)|rc(fpr)|rc(sng)|0x1c, "%f28" },
132 { rc(arg)|rc(fpr)|rc(sng)|0x1a, "%f26" },
134 { rc(arg)|rc(fpr)|rc(sng)|0x18, "%f24" },
136 { rc(arg)|rc(fpr)|rc(sng)|0x16, "%f22" },
138 { rc(arg)|rc(fpr)|rc(sng)|0x14, "%f20" },
140 { rc(arg)|rc(fpr)|rc(sng)|0x12, "%f18" },
142 { rc(arg)|rc(fpr)|rc(sng)|0x10, "%f16" },
144 { rc(arg)|rc(fpr)|rc(sng)|0x0e, "%f14" },
146 { rc(arg)|rc(fpr)|rc(sng)|0x0c, "%f12" },
148 { rc(arg)|rc(fpr)|rc(sng)|0x0a, "%f10" },
150 { rc(arg)|rc(fpr)|rc(sng)|0x08, "%f8" },
152 { rc(arg)|rc(fpr)|rc(sng)|0x06, "%f6" },
154 { rc(arg)|rc(fpr)|rc(sng)|0x04, "%f4" },
156 { rc(arg)|rc(fpr)|rc(sng)|0x02, "%f2" },
158 { rc(arg)|rc(fpr)|rc(sng)|0x00, "%f0" },
160 { _NOREG, "<none>" },
171 sigill_handler(int signum)
174 siglongjmp(jit_env, 1);
183 struct sigaction new_action, old_action;
184 new_action.sa_handler = sigill_handler;
185 sigemptyset(&new_action.sa_mask);
186 new_action.sa_flags = 0;
187 sigaction(SIGILL, NULL, &old_action);
188 if (old_action.sa_handler != SIG_IGN) {
189 sigaction(SIGILL, &new_action, NULL);
190 if (!sigsetjmp(jit_env, 1)) {
193 __asm__ volatile("mov %%g2, %0; .long 0xa3b0021; mov %0, %%g2"
195 sigaction(SIGILL, &old_action, NULL);
204 _jit_init(jit_state_t *_jit)
206 _jitc->reglen = jit_size(_rvs) - 1;
207 # if __WORDSIZE == 64
213 _jit_prolog(jit_state_t *_jit)
219 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
220 jit_regset_set_ui(&_jitc->regsav, 0);
221 offset = _jitc->functions.offset;
222 if (offset >= _jitc->functions.length) {
223 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
224 _jitc->functions.length * sizeof(jit_function_t),
225 (_jitc->functions.length + 16) * sizeof(jit_function_t));
226 _jitc->functions.length += 16;
228 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
229 _jitc->function->self.size = stack_framesize;
230 _jitc->function->self.argi = _jitc->function->self.argf =
231 _jitc->function->self.alen = 0;
232 /* float conversion */
233 # if __WORDSIZE == 32
234 _jitc->function->self.aoff = -8;
236 /* extra slots in case qmul is called */
237 _jitc->function->self.aoff = -24;
239 _jitc->function->self.call = jit_call_default;
240 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
241 _jitc->reglen * sizeof(jit_int32_t));
243 /* _no_link here does not mean the jit_link() call can be removed
245 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
247 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
248 jit_link(_jitc->function->prolog);
249 _jitc->function->prolog->w.w = offset;
250 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
252 * v: offset in blocks vector
253 * w: offset in functions vector
255 _jitc->function->epilog->w.w = offset;
257 jit_regset_new(&_jitc->function->regset);
261 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
263 assert(_jitc->function);
265 case 0: case 1: break;
266 case 2: _jitc->function->self.aoff &= -2; break;
267 case 3: case 4: _jitc->function->self.aoff &= -4; break;
268 default: _jitc->function->self.aoff &= -8; break;
270 _jitc->function->self.aoff -= length;
271 if (!_jitc->realize) {
272 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
275 return (BIAS(_jitc->function->self.aoff));
279 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
282 assert(_jitc->function);
283 jit_inc_synth_ww(allocar, u, v);
284 if (!_jitc->function->allocar) {
285 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
286 _jitc->function->allocar = 1;
288 reg = jit_get_reg(jit_class_gpr);
290 jit_andi(reg, reg, -16);
291 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
293 jit_addr(_SP, _SP, reg);
294 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
300 _jit_ret(jit_state_t *_jit)
303 assert(_jitc->function);
307 jit_patch_at(instr, _jitc->function->epilog);
312 _jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
314 jit_code_inc_synth_w(code, u);
315 jit_movr(JIT_RET, u);
321 _jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
323 jit_code_inc_synth_w(code, u);
324 jit_movi(JIT_RET, u);
330 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
332 jit_inc_synth_w(retr_f, u);
334 jit_movr_f(JIT_FRET, u);
342 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
344 jit_inc_synth_f(reti_f, u);
345 jit_movi_f(JIT_FRET, u);
351 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
353 jit_inc_synth_w(retr_d, u);
355 jit_movr_d(JIT_FRET, u);
363 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
365 jit_inc_synth_d(reti_d, u);
366 jit_movi_d(JIT_FRET, u);
372 _jit_epilog(jit_state_t *_jit)
374 assert(_jitc->function);
375 assert(_jitc->function->epilog->next == NULL);
376 jit_link(_jitc->function->epilog);
377 _jitc->function = NULL;
381 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
383 # if __WORDSIZE == 32
384 if ((u->code >= jit_code_arg_c && u->code <= jit_code_arg) ||
385 u->code == jit_code_arg_f)
386 return (jit_arg_reg_p(u->u.w));
387 assert(u->code == jit_code_arg_d);
388 return (jit_arg_d_reg_p(u->u.w));
390 if (u->code >= jit_code_arg_c && u->code <= jit_code_arg)
391 return (jit_arg_reg_p(u->u.w));
392 assert(u->code == jit_code_arg_d || u->code == jit_code_arg_f);
393 return (jit_arg_d_reg_p(u->u.w));
398 _jit_ellipsis(jit_state_t *_jit)
400 jit_inc_synth(ellipsis);
401 if (_jitc->prepare) {
403 assert(!(_jitc->function->call.call & jit_call_varargs));
404 _jitc->function->call.call |= jit_call_varargs;
408 assert(!(_jitc->function->self.call & jit_call_varargs));
409 _jitc->function->self.call |= jit_call_varargs;
411 _jitc->function->vagp = _jitc->function->self.argi;
417 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
419 jit_inc_synth_w(va_push, u);
425 _jit_arg(jit_state_t *_jit, jit_code_t code)
429 assert(_jitc->function);
430 assert(!(_jitc->function->self.call & jit_call_varargs));
431 #if STRONG_TYPE_CHECKING
432 assert(code >= jit_code_arg_c && code <= jit_code_arg);
434 if (jit_arg_reg_p(_jitc->function->self.argi))
435 offset = _jitc->function->self.argi++;
437 # if __WORDSIZE == 64
438 if (jit_arg_d_reg_p(_jitc->function->self.argi))
439 ++_jitc->function->self.argi;
441 offset = BIAS(_jitc->function->self.size);
442 _jitc->function->self.size += sizeof(jit_word_t);
444 node = jit_new_node_ww(code, offset,
445 ++_jitc->function->self.argn);
451 _jit_arg_f(jit_state_t *_jit)
455 # if __WORDSIZE == 64
458 assert(_jitc->function);
459 # if __WORDSIZE == 32
460 if (jit_arg_reg_p(_jitc->function->self.argi))
461 offset = _jitc->function->self.argi++;
463 offset = _jitc->function->self.size;
464 _jitc->function->self.size += sizeof(jit_word_t);
467 inc = !jit_arg_reg_p(_jitc->function->self.argi);
468 if (jit_arg_d_reg_p(_jitc->function->self.argi))
469 offset = _jitc->function->self.argi++;
471 offset = BIAS(_jitc->function->self.size);
473 _jitc->function->self.size += sizeof(jit_word_t);
475 node = jit_new_node_ww(jit_code_arg_f, offset,
476 ++_jitc->function->self.argn);
482 _jit_arg_d(jit_state_t *_jit)
486 # if __WORDSIZE == 64
489 assert(_jitc->function);
490 # if __WORDSIZE == 32
491 if (jit_arg_d_reg_p(_jitc->function->self.argi)) {
492 offset = _jitc->function->self.argi;
493 _jitc->function->self.argi += 2;
495 else if (jit_arg_reg_p(_jitc->function->self.argi)) {
496 offset = _jitc->function->self.argi++;
497 _jitc->function->self.size += sizeof(jit_float32_t);
500 offset = _jitc->function->self.size;
501 _jitc->function->self.size += sizeof(jit_float64_t);
504 inc = !jit_arg_reg_p(_jitc->function->self.argi);
505 if (jit_arg_d_reg_p(_jitc->function->self.argi))
506 offset = _jitc->function->self.argi++;
508 offset = BIAS(_jitc->function->self.size);
510 _jitc->function->self.size += sizeof(jit_word_t);
512 node = jit_new_node_ww(jit_code_arg_d, offset,
513 ++_jitc->function->self.argn);
519 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
521 assert_arg_type(v->code, jit_code_arg_c);
522 jit_inc_synth_wp(getarg_c, u, v);
523 if (jit_arg_reg_p(v->u.w))
524 jit_extr_c(u, _I0 + v->u.w);
526 jit_ldxi_c(u, JIT_FP,
527 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t));
532 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
534 assert_arg_type(v->code, jit_code_arg_c);
535 jit_inc_synth_wp(getarg_uc, u, v);
536 if (jit_arg_reg_p(v->u.w))
537 jit_extr_uc(u, _I0 + v->u.w);
539 jit_ldxi_uc(u, JIT_FP,
540 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t));
545 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
547 assert_arg_type(v->code, jit_code_arg_s);
548 jit_inc_synth_wp(getarg_s, u, v);
549 if (jit_arg_reg_p(v->u.w))
550 jit_extr_s(u, _I0 + v->u.w);
552 jit_ldxi_s(u, JIT_FP,
553 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t));
558 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
560 assert_arg_type(v->code, jit_code_arg_s);
561 jit_inc_synth_wp(getarg_us, u, v);
562 if (jit_arg_reg_p(v->u.w))
563 jit_extr_us(u, _I0 + v->u.w);
565 jit_ldxi_us(u, JIT_FP,
566 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t));
571 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
573 assert_arg_type(v->code, jit_code_arg_i);
574 jit_inc_synth_wp(getarg_i, u, v);
575 if (jit_arg_reg_p(v->u.w)) {
576 # if __WORDSIZE == 64
577 jit_extr_i(u, _I0 + v->u.w);
579 jit_movr(u, _I0 + v->u.w);
583 jit_ldxi_i(u, JIT_FP,
584 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t));
588 # if __WORDSIZE == 64
590 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
592 assert_arg_type(v->code, jit_code_arg_i);
593 jit_inc_synth_wp(getarg_i, u, v);
594 if (jit_arg_reg_p(v->u.w))
595 jit_extr_ui(u, _I0 + v->u.w);
597 jit_ldxi_ui(u, JIT_FP,
598 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t));
603 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
605 assert_arg_type(v->code, jit_code_arg_l);
606 jit_inc_synth_wp(getarg_i, u, v);
607 if (jit_arg_reg_p(v->u.w))
608 jit_movr(u, _I0 + v->u.w);
610 jit_ldxi_l(u, JIT_FP, v->u.w);
616 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
618 assert_putarg_type(code, v->code);
619 jit_code_inc_synth_wp(code, u, v);
620 if (jit_arg_reg_p(v->u.w))
621 jit_movr(_I0 + v->u.w, u);
623 jit_stxi(v->u.w, JIT_FP, u);
628 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
631 assert_putarg_type(code, v->code);
632 jit_code_inc_synth_wp(code, u, v);
633 if (jit_arg_reg_p(v->u.w))
634 jit_movi(_I0 + v->u.w, u);
636 regno = jit_get_reg(jit_class_gpr);
638 jit_stxi(v->u.w, JIT_FP, regno);
639 jit_unget_reg(regno);
645 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
647 assert(v->code == jit_code_arg_f);
648 assert(_jitc->function);
649 jit_inc_synth_wp(getarg_f, u, v);
650 # if __WORDSIZE == 32
651 if (jit_arg_reg_p(v->u.w)) {
652 jit_stxi_i(-4, JIT_FP, _I0 + v->u.w);
653 jit_ldxi_f(u, JIT_FP, -4);
656 if (jit_arg_d_reg_p(v->u.w)) {
657 jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */
658 jit_movr_f(u, (_F0 - (v->u.w << 1)) - 1);
662 jit_ldxi_f(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) -
663 sizeof(jit_float32_t));
668 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
670 assert(v->code == jit_code_arg_f);
671 jit_inc_synth_wp(putargr_f, u, v);
672 # if __WORDSIZE == 32
673 if (jit_arg_reg_p(v->u.w)) {
674 jit_stxi_f(-4, JIT_FP, u);
675 jit_ldxi_i(_I0 + v->u.w, JIT_FP, -4);
678 if (jit_arg_d_reg_p(v->u.w)) {
679 jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */
680 jit_movr_f((_F0 - (v->u.w << 1)) - 1, u);
684 jit_stxi_f(v->u.w + (__WORDSIZE >> 3) -
685 sizeof(jit_float32_t), JIT_FP, u);
690 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
693 assert(v->code == jit_code_arg_f);
694 jit_inc_synth_fp(putargi_f, u, v);
695 # if __WORDSIZE == 32
696 regno = jit_get_reg(jit_class_fpr);
697 jit_movi_f(regno, u);
698 if (jit_arg_reg_p(v->u.w)) {
699 jit_stxi_f(-4, JIT_FP, regno);
700 jit_ldxi_i(_I0 + v->u.w, JIT_FP, -4);
703 jit_stxi_f(v->u.w, JIT_FP, regno);
704 jit_unget_reg(regno);
706 if (jit_arg_d_reg_p(v->u.w)) {
707 jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */
708 jit_movi_f((_F0 - (v->u.w << 1)) - 1, u);
711 regno = jit_get_reg(jit_class_fpr | jit_class_sng);
712 jit_movi_f(regno, u);
713 jit_stxi_f(v->u.w + (__WORDSIZE >> 3) -
714 sizeof(jit_float32_t), JIT_FP, regno);
715 jit_unget_reg(regno);
722 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
724 assert(v->code == jit_code_arg_d);
725 assert(_jitc->function);
726 jit_inc_synth_wp(getarg_d, u, v);
727 if (jit_arg_d_reg_p(v->u.w)) {
728 # if __WORDSIZE == 32
729 jit_stxi(-8, JIT_FP, _I0 + v->u.w);
730 jit_stxi(-4, JIT_FP, _I0 + v->u.w + 1);
731 jit_ldxi_d(u, JIT_FP, -8);
733 jit_movr_d(u, _F0 - (v->u.w << 1));
736 # if __WORDSIZE == 32
737 else if (jit_arg_reg_p(v->u.w)) {
738 jit_stxi(-8, JIT_FP, _I0 + v->u.w);
739 jit_ldxi_f(u, JIT_FP, -8);
740 jit_ldxi_f(u + 1, JIT_FP, stack_framesize);
744 # if __WORDSIZE == 32
745 jit_ldxi_f(u, JIT_FP, v->u.w);
746 jit_ldxi_f(u + 1, JIT_FP, v->u.w + 4);
748 jit_ldxi_d(u, JIT_FP, v->u.w);
755 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
758 assert(v->code == jit_code_arg_d);
759 jit_inc_synth_wp(putargr_d, u, v);
760 # if __WORDSIZE == 32
761 if (jit_arg_d_reg_p(v->u.w)) {
762 jit_stxi_d(-8, JIT_FP, u);
763 jit_ldxi(_I0 + v->u.w, JIT_FP, -8);
764 jit_ldxi(_I0 + v->u.w + 1, JIT_FP, -4);
766 else if (jit_arg_reg_p(v->u.w)) {
767 regno = jit_get_reg(jit_class_gpr);
768 jit_stxi_d(-8, JIT_FP, u);
769 jit_ldxi(_I0 + v->u.w, JIT_FP, -8);
770 jit_ldxi(regno, JIT_FP, -4);
771 jit_stxi(stack_framesize, JIT_FP, regno);
772 jit_unget_reg(regno);
774 else if ((v->u.w & 7) == 0)
775 jit_stxi_d(v->u.w, JIT_FP, u);
777 jit_stxi_d(-8, JIT_FP, u);
778 regno = jit_get_reg(jit_class_gpr);
779 jit_ldxi(regno, JIT_FP, -8);
780 jit_stxi(v->u.w, JIT_FP, regno);
781 jit_ldxi(regno, JIT_FP, -4);
782 jit_stxi(v->u.w + 4, JIT_FP, regno);
783 jit_unget_reg(regno);
786 if (jit_arg_d_reg_p(v->u.w))
787 jit_movr_d(_F0 - (v->u.w << 1), u);
789 jit_stxi_d(v->u.w, JIT_FP, u);
795 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
797 # if __WORDSIZE == 32
801 assert(v->code == jit_code_arg_d);
802 jit_inc_synth_dp(putargi_d, u, v);
803 # if __WORDSIZE == 32
804 regno = jit_get_reg(jit_class_fpr);
805 jit_movi_d(regno, u);
806 if (jit_arg_d_reg_p(v->u.w)) {
807 jit_stxi_d(-8, JIT_FP, regno);
808 jit_ldxi(_I0 + v->u.w, JIT_FP, -8);
809 jit_ldxi(_I0 + v->u.w + 1, JIT_FP, -4);
811 else if (jit_arg_reg_p(v->u.w)) {
812 gpr = jit_get_reg(jit_class_gpr);
813 jit_stxi_d(-8, JIT_FP, regno);
814 jit_ldxi(_I0 + v->u.w, JIT_FP, -8);
815 jit_ldxi(gpr, JIT_FP, -4);
816 jit_stxi(stack_framesize, JIT_FP, gpr);
819 else if ((v->u.w & 7) == 0)
820 jit_stxi_d(v->u.w, JIT_FP, regno);
822 jit_stxi_d(-8, JIT_FP, regno);
823 gpr = jit_get_reg(jit_class_gpr);
824 jit_ldxi(gpr, JIT_FP, -8);
825 jit_stxi(v->u.w, JIT_FP, gpr);
826 jit_ldxi(gpr, JIT_FP, -4);
827 jit_stxi(v->u.w + 4, JIT_FP, gpr);
830 jit_unget_reg(regno);
832 if (jit_arg_d_reg_p(v->u.w))
833 jit_movi_d(_F0 - (v->u.w << 1), u);
835 regno = jit_get_reg(jit_class_fpr | jit_class_dbl);
836 jit_movi_d(regno, u);
837 jit_stxi_d(v->u.w, JIT_FP, regno);
838 jit_unget_reg(regno);
845 _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
847 jit_code_inc_synth_w(code, u);
849 if (jit_arg_reg_p(_jitc->function->call.argi)) {
850 jit_movr(_O0 + _jitc->function->call.argi, u);
851 ++_jitc->function->call.argi;
854 # if __WORDSIZE == 64
855 if (jit_arg_d_reg_p(_jitc->function->call.argi))
856 ++_jitc->function->call.argi;
858 jit_stxi(BIAS(_jitc->function->call.size + stack_framesize),
860 _jitc->function->call.size += sizeof(jit_word_t);
866 _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
869 jit_code_inc_synth_w(code, u);
871 if (jit_arg_reg_p(_jitc->function->call.argi)) {
872 jit_movi(_O0 + _jitc->function->call.argi, u);
873 ++_jitc->function->call.argi;
876 # if __WORDSIZE == 64
877 if (jit_arg_d_reg_p(_jitc->function->call.argi))
878 ++_jitc->function->call.argi;
880 regno = jit_get_reg(jit_class_gpr);
882 jit_stxi(BIAS(_jitc->function->call.size + stack_framesize),
884 jit_unget_reg(regno);
885 _jitc->function->call.size += sizeof(jit_word_t);
891 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
893 jit_inc_synth_w(pushargr_f, u);
895 # if __WORDSIZE == 32
896 if (jit_arg_reg_p(_jitc->function->call.argi)) {
897 jit_stxi_f(-8, JIT_FP, u);
898 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
899 ++_jitc->function->call.argi;
902 jit_stxi_f(_jitc->function->call.size + stack_framesize,
904 _jitc->function->call.size += sizeof(jit_float32_t);
907 if ((_jitc->function->call.call & jit_call_varargs) &&
908 jit_arg_reg_p(_jitc->function->call.argi)) {
909 jit_stxi_f(BIAS(-8), JIT_FP, u);
910 jit_ldxi_i(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
911 ++_jitc->function->call.argi;
913 else if (!(_jitc->function->call.call & jit_call_varargs) &&
914 jit_arg_d_reg_p(_jitc->function->call.argi)) {
915 /* pair of registers is live */
916 jit_live(_F0 - (_jitc->function->call.argi << 1));
917 jit_movr_f((_F0 - (_jitc->function->call.argi << 1)) - 1, u);
918 if (!jit_arg_reg_p(_jitc->function->call.argi))
919 _jitc->function->call.size += sizeof(jit_float64_t);
920 ++_jitc->function->call.argi;
923 jit_stxi_f(BIAS(_jitc->function->call.size + stack_framesize + 4),
925 _jitc->function->call.size += sizeof(jit_float64_t);
932 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
935 jit_inc_synth_f(pushargi_f, u);
937 # if __WORDSIZE == 32
938 regno = jit_get_reg(jit_class_fpr);
939 jit_movi_f(regno, u);
940 if (jit_arg_reg_p(_jitc->function->call.argi)) {
941 jit_stxi_f(-8, JIT_FP, regno);
942 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
943 _jitc->function->call.argi++;
946 jit_stxi_f(_jitc->function->call.size + stack_framesize,
948 _jitc->function->call.size += sizeof(jit_float32_t);
950 jit_unget_reg(regno);
952 if ((_jitc->function->call.call & jit_call_varargs) &&
953 jit_arg_reg_p(_jitc->function->call.argi)) {
954 regno = jit_get_reg(jit_class_fpr | jit_class_sng);
955 jit_movi_f(regno, u);
956 jit_stxi_f(BIAS(-8), JIT_FP, regno);
957 jit_ldxi_i(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
958 ++_jitc->function->call.argi;
959 jit_unget_reg(regno);
961 else if (!(_jitc->function->call.call & jit_call_varargs) &&
962 jit_arg_d_reg_p(_jitc->function->call.argi)) {
963 /* pair of registers is live */
964 jit_live(_F0 - (_jitc->function->call.argi << 1));
965 jit_movi_f((_F0 - (_jitc->function->call.argi << 1)) - 1, u);
966 if (!jit_arg_reg_p(_jitc->function->call.argi))
967 _jitc->function->call.size += sizeof(jit_float64_t);
968 ++_jitc->function->call.argi;
971 regno = jit_get_reg(jit_class_fpr | jit_class_sng);
972 jit_movi_f(regno, u);
973 jit_stxi_f(BIAS(_jitc->function->call.size + stack_framesize + 4),
975 jit_unget_reg(regno);
976 _jitc->function->call.size += sizeof(jit_float64_t);
983 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
985 jit_inc_synth_w(pushargr_d, u);
987 # if __WORDSIZE == 32
988 if (jit_arg_d_reg_p(_jitc->function->call.argi)) {
989 jit_stxi_d(BIAS(-8), JIT_FP, u);
990 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
991 jit_ldxi(_O0 + _jitc->function->call.argi + 1, JIT_FP, -4);
992 _jitc->function->call.argi += 2;
994 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
995 jit_stxi_f(-8, JIT_FP, u);
996 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
997 ++_jitc->function->call.argi;
998 jit_stxi_f(stack_framesize, JIT_SP, u + 1);
999 _jitc->function->call.size += sizeof(jit_float32_t);
1002 jit_stxi_f(_jitc->function->call.size + stack_framesize,
1004 jit_stxi_f(_jitc->function->call.size + stack_framesize + 4,
1006 _jitc->function->call.size += sizeof(jit_float64_t);
1009 if ((_jitc->function->call.call & jit_call_varargs) &&
1010 jit_arg_reg_p(_jitc->function->call.argi)) {
1011 jit_stxi_d(BIAS(-8), JIT_FP, u);
1012 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
1013 ++_jitc->function->call.argi;
1015 else if (!(_jitc->function->call.call & jit_call_varargs) &&
1016 jit_arg_d_reg_p(_jitc->function->call.argi)) {
1017 jit_movr_d(_F0 - (_jitc->function->call.argi << 1), u);
1018 if (!jit_arg_reg_p(_jitc->function->call.argi))
1019 _jitc->function->call.size += sizeof(jit_float64_t);
1020 ++_jitc->function->call.argi;
1023 jit_stxi_d(BIAS(_jitc->function->call.size + stack_framesize),
1025 _jitc->function->call.size += sizeof(jit_float64_t);
1032 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
1035 jit_inc_synth_d(pushargi_d, u);
1037 # if __WORDSIZE == 32
1038 regno = jit_get_reg(jit_class_fpr);
1039 jit_movi_d(regno, u);
1040 if (jit_arg_d_reg_p(_jitc->function->call.argi)) {
1041 jit_stxi_d(BIAS(-8), JIT_FP, regno);
1042 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
1043 jit_ldxi(_O0 + _jitc->function->call.argi + 1, JIT_FP, -4);
1044 _jitc->function->call.argi += 2;
1046 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
1047 jit_stxi_f(-8, JIT_FP, regno);
1048 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
1049 ++_jitc->function->call.argi;
1050 jit_stxi_f(stack_framesize, JIT_SP, u + 1);
1051 _jitc->function->call.size += sizeof(jit_float32_t);
1054 jit_stxi_f(_jitc->function->call.size + stack_framesize,
1056 jit_stxi_f(_jitc->function->call.size + stack_framesize + 4,
1058 _jitc->function->call.size += sizeof(jit_float64_t);
1060 jit_unget_reg(regno);
1062 if ((_jitc->function->call.call & jit_call_varargs) &&
1063 jit_arg_reg_p(_jitc->function->call.argi)) {
1064 regno = jit_get_reg(jit_class_fpr | jit_class_dbl);
1065 jit_movi_d(regno, u);
1066 jit_stxi_d(BIAS(-8), JIT_FP, regno);
1067 jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8));
1068 ++_jitc->function->call.argi;
1069 jit_unget_reg(regno);
1071 else if (!(_jitc->function->call.call & jit_call_varargs) &&
1072 jit_arg_d_reg_p(_jitc->function->call.argi)) {
1073 jit_movi_d(_F0 - (_jitc->function->call.argi << 1), u);
1074 if (!jit_arg_reg_p(_jitc->function->call.argi))
1075 _jitc->function->call.size += sizeof(jit_float64_t);
1076 ++_jitc->function->call.argi;
1079 regno = jit_get_reg(jit_class_fpr | jit_class_dbl);
1080 jit_movi_d(regno, u);
1081 jit_stxi_d(BIAS(_jitc->function->call.size + stack_framesize),
1083 jit_unget_reg(regno);
1084 _jitc->function->call.size += sizeof(jit_float64_t);
1091 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
1095 spec = jit_class(_rvs[regno].spec);
1096 if ((spec & (jit_class_arg|jit_class_gpr)) ==
1097 (jit_class_arg|jit_class_gpr)) {
1099 if (regno >= 0 && regno < node->v.w)
1102 # if __WORDSIZE == 64
1103 if ((spec & (jit_class_arg|jit_class_fpr)) ==
1104 (jit_class_arg|jit_class_fpr)) {
1105 regno = _F0 - (regno >> 1);
1106 if (regno >= 0 && regno < node->v.w)
1115 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
1118 assert(_jitc->function);
1119 jit_inc_synth_w(finishr, r0);
1120 if (_jitc->function->self.alen < _jitc->function->call.size)
1121 _jitc->function->self.alen = _jitc->function->call.size;
1122 call = jit_callr(r0);
1123 call->v.w = _jitc->function->self.argi;
1124 call->w.w = _jitc->function->self.argf;
1125 _jitc->function->call.argi = _jitc->function->call.argf =
1126 _jitc->function->call.size = 0;
1132 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
1135 assert(_jitc->function);
1136 jit_inc_synth_w(finishi, (jit_word_t)i0);
1137 if (_jitc->function->self.alen < _jitc->function->call.size)
1138 _jitc->function->self.alen = _jitc->function->call.size;
1139 node = jit_calli(i0);
1140 node->v.w = _jitc->function->call.argi;
1141 node->w.w = _jitc->function->call.argf;
1142 _jitc->function->call.argi = _jitc->function->call.argf =
1143 _jitc->function->call.size = 0;
1150 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
1152 jit_inc_synth_w(retval_c, r0);
1153 jit_extr_c(r0, _O0);
1158 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
1160 jit_inc_synth_w(retval_uc, r0);
1161 jit_extr_uc(r0, _O0);
1166 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
1168 jit_inc_synth_w(retval_s, r0);
1169 jit_extr_s(r0, _O0);
1174 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
1176 jit_inc_synth_w(retval_us, r0);
1177 jit_extr_us(r0, _O0);
1182 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
1184 jit_inc_synth_w(retval_i, r0);
1185 # if __WORDSIZE == 32
1189 jit_extr_i(r0, _O0);
1194 # if __WORDSIZE == 64
1196 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
1198 jit_inc_synth_w(retval_i, r0);
1200 jit_extr_ui(r0, _O0);
1205 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
1207 jit_inc_synth_w(retval_i, r0);
1215 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
1217 jit_inc_synth_w(retval_f, r0);
1219 jit_movr_f(r0, JIT_FRET);
1224 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
1226 jit_inc_synth_w(retval_d, r0);
1228 jit_movr_d(r0, JIT_FRET);
1233 _emit_code(jit_state_t *_jit)
1243 jit_function_t func;
1244 #if DEVEL_DISASSEMBLER
1247 jit_int32_t patch_offset;
1249 #if DEVEL_DISASSEMBLER
1253 _jitc->function = NULL;
1255 jit_reglive_setup();
1259 undo.patch_offset = 0;
1261 #define case_rr(name, type) \
1262 case jit_code_##name##r##type: \
1263 name##r##type(rn(node->u.w), rn(node->v.w)); \
1265 #define case_rw(name, type) \
1266 case jit_code_##name##i##type: \
1267 name##i##type(rn(node->u.w), node->v.w); \
1269 #define case_wr(name, type) \
1270 case jit_code_##name##i##type: \
1271 name##i##type(node->u.w, rn(node->v.w)); \
1273 #define case_rf(name) \
1274 case jit_code_##name##i##type: \
1275 assert(node->flag & jit_flag_data); \
1276 name##_f(rn(node->u.w), \
1277 (jit_float32_t *)node->v.n->u.w); \
1279 #define case_rd(name) \
1280 case jit_code_##name##i_d: \
1281 assert(node->flag & jit_flag_data); \
1282 name##_d(rn(node->u.w), \
1283 (jit_float64_t *)node->v.n->u.w); \
1285 #define case_rrr(name, type) \
1286 case jit_code_##name##r##type: \
1287 name##r##type(rn(node->u.w), \
1288 rn(node->v.w), rn(node->w.w)); \
1290 #define case_rrrr(name, type) \
1291 case jit_code_##name##r##type: \
1292 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
1293 rn(node->v.w), rn(node->w.w)); \
1295 #define case_rqr(name, type) \
1296 case jit_code_##name##r##type: \
1297 name##r##type(rn(node->u.w), rn(node->v.q.l), \
1298 rn(node->v.q.h), rn(node->w.w)); \
1299 case jit_code_##name##i##type: \
1301 #define case_rrw(name, type) \
1302 case jit_code_##name##i##type: \
1303 name##i##type(rn(node->u.w), \
1304 rn(node->v.w), node->w.w); \
1306 #define case_rrrw(name, type) \
1307 case jit_code_##name##i##type: \
1308 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
1309 rn(node->v.w), node->w.w); \
1311 #define case_rrf(name, type, size) \
1312 case jit_code_##name##i##type: \
1313 assert(node->flag & jit_flag_data); \
1314 name##i##type(rn(node->u.w), rn(node->v.w), \
1315 (jit_float##size##_t *)node->w.n->u.w); \
1317 #define case_wrr(name, type) \
1318 case jit_code_##name##i##type: \
1319 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1321 #define case_brr(name, type) \
1322 case jit_code_##name##r##type: \
1324 assert(temp->code == jit_code_label || \
1325 temp->code == jit_code_epilog); \
1326 if (temp->flag & jit_flag_patch) \
1327 name##r##type(temp->u.w, rn(node->v.w), \
1330 word = name##r##type(_jit->pc.w, \
1331 rn(node->v.w), rn(node->w.w)); \
1332 patch(word, node); \
1335 #define case_brw(name, type) \
1336 case jit_code_##name##i##type: \
1338 assert(temp->code == jit_code_label || \
1339 temp->code == jit_code_epilog); \
1340 if (temp->flag & jit_flag_patch) \
1341 name##i##type(temp->u.w, \
1342 rn(node->v.w), node->w.w); \
1344 word = name##i##type(_jit->pc.w, \
1345 rn(node->v.w), node->w.w); \
1346 patch(word, node); \
1349 #define case_brf(name, type, size) \
1350 case jit_code_##name##i##type: \
1352 assert(temp->code == jit_code_label || \
1353 temp->code == jit_code_epilog); \
1354 if (temp->flag & jit_flag_patch) \
1355 name##i##type(temp->u.w, rn(node->v.w), \
1356 (jit_float##size##_t *)node->w.n->u.w); \
1358 word = name##i##type(_jit->pc.w, rn(node->v.w), \
1359 (jit_float##size##_t *)node->w.n->u.w); \
1360 patch(word, node); \
1363 #if DEVEL_DISASSEMBLER
1366 for (node = _jitc->head; node; node = node->next) {
1367 if (_jit->pc.uc >= _jitc->code.end)
1370 #if DEVEL_DISASSEMBLER
1371 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1374 value = jit_classify(node->code);
1375 jit_regarg_set(node, value);
1376 switch (node->code) {
1377 case jit_code_align:
1378 /* Must align to a power of two */
1379 assert(!(node->u.w & (node->u.w - 1)));
1380 if ((word = _jit->pc.w & (node->u.w - 1)))
1381 nop(node->u.w - word);
1384 nop((node->u.w + 3) & ~3);
1386 case jit_code_note: case jit_code_name:
1387 node->u.w = _jit->pc.w;
1389 case jit_code_label:
1390 if ((node->link || (node->flag & jit_flag_use)) &&
1391 (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
1392 nop(sizeof(jit_word_t) - word);
1393 /* remember label is defined */
1394 node->flag |= jit_flag_patch;
1395 node->u.w = _jit->pc.w;
1418 case_rrrr(qmul, _u);
1419 case_rrrw(qmul, _u);
1426 case_rrrr(qdiv, _u);
1427 case_rrrw(qdiv, _u);
1440 #define qlshr(r0, r1, r2, r3) fallback_qlshr(r0, r1, r2, r3)
1441 #define qlshi(r0, r1, r2, i0) fallback_qlshi(r0, r1, r2, i0)
1442 #define qlshr_u(r0, r1, r2, r3) fallback_qlshr_u(r0, r1, r2, r3)
1443 #define qlshi_u(r0, r1, r2, i0) fallback_qlshi_u(r0, r1, r2, i0)
1446 case_rrrr(qlsh, _u);
1447 case_rrrw(qlsh, _u);
1452 #define qrshr(r0, r1, r2, r3) fallback_qrshr(r0, r1, r2, r3)
1453 #define qrshi(r0, r1, r2, i0) fallback_qrshi(r0, r1, r2, i0)
1454 #define qrshr_u(r0, r1, r2, r3) fallback_qrshr_u(r0, r1, r2, r3)
1455 #define qrshi_u(r0, r1, r2, i0) fallback_qrshi_u(r0, r1, r2, i0)
1458 case_rrrr(qrsh, _u);
1459 case_rrrw(qrsh, _u);
1460 #define lrotr(r0,r1,r2) fallback_lrotr(r0,r1,r2)
1461 #define lroti(r0,r1,i0) fallback_lroti(r0,r1,i0)
1462 #define rrotr(r0,r1,r2) fallback_rrotr(r0,r1,r2)
1463 #define rroti(r0,r1,i0) fallback_rroti(r0,r1,i0)
1468 case_rr(trunc, _f_i);
1469 case_rr(trunc, _d_i);
1470 #if __WORDSIZE == 64
1471 case_rr(trunc, _f_l);
1472 case_rr(trunc, _d_l);
1504 #if __WORDSIZE == 64
1520 #if __WORDSIZE == 64
1526 #define unldr(r0, r1, i0) fallback_unldr(r0, r1, i0)
1527 case jit_code_unldr:
1528 unldr(rn(node->u.w), rn(node->v.w), node->w.w);
1530 #define unldi(r0, i0, i1) fallback_unldi(r0, i0, i1)
1531 case jit_code_unldi:
1532 unldi(rn(node->u.w), node->v.w, node->w.w);
1534 #define unldr_u(r0, r1, i0) fallback_unldr_u(r0, r1, i0)
1535 case jit_code_unldr_u:
1536 unldr_u(rn(node->u.w), rn(node->v.w), node->w.w);
1538 #define unldi_u(r0, i0, i1) fallback_unldi_u(r0, i0, i1)
1539 case jit_code_unldi_u:
1540 unldi_u(rn(node->u.w), node->v.w, node->w.w);
1548 #if __WORDSIZE == 64
1558 #if __WORDSIZE == 64
1562 #define unstr(r0, r1, i0) fallback_unstr(r0, r1, i0)
1563 case jit_code_unstr:
1564 unstr(rn(node->u.w), rn(node->v.w), node->w.w);
1566 #define unsti(i0, r0, i1) fallback_unsti(i0, r0, i1)
1567 case jit_code_unsti:
1568 unsti(node->u.w, rn(node->v.w), node->w.w);
1572 #if __WORDSIZE == 64
1575 case_rr(bswap, _us);
1576 case_rr(bswap, _ui);
1577 #if __WORDSIZE == 64
1578 case_rr(bswap, _ul);
1580 #define extr(r0, r1, i0, i1) fallback_ext(r0, r1, i0, i1)
1581 #define extr_u(r0, r1, i0, i1) fallback_ext_u(r0, r1, i0, i1)
1582 #define depr(r0, r1, i0, i1) fallback_dep(r0, r1, i0, i1)
1584 extr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1586 case jit_code_extr_u:
1587 extr_u(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1590 depr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1593 depi(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1599 #if __WORDSIZE == 64
1604 casr(rn(node->u.w), rn(node->v.w),
1605 rn(node->w.q.l), rn(node->w.q.h));
1608 casi(rn(node->u.w), node->v.w,
1609 rn(node->w.q.l), rn(node->w.q.h));
1615 if (node->flag & jit_flag_node) {
1617 if (temp->code == jit_code_data ||
1618 (temp->code == jit_code_label &&
1619 (temp->flag & jit_flag_patch)))
1620 movi(rn(node->u.w), temp->u.w);
1622 assert(temp->code == jit_code_label ||
1623 temp->code == jit_code_epilog);
1624 word = movi_p(rn(node->u.w), node->v.w);
1629 movi(rn(node->u.w), node->v.w);
1637 #define rbitr(r0, r1) fallback_rbit(r0, r1)
1638 #define popcntr(r0, r1) fallback_popcnt(r0, r1)
1663 case_brr(boadd, _u);
1664 case_brw(boadd, _u);
1667 case_brr(bxadd, _u);
1668 case_brw(bxadd, _u);
1671 case_brr(bosub, _u);
1672 case_brw(bosub, _u);
1675 case_brr(bxsub, _u);
1676 case_brw(bxsub, _u);
1682 case_rrf(add, _f, 32);
1684 case_rrf(sub, _f, 32);
1685 case_rrf(rsb, _f, 32);
1687 case_rrf(mul, _f, 32);
1689 case_rrf(div, _f, 32);
1700 case_rrf(lt, _f, 32);
1702 case_rrf(le, _f, 32);
1704 case_rrf(eq, _f, 32);
1706 case_rrf(ge, _f, 32);
1708 case_rrf(gt, _f, 32);
1710 case_rrf(ne, _f, 32);
1712 case_rrf(unlt, _f, 32);
1714 case_rrf(unle, _f, 32);
1716 case_rrf(uneq, _f, 32);
1718 case_rrf(unge, _f, 32);
1720 case_rrf(ungt, _f, 32);
1722 case_rrf(ltgt, _f, 32);
1724 case_rrf(ord, _f, 32);
1725 case_rrr(unord, _f);
1726 case_rrf(unord, _f, 32);
1731 #define unldr_x(r0, r1, i0) fallback_unldr_x(r0, r1, i0)
1732 case jit_code_unldr_x:
1733 unldr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1735 #define unldi_x(r0, i0, i1) fallback_unldi_x(r0, i0, i1)
1736 case jit_code_unldi_x:
1737 unldi_x(rn(node->u.w), node->v.w, node->w.w);
1743 #define unstr_x(r0, r1, i0) fallback_unstr_x(r0, r1, i0)
1744 case jit_code_unstr_x:
1745 unstr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1747 #define unsti_x(i0, r0, i1) fallback_unsti_x(i0, r0, i1)
1748 case jit_code_unsti_x:
1749 unsti_x(node->u.w, rn(node->v.w), node->w.w);
1752 case jit_code_movi_f:
1753 assert(node->flag & jit_flag_data);
1754 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1757 case_brf(blt, _f, 32);
1759 case_brf(ble, _f, 32);
1761 case_brf(beq, _f, 32);
1763 case_brf(bge, _f, 32);
1765 case_brf(bgt, _f, 32);
1767 case_brf(bne, _f, 32);
1768 case_brr(bunlt, _f);
1769 case_brf(bunlt, _f, 32);
1770 case_brr(bunle, _f);
1771 case_brf(bunle, _f, 32);
1772 case_brr(buneq, _f);
1773 case_brf(buneq, _f, 32);
1774 case_brr(bunge, _f);
1775 case_brf(bunge, _f, 32);
1776 case_brr(bungt, _f);
1777 case_brf(bungt, _f, 32);
1778 case_brr(bltgt, _f);
1779 case_brf(bltgt, _f, 32);
1781 case_brf(bord, _f, 32);
1782 case_brr(bunord, _f);
1783 case_brf(bunord, _f, 32);
1785 case_rrf(add, _d, 64);
1787 case_rrf(sub, _d, 64);
1788 case_rrf(rsb, _d, 64);
1790 case_rrf(mul, _d, 64);
1792 case_rrf(div, _d, 64);
1803 case_rrf(lt, _d, 64);
1805 case_rrf(le, _d, 64);
1807 case_rrf(eq, _d, 64);
1809 case_rrf(ge, _d, 64);
1811 case_rrf(gt, _d, 64);
1813 case_rrf(ne, _d, 64);
1815 case_rrf(unlt, _d, 64);
1817 case_rrf(unle, _d, 64);
1819 case_rrf(uneq, _d, 64);
1821 case_rrf(unge, _d, 64);
1823 case_rrf(ungt, _d, 64);
1825 case_rrf(ltgt, _d, 64);
1827 case_rrf(ord, _d, 64);
1828 case_rrr(unord, _d);
1829 case_rrf(unord, _d, 64);
1839 case jit_code_movi_d:
1840 assert(node->flag & jit_flag_data);
1841 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1844 case_brf(blt, _d, 64);
1846 case_brf(ble, _d, 64);
1848 case_brf(beq, _d, 64);
1850 case_brf(bge, _d, 64);
1852 case_brf(bgt, _d, 64);
1854 case_brf(bne, _d, 64);
1855 case_brr(bunlt, _d);
1856 case_brf(bunlt, _d, 64);
1857 case_brr(bunle, _d);
1858 case_brf(bunle, _d, 64);
1859 case_brr(buneq, _d);
1860 case_brf(buneq, _d, 64);
1861 case_brr(bunge, _d);
1862 case_brf(bunge, _d, 64);
1863 case_brr(bungt, _d);
1864 case_brf(bungt, _d, 64);
1865 case_brr(bltgt, _d);
1866 case_brf(bltgt, _d, 64);
1868 case_brf(bord, _d, 64);
1869 case_brr(bunord, _d);
1870 case_brf(bunord, _d, 64);
1872 jmpr(rn(node->u.w));
1875 if (node->flag & jit_flag_node) {
1877 assert(temp->code == jit_code_label ||
1878 temp->code == jit_code_epilog);
1879 if (temp->flag & jit_flag_patch)
1882 word = _jit->code.length -
1883 (_jit->pc.uc - _jit->code.ptr);
1884 if (s22_p(word >> 2))
1885 word = jmpi(_jit->pc.w);
1887 word = jmpi_p(_jit->pc.w);
1894 case jit_code_callr:
1895 callr(rn(node->u.w));
1897 case jit_code_calli:
1898 if (node->flag & jit_flag_node) {
1900 assert(temp->code == jit_code_label ||
1901 temp->code == jit_code_epilog);
1902 if (temp->flag & jit_flag_patch)
1905 word = _jit->code.length -
1906 (_jit->pc.uc - _jit->code.ptr);
1907 if (s30_p(word >> 2))
1908 word = calli(_jit->pc.w);
1910 word = calli_p(_jit->pc.w);
1917 case jit_code_prolog:
1918 _jitc->function = _jitc->functions.ptr + node->w.w;
1920 undo.word = _jit->pc.w;
1921 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
1922 #if DEVEL_DISASSEMBLER
1925 undo.patch_offset = _jitc->patches.offset;
1930 case jit_code_epilog:
1931 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1933 for (temp = undo.node->next;
1934 temp != node; temp = temp->next) {
1935 if (temp->code == jit_code_label ||
1936 temp->code == jit_code_epilog)
1937 temp->flag &= ~jit_flag_patch;
1939 temp->flag &= ~jit_flag_patch;
1941 _jit->pc.w = undo.word;
1942 /* undo.func.self.aoff and undo.func.regset should not
1943 * be undone, as they will be further updated, and are
1944 * the reason of the undo. */
1945 undo.func.self.aoff = _jitc->function->frame +
1946 _jitc->function->self.aoff;
1947 jit_regset_set(&undo.func.regset, &_jitc->function->regset);
1948 /* allocar information also does not need to be undone */
1949 undo.func.aoffoff = _jitc->function->aoffoff;
1950 undo.func.allocar = _jitc->function->allocar;
1951 /* cvt_offset must also not be undone */
1952 undo.func.cvt_offset = _jitc->function->cvt_offset;
1953 memcpy(_jitc->function, &undo.func, sizeof(undo.func));
1954 #if DEVEL_DISASSEMBLER
1957 _jitc->patches.offset = undo.patch_offset;
1958 goto restart_function;
1960 /* remember label is defined */
1961 node->flag |= jit_flag_patch;
1962 node->u.w = _jit->pc.w;
1964 _jitc->function = NULL;
1966 case jit_code_movr_w_f:
1967 movr_w_f(rn(node->u.w), rn(node->v.w));
1969 case jit_code_movr_f_w:
1970 movr_f_w(rn(node->u.w), rn(node->v.w));
1972 case jit_code_movi_f_w:
1973 assert(node->flag & jit_flag_data);
1974 movi_f_w(rn(node->u.w), *(jit_float32_t *)node->v.n->u.w);
1976 case jit_code_movi_w_f:
1977 movi_w_f(rn(node->u.w), node->v.w);
1979 #if __WORDSIZE == 32
1980 case jit_code_movr_ww_d:
1981 movr_ww_d(rn(node->u.w), rn(node->v.w), rn(node->w.w));
1983 case jit_code_movr_d_ww:
1984 movr_d_ww(rn(node->u.w), rn(node->v.w), rn(node->w.w));
1986 case jit_code_movi_d_ww:
1987 assert(node->flag & jit_flag_data);
1988 movi_d_ww(rn(node->u.w), rn(node->v.w),
1989 *(jit_float64_t *)node->w.n->u.w);
1991 case jit_code_movi_ww_d:
1992 movi_ww_d(rn(node->u.w), node->v.w, node->w.w);
1995 case jit_code_movr_w_d:
1996 movr_w_d(rn(node->u.w), rn(node->v.w));
1998 case jit_code_movr_d_w:
1999 movr_d_w(rn(node->u.w), rn(node->v.w));
2001 case jit_code_movi_d_w:
2002 assert(node->flag & jit_flag_data);
2003 movi_d_w(rn(node->u.w), *(jit_float64_t *)node->v.n->u.w);
2005 case jit_code_movi_w_d:
2006 movi_w_d(rn(node->u.w), node->v.w);
2009 case jit_code_va_start:
2010 vastart(rn(node->u.w));
2012 case jit_code_va_arg:
2013 vaarg(rn(node->u.w), rn(node->v.w));
2015 case jit_code_va_arg_d:
2016 vaarg_d(rn(node->u.w), rn(node->v.w));
2018 case jit_code_live: case jit_code_ellipsis:
2019 case jit_code_va_push:
2020 case jit_code_allocai: case jit_code_allocar:
2021 case jit_code_arg_c: case jit_code_arg_s:
2022 case jit_code_arg_i:
2023 #if __WORDSIZE == 64
2024 case jit_code_arg_l:
2026 case jit_code_arg_f: case jit_code_arg_d:
2027 case jit_code_va_end:
2029 case jit_code_retr_c: case jit_code_reti_c:
2030 case jit_code_retr_uc: case jit_code_reti_uc:
2031 case jit_code_retr_s: case jit_code_reti_s:
2032 case jit_code_retr_us: case jit_code_reti_us:
2033 case jit_code_retr_i: case jit_code_reti_i:
2034 #if __WORDSIZE == 64
2035 case jit_code_retr_ui: case jit_code_reti_ui:
2036 case jit_code_retr_l: case jit_code_reti_l:
2038 case jit_code_retr_f: case jit_code_reti_f:
2039 case jit_code_retr_d: case jit_code_reti_d:
2040 case jit_code_getarg_c: case jit_code_getarg_uc:
2041 case jit_code_getarg_s: case jit_code_getarg_us:
2042 case jit_code_getarg_i:
2043 #if __WORDSIZE == 64
2044 case jit_code_getarg_ui: case jit_code_getarg_l:
2046 case jit_code_getarg_f: case jit_code_getarg_d:
2047 case jit_code_putargr_c: case jit_code_putargi_c:
2048 case jit_code_putargr_uc: case jit_code_putargi_uc:
2049 case jit_code_putargr_s: case jit_code_putargi_s:
2050 case jit_code_putargr_us: case jit_code_putargi_us:
2051 case jit_code_putargr_i: case jit_code_putargi_i:
2052 #if __WORDSIZE == 64
2053 case jit_code_putargr_ui: case jit_code_putargi_ui:
2054 case jit_code_putargr_l: case jit_code_putargi_l:
2056 case jit_code_putargr_f: case jit_code_putargi_f:
2057 case jit_code_putargr_d: case jit_code_putargi_d:
2058 case jit_code_pushargr_c: case jit_code_pushargi_c:
2059 case jit_code_pushargr_uc: case jit_code_pushargi_uc:
2060 case jit_code_pushargr_s: case jit_code_pushargi_s:
2061 case jit_code_pushargr_us: case jit_code_pushargi_us:
2062 case jit_code_pushargr_i: case jit_code_pushargi_i:
2063 #if __WORDSIZE == 64
2064 case jit_code_pushargr_ui: case jit_code_pushargi_ui:
2065 case jit_code_pushargr_l: case jit_code_pushargi_l:
2067 case jit_code_pushargr_f: case jit_code_pushargi_f:
2068 case jit_code_pushargr_d: case jit_code_pushargi_d:
2069 case jit_code_retval_c: case jit_code_retval_uc:
2070 case jit_code_retval_s: case jit_code_retval_us:
2071 case jit_code_retval_i:
2072 #if __WORDSIZE == 64
2073 case jit_code_retval_ui: case jit_code_retval_l:
2075 case jit_code_retval_f: case jit_code_retval_d:
2076 case jit_code_prepare:
2077 case jit_code_finishr: case jit_code_finishi:
2078 case jit_code_negi_f: case jit_code_absi_f:
2079 case jit_code_sqrti_f: case jit_code_negi_d:
2080 case jit_code_absi_d: case jit_code_sqrti_d:
2083 negi(rn(node->u.w), node->v.w);
2086 comi(rn(node->u.w), node->v.w);
2088 case jit_code_exti_c:
2089 exti_c(rn(node->u.w), node->v.w);
2091 case jit_code_exti_uc:
2092 exti_uc(rn(node->u.w), node->v.w);
2094 case jit_code_exti_s:
2095 exti_s(rn(node->u.w), node->v.w);
2097 case jit_code_exti_us:
2098 exti_us(rn(node->u.w), node->v.w);
2100 case jit_code_bswapi_us:
2101 bswapi_us(rn(node->u.w), node->v.w);
2103 case jit_code_bswapi_ui:
2104 bswapi_ui(rn(node->u.w), node->v.w);
2106 case jit_code_htoni_us:
2107 htoni_us(rn(node->u.w), node->v.w);
2109 case jit_code_htoni_ui:
2110 htoni_ui(rn(node->u.w), node->v.w);
2112 #if __WORDSIZE == 64
2113 case jit_code_exti_i:
2114 exti_i(rn(node->u.w), node->v.w);
2116 case jit_code_exti_ui:
2117 exti_ui(rn(node->u.w), node->v.w);
2119 case jit_code_bswapi_ul:
2120 bswapi_ul(rn(node->u.w), node->v.w);
2122 case jit_code_htoni_ul:
2123 htoni_ul(rn(node->u.w), node->v.w);
2127 cloi(rn(node->u.w), node->v.w);
2130 clzi(rn(node->u.w), node->v.w);
2133 ctoi(rn(node->u.w), node->v.w);
2136 ctzi(rn(node->u.w), node->v.w);
2138 case jit_code_rbiti:
2139 rbiti(rn(node->u.w), node->v.w);
2141 case jit_code_popcnti:
2142 popcnti(rn(node->u.w), node->v.w);
2145 exti(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
2147 case jit_code_exti_u:
2148 exti_u(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
2153 # if __WORDSIZE == 64
2154 if (jit_carry != _NOREG) {
2155 switch (node->code) {
2157 case jit_code_addcr: case jit_code_addci:
2158 case jit_code_addxr: case jit_code_addxi:
2159 case jit_code_subcr: case jit_code_subci:
2160 case jit_code_subxr: case jit_code_subxi:
2163 jit_unget_reg(jit_carry);
2169 jit_regarg_clr(node, value);
2170 # if __WORDSIZE == 64
2171 if (jit_regset_cmp_ui(&_jitc->regarg, 0) != 0) {
2172 assert(jit_regset_scan1(&_jitc->regarg, 0) == jit_carry);
2173 assert(jit_regset_scan1(&_jitc->regarg, jit_carry + 1) == ULONG_MAX);
2175 assert(_jitc->synth == 0);
2177 assert(_jitc->regarg == 0 && _jitc->synth == 0);
2195 for (offset = 0; offset < _jitc->patches.offset; offset++) {
2196 node = _jitc->patches.ptr[offset].node;
2197 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
2198 patch_at(_jitc->patches.ptr[offset].inst, word);
2201 jit_flush(_jit->code.ptr, _jit->pc.uc);
2203 return (_jit->code.ptr);
2207 # include "jit_sparc-cpu.c"
2208 # include "jit_sparc-fpu.c"
2209 # include "jit_fallback.c"
2213 jit_flush(void *fptr, void *tptr)
2218 _emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0)
2220 ldxi(rn(r0), rn(r1), i0);
2224 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1)
2226 stxi(i0, rn(r0), rn(r1));
2230 _emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0)
2232 ldxi_d(rn(r0), rn(r1), i0);
2236 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1)
2238 stxi_d(i0, rn(r0), rn(r1));
2242 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
2246 assert(node->flag & jit_flag_node);
2247 if (node->code == jit_code_movi)
2248 flag = node->v.n->flag;
2250 flag = node->u.n->flag;
2251 assert(!(flag & jit_flag_patch));
2252 if (_jitc->patches.offset >= _jitc->patches.length) {
2253 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
2254 _jitc->patches.length * sizeof(jit_patch_t),
2255 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
2256 memset(_jitc->patches.ptr + _jitc->patches.length, 0,
2257 1024 * sizeof(jit_patch_t));
2258 _jitc->patches.length += 1024;
2260 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
2261 _jitc->patches.ptr[_jitc->patches.offset].node = node;
2262 ++_jitc->patches.offset;