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_rrw(name, type) \
1296 case jit_code_##name##i##type: \
1297 name##i##type(rn(node->u.w), \
1298 rn(node->v.w), node->w.w); \
1300 #define case_rrrw(name, type) \
1301 case jit_code_##name##i##type: \
1302 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
1303 rn(node->v.w), node->w.w); \
1305 #define case_rrf(name, type, size) \
1306 case jit_code_##name##i##type: \
1307 assert(node->flag & jit_flag_data); \
1308 name##i##type(rn(node->u.w), rn(node->v.w), \
1309 (jit_float##size##_t *)node->w.n->u.w); \
1311 #define case_wrr(name, type) \
1312 case jit_code_##name##i##type: \
1313 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1315 #define case_brr(name, type) \
1316 case jit_code_##name##r##type: \
1318 assert(temp->code == jit_code_label || \
1319 temp->code == jit_code_epilog); \
1320 if (temp->flag & jit_flag_patch) \
1321 name##r##type(temp->u.w, rn(node->v.w), \
1324 word = name##r##type(_jit->pc.w, \
1325 rn(node->v.w), rn(node->w.w)); \
1326 patch(word, node); \
1329 #define case_brw(name, type) \
1330 case jit_code_##name##i##type: \
1332 assert(temp->code == jit_code_label || \
1333 temp->code == jit_code_epilog); \
1334 if (temp->flag & jit_flag_patch) \
1335 name##i##type(temp->u.w, \
1336 rn(node->v.w), node->w.w); \
1338 word = name##i##type(_jit->pc.w, \
1339 rn(node->v.w), node->w.w); \
1340 patch(word, node); \
1343 #define case_brf(name, type, size) \
1344 case jit_code_##name##i##type: \
1346 assert(temp->code == jit_code_label || \
1347 temp->code == jit_code_epilog); \
1348 if (temp->flag & jit_flag_patch) \
1349 name##i##type(temp->u.w, rn(node->v.w), \
1350 (jit_float##size##_t *)node->w.n->u.w); \
1352 word = name##i##type(_jit->pc.w, rn(node->v.w), \
1353 (jit_float##size##_t *)node->w.n->u.w); \
1354 patch(word, node); \
1357 #if DEVEL_DISASSEMBLER
1360 for (node = _jitc->head; node; node = node->next) {
1361 if (_jit->pc.uc >= _jitc->code.end)
1364 #if DEVEL_DISASSEMBLER
1365 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1368 value = jit_classify(node->code);
1369 jit_regarg_set(node, value);
1370 switch (node->code) {
1371 case jit_code_align:
1372 /* Must align to a power of two */
1373 assert(!(node->u.w & (node->u.w - 1)));
1374 if ((word = _jit->pc.w & (node->u.w - 1)))
1375 nop(node->u.w - word);
1378 nop((node->u.w + 3) & ~3);
1380 case jit_code_note: case jit_code_name:
1381 node->u.w = _jit->pc.w;
1383 case jit_code_label:
1384 if ((node->link || (node->flag & jit_flag_use)) &&
1385 (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
1386 nop(sizeof(jit_word_t) - word);
1387 /* remember label is defined */
1388 node->flag |= jit_flag_patch;
1389 node->u.w = _jit->pc.w;
1408 case_rrrr(qmul, _u);
1409 case_rrrw(qmul, _u);
1416 case_rrrr(qdiv, _u);
1417 case_rrrw(qdiv, _u);
1434 case_rr(trunc, _f_i);
1435 case_rr(trunc, _d_i);
1436 #if __WORDSIZE == 64
1437 case_rr(trunc, _f_l);
1438 case_rr(trunc, _d_l);
1470 #if __WORDSIZE == 64
1486 #if __WORDSIZE == 64
1498 #if __WORDSIZE == 64
1508 #if __WORDSIZE == 64
1514 #if __WORDSIZE == 64
1517 case_rr(bswap, _us);
1518 case_rr(bswap, _ui);
1519 #if __WORDSIZE == 64
1520 case_rr(bswap, _ul);
1526 #if __WORDSIZE == 64
1531 casr(rn(node->u.w), rn(node->v.w),
1532 rn(node->w.q.l), rn(node->w.q.h));
1535 casi(rn(node->u.w), node->v.w,
1536 rn(node->w.q.l), rn(node->w.q.h));
1542 if (node->flag & jit_flag_node) {
1544 if (temp->code == jit_code_data ||
1545 (temp->code == jit_code_label &&
1546 (temp->flag & jit_flag_patch)))
1547 movi(rn(node->u.w), temp->u.w);
1549 assert(temp->code == jit_code_label ||
1550 temp->code == jit_code_epilog);
1551 word = movi_p(rn(node->u.w), node->v.w);
1556 movi(rn(node->u.w), node->v.w);
1586 case_brr(boadd, _u);
1587 case_brw(boadd, _u);
1590 case_brr(bxadd, _u);
1591 case_brw(bxadd, _u);
1594 case_brr(bosub, _u);
1595 case_brw(bosub, _u);
1598 case_brr(bxsub, _u);
1599 case_brw(bxsub, _u);
1605 case_rrf(add, _f, 32);
1607 case_rrf(sub, _f, 32);
1608 case_rrf(rsb, _f, 32);
1610 case_rrf(mul, _f, 32);
1612 case_rrf(div, _f, 32);
1619 case_rrf(lt, _f, 32);
1621 case_rrf(le, _f, 32);
1623 case_rrf(eq, _f, 32);
1625 case_rrf(ge, _f, 32);
1627 case_rrf(gt, _f, 32);
1629 case_rrf(ne, _f, 32);
1631 case_rrf(unlt, _f, 32);
1633 case_rrf(unle, _f, 32);
1635 case_rrf(uneq, _f, 32);
1637 case_rrf(unge, _f, 32);
1639 case_rrf(ungt, _f, 32);
1641 case_rrf(ltgt, _f, 32);
1643 case_rrf(ord, _f, 32);
1644 case_rrr(unord, _f);
1645 case_rrf(unord, _f, 32);
1655 case jit_code_movi_f:
1656 assert(node->flag & jit_flag_data);
1657 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1660 case_brf(blt, _f, 32);
1662 case_brf(ble, _f, 32);
1664 case_brf(beq, _f, 32);
1666 case_brf(bge, _f, 32);
1668 case_brf(bgt, _f, 32);
1670 case_brf(bne, _f, 32);
1671 case_brr(bunlt, _f);
1672 case_brf(bunlt, _f, 32);
1673 case_brr(bunle, _f);
1674 case_brf(bunle, _f, 32);
1675 case_brr(buneq, _f);
1676 case_brf(buneq, _f, 32);
1677 case_brr(bunge, _f);
1678 case_brf(bunge, _f, 32);
1679 case_brr(bungt, _f);
1680 case_brf(bungt, _f, 32);
1681 case_brr(bltgt, _f);
1682 case_brf(bltgt, _f, 32);
1684 case_brf(bord, _f, 32);
1685 case_brr(bunord, _f);
1686 case_brf(bunord, _f, 32);
1688 case_rrf(add, _d, 64);
1690 case_rrf(sub, _d, 64);
1691 case_rrf(rsb, _d, 64);
1693 case_rrf(mul, _d, 64);
1695 case_rrf(div, _d, 64);
1702 case_rrf(lt, _d, 64);
1704 case_rrf(le, _d, 64);
1706 case_rrf(eq, _d, 64);
1708 case_rrf(ge, _d, 64);
1710 case_rrf(gt, _d, 64);
1712 case_rrf(ne, _d, 64);
1714 case_rrf(unlt, _d, 64);
1716 case_rrf(unle, _d, 64);
1718 case_rrf(uneq, _d, 64);
1720 case_rrf(unge, _d, 64);
1722 case_rrf(ungt, _d, 64);
1724 case_rrf(ltgt, _d, 64);
1726 case_rrf(ord, _d, 64);
1727 case_rrr(unord, _d);
1728 case_rrf(unord, _d, 64);
1738 case jit_code_movi_d:
1739 assert(node->flag & jit_flag_data);
1740 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1743 case_brf(blt, _d, 64);
1745 case_brf(ble, _d, 64);
1747 case_brf(beq, _d, 64);
1749 case_brf(bge, _d, 64);
1751 case_brf(bgt, _d, 64);
1753 case_brf(bne, _d, 64);
1754 case_brr(bunlt, _d);
1755 case_brf(bunlt, _d, 64);
1756 case_brr(bunle, _d);
1757 case_brf(bunle, _d, 64);
1758 case_brr(buneq, _d);
1759 case_brf(buneq, _d, 64);
1760 case_brr(bunge, _d);
1761 case_brf(bunge, _d, 64);
1762 case_brr(bungt, _d);
1763 case_brf(bungt, _d, 64);
1764 case_brr(bltgt, _d);
1765 case_brf(bltgt, _d, 64);
1767 case_brf(bord, _d, 64);
1768 case_brr(bunord, _d);
1769 case_brf(bunord, _d, 64);
1771 jmpr(rn(node->u.w));
1774 if (node->flag & jit_flag_node) {
1776 assert(temp->code == jit_code_label ||
1777 temp->code == jit_code_epilog);
1778 if (temp->flag & jit_flag_patch)
1781 word = _jit->code.length -
1782 (_jit->pc.uc - _jit->code.ptr);
1783 if (s22_p(word >> 2))
1784 word = jmpi(_jit->pc.w);
1786 word = jmpi_p(_jit->pc.w);
1793 case jit_code_callr:
1794 callr(rn(node->u.w));
1796 case jit_code_calli:
1797 if (node->flag & jit_flag_node) {
1799 assert(temp->code == jit_code_label ||
1800 temp->code == jit_code_epilog);
1801 if (temp->flag & jit_flag_patch)
1804 word = _jit->code.length -
1805 (_jit->pc.uc - _jit->code.ptr);
1806 if (s30_p(word >> 2))
1807 word = calli(_jit->pc.w);
1809 word = calli_p(_jit->pc.w);
1816 case jit_code_prolog:
1817 _jitc->function = _jitc->functions.ptr + node->w.w;
1819 undo.word = _jit->pc.w;
1820 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
1821 #if DEVEL_DISASSEMBLER
1824 undo.patch_offset = _jitc->patches.offset;
1829 case jit_code_epilog:
1830 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1832 for (temp = undo.node->next;
1833 temp != node; temp = temp->next) {
1834 if (temp->code == jit_code_label ||
1835 temp->code == jit_code_epilog)
1836 temp->flag &= ~jit_flag_patch;
1838 temp->flag &= ~jit_flag_patch;
1840 _jit->pc.w = undo.word;
1841 /* undo.func.self.aoff and undo.func.regset should not
1842 * be undone, as they will be further updated, and are
1843 * the reason of the undo. */
1844 undo.func.self.aoff = _jitc->function->frame +
1845 _jitc->function->self.aoff;
1846 jit_regset_set(&undo.func.regset, &_jitc->function->regset);
1847 /* allocar information also does not need to be undone */
1848 undo.func.aoffoff = _jitc->function->aoffoff;
1849 undo.func.allocar = _jitc->function->allocar;
1850 memcpy(_jitc->function, &undo.func, sizeof(undo.func));
1851 #if DEVEL_DISASSEMBLER
1854 _jitc->patches.offset = undo.patch_offset;
1855 goto restart_function;
1857 /* remember label is defined */
1858 node->flag |= jit_flag_patch;
1859 node->u.w = _jit->pc.w;
1861 _jitc->function = NULL;
1863 case jit_code_va_start:
1864 vastart(rn(node->u.w));
1866 case jit_code_va_arg:
1867 vaarg(rn(node->u.w), rn(node->v.w));
1869 case jit_code_va_arg_d:
1870 vaarg_d(rn(node->u.w), rn(node->v.w));
1872 case jit_code_live: case jit_code_ellipsis:
1873 case jit_code_va_push:
1874 case jit_code_allocai: case jit_code_allocar:
1875 case jit_code_arg_c: case jit_code_arg_s:
1876 case jit_code_arg_i:
1877 #if __WORDSIZE == 64
1878 case jit_code_arg_l:
1880 case jit_code_arg_f: case jit_code_arg_d:
1881 case jit_code_va_end:
1883 case jit_code_retr_c: case jit_code_reti_c:
1884 case jit_code_retr_uc: case jit_code_reti_uc:
1885 case jit_code_retr_s: case jit_code_reti_s:
1886 case jit_code_retr_us: case jit_code_reti_us:
1887 case jit_code_retr_i: case jit_code_reti_i:
1888 #if __WORDSIZE == 64
1889 case jit_code_retr_ui: case jit_code_reti_ui:
1890 case jit_code_retr_l: case jit_code_reti_l:
1892 case jit_code_retr_f: case jit_code_reti_f:
1893 case jit_code_retr_d: case jit_code_reti_d:
1894 case jit_code_getarg_c: case jit_code_getarg_uc:
1895 case jit_code_getarg_s: case jit_code_getarg_us:
1896 case jit_code_getarg_i:
1897 #if __WORDSIZE == 64
1898 case jit_code_getarg_ui: case jit_code_getarg_l:
1900 case jit_code_getarg_f: case jit_code_getarg_d:
1901 case jit_code_putargr_c: case jit_code_putargi_c:
1902 case jit_code_putargr_uc: case jit_code_putargi_uc:
1903 case jit_code_putargr_s: case jit_code_putargi_s:
1904 case jit_code_putargr_us: case jit_code_putargi_us:
1905 case jit_code_putargr_i: case jit_code_putargi_i:
1906 #if __WORDSIZE == 64
1907 case jit_code_putargr_ui: case jit_code_putargi_ui:
1908 case jit_code_putargr_l: case jit_code_putargi_l:
1910 case jit_code_putargr_f: case jit_code_putargi_f:
1911 case jit_code_putargr_d: case jit_code_putargi_d:
1912 case jit_code_pushargr_c: case jit_code_pushargi_c:
1913 case jit_code_pushargr_uc: case jit_code_pushargi_uc:
1914 case jit_code_pushargr_s: case jit_code_pushargi_s:
1915 case jit_code_pushargr_us: case jit_code_pushargi_us:
1916 case jit_code_pushargr_i: case jit_code_pushargi_i:
1917 #if __WORDSIZE == 64
1918 case jit_code_pushargr_ui: case jit_code_pushargi_ui:
1919 case jit_code_pushargr_l: case jit_code_pushargi_l:
1921 case jit_code_pushargr_f: case jit_code_pushargi_f:
1922 case jit_code_pushargr_d: case jit_code_pushargi_d:
1923 case jit_code_retval_c: case jit_code_retval_uc:
1924 case jit_code_retval_s: case jit_code_retval_us:
1925 case jit_code_retval_i:
1926 #if __WORDSIZE == 64
1927 case jit_code_retval_ui: case jit_code_retval_l:
1929 case jit_code_retval_f: case jit_code_retval_d:
1930 case jit_code_prepare:
1931 case jit_code_finishr: case jit_code_finishi:
1936 # if __WORDSIZE == 64
1937 if (jit_carry != _NOREG) {
1938 switch (node->code) {
1940 case jit_code_addcr: case jit_code_addci:
1941 case jit_code_addxr: case jit_code_addxi:
1942 case jit_code_subcr: case jit_code_subci:
1943 case jit_code_subxr: case jit_code_subxi:
1946 jit_unget_reg(jit_carry);
1952 jit_regarg_clr(node, value);
1953 # if __WORDSIZE == 64
1954 if (jit_regset_cmp_ui(&_jitc->regarg, 0) != 0) {
1955 assert(jit_regset_scan1(&_jitc->regarg, 0) == jit_carry);
1956 assert(jit_regset_scan1(&_jitc->regarg, jit_carry + 1) == ULONG_MAX);
1958 assert(_jitc->synth == 0);
1960 assert(_jitc->regarg == 0 && _jitc->synth == 0);
1978 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1979 node = _jitc->patches.ptr[offset].node;
1980 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1981 patch_at(_jitc->patches.ptr[offset].inst, word);
1984 jit_flush(_jit->code.ptr, _jit->pc.uc);
1986 return (_jit->code.ptr);
1990 # include "jit_sparc-cpu.c"
1991 # include "jit_sparc-fpu.c"
1992 # include "jit_fallback.c"
1996 jit_flush(void *fptr, void *tptr)
2001 _emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0)
2003 ldxi(rn(r0), rn(r1), i0);
2007 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1)
2009 stxi(i0, rn(r0), rn(r1));
2013 _emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0)
2015 ldxi_d(rn(r0), rn(r1), i0);
2019 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1)
2021 stxi_d(i0, rn(r0), rn(r1));
2025 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
2029 assert(node->flag & jit_flag_node);
2030 if (node->code == jit_code_movi)
2031 flag = node->v.n->flag;
2033 flag = node->u.n->flag;
2034 assert(!(flag & jit_flag_patch));
2035 if (_jitc->patches.offset >= _jitc->patches.length) {
2036 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
2037 _jitc->patches.length * sizeof(jit_patch_t),
2038 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
2039 memset(_jitc->patches.ptr + _jitc->patches.length, 0,
2040 1024 * sizeof(jit_patch_t));
2041 _jitc->patches.length += 1024;
2043 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
2044 _jitc->patches.ptr[_jitc->patches.offset].node = node;
2045 ++_jitc->patches.offset;