2 * Copyright (C) 2022-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[0-8]+fs[0-7]) + align16(a[0-7]) */
22 #define stack_framesize (144 + 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 struct jit_pointer_t jit_va_list_t;
35 #define compute_framesize() _compute_framesize(_jit)
36 static void _compute_framesize(jit_state_t*);
37 #define patch(instr, node) _patch(_jit, instr, node)
38 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
41 # include "jit_loongarch-cpu.c"
42 # include "jit_loongarch-fpu.c"
43 # include "jit_fallback.c"
50 jit_register_t _rvs[] = {
51 { rc(gpr) | 0x14, "$t8" },
52 { rc(gpr) | 0x13, "$t7" },
53 { rc(gpr) | 0x12, "$t6" },
54 { rc(gpr) | 0x11, "$t5" },
55 { rc(gpr) | 0x10, "$t4" },
56 { rc(gpr) | 0x0f, "$t3" },
57 { rc(gpr) | 0x0e, "$t2" },
58 { rc(gpr) | 0x0d, "$t1" },
59 { rc(gpr) | 0x0c, "$t0" },
60 { rc(sav) | rc(gpr) | 0x1f, "$s8" },
61 { rc(sav) | rc(gpr) | 0x1e, "$s7" },
62 { rc(sav) | rc(gpr) | 0x1d, "$s6" },
63 { rc(sav) | rc(gpr) | 0x1c, "$s5" },
64 { rc(sav) | rc(gpr) | 0x1b, "$s4" },
65 { rc(sav) | rc(gpr) | 0x1a, "$s3" },
66 { rc(sav) | rc(gpr) | 0x19, "$s2" },
67 { rc(sav) | rc(gpr) | 0x18, "$s1" },
68 { rc(sav) | rc(gpr) | 0x17, "$s0" },
69 { rc(arg) | rc(gpr) | 0x0b, "$a7" },
70 { rc(arg) | rc(gpr) | 0x0a, "$a6" },
71 { rc(arg) | rc(gpr) | 0x09, "$a5" },
72 { rc(arg) | rc(gpr) | 0x08, "$a4" },
73 { rc(arg) | rc(gpr) | 0x07, "$a3" },
74 { rc(arg) | rc(gpr) | 0x06, "$a2" },
75 { rc(arg) | rc(gpr) | 0x05, "$a1" },
76 { rc(arg) | rc(gpr) | 0x04, "$a0" },
78 { 0x15, "<reserved>" },
83 { rc(fpr) | 0x08, "$ft0" },
84 { rc(fpr) | 0x09, "$ft1" },
85 { rc(fpr) | 0x0a, "$ft2" },
86 { rc(fpr) | 0x0b, "$ft3" },
87 { rc(fpr) | 0x0c, "$ft4" },
88 { rc(fpr) | 0x0d, "$ft5" },
89 { rc(fpr) | 0x0e, "$ft6" },
90 { rc(fpr) | 0x0f, "$ft7" },
91 { rc(fpr) | 0x10, "$ft8" },
92 { rc(fpr) | 0x11, "$ft9" },
93 { rc(fpr) | 0x12, "$ft10" },
94 { rc(fpr) | 0x13, "$ft11" },
95 { rc(fpr) | 0x14, "$ft12" },
96 { rc(fpr) | 0x15, "$ft13" },
97 { rc(fpr) | 0x16, "$ft14" },
98 { rc(fpr) | 0x17, "$ft15" },
99 { rc(arg) | rc(fpr) | 0x07, "$fa7" },
100 { rc(arg) | rc(fpr) | 0x06, "$fa6" },
101 { rc(arg) | rc(fpr) | 0x05, "$fa5" },
102 { rc(arg) | rc(fpr) | 0x04, "$fa4" },
103 { rc(arg) | rc(fpr) | 0x03, "$fa3" },
104 { rc(arg) | rc(fpr) | 0x02, "$fa2" },
105 { rc(arg) | rc(fpr) | 0x01, "$fa1" },
106 { rc(arg) | rc(fpr) | 0x00, "$fa0" },
107 { rc(sav) | rc(fpr) | 0x1f, "$fs7" },
108 { rc(sav) | rc(fpr) | 0x1e, "$fs6" },
109 { rc(sav) | rc(fpr) | 0x1d, "$fs5" },
110 { rc(sav) | rc(fpr) | 0x1c, "$fs4" },
111 { rc(sav) | rc(fpr) | 0x1b, "$fs3" },
112 { rc(sav) | rc(fpr) | 0x1a, "$fs2" },
113 { rc(sav) | rc(fpr) | 0x19, "$fs1" },
114 { rc(sav) | rc(fpr) | 0x18, "$fs0" },
115 { _NOREG, "<none>" },
118 static jit_int32_t iregs[] = {
119 _S0, _S1, _S2, _S3, _S4, _S5, _S6, _S7, _S8
122 static jit_int32_t fregs[] = {
123 _FS0, _FS1, _FS2, _FS3, _FS4, _FS5, _FS6, _FS7
135 _jit_init(jit_state_t *_jit)
137 _jitc->reglen = jit_size(_rvs) - 1;
139 /* By default assume kernel or cpu will handle unaligned load/store */
140 jit_cpu.unaligned = 0;
144 _jit_prolog(jit_state_t *_jit)
150 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
151 jit_regset_set_ui(&_jitc->regsav, 0);
152 offset = _jitc->functions.offset;
153 if (offset >= _jitc->functions.length) {
154 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
155 _jitc->functions.length * sizeof(jit_function_t),
156 (_jitc->functions.length + 16) * sizeof(jit_function_t));
157 _jitc->functions.length += 16;
159 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
160 _jitc->function->self.size = stack_framesize;
161 _jitc->function->self.argi = _jitc->function->self.argf =
162 _jitc->function->self.aoff = _jitc->function->self.alen = 0;
163 _jitc->function->self.call = jit_call_default;
164 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
165 _jitc->reglen * sizeof(jit_int32_t));
167 /* _no_link here does not mean the jit_link() call can be removed
169 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
171 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
172 jit_link(_jitc->function->prolog);
173 _jitc->function->prolog->w.w = offset;
174 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
176 * v: offset in blocks vector
177 * w: offset in functions vector
179 _jitc->function->epilog->w.w = offset;
181 jit_regset_new(&_jitc->function->regset);
185 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
187 assert(_jitc->function);
190 case 0: case 1: break;
191 case 2: _jitc->function->self.aoff &= -2; break;
192 case 3: case 4: _jitc->function->self.aoff &= -4; break;
193 default: _jitc->function->self.aoff &= -8; break;
195 _jitc->function->self.aoff -= length;
196 if (!_jitc->realize) {
197 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
200 return (_jitc->function->self.aoff);
204 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
207 assert(_jitc->function);
208 jit_inc_synth_ww(allocar, u, v);
209 if (!_jitc->function->allocar) {
210 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
211 _jitc->function->allocar = 1;
213 reg = jit_get_reg(jit_class_gpr);
215 jit_andi(reg, reg, -16);
216 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
218 jit_addr(JIT_SP, JIT_SP, reg);
219 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
225 _jit_ret(jit_state_t *_jit)
228 assert(_jitc->function);
232 jit_patch_at(instr, _jitc->function->epilog);
237 _jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
239 jit_code_inc_synth_w(code, u);
240 jit_movr(JIT_RET, u);
246 _jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
248 jit_code_inc_synth_w(code, u);
249 jit_movi(JIT_RET, u);
255 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
257 jit_inc_synth_w(retr_f, u);
259 jit_movr_f(JIT_FRET, u);
267 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
269 jit_inc_synth_f(reti_f, u);
270 jit_movi_f(JIT_FRET, u);
276 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
278 jit_inc_synth_w(retr_d, u);
280 jit_movr_d(JIT_FRET, u);
288 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
290 jit_inc_synth_d(reti_d, u);
291 jit_movi_d(JIT_FRET, u);
297 _jit_epilog(jit_state_t *_jit)
299 assert(_jitc->function);
300 assert(_jitc->function->epilog->next == NULL);
301 jit_link(_jitc->function->epilog);
302 _jitc->function = NULL;
306 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
308 if (u->code >= jit_code_arg_c && u->code <= jit_code_arg)
309 return (jit_arg_reg_p(u->u.w));
310 assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
311 return (jit_arg_f_reg_p(u->u.w) || jit_arg_reg_p(u->u.w - 8));
315 _jit_ellipsis(jit_state_t *_jit)
317 jit_inc_synth(ellipsis);
319 if (_jitc->prepare) {
321 assert(!(_jitc->function->call.call & jit_call_varargs));
322 _jitc->function->call.call |= jit_call_varargs;
326 assert(!(_jitc->function->self.call & jit_call_varargs));
327 _jitc->function->self.call |= jit_call_varargs;
328 _jitc->function->vagp = _jitc->function->self.argi;
334 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
336 jit_inc_synth_w(va_push, u);
342 _jit_arg(jit_state_t *_jit, jit_code_t code)
346 assert(_jitc->function);
347 assert(!(_jitc->function->self.call & jit_call_varargs));
348 #if STRONG_TYPE_CHECKING
349 assert(code >= jit_code_arg_c && code <= jit_code_arg);
351 if (jit_arg_reg_p(_jitc->function->self.argi))
352 offset = _jitc->function->self.argi++;
354 offset = _jitc->function->self.size;
355 _jitc->function->self.size += sizeof(jit_word_t);
358 node = jit_new_node_ww(code, offset,
359 ++_jitc->function->self.argn);
365 _jit_arg_f(jit_state_t *_jit)
369 assert(_jitc->function);
370 assert(!(_jitc->function->self.call & jit_call_varargs));
371 if (jit_arg_f_reg_p(_jitc->function->self.argf))
372 offset = _jitc->function->self.argf++;
373 else if (jit_arg_reg_p(_jitc->function->self.argi)) {
374 offset = _jitc->function->self.argi++;
378 offset = _jitc->function->self.size;
379 _jitc->function->self.size += sizeof(jit_word_t);
382 node = jit_new_node_ww(jit_code_arg_f, offset,
383 ++_jitc->function->self.argn);
389 _jit_arg_d(jit_state_t *_jit)
393 assert(_jitc->function);
394 assert(!(_jitc->function->self.call & jit_call_varargs));
395 if (jit_arg_f_reg_p(_jitc->function->self.argf))
396 offset = _jitc->function->self.argf++;
397 else if (jit_arg_reg_p(_jitc->function->self.argi)) {
398 offset = _jitc->function->self.argi++;
402 offset = _jitc->function->self.size;
403 _jitc->function->self.size += sizeof(jit_word_t);
406 node = jit_new_node_ww(jit_code_arg_d, offset,
407 ++_jitc->function->self.argn);
413 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
415 assert_arg_type(v->code, jit_code_arg_c);
416 jit_inc_synth_wp(getarg_c, u, v);
417 if (jit_arg_reg_p(v->u.w))
418 jit_extr_c(u, _A0 - v->u.w);
420 jit_node_t *node = jit_ldxi_c(u, JIT_FP, v->u.w);
421 jit_link_alist(node);
427 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
429 assert_arg_type(v->code, jit_code_arg_c);
430 jit_inc_synth_wp(getarg_uc, u, v);
431 if (jit_arg_reg_p(v->u.w))
432 jit_extr_uc(u, _A0 - v->u.w);
434 jit_node_t *node = jit_ldxi_uc(u, JIT_FP, v->u.w);
435 jit_link_alist(node);
441 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
443 assert_arg_type(v->code, jit_code_arg_s);
444 jit_inc_synth_wp(getarg_s, u, v);
445 if (jit_arg_reg_p(v->u.w))
446 jit_extr_s(u, _A0 - v->u.w);
448 jit_node_t *node = jit_ldxi_s(u, JIT_FP, v->u.w);
449 jit_link_alist(node);
455 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
457 assert_arg_type(v->code, jit_code_arg_s);
458 jit_inc_synth_wp(getarg_us, u, v);
459 if (jit_arg_reg_p(v->u.w))
460 jit_extr_us(u, _A0 - v->u.w);
462 jit_node_t *node = jit_ldxi_us(u, JIT_FP, v->u.w);
463 jit_link_alist(node);
469 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
471 assert_arg_type(v->code, jit_code_arg_i);
472 jit_inc_synth_wp(getarg_i, u, v);
473 if (jit_arg_reg_p(v->u.w))
474 jit_extr_i(u, _A0 - v->u.w);
476 jit_node_t *node = jit_ldxi_i(u, JIT_FP, v->u.w);
477 jit_link_alist(node);
483 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
485 assert_arg_type(v->code, jit_code_arg_i);
486 jit_inc_synth_wp(getarg_ui, u, v);
487 if (jit_arg_reg_p(v->u.w))
488 jit_extr_ui(u, _A0 - v->u.w);
490 jit_node_t *node = jit_ldxi_ui(u, JIT_FP, v->u.w);
491 jit_link_alist(node);
497 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
499 assert_arg_type(v->code, jit_code_arg_l);
500 jit_inc_synth_wp(getarg_l, u, v);
501 if (jit_arg_reg_p(v->u.w))
502 jit_movr(u, _A0 - v->u.w);
504 jit_node_t *node = jit_ldxi_l(u, JIT_FP, v->u.w);
505 jit_link_alist(node);
511 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
513 assert_putarg_type(code, v->code);
514 jit_code_inc_synth_wp(code, u, v);
515 if (jit_arg_reg_p(v->u.w))
516 jit_movr(_A0 - v->u.w, u);
518 jit_node_t *node = jit_stxi(v->u.w, JIT_FP, u);
519 jit_link_alist(node);
525 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
528 assert_putarg_type(code, v->code);
529 jit_code_inc_synth_wp(code, u, v);
530 if (jit_arg_reg_p(v->u.w))
531 jit_movi(_A0 - v->u.w, u);
534 regno = jit_get_reg(jit_class_gpr);
536 node = jit_stxi(v->u.w, JIT_FP, regno);
537 jit_link_alist(node);
538 jit_unget_reg(regno);
544 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
546 assert(v->code == jit_code_arg_f);
547 jit_inc_synth_wp(getarg_f, u, v);
548 if (jit_arg_f_reg_p(v->u.w))
549 jit_movr_f(u, _FA0 - v->u.w);
550 else if (jit_arg_reg_p(v->u.w - 8))
551 jit_movr_w_f(u, JIT_RA0 - (v->u.w - 8));
553 jit_node_t *node = jit_ldxi_f(u, JIT_FP, v->u.w);
554 jit_link_alist(node);
560 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
562 assert(v->code == jit_code_arg_f);
563 jit_inc_synth_wp(putargr_f, u, v);
564 if (jit_arg_f_reg_p(v->u.w))
565 jit_movr_f(_FA0 - v->u.w, u);
566 else if (jit_arg_reg_p(v->u.w - 8))
567 jit_movr_f_w(JIT_RA0 - (v->u.w - 8), u);
569 jit_node_t *node = jit_stxi_f(v->u.w, JIT_FP, u);
570 jit_link_alist(node);
576 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
579 assert(v->code == jit_code_arg_f);
580 jit_inc_synth_fp(putargi_f, u, v);
581 if (jit_arg_f_reg_p(v->u.w))
582 jit_movi_f(_FA0 - v->u.w, u);
583 else if (jit_arg_reg_p(v->u.w - 8))
584 jit_movi_f_w(JIT_RA0 - (v->u.w - 8), u);
587 regno = jit_get_reg(jit_class_fpr);
588 jit_movi_f(regno, u);
589 node = jit_stxi_f(v->u.w, JIT_FP, regno);
590 jit_link_alist(node);
591 jit_unget_reg(regno);
597 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
599 assert(v->code == jit_code_arg_d);
600 jit_inc_synth_wp(getarg_d, u, v);
601 if (jit_arg_f_reg_p(v->u.w))
602 jit_movr_d(u, _FA0 - v->u.w);
603 else if (jit_arg_reg_p(v->u.w - 8))
604 jit_movr_w_d(u, JIT_RA0 - (v->u.w - 8));
606 jit_node_t *node = jit_ldxi_d(u, JIT_FP, v->u.w);
607 jit_link_alist(node);
613 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
615 assert(v->code == jit_code_arg_d);
616 jit_inc_synth_wp(putargr_d, u, v);
617 if (jit_arg_f_reg_p(v->u.w))
618 jit_movr_d(_FA0 - v->u.w, u);
619 else if (jit_arg_reg_p(v->u.w - 8))
620 jit_movr_d_w(JIT_RA0 - (v->u.w - 8), u);
622 jit_node_t *node = jit_stxi_d(v->u.w, JIT_FP, u);
623 jit_link_alist(node);
629 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
632 assert(v->code == jit_code_arg_d);
633 jit_inc_synth_dp(putargi_d, u, v);
634 if (jit_arg_f_reg_p(v->u.w))
635 jit_movi_d(_FA0 - v->u.w, u);
636 else if (jit_arg_reg_p(v->u.w - 8))
637 jit_movi_d_w(JIT_RA0 - (v->u.w - 8), u);
640 regno = jit_get_reg(jit_class_fpr);
641 jit_movi_d(regno, u);
642 node = jit_stxi_d(v->u.w, JIT_FP, regno);
643 jit_link_alist(node);
644 jit_unget_reg(regno);
650 _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
652 assert(_jitc->function);
653 jit_code_inc_synth_w(code, u);
655 if (jit_arg_reg_p(_jitc->function->call.argi)) {
656 jit_movr(_A0 - _jitc->function->call.argi, u);
657 ++_jitc->function->call.argi;
660 jit_stxi(_jitc->function->call.size, JIT_SP, u);
661 _jitc->function->call.size += sizeof(jit_word_t);
668 _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
671 assert(_jitc->function);
672 jit_code_inc_synth_w(code, u);
674 if (jit_arg_reg_p(_jitc->function->call.argi)) {
675 jit_movi(_A0 - _jitc->function->call.argi, u);
676 ++_jitc->function->call.argi;
679 regno = jit_get_reg(jit_class_gpr);
681 jit_stxi(_jitc->function->call.size, JIT_SP, regno);
682 jit_unget_reg(regno);
683 _jitc->function->call.size += sizeof(jit_word_t);
690 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
692 assert(_jitc->function);
693 jit_inc_synth_w(pushargr_f, u);
695 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
696 !(_jitc->function->call.call & jit_call_varargs)) {
697 jit_movr_f(_FA0 - _jitc->function->call.argf, u);
698 ++_jitc->function->call.argf;
700 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
701 jit_movr_f_w(_A0 - _jitc->function->call.argi, u);
702 ++_jitc->function->call.argi;
705 jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
706 _jitc->function->call.size += sizeof(jit_word_t);
713 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
716 assert(_jitc->function);
717 jit_inc_synth_f(pushargi_f, u);
719 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
720 !(_jitc->function->call.call & jit_call_varargs)) {
721 jit_movi_f(_FA0 - _jitc->function->call.argf, u);
722 ++_jitc->function->call.argf;
724 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
725 jit_movi_f_w(_A0 - _jitc->function->call.argi, u);
726 ++_jitc->function->call.argi;
729 regno = jit_get_reg(jit_class_fpr);
730 jit_movi_f(regno, u);
731 jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
732 jit_unget_reg(regno);
733 _jitc->function->call.size += sizeof(jit_word_t);
740 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
742 assert(_jitc->function);
743 jit_inc_synth_w(pushargr_d, u);
745 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
746 !(_jitc->function->call.call & jit_call_varargs)) {
747 jit_movr_d(_FA0 - _jitc->function->call.argf, u);
748 ++_jitc->function->call.argf;
750 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
751 jit_movr_d_w(_A0 - _jitc->function->call.argi, u);
752 ++_jitc->function->call.argi;
755 jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
756 _jitc->function->call.size += sizeof(jit_word_t);
763 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
766 assert(_jitc->function);
767 jit_inc_synth_d(pushargi_d, u);
769 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
770 !(_jitc->function->call.call & jit_call_varargs)) {
771 jit_movi_d(_FA0 - _jitc->function->call.argf, u);
772 ++_jitc->function->call.argf;
774 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
775 jit_movi_d_w(_A0 - _jitc->function->call.argi, u);
776 ++_jitc->function->call.argi;
779 regno = jit_get_reg(jit_class_fpr);
780 jit_movi_d(regno, u);
781 jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
782 jit_unget_reg(regno);
783 _jitc->function->call.size += sizeof(jit_word_t);
790 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
793 spec = jit_class(_rvs[regno].spec);
794 if (spec & jit_class_arg) {
796 if (regno >= 0 && regno < node->v.w)
798 if (spec & jit_class_fpr) {
799 regno = _FA0 - regno;
800 if (regno >= 0 && regno < node->w.w)
808 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
811 assert(_jitc->function);
813 jit_inc_synth_w(finishr, r0);
814 if (_jitc->function->self.alen < _jitc->function->call.size)
815 _jitc->function->self.alen = _jitc->function->call.size;
816 node = jit_callr(r0);
817 node->v.w = _jitc->function->call.argi;
818 node->w.w = _jitc->function->call.argf;
819 _jitc->function->call.argi = _jitc->function->call.argf =
820 _jitc->function->call.size = 0;
826 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
829 assert(_jitc->function);
831 jit_inc_synth_w(finishi, (jit_word_t)i0);
832 if (_jitc->function->self.alen < _jitc->function->call.size)
833 _jitc->function->self.alen = _jitc->function->call.size;
834 node = jit_calli(i0);
835 node->v.w = _jitc->function->call.argi;
836 node->w.w = _jitc->function->call.argf;
837 _jitc->function->call.argi = _jitc->function->call.argf =
838 _jitc->function->call.size = 0;
845 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
847 jit_inc_synth_w(retval_c, r0);
848 jit_extr_c(r0, JIT_RET);
853 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
855 jit_inc_synth_w(retval_uc, r0);
856 jit_extr_uc(r0, JIT_RET);
861 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
863 jit_inc_synth_w(retval_s, r0);
864 jit_extr_s(r0, JIT_RET);
869 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
871 jit_inc_synth_w(retval_us, r0);
872 jit_extr_us(r0, JIT_RET);
877 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
879 jit_inc_synth_w(retval_i, r0);
880 jit_extr_i(r0, JIT_RET);
885 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
887 jit_inc_synth_w(retval_ui, r0);
888 jit_extr_ui(r0, JIT_RET);
893 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
895 jit_inc_synth_w(retval_l, r0);
897 jit_movr(r0, JIT_RET);
902 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
904 jit_inc_synth_w(retval_f, r0);
906 jit_movr_f(r0, JIT_FRET);
911 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
913 jit_inc_synth_w(retval_d, r0);
915 jit_movr_d(r0, JIT_FRET);
920 _emit_code(jit_state_t *_jit)
931 #if DEVEL_DISASSEMBLER
934 jit_int32_t patch_offset;
936 #if DEVEL_DISASSEMBLER
940 _jitc->function = NULL;
946 undo.patch_offset = 0;
948 #define assert_data(node) /**/
949 #define case_rr(name, type) \
950 case jit_code_##name##r##type: \
951 name##r##type(rn(node->u.w), rn(node->v.w)); \
953 #define case_rw(name, type) \
954 case jit_code_##name##i##type: \
955 name##i##type(rn(node->u.w), node->v.w); \
957 #define case_wr(name, type) \
958 case jit_code_##name##i##type: \
959 name##i##type(node->u.w, rn(node->v.w)); \
961 #define case_rrr(name, type) \
962 case jit_code_##name##r##type: \
963 name##r##type(rn(node->u.w), \
964 rn(node->v.w), rn(node->w.w)); \
966 #define case_rrrr(name, type) \
967 case jit_code_##name##r##type: \
968 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
969 rn(node->v.w), rn(node->w.w)); \
971 #define case_rqr(name, type) \
972 case jit_code_##name##r##type: \
973 name##r##type(rn(node->u.w), rn(node->v.q.l), \
974 rn(node->v.q.h), rn(node->w.w)); \
975 case jit_code_##name##i##type: \
977 #define case_rrw(name, type) \
978 case jit_code_##name##i##type: \
979 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
981 #define case_rrrw(name, type) \
982 case jit_code_##name##i##type: \
983 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
984 rn(node->v.w), node->w.w); \
986 #define case_rrf(name) \
987 case jit_code_##name##i_f: \
989 name##i_f(rn(node->u.w), rn(node->v.w), node->w.f); \
991 #define case_rrd(name) \
992 case jit_code_##name##i_d: \
994 name##i_d(rn(node->u.w), rn(node->v.w),node->w.d); \
996 #define case_wrr(name, type) \
997 case jit_code_##name##i##type: \
998 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1000 #define case_brr(name, type) \
1001 case jit_code_##name##r##type: \
1003 assert(temp->code == jit_code_label || \
1004 temp->code == jit_code_epilog); \
1005 if (temp->flag & jit_flag_patch) \
1006 name##r##type(temp->u.w, rn(node->v.w), \
1009 word = name##r##type(_jit->pc.w, \
1012 patch(word, node); \
1015 #define case_brw(name, type) \
1016 case jit_code_##name##i##type: \
1018 assert(temp->code == jit_code_label || \
1019 temp->code == jit_code_epilog); \
1020 if (temp->flag & jit_flag_patch) \
1021 name##i##type(temp->u.w, \
1022 rn(node->v.w), node->w.w); \
1024 word = name##i##type(_jit->pc.w, \
1025 rn(node->v.w), node->w.w); \
1026 patch(word, node); \
1029 #define case_brf(name) \
1030 case jit_code_##name##i_f: \
1032 assert(temp->code == jit_code_label || \
1033 temp->code == jit_code_epilog); \
1034 if (temp->flag & jit_flag_patch) \
1035 name##i_f(temp->u.w, rn(node->v.w), node->w.f); \
1037 word = name##i_f(_jit->pc.w, rn(node->v.w), \
1039 patch(word, node); \
1042 #define case_brd(name) \
1043 case jit_code_##name##i_d: \
1045 assert(temp->code == jit_code_label || \
1046 temp->code == jit_code_epilog); \
1047 if (temp->flag & jit_flag_patch) \
1048 name##i_d(temp->u.w, rn(node->v.w), node->w.d); \
1050 word = name##i_d(_jit->pc.w, rn(node->v.w), \
1052 patch(word, node); \
1055 #if DEVEL_DISASSEMBLER
1058 for (node = _jitc->head; node; node = node->next) {
1059 if (_jit->pc.uc >= _jitc->code.end)
1062 #if DEVEL_DISASSEMBLER
1063 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1066 value = jit_classify(node->code);
1067 jit_regarg_set(node, value);
1068 switch (node->code) {
1069 case jit_code_align:
1070 /* Must align to a power of two */
1071 assert(!(node->u.w & (node->u.w - 1)));
1072 if ((word = _jit->pc.w & (node->u.w - 1)))
1073 nop(node->u.w - word);
1076 nop((node->u.w + 3) & ~3);
1078 case jit_code_note: case jit_code_name:
1079 node->u.w = _jit->pc.w;
1081 case jit_code_label:
1082 /* remember label is defined */
1083 node->flag |= jit_flag_patch;
1084 node->u.w = _jit->pc.w;
1107 case_rrrr(qmul, _u);
1108 case_rrrw(qmul, _u);
1119 case_rrrr(qdiv, _u);
1120 case_rrrw(qdiv, _u);
1123 #define qlshr(r0, r1, r2, r3) fallback_qlshr(r0, r1, r2, r3)
1124 #define qlshi(r0, r1, r2, i0) fallback_qlshi(r0, r1, r2, i0)
1125 #define qlshr_u(r0, r1, r2, r3) fallback_qlshr_u(r0, r1, r2, r3)
1126 #define qlshi_u(r0, r1, r2, i0) fallback_qlshi_u(r0, r1, r2, i0)
1129 case_rrrr(qlsh, _u);
1130 case_rrrw(qlsh, _u);
1135 #define qrshr(r0, r1, r2, r3) fallback_qrshr(r0, r1, r2, r3)
1136 #define qrshi(r0, r1, r2, i0) fallback_qrshi(r0, r1, r2, i0)
1137 #define qrshr_u(r0, r1, r2, r3) fallback_qrshr_u(r0, r1, r2, r3)
1138 #define qrshi_u(r0, r1, r2, i0) fallback_qrshi_u(r0, r1, r2, i0)
1141 case_rrrr(qrsh, _u);
1142 case_rrrw(qrsh, _u);
1154 #define popcntr(r0, r1) fallback_popcnt(r0, r1)
1162 case_rr(trunc, _f_i);
1163 case_rr(trunc, _d_i);
1164 case_rr(trunc, _f_l);
1165 case_rr(trunc, _d_l);
1194 case jit_code_unldr:
1195 unldr(rn(node->u.w), rn(node->v.w), node->w.w);
1197 case jit_code_unldi:
1198 unldi(rn(node->u.w), node->v.w, node->w.w);
1200 case jit_code_unldr_u:
1201 unldr_u(rn(node->u.w), rn(node->v.w), node->w.w);
1203 case jit_code_unldi_u:
1204 unldi_u(rn(node->u.w), node->v.w, node->w.w);
1222 case jit_code_unstr:
1223 unstr(rn(node->u.w), rn(node->v.w), node->w.w);
1225 case jit_code_unsti:
1226 unsti(node->u.w, rn(node->v.w), node->w.w);
1231 case_rr(bswap, _us);
1232 case_rr(bswap, _ui);
1233 case_rr(bswap, _ul);
1235 extr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1237 case jit_code_extr_u:
1238 extr_u(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1241 depr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1244 depi(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1253 casr(rn(node->u.w), rn(node->v.w),
1254 rn(node->w.q.l), rn(node->w.q.h));
1257 casi(rn(node->u.w), node->v.w,
1258 rn(node->w.q.l), rn(node->w.q.h));
1264 if (node->flag & jit_flag_node) {
1266 if (temp->code == jit_code_data ||
1267 (temp->code == jit_code_label &&
1268 (temp->flag & jit_flag_patch)))
1269 movi(rn(node->u.w), temp->u.w);
1271 assert(temp->code == jit_code_label ||
1272 temp->code == jit_code_epilog);
1273 word = movi_p(rn(node->u.w), temp->u.w);
1278 movi(rn(node->u.w), node->v.w);
1322 case_brr(boadd, _u);
1323 case_brw(boadd, _u);
1326 case_brr(bxadd, _u);
1327 case_brw(bxadd, _u);
1330 case_brr(bosub, _u);
1331 case_brw(bosub, _u);
1334 case_brr(bxsub, _u);
1335 case_brw(bxsub, _u);
1361 case jit_code_unldr_x:
1362 unldr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1364 case jit_code_unldi_x:
1365 unldi_x(rn(node->u.w), node->v.w, node->w.w);
1371 case jit_code_unstr_x:
1372 unstr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1374 case jit_code_unsti_x:
1375 unsti_x(node->u.w, rn(node->v.w), node->w.w);
1378 case jit_code_movi_f:
1380 movi_f(rn(node->u.w), node->v.f);
1409 case_rrr(unord, _f);
1423 case_brr(bunlt, _f);
1425 case_brr(bunle, _f);
1427 case_brr(buneq, _f);
1429 case_brr(bunge, _f);
1431 case_brr(bungt, _f);
1433 case_brr(bltgt, _f);
1437 case_brr(bunord, _f);
1465 case jit_code_movi_d:
1467 movi_d(rn(node->u.w), node->v.d);
1496 case_rrr(unord, _d);
1510 case_brr(bunlt, _d);
1512 case_brr(bunle, _d);
1514 case_brr(buneq, _d);
1516 case_brr(bunge, _d);
1518 case_brr(bungt, _d);
1520 case_brr(bltgt, _d);
1524 case_brr(bunord, _d);
1528 jmpr(rn(node->u.w));
1531 if (node->flag & jit_flag_node) {
1533 assert(temp->code == jit_code_label ||
1534 temp->code == jit_code_epilog);
1535 if (temp->flag & jit_flag_patch)
1538 word = _jit->code.length -
1539 (_jit->pc.uc - _jit->code.ptr);
1540 if (can_sign_extend_si26_p(word))
1541 word = jmpi(_jit->pc.w);
1543 word = jmpi_p(_jit->pc.w);
1552 case jit_code_callr:
1554 callr(rn(node->u.w));
1556 case jit_code_calli:
1557 if (node->flag & jit_flag_node) {
1559 assert(temp->code == jit_code_label ||
1560 temp->code == jit_code_epilog);
1561 if (temp->flag & jit_flag_patch)
1564 word = _jit->code.length -
1565 (_jit->pc.uc - _jit->code.ptr);
1566 if (can_sign_extend_si26_p(word))
1567 word = calli(_jit->pc.w);
1569 word = calli_p(_jit->pc.w);
1578 case jit_code_prolog:
1579 _jitc->function = _jitc->functions.ptr + node->w.w;
1581 undo.word = _jit->pc.w;
1582 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
1583 #if DEVEL_DISASSEMBLER
1586 undo.patch_offset = _jitc->patches.offset;
1588 compute_framesize();
1593 case jit_code_epilog:
1594 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1596 for (temp = undo.node->next;
1597 temp != node; temp = temp->next) {
1598 if (temp->code == jit_code_label ||
1599 temp->code == jit_code_epilog)
1600 temp->flag &= ~jit_flag_patch;
1602 temp->flag &= ~jit_flag_patch;
1604 _jit->pc.w = undo.word;
1605 /* undo.func.self.aoff and undo.func.regset should not
1606 * be undone, as they will be further updated, and are
1607 * the reason of the undo. */
1608 undo.func.self.aoff = _jitc->function->frame +
1609 _jitc->function->self.aoff;
1610 undo.func.need_frame = _jitc->function->need_frame;
1611 jit_regset_set(&undo.func.regset, &_jitc->function->regset);
1612 /* allocar information also does not need to be undone */
1613 undo.func.aoffoff = _jitc->function->aoffoff;
1614 undo.func.allocar = _jitc->function->allocar;
1615 /* this will be recomputed but undo anyway to have it
1616 * better self documented.*/
1617 undo.func.need_stack = _jitc->function->need_stack;
1618 memcpy(_jitc->function, &undo.func, sizeof(undo.func));
1619 #if DEVEL_DISASSEMBLER
1622 _jitc->patches.offset = undo.patch_offset;
1624 goto restart_function;
1626 if (node->link && (word = _jit->pc.w & 3))
1628 /* remember label is defined */
1629 node->flag |= jit_flag_patch;
1630 node->u.w = _jit->pc.w;
1632 _jitc->function = NULL;
1634 case jit_code_movr_w_f:
1635 movr_w_f(rn(node->u.w), rn(node->v.w));
1637 case jit_code_movr_f_w:
1638 movr_f_w(rn(node->u.w), rn(node->v.w));
1640 case jit_code_movi_f_w:
1642 movi_f_w(rn(node->u.w), node->v.f);
1644 case jit_code_movi_w_f:
1645 movi_w_f(rn(node->u.w), node->v.w);
1647 case jit_code_movr_w_d:
1648 movr_w_d(rn(node->u.w), rn(node->v.w));
1650 case jit_code_movr_d_w:
1651 movr_d_w(rn(node->u.w), rn(node->v.w));
1653 case jit_code_movi_d_w:
1655 movi_d_w(rn(node->u.w), node->v.d);
1657 case jit_code_movi_w_d:
1658 movi_w_d(rn(node->u.w), node->v.w);
1660 case jit_code_va_start:
1661 vastart(rn(node->u.w));
1663 case jit_code_va_arg:
1664 vaarg(rn(node->u.w), rn(node->v.w));
1666 case jit_code_va_arg_d:
1667 vaarg_d(rn(node->u.w), rn(node->v.w));
1669 case jit_code_live: case jit_code_ellipsis:
1670 case jit_code_va_push:
1671 case jit_code_allocai: case jit_code_allocar:
1672 case jit_code_arg_c: case jit_code_arg_s:
1673 case jit_code_arg_i: case jit_code_arg_l:
1674 case jit_code_arg_f: case jit_code_arg_d:
1675 case jit_code_va_end:
1677 case jit_code_retr_c: case jit_code_reti_c:
1678 case jit_code_retr_uc: case jit_code_reti_uc:
1679 case jit_code_retr_s: case jit_code_reti_s:
1680 case jit_code_retr_us: case jit_code_reti_us:
1681 case jit_code_retr_i: case jit_code_reti_i:
1682 case jit_code_retr_ui: case jit_code_reti_ui:
1683 case jit_code_retr_l: case jit_code_reti_l:
1684 case jit_code_retr_f: case jit_code_reti_f:
1685 case jit_code_retr_d: case jit_code_reti_d:
1686 case jit_code_getarg_c: case jit_code_getarg_uc:
1687 case jit_code_getarg_s: case jit_code_getarg_us:
1688 case jit_code_getarg_i:
1689 case jit_code_getarg_ui: case jit_code_getarg_l:
1690 case jit_code_getarg_f: case jit_code_getarg_d:
1691 case jit_code_putargr_c: case jit_code_putargi_c:
1692 case jit_code_putargr_uc: case jit_code_putargi_uc:
1693 case jit_code_putargr_s: case jit_code_putargi_s:
1694 case jit_code_putargr_us: case jit_code_putargi_us:
1695 case jit_code_putargr_i: case jit_code_putargi_i:
1696 case jit_code_putargr_ui: case jit_code_putargi_ui:
1697 case jit_code_putargr_l: case jit_code_putargi_l:
1698 case jit_code_putargr_f: case jit_code_putargi_f:
1699 case jit_code_putargr_d: case jit_code_putargi_d:
1700 case jit_code_pushargr_c: case jit_code_pushargi_c:
1701 case jit_code_pushargr_uc: case jit_code_pushargi_uc:
1702 case jit_code_pushargr_s: case jit_code_pushargi_s:
1703 case jit_code_pushargr_us: case jit_code_pushargi_us:
1704 case jit_code_pushargr_i: case jit_code_pushargi_i:
1705 case jit_code_pushargr_ui: case jit_code_pushargi_ui:
1706 case jit_code_pushargr_l: case jit_code_pushargi_l:
1707 case jit_code_pushargr_f: case jit_code_pushargi_f:
1708 case jit_code_pushargr_d: case jit_code_pushargi_d:
1709 case jit_code_retval_c: case jit_code_retval_uc:
1710 case jit_code_retval_s: case jit_code_retval_us:
1711 case jit_code_retval_i:
1712 case jit_code_retval_ui: case jit_code_retval_l:
1713 case jit_code_retval_f: case jit_code_retval_d:
1714 case jit_code_prepare:
1715 case jit_code_finishr: case jit_code_finishi:
1716 case jit_code_negi_f: case jit_code_absi_f:
1717 case jit_code_sqrti_f: case jit_code_negi_d:
1718 case jit_code_absi_d: case jit_code_sqrti_d:
1721 negi(rn(node->u.w), node->v.w);
1724 comi(rn(node->u.w), node->v.w);
1726 case jit_code_exti_c:
1727 exti_c(rn(node->u.w), node->v.w);
1729 case jit_code_exti_uc:
1730 exti_uc(rn(node->u.w), node->v.w);
1732 case jit_code_exti_s:
1733 exti_s(rn(node->u.w), node->v.w);
1735 case jit_code_exti_us:
1736 exti_us(rn(node->u.w), node->v.w);
1738 case jit_code_bswapi_us:
1739 bswapi_us(rn(node->u.w), node->v.w);
1741 case jit_code_bswapi_ui:
1742 bswapi_ui(rn(node->u.w), node->v.w);
1744 case jit_code_htoni_us:
1745 htoni_us(rn(node->u.w), node->v.w);
1747 case jit_code_htoni_ui:
1748 htoni_ui(rn(node->u.w), node->v.w);
1750 #if __WORDSIZE == 64
1751 case jit_code_exti_i:
1752 exti_i(rn(node->u.w), node->v.w);
1754 case jit_code_exti_ui:
1755 exti_ui(rn(node->u.w), node->v.w);
1757 case jit_code_bswapi_ul:
1758 bswapi_ul(rn(node->u.w), node->v.w);
1760 case jit_code_htoni_ul:
1761 htoni_ul(rn(node->u.w), node->v.w);
1765 cloi(rn(node->u.w), node->v.w);
1768 clzi(rn(node->u.w), node->v.w);
1771 ctoi(rn(node->u.w), node->v.w);
1774 ctzi(rn(node->u.w), node->v.w);
1776 case jit_code_rbiti:
1777 rbiti(rn(node->u.w), node->v.w);
1779 case jit_code_popcnti:
1780 popcnti(rn(node->u.w), node->v.w);
1783 exti(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1785 case jit_code_exti_u:
1786 exti_u(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1791 if (jit_carry != _NOREG) {
1792 switch (node->code) {
1794 case jit_code_addcr: case jit_code_addci:
1795 case jit_code_addxr: case jit_code_addxi:
1796 case jit_code_subcr: case jit_code_subci:
1797 case jit_code_subxr: case jit_code_subxi:
1800 jit_unget_reg(jit_carry);
1805 jit_regarg_clr(node, value);
1806 assert(_jitc->regarg == 0 ||
1807 (jit_carry != _NOREG && _jitc->regarg == (1 << jit_carry)));
1808 assert(_jitc->synth == 0);
1809 /* update register live state */
1821 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1822 node = _jitc->patches.ptr[offset].node;
1823 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1824 patch_at(_jitc->patches.ptr[offset].inst, word);
1827 jit_flush(_jit->code.ptr, _jit->pc.uc);
1829 return (_jit->code.ptr);
1833 # include "jit_loongarch-cpu.c"
1834 # include "jit_loongarch-fpu.c"
1835 # include "jit_fallback.c"
1839 jit_flush(void *fptr, void *tptr)
1841 #if defined(__GNUC__)
1844 s = sysconf(_SC_PAGE_SIZE);
1845 f = (jit_word_t)fptr & -s;
1846 t = (((jit_word_t)tptr) + s - 1) & -s;
1847 __clear_cache((void *)f, (void *)t);
1852 _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1854 ldxi(rn(r0), rn(r1), i0);
1858 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1860 stxi(i0, rn(r0), rn(r1));
1864 _emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1866 ldxi_d(rn(r0), rn(r1), i0);
1870 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1872 stxi_d(i0, rn(r0), rn(r1));
1876 _compute_framesize(jit_state_t *_jit)
1879 _jitc->framesize = 16; /* ra+fp */
1880 for (reg = 0; reg < jit_size(iregs); reg++)
1881 if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg]))
1882 _jitc->framesize += sizeof(jit_word_t);
1884 for (reg = 0; reg < jit_size(fregs); reg++)
1885 if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg]))
1886 _jitc->framesize += sizeof(jit_float64_t);
1888 /* Space to store variadic arguments */
1889 if (_jitc->function->self.call & jit_call_varargs)
1890 _jitc->framesize += (8 - _jitc->function->vagp) * 8;
1892 /* Make sure functions called have a 16 byte aligned stack */
1893 _jitc->framesize = (_jitc->framesize + 15) & -16;
1897 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
1901 assert(node->flag & jit_flag_node);
1902 if (node->code == jit_code_movi)
1903 flag = node->v.n->flag;
1905 flag = node->u.n->flag;
1906 assert(!(flag & jit_flag_patch));
1907 if (_jitc->patches.offset >= _jitc->patches.length) {
1908 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
1909 _jitc->patches.length * sizeof(jit_patch_t),
1910 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
1911 _jitc->patches.length += 1024;
1913 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
1914 _jitc->patches.ptr[_jitc->patches.offset].node = node;
1915 ++_jitc->patches.offset;