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
21 * align16(lr+fp+x19+x2[0-8]+v8+v9+v1[0-15]) */
22 #define stack_framesize 160
24 #define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8)
25 #define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8)
28 typedef jit_pointer_t jit_va_list_t;
30 typedef struct jit_qreg {
35 #define va_gp_top_offset offsetof(jit_va_list_t, q0)
36 #define va_fp_top_offset sizeof(jit_va_list_t)
37 typedef struct jit_va_list {
67 #define compute_framesize() _compute_framesize(_jit)
68 static void _compute_framesize(jit_state_t*);
69 #define patch(instr, node) _patch(_jit, instr, node)
70 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
73 extern void __clear_cache(void *, void *);
76 # include "jit_aarch64-cpu.c"
77 # include "jit_aarch64-fpu.c"
83 jit_register_t _rvs[] = {
84 { rc(gpr) | 0x08, "x8" },
88 { rc(gpr) | 0x12, "x18" },
90 { rc(gpr) | 0x11, "x17" },
91 { rc(gpr) | 0x10, "x16" },
92 { rc(gpr) | 0x09, "x9" },
93 { rc(gpr) | 0x0a, "x10" },
94 { rc(gpr) | 0x0b, "x11" },
95 { rc(gpr) | 0x0c, "x12" },
96 { rc(gpr) | 0x0d, "x13" },
97 { rc(gpr) | 0x0e, "x14" },
98 { rc(gpr) | 0x0f, "x15" },
99 { rc(sav) | rc(gpr) | 0x13, "x19" },
100 { rc(sav) | rc(gpr) | 0x14, "x20" },
101 { rc(sav) | rc(gpr) | 0x15, "x21" },
102 { rc(sav) | rc(gpr) | 0x16, "x22" },
103 { rc(sav) | rc(gpr) | 0x17, "x23" },
104 { rc(sav) | rc(gpr) | 0x18, "x24" },
105 { rc(sav) | rc(gpr) | 0x19, "x25" },
106 { rc(sav) | rc(gpr) | 0x1a, "x26" },
107 { rc(sav) | rc(gpr) | 0x1b, "x27" },
108 { rc(sav) | rc(gpr) | 0x1c, "x28" },
112 { rc(arg) | rc(gpr) | 0x07, "x7" },
113 { rc(arg) | rc(gpr) | 0x06, "x6" },
114 { rc(arg) | rc(gpr) | 0x05, "x5" },
115 { rc(arg) | rc(gpr) | 0x04, "x4" },
116 { rc(arg) | rc(gpr) | 0x03, "x3" },
117 { rc(arg) | rc(gpr) | 0x02, "x2" },
118 { rc(arg) | rc(gpr) | 0x01, "x1" },
119 { rc(arg) | rc(gpr) | 0x00, "x0" },
120 { rc(fpr) | 0x1f, "v31" },
121 { rc(fpr) | 0x1e, "v30" },
122 { rc(fpr) | 0x1d, "v29" },
123 { rc(fpr) | 0x1c, "v28" },
124 { rc(fpr) | 0x1b, "v27" },
125 { rc(fpr) | 0x1a, "v26" },
126 { rc(fpr) | 0x19, "v25" },
127 { rc(fpr) | 0x18, "v24" },
128 { rc(fpr) | 0x17, "v23" },
129 { rc(fpr) | 0x16, "v22" },
130 { rc(fpr) | 0x15, "v21" },
131 { rc(fpr) | 0x14, "v20" },
132 { rc(fpr) | 0x13, "v19" },
133 { rc(fpr) | 0x12, "v18" },
134 { rc(fpr) | 0x11, "v17" },
135 { rc(fpr) | 0x10, "v16" },
136 { rc(sav) | rc(fpr) | 0x08, "v8" },
137 { rc(sav) | rc(fpr) | 0x09, "v9" },
138 { rc(sav) | rc(fpr) | 0x0a, "v10" },
139 { rc(sav) | rc(fpr) | 0x0b, "v11" },
140 { rc(sav) | rc(fpr) | 0x0c, "v12" },
141 { rc(sav) | rc(fpr) | 0x0d, "v13" },
142 { rc(sav) | rc(fpr) | 0x0e, "v14" },
143 { rc(sav) | rc(fpr) | 0x0f, "v15" },
144 { rc(arg) | rc(fpr) | 0x07, "v7" },
145 { rc(arg) | rc(fpr) | 0x06, "v6" },
146 { rc(arg) | rc(fpr) | 0x05, "v5" },
147 { rc(arg) | rc(fpr) | 0x04, "v4" },
148 { rc(arg) | rc(fpr) | 0x03, "v3" },
149 { rc(arg) | rc(fpr) | 0x02, "v2" },
150 { rc(arg) | rc(fpr) | 0x01, "v1" },
151 { rc(arg) | rc(fpr) | 0x00, "v0" },
152 { _NOREG, "<none>" },
155 static jit_int32_t iregs[] = {
156 _R19, _R20, _R21, _R22, _R23, _R24, _R25, _R26, _R27, _R28
159 static jit_int32_t fregs[] = {
160 _V8, _V9, _V10, _V11, _V12, _V13, _V14, _V15
172 _jit_init(jit_state_t *_jit)
174 _jitc->reglen = jit_size(_rvs) - 1;
178 _jit_prolog(jit_state_t *_jit)
184 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
185 jit_regset_set_ui(&_jitc->regsav, 0);
186 offset = _jitc->functions.offset;
187 if (offset >= _jitc->functions.length) {
188 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
189 _jitc->functions.length * sizeof(jit_function_t),
190 (_jitc->functions.length + 16) * sizeof(jit_function_t));
191 _jitc->functions.length += 16;
193 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
194 _jitc->function->self.size = stack_framesize;
195 _jitc->function->self.argi = _jitc->function->self.argf =
196 _jitc->function->self.alen = 0;
197 _jitc->function->self.aoff = 0;
198 _jitc->function->self.call = jit_call_default;
199 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
200 _jitc->reglen * sizeof(jit_int32_t));
202 /* _no_link here does not mean the jit_link() call can be removed
204 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
206 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
207 jit_link(_jitc->function->prolog);
208 _jitc->function->prolog->w.w = offset;
209 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
211 * v: offset in blocks vector
212 * w: offset in functions vector
214 _jitc->function->epilog->w.w = offset;
216 jit_regset_new(&_jitc->function->regset);
220 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
222 assert(_jitc->function);
225 case 0: case 1: break;
226 case 2: _jitc->function->self.aoff &= -2; break;
227 case 3: case 4: _jitc->function->self.aoff &= -4; break;
228 default: _jitc->function->self.aoff &= -8; break;
230 _jitc->function->self.aoff -= length;
231 if (!_jitc->realize) {
232 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
235 return (_jitc->function->self.aoff);
239 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
242 assert(_jitc->function);
243 jit_inc_synth_ww(allocar, u, v);
244 if (!_jitc->function->allocar) {
245 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
246 _jitc->function->allocar = 1;
248 r0 = jit_get_reg(jit_class_gpr);
250 jit_andi(r0, r0, -16);
251 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
253 /* Cannot "addr sp, sp, reg" because in this context "sp" is "[w|x]zr",
254 * the zero register */
256 jit_addr(JIT_SP, JIT_SP, r0);
258 r1 = jit_get_reg(jit_class_gpr);
259 /* note that "mov r1, sp" does not work, but the proper encoding
260 * can be triggered before actually emiting with "add r1, sp, 0" */
261 jit_addi(r1, JIT_SP, 0);
262 jit_addr(r1, r1, r0);
263 jit_addi(JIT_SP, r1, 0);
266 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
272 _jit_ret(jit_state_t *_jit)
275 assert(_jitc->function);
279 jit_patch_at(instr, _jitc->function->epilog);
284 _jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
286 jit_code_inc_synth_w(code, u);
287 jit_movr(JIT_RET, u);
293 _jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
295 jit_code_inc_synth_w(code, u);
296 jit_movi(JIT_RET, u);
302 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
304 jit_inc_synth_w(retr_f, u);
306 jit_movr_f(JIT_FRET, u);
314 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
316 jit_inc_synth_f(reti_f, u);
317 jit_movi_f(JIT_FRET, u);
323 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
325 jit_inc_synth_w(retr_d, u);
327 jit_movr_d(JIT_FRET, u);
335 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
337 jit_inc_synth_d(reti_d, u);
338 jit_movi_d(JIT_FRET, u);
344 _jit_epilog(jit_state_t *_jit)
346 assert(_jitc->function);
347 assert(_jitc->function->epilog->next == NULL);
348 jit_link(_jitc->function->epilog);
349 _jitc->function = NULL;
353 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
355 if (u->code >= jit_code_arg_c && u->code <= jit_code_arg)
356 return (jit_arg_reg_p(u->u.w));
357 assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
358 return (jit_arg_f_reg_p(u->u.w));
362 _jit_ellipsis(jit_state_t *_jit)
364 jit_inc_synth(ellipsis);
366 if (_jitc->prepare) {
368 assert(!(_jitc->function->call.call & jit_call_varargs));
369 _jitc->function->call.call |= jit_call_varargs;
373 assert(!(_jitc->function->self.call & jit_call_varargs));
374 _jitc->function->self.call |= jit_call_varargs;
377 /* Allocate va_list like object in the stack,
378 * with enough space to save all argument
379 * registers, and use fixed offsets for them. */
380 _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
382 /* Initialize gp offset in save area. */
383 if (jit_arg_reg_p(_jitc->function->self.argi))
384 _jitc->function->vagp = (8 - _jitc->function->self.argi) * -8;
386 _jitc->function->vagp = 0;
388 /* Initialize fp offset in save area. */
389 if (jit_arg_f_reg_p(_jitc->function->self.argf))
390 _jitc->function->vafp = (8 - _jitc->function->self.argf) * -16;
392 _jitc->function->vafp = 0;
399 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
401 jit_inc_synth_w(va_push, u);
407 _jit_arg(jit_state_t *_jit, jit_code_t code)
411 assert(_jitc->function);
412 assert(!(_jitc->function->self.call & jit_call_varargs));
413 if (jit_arg_reg_p(_jitc->function->self.argi))
414 offset = _jitc->function->self.argi++;
416 #if PACKED_STACK || STRONG_TYPE_CHECKING
417 assert(code >= jit_code_arg_c && code <= jit_code_arg);
420 _jitc->function->self.size +=
421 _jitc->function->self.size & ((1 << (code - jit_code_arg_c)) - 1);
423 offset = _jitc->function->self.size;
425 _jitc->function->self.size += 1 << (code - jit_code_arg_c);
427 _jitc->function->self.size += sizeof(jit_word_t);
431 node = jit_new_node_ww(code, offset,
432 ++_jitc->function->self.argn);
438 _jit_arg_f(jit_state_t *_jit)
442 assert(_jitc->function);
443 assert(!(_jitc->function->self.call & jit_call_varargs));
444 if (jit_arg_f_reg_p(_jitc->function->self.argf))
445 offset = _jitc->function->self.argf++;
448 _jitc->function->self.size +=
449 _jitc->function->self.size & (sizeof(jit_float32_t) - 1);
451 offset = _jitc->function->self.size;
453 _jitc->function->self.size += sizeof(jit_float32_t);
455 _jitc->function->self.size += sizeof(jit_word_t);
459 node = jit_new_node_ww(jit_code_arg_f, offset,
460 ++_jitc->function->self.argn);
466 _jit_arg_d(jit_state_t *_jit)
470 assert(_jitc->function);
471 assert(!(_jitc->function->self.call & jit_call_varargs));
472 if (jit_arg_f_reg_p(_jitc->function->self.argf))
473 offset = _jitc->function->self.argf++;
476 _jitc->function->self.size +=
477 _jitc->function->self.size & (sizeof(jit_float64_t) - 1);
479 offset = _jitc->function->self.size;
480 _jitc->function->self.size += sizeof(jit_float64_t);
483 node = jit_new_node_ww(jit_code_arg_d, offset,
484 ++_jitc->function->self.argn);
490 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
492 assert_arg_type(v->code, jit_code_arg_c);
493 jit_inc_synth_wp(getarg_c, u, v);
494 if (jit_arg_reg_p(v->u.w)) {
496 jit_movr(u, JIT_RA0 - v->u.w);
498 jit_extr_c(u, JIT_RA0 - v->u.w);
502 jit_node_t *node = jit_ldxi_c(u, JIT_FP, v->u.w);
503 jit_link_alist(node);
509 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
511 assert_arg_type(v->code, jit_code_arg_c);
512 jit_inc_synth_wp(getarg_uc, u, v);
513 if (jit_arg_reg_p(v->u.w)) {
515 jit_movr(u, JIT_RA0 - v->u.w);
517 jit_extr_uc(u, JIT_RA0 - v->u.w);
521 jit_node_t *node = jit_ldxi_uc(u, JIT_FP, v->u.w);
522 jit_link_alist(node);
528 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
530 assert_arg_type(v->code, jit_code_arg_s);
531 jit_inc_synth_wp(getarg_s, u, v);
532 if (jit_arg_reg_p(v->u.w)) {
534 jit_movr(u, JIT_RA0 - v->u.w);
536 jit_extr_s(u, JIT_RA0 - v->u.w);
540 jit_node_t *node = jit_ldxi_s(u, JIT_FP, v->u.w);
541 jit_link_alist(node);
547 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
549 assert_arg_type(v->code, jit_code_arg_s);
550 jit_inc_synth_wp(getarg_us, u, v);
551 if (jit_arg_reg_p(v->u.w)) {
553 jit_movr(u, JIT_RA0 - v->u.w);
555 jit_extr_us(u, JIT_RA0 - v->u.w);
559 jit_node_t *node = jit_ldxi_us(u, JIT_FP, v->u.w);
560 jit_link_alist(node);
566 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
568 assert_arg_type(v->code, jit_code_arg_i);
569 jit_inc_synth_wp(getarg_i, u, v);
570 if (jit_arg_reg_p(v->u.w)) {
571 #if PACKED_STACK || __WORDSIZE == 32
572 jit_movr(u, JIT_RA0 - v->u.w);
574 jit_extr_i(u, JIT_RA0 - v->u.w);
578 jit_node_t *node = jit_ldxi_i(u, JIT_FP, v->u.w);
579 jit_link_alist(node);
586 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
588 assert_arg_type(v->code, jit_code_arg_i);
589 jit_inc_synth_wp(getarg_ui, u, v);
590 if (jit_arg_reg_p(v->u.w)) {
592 jit_movr(u, JIT_RA0 - v->u.w);
594 jit_extr_ui(u, JIT_RA0 - v->u.w);
598 jit_node_t *node = jit_ldxi_ui(u, JIT_FP, v->u.w);
599 jit_link_alist(node);
605 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
607 assert_arg_type(v->code, jit_code_arg_l);
608 jit_inc_synth_wp(getarg_l, u, v);
609 if (jit_arg_reg_p(v->u.w))
610 jit_movr(u, JIT_RA0 - v->u.w);
612 jit_node_t *node = jit_ldxi_l(u, JIT_FP, v->u.w);
613 jit_link_alist(node);
620 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
622 assert_putarg_type(code, v->code);
623 jit_code_inc_synth_wp(code, u, v);
624 if (jit_arg_reg_p(v->u.w)) {
625 jit_int32_t regno = JIT_RA0 - v->u.w;
628 case jit_code_putargr_c: jit_extr_c(regno, u); break;
629 case jit_code_putargr_uc: jit_extr_uc(regno, u); break;
630 case jit_code_putargr_s: jit_extr_s(regno, u); break;
631 case jit_code_putargr_us: jit_extr_us(regno, u); break;
632 # if __WORDISZE == 32
633 case jit_code_putargr_i: jit_movr(regno, u); break;
635 case jit_code_putargr_i: jit_extr_i(regno, u); break;
636 case jit_code_putargr_ui: jit_extr_ui(regno, u); break;
637 case jit_code_putargr_l: jit_movr(regno, u); break;
639 default: abort(); break;
649 case jit_code_putargr_c: case jit_code_putargr_uc:
650 node = jit_stxi_c(v->u.w, JIT_FP, u); break;
651 case jit_code_putargr_s: case jit_code_putargr_us:
652 node = jit_stxi_s(v->u.w, JIT_FP, u); break;
653 # if __WORDSIZE == 32
654 case jit_code_putargr_i:
655 node = jit_stxi(v->u.w, JIT_FP, u); break;
657 case jit_code_putargr_i: case jit_code_putargr_ui:
658 node = jit_stxi_i(v->u.w, JIT_FP, u); break;
659 case jit_code_putargr_l:
660 node = jit_stxi(v->u.w, JIT_FP, u); break;
662 default: abort(); break;
665 node = jit_stxi(v->u.w, JIT_FP, u);
667 jit_link_alist(node);
673 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
676 assert_putarg_type(code, v->code);
677 jit_code_inc_synth_wp(code, u, v);
680 case jit_code_putargi_c: u = (jit_int8_t)u; break;
681 case jit_code_putargi_uc: u = (jit_uint8_t)u; break;
682 case jit_code_putargi_s: u = (jit_int16_t)u; break;
683 case jit_code_putargi_us: u = (jit_uint16_t)u; break;
684 # if __WORDSIZE == 32
685 case jit_code_putargi_i: break;
687 case jit_code_putargi_i: u = (jit_int32_t)u; break;
688 case jit_code_putargi_ui: u = (jit_uint32_t)u; break;
689 case jit_code_putargi_l: break;
691 default: abort(); break;
694 if (jit_arg_reg_p(v->u.w))
695 jit_movi(JIT_RA0 - v->u.w, u);
698 regno = jit_get_reg(jit_class_gpr);
702 case jit_code_putargi_c: case jit_code_putargi_uc:
703 node = jit_stxi_c(v->u.w, JIT_FP, regno); break;
704 case jit_code_putargi_s: case jit_code_putargi_us:
705 node = jit_stxi_s(v->u.w, JIT_FP, regno); break;
706 # if __WORDSIZE == 32
707 case jit_code_putargi_i:
708 node = jit_stxi(v->u.w, JIT_FP, regno); break;
710 case jit_code_putargi_i: case jit_code_putargi_ui:
711 node = jit_stxi_i(v->u.w, JIT_FP, regno); break;
712 case jit_code_putargi_l:
713 node = jit_stxi(v->u.w, JIT_FP, regno); break;
715 default: abort(); break;
718 node = jit_stxi(v->u.w, JIT_FP, regno);
720 jit_link_alist(node);
721 jit_unget_reg(regno);
727 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
729 assert(v->code == jit_code_arg_f);
730 jit_inc_synth_wp(getarg_f, u, v);
731 if (jit_arg_reg_p(v->u.w))
732 jit_movr_f(u, JIT_FA0 - v->u.w);
734 jit_node_t *node = jit_ldxi_f(u, JIT_FP, v->u.w);
735 jit_link_alist(node);
741 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
743 assert(v->code == jit_code_arg_f);
744 jit_inc_synth_wp(putargr_f, u, v);
745 if (jit_arg_f_reg_p(v->u.w))
746 jit_movr_f(JIT_FA0 - v->u.w, u);
748 jit_node_t *node = jit_stxi_f(v->u.w, JIT_FP, u);
749 jit_link_alist(node);
755 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
758 assert(v->code == jit_code_arg_f);
759 jit_inc_synth_fp(putargi_f, u, v);
760 if (jit_arg_f_reg_p(v->u.w))
761 jit_movi_f(JIT_FA0 - v->u.w, u);
764 regno = jit_get_reg(jit_class_fpr);
765 jit_movi_f(regno, u);
766 node = jit_stxi_f(v->u.w, JIT_FP, regno);
767 jit_link_alist(node);
768 jit_unget_reg(regno);
774 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
776 assert(v->code == jit_code_arg_d);
777 jit_inc_synth_wp(getarg_d, u, v);
778 if (jit_arg_f_reg_p(v->u.w))
779 jit_movr_d(u, JIT_FA0 - v->u.w);
781 jit_node_t *node = jit_ldxi_d(u, JIT_FP, v->u.w);
782 jit_link_alist(node);
788 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
790 assert(v->code == jit_code_arg_d);
791 jit_inc_synth_wp(putargr_d, u, v);
792 if (jit_arg_reg_p(v->u.w))
793 jit_movr_d(JIT_FA0 - v->u.w, u);
795 jit_node_t *node = jit_stxi_d(v->u.w, JIT_FP, u);
796 jit_link_alist(node);
802 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
805 assert(v->code == jit_code_arg_d);
806 jit_inc_synth_dp(putargi_d, u, v);
807 if (jit_arg_reg_p(v->u.w))
808 jit_movi_d(JIT_FA0 - v->u.w, u);
811 regno = jit_get_reg(jit_class_fpr);
812 jit_movi_d(regno, u);
813 node = jit_stxi_d(v->u.w, JIT_FP, regno);
814 jit_link_alist(node);
815 jit_unget_reg(regno);
821 _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
823 assert(_jitc->function);
824 jit_code_inc_synth_w(code, u);
826 if (jit_arg_reg_p(_jitc->function->call.argi)) {
827 jit_int32_t regno = JIT_RA0 - _jitc->function->call.argi;
830 case jit_code_pushargr_c: jit_extr_c(regno, u); break;
831 case jit_code_pushargr_uc: jit_extr_uc(regno, u); break;
832 case jit_code_pushargr_s: jit_extr_s(regno, u); break;
833 case jit_code_pushargr_us: jit_extr_us(regno, u); break;
834 # if __WORDISZE == 32
835 case jit_code_pushargr_i: jit_movr(regno, u); break;
837 case jit_code_pushargr_i: jit_extr_i(regno, u); break;
838 case jit_code_pushargr_ui: jit_extr_ui(regno, u); break;
839 case jit_code_pushargr_l: jit_movr(regno, u); break;
841 default: abort(); break;
847 if (_jitc->function->call.call & jit_call_varargs) {
848 assert(code == jit_code_pushargr);
849 jit_stxi(_jitc->function->call.size, JIT_SP, u);
850 _jitc->function->call.size += sizeof(jit_word_t);
853 ++_jitc->function->call.argi;
857 _jitc->function->call.size +=
858 _jitc->function->call.size &
859 ((1 << ((code - jit_code_pushargr_c) >> 2)) - 1);
861 case jit_code_pushargr_c: case jit_code_pushargr_uc:
862 jit_stxi_c(_jitc->function->call.size, JIT_SP, u);
864 case jit_code_pushargr_s: case jit_code_pushargr_us:
865 jit_stxi_s(_jitc->function->call.size, JIT_SP, u);
867 # if __WORDSIZE == 32
868 case jit_code_pushargr_i:
869 jit_stxi(_jitc->function->call.size, JIT_SP, u);
872 case jit_code_pushargr_i: case jit_code_pushargr_ui:
873 jit_stxi_i(_jitc->function->call.size, JIT_SP, u);
875 case jit_code_pushargr_l:
876 jit_stxi(_jitc->function->call.size, JIT_SP, u);
883 _jitc->function->call.size += 1 << ((code - jit_code_pushargr_c) >> 2);
885 jit_stxi(_jitc->function->call.size, JIT_SP, u);
886 _jitc->function->call.size += sizeof(jit_word_t);
894 _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
897 assert(_jitc->function);
898 jit_code_inc_synth_w(code, u);
902 case jit_code_pushargi_c: u = (jit_int8_t)u; break;
903 case jit_code_pushargi_uc: u = (jit_uint8_t)u; break;
904 case jit_code_pushargi_s: u = (jit_int16_t)u; break;
905 case jit_code_pushargi_us: u = (jit_uint16_t)u; break;
906 # if __WORDSIZE == 32
907 case jit_code_pushargi_i: break;
909 case jit_code_pushargi_i: u = (jit_int32_t)u; break;
910 case jit_code_pushargi_ui: u = (jit_uint32_t)u; break;
911 case jit_code_pushargi_l: break;
913 default: abort(); break;
916 if (jit_arg_reg_p(_jitc->function->call.argi)) {
917 regno = JIT_RA0 - _jitc->function->call.argi;
920 if (_jitc->function->call.call & jit_call_varargs) {
921 assert(code == jit_code_pushargi);
922 jit_stxi(_jitc->function->call.size, JIT_SP, regno);
923 _jitc->function->call.size += sizeof(jit_word_t);
926 ++_jitc->function->call.argi;
929 regno = jit_get_reg(jit_class_gpr);
932 _jitc->function->call.size +=
933 _jitc->function->call.size &
934 ((1 << ((code - jit_code_pushargr_c) >> 2)) - 1);
936 case jit_code_pushargi_c: case jit_code_pushargi_uc:
937 jit_stxi_c(_jitc->function->call.size, JIT_SP, regno);
939 case jit_code_pushargi_s: case jit_code_pushargi_us:
940 jit_stxi_s(_jitc->function->call.size, JIT_SP, regno);
942 # if __WORDSIZE == 32
943 case jit_code_pushargi_i:
944 jit_stxi(_jitc->function->call.size, JIT_SP, regno);
947 case jit_code_pushargi_i: case jit_code_pushargi_ui:
948 jit_stxi_i(_jitc->function->call.size, JIT_SP, regno);
950 case jit_code_pushargi_l:
951 jit_stxi(_jitc->function->call.size, JIT_SP, regno);
958 _jitc->function->call.size += 1 << ((code - jit_code_pushargr_c) >> 2);
960 jit_stxi(_jitc->function->call.size, JIT_SP, regno);
961 _jitc->function->call.size += sizeof(jit_word_t);
963 jit_unget_reg(regno);
970 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
972 assert(_jitc->function);
973 jit_inc_synth_w(pushargr_f, u);
975 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
976 jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u);
978 if (_jitc->function->call.call & jit_call_varargs) {
979 assert(sizeof(jit_float32_t) == sizeof(jit_word_t));
980 jit_stxi_f(_jitc->function->call.size, JIT_SP,
981 JIT_FA0 - _jitc->function->call.argf);
982 _jitc->function->call.size += sizeof(jit_word_t);
985 ++_jitc->function->call.argf;
989 _jitc->function->call.size +=
990 _jitc->function->call.size & (sizeof(jit_float32_t) - 1);
991 jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
992 _jitc->function->call.size += sizeof(jit_float32_t);
994 jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
995 _jitc->function->call.size += sizeof(jit_word_t);
1003 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
1006 assert(_jitc->function);
1007 jit_inc_synth_f(pushargi_f, u);
1009 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
1010 jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u);
1012 if (_jitc->function->call.call & jit_call_varargs) {
1013 assert(sizeof(jit_float32_t) == sizeof(jit_word_t));
1014 jit_stxi_f(_jitc->function->call.size, JIT_SP,
1015 JIT_FA0 - _jitc->function->call.argf);
1016 _jitc->function->call.size += sizeof(jit_word_t);
1019 ++_jitc->function->call.argf;
1022 regno = jit_get_reg(jit_class_fpr);
1023 jit_movi_f(regno, u);
1025 _jitc->function->call.size +=
1026 _jitc->function->call.size & (sizeof(jit_float32_t) - 1);
1027 jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
1028 _jitc->function->call.size += sizeof(jit_float32_t);
1030 jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
1031 _jitc->function->call.size += sizeof(jit_word_t);
1033 jit_unget_reg(regno);
1040 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
1042 assert(_jitc->function);
1043 jit_inc_synth_w(pushargr_d, u);
1045 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
1046 jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
1048 if (_jitc->function->call.call & jit_call_varargs) {
1049 assert(sizeof(jit_float64_t) == sizeof(jit_word_t));
1050 jit_stxi_d(_jitc->function->call.size, JIT_SP,
1051 JIT_FA0 - _jitc->function->call.argf);
1052 _jitc->function->call.size += sizeof(jit_float64_t);
1055 ++_jitc->function->call.argf;
1059 _jitc->function->call.size +=
1060 _jitc->function->call.size & (sizeof(jit_float64_t) - 1);
1062 jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
1063 _jitc->function->call.size += sizeof(jit_float64_t);
1070 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
1073 assert(_jitc->function);
1074 jit_inc_synth_d(pushargi_d, u);
1076 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
1077 jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
1079 if (_jitc->function->call.call & jit_call_varargs) {
1080 assert(sizeof(jit_float64_t) == sizeof(jit_word_t));
1081 jit_stxi_d(_jitc->function->call.size, JIT_SP,
1082 JIT_FA0 - _jitc->function->call.argf);
1083 _jitc->function->call.size += sizeof(jit_float64_t);
1086 ++_jitc->function->call.argf;
1089 regno = jit_get_reg(jit_class_fpr);
1090 jit_movi_d(regno, u);
1092 _jitc->function->call.size +=
1093 _jitc->function->call.size & (sizeof(jit_float64_t) - 1);
1095 jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
1096 jit_unget_reg(regno);
1097 _jitc->function->call.size += sizeof(jit_float64_t);
1104 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
1107 spec = jit_class(_rvs[regno].spec);
1108 if (spec & jit_class_arg) {
1109 regno = JIT_RA0 - regno;
1110 if (regno >= 0 && regno < node->v.w)
1112 if (spec & jit_class_fpr) {
1113 regno = JIT_FA0 - regno;
1114 if (regno >= 0 && regno < node->w.w)
1123 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
1126 assert(_jitc->function);
1128 jit_inc_synth_w(finishr, r0);
1130 _jitc->function->call.size +=
1131 _jitc->function->call.size & (sizeof(jit_word_t) - 1);
1133 if (_jitc->function->self.alen < _jitc->function->call.size)
1134 _jitc->function->self.alen = _jitc->function->call.size;
1135 node = jit_callr(r0);
1136 node->v.w = _jitc->function->self.argi;
1137 node->w.w = _jitc->function->call.argf;
1138 _jitc->function->call.argi = _jitc->function->call.argf =
1139 _jitc->function->call.size = 0;
1145 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
1148 assert(_jitc->function);
1150 jit_inc_synth_w(finishi, (jit_word_t)i0);
1152 _jitc->function->call.size +=
1153 _jitc->function->call.size & (sizeof(jit_word_t) - 1);
1155 if (_jitc->function->self.alen < _jitc->function->call.size)
1156 _jitc->function->self.alen = _jitc->function->call.size;
1157 node = jit_calli(i0);
1158 node->v.w = _jitc->function->call.argi;
1159 node->w.w = _jitc->function->call.argf;
1160 _jitc->function->call.argi = _jitc->function->call.argf =
1161 _jitc->function->call.size = 0;
1168 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
1170 jit_inc_synth_w(retval_c, r0);
1171 jit_extr_c(r0, JIT_RET);
1176 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
1178 jit_inc_synth_w(retval_uc, r0);
1179 jit_extr_uc(r0, JIT_RET);
1184 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
1186 jit_inc_synth_w(retval_s, r0);
1187 jit_extr_s(r0, JIT_RET);
1192 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
1194 jit_inc_synth_w(retval_us, r0);
1195 jit_extr_us(r0, JIT_RET);
1200 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
1202 jit_inc_synth_w(retval_i, r0);
1203 #if __WORDSIZE == 32
1204 jit_movr(r0, JIT_RET);
1206 jit_extr_i(r0, JIT_RET);
1211 #if __WORDSIZE == 64
1213 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
1215 jit_inc_synth_w(retval_ui, r0);
1216 jit_extr_ui(r0, JIT_RET);
1221 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
1223 jit_inc_synth_w(retval_l, r0);
1224 jit_movr(r0, JIT_RET);
1230 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
1232 jit_inc_synth_w(retval_f, r0);
1234 jit_movr_f(r0, JIT_FRET);
1239 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
1241 jit_inc_synth_w(retval_d, r0);
1243 jit_movr_d(r0, JIT_FRET);
1248 _emit_code(jit_state_t *_jit)
1259 jit_function_t func;
1260 #if DEVEL_DISASSEMBLER
1263 jit_int32_t const_offset;
1264 jit_int32_t patch_offset;
1266 #if DEVEL_DISASSEMBLER
1270 _jitc->function = NULL;
1272 jit_reglive_setup();
1276 undo.const_offset = undo.patch_offset = 0;
1277 # define assert_data(node) /**/
1278 #define case_rr(name, type) \
1279 case jit_code_##name##r##type: \
1280 name##r##type(rn(node->u.w), rn(node->v.w)); \
1282 #define case_rw(name, type) \
1283 case jit_code_##name##i##type: \
1284 name##i##type(rn(node->u.w), node->v.w); \
1286 #define case_wr(name, type) \
1287 case jit_code_##name##i##type: \
1288 name##i##type(node->u.w, rn(node->v.w)); \
1290 #define case_rrr(name, type) \
1291 case jit_code_##name##r##type: \
1292 name##r##type(rn(node->u.w), \
1293 rn(node->v.w), rn(node->w.w)); \
1295 #define case_rrrr(name, type) \
1296 case jit_code_##name##r##type: \
1297 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
1298 rn(node->v.w), rn(node->w.w)); \
1300 #define case_rqr(name, type) \
1301 case jit_code_##name##r##type: \
1302 name##r##type(rn(node->u.w), rn(node->v.q.l), \
1303 rn(node->v.q.h), rn(node->w.w)); \
1304 case jit_code_##name##i##type: \
1306 #define case_rrw(name, type) \
1307 case jit_code_##name##i##type: \
1308 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
1310 #define case_rrrw(name, type) \
1311 case jit_code_##name##i##type: \
1312 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
1313 rn(node->v.w), node->w.w); \
1315 #define case_rrf(name) \
1316 case jit_code_##name##i_f: \
1317 assert_data(node); \
1318 name##i_f(rn(node->u.w), rn(node->v.w), node->w.f); \
1320 #define case_rrd(name) \
1321 case jit_code_##name##i_d: \
1322 assert_data(node); \
1323 name##i_d(rn(node->u.w), rn(node->v.w), node->w.d); \
1325 #define case_wrr(name, type) \
1326 case jit_code_##name##i##type: \
1327 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1329 #define case_brr(name, type) \
1330 case jit_code_##name##r##type: \
1332 assert(temp->code == jit_code_label || \
1333 temp->code == jit_code_epilog); \
1334 if (temp->flag & jit_flag_patch) \
1335 name##r##type(temp->u.w, rn(node->v.w), \
1338 word = name##r##type(_jit->pc.w, \
1339 rn(node->v.w), rn(node->w.w)); \
1340 patch(word, node); \
1343 #define case_brw(name, type) \
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, \
1350 rn(node->v.w), node->w.w); \
1352 word = name##i##type(_jit->pc.w, \
1353 rn(node->v.w), node->w.w); \
1354 patch(word, node); \
1357 #define case_brf(name) \
1358 case jit_code_##name##i_f: \
1360 assert(temp->code == jit_code_label || \
1361 temp->code == jit_code_epilog); \
1362 if (temp->flag & jit_flag_patch) \
1363 name##i_f(temp->u.w, rn(node->v.w), node->w.f); \
1365 word = name##i_f(_jit->pc.w, rn(node->v.w), \
1367 patch(word, node); \
1370 #define case_brd(name) \
1371 case jit_code_##name##i_d: \
1373 assert(temp->code == jit_code_label || \
1374 temp->code == jit_code_epilog); \
1375 if (temp->flag & jit_flag_patch) \
1376 name##i_d(temp->u.w, rn(node->v.w), node->w.d); \
1378 word = name##i_d(_jit->pc.w, rn(node->v.w), \
1380 patch(word, node); \
1383 #if DEVEL_DISASSEMBLER
1386 for (node = _jitc->head; node; node = node->next) {
1387 if (_jit->pc.uc >= _jitc->code.end)
1390 #if DEVEL_DISASSEMBLER
1391 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1394 value = jit_classify(node->code);
1395 jit_regarg_set(node, value);
1396 switch (node->code) {
1397 case jit_code_align:
1398 /* Must align to a power of two */
1399 assert(!(node->u.w & (node->u.w - 1)));
1400 if ((word = _jit->pc.w & (node->u.w - 1)))
1401 nop(node->u.w - word);
1404 nop((node->u.w + 3) & ~3);
1406 case jit_code_note: case jit_code_name:
1407 node->u.w = _jit->pc.w;
1409 case jit_code_label:
1410 /* remember label is defined */
1411 node->flag |= jit_flag_patch;
1412 node->u.w = _jit->pc.w;
1435 case_rrrr(qmul, _u);
1436 case_rrrw(qmul, _u);
1443 case_rrrr(qdiv, _u);
1444 case_rrrw(qdiv, _u);
1453 case_rrrr(qlsh, _u);
1454 case_rrrw(qlsh, _u);
1461 case_rrrr(qrsh, _u);
1462 case_rrrw(qrsh, _u);
1481 case_rr(trunc, _f_i);
1482 case_rr(trunc, _d_i);
1483 case_rr(trunc, _f_l);
1484 case_rr(trunc, _d_l);
1513 case jit_code_unldr:
1514 unldr(rn(node->u.w), rn(node->v.w), node->w.w);
1516 case jit_code_unldi:
1517 unldi(rn(node->u.w), node->v.w, node->w.w);
1519 case jit_code_unldr_u:
1520 unldr_u(rn(node->u.w), rn(node->v.w), node->w.w);
1522 case jit_code_unldi_u:
1523 unldi_u(rn(node->u.w), node->v.w, node->w.w);
1541 case jit_code_unstr:
1542 unstr(rn(node->u.w), rn(node->v.w), node->w.w);
1544 case jit_code_unsti:
1545 unsti(node->u.w, rn(node->v.w), node->w.w);
1550 case_rr(bswap, _us);
1551 case_rr(bswap, _ui);
1552 case_rr(bswap, _ul);
1554 extr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1556 case jit_code_extr_u:
1557 extr_u(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1560 depr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1563 depi(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1572 casr(rn(node->u.w), rn(node->v.w),
1573 rn(node->w.q.l), rn(node->w.q.h));
1576 casi(rn(node->u.w), node->v.w,
1577 rn(node->w.q.l), rn(node->w.q.h));
1583 if (node->flag & jit_flag_node) {
1585 if (temp->code == jit_code_data ||
1586 (temp->code == jit_code_label &&
1587 (temp->flag & jit_flag_patch)))
1588 movi(rn(node->u.w), temp->u.w);
1590 assert(temp->code == jit_code_label ||
1591 temp->code == jit_code_epilog);
1592 word = movi_p(rn(node->u.w), temp->u.w);
1597 movi(rn(node->u.w), node->v.w);
1641 case_brr(boadd, _u);
1642 case_brw(boadd, _u);
1645 case_brr(bxadd, _u);
1646 case_brw(bxadd, _u);
1649 case_brr(bosub, _u);
1650 case_brw(bosub, _u);
1653 case_brr(bxsub, _u);
1654 case_brw(bxsub, _u);
1680 case jit_code_unldr_x:
1681 unldr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1683 case jit_code_unldi_x:
1684 unldi_x(rn(node->u.w), node->v.w, node->w.w);
1690 case jit_code_unstr_x:
1691 unstr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1693 case jit_code_unsti_x:
1694 unsti_x(node->u.w, rn(node->v.w), node->w.w);
1697 case jit_code_movi_f:
1699 movi_f(rn(node->u.w), node->v.f);
1728 case_rrr(unord, _f);
1742 case_brr(bunlt, _f);
1744 case_brr(bunle, _f);
1746 case_brr(buneq, _f);
1748 case_brr(bunge, _f);
1750 case_brr(bungt, _f);
1752 case_brr(bltgt, _f);
1756 case_brr(bunord, _f);
1784 case jit_code_movi_d:
1786 movi_d(rn(node->u.w), node->v.d);
1815 case_rrr(unord, _d);
1829 case_brr(bunlt, _d);
1831 case_brr(bunle, _d);
1833 case_brr(buneq, _d);
1835 case_brr(bunge, _d);
1837 case_brr(bungt, _d);
1839 case_brr(bltgt, _d);
1843 case_brr(bunord, _d);
1847 jmpr(rn(node->u.w));
1850 if (node->flag & jit_flag_node) {
1852 assert(temp->code == jit_code_label ||
1853 temp->code == jit_code_epilog);
1854 if (temp->flag & jit_flag_patch)
1857 word = _jit->code.length -
1858 (_jit->pc.uc - _jit->code.ptr);
1860 word = jmpi(_jit->pc.w);
1862 word = jmpi_p(_jit->pc.w);
1871 case jit_code_callr:
1873 callr(rn(node->u.w));
1875 case jit_code_calli:
1877 if (node->flag & jit_flag_node) {
1879 assert(temp->code == jit_code_label ||
1880 temp->code == jit_code_epilog);
1881 if (temp->flag & jit_flag_patch)
1884 word = _jit->code.length -
1885 (_jit->pc.uc - _jit->code.ptr);
1887 word = calli(_jit->pc.w);
1889 word = calli_p(_jit->pc.w);
1896 case jit_code_prolog:
1897 _jitc->function = _jitc->functions.ptr + node->w.w;
1899 undo.word = _jit->pc.w;
1900 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
1901 #if DEVEL_DISASSEMBLER
1904 undo.patch_offset = _jitc->patches.offset;
1906 compute_framesize();
1911 case jit_code_epilog:
1912 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1914 for (temp = undo.node->next;
1915 temp != node; temp = temp->next) {
1916 if (temp->code == jit_code_label ||
1917 temp->code == jit_code_epilog)
1918 temp->flag &= ~jit_flag_patch;
1920 temp->flag &= ~jit_flag_patch;
1922 _jit->pc.w = undo.word;
1923 /* undo.func.self.aoff and undo.func.regset should not
1924 * be undone, as they will be further updated, and are
1925 * the reason of the undo. */
1926 undo.func.self.aoff = _jitc->function->frame +
1927 _jitc->function->self.aoff;
1928 undo.func.need_frame = _jitc->function->need_frame;
1929 jit_regset_set(&undo.func.regset, &_jitc->function->regset);
1930 /* allocar information also does not need to be undone */
1931 undo.func.aoffoff = _jitc->function->aoffoff;
1932 undo.func.allocar = _jitc->function->allocar;
1933 memcpy(_jitc->function, &undo.func, sizeof(undo.func));
1934 #if DEVEL_DISASSEMBLER
1937 _jitc->patches.offset = undo.patch_offset;
1939 goto restart_function;
1941 /* remember label is defined */
1942 node->flag |= jit_flag_patch;
1943 node->u.w = _jit->pc.w;
1945 _jitc->function = NULL;
1947 case jit_code_movr_w_f:
1948 movr_w_f(rn(node->u.w), rn(node->v.w));
1950 case jit_code_movr_f_w:
1951 movr_f_w(rn(node->u.w), rn(node->v.w));
1953 case jit_code_movi_f_w:
1954 movi_f_w(rn(node->u.w), node->v.f);
1956 case jit_code_movi_w_f:
1957 movi_w_f(rn(node->u.w), node->v.w);
1959 case jit_code_movr_w_d:
1960 movr_w_d(rn(node->u.w), rn(node->v.w));
1962 case jit_code_movr_d_w:
1963 movr_d_w(rn(node->u.w), rn(node->v.w));
1965 case jit_code_movi_d_w:
1966 movi_d_w(rn(node->u.w), node->v.d);
1968 case jit_code_movi_w_d:
1969 movi_w_d(rn(node->u.w), node->v.w);
1971 case jit_code_va_start:
1972 vastart(rn(node->u.w));
1974 case jit_code_va_arg:
1975 vaarg(rn(node->u.w), rn(node->v.w));
1977 case jit_code_va_arg_d:
1978 vaarg_d(rn(node->u.w), rn(node->v.w));
1980 case jit_code_live: case jit_code_ellipsis:
1981 case jit_code_va_push:
1982 case jit_code_allocai: case jit_code_allocar:
1983 case jit_code_arg_c: case jit_code_arg_s:
1984 case jit_code_arg_i:
1985 # if __WORDSIZE == 64
1986 case jit_code_arg_l:
1988 case jit_code_arg_f: case jit_code_arg_d:
1989 case jit_code_va_end:
1991 case jit_code_retr_c: case jit_code_reti_c:
1992 case jit_code_retr_uc: case jit_code_reti_uc:
1993 case jit_code_retr_s: case jit_code_reti_s:
1994 case jit_code_retr_us: case jit_code_reti_us:
1995 case jit_code_retr_i: case jit_code_reti_i:
1996 #if __WORDSIZE == 64
1997 case jit_code_retr_ui: case jit_code_reti_ui:
1998 case jit_code_retr_l: case jit_code_reti_l:
2000 case jit_code_retr_f: case jit_code_reti_f:
2001 case jit_code_retr_d: case jit_code_reti_d:
2002 case jit_code_getarg_c: case jit_code_getarg_uc:
2003 case jit_code_getarg_s: case jit_code_getarg_us:
2004 case jit_code_getarg_i: case jit_code_getarg_ui:
2005 case jit_code_getarg_l:
2006 case jit_code_getarg_f: case jit_code_getarg_d:
2007 case jit_code_putargr_c: case jit_code_putargi_c:
2008 case jit_code_putargr_uc: case jit_code_putargi_uc:
2009 case jit_code_putargr_s: case jit_code_putargi_s:
2010 case jit_code_putargr_us: case jit_code_putargi_us:
2011 case jit_code_putargr_i: case jit_code_putargi_i:
2012 #if __WORDSIZE == 64
2013 case jit_code_putargr_ui: case jit_code_putargi_ui:
2014 case jit_code_putargr_l: case jit_code_putargi_l:
2016 case jit_code_putargr_f: case jit_code_putargi_f:
2017 case jit_code_putargr_d: case jit_code_putargi_d:
2018 case jit_code_pushargr_c: case jit_code_pushargi_c:
2019 case jit_code_pushargr_uc: case jit_code_pushargi_uc:
2020 case jit_code_pushargr_s: case jit_code_pushargi_s:
2021 case jit_code_pushargr_us: case jit_code_pushargi_us:
2022 case jit_code_pushargr_i: case jit_code_pushargi_i:
2023 #if __WORDSIZE == 64
2024 case jit_code_pushargr_ui: case jit_code_pushargi_ui:
2025 case jit_code_pushargr_l: case jit_code_pushargi_l:
2027 case jit_code_pushargr_f: case jit_code_pushargi_f:
2028 case jit_code_pushargr_d: case jit_code_pushargi_d:
2029 case jit_code_retval_c: case jit_code_retval_uc:
2030 case jit_code_retval_s: case jit_code_retval_us:
2031 case jit_code_retval_i:
2032 #if __WORDSIZE == 64
2033 case jit_code_retval_ui: case jit_code_retval_l:
2035 case jit_code_retval_f: case jit_code_retval_d:
2036 case jit_code_prepare:
2037 case jit_code_finishr: case jit_code_finishi:
2038 case jit_code_negi_f: case jit_code_absi_f:
2039 case jit_code_sqrti_f: case jit_code_negi_d:
2040 case jit_code_absi_d: case jit_code_sqrti_d:
2043 negi(rn(node->u.w), node->v.w);
2046 comi(rn(node->u.w), node->v.w);
2048 case jit_code_exti_c:
2049 exti_c(rn(node->u.w), node->v.w);
2051 case jit_code_exti_uc:
2052 exti_uc(rn(node->u.w), node->v.w);
2054 case jit_code_exti_s:
2055 exti_s(rn(node->u.w), node->v.w);
2057 case jit_code_exti_us:
2058 exti_us(rn(node->u.w), node->v.w);
2060 case jit_code_bswapi_us:
2061 bswapi_us(rn(node->u.w), node->v.w);
2063 case jit_code_bswapi_ui:
2064 bswapi_ui(rn(node->u.w), node->v.w);
2066 case jit_code_htoni_us:
2067 htoni_us(rn(node->u.w), node->v.w);
2069 case jit_code_htoni_ui:
2070 htoni_ui(rn(node->u.w), node->v.w);
2072 #if __WORDSIZE == 64
2073 case jit_code_exti_i:
2074 exti_i(rn(node->u.w), node->v.w);
2076 case jit_code_exti_ui:
2077 exti_ui(rn(node->u.w), node->v.w);
2079 case jit_code_bswapi_ul:
2080 bswapi_ul(rn(node->u.w), node->v.w);
2082 case jit_code_htoni_ul:
2083 htoni_ul(rn(node->u.w), node->v.w);
2087 cloi(rn(node->u.w), node->v.w);
2090 clzi(rn(node->u.w), node->v.w);
2093 ctoi(rn(node->u.w), node->v.w);
2096 ctzi(rn(node->u.w), node->v.w);
2098 case jit_code_rbiti:
2099 rbiti(rn(node->u.w), node->v.w);
2101 case jit_code_popcnti:
2102 popcnti(rn(node->u.w), node->v.w);
2105 exti(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
2107 case jit_code_exti_u:
2108 exti_u(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
2113 jit_regarg_clr(node, value);
2114 assert(_jitc->regarg == 0 && _jitc->synth == 0);
2115 /* update register live state */
2127 for (offset = 0; offset < _jitc->patches.offset; offset++) {
2128 node = _jitc->patches.ptr[offset].node;
2129 word = _jitc->patches.ptr[offset].inst;
2130 value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
2131 patch_at(word, value);
2134 jit_flush(_jit->code.ptr, _jit->pc.uc);
2136 return (_jit->code.ptr);
2140 # include "jit_aarch64-cpu.c"
2141 # include "jit_aarch64-fpu.c"
2145 jit_flush(void *fptr, void *tptr)
2147 #if defined(__GNUC__)
2150 s = sysconf(_SC_PAGE_SIZE);
2151 f = (jit_word_t)fptr & -s;
2152 t = (((jit_word_t)tptr) + s - 1) & -s;
2153 __clear_cache((void *)f, (void *)t);
2158 _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2160 ldxi(rn(r0), rn(r1), i0);
2164 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2166 stxi(i0, rn(r0), rn(r1));
2170 _emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2172 ldxi_d(rn(r0), rn(r1), i0);
2176 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2178 stxi_d(i0, rn(r0), rn(r1));
2182 _compute_framesize(jit_state_t *_jit)
2185 _jitc->framesize = 16; /* ra+fp */
2186 for (reg = 0; reg < jit_size(iregs); reg++)
2187 if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg]))
2188 _jitc->framesize += sizeof(jit_word_t);
2190 for (reg = 0; reg < jit_size(fregs); reg++)
2191 if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg]))
2192 _jitc->framesize += sizeof(jit_float64_t);
2194 /* Make sure functions called have a 16 byte aligned stack */
2195 _jitc->framesize = (_jitc->framesize + 15) & -16;
2199 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
2203 assert(node->flag & jit_flag_node);
2204 if (node->code == jit_code_movi)
2205 flag = node->v.n->flag;
2207 flag = node->u.n->flag;
2208 assert(!(flag & jit_flag_patch));
2209 if (_jitc->patches.offset >= _jitc->patches.length) {
2210 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
2211 _jitc->patches.length * sizeof(jit_patch_t),
2212 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
2213 _jitc->patches.length += 1024;
2215 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
2216 _jitc->patches.ptr[_jitc->patches.offset].node = node;
2217 ++_jitc->patches.offset;