2 * Copyright (C) 2012-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 #define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8)
22 # define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 13)
24 # define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8)
26 # define va_gp_shift 2
28 # define va_gp_shift 3
30 # define va_gp_increment sizeof(jit_word_t)
31 # define first_gp_argument r3
32 # define first_gp_offset offsetof(jit_va_list_t, \
34 # define va_fp_increment sizeof(jit_float64_t)
35 # define first_fp_argument f1
36 # define first_fp_offset offsetof(jit_va_list_t, \
39 #if __BYTE_ORDER == __LITTLE_ENDIAN
45 # define C_DISP (__WORDSIZE >> 3) - sizeof(jit_int8_t)
46 # define S_DISP (__WORDSIZE >> 3) - sizeof(jit_int16_t)
47 # define I_DISP (__WORDSIZE >> 3) - sizeof(jit_int32_t)
48 # define F_DISP (__WORDSIZE >> 3) - sizeof(jit_float32_t)
50 #define CVT_OFFSET _jitc->function->cvt_offset
51 #define CHECK_CVT_OFFSET() \
53 if (!_jitc->function->cvt_offset) { \
55 _jitc->function->cvt_offset = \
56 jit_allocai(sizeof(jit_float64_t)); \
64 typedef struct jit_va_list {
94 typedef jit_pointer_t jit_va_list_t;
100 #define patch(instr, node) _patch(_jit, instr, node)
101 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
104 extern void __clear_cache(void *, void *);
107 # include "jit_ppc-cpu.c"
108 # include "jit_ppc-fpu.c"
109 # include "jit_fallback.c"
115 jit_register_t _rvs[] = {
116 { rc(sav) | 0, "r0" },
117 { rc(sav) | 11, "r11" }, /* env */
118 { rc(sav) | 12, "r12" }, /* exception */
119 { rc(sav) | 13, "r13" }, /* thread */
120 { rc(sav) | 2, "r2" }, /* toc */
121 { rc(sav) | rc(gpr) | 14, "r14" },
122 { rc(sav) | rc(gpr) | 15, "r15" },
123 { rc(sav) | rc(gpr) | 16, "r16" },
124 { rc(sav) | rc(gpr) | 17, "r17" },
125 { rc(sav) | rc(gpr) | 18, "r18" },
126 { rc(sav) | rc(gpr) | 19, "r19" },
127 { rc(sav) | rc(gpr) | 20, "r20" },
128 { rc(sav) | rc(gpr) | 21, "r21" },
129 { rc(sav) | rc(gpr) | 22, "r22" },
130 { rc(sav) | rc(gpr) | 23, "r23" },
131 { rc(sav) | rc(gpr) | 24, "r24" },
132 { rc(sav) | rc(gpr) | 25, "r25" },
133 { rc(sav) | rc(gpr) | 26, "r26" },
134 { rc(sav) | rc(gpr) | 27, "r27" },
135 { rc(sav) | rc(gpr) | 28, "r28" },
136 { rc(sav) | rc(gpr) | 29, "r29" },
137 { rc(sav) | rc(gpr) | 30, "r30" },
138 { rc(sav) | 1, "r1" },
139 { rc(sav) | 31, "r31" },
140 { rc(arg) | rc(gpr) | 10, "r10" },
141 { rc(arg) | rc(gpr) | 9, "r9" },
142 { rc(arg) | rc(gpr) | 8, "r8" },
143 { rc(arg) | rc(gpr) | 7, "r7" },
144 { rc(arg) | rc(gpr) | 6, "r6" },
145 { rc(arg) | rc(gpr) | 5, "r5" },
146 { rc(arg) | rc(gpr) | 4, "r4" },
147 { rc(arg) | rc(gpr) | 3, "r3" },
148 { rc(fpr) | 0, "f0" },
149 { rc(sav) | rc(fpr) | 14, "f14" },
150 { rc(sav) | rc(fpr) | 15, "f15" },
151 { rc(sav) | rc(fpr) | 16, "f16" },
152 { rc(sav) | rc(fpr) | 17, "f17" },
153 { rc(sav) | rc(fpr) | 18, "f18" },
154 { rc(sav) | rc(fpr) | 19, "f19" },
155 { rc(sav) | rc(fpr) | 20, "f20" },
156 { rc(sav) | rc(fpr) | 21, "f21" },
157 { rc(sav) | rc(fpr) | 22, "f22" },
158 { rc(sav) | rc(fpr) | 23, "f23" },
159 { rc(sav) | rc(fpr) | 24, "f24" },
160 { rc(sav) | rc(fpr) | 25, "f25" },
161 { rc(sav) | rc(fpr) | 26, "f26" },
162 { rc(sav) | rc(fpr) | 27, "f27" },
163 { rc(sav) | rc(fpr) | 28, "f28" },
164 { rc(sav) | rc(fpr) | 29, "f29" },
165 { rc(sav) | rc(fpr) | 30, "f30" },
166 { rc(sav) | rc(fpr) | 31, "f31" },
168 { rc(arg) | rc(fpr) | 13, "f13" },
169 { rc(arg) | rc(fpr) | 12, "f12" },
170 { rc(arg) | rc(fpr) | 11, "f11" },
171 { rc(arg) | rc(fpr) | 10, "f10" },
172 { rc(arg) | rc(fpr) | 9, "f9" },
174 { rc(fpr) | 13, "f13" },
175 { rc(fpr) | 12, "f12" },
176 { rc(fpr) | 11, "f11" },
177 { rc(fpr) | 10, "f10" },
178 { rc(fpr) | 9, "f9" },
180 { rc(arg) | rc(fpr) | 8, "f8" },
181 { rc(arg) | rc(fpr) | 7, "f7" },
182 { rc(arg) | rc(fpr) | 6, "f6" },
183 { rc(arg) | rc(fpr) | 5, "f5" },
184 { rc(arg) | rc(fpr) | 4, "f4" },
185 { rc(arg) | rc(fpr) | 3, "f3" },
186 { rc(arg) | rc(fpr) | 2, "f2" },
187 { rc(arg) | rc(fpr) | 1, "f1" },
188 { _NOREG, "<none>" },
191 static jit_int32_t iregs[] = {
192 _R14, _R15, _R16, _R17, _R18, _R19, _R20, _R21, _R22,
193 _R23, _R24, _R25, _R26, _R27, _R28, _R29, _R30
196 static jit_int32_t fregs[] = {
197 _F14, _F15, _F16, _F17, _F18, _F19, _F20, _F21,
209 _jit_init(jit_state_t *_jit)
211 _jitc->reglen = jit_size(_rvs) - 1;
215 _jit_prolog(jit_state_t *_jit)
221 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
222 jit_regset_set_ui(&_jitc->regsav, 0);
223 offset = _jitc->functions.offset;
224 if (offset >= _jitc->functions.length) {
225 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
226 _jitc->functions.length * sizeof(jit_function_t),
227 (_jitc->functions.length + 16) * sizeof(jit_function_t));
228 _jitc->functions.length += 16;
230 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
231 _jitc->function->self.size = params_offset;
232 _jitc->function->self.argi = _jitc->function->self.argf =
233 _jitc->function->self.alen = 0;
234 /* float conversion */
235 _jitc->function->cvt_offset = 0;
236 _jitc->function->self.aoff = alloca_offset - 8;
237 _jitc->function->self.call = jit_call_default;
238 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
239 _jitc->reglen * sizeof(jit_int32_t));
241 /* _no_link here does not mean the jit_link() call can be removed
243 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
245 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
246 jit_link(_jitc->function->prolog);
247 _jitc->function->prolog->w.w = offset;
248 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
250 * v: offset in blocks vector
251 * w: offset in functions vector
253 _jitc->function->epilog->w.w = offset;
255 jit_regset_new(&_jitc->function->regset);
259 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
261 assert(_jitc->function);
264 case 0: case 1: break;
265 case 2: _jitc->function->self.aoff &= -2; break;
266 case 3: case 4: _jitc->function->self.aoff &= -4; break;
267 default: _jitc->function->self.aoff &= -8; break;
269 _jitc->function->self.aoff -= length;
270 if (!_jitc->realize) {
271 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
274 return (_jitc->function->self.aoff);
278 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
281 assert(_jitc->function);
282 jit_inc_synth_ww(allocar, u, v);
283 if (!_jitc->function->allocar) {
284 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
285 _jitc->function->allocar = 1;
287 r0 = jit_get_reg(jit_class_gpr);
288 r1 = jit_get_reg(jit_class_gpr);
291 jit_andi(r1, r1, -16);
292 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
294 jit_addr(JIT_SP, JIT_SP, r1);
295 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
303 _jit_ret(jit_state_t *_jit)
306 assert(_jitc->function);
310 jit_patch_at(instr, _jitc->function->epilog);
315 _jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
317 jit_code_inc_synth_w(code, u);
318 jit_movr(JIT_RET, u);
324 _jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
326 jit_code_inc_synth_w(code, u);
327 jit_movi(JIT_RET, u);
333 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
335 jit_inc_synth_w(retr_f, u);
337 jit_movr_f(JIT_FRET, u);
345 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
347 jit_inc_synth_f(reti_f, u);
348 jit_movi_f(JIT_FRET, u);
354 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
356 jit_inc_synth_w(retr_d, u);
358 jit_movr_d(JIT_FRET, u);
366 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
368 jit_inc_synth_d(reti_d, u);
369 jit_movi_d(JIT_FRET, u);
375 _jit_epilog(jit_state_t *_jit)
377 assert(_jitc->function);
378 assert(_jitc->function->epilog->next == NULL);
379 jit_link(_jitc->function->epilog);
380 _jitc->function = NULL;
384 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
386 if (u->code >= jit_code_arg_c && u->code <= jit_code_arg)
387 return (jit_arg_reg_p(u->u.w));
388 assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
389 return (jit_arg_f_reg_p(u->u.w));
393 _jit_ellipsis(jit_state_t *_jit)
395 jit_inc_synth(ellipsis);
396 if (_jitc->prepare) {
398 assert(!(_jitc->function->call.call & jit_call_varargs));
399 _jitc->function->call.call |= jit_call_varargs;
403 assert(!(_jitc->function->self.call & jit_call_varargs));
404 _jitc->function->self.call |= jit_call_varargs;
406 /* Allocate va_list like object in the stack.
407 * If applicable, with enough space to save all argument
408 * registers, and use fixed offsets for them. */
409 _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
411 _jitc->function->vagp = _jitc->function->self.argi;
412 _jitc->function->vafp = _jitc->function->self.argf;
418 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
420 jit_inc_synth_w(va_push, u);
426 _jit_arg(jit_state_t *_jit, jit_code_t code)
431 assert(_jitc->function);
432 assert(!(_jitc->function->self.call & jit_call_varargs));
433 #if STRONG_TYPE_CHECKING
434 assert(code >= jit_code_arg_c && code <= jit_code_arg);
436 if (jit_arg_reg_p(_jitc->function->self.argi)) {
437 offset = _jitc->function->self.argi++;
443 offset = _jitc->function->self.size;
445 _jitc->function->self.size += sizeof(jit_word_t);
446 node = jit_new_node_ww(code, offset,
447 ++_jitc->function->self.argn);
453 _jit_arg_f(jit_state_t *_jit)
458 assert(_jitc->function);
459 if (jit_arg_f_reg_p(_jitc->function->self.argf)) {
460 offset = _jitc->function->self.argf++;
466 offset = _jitc->function->self.size + F_DISP;
468 if (jit_arg_reg_p(_jitc->function->self.argi)) {
469 # if __WORDSIZE == 32
470 _jitc->function->self.argi += 2;
472 _jitc->function->self.argi++;
477 _jitc->function->self.size += sizeof(jit_word_t);
478 node = jit_new_node_ww(jit_code_arg_f, offset,
479 ++_jitc->function->self.argn);
485 _jit_arg_d(jit_state_t *_jit)
490 assert(_jitc->function);
491 if (jit_arg_f_reg_p(_jitc->function->self.argf)) {
492 offset = _jitc->function->self.argf++;
499 if (_jitc->function->self.size & 7)
500 _jitc->function->self.size += 4;
502 offset = _jitc->function->self.size;
505 if (jit_arg_reg_p(_jitc->function->self.argi)) {
506 # if __WORDSIZE == 32
507 _jitc->function->self.argi += 2;
509 _jitc->function->self.argi++;
514 _jitc->function->self.size += sizeof(jit_float64_t);
515 node = jit_new_node_ww(jit_code_arg_d, offset,
516 ++_jitc->function->self.argn);
522 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
524 assert_arg_type(v->code, jit_code_arg_c);
525 jit_inc_synth_wp(getarg_c, u, v);
526 if (jit_arg_reg_p(v->u.w))
527 jit_extr_c(u, JIT_RA0 - v->u.w);
530 jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP);
536 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
538 assert_arg_type(v->code, jit_code_arg_c);
539 jit_inc_synth_wp(getarg_uc, u, v);
540 if (jit_arg_reg_p(v->u.w))
541 jit_extr_uc(u, JIT_RA0 - v->u.w);
544 jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP);
550 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
552 assert_arg_type(v->code, jit_code_arg_s);
553 jit_inc_synth_wp(getarg_s, u, v);
554 if (jit_arg_reg_p(v->u.w))
555 jit_extr_s(u, JIT_RA0 - v->u.w);
558 jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP);
564 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
566 assert_arg_type(v->code, jit_code_arg_s);
567 jit_inc_synth_wp(getarg_us, u, v);
568 if (jit_arg_reg_p(v->u.w))
569 jit_extr_us(u, JIT_RA0 - v->u.w);
572 jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP);
578 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
580 assert_arg_type(v->code, jit_code_arg_i);
581 jit_inc_synth_wp(getarg_i, u, v);
582 if (jit_arg_reg_p(v->u.w)) {
584 jit_movr(u, JIT_RA0 - v->u.w);
586 jit_extr_i(u, JIT_RA0 - v->u.w);
591 jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP);
598 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
600 assert_arg_type(v->code, jit_code_arg_i);
601 jit_inc_synth_wp(getarg_ui, u, v);
602 if (jit_arg_reg_p(v->u.w))
603 jit_extr_ui(u, JIT_RA0 - v->u.w);
606 jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP);
612 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
614 assert_arg_type(v->code, jit_code_arg_l);
615 jit_inc_synth_wp(getarg_l, u, v);
616 if (jit_arg_reg_p(v->u.w))
617 jit_movr(u, JIT_RA0 - v->u.w);
620 jit_ldxi_l(u, JIT_FP, v->u.w);
627 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
629 assert_putarg_type(code, v->code);
630 jit_code_inc_synth_wp(code, u, v);
631 if (jit_arg_reg_p(v->u.w))
632 jit_movr(JIT_RA0 - v->u.w, u);
635 jit_stxi(v->u.w, JIT_FP, u);
641 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
644 assert_putarg_type(code, v->code);
645 jit_code_inc_synth_wp(code, u, v);
646 if (jit_arg_reg_p(v->u.w))
647 jit_movi(JIT_RA0 - v->u.w, u);
650 regno = jit_get_reg(jit_class_gpr);
652 jit_stxi(v->u.w, JIT_FP, regno);
653 jit_unget_reg(regno);
659 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
661 assert(v->code == jit_code_arg_f);
662 jit_inc_synth_wp(getarg_f, u, v);
663 if (jit_arg_f_reg_p(v->u.w))
664 jit_movr_d(u, JIT_FA0 - v->u.w);
667 jit_ldxi_f(u, JIT_FP, v->u.w);
673 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
675 assert(v->code == jit_code_arg_f);
676 jit_inc_synth_wp(putargr_f, u, v);
677 if (jit_arg_f_reg_p(v->u.w))
678 jit_movr_d(JIT_FA0 - v->u.w, u);
681 jit_stxi_f(v->u.w, JIT_FP, u);
687 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
690 assert(v->code == jit_code_arg_f);
691 jit_inc_synth_fp(putargi_f, u, v);
692 if (jit_arg_f_reg_p(v->u.w))
693 jit_movi_d(JIT_FA0 - v->u.w, u);
696 regno = jit_get_reg(jit_class_fpr);
697 jit_movi_d(regno, u);
698 jit_stxi_f(v->u.w, JIT_FP, regno);
699 jit_unget_reg(regno);
705 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
707 assert(v->code == jit_code_arg_d);
708 jit_inc_synth_wp(getarg_d, u, v);
709 if (jit_arg_f_reg_p(v->u.w))
710 jit_movr_d(u, JIT_FA0 - v->u.w);
713 jit_ldxi_d(u, JIT_FP, v->u.w);
719 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
721 assert(v->code == jit_code_arg_d);
722 jit_inc_synth_wp(putargr_d, u, v);
723 if (jit_arg_f_reg_p(v->u.w))
724 jit_movr_d(JIT_FA0 - v->u.w, u);
727 jit_stxi_d(v->u.w, JIT_FP, u);
733 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
736 assert(v->code == jit_code_arg_d);
737 jit_inc_synth_dp(putargi_d, u, v);
738 if (jit_arg_f_reg_p(v->u.w))
739 jit_movi_d(JIT_FA0 - v->u.w, u);
742 regno = jit_get_reg(jit_class_fpr);
743 jit_movi_d(regno, u);
744 jit_stxi_d(v->u.w, JIT_FP, regno);
745 jit_unget_reg(regno);
751 _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
754 assert(_jitc->function);
755 jit_code_inc_synth_w(code, u);
757 if (jit_arg_reg_p(_jitc->function->call.argi)) {
758 jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
759 ++_jitc->function->call.argi;
765 jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
767 _jitc->function->call.size += sizeof(jit_word_t);
772 _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
776 assert(_jitc->function);
777 jit_code_inc_synth_w(code, u);
779 if (jit_arg_reg_p(_jitc->function->call.argi)) {
780 jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
781 ++_jitc->function->call.argi;
787 regno = jit_get_reg(jit_class_gpr);
789 jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno);
790 jit_unget_reg(regno);
793 _jitc->function->call.size += sizeof(jit_word_t);
798 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
801 assert(_jitc->function);
802 jit_inc_synth_w(pushargr_f, u);
804 if (jit_arg_f_reg_p(_jitc->function->call.argf)
806 && !(_jitc->function->call.call & jit_call_varargs)
809 jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
810 ++_jitc->function->call.argf;
812 /* in case of excess arguments */
813 if (jit_arg_reg_p(_jitc->function->call.argi)) {
814 # if __WORDSIZE == 32
815 _jitc->function->call.argi += 2;
816 if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
817 --_jitc->function->call.argi;
819 _jitc->function->call.argi++;
827 else if (jit_arg_reg_p(_jitc->function->call.argi
828 # if __WORDSIZE == 32
834 jit_stxi_d(CVT_OFFSET, JIT_FP, u);
835 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, CVT_OFFSET);
836 _jitc->function->call.argi++;
837 # if __WORDSIZE == 32
838 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
840 _jitc->function->call.argi++;
845 jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP,
848 _jitc->function->call.size += sizeof(jit_word_t);
853 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
857 assert(_jitc->function);
858 jit_inc_synth_f(pushargi_f, u);
860 if (jit_arg_f_reg_p(_jitc->function->call.argf)
862 && !(_jitc->function->call.call & jit_call_varargs)
865 jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
866 ++_jitc->function->call.argf;
868 /* in case of excess arguments */
869 # if __WORDSIZE == 32
870 _jitc->function->call.argi += 2;
871 if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
872 --_jitc->function->call.argi;
874 _jitc->function->call.argi++;
881 regno = jit_get_reg(jit_class_fpr);
882 jit_movi_f(regno, u);
884 if (jit_arg_reg_p(_jitc->function->call.argi
885 # if __WORDSIZE == 32
891 jit_stxi_d(CVT_OFFSET, JIT_FP, regno);
892 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
894 _jitc->function->call.argi++;
895 # if __WORDSIZE == 32
896 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
898 _jitc->function->call.argi++;
903 jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP,
905 jit_unget_reg(regno);
908 _jitc->function->call.size += sizeof(jit_word_t);
913 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
916 assert(_jitc->function);
917 jit_inc_synth_w(pushargr_d, u);
919 if (jit_arg_f_reg_p(_jitc->function->call.argf)
921 && !(_jitc->function->call.call & jit_call_varargs)
924 jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
925 ++_jitc->function->call.argf;
927 /* in case of excess arguments */
928 # if __WORDSIZE == 32
929 _jitc->function->call.argi += 2;
930 if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
931 --_jitc->function->call.argi;
933 _jitc->function->call.argi++;
935 #else /* _CALL_SYSV */
940 else if (jit_arg_reg_p(_jitc->function->call.argi
941 # if __WORDSIZE == 32
947 jit_stxi_d(CVT_OFFSET, JIT_FP, u);
948 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, CVT_OFFSET);
949 _jitc->function->call.argi++;
950 # if __WORDSIZE == 32
951 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, CVT_OFFSET + 4);
952 _jitc->function->call.argi++;
956 #endif /* !_CALL_SYSV */
959 if (_jitc->function->call.size & 7)
960 _jitc->function->call.size += 4;
962 jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
963 #if !_CALL_SYSV && __WORDSIZE == 32
964 if (jit_arg_reg_p(_jitc->function->call.argi)) {
965 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_SP,
966 _jitc->function->call.size + params_offset);
967 _jitc->function->call.argi++;
972 _jitc->function->call.size += sizeof(jit_float64_t);
977 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
981 assert(_jitc->function);
982 jit_inc_synth_d(pushargi_d, u);
984 if (jit_arg_f_reg_p(_jitc->function->call.argf)
986 && !(_jitc->function->call.call & jit_call_varargs)
989 jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
990 ++_jitc->function->call.argf;
992 /* in case of excess arguments */
993 if (jit_arg_reg_p(_jitc->function->call.argi)) {
994 # if __WORDSIZE == 32
995 _jitc->function->call.argi += 2;
996 if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
997 --_jitc->function->call.argi;
999 _jitc->function->call.argi++;
1002 #else /* _CALL_SYSV */
1007 regno = jit_get_reg(jit_class_fpr);
1008 jit_movi_d(regno, u);
1010 if (jit_arg_reg_p(_jitc->function->call.argi
1011 # if __WORDSIZE == 32
1017 jit_stxi_d(CVT_OFFSET, JIT_FP, regno);
1018 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
1020 _jitc->function->call.argi++;
1021 # if __WORDSIZE == 32
1022 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
1024 _jitc->function->call.argi++;
1028 #endif /* !_CALL_SYSV */
1031 if (_jitc->function->call.size & 7)
1032 _jitc->function->call.size += 4;
1034 jit_stxi_d(_jitc->function->call.size + params_offset,
1036 #if !_CALL_SYSV && __WORDSIZE == 32
1037 if (jit_arg_reg_p(_jitc->function->call.argi)) {
1038 jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_SP,
1039 _jitc->function->call.size + params_offset);
1040 _jitc->function->call.argi++;
1044 jit_unget_reg(regno);
1047 _jitc->function->call.size += sizeof(jit_float64_t);
1052 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
1055 spec = jit_class(_rvs[regno].spec);
1056 if (spec & jit_class_arg) {
1057 if (spec & jit_class_gpr) {
1058 regno = JIT_RA0 - regno;
1059 if (regno >= 0 && regno < node->v.w)
1062 else if (spec & jit_class_fpr) {
1063 regno = JIT_FA0 - regno;
1064 if (regno >= 0 && regno < node->w.w)
1072 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
1075 assert(_jitc->function);
1076 jit_inc_synth_w(finishr, r0);
1077 if (_jitc->function->self.alen < _jitc->function->call.size)
1078 _jitc->function->self.alen = _jitc->function->call.size;
1079 call = jit_callr(r0);
1080 call->v.w = _jitc->function->call.argi;
1081 call->w.w = _jitc->function->call.argf;
1083 /* If passing float arguments in registers */
1084 if ((_jitc->function->call.call & jit_call_varargs) && call->w.w)
1085 call->flag |= jit_flag_varargs;
1087 _jitc->function->call.argi = _jitc->function->call.argf = 0;
1093 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
1096 assert(_jitc->function);
1097 jit_inc_synth_w(finishi, (jit_word_t)i0);
1098 if (_jitc->function->self.alen < _jitc->function->call.size)
1099 _jitc->function->self.alen = _jitc->function->call.size;
1100 node = jit_calli(i0);
1101 node->v.w = _jitc->function->call.argi;
1102 node->w.w = _jitc->function->call.argf;
1104 if ((_jitc->function->call.call & jit_call_varargs) && node->w.w)
1105 node->flag |= jit_flag_varargs;
1107 _jitc->function->call.argi = _jitc->function->call.argf = 0;
1114 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
1116 jit_inc_synth(retval_c);
1117 jit_extr_c(r0, JIT_RET);
1122 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
1124 jit_inc_synth(retval_uc);
1125 jit_extr_uc(r0, JIT_RET);
1130 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
1132 jit_inc_synth(retval_s);
1133 jit_extr_s(r0, JIT_RET);
1138 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
1140 jit_inc_synth(retval_us);
1141 jit_extr_us(r0, JIT_RET);
1146 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
1148 jit_inc_synth(retval_i);
1149 #if __WORDSIZE == 32
1151 jit_movr(r0, JIT_RET);
1153 jit_extr_i(r0, JIT_RET);
1158 #if __WORDSIZE == 64
1160 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
1162 jit_inc_synth(retval_ui);
1163 jit_extr_ui(r0, JIT_RET);
1168 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
1170 jit_inc_synth(retval_l);
1172 jit_movr(r0, JIT_RET);
1178 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
1180 jit_inc_synth(retval_f);
1186 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
1188 jit_inc_synth(retval_d);
1190 jit_movr_d(r0, JIT_FRET);
1195 _emit_code(jit_state_t *_jit)
1202 jit_bool_t no_flag = 0; /* Set if previous instruction is
1203 * *not* a jump target. */
1207 jit_function_t func;
1208 #if DEVEL_DISASSEMBLER
1211 jit_word_t patch_offset;
1213 jit_word_t prolog_offset;
1216 #if DEVEL_DISASSEMBLER
1220 _jitc->function = NULL;
1222 jit_reglive_setup();
1226 undo.patch_offset = 0;
1228 #if DEVEL_DISASSEMBLER
1232 undo.prolog_offset = 0;
1233 for (node = _jitc->head; node; node = node->next)
1234 if (node->code != jit_code_label &&
1235 node->code != jit_code_note &&
1236 node->code != jit_code_name)
1238 if (node && (node->code != jit_code_prolog ||
1239 !(_jitc->functions.ptr + node->w.w)->assume_frame)) {
1240 /* code may start with a jump so add an initial function descriptor */
1241 word = _jit->pc.w + sizeof(void*) * 3;
1242 iw(word); /* addr */
1248 #define case_rr(name, type) \
1249 case jit_code_##name##r##type: \
1250 name##r##type(rn(node->u.w), rn(node->v.w)); \
1252 #define case_rw(name, type) \
1253 case jit_code_##name##i##type: \
1254 name##i##type(rn(node->u.w), node->v.w); \
1256 #define case_wr(name, type) \
1257 case jit_code_##name##i##type: \
1258 name##i##type(node->u.w, rn(node->v.w)); \
1260 #define case_rrr(name, type) \
1261 case jit_code_##name##r##type: \
1262 name##r##type(rn(node->u.w), \
1263 rn(node->v.w), rn(node->w.w)); \
1265 #define case_rrrr(name, type) \
1266 case jit_code_##name##r##type: \
1267 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
1268 rn(node->v.w), rn(node->w.w)); \
1270 #define case_rqr(name, type) \
1271 case jit_code_##name##r##type: \
1272 name##r##type(rn(node->u.w), rn(node->v.q.l), \
1273 rn(node->v.q.h), rn(node->w.w)); \
1274 case jit_code_##name##i##type: \
1276 #define case_rrw(name, type) \
1277 case jit_code_##name##i##type: \
1278 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
1280 #define case_rrrw(name, type) \
1281 case jit_code_##name##i##type: \
1282 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
1283 rn(node->v.w), node->w.w); \
1285 #define case_rrf(name, type, size) \
1286 case jit_code_##name##i##type: \
1287 assert(node->flag & jit_flag_data); \
1288 name##i##type(rn(node->u.w), rn(node->v.w), \
1289 (jit_float##size##_t *)node->w.n->u.w); \
1291 #define case_wrr(name, type) \
1292 case jit_code_##name##i##type: \
1293 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1295 #define case_brr(name, type) \
1296 case jit_code_##name##r##type: \
1298 assert(temp->code == jit_code_label || \
1299 temp->code == jit_code_epilog); \
1300 if (temp->flag & jit_flag_patch) \
1301 name##r##type(temp->u.w, rn(node->v.w), \
1304 word = name##r##type(_jit->pc.w, \
1305 rn(node->v.w), rn(node->w.w)); \
1306 patch(word, node); \
1309 #define case_brw(name, type) \
1310 case jit_code_##name##i##type: \
1312 assert(temp->code == jit_code_label || \
1313 temp->code == jit_code_epilog); \
1314 if (temp->flag & jit_flag_patch) \
1315 name##i##type(temp->u.w, \
1316 rn(node->v.w), node->w.w); \
1318 word = name##i##type(_jit->pc.w, \
1319 rn(node->v.w), node->w.w); \
1320 patch(word, node); \
1323 #define case_brf(name, type, size) \
1324 case jit_code_##name##i##type: \
1326 assert(temp->code == jit_code_label || \
1327 temp->code == jit_code_epilog); \
1328 if (temp->flag & jit_flag_patch) \
1329 name##i##type(temp->u.w, rn(node->v.w), \
1330 (jit_float##size##_t *)node->w.n->u.w); \
1332 word = name##i##type(_jit->pc.w, rn(node->v.w), \
1333 (jit_float##size##_t *)node->w.n->u.w); \
1334 patch(word, node); \
1337 for (node = _jitc->head; node; node = node->next) {
1338 if (_jit->pc.uc >= _jitc->code.end)
1341 #if DEVEL_DISASSEMBLER
1342 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1345 value = jit_classify(node->code);
1346 jit_regarg_set(node, value);
1347 switch (node->code) {
1348 case jit_code_align:
1349 /* Must align to a power of two */
1350 assert(!(node->u.w & (node->u.w - 1)));
1351 if ((word = _jit->pc.w & (node->u.w - 1)))
1352 nop(node->u.w - word);
1355 nop((node->u.w + 3) & ~3);
1357 case jit_code_note: case jit_code_name:
1358 node->u.w = _jit->pc.w;
1360 case jit_code_label:
1361 /* remember label is defined */
1362 node->flag |= jit_flag_patch;
1363 node->u.w = _jit->pc.w;
1386 case_rrrr(qmul, _u);
1387 case_rrrw(qmul, _u);
1394 case_rrrr(qdiv, _u);
1395 case_rrrw(qdiv, _u);
1410 case_rrrr(qlsh, _u);
1411 case_rrrw(qlsh, _u);
1418 case_rrrr(qrsh, _u);
1419 case_rrrw(qrsh, _u);
1425 extr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1427 case jit_code_extr_u:
1428 extr_u(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1431 depr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1434 depi(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1440 # if __WORDSIZE == 64
1446 # if __WORDSIZE == 64
1449 case jit_code_bswapr_us:
1450 bswapr_us_lh(rn(node->u.w), rn(node->v.w), no_flag);
1452 case jit_code_bswapr_ui:
1453 bswapr_ui_lw(rn(node->u.w), rn(node->v.w), no_flag);
1455 # if __WORDSIZE == 64
1456 case_rr(bswap, _ul);
1464 #define rbitr(r0, r1) fallback_rbit(r0, r1)
1468 casr(rn(node->u.w), rn(node->v.w),
1469 rn(node->w.q.l), rn(node->w.q.h));
1472 casi(rn(node->u.w), node->v.w,
1473 rn(node->w.q.l), rn(node->w.q.h));
1479 if (node->flag & jit_flag_node) {
1481 if (temp->code == jit_code_data ||
1482 (temp->code == jit_code_label &&
1483 (temp->flag & jit_flag_patch)))
1484 movi(rn(node->u.w), temp->u.w);
1486 assert(temp->code == jit_code_label ||
1487 temp->code == jit_code_epilog);
1488 word = movi_p(rn(node->u.w), node->v.w);
1493 movi(rn(node->u.w), node->v.w);
1495 case_rr(trunc, _f_i);
1496 case_rr(trunc, _d_i);
1497 # if __WORDSIZE == 64
1498 case_rr(trunc, _f_l);
1499 case_rr(trunc, _d_l);
1549 case_brr(boadd, _u);
1550 case_brw(boadd, _u);
1553 case_brr(bxadd, _u);
1554 case_brw(bxadd, _u);
1557 case_brr(bosub, _u);
1558 case_brw(bosub, _u);
1561 case_brr(bxsub, _u);
1562 case_brw(bxsub, _u);
1581 #if __WORDSIZE == 64
1591 #define unldr(r0, r1, i0) fallback_unldr(r0, r1, i0)
1592 case jit_code_unldr:
1593 unldr(rn(node->u.w), rn(node->v.w), node->w.w);
1595 #define unldi(r0, i0, i1) fallback_unldi(r0, i0, i1)
1596 case jit_code_unldi:
1597 unldi(rn(node->u.w), node->v.w, node->w.w);
1599 #define unldr_u(r0, r1, i0) fallback_unldr_u(r0, r1, i0)
1600 case jit_code_unldr_u:
1601 unldr_u(rn(node->u.w), rn(node->v.w), node->w.w);
1603 #define unldi_u(r0, i0, i1) fallback_unldi_u(r0, i0, i1)
1604 case jit_code_unldi_u:
1605 unldi_u(rn(node->u.w), node->v.w, node->w.w);
1619 #if __WORDSIZE == 64
1625 #define unstr(r0, r1, i0) fallback_unstr(r0, r1, i0)
1626 case jit_code_unstr:
1627 unstr(rn(node->u.w), rn(node->v.w), node->w.w);
1629 #define unsti(i0, r0, i1) fallback_unsti(i0, r0, i1)
1630 case jit_code_unsti:
1631 unsti(node->u.w, rn(node->v.w), node->w.w);
1634 case jit_code_movi_f:
1635 assert(node->flag & jit_flag_data);
1636 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1648 case_rrf(add, _f, 32);
1650 case_rrf(sub, _f, 32);
1651 case_rrf(rsb, _f, 32);
1653 case_rrf(mul, _f, 32);
1655 case_rrf(div, _f, 32);
1657 case_rrf(lt, _f, 32);
1659 case_rrf(le, _f, 32);
1661 case_rrf(eq, _f, 32);
1663 case_rrf(ge, _f, 32);
1665 case_rrf(gt, _f, 32);
1667 case_rrf(ne, _f, 32);
1669 case_rrf(unlt, _f, 32);
1671 case_rrf(unle, _f, 32);
1673 case_rrf(uneq, _f, 32);
1675 case_rrf(unge, _f, 32);
1677 case_rrf(ungt, _f, 32);
1679 case_rrf(ltgt, _f, 32);
1681 case_rrf(ord, _f, 32);
1682 case_rrr(unord, _f);
1683 case_rrf(unord, _f, 32);
1685 case_brf(blt, _f, 32);
1687 case_brf(ble, _f, 32);
1689 case_brf(beq, _f, 32);
1691 case_brf(bge, _f, 32);
1693 case_brf(bgt, _f, 32);
1695 case_brf(bne, _f, 32);
1696 case_brr(bunlt, _f);
1697 case_brf(bunlt, _f, 32);
1698 case_brr(bunle, _f);
1699 case_brf(bunle, _f, 32);
1700 case_brr(buneq, _f);
1701 case_brf(buneq, _f, 32);
1702 case_brr(bunge, _f);
1703 case_brf(bunge, _f, 32);
1704 case_brr(bungt, _f);
1705 case_brf(bungt, _f, 32);
1706 case_brr(bltgt, _f);
1707 case_brf(bltgt, _f, 32);
1709 case_brf(bord, _f, 32);
1710 case_brr(bunord, _f);
1711 case_brf(bunord, _f, 32);
1716 #define unldr_x(r0, r1, i0) fallback_unldr_x(r0, r1, i0)
1717 case jit_code_unldr_x:
1718 unldr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1720 #define unldi_x(r0, i0, i1) fallback_unldi_x(r0, i0, i1)
1721 case jit_code_unldi_x:
1722 unldi_x(rn(node->u.w), node->v.w, node->w.w);
1728 #define unstr_x(r0, r1, i0) fallback_unstr_x(r0, r1, i0)
1729 case jit_code_unstr_x:
1730 unstr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1732 #define unsti_x(i0, r0, i1) fallback_unsti_x(i0, r0, i1)
1733 case jit_code_unsti_x:
1734 unsti_x(node->u.w, rn(node->v.w), node->w.w);
1737 case jit_code_movi_d:
1738 assert(node->flag & jit_flag_data);
1739 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1751 case_rrf(add, _d, 64);
1753 case_rrf(sub, _d, 64);
1754 case_rrf(rsb, _d, 64);
1756 case_rrf(mul, _d, 64);
1758 case_rrf(div, _d, 64);
1760 case_rrf(lt, _d, 64);
1762 case_rrf(le, _d, 64);
1764 case_rrf(eq, _d, 64);
1766 case_rrf(ge, _d, 64);
1768 case_rrf(gt, _d, 64);
1770 case_rrf(ne, _d, 64);
1772 case_rrf(unlt, _d, 64);
1774 case_rrf(unle, _d, 64);
1776 case_rrf(uneq, _d, 64);
1778 case_rrf(unge, _d, 64);
1780 case_rrf(ungt, _d, 64);
1782 case_rrf(ltgt, _d, 64);
1784 case_rrf(ord, _d, 64);
1785 case_rrr(unord, _d);
1786 case_rrf(unord, _d, 64);
1788 case_brf(blt, _d, 64);
1790 case_brf(ble, _d, 64);
1792 case_brf(beq, _d, 64);
1794 case_brf(bge, _d, 64);
1796 case_brf(bgt, _d, 64);
1798 case_brf(bne, _d, 64);
1799 case_brr(bunlt, _d);
1800 case_brf(bunlt, _d, 64);
1801 case_brr(bunle, _d);
1802 case_brf(bunle, _d, 64);
1803 case_brr(buneq, _d);
1804 case_brf(buneq, _d, 64);
1805 case_brr(bunge, _d);
1806 case_brf(bunge, _d, 64);
1807 case_brr(bungt, _d);
1808 case_brf(bungt, _d, 64);
1809 case_brr(bltgt, _d);
1810 case_brf(bltgt, _d, 64);
1812 case_brf(bord, _d, 64);
1813 case_brr(bunord, _d);
1814 case_brf(bunord, _d, 64);
1825 jmpr(rn(node->u.w));
1828 if (node->flag & jit_flag_node) {
1830 if (_jit->pc.uc == _jit->code.ptr + sizeof(void*) * 3)
1834 assert(temp->code == jit_code_label ||
1835 temp->code == jit_code_epilog);
1836 if (temp->flag & jit_flag_patch)
1839 word = _jit->code.length -
1840 (_jit->pc.uc - _jit->code.ptr);
1841 if (can_sign_extend_jump_p(word))
1842 word = jmpi(_jit->pc.w);
1844 word = jmpi_p(_jit->pc.w);
1853 case jit_code_callr:
1855 # define xcallr(u, v) callr(u, v)
1856 # define xcalli_p(u, v) calli_p(u, v)
1857 # define xcalli(u, v) calli(u, v)
1859 # define xcallr(u, v) callr(u)
1860 # define xcalli_p(u, v) calli_p(u)
1861 # define xcalli(u, v) calli(u)
1864 xcallr(rn(node->u.w), !!(node->flag & jit_flag_varargs));
1866 case jit_code_calli:
1867 value = !!(node->flag & jit_flag_varargs);
1868 if (node->flag & jit_flag_node) {
1869 _jitc->function->need_return = 1;
1871 assert(temp->code == jit_code_label ||
1872 temp->code == jit_code_epilog);
1873 if (temp->flag & jit_flag_patch)
1874 xcalli(temp->u.w, value);
1876 word = _jit->code.length -
1877 (_jit->pc.uc - _jit->code.ptr);
1879 if (can_sign_extend_jump_p(word + value * 4))
1880 word = xcalli(_jit->pc.w, value);
1883 word = xcalli_p(_jit->pc.w, value);
1889 xcalli(node->u.w, value);
1892 case jit_code_prolog:
1893 _jitc->function = _jitc->functions.ptr + node->w.w;
1895 undo.word = _jit->pc.w;
1896 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
1897 #if DEVEL_DISASSEMBLER
1900 undo.patch_offset = _jitc->patches.offset;
1902 undo.prolog_offset = _jitc->prolog.offset;
1907 if (_jitc->jump && !_jitc->function->assume_frame) {
1908 /* remember prolog to hide offset adjustment for a jump
1909 * to the start of a function, what is expected to be
1910 * a common practice as first jit instruction */
1911 if (_jitc->prolog.offset >= _jitc->prolog.length) {
1912 _jitc->prolog.length += 16;
1913 jit_realloc((jit_pointer_t *)&_jitc->prolog.ptr,
1914 (_jitc->prolog.length - 16) *
1916 _jitc->prolog.length * sizeof(jit_word_t));
1918 _jitc->prolog.ptr[_jitc->prolog.offset++] = _jit->pc.w;
1919 /* function descriptor */
1920 word = _jit->pc.w + sizeof(void*) * 3;
1921 iw(word); /* addr */
1928 case jit_code_epilog:
1929 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1931 for (temp = undo.node->next;
1932 temp != node; temp = temp->next) {
1933 if (temp->code == jit_code_label ||
1934 temp->code == jit_code_epilog)
1935 temp->flag &= ~jit_flag_patch;
1937 temp->flag &= ~jit_flag_patch;
1939 _jit->pc.w = undo.word;
1940 /* undo.func.self.aoff and undo.func.regset should not
1941 * be undone, as they will be further updated, and are
1942 * the reason of the undo. */
1943 undo.func.self.aoff = _jitc->function->frame +
1944 _jitc->function->self.aoff;
1945 undo.func.need_frame = _jitc->function->need_frame;
1946 undo.func.need_stack = _jitc->function->need_stack;
1947 undo.func.need_return = _jitc->function->need_return;
1948 jit_regset_set(&undo.func.regset, &_jitc->function->regset);
1949 /* allocar information also does not need to be undone */
1950 undo.func.aoffoff = _jitc->function->aoffoff;
1951 undo.func.allocar = _jitc->function->allocar;
1952 /* cvt_offset must also not be undone */
1953 undo.func.cvt_offset = _jitc->function->cvt_offset;
1954 memcpy(_jitc->function, &undo.func, sizeof(undo.func));
1955 #if DEVEL_DISASSEMBLER
1958 _jitc->patches.offset = undo.patch_offset;
1960 _jitc->prolog.offset = undo.prolog_offset;
1962 goto restart_function;
1964 /* remember label is defined */
1965 node->flag |= jit_flag_patch;
1966 node->u.w = _jit->pc.w;
1968 _jitc->function = NULL;
1970 case jit_code_movr_w_f:
1971 movr_w_f(rn(node->u.w), rn(node->v.w));
1973 case jit_code_movr_f_w:
1974 movr_f_w(rn(node->u.w), rn(node->v.w));
1976 case jit_code_movi_f_w:
1977 assert(node->flag & jit_flag_data);
1978 movi_f_w(rn(node->u.w), *(jit_float32_t *)node->v.n->u.w);
1980 case jit_code_movi_w_f:
1981 movi_w_f(rn(node->u.w), node->v.w);
1983 #if __WORDSIZE == 64
1984 case jit_code_movr_d_w:
1985 movr_d_w(rn(node->u.w), rn(node->v.w));
1987 case jit_code_movi_d_w:
1988 assert(node->flag & jit_flag_data);
1989 movi_d_w(rn(node->u.w), *(jit_float64_t *)node->v.n->u.w);
1991 case jit_code_movr_w_d:
1992 movr_w_d(rn(node->u.w), rn(node->v.w));
1994 case jit_code_movi_w_d:
1995 movi_w_d(rn(node->u.w), node->v.w);
1998 case jit_code_movr_ww_d:
1999 movr_ww_d(rn(node->u.w), rn(node->v.w), rn(node->w.w));
2001 case jit_code_movr_d_ww:
2002 movr_d_ww(rn(node->u.w), rn(node->v.w), rn(node->w.w));
2004 case jit_code_movi_d_ww:
2005 assert(node->flag & jit_flag_data);
2006 movi_d_ww(rn(node->u.w), rn(node->v.w),
2007 *(jit_float64_t *)node->w.n->u.w);
2009 case jit_code_movi_ww_d:
2010 movi_ww_d(rn(node->u.w), node->v.w, node->w.w);
2013 case jit_code_va_start:
2014 vastart(rn(node->u.w));
2016 case jit_code_va_arg:
2017 vaarg(rn(node->u.w), rn(node->v.w));
2019 case jit_code_va_arg_d:
2020 vaarg_d(rn(node->u.w), rn(node->v.w));
2022 case jit_code_live: case jit_code_ellipsis:
2023 case jit_code_va_push:
2024 case jit_code_allocai: case jit_code_allocar:
2025 case jit_code_arg_c: case jit_code_arg_s:
2026 case jit_code_arg_i:
2027 # if __WORDSIZE == 64
2028 case jit_code_arg_l:
2030 case jit_code_arg_f: case jit_code_arg_d:
2031 case jit_code_va_end:
2033 case jit_code_retr_c: case jit_code_reti_c:
2034 case jit_code_retr_uc: case jit_code_reti_uc:
2035 case jit_code_retr_s: case jit_code_reti_s:
2036 case jit_code_retr_us: case jit_code_reti_us:
2037 case jit_code_retr_i: case jit_code_reti_i:
2038 #if __WORDSIZE == 64
2039 case jit_code_retr_ui: case jit_code_reti_ui:
2040 case jit_code_retr_l: case jit_code_reti_l:
2042 case jit_code_retr_f: case jit_code_reti_f:
2043 case jit_code_retr_d: case jit_code_reti_d:
2044 case jit_code_getarg_c: case jit_code_getarg_uc:
2045 case jit_code_getarg_s: case jit_code_getarg_us:
2046 case jit_code_getarg_i:
2047 #if __WORDSIZE == 64
2048 case jit_code_getarg_ui: case jit_code_getarg_l:
2050 case jit_code_getarg_f: case jit_code_getarg_d:
2051 case jit_code_putargr_c: case jit_code_putargi_c:
2052 case jit_code_putargr_uc: case jit_code_putargi_uc:
2053 case jit_code_putargr_s: case jit_code_putargi_s:
2054 case jit_code_putargr_us: case jit_code_putargi_us:
2055 case jit_code_putargr_i: case jit_code_putargi_i:
2056 #if __WORDSIZE == 64
2057 case jit_code_putargr_ui: case jit_code_putargi_ui:
2058 case jit_code_putargr_l: case jit_code_putargi_l:
2060 case jit_code_putargr_f: case jit_code_putargi_f:
2061 case jit_code_putargr_d: case jit_code_putargi_d:
2062 case jit_code_pushargr_c: case jit_code_pushargi_c:
2063 case jit_code_pushargr_uc: case jit_code_pushargi_uc:
2064 case jit_code_pushargr_s: case jit_code_pushargi_s:
2065 case jit_code_pushargr_us: case jit_code_pushargi_us:
2066 case jit_code_pushargr_i: case jit_code_pushargi_i:
2067 #if __WORDSIZE == 64
2068 case jit_code_pushargr_ui: case jit_code_pushargi_ui:
2069 case jit_code_pushargr_l: case jit_code_pushargi_l:
2071 case jit_code_pushargr_f: case jit_code_pushargi_f:
2072 case jit_code_pushargr_d: case jit_code_pushargi_d:
2073 case jit_code_retval_c: case jit_code_retval_uc:
2074 case jit_code_retval_s: case jit_code_retval_us:
2075 case jit_code_retval_i:
2076 #if __WORDSIZE == 64
2077 case jit_code_retval_ui: case jit_code_retval_l:
2079 case jit_code_retval_f: case jit_code_retval_d:
2080 case jit_code_prepare:
2081 case jit_code_finishr: case jit_code_finishi:
2082 case jit_code_negi_f: case jit_code_absi_f:
2083 case jit_code_sqrti_f: case jit_code_negi_d:
2084 case jit_code_absi_d: case jit_code_sqrti_d:
2087 negi(rn(node->u.w), node->v.w);
2090 comi(rn(node->u.w), node->v.w);
2092 case jit_code_exti_c:
2093 exti_c(rn(node->u.w), node->v.w);
2095 case jit_code_exti_uc:
2096 exti_uc(rn(node->u.w), node->v.w);
2098 case jit_code_exti_s:
2099 exti_s(rn(node->u.w), node->v.w);
2101 case jit_code_exti_us:
2102 exti_us(rn(node->u.w), node->v.w);
2104 case jit_code_bswapi_us:
2105 bswapi_us(rn(node->u.w), node->v.w);
2107 case jit_code_bswapi_ui:
2108 bswapi_ui(rn(node->u.w), node->v.w);
2110 case jit_code_htoni_us:
2111 htoni_us(rn(node->u.w), node->v.w);
2113 case jit_code_htoni_ui:
2114 htoni_ui(rn(node->u.w), node->v.w);
2116 #if __WORDSIZE == 64
2117 case jit_code_exti_i:
2118 exti_i(rn(node->u.w), node->v.w);
2120 case jit_code_exti_ui:
2121 exti_ui(rn(node->u.w), node->v.w);
2123 case jit_code_bswapi_ul:
2124 bswapi_ul(rn(node->u.w), node->v.w);
2126 case jit_code_htoni_ul:
2127 htoni_ul(rn(node->u.w), node->v.w);
2131 cloi(rn(node->u.w), node->v.w);
2134 clzi(rn(node->u.w), node->v.w);
2137 ctoi(rn(node->u.w), node->v.w);
2140 ctzi(rn(node->u.w), node->v.w);
2142 case jit_code_rbiti:
2143 rbiti(rn(node->u.w), node->v.w);
2145 case jit_code_popcnti:
2146 popcnti(rn(node->u.w), node->v.w);
2149 exti(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
2151 case jit_code_exti_u:
2152 exti_u(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
2157 jit_regarg_clr(node, value);
2158 assert(_jitc->regarg == 0 && _jitc->synth == 0);
2159 /* update register live state */
2162 no_flag = !(node->flag & jit_flag_patch);
2175 for (offset = 0; offset < _jitc->patches.offset; offset++) {
2176 node = _jitc->patches.ptr[offset].node;
2177 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
2178 patch_at(_jitc->patches.ptr[offset].inst, word);
2181 jit_flush(_jit->code.ptr, _jit->pc.uc);
2183 return (_jit->code.ptr);
2187 # include "jit_ppc-cpu.c"
2188 # include "jit_ppc-fpu.c"
2189 # include "jit_fallback.c"
2193 jit_flush(void *fptr, void *tptr)
2195 #if defined(__GNUC__)
2198 s = sysconf(_SC_PAGE_SIZE);
2199 f = (jit_word_t)fptr & -s;
2200 t = (((jit_word_t)tptr) + s - 1) & -s;
2201 __clear_cache((void *)f, (void *)t);
2206 _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2208 #if __WORDSIZE == 32
2209 ldxi_i(rn(r0), rn(r1), i0);
2211 ldxi_l(rn(r0), rn(r1), i0);
2216 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2218 #if __WORDSIZE == 32
2219 stxi_i(i0, rn(r0), rn(r1));
2221 stxi_l(i0, rn(r0), rn(r1));
2226 _emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2228 ldxi_d(rn(r0), rn(r1), i0);
2232 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2234 stxi_d(i0, rn(r0), rn(r1));
2238 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
2242 assert(node->flag & jit_flag_node);
2243 if (node->code == jit_code_movi)
2244 flag = node->v.n->flag;
2246 flag = node->u.n->flag;
2247 assert(!(flag & jit_flag_patch));
2248 if (_jitc->patches.offset >= _jitc->patches.length) {
2249 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
2250 _jitc->patches.length * sizeof(jit_patch_t),
2251 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
2252 _jitc->patches.length += 1024;
2254 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
2255 _jitc->patches.ptr[_jitc->patches.offset].node = node;
2256 ++_jitc->patches.offset;