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 #if defined(__linux__)
21 # include <sys/cachectl.h>
25 # define __mips_soft_float 0
26 #elif __mips_soft_float
27 # define __mips_hard_float 0
29 /* Must have a floating point unit and cannot figure
30 * if can attempt to work with software floats
32 # define __mips_soft_float 0
33 # define __mips_hard_float 1
37 /* callee save + variadic arguments
38 * align16(ra+fp+s[0-7]++f20+f22+f24+f26+f28+f30) + align16(a[0-7]) */
39 # define stack_framesize (128 + 64)
42 * align16(ra+fp+s[0-7]+f16+f18+f20+f22+f24+f26+f28+f30) */
43 # define stack_framesize 128
47 # define NUM_WORD_ARGS 8
49 # define STACK_SHIFT 3
51 # define NUM_WORD_ARGS 4
53 # define STACK_SHIFT 2
55 #if NEW_ABI && __BYTE_ORDER == __BIG_ENDIAN && __WORDSIZE == 32
56 # define WORD_ADJUST 4
58 # define WORD_ADJUST 0
60 #define jit_arg_reg_p(i) ((i) >= 0 && (i) < NUM_WORD_ARGS)
61 #if __BYTE_ORDER == __LITTLE_ENDIAN
66 # define C_DISP STACK_SLOT - sizeof(jit_int8_t)
67 # define S_DISP STACK_SLOT - sizeof(jit_int16_t)
68 # define I_DISP STACK_SLOT - sizeof(jit_int32_t)
74 typedef struct jit_pointer_t jit_va_list_t;
79 #define jit_make_arg(node,code) _jit_make_arg(_jit,node,code)
80 static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*,jit_code_t);
81 #define jit_make_arg_f(node) _jit_make_arg_f(_jit,node)
82 static jit_node_t *_jit_make_arg_f(jit_state_t*,jit_node_t*);
83 #define jit_make_arg_d(node) _jit_make_arg_d(_jit,node)
84 static jit_node_t *_jit_make_arg_d(jit_state_t*,jit_node_t*);
85 #define compute_framesize() _compute_framesize(_jit)
86 static void _compute_framesize(jit_state_t*);
87 #define patch(instr, node) _patch(_jit, instr, node)
88 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
91 # include "jit_rewind.c"
92 # include "jit_mips-cpu.c"
93 # include "jit_mips-fpu.c"
94 # include "jit_fallback.c"
101 jit_register_t _rvs[] = {
102 { rc(gpr) | 0x01, "at" },
103 { rc(gpr) | 0x02, "v0" },
104 { rc(gpr) | 0x03, "v1" },
106 { rc(gpr) | 0x08, "t0" },
107 { rc(gpr) | 0x09, "t1" },
108 { rc(gpr) | 0x0a, "t2" },
109 { rc(gpr) | 0x0b, "t3" },
111 { rc(gpr) | 0x0c, "t4" },
112 { rc(gpr) | 0x0d, "t5" },
113 { rc(gpr) | 0x0e, "t6" },
114 { rc(gpr) | 0x0f, "t7" },
115 { rc(gpr) | 0x18, "t8" },
116 { rc(gpr) | 0x19, "t9" },
117 { rc(sav) | rc(gpr) | 0x10, "s0" },
118 { rc(sav) | rc(gpr) | 0x11, "s1" },
119 { rc(sav) | rc(gpr) | 0x12, "s2" },
120 { rc(sav) | rc(gpr) | 0x13, "s3" },
121 { rc(sav) | rc(gpr) | 0x14, "s4" },
122 { rc(sav) | rc(gpr) | 0x15, "s5" },
123 { rc(sav) | rc(gpr) | 0x16, "s6" },
124 { rc(sav) | rc(gpr) | 0x17, "s7" },
128 { rc(sav) | 0x1f, "ra" },
129 { rc(sav) | 0x1c, "gp" },
130 { rc(sav) | 0x1d, "sp" },
131 { rc(sav) | 0x1e, "fp" },
133 { rc(gpr) | 0x0b, "a7" },
134 { rc(gpr) | 0x0a, "a6" },
135 { rc(gpr) | 0x09, "a5" },
136 { rc(gpr) | 0x08, "a4" },
138 { rc(arg) | rc(gpr) | 0x07, "a3" },
139 { rc(arg) | rc(gpr) | 0x06, "a2" },
140 { rc(arg) | rc(gpr) | 0x05, "a1" },
141 { rc(arg) | rc(gpr) | 0x04, "a0" },
142 { rc(fpr) | 0x00, "$f0" },
143 { rc(fpr) | 0x02, "$f2" },
144 { rc(fpr) | 0x04, "$f4" },
145 { rc(fpr) | 0x06, "$f6" },
146 { rc(fpr) | 0x08, "$f8" },
147 { rc(fpr) | 0x0a, "$f10" },
149 { rc(sav) | rc(fpr) | 0x10, "$f16" },
150 { rc(sav) | rc(fpr) | 0x12, "$f18" },
152 { rc(sav) | rc(fpr) | 0x14, "$f20" },
153 { rc(sav) | rc(fpr) | 0x16, "$f22" },
154 { rc(sav) | rc(fpr) | 0x18, "$f24" },
155 { rc(sav) | rc(fpr) | 0x1a, "$f26" },
156 { rc(sav) | rc(fpr) | 0x1c, "$f28" },
157 { rc(sav) | rc(fpr) | 0x1e, "$f30" },
159 { rc(arg) | rc(fpr) | 0x13, "$f19" },
160 { rc(arg) | rc(fpr) | 0x12, "$f18" },
161 { rc(arg) | rc(fpr) | 0x11, "$f17" },
162 { rc(arg) | rc(fpr) | 0x10, "$f16" },
163 { rc(arg) | rc(fpr) | 0x0f, "$f15" },
164 { rc(arg) | rc(fpr) | 0x0e, "$f14" },
165 { rc(arg) | rc(fpr) | 0x0d, "$f13" },
166 { rc(arg) | rc(fpr) | 0x0c, "$f12" },
168 { rc(arg) | rc(fpr) | 0x0e, "$f14" },
169 { rc(arg) | rc(fpr) | 0x0c, "$f12" },
171 { _NOREG, "<none>" },
174 static jit_int32_t iregs[] = {
175 _S0, _S1, _S2, _S3, _S4, _S5, _S6, _S7
178 static jit_int32_t fregs[] = {
182 _F20, _F22, _F24, _F26, _F28, _F30
191 /* By default assume it works or have/need unaligned instructions. */
192 jit_cpu.sll_delay = jit_cpu.cop1_delay = jit_cpu.lwl_lwr_delay =
193 jit_cpu.unaligned = 1;
195 #if defined(__linux__)
200 if ((fp = fopen("/proc/cpuinfo", "r")) != NULL) {
201 while (fgets(buf, sizeof(buf), fp)) {
202 if (strncmp(buf, "isa\t\t\t: ", 8) == 0) {
203 if ((ptr = strstr(buf + 9, "mips64r")))
204 jit_cpu.release = strtoul(ptr + 7, NULL, 10);
207 /* Just for some actual hardware tested. Below check
208 * for mips 1 would disable these delays anyway. */
209 if (strncmp(buf, "cpu model\t\t: ", 13) == 0) {
210 /* ICT Loongson-2 V0.3 FPU V0.1 */
211 if (strstr(buf + 13, "FPU V0.1"))
212 jit_cpu.sll_delay = jit_cpu.cop1_delay = 0;
213 /* Cavium Octeon III V0.2 FPU V0.0 */
214 else if (strstr(buf + 13, "FPU V0.0"))
215 jit_cpu.sll_delay = jit_cpu.cop1_delay = 0;
216 /* Cavium Octeon II V0.1 */
217 else if (strstr(buf + 13, " II "))
218 jit_cpu.sll_delay = jit_cpu.cop1_delay = 0;
226 if (!jit_cpu.release)
227 jit_cpu.release = __mips_isa_rev;
228 #elif defined _MIPS_ARCH
229 if (!jit_cpu.release)
230 jit_cpu.release = strtoul(&_MIPS_ARCH[4], NULL, 10);
231 #elif defined(__mips) && __mips < 6
232 if (!jit_cpu.release)
233 jit_cpu.release = __mips;
235 /* Assume all mips 1 and 2, or detected as release 1 or 2 have this
237 /* Note that jit_cpu is global, and can be overriden, that is, add
238 * the C code "jit_cpu.cop1_delay = 1;" after the call to init_jit()
239 * if it is functional. */
240 if (jit_cpu.cop1_delay && jit_cpu.release < 3)
241 jit_cpu.cop1_delay = 0;
242 if (jit_cpu.sll_delay && jit_cpu.release < 3)
243 jit_cpu.sll_delay = 0;
244 if (jit_cpu.lwl_lwr_delay && jit_cpu.release < 2)
245 jit_cpu.lwl_lwr_delay = 0;
246 if (jit_cpu.release >= 6)
247 jit_cpu.unaligned = 0;
251 _jit_init(jit_state_t *_jit)
253 _jitc->reglen = jit_size(_rvs) - 1;
255 * o reserve a register for carry (overkill)
256 * o use MTLO/MFLO (performance hit)
257 * So, keep a register allocated after setting carry, and implicitly
258 * deallocate it if it can no longer be tracked
264 _jit_prolog(jit_state_t *_jit)
270 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
271 jit_regset_set_ui(&_jitc->regsav, 0);
272 offset = _jitc->functions.offset;
273 if (offset >= _jitc->functions.length) {
274 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
275 _jitc->functions.length * sizeof(jit_function_t),
276 (_jitc->functions.length + 16) * sizeof(jit_function_t));
277 _jitc->functions.length += 16;
279 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
280 _jitc->function->self.size = stack_framesize;
281 _jitc->function->self.argi = _jitc->function->self.argf =
282 _jitc->function->self.aoff = _jitc->function->self.alen = 0;
283 _jitc->function->self.call = jit_call_default;
284 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
285 _jitc->reglen * sizeof(jit_int32_t));
287 /* _no_link here does not mean the jit_link() call can be removed
289 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
291 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
292 jit_link(_jitc->function->prolog);
293 _jitc->function->prolog->w.w = offset;
294 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
296 * v: offset in blocks vector
297 * w: offset in functions vector
299 _jitc->function->epilog->w.w = offset;
301 jit_regset_new(&_jitc->function->regset);
305 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
307 assert(_jitc->function);
310 case 0: case 1: break;
311 case 2: _jitc->function->self.aoff &= -2; break;
312 case 3: case 4: _jitc->function->self.aoff &= -4; break;
313 default: _jitc->function->self.aoff &= -8; break;
315 _jitc->function->self.aoff -= length;
316 if (!_jitc->realize) {
317 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
320 return (_jitc->function->self.aoff);
324 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
327 assert(_jitc->function);
328 jit_inc_synth_ww(allocar, u, v);
329 if (!_jitc->function->allocar) {
330 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
331 _jitc->function->allocar = 1;
333 reg = jit_get_reg(jit_class_gpr);
335 jit_andi(reg, reg, -8);
336 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
338 jit_addr(JIT_SP, JIT_SP, reg);
339 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
345 _jit_ret(jit_state_t *_jit)
348 assert(_jitc->function);
352 jit_patch_at(instr, _jitc->function->epilog);
357 _jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
359 jit_code_inc_synth_w(code, u);
360 jit_movr(JIT_RET, u);
366 _jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
368 jit_code_inc_synth_w(code, u);
369 jit_movi(JIT_RET, u);
375 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
377 jit_inc_synth_w(retr_f, u);
378 #if __mips_soft_float
379 # warning *** GNU Lightning will use hard float registers! ***
380 # warning *** Are you sure about -msoft-float usage? ***
381 jit_movr_f_w(JIT_RET, u);
384 jit_movr_f(JIT_FRET, u);
393 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
395 jit_inc_synth_f(reti_f, u);
396 #if __mips_soft_float
397 jit_movi_f_w(JIT_RET, u);
399 jit_movi_f(JIT_FRET, u);
406 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
408 jit_inc_synth_w(retr_d, u);
409 #if __mips_soft_float
410 jit_movr_d_w(JIT_RET, u);
413 jit_movr_d(JIT_FRET, u);
422 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
424 jit_inc_synth_d(reti_d, u);
425 #if __mips_soft_float
426 jit_movi_d_w(JIT_RET, u);
428 jit_movi_d(JIT_FRET, u);
435 _jit_epilog(jit_state_t *_jit)
437 assert(_jitc->function);
438 assert(_jitc->function->epilog->next == NULL);
439 jit_link(_jitc->function->epilog);
440 _jitc->function = NULL;
444 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
446 if (u->code >= jit_code_arg_c && u->code <= jit_code_arg)
447 return (jit_arg_reg_p(u->u.w));
448 assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
450 return (jit_arg_reg_p(u->u.w) || jit_arg_reg_p(u->u.w - 8));
457 _jit_make_arg(jit_state_t *_jit, jit_node_t *node, jit_code_t code)
461 if (jit_arg_reg_p(_jitc->function->self.argi))
462 offset = _jitc->function->self.argi++;
464 offset = _jitc->function->self.size;
465 _jitc->function->self.size += STACK_SLOT;
468 offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT;
469 ++_jitc->function->self.argi;
471 offset = _jitc->function->self.size;
472 _jitc->function->self.size += STACK_SLOT;
474 if (node == (jit_node_t *)0)
475 node = jit_new_node(code);
479 node->v.w = ++_jitc->function->self.argn;
485 _jit_make_arg_f(jit_state_t *_jit, jit_node_t *node)
489 if (jit_arg_reg_p(_jitc->function->self.argi)) {
490 offset = _jitc->function->self.argi++;
491 if (__mips_soft_float ||
492 (_jitc->function->self.call & jit_call_varargs))
496 offset = _jitc->function->self.size;
497 _jitc->function->self.size += STACK_SLOT;
500 offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT;
501 if (offset < NUM_WORD_ARGS) {
502 if (!_jitc->function->self.argi &&
503 !(_jitc->function->self.call & jit_call_varargs)) {
508 _jitc->function->self.argi = 1;
510 /* Use as flag to rewind in case of varargs function */
511 ++_jitc->function->self.argf;
515 offset = _jitc->function->self.size;
516 _jitc->function->self.size += STACK_SLOT;
518 if (node == (jit_node_t *)0)
519 node = jit_new_node(jit_code_arg_f);
523 node->v.w = ++_jitc->function->self.argn;
529 _jit_make_arg_d(jit_state_t *_jit, jit_node_t *node)
533 if (jit_arg_reg_p(_jitc->function->self.argi)) {
534 offset = _jitc->function->self.argi++;
535 if (__mips_soft_float ||
536 (_jitc->function->self.call & jit_call_varargs))
540 offset = _jitc->function->self.size;
541 _jitc->function->self.size += STACK_SLOT;
544 if (_jitc->function->self.size & 7) {
545 _jitc->function->self.size += 4;
546 _jitc->function->self.argi = 1;
548 offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT;
549 if (offset < NUM_WORD_ARGS) {
550 if (!_jitc->function->self.argi &&
551 !(_jitc->function->self.call & jit_call_varargs)) {
553 /* Use as flag to rewind in case of varargs function */
554 ++_jitc->function->self.argf;
558 offset = _jitc->function->self.size;
559 _jitc->function->self.size += sizeof(jit_float64_t);
561 if (node == (jit_node_t *)0)
562 node = jit_new_node(jit_code_arg_d);
566 node->v.w = ++_jitc->function->self.argn;
572 _jit_ellipsis(jit_state_t *_jit)
574 if (_jitc->prepare) {
575 assert(!(_jitc->function->call.call & jit_call_varargs));
576 _jitc->function->call.call |= jit_call_varargs;
578 if (_jitc->function->call.argf)
583 assert(!(_jitc->function->self.call & jit_call_varargs));
585 if (jit_arg_reg_p(_jitc->function->self.argi))
587 /* Do not set during possible rewind. */
588 _jitc->function->self.call |= jit_call_varargs;
590 _jitc->function->self.call |= jit_call_varargs;
591 if (_jitc->function->self.argf)
594 _jitc->function->vagp = _jitc->function->self.argi;
596 jit_inc_synth(ellipsis);
606 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
608 jit_inc_synth_w(va_push, u);
614 _jit_arg(jit_state_t *_jit, jit_code_t code)
616 assert(_jitc->function);
617 assert(!(_jitc->function->self.call & jit_call_varargs));
618 #if STRONG_TYPE_CHECKING
619 assert(code >= jit_code_arg_c && code <= jit_code_arg);
621 return (jit_make_arg((jit_node_t*)0, code));
625 _jit_arg_f(jit_state_t *_jit)
627 assert(_jitc->function);
628 return (jit_make_arg_f((jit_node_t*)0));
632 _jit_arg_d(jit_state_t *_jit)
634 assert(_jitc->function);
635 return (jit_make_arg_d((jit_node_t*)0));
639 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
641 assert_arg_type(v->code, jit_code_arg_c);
642 jit_inc_synth_wp(getarg_c, u, v);
643 if (jit_arg_reg_p(v->u.w))
644 jit_extr_c(u, _A0 - v->u.w);
646 jit_node_t *node = jit_ldxi_c(u, _FP, v->u.w + C_DISP);
647 jit_link_alist(node);
654 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
656 assert_arg_type(v->code, jit_code_arg_c);
657 jit_inc_synth_wp(getarg_uc, u, v);
658 if (jit_arg_reg_p(v->u.w))
659 jit_extr_uc(u, _A0 - v->u.w);
661 jit_node_t *node = jit_ldxi_uc(u, _FP, v->u.w + C_DISP);
662 jit_link_alist(node);
669 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
671 assert_arg_type(v->code, jit_code_arg_s);
672 jit_inc_synth_wp(getarg_s, u, v);
673 if (jit_arg_reg_p(v->u.w))
674 jit_extr_s(u, _A0 - v->u.w);
676 jit_node_t *node = jit_ldxi_s(u, _FP, v->u.w + S_DISP);
677 jit_link_alist(node);
684 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
686 assert_arg_type(v->code, jit_code_arg_s);
687 jit_inc_synth_wp(getarg_us, u, v);
688 if (jit_arg_reg_p(v->u.w))
689 jit_extr_us(u, _A0 - v->u.w);
691 jit_node_t *node = jit_ldxi_us(u, _FP, v->u.w + S_DISP);
692 jit_link_alist(node);
699 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
701 assert_arg_type(v->code, jit_code_arg_i);
702 jit_inc_synth_wp(getarg_i, u, v);
703 if (jit_arg_reg_p(v->u.w)) {
705 jit_extr_i(u, _A0 - v->u.w);
707 jit_movr(u, _A0 - v->u.w);
711 jit_node_t *node = jit_ldxi_i(u, _FP, v->u.w + I_DISP);
712 jit_link_alist(node);
720 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
722 assert_arg_type(v->code, jit_code_arg_i);
723 jit_inc_synth_wp(getarg_ui, u, v);
724 if (jit_arg_reg_p(v->u.w))
725 jit_extr_ui(u, _A0 - v->u.w);
727 jit_node_t *node = jit_ldxi_ui(u, _FP, v->u.w + I_DISP);
728 jit_link_alist(node);
735 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
737 assert_arg_type(v->code, jit_code_arg_l);
738 jit_inc_synth_wp(getarg_l, u, v);
739 if (jit_arg_reg_p(v->u.w))
740 jit_movr(u, _A0 - v->u.w);
742 jit_node_t *node = jit_ldxi_l(u, _FP, v->u.w);
743 jit_link_alist(node);
751 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
753 assert_putarg_type(code, v->code);
754 jit_code_inc_synth_wp(code, u, v);
755 if (jit_arg_reg_p(v->u.w))
756 jit_movr(_A0 - v->u.w, u);
758 jit_node_t *node = jit_stxi(v->u.w + WORD_ADJUST, _FP, u);
759 jit_link_alist(node);
766 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
769 assert_putarg_type(code, v->code);
770 jit_code_inc_synth_wp(code, u, v);
771 if (jit_arg_reg_p(v->u.w))
772 jit_movi(_A0 - v->u.w, u);
775 regno = jit_get_reg(jit_class_gpr);
777 node = jit_stxi(v->u.w + WORD_ADJUST, _FP, regno);
778 jit_link_alist(node);
780 jit_unget_reg(regno);
786 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
788 assert(v->code == jit_code_arg_f);
789 jit_inc_synth_wp(getarg_f, u, v);
791 if (jit_arg_reg_p(v->u.w))
792 jit_movr_f(u, _F12 - v->u.w);
793 else if (jit_arg_reg_p(v->u.w - 8))
794 jit_movr_w_f(u, _A0 - (v->u.w - 8));
797 jit_movr_w_f(u, _A0 - v->u.w);
799 jit_movr_f(u, _F12 - ((v->u.w - 4) >> 1));
802 jit_node_t *node = jit_ldxi_f(u, _FP, v->u.w);
803 jit_link_alist(node);
810 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
812 assert(v->code == jit_code_arg_f);
813 jit_inc_synth_wp(putargr_f, u, v);
815 if (jit_arg_reg_p(v->u.w))
816 jit_movr_f(_F12 - v->u.w, u);
817 else if (jit_arg_reg_p(v->u.w - 8))
818 jit_movr_f_w(_A0 - (v->u.w - 8), u);
821 jit_movr_f_w(_A0 - v->u.w, u);
823 jit_movr_f(_F12 - ((v->u.w - 4) >> 1), u);
826 jit_node_t *node = jit_stxi_f(v->u.w, _FP, u);
827 jit_link_alist(node);
834 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
837 assert(v->code == jit_code_arg_f);
838 jit_inc_synth_fp(putargi_f, u, v);
840 if (jit_arg_reg_p(v->u.w))
841 jit_movi_f(_F12 - v->u.w, u);
842 else if (jit_arg_reg_p(v->u.w - 8))
843 jit_movi_f_w(_A0 - (v->u.w - 8), u);
846 regno = jit_get_reg(jit_class_fpr);
847 jit_movi_f(regno, u);
848 jit_movr_f_w(_A0 - ((v->u.w - 4) >> 1), regno);
849 jit_unget_reg(regno);
852 jit_movi_f(_F12 - ((v->u.w - 4) >> 1), u);
856 regno = jit_get_reg(jit_class_fpr);
857 jit_movi_f(regno, u);
858 node = jit_stxi_f(v->u.w, _FP, regno);
859 jit_link_alist(node);
861 jit_unget_reg(regno);
867 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
869 assert(v->code == jit_code_arg_d);
870 jit_inc_synth_wp(getarg_d, u, v);
872 if (jit_arg_reg_p(v->u.w))
873 jit_movr_d(u, _F12 - v->u.w);
874 else if (jit_arg_reg_p(v->u.w - 8))
875 jit_movr_w_d(u, _A0 - (v->u.w - 8));
878 jit_movr_ww_d(u, _A0 - v->u.w, _A0 - (v->u.w + 1));
880 jit_movr_d(u, _F12 - ((v->u.w - 4) >> 1));
883 jit_node_t *node = jit_ldxi_d(u, _FP, v->u.w);
884 jit_link_alist(node);
891 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
893 assert(v->code == jit_code_arg_d);
894 jit_inc_synth_wp(putargr_d, u, v);
896 if (jit_arg_reg_p(v->u.w))
897 jit_movr_d(_F12 - v->u.w, u);
898 else if (jit_arg_reg_p(v->u.w - 8))
899 jit_movr_d_w(_A0 - (v->u.w - 8), u);
902 jit_movr_d_ww(_A0 - v->u.w, _A0 - (v->u.w + 1), u);
904 jit_movr_d(_F12 - ((v->u.w - 4) >> 1), u);
907 jit_node_t *node = jit_stxi_d(v->u.w, _FP, u);
908 jit_link_alist(node);
915 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
918 assert(v->code == jit_code_arg_d);
919 jit_inc_synth_dp(putargi_d, u, v);
921 if (jit_arg_reg_p(v->u.w))
922 jit_movi_d(_F12 - v->u.w, u);
923 else if (jit_arg_reg_p(v->u.w - 8))
924 jit_movi_d_w(_A0 - (v->u.w - 8), u);
927 regno = jit_get_reg(jit_class_fpr);
928 jit_movi_d(regno, u);
929 jit_movr_d_ww(_A0 - v->u.w, _A0 - (v->u.w + 1), regno);
930 jit_unget_reg(regno);
933 jit_movi_d(_F12 - ((v->u.w - 4) >> 1), u);
937 regno = jit_get_reg(jit_class_fpr);
938 jit_movi_d(regno, u);
939 node = jit_stxi_d(v->u.w, _FP, regno);
940 jit_link_alist(node);
942 jit_unget_reg(regno);
948 _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
950 jit_code_inc_synth_w(code, u);
953 assert(_jitc->function);
954 if (jit_arg_reg_p(_jitc->function->call.argi)) {
955 jit_movr(_A0 - _jitc->function->call.argi, u);
956 ++_jitc->function->call.argi;
960 jit_stxi(_jitc->function->call.size + WORD_ADJUST, JIT_SP, u);
961 _jitc->function->call.size += STACK_SLOT;
965 assert(_jitc->function);
966 offset = _jitc->function->call.size >> STACK_SHIFT;
967 ++_jitc->function->call.argi;
968 if (jit_arg_reg_p(offset))
969 jit_movr(_A0 - offset, u);
972 jit_stxi(_jitc->function->call.size, JIT_SP, u);
974 _jitc->function->call.size += STACK_SLOT;
980 _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
986 assert(_jitc->function);
987 jit_code_inc_synth_w(code, u);
990 if (jit_arg_reg_p(_jitc->function->call.argi)) {
991 jit_movi(_A0 - _jitc->function->call.argi, u);
992 ++_jitc->function->call.argi;
996 regno = jit_get_reg(jit_class_gpr);
998 jit_stxi(_jitc->function->call.size + WORD_ADJUST, JIT_SP, regno);
999 _jitc->function->call.size += STACK_SLOT;
1000 jit_unget_reg(regno);
1003 offset = _jitc->function->call.size >> STACK_SHIFT;
1004 ++_jitc->function->call.argi;
1005 if (jit_arg_reg_p(offset))
1006 jit_movi(_A0 - offset, u);
1009 regno = jit_get_reg(jit_class_gpr);
1011 jit_stxi(_jitc->function->call.size, JIT_SP, regno);
1012 jit_unget_reg(regno);
1014 _jitc->function->call.size += STACK_SLOT;
1020 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
1025 assert(_jitc->function);
1026 jit_inc_synth_w(pushargr_f, u);
1029 if (jit_arg_reg_p(_jitc->function->call.argi)) {
1030 if (__mips_hard_float &&
1031 !(_jitc->function->call.call & jit_call_varargs))
1032 jit_movr_f(_F12 - _jitc->function->call.argi, u);
1034 jit_movr_f_w(_A0 - _jitc->function->call.argi, u);
1035 ++_jitc->function->call.argi;
1039 jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
1040 _jitc->function->call.size += STACK_SLOT;
1043 offset = _jitc->function->call.size >> STACK_SHIFT;
1044 if (offset < 2 && !_jitc->function->call.argi &&
1045 !(_jitc->function->call.call & jit_call_varargs)) {
1046 ++_jitc->function->call.argf;
1047 jit_movr_f(_F12 - offset, u);
1049 else if (offset < 4) {
1050 ++_jitc->function->call.argi;
1051 jit_movr_f_w(_A0 - offset, u);
1055 jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
1057 _jitc->function->call.size += STACK_SLOT;
1063 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
1069 assert(_jitc->function);
1070 jit_inc_synth_f(pushargi_f, u);
1073 if (jit_arg_reg_p(_jitc->function->call.argi)) {
1074 if (__mips_hard_float &&
1075 !(_jitc->function->call.call & jit_call_varargs))
1076 jit_movi_f(_F12 - _jitc->function->call.argi, u);
1078 jit_movi_f_w(_A0 - _jitc->function->call.argi, u);
1079 ++_jitc->function->call.argi;
1083 regno = jit_get_reg(jit_class_fpr);
1084 jit_movi_f(regno, u);
1085 jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
1086 _jitc->function->call.size += STACK_SLOT;
1087 jit_unget_reg(regno);
1090 offset = _jitc->function->call.size >> STACK_SHIFT;
1091 if (offset < 2 && !_jitc->function->call.argi &&
1092 !(_jitc->function->call.call & jit_call_varargs)) {
1093 ++_jitc->function->call.argf;
1094 jit_movi_f(_F12 - offset, u);
1096 else if (offset < 4) {
1097 ++_jitc->function->call.argi;
1098 jit_movi_f_w(_A0 - offset, u);
1102 regno = jit_get_reg(jit_class_fpr);
1103 jit_movi_f(regno, u);
1104 jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
1105 jit_unget_reg(regno);
1107 _jitc->function->call.size += STACK_SLOT;
1113 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
1119 assert(_jitc->function);
1120 jit_inc_synth_w(pushargr_d, u);
1123 if (jit_arg_reg_p(_jitc->function->call.argi)) {
1124 if (__mips_hard_float &&
1125 !(_jitc->function->call.call & jit_call_varargs))
1126 jit_movr_d(_F12 - _jitc->function->call.argi, u);
1128 jit_movr_d_w(_A0 - _jitc->function->call.argi, u);
1129 ++_jitc->function->call.argi;
1133 jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
1134 _jitc->function->call.size += STACK_SLOT;
1137 adjust = !!_jitc->function->call.argi;
1138 if (_jitc->function->call.size & 7) {
1139 _jitc->function->call.size += 4;
1142 offset = _jitc->function->call.size >> STACK_SHIFT;
1144 if (adjust || (_jitc->function->call.call & jit_call_varargs)) {
1145 jit_movr_d_ww(_A0 - offset, _A0 - (offset + 1), u);
1146 _jitc->function->call.argi += 2;
1149 jit_movr_d(_F12 - (offset >> 1), u);
1150 ++_jitc->function->call.argf;
1155 jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
1157 _jitc->function->call.size += sizeof(jit_float64_t);
1163 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
1170 assert(_jitc->function);
1171 jit_inc_synth_d(pushargi_d, u);
1174 if (jit_arg_reg_p(_jitc->function->call.argi)) {
1175 if (__mips_hard_float &&
1176 !(_jitc->function->call.call & jit_call_varargs))
1177 jit_movi_d(_F12 - _jitc->function->call.argi, u);
1179 jit_movi_d_w(_A0 - _jitc->function->call.argi, u);
1180 ++_jitc->function->call.argi;
1184 regno = jit_get_reg(jit_class_fpr);
1185 jit_movi_d(regno, u);
1186 jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
1187 _jitc->function->call.size += STACK_SLOT;
1188 jit_unget_reg(regno);
1191 adjust = !!_jitc->function->call.argi;
1192 if (_jitc->function->call.size & 7) {
1193 _jitc->function->call.size += 4;
1196 offset = _jitc->function->call.size >> STACK_SHIFT;
1198 if (adjust || (_jitc->function->call.call & jit_call_varargs)) {
1199 jit_movi_d_ww(_A0 - offset, _A0 - (offset + 1), u);
1200 _jitc->function->call.argi += 2;
1203 jit_movi_d(_F12 - (offset >> 1), u);
1204 ++_jitc->function->call.argf;
1209 regno = jit_get_reg(jit_class_fpr);
1210 jit_movi_d(regno, u);
1211 jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
1212 jit_unget_reg(regno);
1214 _jitc->function->call.size += sizeof(jit_float64_t);
1220 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
1224 spec = jit_class(_rvs[regno].spec);
1225 if (spec & jit_class_arg) {
1226 if (spec & jit_class_gpr) {
1227 regno = _A0 - regno;
1228 if (regno >= 0 && regno < node->v.w)
1231 else if (spec & jit_class_fpr) {
1232 regno = _F12 - regno;
1233 if (regno >= 0 && regno < node->w.w)
1242 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
1245 assert(_jitc->function);
1247 jit_inc_synth_w(finishr, r0);
1248 if (_jitc->function->self.alen < _jitc->function->call.size)
1249 _jitc->function->self.alen = _jitc->function->call.size;
1250 call = jit_callr(r0);
1251 call->v.w = _jitc->function->self.argi;
1253 call->w.w = call->v.w;
1255 call->w.w = _jitc->function->self.argf;
1257 _jitc->function->call.argi = _jitc->function->call.argf =
1258 _jitc->function->call.size = 0;
1264 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
1267 assert(_jitc->function);
1269 jit_inc_synth_w(finishi, (jit_word_t)i0);
1270 if (_jitc->function->self.alen < _jitc->function->call.size)
1271 _jitc->function->self.alen = _jitc->function->call.size;
1272 call = jit_calli(i0);
1273 call->v.w = _jitc->function->call.argi;
1275 call->w.w = call->v.w;
1277 call->w.w = _jitc->function->call.argf;
1279 _jitc->function->call.argi = _jitc->function->call.argf =
1280 _jitc->function->call.size = 0;
1287 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
1289 jit_inc_synth_w(retval_c, r0);
1290 jit_extr_c(r0, JIT_RET);
1295 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
1297 jit_inc_synth_w(retval_uc, r0);
1298 jit_extr_uc(r0, JIT_RET);
1303 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
1305 jit_inc_synth_w(retval_s, r0);
1306 jit_extr_s(r0, JIT_RET);
1311 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
1313 jit_inc_synth_w(retval_us, r0);
1314 jit_extr_us(r0, JIT_RET);
1319 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
1321 jit_inc_synth_w(retval_i, r0);
1322 #if __WORDSIZE == 32
1324 jit_movr(r0, JIT_RET);
1326 jit_extr_i(r0, JIT_RET);
1331 #if __WORDSIZE == 64
1333 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
1335 jit_inc_synth_w(retval_ui, r0);
1336 jit_extr_ui(r0, JIT_RET);
1341 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
1343 jit_inc_synth_w(retval_l, r0);
1345 jit_movr(r0, JIT_RET);
1351 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
1353 jit_inc_synth_w(retval_f, r0);
1354 #if __mips_soft_float
1355 jit_movr_w_f(r0, JIT_RET);
1358 jit_movr_f(r0, JIT_FRET);
1364 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
1366 jit_inc_synth_w(retval_d, r0);
1367 #if __mips_soft_float
1368 jit_movr_w_d(r0, JIT_RET);
1371 jit_movr_d(r0, JIT_FRET);
1377 _emit_code(jit_state_t *_jit)
1388 jit_function_t func;
1389 #if DEVEL_DISASSEMBLER
1392 jit_int32_t patch_offset;
1394 #if DEVEL_DISASSEMBLER
1398 _jitc->function = NULL;
1399 _jitc->inst.pend = 0;
1401 jit_reglive_setup();
1405 undo.patch_offset = 0;
1406 #define case_rr(name, type) \
1407 case jit_code_##name##r##type: \
1408 name##r##type(rn(node->u.w), rn(node->v.w)); \
1410 #define case_rw(name, type) \
1411 case jit_code_##name##i##type: \
1412 name##i##type(rn(node->u.w), node->v.w); \
1414 #define case_wr(name, type) \
1415 case jit_code_##name##i##type: \
1416 name##i##type(node->u.w, rn(node->v.w)); \
1418 #define case_rrr(name, type) \
1419 case jit_code_##name##r##type: \
1420 name##r##type(rn(node->u.w), \
1421 rn(node->v.w), rn(node->w.w)); \
1423 #define case_rrw(name, type) \
1424 case jit_code_##name##i##type: \
1425 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
1427 #define case_rrrr(name, type) \
1428 case jit_code_##name##r##type: \
1429 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
1430 rn(node->v.w), rn(node->w.w)); \
1432 #define case_rrrw(name, type) \
1433 case jit_code_##name##i##type: \
1434 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
1435 rn(node->v.w), node->w.w); \
1437 #define case_rqr(name, type) \
1438 case jit_code_##name##r##type: \
1439 name##r##type(rn(node->u.w), rn(node->v.q.l), \
1440 rn(node->v.q.h), rn(node->w.w)); \
1441 case jit_code_##name##i##type: \
1443 #define case_rrf(name, type, size) \
1444 case jit_code_##name##i##type: \
1445 assert(node->flag & jit_flag_data); \
1446 name##i##type(rn(node->u.w), rn(node->v.w), \
1447 (jit_float##size##_t *)node->w.n->u.w); \
1449 #define case_wrr(name, type) \
1450 case jit_code_##name##i##type: \
1451 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1453 #define case_brr(name, type) \
1454 case jit_code_##name##r##type: \
1456 assert(temp->code == jit_code_label || \
1457 temp->code == jit_code_epilog); \
1458 if (temp->flag & jit_flag_patch) \
1459 name##r##type(temp->u.w, rn(node->v.w), \
1462 word = name##r##type(_jit->pc.w, \
1463 rn(node->v.w), rn(node->w.w)); \
1464 patch(word, node); \
1467 #define case_brw(name, type) \
1468 case jit_code_##name##i##type: \
1470 assert(temp->code == jit_code_label || \
1471 temp->code == jit_code_epilog); \
1472 if (temp->flag & jit_flag_patch) \
1473 name##i##type(temp->u.w, \
1474 rn(node->v.w), node->w.w); \
1476 word = name##i##type(_jit->pc.w, \
1477 rn(node->v.w), node->w.w); \
1478 patch(word, node); \
1481 #define case_brf(name, type, size) \
1482 case jit_code_##name##i##type: \
1484 assert(temp->code == jit_code_label || \
1485 temp->code == jit_code_epilog); \
1486 if (temp->flag & jit_flag_patch) \
1487 name##i##type(temp->u.w, rn(node->v.w), \
1488 (jit_float##size##_t *)node->w.n->u.w); \
1490 word = name##i##type(_jit->pc.w, rn(node->v.w), \
1491 (jit_float##size##_t *)node->w.n->u.w); \
1492 patch(word, node); \
1495 #if DEVEL_DISASSEMBLER
1498 for (node = _jitc->head; node; node = node->next) {
1499 if (_jit->pc.uc >= _jitc->code.end)
1502 #if DEVEL_DISASSEMBLER
1503 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1505 if (_jitc->inst.pend) {
1510 value = jit_classify(node->code);
1514 jit_regarg_set(node, value);
1515 switch (node->code) {
1516 case jit_code_align:
1517 /* Must align to a power of two */
1518 assert(!(node->u.w & (node->u.w - 1)));
1520 if ((word = _jit->pc.w & (node->u.w - 1)))
1521 nop(node->u.w - word);
1526 nop((node->u.w + 3) & ~3);
1529 case jit_code_note: case jit_code_name:
1531 node->u.w = _jit->pc.w;
1533 case jit_code_label:
1535 /* remember label is defined */
1536 node->flag |= jit_flag_patch;
1537 node->u.w = _jit->pc.w;
1560 case_rrrr(qmul, _u);
1561 case_rrrw(qmul, _u);
1568 case_rrrr(qdiv, _u);
1569 case_rrrw(qdiv, _u);
1578 case_rrrr(qlsh, _u);
1579 case_rrrw(qlsh, _u);
1586 case_rrrr(qrsh, _u);
1587 case_rrrw(qrsh, _u);
1598 case_rr(trunc, _f_i);
1599 case_rr(trunc, _d_i);
1600 #if __WORDSIZE == 64
1601 case_rr(trunc, _f_l);
1602 case_rr(trunc, _d_l);
1614 #if __WORDSIZE == 64
1630 #if __WORDSIZE == 64
1636 case jit_code_unldr:
1637 unldr(rn(node->u.w), rn(node->v.w), node->w.w);
1639 case jit_code_unldi:
1640 unldi(rn(node->u.w), node->v.w, node->w.w);
1642 case jit_code_unldr_u:
1643 unldr_u(rn(node->u.w), rn(node->v.w), node->w.w);
1645 case jit_code_unldi_u:
1646 unldi_u(rn(node->u.w), node->v.w, node->w.w);
1654 #if __WORDSIZE == 64
1664 #if __WORDSIZE == 64
1668 case jit_code_unstr:
1669 unstr(rn(node->u.w), rn(node->v.w), node->w.w);
1671 case jit_code_unsti:
1672 unsti(node->u.w, rn(node->v.w), node->w.w);
1676 #if __WORDSIZE == 64
1679 case_rr(bswap, _us);
1680 case_rr(bswap, _ui);
1681 #if __WORDSIZE == 64
1682 case_rr(bswap, _ul);
1685 extr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1687 case jit_code_extr_u:
1688 extr_u(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1691 depr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1694 depi(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1700 #if __WORDSIZE == 64
1705 casr(rn(node->u.w), rn(node->v.w),
1706 rn(node->w.q.l), rn(node->w.q.h));
1709 casi(rn(node->u.w), node->v.w,
1710 rn(node->w.q.l), rn(node->w.q.h));
1716 if (node->flag & jit_flag_node) {
1718 if (temp->code == jit_code_data ||
1719 (temp->code == jit_code_label &&
1720 (temp->flag & jit_flag_patch)))
1721 movi(rn(node->u.w), temp->u.w);
1723 assert(temp->code == jit_code_label ||
1724 temp->code == jit_code_epilog);
1725 word = movi_p(rn(node->u.w), node->v.w);
1730 movi(rn(node->u.w), node->v.w);
1739 #define popcntr(r0, r1) fallback_popcnt(r0, r1)
1783 case_brr(boadd, _u);
1784 case_brw(boadd, _u);
1787 case_brr(bxadd, _u);
1788 case_brw(bxadd, _u);
1791 case_brr(bosub, _u);
1792 case_brw(bosub, _u);
1795 case_brr(bxsub, _u);
1796 case_brw(bxsub, _u);
1802 case_rrf(add, _f, 32);
1804 case_rrf(sub, _f, 32);
1805 case_rrf(rsb, _f, 32);
1807 case_rrf(mul, _f, 32);
1809 case_rrf(div, _f, 32);
1822 case jit_code_unldr_x:
1823 unldr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1825 case jit_code_unldi_x:
1826 unldi_x(rn(node->u.w), node->v.w, node->w.w);
1832 case jit_code_unstr_x:
1833 unstr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1835 case jit_code_unsti_x:
1836 unsti_x(node->u.w, rn(node->v.w), node->w.w);
1839 case jit_code_movi_f:
1840 assert(node->flag & jit_flag_data);
1841 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1845 case_rrf(lt, _f, 32);
1847 case_rrf(le, _f, 32);
1849 case_rrf(eq, _f, 32);
1851 case_rrf(ge, _f, 32);
1853 case_rrf(gt, _f, 32);
1855 case_rrf(ne, _f, 32);
1857 case_rrf(unlt, _f, 32);
1859 case_rrf(unle, _f, 32);
1861 case_rrf(uneq, _f, 32);
1863 case_rrf(unge, _f, 32);
1865 case_rrf(ungt, _f, 32);
1867 case_rrf(ltgt, _f, 32);
1869 case_rrf(ord, _f, 32);
1870 case_rrr(unord, _f);
1871 case_rrf(unord, _f, 32);
1873 case_brf(blt, _f, 32);
1875 case_brf(ble, _f, 32);
1877 case_brf(beq, _f, 32);
1879 case_brf(bge, _f, 32);
1881 case_brf(bgt, _f, 32);
1883 case_brf(bne, _f, 32);
1884 case_brr(bunlt, _f);
1885 case_brf(bunlt, _f, 32);
1886 case_brr(bunle, _f);
1887 case_brf(bunle, _f, 32);
1888 case_brr(buneq, _f);
1889 case_brf(buneq, _f, 32);
1890 case_brr(bunge, _f);
1891 case_brf(bunge, _f, 32);
1892 case_brr(bungt, _f);
1893 case_brf(bungt, _f, 32);
1894 case_brr(bltgt, _f);
1895 case_brf(bltgt, _f, 32);
1897 case_brf(bord, _f, 32);
1898 case_brr(bunord, _f);
1899 case_brf(bunord, _f, 32);
1901 case_rrf(add, _d, 64);
1903 case_rrf(sub, _d, 64);
1904 case_rrf(rsb, _d, 64);
1906 case_rrf(mul, _d, 64);
1908 case_rrf(div, _d, 64);
1926 case jit_code_movi_d:
1927 assert(node->flag & jit_flag_data);
1928 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1932 case_rrf(lt, _d, 64);
1934 case_rrf(le, _d, 64);
1936 case_rrf(eq, _d, 64);
1938 case_rrf(ge, _d, 64);
1940 case_rrf(gt, _d, 64);
1942 case_rrf(ne, _d, 64);
1944 case_rrf(unlt, _d, 64);
1946 case_rrf(unle, _d, 64);
1948 case_rrf(uneq, _d, 64);
1950 case_rrf(unge, _d, 64);
1952 case_rrf(ungt, _d, 64);
1954 case_rrf(ltgt, _d, 64);
1956 case_rrf(ord, _d, 64);
1957 case_rrr(unord, _d);
1958 case_rrf(unord, _d, 64);
1960 case_brf(blt, _d, 64);
1962 case_brf(ble, _d, 64);
1964 case_brf(beq, _d, 64);
1966 case_brf(bge, _d, 64);
1968 case_brf(bgt, _d, 64);
1970 case_brf(bne, _d, 64);
1971 case_brr(bunlt, _d);
1972 case_brf(bunlt, _d, 64);
1973 case_brr(bunle, _d);
1974 case_brf(bunle, _d, 64);
1975 case_brr(buneq, _d);
1976 case_brf(buneq, _d, 64);
1977 case_brr(bunge, _d);
1978 case_brf(bunge, _d, 64);
1979 case_brr(bungt, _d);
1980 case_brf(bungt, _d, 64);
1981 case_brr(bltgt, _d);
1982 case_brf(bltgt, _d, 64);
1984 case_brf(bord, _d, 64);
1985 case_brr(bunord, _d);
1986 case_brf(bunord, _d, 64);
1989 jmpr(rn(node->u.w));
1992 if (node->flag & jit_flag_node) {
1994 assert(temp->code == jit_code_label ||
1995 temp->code == jit_code_epilog);
1996 if (temp->flag & jit_flag_patch)
1999 word = _jit->code.length -
2000 (_jit->pc.uc - _jit->code.ptr);
2001 if ((jit_mips2_p() && can_relative_jump_p(word))
2004 (jit_mips6_p() && can_compact_jump_p(word))
2007 word = jmpi(_jit->pc.w, 1);
2009 word = jmpi_p(_jit->pc.w);
2018 case jit_code_callr:
2020 callr(rn(node->u.w));
2022 case jit_code_calli:
2023 if (node->flag & jit_flag_node) {
2025 assert(temp->code == jit_code_label ||
2026 temp->code == jit_code_epilog);
2027 if (temp->flag & jit_flag_patch)
2028 calli(temp->u.w, 0);
2030 word = _jit->code.length -
2031 (_jit->pc.uc - _jit->code.ptr);
2032 if ((jit_mips2_p() && can_relative_jump_p(word))
2035 (jit_mips6_p() && can_compact_jump_p(word))
2038 word = calli(_jit->pc.w, 1);
2040 word = calli_p(_jit->pc.w);
2046 calli(node->u.w, 0);
2049 case jit_code_prolog:
2051 _jitc->function = _jitc->functions.ptr + node->w.w;
2053 undo.word = _jit->pc.w;
2054 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
2055 #if DEVEL_DISASSEMBLER
2058 undo.patch_offset = _jitc->patches.offset;
2061 compute_framesize();
2065 case jit_code_epilog:
2066 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
2068 for (temp = undo.node->next;
2069 temp != node; temp = temp->next) {
2070 if (temp->code == jit_code_label ||
2071 temp->code == jit_code_epilog)
2072 temp->flag &= ~jit_flag_patch;
2074 temp->flag &= ~jit_flag_patch;
2076 _jit->pc.w = undo.word;
2077 /* undo.func.self.aoff and undo.func.regset should not
2078 * be undone, as they will be further updated, and are
2079 * the reason of the undo. */
2080 undo.func.self.aoff = _jitc->function->frame +
2081 _jitc->function->self.aoff;
2082 undo.func.need_frame = _jitc->function->need_frame;
2083 jit_regset_set(&undo.func.regset, &_jitc->function->regset);
2084 /* allocar information also does not need to be undone */
2085 undo.func.aoffoff = _jitc->function->aoffoff;
2086 undo.func.allocar = _jitc->function->allocar;
2087 /* this will be recomputed but undo anyway to have it
2088 * better self documented.*/
2089 undo.func.need_stack = _jitc->function->need_stack;
2090 memcpy(_jitc->function, &undo.func, sizeof(undo.func));
2091 #if DEVEL_DISASSEMBLER
2094 _jitc->patches.offset = undo.patch_offset;
2096 goto restart_function;
2098 /* remember label is defined */
2100 node->flag |= jit_flag_patch;
2101 node->u.w = _jit->pc.w;
2103 _jitc->function = NULL;
2105 case jit_code_movr_w_f:
2106 movr_w_f(rn(node->u.w), rn(node->v.w));
2108 case jit_code_movr_f_w:
2109 movr_f_w(rn(node->u.w), rn(node->v.w));
2111 case jit_code_movi_f_w:
2112 assert(node->flag & jit_flag_data);
2113 movi_f_w(rn(node->u.w), *(jit_float32_t *)node->v.n->u.w);
2115 case jit_code_movi_w_f:
2116 movi_w_f(rn(node->u.w), node->v.w);
2118 #if __WORDSIZE == 64 || NEW_ABI
2119 case jit_code_movr_d_w:
2120 movr_d_w(rn(node->u.w), rn(node->v.w));
2122 case jit_code_movi_d_w:
2123 assert(node->flag & jit_flag_data);
2124 movi_d_w(rn(node->u.w), *(jit_float64_t *)node->v.n->u.w);
2126 case jit_code_movr_w_d:
2127 movr_w_d(rn(node->u.w), rn(node->v.w));
2129 case jit_code_movi_w_d:
2130 movi_w_d(rn(node->u.w), node->v.w);
2133 #if __WORDSIZE == 32
2134 case jit_code_movr_ww_d:
2135 movr_ww_d(rn(node->u.w), rn(node->v.w), rn(node->w.w));
2137 case jit_code_movr_d_ww:
2138 movr_d_ww(rn(node->u.w), rn(node->v.w), rn(node->w.w));
2140 case jit_code_movi_d_ww:
2141 assert(node->flag & jit_flag_data);
2142 movi_d_ww(rn(node->u.w), rn(node->v.w),
2143 *(jit_float64_t *)node->w.n->u.w);
2145 case jit_code_movi_ww_d:
2146 movi_ww_d(rn(node->u.w), node->v.w, node->w.w);
2149 case jit_code_va_start:
2150 vastart(rn(node->u.w));
2152 case jit_code_va_arg:
2153 vaarg(rn(node->u.w), rn(node->v.w));
2155 case jit_code_va_arg_d:
2156 vaarg_d(rn(node->u.w), rn(node->v.w));
2158 case jit_code_live: case jit_code_ellipsis:
2159 case jit_code_va_push:
2160 case jit_code_allocai: case jit_code_allocar:
2161 case jit_code_arg_c: case jit_code_arg_s:
2162 case jit_code_arg_i:
2163 # if __WORDSIZE == 64
2164 case jit_code_arg_l:
2166 case jit_code_arg_f: case jit_code_arg_d:
2167 case jit_code_va_end:
2169 case jit_code_retr_c: case jit_code_reti_c:
2170 case jit_code_retr_uc: case jit_code_reti_uc:
2171 case jit_code_retr_s: case jit_code_reti_s:
2172 case jit_code_retr_us: case jit_code_reti_us:
2173 case jit_code_retr_i: case jit_code_reti_i:
2174 #if __WORDSIZE == 64
2175 case jit_code_retr_ui: case jit_code_reti_ui:
2176 case jit_code_retr_l: case jit_code_reti_l:
2178 case jit_code_retr_f: case jit_code_reti_f:
2179 case jit_code_retr_d: case jit_code_reti_d:
2180 case jit_code_getarg_c: case jit_code_getarg_uc:
2181 case jit_code_getarg_s: case jit_code_getarg_us:
2182 case jit_code_getarg_i:
2183 #if __WORDSIZE == 64
2184 case jit_code_getarg_ui: case jit_code_getarg_l:
2186 case jit_code_getarg_f: case jit_code_getarg_d:
2187 case jit_code_putargr_c: case jit_code_putargi_c:
2188 case jit_code_putargr_uc: case jit_code_putargi_uc:
2189 case jit_code_putargr_s: case jit_code_putargi_s:
2190 case jit_code_putargr_us: case jit_code_putargi_us:
2191 case jit_code_putargr_i: case jit_code_putargi_i:
2192 #if __WORDSIZE == 64
2193 case jit_code_putargr_ui: case jit_code_putargi_ui:
2194 case jit_code_putargr_l: case jit_code_putargi_l:
2196 case jit_code_putargr_f: case jit_code_putargi_f:
2197 case jit_code_putargr_d: case jit_code_putargi_d:
2198 case jit_code_pushargr_c: case jit_code_pushargi_c:
2199 case jit_code_pushargr_uc: case jit_code_pushargi_uc:
2200 case jit_code_pushargr_s: case jit_code_pushargi_s:
2201 case jit_code_pushargr_us: case jit_code_pushargi_us:
2202 case jit_code_pushargr_i: case jit_code_pushargi_i:
2203 #if __WORDSIZE == 64
2204 case jit_code_pushargr_ui: case jit_code_pushargi_ui:
2205 case jit_code_pushargr_l: case jit_code_pushargi_l:
2207 case jit_code_pushargr_f: case jit_code_pushargi_f:
2208 case jit_code_pushargr_d: case jit_code_pushargi_d:
2209 case jit_code_retval_c: case jit_code_retval_uc:
2210 case jit_code_retval_s: case jit_code_retval_us:
2211 case jit_code_retval_i:
2212 #if __WORDSIZE == 64
2213 case jit_code_retval_ui: case jit_code_retval_l:
2215 case jit_code_retval_f: case jit_code_retval_d:
2216 case jit_code_prepare:
2217 case jit_code_finishr: case jit_code_finishi:
2218 case jit_code_negi_f: case jit_code_absi_f:
2219 case jit_code_sqrti_f: case jit_code_negi_d:
2220 case jit_code_absi_d: case jit_code_sqrti_d:
2223 negi(rn(node->u.w), node->v.w);
2226 comi(rn(node->u.w), node->v.w);
2228 case jit_code_exti_c:
2229 exti_c(rn(node->u.w), node->v.w);
2231 case jit_code_exti_uc:
2232 exti_uc(rn(node->u.w), node->v.w);
2234 case jit_code_exti_s:
2235 exti_s(rn(node->u.w), node->v.w);
2237 case jit_code_exti_us:
2238 exti_us(rn(node->u.w), node->v.w);
2240 case jit_code_bswapi_us:
2241 bswapi_us(rn(node->u.w), node->v.w);
2243 case jit_code_bswapi_ui:
2244 bswapi_ui(rn(node->u.w), node->v.w);
2246 case jit_code_htoni_us:
2247 htoni_us(rn(node->u.w), node->v.w);
2249 case jit_code_htoni_ui:
2250 htoni_ui(rn(node->u.w), node->v.w);
2252 #if __WORDSIZE == 64
2253 case jit_code_exti_i:
2254 exti_i(rn(node->u.w), node->v.w);
2256 case jit_code_exti_ui:
2257 exti_ui(rn(node->u.w), node->v.w);
2259 case jit_code_bswapi_ul:
2260 bswapi_ul(rn(node->u.w), node->v.w);
2262 case jit_code_htoni_ul:
2263 htoni_ul(rn(node->u.w), node->v.w);
2267 cloi(rn(node->u.w), node->v.w);
2270 clzi(rn(node->u.w), node->v.w);
2273 ctoi(rn(node->u.w), node->v.w);
2276 ctzi(rn(node->u.w), node->v.w);
2278 case jit_code_rbiti:
2279 rbiti(rn(node->u.w), node->v.w);
2281 case jit_code_popcnti:
2282 popcnti(rn(node->u.w), node->v.w);
2285 exti(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
2287 case jit_code_exti_u:
2288 exti_u(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
2293 if (jit_carry != _NOREG) {
2294 switch (node->code) {
2296 case jit_code_addcr: case jit_code_addci:
2297 case jit_code_addxr: case jit_code_addxi:
2298 case jit_code_subcr: case jit_code_subci:
2299 case jit_code_subxr: case jit_code_subxi:
2302 jit_unget_reg(jit_carry);
2310 jit_regarg_clr(node, value);
2311 assert(_jitc->regarg == 0 ||
2312 (jit_carry != _NOREG && _jitc->regarg == (1 << jit_carry)));
2313 assert(_jitc->synth == 0);
2314 /* update register live state */
2329 for (offset = 0; offset < _jitc->patches.offset; offset++) {
2330 node = _jitc->patches.ptr[offset].node;
2331 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
2332 patch_at(_jitc->patches.ptr[offset].inst, word);
2335 jit_flush(_jit->code.ptr, _jit->pc.uc);
2337 return (_jit->code.ptr);
2341 # include "jit_rewind.c"
2342 # include "jit_mips-cpu.c"
2343 # include "jit_mips-fpu.c"
2344 # include "jit_fallback.c"
2348 jit_flush(void *fptr, void *tptr)
2350 #if defined(__linux__)
2353 s = sysconf(_SC_PAGE_SIZE);
2354 f = (jit_word_t)fptr & -s;
2355 t = (((jit_word_t)tptr) + s - 1) & -s;
2356 _flush_cache((void *)f, t - f, ICACHE);
2361 _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2363 ldxi(rn(r0), rn(r1), i0);
2367 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2369 stxi(i0, rn(r0), rn(r1));
2373 _emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2375 ldxi_d(rn(r0), rn(r1), i0);
2379 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2381 stxi_d(i0, rn(r0), rn(r1));
2385 _compute_framesize(jit_state_t *_jit)
2388 _jitc->framesize = STACK_SLOT << 1; /* ra+fp */
2389 for (reg = 0; reg < jit_size(iregs); reg++)
2390 if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg]))
2391 _jitc->framesize += STACK_SLOT;
2393 for (reg = 0; reg < jit_size(fregs); reg++)
2394 if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg]))
2395 _jitc->framesize += sizeof(jit_float64_t);
2398 /* Space to store variadic arguments */
2399 if (_jitc->function->self.call & jit_call_varargs)
2400 _jitc->framesize += (NUM_WORD_ARGS - _jitc->function->vagp) * STACK_SLOT;
2403 /* Make sure functions called have a 16 byte aligned stack */
2404 _jitc->framesize = (_jitc->framesize + 15) & -16;
2408 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
2412 assert(node->flag & jit_flag_node);
2413 if (node->code == jit_code_movi)
2414 flag = node->v.n->flag;
2416 flag = node->u.n->flag;
2417 assert(!(flag & jit_flag_patch));
2418 if (_jitc->patches.offset >= _jitc->patches.length) {
2419 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
2420 _jitc->patches.length * sizeof(jit_patch_t),
2421 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
2422 _jitc->patches.length += 1024;
2424 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
2425 _jitc->patches.ptr[_jitc->patches.offset].node = node;
2426 ++_jitc->patches.offset;