2 * Copyright (C) 2019-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 /* callee save + variadic arguments
21 * align16(ra+fp+s[1-9]+s10+s11+fs[0-9]+fs10+fs11)+align16(a[0-7]) */
22 #define stack_framesize (208 + 64)
24 #define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8)
25 #define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8)
30 typedef jit_pointer_t jit_va_list_t;
35 #define compute_framesize() _compute_framesize(_jit)
36 static void _compute_framesize(jit_state_t*);
38 # define load_const(r0, i0) _load_const(_jit, r0, i0)
39 static void _load_const(jit_state_t*, jit_int32_t, jit_word_t);
40 static jit_word_t hash_const(jit_word_t);
41 # define put_const(i0) _put_const(_jit, i0)
42 static void _put_const(jit_state_t*, jit_word_t);
43 # define get_const(i0) _get_const(_jit, i0)
44 static jit_word_t _get_const(jit_state_t*, jit_word_t);
46 #define patch(instr, node) _patch(_jit, instr, node)
47 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
50 # include "jit_riscv-cpu.c"
51 # include "jit_riscv-fpu.c"
52 # include "jit_fallback.c"
59 jit_register_t _rvs[] = {
64 #if 0 /* Pretend it does not exist, so _NOREG can be used in
68 { rc(gpr) | 0x05, "t0" },
69 { rc(gpr) | 0x06, "t1" },
70 { rc(gpr) | 0x07, "t2" },
71 { rc(gpr) | 0x1c, "t3" },
72 { rc(gpr) | 0x1d, "t4" },
73 { rc(gpr) | 0x1e, "t5" },
74 { rc(gpr) | 0x1f, "t6" },
76 { rc(sav) | rc(gpr) | 0x09, "s1" },
77 { rc(sav) | rc(gpr) | 0x12, "s2" },
78 { rc(sav) | rc(gpr) | 0x13, "s3" },
79 { rc(sav) | rc(gpr) | 0x14, "s4" },
80 { rc(sav) | rc(gpr) | 0x15, "s5" },
81 { rc(sav) | rc(gpr) | 0x16, "s6" },
82 { rc(sav) | rc(gpr) | 0x17, "s7" },
83 { rc(sav) | rc(gpr) | 0x18, "s8" },
84 { rc(sav) | rc(gpr) | 0x19, "s9" },
85 { rc(sav) | rc(gpr) | 0x1a, "s10" },
86 { rc(sav) | rc(gpr) | 0x1b, "s11" },
87 { rc(arg) | rc(gpr) | 0x11, "a7" },
88 { rc(arg) | rc(gpr) | 0x10, "a6" },
89 { rc(arg) | rc(gpr) | 0x0f, "a5" },
90 { rc(arg) | rc(gpr) | 0x0e, "a4" },
91 { rc(arg) | rc(gpr) | 0x0d, "a3" },
92 { rc(arg) | rc(gpr) | 0x0c, "a2" },
93 { rc(arg) | rc(gpr) | 0x0b, "a1" },
94 { rc(arg) | rc(gpr) | 0x0a, "a0" },
95 { rc(fpr) | 0x00, "ft0" },
96 { rc(fpr) | 0x01, "ft1" },
97 { rc(fpr) | 0x02, "ft2" },
98 { rc(fpr) | 0x03, "ft3" },
99 { rc(fpr) | 0x04, "ft4" },
100 { rc(fpr) | 0x05, "ft5" },
101 { rc(fpr) | 0x06, "ft6" },
102 { rc(fpr) | 0x07, "ft7" },
103 { rc(fpr) | 0x1c, "ft8" },
104 { rc(fpr) | 0x1d, "ft9" },
105 { rc(fpr) | 0x1e, "ft10" },
106 { rc(fpr) | 0x1f, "ft11" },
107 { rc(sav) | rc(fpr) | 0x08, "fs0" },
108 { rc(sav) | rc(fpr) | 0x09, "fs1" },
109 { rc(sav) | rc(fpr) | 0x12, "fs2" },
110 { rc(sav) | rc(fpr) | 0x13, "fs3" },
111 { rc(sav) | rc(fpr) | 0x14, "fs4" },
112 { rc(sav) | rc(fpr) | 0x15, "fs5" },
113 { rc(sav) | rc(fpr) | 0x16, "fs6" },
114 { rc(sav) | rc(fpr) | 0x17, "fs7" },
115 { rc(sav) | rc(fpr) | 0x18, "fs8" },
116 { rc(sav) | rc(fpr) | 0x19, "fs9" },
117 { rc(sav) | rc(fpr) | 0x1a, "fs10" },
118 { rc(sav) | rc(fpr) | 0x1b, "fs11" },
119 { rc(arg) | rc(fpr) | 0x11, "fa7" },
120 { rc(arg) | rc(fpr) | 0x10, "fa6" },
121 { rc(arg) | rc(fpr) | 0x0f, "fa5" },
122 { rc(arg) | rc(fpr) | 0x0e, "fa4" },
123 { rc(arg) | rc(fpr) | 0x0d, "fa3" },
124 { rc(arg) | rc(fpr) | 0x0c, "fa2" },
125 { rc(arg) | rc(fpr) | 0x0b, "fa1" },
126 { rc(arg) | rc(fpr) | 0x0a, "fa0" },
127 { _NOREG, "<none>" },
130 static jit_int32_t iregs[] = {
131 _S1, _S2, _S3, _S4, _S5, _S6, _S7, _S8, _S9, _S10, _S11
134 static jit_int32_t fregs[] = {
135 _FS0, _FS1, _FS2, _FS3, _FS4, _FS5, _FS6, _FS7, _FS8, _FS9, _FS10, _FS11
144 /* By default generate extra instructions for unaligned load/store. */
145 jit_cpu.unaligned = 0;
149 _jit_init(jit_state_t *_jit)
151 _jitc->reglen = jit_size(_rvs) - 1;
156 _jit_prolog(jit_state_t *_jit)
162 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
163 jit_regset_set_ui(&_jitc->regsav, 0);
164 offset = _jitc->functions.offset;
165 if (offset >= _jitc->functions.length) {
166 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
167 _jitc->functions.length * sizeof(jit_function_t),
168 (_jitc->functions.length + 16) * sizeof(jit_function_t));
169 _jitc->functions.length += 16;
171 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
172 _jitc->function->self.size = stack_framesize;
173 _jitc->function->self.argi = _jitc->function->self.argf =
174 _jitc->function->self.alen = 0;
175 _jitc->function->self.aoff = 0;
176 _jitc->function->self.call = jit_call_default;
177 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
178 _jitc->reglen * sizeof(jit_int32_t));
180 /* _no_link here does not mean the jit_link() call can be removed
182 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
184 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
185 jit_link(_jitc->function->prolog);
186 _jitc->function->prolog->w.w = offset;
187 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
189 * v: offset in blocks vector
190 * w: offset in functions vector
192 _jitc->function->epilog->w.w = offset;
194 jit_regset_new(&_jitc->function->regset);
198 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
200 assert(_jitc->function);
203 case 0: case 1: break;
204 case 2: _jitc->function->self.aoff &= -2; break;
205 case 3: case 4: _jitc->function->self.aoff &= -4; break;
206 default: _jitc->function->self.aoff &= -8; break;
208 _jitc->function->self.aoff -= length;
209 if (!_jitc->realize) {
210 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
213 return (_jitc->function->self.aoff);
217 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
220 assert(_jitc->function);
221 jit_inc_synth_ww(allocar, u, v);
222 if (!_jitc->function->allocar) {
223 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
224 _jitc->function->allocar = 1;
226 r0 = jit_get_reg(jit_class_gpr);
228 jit_andi(r0, r0, -16);
229 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
231 jit_addr(JIT_SP, JIT_SP, r0);
232 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
238 _jit_ret(jit_state_t *_jit)
241 assert(_jitc->function);
245 jit_patch_at(instr, _jitc->function->epilog);
250 _jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
252 jit_code_inc_synth_w(code, u);
253 jit_movr(JIT_RET, u);
259 _jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
261 jit_code_inc_synth_w(code, u);
262 jit_movi(JIT_RET, u);
268 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
270 jit_inc_synth_w(retr_f, u);
272 jit_movr_f(JIT_FRET, u);
280 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
282 jit_inc_synth_f(reti_f, u);
283 jit_movi_f(JIT_FRET, u);
289 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
291 jit_inc_synth_w(retr_d, u);
293 jit_movr_d(JIT_FRET, u);
301 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
303 jit_inc_synth_d(reti_d, u);
304 jit_movi_d(JIT_FRET, u);
310 _jit_epilog(jit_state_t *_jit)
312 assert(_jitc->function);
313 assert(_jitc->function->epilog->next == NULL);
314 jit_link(_jitc->function->epilog);
315 _jitc->function = NULL;
319 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
321 if (u->code >= jit_code_arg_c && u->code <= jit_code_arg)
322 return (jit_arg_reg_p(u->u.w));
323 assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
324 return (jit_arg_f_reg_p(u->u.w) || jit_arg_reg_p(u->u.w - 8));
328 _jit_ellipsis(jit_state_t *_jit)
330 jit_inc_synth(ellipsis);
332 if (_jitc->prepare) {
334 assert(!(_jitc->function->call.call & jit_call_varargs));
335 _jitc->function->call.call |= jit_call_varargs;
339 assert(!(_jitc->function->self.call & jit_call_varargs));
340 _jitc->function->self.call |= jit_call_varargs;
341 _jitc->function->vagp = _jitc->function->self.argi;
347 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
349 jit_inc_synth_w(va_push, u);
355 _jit_arg(jit_state_t *_jit, jit_code_t code)
359 assert(_jitc->function);
360 assert(!(_jitc->function->self.call & jit_call_varargs));
361 #if STRONG_TYPE_CHECKING
362 assert(code >= jit_code_arg_c && code <= jit_code_arg);
364 if (jit_arg_reg_p(_jitc->function->self.argi))
365 offset = _jitc->function->self.argi++;
367 offset = _jitc->function->self.size;
368 _jitc->function->self.size += sizeof(jit_word_t);
371 node = jit_new_node_ww(code, offset,
372 ++_jitc->function->self.argn);
378 _jit_arg_f(jit_state_t *_jit)
382 assert(_jitc->function);
383 assert(!(_jitc->function->self.call & jit_call_varargs));
384 if (jit_arg_f_reg_p(_jitc->function->self.argf))
385 offset = _jitc->function->self.argf++;
386 else if (jit_arg_reg_p(_jitc->function->self.argi)) {
387 offset = _jitc->function->self.argi++;
391 offset = _jitc->function->self.size;
392 _jitc->function->self.size += sizeof(jit_word_t);
395 node = jit_new_node_ww(jit_code_arg_f, offset,
396 ++_jitc->function->self.argn);
402 _jit_arg_d(jit_state_t *_jit)
406 assert(_jitc->function);
407 assert(!(_jitc->function->self.call & jit_call_varargs));
408 if (jit_arg_f_reg_p(_jitc->function->self.argf))
409 offset = _jitc->function->self.argf++;
410 else if (jit_arg_reg_p(_jitc->function->self.argi)) {
411 offset = _jitc->function->self.argi++;
415 offset = _jitc->function->self.size;
416 _jitc->function->self.size += sizeof(jit_word_t);
419 node = jit_new_node_ww(jit_code_arg_d, offset,
420 ++_jitc->function->self.argn);
426 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
428 assert_arg_type(v->code, jit_code_arg_c);
429 jit_inc_synth_wp(getarg_c, u, v);
430 if (jit_arg_reg_p(v->u.w))
431 jit_extr_c(u, JIT_RA0 - v->u.w);
433 jit_node_t *node = jit_ldxi_c(u, JIT_FP, v->u.w);
434 jit_link_alist(node);
440 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
442 assert_arg_type(v->code, jit_code_arg_c);
443 jit_inc_synth_wp(getarg_uc, u, v);
444 if (jit_arg_reg_p(v->u.w))
445 jit_extr_uc(u, JIT_RA0 - v->u.w);
447 jit_node_t *node = jit_ldxi_uc(u, JIT_FP, v->u.w);
448 jit_link_alist(node);
454 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
456 assert_arg_type(v->code, jit_code_arg_s);
457 jit_inc_synth_wp(getarg_s, u, v);
458 if (jit_arg_reg_p(v->u.w))
459 jit_extr_s(u, JIT_RA0 - v->u.w);
461 jit_node_t *node = jit_ldxi_s(u, JIT_FP, v->u.w);
462 jit_link_alist(node);
468 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
470 assert_arg_type(v->code, jit_code_arg_s);
471 jit_inc_synth_wp(getarg_us, u, v);
472 if (jit_arg_reg_p(v->u.w))
473 jit_extr_us(u, JIT_RA0 - v->u.w);
475 jit_node_t *node = jit_ldxi_us(u, JIT_FP, v->u.w);
476 jit_link_alist(node);
482 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
484 assert_arg_type(v->code, jit_code_arg_i);
485 jit_inc_synth_wp(getarg_i, u, v);
486 if (jit_arg_reg_p(v->u.w))
487 jit_extr_i(u, JIT_RA0 - v->u.w);
489 jit_node_t *node = jit_ldxi_i(u, JIT_FP, v->u.w);
490 jit_link_alist(node);
496 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
498 assert_arg_type(v->code, jit_code_arg_i);
499 jit_inc_synth_wp(getarg_ui, u, v);
500 if (jit_arg_reg_p(v->u.w))
501 jit_extr_ui(u, JIT_RA0 - v->u.w);
503 jit_node_t *node = jit_ldxi_ui(u, JIT_FP, v->u.w);
504 jit_link_alist(node);
510 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
512 assert_arg_type(v->code, jit_code_arg_l);
513 jit_inc_synth_wp(getarg_l, u, v);
514 if (jit_arg_reg_p(v->u.w))
515 jit_movr(u, JIT_RA0 - v->u.w);
517 jit_node_t *node = jit_ldxi_l(u, JIT_FP, v->u.w);
518 jit_link_alist(node);
524 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
526 assert_putarg_type(code, v->code);
527 jit_code_inc_synth_wp(code, u, v);
528 if (jit_arg_reg_p(v->u.w))
529 jit_movr(JIT_RA0 - v->u.w, u);
531 jit_node_t *node = jit_stxi(v->u.w, JIT_FP, u);
532 jit_link_alist(node);
538 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
541 assert_putarg_type(code, v->code);
542 jit_code_inc_synth_wp(code, u, v);
543 if (jit_arg_reg_p(v->u.w))
544 jit_movi(JIT_RA0 - v->u.w, u);
547 regno = jit_get_reg(jit_class_gpr);
549 node = jit_stxi(v->u.w, JIT_FP, regno);
550 jit_link_alist(node);
551 jit_unget_reg(regno);
557 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
559 assert(v->code == jit_code_arg_f);
560 jit_inc_synth_wp(getarg_f, u, v);
561 if (jit_arg_f_reg_p(v->u.w))
562 jit_movr_f(u, JIT_FA0 - v->u.w);
563 else if (jit_arg_reg_p(v->u.w - 8))
564 jit_movr_w_f(u, JIT_RA0 - (v->u.w - 8));
566 jit_node_t *node = jit_ldxi_f(u, JIT_FP, v->u.w);
567 jit_link_alist(node);
573 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
575 assert(v->code == jit_code_arg_f);
576 jit_inc_synth_wp(putargr_f, u, v);
577 if (jit_arg_f_reg_p(v->u.w))
578 jit_movr_f(JIT_FA0 - v->u.w, u);
579 else if (jit_arg_reg_p(v->u.w - 8))
580 jit_movr_f_w(JIT_RA0 - (v->u.w - 8), u);
582 jit_node_t *node = jit_stxi_f(v->u.w, JIT_FP, u);
583 jit_link_alist(node);
589 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
592 assert(v->code == jit_code_arg_f);
593 jit_inc_synth_fp(putargi_f, u, v);
594 if (jit_arg_f_reg_p(v->u.w))
595 jit_movi_f(JIT_FA0 - v->u.w, u);
596 else if (jit_arg_reg_p(v->u.w - 8))
597 jit_movi_f_w(JIT_RA0 - (v->u.w - 8), u);
600 regno = jit_get_reg(jit_class_fpr);
601 jit_movi_f(regno, u);
602 node = jit_stxi_f(v->u.w, JIT_FP, regno);
603 jit_link_alist(node);
604 jit_unget_reg(regno);
610 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
612 assert(v->code == jit_code_arg_d);
613 jit_inc_synth_wp(getarg_d, u, v);
614 if (jit_arg_f_reg_p(v->u.w))
615 jit_movr_d(u, JIT_FA0 - v->u.w);
616 else if (jit_arg_reg_p(v->u.w - 8))
617 jit_movr_w_d(u, JIT_RA0 - (v->u.w - 8));
619 jit_node_t *node = jit_ldxi_d(u, JIT_FP, v->u.w);
620 jit_link_alist(node);
626 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
628 assert(v->code == jit_code_arg_d);
629 jit_inc_synth_wp(putargr_d, u, v);
630 if (jit_arg_reg_p(v->u.w))
631 jit_movr_d(JIT_FA0 - v->u.w, u);
632 else if (jit_arg_reg_p(v->u.w - 8))
633 jit_movr_d_w(JIT_RA0 - (v->u.w - 8), u);
635 jit_node_t *node = jit_stxi_d(v->u.w, JIT_FP, u);
636 jit_link_alist(node);
642 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
645 assert(v->code == jit_code_arg_d);
646 jit_inc_synth_dp(putargi_d, u, v);
647 if (jit_arg_reg_p(v->u.w))
648 jit_movi_d(JIT_FA0 - v->u.w, u);
649 else if (jit_arg_reg_p(v->u.w - 8))
650 jit_movi_d_w(JIT_RA0 - (v->u.w - 8), u);
653 regno = jit_get_reg(jit_class_fpr);
654 jit_movi_d(regno, u);
655 node = jit_stxi_d(v->u.w, JIT_FP, regno);
656 jit_link_alist(node);
657 jit_unget_reg(regno);
663 _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
665 assert(_jitc->function);
666 jit_code_inc_synth_w(code, u);
668 if (jit_arg_reg_p(_jitc->function->call.argi)) {
669 jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
670 ++_jitc->function->call.argi;
673 jit_stxi(_jitc->function->call.size, JIT_SP, u);
674 _jitc->function->call.size += sizeof(jit_word_t);
681 _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
684 assert(_jitc->function);
685 jit_code_inc_synth_w(code, u);
687 if (jit_arg_reg_p(_jitc->function->call.argi)) {
688 jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
689 ++_jitc->function->call.argi;
692 regno = jit_get_reg(jit_class_gpr);
694 jit_stxi(_jitc->function->call.size, JIT_SP, regno);
695 jit_unget_reg(regno);
696 _jitc->function->call.size += sizeof(jit_word_t);
703 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
705 assert(_jitc->function);
706 jit_inc_synth_w(pushargr_f, u);
708 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
709 !(_jitc->function->call.call & jit_call_varargs)) {
710 jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u);
711 ++_jitc->function->call.argf;
713 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
714 jit_movr_f_w(JIT_RA0 - _jitc->function->call.argi, u);
715 ++_jitc->function->call.argi;
718 jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
719 _jitc->function->call.size += sizeof(jit_word_t);
726 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
729 assert(_jitc->function);
730 jit_inc_synth_f(pushargi_f, u);
732 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
733 !(_jitc->function->call.call & jit_call_varargs)) {
734 jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u);
735 ++_jitc->function->call.argf;
737 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
738 jit_movi_f_w(JIT_RA0 - _jitc->function->call.argi, u);
739 ++_jitc->function->call.argi;
742 regno = jit_get_reg(jit_class_fpr);
743 jit_movi_f(regno, u);
744 jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
745 jit_unget_reg(regno);
746 _jitc->function->call.size += sizeof(jit_word_t);
753 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
755 assert(_jitc->function);
756 jit_inc_synth_w(pushargr_d, u);
758 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
759 !(_jitc->function->call.call & jit_call_varargs)) {
760 jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
761 ++_jitc->function->call.argf;
763 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
764 jit_movr_d_w(JIT_RA0 - _jitc->function->call.argi, u);
765 ++_jitc->function->call.argi;
768 jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
769 _jitc->function->call.size += sizeof(jit_word_t);
776 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
779 assert(_jitc->function);
780 jit_inc_synth_d(pushargi_d, u);
782 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
783 !(_jitc->function->call.call & jit_call_varargs)) {
784 jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
785 ++_jitc->function->call.argf;
787 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
788 jit_movi_d_w(JIT_RA0 - _jitc->function->call.argi, u);
789 ++_jitc->function->call.argi;
792 regno = jit_get_reg(jit_class_fpr);
793 jit_movi_d(regno, u);
794 jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
795 jit_unget_reg(regno);
796 _jitc->function->call.size += sizeof(jit_word_t);
803 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
806 spec = jit_class(_rvs[regno].spec);
807 if (spec & jit_class_arg) {
808 regno = JIT_RA0 - regno;
809 if (regno >= 0 && regno < node->v.w)
811 if (spec & jit_class_fpr) {
812 regno = JIT_FA0 - regno;
813 if (regno >= 0 && regno < node->w.w)
822 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
825 assert(_jitc->function);
827 jit_inc_synth_w(finishr, r0);
828 if (_jitc->function->self.alen < _jitc->function->call.size)
829 _jitc->function->self.alen = _jitc->function->call.size;
830 node = jit_callr(r0);
831 node->v.w = _jitc->function->self.argi;
832 node->w.w = _jitc->function->call.argf;
833 _jitc->function->call.argi = _jitc->function->call.argf =
834 _jitc->function->call.size = 0;
840 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
843 assert(_jitc->function);
845 jit_inc_synth_w(finishi, (jit_word_t)i0);
846 if (_jitc->function->self.alen < _jitc->function->call.size)
847 _jitc->function->self.alen = _jitc->function->call.size;
848 node = jit_calli(i0);
849 node->v.w = _jitc->function->call.argi;
850 node->w.w = _jitc->function->call.argf;
851 _jitc->function->call.argi = _jitc->function->call.argf =
852 _jitc->function->call.size = 0;
859 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
861 jit_inc_synth_w(retval_c, r0);
862 jit_extr_c(r0, JIT_RET);
867 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
869 jit_inc_synth_w(retval_uc, r0);
870 jit_extr_uc(r0, JIT_RET);
875 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
877 jit_inc_synth_w(retval_s, r0);
878 jit_extr_s(r0, JIT_RET);
883 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
885 jit_inc_synth_w(retval_us, r0);
886 jit_extr_us(r0, JIT_RET);
891 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
893 jit_inc_synth_w(retval_i, r0);
894 jit_extr_i(r0, JIT_RET);
899 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
901 jit_inc_synth_w(retval_ui, r0);
902 jit_extr_ui(r0, JIT_RET);
907 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
909 jit_inc_synth_w(retval_l, r0);
911 jit_movr(r0, JIT_RET);
916 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
918 jit_inc_synth_w(retval_f, r0);
920 jit_movr_f(r0, JIT_FRET);
925 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
927 jit_inc_synth_w(retval_d, r0);
929 jit_movr_d(r0, JIT_FRET);
934 _emit_code(jit_state_t *_jit)
946 #if DEVEL_DISASSEMBLER
949 jit_int32_t const_offset;
950 jit_int32_t patch_offset;
952 #if DEVEL_DISASSEMBLER
957 if (!_jitc->consts.hash.table) {
958 jit_alloc((jit_pointer_t *)&_jitc->consts.hash.table,
959 16 * sizeof(jit_const_t *));
960 _jitc->consts.hash.size = 16;
961 jit_alloc((jit_pointer_t *)&_jitc->consts.pool.ptr,
962 sizeof(jit_const_t *));
963 jit_alloc((jit_pointer_t *)_jitc->consts.pool.ptr,
964 1024 * sizeof(jit_const_t));
965 _jitc->consts.pool.length = 1;
967 /* Reset table if starting over jit generation */
969 memset(_jitc->consts.hash.table, 0,
970 _jitc->consts.hash.size * sizeof(jit_word_t));
971 for (offset = 0; offset < _jitc->consts.pool.length; offset++) {
973 jit_const_t *list = _jitc->consts.pool.ptr[offset];
974 for (i = 0; i < 1023; ++i, ++list)
975 list->next = list + 1;
976 if (offset + 1 < _jitc->consts.pool.length)
977 list->next = _jitc->consts.pool.ptr[offset + 1];
981 _jitc->consts.pool.list = _jitc->consts.pool.ptr[0];
982 _jitc->consts.hash.count = 0;
983 if (!_jitc->consts.vector.instrs) {
984 jit_alloc((jit_pointer_t *)&_jitc->consts.vector.instrs,
985 16 * sizeof(jit_word_t));
986 jit_alloc((jit_pointer_t *)&_jitc->consts.vector.values,
987 16 * sizeof(jit_word_t));
988 _jitc->consts.vector.length = 16;
990 _jitc->consts.vector.offset = 0;
993 _jitc->function = NULL;
999 undo.const_offset = undo.patch_offset = 0;
1000 # define assert_data(node) /**/
1001 #define case_rr(name, type) \
1002 case jit_code_##name##r##type: \
1003 name##r##type(rn(node->u.w), rn(node->v.w)); \
1005 #define case_rw(name, type) \
1006 case jit_code_##name##i##type: \
1007 name##i##type(rn(node->u.w), node->v.w); \
1009 #define case_wr(name, type) \
1010 case jit_code_##name##i##type: \
1011 name##i##type(node->u.w, rn(node->v.w)); \
1013 #define case_rrr(name, type) \
1014 case jit_code_##name##r##type: \
1015 name##r##type(rn(node->u.w), \
1016 rn(node->v.w), rn(node->w.w)); \
1018 #define case_rrrr(name, type) \
1019 case jit_code_##name##r##type: \
1020 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
1021 rn(node->v.w), rn(node->w.w)); \
1023 #define case_rqr(name, type) \
1024 case jit_code_##name##r##type: \
1025 name##r##type(rn(node->u.w), rn(node->v.q.l), \
1026 rn(node->v.q.h), rn(node->w.w)); \
1027 case jit_code_##name##i##type: \
1029 #define case_rrw(name, type) \
1030 case jit_code_##name##i##type: \
1031 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
1033 #define case_rrrw(name, type) \
1034 case jit_code_##name##i##type: \
1035 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
1036 rn(node->v.w), node->w.w); \
1038 #define case_rrf(name) \
1039 case jit_code_##name##i_f: \
1040 assert_data(node); \
1041 name##i_f(rn(node->u.w), rn(node->v.w), node->w.f); \
1043 #define case_rrd(name) \
1044 case jit_code_##name##i_d: \
1045 assert_data(node); \
1046 name##i_d(rn(node->u.w), rn(node->v.w), node->w.d); \
1048 #define case_wrr(name, type) \
1049 case jit_code_##name##i##type: \
1050 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1052 #define case_brr(name, type) \
1053 case jit_code_##name##r##type: \
1055 assert(temp->code == jit_code_label || \
1056 temp->code == jit_code_epilog); \
1057 if (temp->flag & jit_flag_patch) \
1058 name##r##type(temp->u.w, rn(node->v.w), \
1061 word = name##r##type(_jit->pc.w, \
1062 rn(node->v.w), rn(node->w.w)); \
1063 patch(word, node); \
1066 #define case_brw(name, type) \
1067 case jit_code_##name##i##type: \
1069 assert(temp->code == jit_code_label || \
1070 temp->code == jit_code_epilog); \
1071 if (temp->flag & jit_flag_patch) \
1072 name##i##type(temp->u.w, \
1073 rn(node->v.w), node->w.w); \
1075 word = name##i##type(_jit->pc.w, \
1076 rn(node->v.w), node->w.w); \
1077 patch(word, node); \
1080 #define case_brf(name) \
1081 case jit_code_##name##i_f: \
1083 assert(temp->code == jit_code_label || \
1084 temp->code == jit_code_epilog); \
1085 if (temp->flag & jit_flag_patch) \
1086 name##i_f(temp->u.w, rn(node->v.w), node->w.f); \
1088 word = name##i_f(_jit->pc.w, rn(node->v.w), \
1090 patch(word, node); \
1093 #define case_brd(name) \
1094 case jit_code_##name##i_d: \
1096 assert(temp->code == jit_code_label || \
1097 temp->code == jit_code_epilog); \
1098 if (temp->flag & jit_flag_patch) \
1099 name##i_d(temp->u.w, rn(node->v.w), node->w.d); \
1101 word = name##i_d(_jit->pc.w, rn(node->v.w), \
1103 patch(word, node); \
1106 #if DEVEL_DISASSEMBLER
1109 for (node = _jitc->head; node; node = node->next) {
1110 if (_jit->pc.uc >= _jitc->code.end)
1113 #if DEVEL_DISASSEMBLER
1114 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1117 value = jit_classify(node->code);
1118 jit_regarg_set(node, value);
1119 switch (node->code) {
1120 case jit_code_align:
1121 /* Must align to a power of two */
1122 assert(!(node->u.w & (node->u.w - 1)));
1123 if ((word = _jit->pc.w & (node->u.w - 1)))
1124 nop(node->u.w - word);
1127 nop((node->u.w + 3) & ~3);
1129 case jit_code_note: case jit_code_name:
1130 node->u.w = _jit->pc.w;
1132 case jit_code_label:
1133 /* remember label is defined */
1134 node->flag |= jit_flag_patch;
1135 node->u.w = _jit->pc.w;
1158 case_rrrr(qmul, _u);
1159 case_rrrw(qmul, _u);
1166 case_rrrr(qdiv, _u);
1167 case_rrrw(qdiv, _u);
1176 #define qlshr(r0, r1, r2, r3) fallback_qlshr(r0, r1, r2, r3)
1177 #define qlshi(r0, r1, r2, i0) fallback_qlshi(r0, r1, r2, i0)
1178 #define qlshr_u(r0, r1, r2, r3) fallback_qlshr_u(r0, r1, r2, r3)
1179 #define qlshi_u(r0, r1, r2, i0) fallback_qlshi_u(r0, r1, r2, i0)
1182 case_rrrr(qlsh, _u);
1183 case_rrrw(qlsh, _u);
1186 #define qrshr(r0, r1, r2, r3) fallback_qrshr(r0, r1, r2, r3)
1187 #define qrshi(r0, r1, r2, i0) fallback_qrshi(r0, r1, r2, i0)
1188 #define qrshr_u(r0, r1, r2, r3) fallback_qrshr_u(r0, r1, r2, r3)
1189 #define qrshi_u(r0, r1, r2, i0) fallback_qrshi_u(r0, r1, r2, i0)
1192 case_rrrr(qrsh, _u);
1193 case_rrrw(qrsh, _u);
1194 #define lrotr(r0,r1,r2) fallback_lrotr(r0,r1,r2)
1195 #define lroti(r0,r1,i0) fallback_lroti(r0,r1,i0)
1196 #define rrotr(r0,r1,r2) fallback_rrotr(r0,r1,r2)
1197 #define rroti(r0,r1,i0) fallback_rroti(r0,r1,i0)
1204 #define clor(r0, r1) fallback_clo(r0, r1)
1205 #define clzr(r0, r1) fallback_clz(r0, r1)
1206 #define ctor(r0, r1) fallback_cto(r0, r1)
1207 #define ctzr(r0, r1) fallback_ctz(r0, r1)
1208 #define rbitr(r0, r1) fallback_rbit(r0, r1)
1209 #define popcntr(r0, r1) fallback_popcnt(r0, r1)
1222 case_rr(trunc, _f_i);
1223 case_rr(trunc, _d_i);
1224 case_rr(trunc, _f_l);
1225 case_rr(trunc, _d_l);
1254 case jit_code_unldr:
1255 unldr(rn(node->u.w), rn(node->v.w), node->w.w);
1257 case jit_code_unldi:
1258 unldi(rn(node->u.w), node->v.w, node->w.w);
1260 case jit_code_unldr_u:
1261 unldr_u(rn(node->u.w), rn(node->v.w), node->w.w);
1263 case jit_code_unldi_u:
1264 unldi_u(rn(node->u.w), node->v.w, node->w.w);
1282 case jit_code_unstr:
1283 unstr(rn(node->u.w), rn(node->v.w), node->w.w);
1285 case jit_code_unsti:
1286 unsti(node->u.w, rn(node->v.w), node->w.w);
1291 case_rr(bswap, _us);
1292 case_rr(bswap, _ui);
1293 case_rr(bswap, _ul);
1294 #define extr(r0, r1, i0, i1) fallback_ext(r0, r1, i0, i1)
1295 #define extr_u(r0, r1, i0, i1) fallback_ext_u(r0, r1, i0, i1)
1296 #define depr(r0, r1, i0, i1) fallback_dep(r0, r1, i0, i1)
1298 extr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1300 case jit_code_extr_u:
1301 extr_u(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1304 depr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1307 depi(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1316 casr(rn(node->u.w), rn(node->v.w),
1317 rn(node->w.q.l), rn(node->w.q.h));
1320 casi(rn(node->u.w), node->v.w,
1321 rn(node->w.q.l), rn(node->w.q.h));
1327 if (node->flag & jit_flag_node) {
1329 if (temp->code == jit_code_data ||
1330 (temp->code == jit_code_label &&
1331 (temp->flag & jit_flag_patch)))
1332 movi(rn(node->u.w), temp->u.w);
1334 assert(temp->code == jit_code_label ||
1335 temp->code == jit_code_epilog);
1336 word = movi_p(rn(node->u.w), temp->u.w);
1341 movi(rn(node->u.w), node->v.w);
1385 case_brr(boadd, _u);
1386 case_brw(boadd, _u);
1389 case_brr(bxadd, _u);
1390 case_brw(bxadd, _u);
1393 case_brr(bosub, _u);
1394 case_brw(bosub, _u);
1397 case_brr(bxsub, _u);
1398 case_brw(bxsub, _u);
1424 case jit_code_unldr_x:
1425 unldr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1427 case jit_code_unldi_x:
1428 unldi_x(rn(node->u.w), node->v.w, node->w.w);
1434 case jit_code_unstr_x:
1435 unstr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1437 case jit_code_unsti_x:
1438 unsti_x(node->u.w, rn(node->v.w), node->w.w);
1441 case jit_code_movi_f:
1443 movi_f(rn(node->u.w), node->v.f);
1472 case_rrr(unord, _f);
1486 case_brr(bunlt, _f);
1488 case_brr(bunle, _f);
1490 case_brr(buneq, _f);
1492 case_brr(bunge, _f);
1494 case_brr(bungt, _f);
1496 case_brr(bltgt, _f);
1500 case_brr(bunord, _f);
1528 case jit_code_movi_d:
1530 movi_d(rn(node->u.w), node->v.d);
1559 case_rrr(unord, _d);
1573 case_brr(bunlt, _d);
1575 case_brr(bunle, _d);
1577 case_brr(buneq, _d);
1579 case_brr(bunge, _d);
1581 case_brr(bungt, _d);
1583 case_brr(bltgt, _d);
1587 case_brr(bunord, _d);
1591 jmpr(rn(node->u.w));
1594 if (node->flag & jit_flag_node) {
1596 assert(temp->code == jit_code_label ||
1597 temp->code == jit_code_epilog);
1598 if (temp->flag & jit_flag_patch)
1601 word = _jit->code.length -
1602 (_jit->pc.uc - _jit->code.ptr);
1604 word = jmpi(_jit->pc.w);
1606 word = jmpi_p(_jit->pc.w);
1615 case jit_code_callr:
1617 callr(rn(node->u.w));
1619 case jit_code_calli:
1620 if (node->flag & jit_flag_node) {
1622 assert(temp->code == jit_code_label ||
1623 temp->code == jit_code_epilog);
1624 if (temp->flag & jit_flag_patch)
1627 word = _jit->code.length -
1628 (_jit->pc.uc - _jit->code.ptr);
1630 word = calli(_jit->pc.w);
1632 word = calli_p(_jit->pc.w);
1641 case jit_code_prolog:
1642 _jitc->function = _jitc->functions.ptr + node->w.w;
1644 undo.word = _jit->pc.w;
1645 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
1646 #if DEVEL_DISASSEMBLER
1649 undo.const_offset = _jitc->consts.vector.offset;
1650 undo.patch_offset = _jitc->patches.offset;
1652 compute_framesize();
1657 case jit_code_epilog:
1658 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1660 for (temp = undo.node->next;
1661 temp != node; temp = temp->next) {
1662 if (temp->code == jit_code_label ||
1663 temp->code == jit_code_epilog)
1664 temp->flag &= ~jit_flag_patch;
1666 temp->flag &= ~jit_flag_patch;
1668 _jit->pc.w = undo.word;
1669 /* undo.func.self.aoff and undo.func.regset should not
1670 * be undone, as they will be further updated, and are
1671 * the reason of the undo. */
1672 undo.func.self.aoff = _jitc->function->frame +
1673 _jitc->function->self.aoff;
1674 undo.func.need_frame = _jitc->function->need_frame;
1675 jit_regset_set(&undo.func.regset, &_jitc->function->regset);
1676 /* allocar information also does not need to be undone */
1677 undo.func.aoffoff = _jitc->function->aoffoff;
1678 undo.func.allocar = _jitc->function->allocar;
1679 /* this will be recomputed but undo anyway to have it
1680 * better self documented.*/
1681 undo.func.need_stack = _jitc->function->need_stack;
1682 memcpy(_jitc->function, &undo.func, sizeof(undo.func));
1683 #if DEVEL_DISASSEMBLER
1686 _jitc->patches.offset = undo.patch_offset;
1687 _jitc->consts.vector.offset = undo.const_offset;
1689 goto restart_function;
1691 /* remember label is defined */
1692 node->flag |= jit_flag_patch;
1693 node->u.w = _jit->pc.w;
1695 _jitc->function = NULL;
1697 case jit_code_movr_w_f:
1698 movr_w_f(rn(node->u.w), rn(node->v.w));
1700 case jit_code_movr_f_w:
1701 movr_f_w(rn(node->u.w), rn(node->v.w));
1703 case jit_code_movi_f_w:
1705 movi_f_w(rn(node->u.w), node->v.f);
1707 case jit_code_movi_w_f:
1708 movi_w_f(rn(node->u.w), node->v.w);
1710 case jit_code_movr_w_d:
1711 movr_w_d(rn(node->u.w), rn(node->v.w));
1713 case jit_code_movr_d_w:
1714 movr_d_w(rn(node->u.w), rn(node->v.w));
1716 case jit_code_movi_d_w:
1718 movi_d_w(rn(node->u.w), node->v.d);
1720 case jit_code_movi_w_d:
1721 movi_w_d(rn(node->u.w), node->v.w);
1723 case jit_code_va_start:
1724 vastart(rn(node->u.w));
1726 case jit_code_va_arg:
1727 vaarg(rn(node->u.w), rn(node->v.w));
1729 case jit_code_va_arg_d:
1730 vaarg_d(rn(node->u.w), rn(node->v.w));
1732 case jit_code_live: case jit_code_ellipsis:
1733 case jit_code_va_push:
1734 case jit_code_allocai: case jit_code_allocar:
1735 case jit_code_arg_c: case jit_code_arg_s:
1736 case jit_code_arg_i:
1737 case jit_code_arg_l:
1738 case jit_code_arg_f: case jit_code_arg_d:
1739 case jit_code_va_end:
1741 case jit_code_retr_c: case jit_code_reti_c:
1742 case jit_code_retr_uc: case jit_code_reti_uc:
1743 case jit_code_retr_s: case jit_code_reti_s:
1744 case jit_code_retr_us: case jit_code_reti_us:
1745 case jit_code_retr_i: case jit_code_reti_i:
1746 case jit_code_retr_ui: case jit_code_reti_ui:
1747 case jit_code_retr_l: case jit_code_reti_l:
1748 case jit_code_retr_f: case jit_code_reti_f:
1749 case jit_code_retr_d: case jit_code_reti_d:
1750 case jit_code_getarg_c: case jit_code_getarg_uc:
1751 case jit_code_getarg_s: case jit_code_getarg_us:
1752 case jit_code_getarg_i: case jit_code_getarg_ui:
1753 case jit_code_getarg_l:
1754 case jit_code_getarg_f: case jit_code_getarg_d:
1755 case jit_code_putargr_c: case jit_code_putargi_c:
1756 case jit_code_putargr_uc: case jit_code_putargi_uc:
1757 case jit_code_putargr_s: case jit_code_putargi_s:
1758 case jit_code_putargr_us: case jit_code_putargi_us:
1759 case jit_code_putargr_i: case jit_code_putargi_i:
1760 case jit_code_putargr_ui: case jit_code_putargi_ui:
1761 case jit_code_putargr_l: case jit_code_putargi_l:
1762 case jit_code_putargr_f: case jit_code_putargi_f:
1763 case jit_code_putargr_d: case jit_code_putargi_d:
1764 case jit_code_pushargr_c: case jit_code_pushargi_c:
1765 case jit_code_pushargr_uc: case jit_code_pushargi_uc:
1766 case jit_code_pushargr_s: case jit_code_pushargi_s:
1767 case jit_code_pushargr_us: case jit_code_pushargi_us:
1768 case jit_code_pushargr_i: case jit_code_pushargi_i:
1769 case jit_code_pushargr_ui: case jit_code_pushargi_ui:
1770 case jit_code_pushargr_l: case jit_code_pushargi_l:
1771 case jit_code_pushargr_f: case jit_code_pushargi_f:
1772 case jit_code_pushargr_d: case jit_code_pushargi_d:
1773 case jit_code_retval_c: case jit_code_retval_uc:
1774 case jit_code_retval_s: case jit_code_retval_us:
1775 case jit_code_retval_i:
1776 case jit_code_retval_ui: case jit_code_retval_l:
1777 case jit_code_retval_f: case jit_code_retval_d:
1778 case jit_code_prepare:
1779 case jit_code_finishr: case jit_code_finishi:
1780 case jit_code_negi_f: case jit_code_absi_f:
1781 case jit_code_sqrti_f: case jit_code_negi_d:
1782 case jit_code_absi_d: case jit_code_sqrti_d:
1785 negi(rn(node->u.w), node->v.w);
1788 comi(rn(node->u.w), node->v.w);
1790 case jit_code_exti_c:
1791 exti_c(rn(node->u.w), node->v.w);
1793 case jit_code_exti_uc:
1794 exti_uc(rn(node->u.w), node->v.w);
1796 case jit_code_exti_s:
1797 exti_s(rn(node->u.w), node->v.w);
1799 case jit_code_exti_us:
1800 exti_us(rn(node->u.w), node->v.w);
1802 case jit_code_bswapi_us:
1803 bswapi_us(rn(node->u.w), node->v.w);
1805 case jit_code_bswapi_ui:
1806 bswapi_ui(rn(node->u.w), node->v.w);
1808 case jit_code_htoni_us:
1809 htoni_us(rn(node->u.w), node->v.w);
1811 case jit_code_htoni_ui:
1812 htoni_ui(rn(node->u.w), node->v.w);
1814 #if __WORDSIZE == 64
1815 case jit_code_exti_i:
1816 exti_i(rn(node->u.w), node->v.w);
1818 case jit_code_exti_ui:
1819 exti_ui(rn(node->u.w), node->v.w);
1821 case jit_code_bswapi_ul:
1822 bswapi_ul(rn(node->u.w), node->v.w);
1824 case jit_code_htoni_ul:
1825 htoni_ul(rn(node->u.w), node->v.w);
1829 cloi(rn(node->u.w), node->v.w);
1832 clzi(rn(node->u.w), node->v.w);
1835 ctoi(rn(node->u.w), node->v.w);
1838 ctzi(rn(node->u.w), node->v.w);
1840 case jit_code_rbiti:
1841 rbiti(rn(node->u.w), node->v.w);
1843 case jit_code_popcnti:
1844 popcnti(rn(node->u.w), node->v.w);
1847 exti(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1849 case jit_code_exti_u:
1850 exti_u(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1855 if (jit_carry != _NOREG) {
1856 switch (node->code) {
1858 case jit_code_addcr: case jit_code_addci:
1859 case jit_code_addxr: case jit_code_addxi:
1860 case jit_code_subcr: case jit_code_subci:
1861 case jit_code_subxr: case jit_code_subxi:
1864 jit_unget_reg(jit_carry);
1869 jit_regarg_clr(node, value);
1870 assert(_jitc->regarg == 0 ||
1871 (jit_carry != _NOREG && _jitc->regarg == (1 << jit_carry)));
1872 assert(_jitc->synth == 0);
1873 /* update register live state */
1885 #if __WORDSIZE == 64
1886 /* Record all constants to be patched */
1887 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1888 node = _jitc->patches.ptr[offset].node;
1889 value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1892 /* Record all direct constants */
1893 for (offset = 0; offset < _jitc->consts.vector.offset; offset++)
1894 put_const(_jitc->consts.vector.values[offset]);
1895 /* Now actually inject constants at the end of code buffer */
1896 if (_jitc->consts.hash.count) {
1898 /* Insert nop if aligned at 4 bytes */
1899 if (_jit->pc.w % sizeof(jit_word_t))
1900 nop(_jit->pc.w % sizeof(jit_word_t));
1901 for (offset = 0; offset < _jitc->consts.hash.size; offset++) {
1902 entry = _jitc->consts.hash.table[offset];
1903 for (; entry; entry = entry->next) {
1904 /* Make sure to not write out of bounds */
1905 if (_jit->pc.uc >= _jitc->code.end)
1907 entry->address = _jit->pc.w;
1908 *_jit->pc.ul++ = entry->value;
1914 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1915 node = _jitc->patches.ptr[offset].node;
1916 word = _jitc->patches.ptr[offset].inst;
1917 value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1918 patch_at(word, value);
1921 #if __WORDSIZE == 64
1922 /* Patch direct complex constants */
1923 if (_jitc->consts.vector.instrs) {
1924 for (offset = 0; offset < _jitc->consts.vector.offset; offset++)
1925 patch_at(_jitc->consts.vector.instrs[offset],
1926 _jitc->consts.vector.values[offset]);
1927 jit_free((jit_pointer_t *)&_jitc->consts.vector.instrs);
1928 jit_free((jit_pointer_t *)&_jitc->consts.vector.values);
1931 /* Hash table no longer need */
1932 if (_jitc->consts.hash.table) {
1933 jit_free((jit_pointer_t *)&_jitc->consts.hash.table);
1934 for (offset = 0; offset < _jitc->consts.pool.length; offset++)
1935 jit_free((jit_pointer_t *)_jitc->consts.pool.ptr + offset);
1936 jit_free((jit_pointer_t *)&_jitc->consts.pool.ptr);
1940 jit_flush(_jit->code.ptr, _jit->pc.uc);
1942 return (_jit->code.ptr);
1946 # include "jit_riscv-cpu.c"
1947 # include "jit_riscv-fpu.c"
1948 # include "jit_fallback.c"
1952 _load_const(jit_state_t *_jit, jit_int32_t reg, jit_word_t value)
1954 if (_jitc->consts.vector.offset >= _jitc->consts.vector.length) {
1955 jit_word_t new_size = _jitc->consts.vector.length *
1956 2 * sizeof(jit_word_t);
1957 jit_realloc((jit_pointer_t *)&_jitc->consts.vector.instrs,
1958 _jitc->consts.vector.length * sizeof(jit_word_t), new_size);
1959 jit_realloc((jit_pointer_t *)&_jitc->consts.vector.values,
1960 _jitc->consts.vector.length * sizeof(jit_word_t), new_size);
1961 _jitc->consts.vector.length *= 2;
1963 _jitc->consts.vector.instrs[_jitc->consts.vector.offset] = _jit->pc.w;
1964 _jitc->consts.vector.values[_jitc->consts.vector.offset] = value;
1965 ++_jitc->consts.vector.offset;
1966 /* Resolve later the pc relative address */
1974 hash_const(jit_word_t value)
1976 const jit_uint8_t *ptr;
1978 for (i = key = 0, ptr = (jit_uint8_t *)&value; i < 4; ++i)
1979 key = (key << (key & 1)) ^ ptr[i];
1985 _put_const(jit_state_t *_jit, jit_word_t value)
1990 /* Check if already inserted in table */
1991 key = hash_const(value) % _jitc->consts.hash.size;
1992 for (entry = _jitc->consts.hash.table[key]; entry; entry = entry->next) {
1993 if (entry->value == value)
1997 /* Check if need to increase pool size */
1998 if (_jitc->consts.pool.list->next == NULL) {
2001 jit_word_t new_size = (_jitc->consts.pool.length + 1) *
2002 sizeof(jit_const_t*);
2003 jit_realloc((jit_pointer_t *)&_jitc->consts.pool.ptr,
2004 _jitc->consts.pool.length * sizeof(jit_const_t*), new_size);
2005 jit_alloc((jit_pointer_t *)
2006 _jitc->consts.pool.ptr + _jitc->consts.pool.length,
2007 1024 * sizeof(jit_const_t));
2008 list = _jitc->consts.pool.ptr[_jitc->consts.pool.length];
2009 _jitc->consts.pool.list->next = list;
2010 for (offset = 0; offset < 1023; ++offset, ++list)
2011 list->next = list + 1;
2013 ++_jitc->consts.pool.length;
2016 /* Rehash if more than 75% used table */
2017 if (_jitc->consts.hash.count > (_jitc->consts.hash.size / 4) * 3) {
2020 jit_const_t **table;
2021 jit_alloc((jit_pointer_t *)&table,
2022 _jitc->consts.hash.size * 2 * sizeof(jit_const_t *));
2023 for (i = 0; i < _jitc->consts.hash.size; ++i) {
2024 for (entry = _jitc->consts.hash.table[i]; entry; entry = next) {
2026 k = hash_const(entry->value) % (_jitc->consts.hash.size * 2);
2027 entry->next = table[k];
2031 jit_free((jit_pointer_t *)&_jitc->consts.hash.table);
2032 _jitc->consts.hash.size *= 2;
2033 _jitc->consts.hash.table = table;
2036 /* Insert in hash */
2037 entry = _jitc->consts.pool.list;
2038 _jitc->consts.pool.list = entry->next;
2039 ++_jitc->consts.hash.count;
2040 entry->value = value;
2041 entry->next = _jitc->consts.hash.table[key];
2042 _jitc->consts.hash.table[key] = entry;
2046 _get_const(jit_state_t *_jit, jit_word_t value)
2050 key = hash_const(value) % _jitc->consts.hash.size;
2051 for (entry = _jitc->consts.hash.table[key]; entry; entry = entry->next) {
2052 if (entry->value == value)
2053 return (entry->address);
2055 /* Only the final patch should call get_const() */
2060 jit_flush(void *fptr, void *tptr)
2062 #if defined(__GNUC__)
2065 s = sysconf(_SC_PAGE_SIZE);
2066 f = (jit_word_t)fptr & -s;
2067 t = (((jit_word_t)tptr) + s - 1) & -s;
2068 __clear_cache((void *)f, (void *)t);
2073 _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2075 ldxi(rn(r0), rn(r1), i0);
2079 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2081 stxi(i0, rn(r0), rn(r1));
2085 _emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2087 ldxi_d(rn(r0), rn(r1), i0);
2091 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2093 stxi_d(i0, rn(r0), rn(r1));
2096 #if __WORDSIZE != 64
2097 # error "only 64 bit ports tested"
2100 _compute_framesize(jit_state_t *_jit)
2103 _jitc->framesize = 16; /* ra+fp */
2104 for (reg = 0; reg < jit_size(iregs); reg++)
2105 if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg]))
2106 _jitc->framesize += sizeof(jit_word_t);
2108 for (reg = 0; reg < jit_size(fregs); reg++)
2109 if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg]))
2110 _jitc->framesize += sizeof(jit_float64_t);
2112 /* Space to store variadic arguments */
2113 if (_jitc->function->self.call & jit_call_varargs)
2114 _jitc->framesize += (8 - _jitc->function->vagp) * 8;
2116 /* Make sure functions called have a 16 byte aligned stack */
2117 _jitc->framesize = (_jitc->framesize + 15) & -16;
2121 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
2125 assert(node->flag & jit_flag_node);
2126 if (node->code == jit_code_movi)
2127 flag = node->v.n->flag;
2129 flag = node->u.n->flag;
2130 assert(!(flag & jit_flag_patch));
2131 if (_jitc->patches.offset >= _jitc->patches.length) {
2132 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
2133 _jitc->patches.length * sizeof(jit_patch_t),
2134 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
2135 _jitc->patches.length += 1024;
2137 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
2138 _jitc->patches.ptr[_jitc->patches.offset].node = node;
2139 ++_jitc->patches.offset;