2 * Copyright (C) 2013-2023 Free Software Foundation, Inc.
4 * This file is part of GNU lightning.
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
17 * Paulo Cesar Pereira de Andrade
26 #include <lightning.h>
27 #include <lightning/jit_private.h>
30 # define NUM_FLOAT_REG_ARGS 2
32 # define NUM_FLOAT_REG_ARGS 4
34 #define jit_arg_reg_p(i) ((i) >= 0 && (i) < 5)
35 #define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < NUM_FLOAT_REG_ARGS)
40 typedef struct jit_va_list {
41 /* The offsets are "1" based, as addresses are fixed in the
42 * standard stack frame format. */
46 /* Easier when there is an explicitly defined type...
48 type = struct __va_list_tag {
51 void *__overflow_arg_area;
52 void *__reg_save_area;
54 Note that gopff (__gpr) and fpoff (__fpr) are jit_word_t equivalent
55 and, again, "1" (unit) based, so must be adjusted at va_arg time.
60 /* For variadic functions, always allocate space to save callee
62 * Note that s390 has a standard stack frame format that lightning
63 * does not fully comply with, but for variadic functions it must,
64 * for those (variadic) do not use the "empty" spaces for any
65 * callee save fpr register, but save them after the va_list
66 * space; and use the standard stack frame format, as required
67 * by variadic functions (and have a compatible va_list pointer). */
81 #define jit_get_reg_pair() _jit_get_reg_pair(_jit)
82 static jit_int32_t _jit_get_reg_pair(jit_state_t*);
83 #define jit_unget_reg_pair(regno) _jit_unget_reg_pair(_jit,regno)
84 static void _jit_unget_reg_pair(jit_state_t*,jit_int32_t);
85 #define jit_get_reg_but_zero(flags) _jit_get_reg_but_zero(_jit,flags)
86 static jit_int32_t _jit_get_reg_but_zero(jit_state_t*,jit_int32_t);
87 #define jit_unget_reg_but_zero(reg) jit_unget_reg(reg)
88 #define patch(instr, node) _patch(_jit, instr, node)
89 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
92 extern void __clear_cache(void *, void *);
95 # include "jit_s390-cpu.c"
96 # include "jit_s390-fpu.c"
97 # include "jit_fallback.c"
104 jit_register_t _rvs[] = {
105 { rc(gpr) | 0x0, "%r0" },
106 { rc(gpr) | 0x1, "%r1" },
107 { rc(gpr) | rc(sav) | 0xc, "%r12" },
108 { rc(gpr) | rc(sav) | 0xb, "%r11" },
109 { rc(gpr) | rc(sav) | 0xa, "%r10" },
110 { rc(gpr) | rc(sav) | 0x9, "%r9" },
111 { rc(gpr) | rc(sav) | 0x8, "%r8" },
112 { rc(gpr) | rc(sav) | 0x7, "%r7" },
113 { rc(gpr) | rc(arg) | rc(sav) | 0x6,"%r6" },
114 { rc(gpr) | rc(arg) | 0x5, "%r5" },
115 { rc(gpr) | rc(arg) | 0x4, "%r4" },
116 { rc(gpr) | rc(arg) | 0x3, "%r3" },
117 { rc(gpr) | rc(arg) | 0x2, "%r2" },
118 { rc(sav) | 0xd, "%r13" }, /* used as JIT_FP */
120 { rc(sav) | 0xf, "%r15" },
121 { rc(fpr) | 0x1, "%f1" },
122 { rc(fpr) | 0x3, "%f3" },
123 { rc(fpr) | 0x5, "%f5" },
124 { rc(fpr) | 0x7, "%f7" },
125 { rc(fpr) | rc(sav) | 0xe, "%f14" },
126 /* Do not use as temporary to simplify stack layout */
128 { rc(fpr) | rc(sav) | 0x8, "%f8" },
129 { rc(fpr) | rc(sav) | 0x9, "%f9" },
130 { rc(fpr) | rc(sav) | 0xa, "%f10" },
131 { rc(fpr) | rc(sav) | 0xb, "%f11" },
132 { rc(fpr) | rc(sav) | 0xc, "%f12" },
133 { rc(fpr) | rc(sav) | 0xd, "%f13" },
134 { rc(fpr) | rc(arg) | 0x6, "%f6" },
135 { rc(fpr) | rc(arg) | 0x4, "%f4" },
136 { rc(fpr) | rc(arg) | 0x2, "%f2" },
137 { rc(fpr) | rc(arg) | 0x0, "%f0" },
138 { _NOREG, "<none>" },
141 static sigjmp_buf jit_env;
149 sigill_handler(int signum)
152 siglongjmp(jit_env, 1);
161 struct sigaction new_action, old_action;
162 new_action.sa_handler = sigill_handler;
163 sigemptyset(&new_action.sa_mask);
164 new_action.sa_flags = 0;
165 sigaction(SIGILL, NULL, &old_action);
166 if (old_action.sa_handler != SIG_IGN) {
167 sigaction(SIGILL, &new_action, NULL);
168 if (!sigsetjmp(jit_env, 1)) {
170 /* flogr %r12, %r12 */
171 __asm__ volatile("lgr %%r12, %0; lgr %%r13, %1;"
172 "flogr %%r12, %%r12;"
173 "lgr %1, %%r13; lgr %0, %%r12;"
174 : "=r" (r12), "=r" (r13));
175 sigaction(SIGILL, &old_action, NULL);
179 /* By default, assume it is available */
185 _jit_init(jit_state_t *_jit)
187 _jitc->reglen = jit_size(_rvs) - 1;
191 _jit_prolog(jit_state_t *_jit)
197 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
198 jit_regset_set_ui(&_jitc->regsav, 0);
199 offset = _jitc->functions.offset;
200 if (offset >= _jitc->functions.length) {
201 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
202 _jitc->functions.length * sizeof(jit_function_t),
203 (_jitc->functions.length + 16) * sizeof(jit_function_t));
204 _jitc->functions.length += 16;
206 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
207 _jitc->function->self.size = stack_framesize;
208 _jitc->function->self.argi = _jitc->function->self.argf =
209 _jitc->function->self.aoff = _jitc->function->self.alen = 0;
210 /* preallocate 8 bytes if not using a constant data buffer */
212 _jitc->function->self.aoff = -8;
213 _jitc->function->self.call = jit_call_default;
214 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
215 _jitc->reglen * sizeof(jit_int32_t));
217 /* _no_link here does not mean the jit_link() call can be removed
219 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
221 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
222 jit_link(_jitc->function->prolog);
223 _jitc->function->prolog->w.w = offset;
224 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
226 * v: offset in blocks vector
227 * w: offset in functions vector
229 _jitc->function->epilog->w.w = offset;
231 jit_regset_new(&_jitc->function->regset);
235 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
237 assert(_jitc->function);
239 case 0: case 1: break;
240 case 2: _jitc->function->self.aoff &= -2; break;
241 case 3: case 4: _jitc->function->self.aoff &= -4; break;
242 default: _jitc->function->self.aoff &= -8; break;
244 _jitc->function->self.aoff -= length;
245 if (!_jitc->realize) {
246 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
249 return (_jitc->function->self.aoff);
253 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
256 assert(_jitc->function);
257 jit_inc_synth_ww(allocar, u, v);
258 if (!_jitc->function->allocar) {
259 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
260 _jitc->function->allocar = 1;
262 reg = jit_get_reg(jit_class_gpr);
264 jit_andi(reg, reg, -8);
265 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
267 jit_addr(JIT_SP, JIT_SP, reg);
268 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
274 _jit_ret(jit_state_t *_jit)
277 assert(_jitc->function);
281 jit_patch_at(instr, _jitc->function->epilog);
286 _jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
288 jit_code_inc_synth_w(code, u);
289 jit_movr(JIT_RET, u);
295 _jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
297 jit_code_inc_synth_w(code, u);
298 jit_movi(JIT_RET, u);
304 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
306 jit_inc_synth_w(retr_f, u);
307 jit_movr_f(JIT_FRET, u);
313 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
315 jit_inc_synth_f(reti_f, u);
316 jit_movi_f(JIT_FRET, u);
322 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
324 jit_inc_synth_w(retr_d, u);
325 jit_movr_d(JIT_FRET, u);
331 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
333 jit_inc_synth_d(reti_d, u);
334 jit_movi_d(JIT_FRET, u);
340 _jit_epilog(jit_state_t *_jit)
342 assert(_jitc->function);
343 assert(_jitc->function->epilog->next == NULL);
344 jit_link(_jitc->function->epilog);
345 _jitc->function = NULL;
349 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
351 if (u->code >= jit_code_arg_c && u->code <= jit_code_arg)
352 return (jit_arg_reg_p(u->u.w));
353 assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
354 return (jit_arg_f_reg_p(u->u.w));
358 _jit_ellipsis(jit_state_t *_jit)
360 jit_inc_synth(ellipsis);
361 if (_jitc->prepare) {
363 assert(!(_jitc->function->call.call & jit_call_varargs));
364 _jitc->function->call.call |= jit_call_varargs;
368 assert(!(_jitc->function->self.call & jit_call_varargs));
369 _jitc->function->self.call |= jit_call_varargs;
371 /* Allocate va_list like object in the stack. */
372 _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
374 /* Initialize gp offset in save area. */
375 if (jit_arg_reg_p(_jitc->function->self.argi))
376 _jitc->function->vagp = _jitc->function->self.argi;
378 _jitc->function->vagp = 5;
380 /* Initialize fp offset in save area. */
381 if (jit_arg_f_reg_p(_jitc->function->self.argf))
382 _jitc->function->vafp = _jitc->function->self.argf;
384 _jitc->function->vafp = NUM_FLOAT_REG_ARGS;
390 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
392 jit_inc_synth_w(va_push, u);
398 _jit_arg(jit_state_t *_jit, jit_code_t code)
402 assert(_jitc->function);
403 assert(!(_jitc->function->self.call & jit_call_varargs));
404 #if STRONG_TYPE_CHECKING
405 assert(code >= jit_code_arg_c && code <= jit_code_arg);
407 if (jit_arg_reg_p(_jitc->function->self.argi))
408 offset = _jitc->function->self.argi++;
410 offset = _jitc->function->self.size;
411 _jitc->function->self.size += sizeof(jit_word_t);
413 node = jit_new_node_ww(code, offset,
414 ++_jitc->function->self.argn);
420 _jit_arg_f(jit_state_t *_jit)
424 assert(_jitc->function);
425 if (jit_arg_f_reg_p(_jitc->function->self.argf))
426 offset = _jitc->function->self.argf++;
428 offset = _jitc->function->self.size;
429 _jitc->function->self.size += sizeof(jit_word_t);
431 node = jit_new_node_ww(jit_code_arg_f, offset,
432 ++_jitc->function->self.argn);
438 _jit_arg_d(jit_state_t *_jit)
442 assert(_jitc->function);
443 if (jit_arg_f_reg_p(_jitc->function->self.argf))
444 offset = _jitc->function->self.argf++;
446 offset = _jitc->function->self.size;
447 _jitc->function->self.size += sizeof(jit_float64_t);
449 node = jit_new_node_ww(jit_code_arg_d, offset,
450 ++_jitc->function->self.argn);
456 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
458 assert_arg_type(v->code, jit_code_arg_c);
459 jit_inc_synth_wp(getarg_c, u, v);
460 if (jit_arg_reg_p(v->u.w))
461 jit_extr_c(u, _R2 - v->u.w);
463 jit_ldxi_c(u, JIT_FP,
464 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t));
469 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
471 assert_arg_type(v->code, jit_code_arg_c);
472 jit_inc_synth_wp(getarg_uc, u, v);
473 if (jit_arg_reg_p(v->u.w))
474 jit_extr_uc(u, _R2 - v->u.w);
476 jit_ldxi_uc(u, JIT_FP,
477 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t));
482 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
484 assert_arg_type(v->code, jit_code_arg_s);
485 jit_inc_synth_wp(getarg_s, u, v);
486 if (jit_arg_reg_p(v->u.w))
487 jit_extr_s(u, _R2 - v->u.w);
489 jit_ldxi_s(u, JIT_FP,
490 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t));
495 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
497 assert_arg_type(v->code, jit_code_arg_s);
498 jit_inc_synth_wp(getarg_us, u, v);
499 if (jit_arg_reg_p(v->u.w))
500 jit_extr_us(u, _R2 - v->u.w);
502 jit_ldxi_us(u, JIT_FP,
503 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t));
508 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
510 assert_arg_type(v->code, jit_code_arg_i);
511 jit_inc_synth_wp(getarg_i, u, v);
512 if (jit_arg_reg_p(v->u.w)) {
514 jit_movr(u, _R2 - v->u.w);
516 jit_extr_i(u, _R2 - v->u.w);
520 jit_ldxi_i(u, JIT_FP,
521 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t));
527 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
529 assert_arg_type(v->code, jit_code_arg_i);
530 jit_inc_synth_wp(getarg_ui, u, v);
531 if (jit_arg_reg_p(v->u.w))
532 jit_extr_ui(u, _R2 - v->u.w);
534 jit_ldxi_ui(u, JIT_FP,
535 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint32_t));
540 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
542 assert_arg_type(v->code, jit_code_arg_l);
543 jit_inc_synth_wp(getarg_l, u, v);
544 if (jit_arg_reg_p(v->u.w))
545 jit_movr(u, _R2 - v->u.w);
547 jit_ldxi_l(u, JIT_FP, v->u.w);
553 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
555 assert_putarg_type(code, v->code);
556 jit_code_inc_synth_wp(code, u, v);
557 if (jit_arg_reg_p(v->u.w))
558 jit_movr(_R2 - v->u.w, u);
560 jit_stxi(v->u.w, JIT_FP, u);
565 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
568 assert_putarg_type(code, v->code);
569 jit_code_inc_synth_wp(code, u, v);
570 if (jit_arg_reg_p(v->u.w))
571 jit_movi(_R2 - v->u.w, u);
573 regno = jit_get_reg(jit_class_gpr);
575 jit_stxi(v->u.w, JIT_FP, regno);
576 jit_unget_reg(regno);
582 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
584 assert(v->code == jit_code_arg_f);
585 jit_inc_synth_wp(getarg_f, u, v);
586 if (jit_arg_f_reg_p(v->u.w))
587 jit_movr_f(u, _F0 - v->u.w);
589 jit_ldxi_f(u, JIT_FP,
592 + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
599 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
601 assert(v->code == jit_code_arg_f);
602 jit_inc_synth_wp(putargr_f, u, v);
603 if (jit_arg_f_reg_p(v->u.w))
604 jit_movr_f(_F0 - v->u.w, u);
608 + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
615 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
618 assert(v->code == jit_code_arg_f);
619 jit_inc_synth_fp(putargi_f, u, v);
620 if (jit_arg_f_reg_p(v->u.w))
621 jit_movi_f(_F0 - v->u.w, u);
623 regno = jit_get_reg(jit_class_fpr);
624 jit_movi_f(regno, u);
627 + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
630 jit_unget_reg(regno);
636 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
638 assert(v->code == jit_code_arg_d);
639 jit_inc_synth_wp(getarg_d, u, v);
640 if (jit_arg_f_reg_p(v->u.w))
641 jit_movr_d(u, _F0 - v->u.w);
643 jit_ldxi_d(u, JIT_FP, v->u.w);
648 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
650 assert(v->code == jit_code_arg_d);
651 jit_inc_synth_wp(putargr_d, u, v);
652 if (jit_arg_f_reg_p(v->u.w))
653 jit_movr_d(_F0 - v->u.w, u);
655 jit_stxi_d(v->u.w, JIT_FP, u);
660 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
663 assert(v->code == jit_code_arg_d);
664 jit_inc_synth_dp(putargi_d, u, v);
665 if (jit_arg_f_reg_p(v->u.w))
666 jit_movi_d(_F0 - v->u.w, u);
668 regno = jit_get_reg(jit_class_fpr);
669 jit_movi_d(regno, u);
670 jit_stxi_d(v->u.w, JIT_FP, regno);
671 jit_unget_reg(regno);
677 _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
679 assert(_jitc->function);
680 jit_code_inc_synth_w(code, u);
682 if (jit_arg_reg_p(_jitc->function->call.argi)) {
683 jit_movr(_R2 - _jitc->function->call.argi, u);
684 ++_jitc->function->call.argi;
687 jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u);
688 _jitc->function->call.size += sizeof(jit_word_t);
694 _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
697 assert(_jitc->function);
698 jit_code_inc_synth_w(code, u);
700 if (jit_arg_reg_p(_jitc->function->call.argi)) {
701 jit_movi(_R2 - _jitc->function->call.argi, u);
702 ++_jitc->function->call.argi;
705 regno = jit_get_reg(jit_class_gpr);
707 jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, regno);
708 jit_unget_reg(regno);
709 _jitc->function->call.size += sizeof(jit_word_t);
715 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
717 assert(_jitc->function);
718 jit_inc_synth_w(pushargr_f, u);
720 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
721 jit_movr_f(_F0 - _jitc->function->call.argf, u);
722 ++_jitc->function->call.argf;
725 jit_stxi_f(_jitc->function->call.size + stack_framesize
727 + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
730 _jitc->function->call.size += sizeof(jit_word_t);
736 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
739 assert(_jitc->function);
740 jit_inc_synth_f(pushargi_f, u);
742 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
743 jit_movi_f(_F0 - _jitc->function->call.argf, u);
744 ++_jitc->function->call.argf;
747 regno = jit_get_reg(jit_class_fpr);
748 jit_movi_f(regno, u);
749 jit_stxi_f(_jitc->function->call.size + stack_framesize
751 + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
754 jit_unget_reg(regno);
755 _jitc->function->call.size += sizeof(jit_word_t);
761 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
763 assert(_jitc->function);
764 jit_inc_synth_w(pushargr_d, u);
766 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
767 jit_movr_d(_F0 - _jitc->function->call.argf, u);
768 ++_jitc->function->call.argf;
771 jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, u);
772 _jitc->function->call.size += sizeof(jit_float64_t);
778 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
781 assert(_jitc->function);
782 jit_inc_synth_d(pushargi_d, u);
784 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
785 jit_movi_d(_F0 - _jitc->function->call.argf, u);
786 ++_jitc->function->call.argf;
789 regno = jit_get_reg(jit_class_fpr);
790 jit_movi_d(regno, u);
791 jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, regno);
792 jit_unget_reg(regno);
793 _jitc->function->call.size += sizeof(jit_float64_t);
799 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
802 spec = jit_class(_rvs[regno].spec);
803 if (spec & jit_class_arg) {
805 if (regno >= 0 && regno < node->v.w)
807 if (spec & jit_class_fpr) {
809 if (regno >= 0 && regno < node->w.w)
817 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
820 assert(_jitc->function);
821 jit_inc_synth_w(finishr, r0);
822 if (_jitc->function->self.alen < _jitc->function->call.size)
823 _jitc->function->self.alen = _jitc->function->call.size;
824 call = jit_callr(r0);
825 call->v.w = _jitc->function->call.argi;
826 call->w.w = _jitc->function->call.argf;
827 _jitc->function->call.argi = _jitc->function->call.argf =
828 _jitc->function->call.size = 0;
834 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
837 assert(_jitc->function);
838 jit_inc_synth_w(finishi, (jit_word_t)i0);
839 if (_jitc->function->self.alen < _jitc->function->call.size)
840 _jitc->function->self.alen = _jitc->function->call.size;
841 node = jit_calli(i0);
842 node->v.w = _jitc->function->call.argi;
843 node->w.w = _jitc->function->call.argf;
844 _jitc->function->call.argi = _jitc->function->call.argf =
845 _jitc->function->call.size = 0;
852 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
854 jit_inc_synth_w(retval_c, r0);
855 jit_extr_c(r0, JIT_RET);
860 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
862 jit_inc_synth_w(retval_uc, r0);
863 jit_extr_uc(r0, JIT_RET);
868 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
870 jit_inc_synth_w(retval_s, r0);
871 jit_extr_s(r0, JIT_RET);
876 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
878 jit_inc_synth_w(retval_us, r0);
879 jit_extr_us(r0, JIT_RET);
884 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
886 jit_inc_synth_w(retval_i, r0);
888 jit_extr_i(r0, JIT_RET);
890 jit_movr(r0, JIT_RET);
897 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
899 jit_inc_synth_w(retval_ui, r0);
900 jit_extr_ui(r0, JIT_RET);
905 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
907 jit_inc_synth_w(retval_l, r0);
908 jit_movr(r0, JIT_RET);
914 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
916 jit_inc_synth_w(retval_f, r0);
917 jit_movr_f(r0, JIT_FRET);
922 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
924 jit_inc_synth_w(retval_d, r0);
925 jit_movr_d(r0, JIT_FRET);
930 _emit_code(jit_state_t *_jit)
941 #if DEVEL_DISASSEMBLER
944 jit_int32_t patch_offset;
946 #if DEVEL_DISASSEMBLER
950 _jitc->function = NULL;
956 undo.patch_offset = 0;
958 #define assert_data(node) /**/
959 #define case_rr(name, type) \
960 case jit_code_##name##r##type: \
961 name##r##type(rn(node->u.w), rn(node->v.w)); \
963 #define case_rw(name, type) \
964 case jit_code_##name##i##type: \
965 name##i##type(rn(node->u.w), node->v.w); \
967 #define case_wr(name, type) \
968 case jit_code_##name##i##type: \
969 name##i##type(node->u.w, rn(node->v.w)); \
971 #define case_rrr(name, type) \
972 case jit_code_##name##r##type: \
973 name##r##type(rn(node->u.w), \
974 rn(node->v.w), rn(node->w.w)); \
976 #define case_rrrr(name, type) \
977 case jit_code_##name##r##type: \
978 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
979 rn(node->v.w), rn(node->w.w)); \
981 #define case_rqr(name, type) \
982 case jit_code_##name##r##type: \
983 name##r##type(rn(node->u.w), rn(node->v.q.l), \
984 rn(node->v.q.h), rn(node->w.w)); \
985 case jit_code_##name##i##type: \
987 #define case_rrw(name, type) \
988 case jit_code_##name##i##type: \
989 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
991 #define case_rrrw(name, type) \
992 case jit_code_##name##i##type: \
993 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
994 rn(node->v.w), node->w.w); \
996 #define case_rrf(name) \
997 case jit_code_##name##i_f: \
999 name##i_f(rn(node->u.w), rn(node->v.w), \
1000 (jit_float32_t *)node->w.n->u.w); \
1002 #define case_rrd(name) \
1003 case jit_code_##name##i_d: \
1004 assert_data(node); \
1005 name##i_d(rn(node->u.w), rn(node->v.w), \
1006 (jit_float64_t *)node->w.n->u.w); \
1008 #define case_wrr(name, type) \
1009 case jit_code_##name##i##type: \
1010 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1012 #define case_brr(name, type) \
1013 case jit_code_##name##r##type: \
1015 assert(temp->code == jit_code_label || \
1016 temp->code == jit_code_epilog); \
1017 if (temp->flag & jit_flag_patch) \
1018 name##r##type(temp->u.w, rn(node->v.w), \
1021 word = name##r##type##_p(_jit->pc.w, \
1024 patch(word, node); \
1027 #define case_brw(name, type) \
1028 case jit_code_##name##i##type: \
1030 assert(temp->code == jit_code_label || \
1031 temp->code == jit_code_epilog); \
1032 if (temp->flag & jit_flag_patch) \
1033 name##i##type(temp->u.w, \
1034 rn(node->v.w), node->w.w); \
1036 word = name##i##type##_p(_jit->pc.w, \
1037 rn(node->v.w), node->w.w); \
1038 patch(word, node); \
1041 #define case_brf(name) \
1042 case jit_code_##name##i_f: \
1044 assert(temp->code == jit_code_label || \
1045 temp->code == jit_code_epilog); \
1046 if (temp->flag & jit_flag_patch) \
1047 name##i_f(temp->u.w, rn(node->v.w), \
1048 (jit_float32_t *)node->w.n->u.w); \
1050 word = name##i_f_p(_jit->pc.w, rn(node->v.w), \
1051 (jit_float32_t *)node->w.n->u.w);\
1052 patch(word, node); \
1055 #define case_brd(name) \
1056 case jit_code_##name##i_d: \
1058 assert(temp->code == jit_code_label || \
1059 temp->code == jit_code_epilog); \
1060 if (temp->flag & jit_flag_patch) \
1061 name##i_d(temp->u.w, rn(node->v.w), \
1062 (jit_float64_t *)node->w.n->u.w); \
1064 word = name##i_d_p(_jit->pc.w, rn(node->v.w), \
1065 (jit_float64_t *)node->w.n->u.w);\
1066 patch(word, node); \
1069 #if DEVEL_DISASSEMBLER
1072 for (node = _jitc->head; node; node = node->next) {
1073 if (_jit->pc.uc >= _jitc->code.end)
1076 #if DEVEL_DISASSEMBLER
1077 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1080 value = jit_classify(node->code);
1081 jit_regarg_set(node, value);
1082 switch (node->code) {
1083 case jit_code_align:
1084 /* Must align to a power of two */
1085 assert(!(node->u.w & (node->u.w - 1)));
1086 if ((word = _jit->pc.w & (node->u.w - 1)))
1087 nop(node->u.w - word);
1090 nop((node->u.w + 1) & ~1);
1092 case jit_code_note: case jit_code_name:
1093 node->u.w = _jit->pc.w;
1095 case jit_code_label:
1096 if ((node->link || (node->flag & jit_flag_use)) &&
1097 (word = _jit->pc.w & 3))
1099 /* remember label is defined */
1100 node->flag |= jit_flag_patch;
1101 node->u.w = _jit->pc.w;
1124 case_rrrr(qmul, _u);
1125 case_rrrw(qmul, _u);
1136 case_rrrr(qdiv, _u);
1137 case_rrrw(qdiv, _u);
1140 #define qlshr(r0, r1, r2, r3) fallback_qlshr(r0, r1, r2, r3)
1141 #define qlshi(r0, r1, r2, i0) fallback_qlshi(r0, r1, r2, i0)
1142 #define qlshr_u(r0, r1, r2, r3) fallback_qlshr_u(r0, r1, r2, r3)
1143 #define qlshi_u(r0, r1, r2, i0) fallback_qlshi_u(r0, r1, r2, i0)
1146 case_rrrr(qlsh, _u);
1147 case_rrrw(qlsh, _u);
1152 #define qrshr(r0, r1, r2, r3) fallback_qrshr(r0, r1, r2, r3)
1153 #define qrshi(r0, r1, r2, i0) fallback_qrshi(r0, r1, r2, i0)
1154 #define qrshr_u(r0, r1, r2, r3) fallback_qrshr_u(r0, r1, r2, r3)
1155 #define qrshi_u(r0, r1, r2, i0) fallback_qrshi_u(r0, r1, r2, i0)
1158 case_rrrr(qrsh, _u);
1159 case_rrrw(qrsh, _u);
1170 #define rbitr(r0, r1) fallback_rbit(r0, r1)
1171 #define popcntr(r0, r1) fallback_popcnt(r0, r1)
1180 case_rr(trunc, _f_i);
1181 case_rr(trunc, _d_i);
1182 #if __WORDSIZE == 64
1183 case_rr(trunc, _f_l);
1184 case_rr(trunc, _d_l);
1196 #if __WORDSIZE == 64
1212 #if __WORDSIZE == 64
1218 #define unldr(r0, r1, i0) fallback_unldr(r0, r1, i0)
1219 case jit_code_unldr:
1220 unldr(rn(node->u.w), rn(node->v.w), node->w.w);
1222 #define unldi(r0, i0, i1) fallback_unldi(r0, i0, i1)
1223 case jit_code_unldi:
1224 unldi(rn(node->u.w), node->v.w, node->w.w);
1226 #define unldr_u(r0, r1, i0) fallback_unldr_u(r0, r1, i0)
1227 case jit_code_unldr_u:
1228 unldr_u(rn(node->u.w), rn(node->v.w), node->w.w);
1230 #define unldi_u(r0, i0, i1) fallback_unldi_u(r0, i0, i1)
1231 case jit_code_unldi_u:
1232 unldi_u(rn(node->u.w), node->v.w, node->w.w);
1240 #if __WORDSIZE == 64
1250 #if __WORDSIZE == 64
1254 #define unstr(r0, r1, i0) fallback_unstr(r0, r1, i0)
1255 case jit_code_unstr:
1256 unstr(rn(node->u.w), rn(node->v.w), node->w.w);
1258 #define unsti(i0, r0, i1) fallback_unsti(i0, r0, i1)
1259 case jit_code_unsti:
1260 unsti(node->u.w, rn(node->v.w), node->w.w);
1264 #if __WORDSIZE == 64
1267 case_rr(bswap, _us);
1268 case_rr(bswap, _ui);
1269 #if __WORDSIZE == 64
1270 case_rr(bswap, _ul);
1273 extr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1275 case jit_code_extr_u:
1276 extr_u(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1279 depr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1282 depi(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1288 #if __WORDSIZE == 64
1293 casr(rn(node->u.w), rn(node->v.w),
1294 rn(node->w.q.l), rn(node->w.q.h));
1297 casi(rn(node->u.w), node->v.w,
1298 rn(node->w.q.l), rn(node->w.q.h));
1304 if (node->flag & jit_flag_node) {
1306 if (temp->code == jit_code_data ||
1307 (temp->code == jit_code_label &&
1308 (temp->flag & jit_flag_patch)))
1309 movi(rn(node->u.w), temp->u.w);
1311 assert(temp->code == jit_code_label ||
1312 temp->code == jit_code_epilog);
1313 word = movi_p(rn(node->u.w), temp->u.w);
1318 movi(rn(node->u.w), node->v.w);
1362 case_brr(boadd, _u);
1363 case_brw(boadd, _u);
1366 case_brr(bxadd, _u);
1367 case_brw(bxadd, _u);
1370 case_brr(bosub, _u);
1371 case_brw(bosub, _u);
1374 case_brr(bxsub, _u);
1375 case_brw(bxsub, _u);
1401 #define unldr_x(r0, r1, i0) fallback_unldr_x(r0, r1, i0)
1402 case jit_code_unldr_x:
1403 unldr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1405 #define unldi_x(r0, i0, i1) fallback_unldi_x(r0, i0, i1)
1406 case jit_code_unldi_x:
1407 unldi_x(rn(node->u.w), node->v.w, node->w.w);
1413 #define unstr_x(r0, r1, i0) fallback_unstr_x(r0, r1, i0)
1414 case jit_code_unstr_x:
1415 unstr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1417 #define unsti_x(i0, r0, i1) fallback_unsti_x(i0, r0, i1)
1418 case jit_code_unsti_x:
1419 unsti_x(node->u.w, rn(node->v.w), node->w.w);
1422 case jit_code_movi_f:
1424 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1453 case_rrr(unord, _f);
1467 case_brr(bunlt, _f);
1469 case_brr(bunle, _f);
1471 case_brr(buneq, _f);
1473 case_brr(bunge, _f);
1475 case_brr(bungt, _f);
1477 case_brr(bltgt, _f);
1481 case_brr(bunord, _f);
1509 case jit_code_movi_d:
1511 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1540 case_rrr(unord, _d);
1554 case_brr(bunlt, _d);
1556 case_brr(bunle, _d);
1558 case_brr(buneq, _d);
1560 case_brr(bunge, _d);
1562 case_brr(bungt, _d);
1564 case_brr(bltgt, _d);
1568 case_brr(bunord, _d);
1571 jmpr(rn(node->u.w));
1574 if (node->flag & jit_flag_node) {
1576 assert(temp->code == jit_code_label ||
1577 temp->code == jit_code_epilog);
1578 if (temp->flag & jit_flag_patch)
1581 word = _jit->code.length -
1582 (_jit->pc.uc - _jit->code.ptr);
1584 offset = s16_p(word);
1585 word = jmpi(_jit->pc.w, offset);
1588 word = jmpi_p(_jit->pc.w);
1595 case jit_code_callr:
1596 callr(rn(node->u.w));
1598 case jit_code_calli:
1599 if (node->flag & jit_flag_node) {
1601 assert(temp->code == jit_code_label ||
1602 temp->code == jit_code_epilog);
1603 if (temp->flag & jit_flag_patch)
1604 calli(temp->u.w, 1);
1606 word = _jit->code.length -
1607 (_jit->pc.uc - _jit->code.ptr);
1609 offset =s16_p(word);
1610 word = calli(_jit->pc.w, offset);
1613 word = calli_p(_jit->pc.w);
1618 calli(node->u.w, 1);
1620 case jit_code_prolog:
1621 _jitc->function = _jitc->functions.ptr + node->w.w;
1623 undo.word = _jit->pc.w;
1624 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
1625 #if DEVEL_DISASSEMBLER
1628 undo.patch_offset = _jitc->patches.offset;
1633 case jit_code_epilog:
1634 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1636 for (temp = undo.node->next;
1637 temp != node; temp = temp->next) {
1638 if (temp->code == jit_code_label ||
1639 temp->code == jit_code_epilog)
1640 temp->flag &= ~jit_flag_patch;
1642 temp->flag &= ~jit_flag_patch;
1644 _jit->pc.w = undo.word;
1645 /* undo.func.self.aoff and undo.func.regset should not
1646 * be undone, as they will be further updated, and are
1647 * the reason of the undo. */
1648 undo.func.self.aoff = _jitc->function->frame +
1649 _jitc->function->self.aoff;
1650 jit_regset_set(&undo.func.regset, &_jitc->function->regset);
1651 /* allocar information also does not need to be undone */
1652 undo.func.aoffoff = _jitc->function->aoffoff;
1653 undo.func.allocar = _jitc->function->allocar;
1654 /* cvt_offset must also not be undone */
1655 undo.func.cvt_offset = _jitc->function->cvt_offset;
1656 memcpy(_jitc->function, &undo.func, sizeof(undo.func));
1657 #if DEVEL_DISASSEMBLER
1660 _jitc->patches.offset = undo.patch_offset;
1661 goto restart_function;
1663 if (node->link && (word = _jit->pc.w & 3))
1665 /* remember label is defined */
1666 node->flag |= jit_flag_patch;
1667 node->u.w = _jit->pc.w;
1669 _jitc->function = NULL;
1671 case jit_code_movr_w_f:
1672 movr_w_f(rn(node->u.w), rn(node->v.w));
1674 case jit_code_movr_f_w:
1675 movr_f_w(rn(node->u.w), rn(node->v.w));
1677 case jit_code_movi_f_w:
1678 assert(node->flag & jit_flag_data);
1679 movi_f_w(rn(node->u.w), *(jit_float32_t *)node->v.n->u.w);
1681 case jit_code_movi_w_f:
1682 movi_w_f(rn(node->u.w), node->v.w);
1684 #if __WORDSIZE == 32
1685 case jit_code_movr_ww_d:
1686 movr_ww_d(rn(node->u.w), rn(node->v.w), rn(node->w.w));
1688 case jit_code_movr_d_ww:
1689 movr_d_ww(rn(node->u.w), rn(node->v.w), rn(node->w.w));
1691 case jit_code_movi_d_ww:
1692 assert(node->flag & jit_flag_data);
1693 movi_d_ww(rn(node->u.w), rn(node->v.w),
1694 *(jit_float64_t *)node->w.n->u.w);
1696 case jit_code_movi_ww_d:
1697 movi_ww_d(rn(node->u.w), node->v.w, node->w.w);
1700 case jit_code_movr_w_d:
1701 movr_w_d(rn(node->u.w), rn(node->v.w));
1703 case jit_code_movr_d_w:
1704 movr_d_w(rn(node->u.w), rn(node->v.w));
1706 case jit_code_movi_d_w:
1707 assert(node->flag & jit_flag_data);
1708 movi_d_w(rn(node->u.w), *(jit_float64_t *)node->v.n->u.w);
1710 case jit_code_movi_w_d:
1711 movi_w_d(rn(node->u.w), node->v.w);
1714 case jit_code_va_start:
1715 vastart(rn(node->u.w));
1717 case jit_code_va_arg:
1718 vaarg(rn(node->u.w), rn(node->v.w));
1720 case jit_code_va_arg_d:
1721 vaarg_d(rn(node->u.w), rn(node->v.w));
1723 case jit_code_live: case jit_code_ellipsis:
1724 case jit_code_va_push:
1725 case jit_code_allocai: case jit_code_allocar:
1726 case jit_code_arg_c: case jit_code_arg_s:
1727 case jit_code_arg_i:
1728 # if __WORDSIZE == 64
1729 case jit_code_arg_l:
1731 case jit_code_arg_f: case jit_code_arg_d:
1732 case jit_code_va_end:
1734 case jit_code_retr_c: case jit_code_reti_c:
1735 case jit_code_retr_uc: case jit_code_reti_uc:
1736 case jit_code_retr_s: case jit_code_reti_s:
1737 case jit_code_retr_us: case jit_code_reti_us:
1738 case jit_code_retr_i: case jit_code_reti_i:
1739 #if __WORDSIZE == 64
1740 case jit_code_retr_ui: case jit_code_reti_ui:
1741 case jit_code_retr_l: case jit_code_reti_l:
1743 case jit_code_retr_f: case jit_code_reti_f:
1744 case jit_code_retr_d: case jit_code_reti_d:
1745 case jit_code_getarg_c: case jit_code_getarg_uc:
1746 case jit_code_getarg_s: case jit_code_getarg_us:
1747 case jit_code_getarg_i:
1748 #if __WORDSIZE == 64
1749 case jit_code_getarg_ui: case jit_code_getarg_l:
1751 case jit_code_getarg_f: case jit_code_getarg_d:
1752 case jit_code_putargr_c: case jit_code_putargi_c:
1753 case jit_code_putargr_uc: case jit_code_putargi_uc:
1754 case jit_code_putargr_s: case jit_code_putargi_s:
1755 case jit_code_putargr_us: case jit_code_putargi_us:
1756 case jit_code_putargr_i: case jit_code_putargi_i:
1757 #if __WORDSIZE == 64
1758 case jit_code_putargr_ui: case jit_code_putargi_ui:
1759 case jit_code_putargr_l: case jit_code_putargi_l:
1761 case jit_code_putargr_f: case jit_code_putargi_f:
1762 case jit_code_putargr_d: case jit_code_putargi_d:
1763 case jit_code_pushargr_c: case jit_code_pushargi_c:
1764 case jit_code_pushargr_uc: case jit_code_pushargi_uc:
1765 case jit_code_pushargr_s: case jit_code_pushargi_s:
1766 case jit_code_pushargr_us: case jit_code_pushargi_us:
1767 case jit_code_pushargr_i: case jit_code_pushargi_i:
1768 #if __WORDSIZE == 64
1769 case jit_code_pushargr_ui: case jit_code_pushargi_ui:
1770 case jit_code_pushargr_l: case jit_code_pushargi_l:
1772 case jit_code_pushargr_f: case jit_code_pushargi_f:
1773 case jit_code_pushargr_d: case jit_code_pushargi_d:
1774 case jit_code_retval_c: case jit_code_retval_uc:
1775 case jit_code_retval_s: case jit_code_retval_us:
1776 case jit_code_retval_i:
1777 #if __WORDSIZE == 64
1778 case jit_code_retval_ui: case jit_code_retval_l:
1780 case jit_code_retval_f: case jit_code_retval_d:
1781 case jit_code_prepare:
1782 case jit_code_finishr: case jit_code_finishi:
1783 case jit_code_negi_f: case jit_code_absi_f:
1784 case jit_code_sqrti_f: case jit_code_negi_d:
1785 case jit_code_absi_d: case jit_code_sqrti_d:
1788 negi(rn(node->u.w), node->v.w);
1791 comi(rn(node->u.w), node->v.w);
1793 case jit_code_exti_c:
1794 exti_c(rn(node->u.w), node->v.w);
1796 case jit_code_exti_uc:
1797 exti_uc(rn(node->u.w), node->v.w);
1799 case jit_code_exti_s:
1800 exti_s(rn(node->u.w), node->v.w);
1802 case jit_code_exti_us:
1803 exti_us(rn(node->u.w), node->v.w);
1805 case jit_code_bswapi_us:
1806 bswapi_us(rn(node->u.w), node->v.w);
1808 case jit_code_bswapi_ui:
1809 bswapi_ui(rn(node->u.w), node->v.w);
1811 case jit_code_htoni_us:
1812 htoni_us(rn(node->u.w), node->v.w);
1814 case jit_code_htoni_ui:
1815 htoni_ui(rn(node->u.w), node->v.w);
1817 #if __WORDSIZE == 64
1818 case jit_code_exti_i:
1819 exti_i(rn(node->u.w), node->v.w);
1821 case jit_code_exti_ui:
1822 exti_ui(rn(node->u.w), node->v.w);
1824 case jit_code_bswapi_ul:
1825 bswapi_ul(rn(node->u.w), node->v.w);
1827 case jit_code_htoni_ul:
1828 htoni_ul(rn(node->u.w), node->v.w);
1832 cloi(rn(node->u.w), node->v.w);
1835 clzi(rn(node->u.w), node->v.w);
1838 ctoi(rn(node->u.w), node->v.w);
1841 ctzi(rn(node->u.w), node->v.w);
1843 case jit_code_rbiti:
1844 rbiti(rn(node->u.w), node->v.w);
1846 case jit_code_popcnti:
1847 popcnti(rn(node->u.w), node->v.w);
1850 exti(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1852 case jit_code_exti_u:
1853 exti_u(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1858 jit_regarg_clr(node, value);
1859 assert(_jitc->regarg == 0 && _jitc->synth == 0);
1860 /* update register live state */
1872 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1873 node = _jitc->patches.ptr[offset].node;
1874 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1875 patch_at(_jitc->patches.ptr[offset].inst, word);
1878 jit_flush(_jit->code.ptr, _jit->pc.uc);
1880 return (_jit->code.ptr);
1884 # include "jit_s390-cpu.c"
1885 # include "jit_s390-fpu.c"
1886 # include "jit_fallback.c"
1890 jit_flush(void *fptr, void *tptr)
1892 #if defined(__GNUC__)
1895 s = sysconf(_SC_PAGE_SIZE);
1896 f = (jit_word_t)fptr & -s;
1897 t = (((jit_word_t)tptr) + s - 1) & -s;
1898 __clear_cache((void *)f, (void *)t);
1903 _emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0)
1905 ldxi(rn(r0), rn(r1), i0);
1909 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1)
1911 stxi(i0, rn(r0), rn(r1));
1915 _emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0)
1917 ldxi_d(rn(r0), rn(r1), i0);
1921 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1)
1923 stxi_d(i0, rn(r0), rn(r1));
1927 _jit_get_reg_pair(jit_state_t *_jit)
1930 /* Try to find a register pair for use with operations that
1931 * require a odd based register pair. Search for the best
1932 * match to avoid spills or at least a valid operation.
1935 /* Try non callee save first */
1936 if (jit_reg_free_p(_R0) && jit_reg_free_p(_R1))
1938 else if (jit_reg_free_p(_R2) && jit_reg_free_p(_R3))
1940 else if (jit_reg_free_p(_R4) && jit_reg_free_p(_R5))
1942 /* Try callee save registers */
1943 else if (jit_reg_free_p(_R10) && jit_reg_free_p(_R11))
1944 r1 = _R10, r2 = _R11;
1945 else if (jit_reg_free_p(_R8) && jit_reg_free_p(_R9))
1947 else if (jit_reg_free_p(_R6) && jit_reg_free_p(_R7))
1950 /* We *must* find a register pair */
1951 else if (jit_reg_free_if_spill_p(_R0) && jit_reg_free_if_spill_p(_R1))
1953 else if (jit_reg_free_if_spill_p(_R2) && jit_reg_free_if_spill_p(_R3))
1955 else if (jit_reg_free_if_spill_p(_R4) && jit_reg_free_if_spill_p(_R5))
1957 else if (jit_reg_free_if_spill_p(_R10) && jit_reg_free_if_spill_p(_R11))
1958 r1 = _R10, r2 = _R11;
1959 else if (jit_reg_free_if_spill_p(_R8) && jit_reg_free_if_spill_p(_R9))
1961 else if (jit_reg_free_if_spill_p(_R6) && jit_reg_free_if_spill_p(_R7))
1964 /* Do not jit_get_reg() all registers to avoid it */
1967 (void)jit_get_reg(jit_class_gpr|jit_class_named|r1);
1968 (void)jit_get_reg(jit_class_gpr|jit_class_named|r2);
1974 _jit_unget_reg_pair(jit_state_t *_jit, jit_int32_t reg)
1979 case _R0: r2 = _R1; break;
1980 case _R2: r2 = _R3; break;
1981 case _R4: r2 = _R5; break;
1982 case _R6: r2 = _R7; break;
1983 case _R8: r2 = _R9; break;
1984 case _R10: r2 = _R11; break;
1992 _jit_get_reg_but_zero(jit_state_t *_jit, jit_int32_t flags)
1995 reg = jit_get_reg(jit_class_gpr);
1997 reg = jit_get_reg(jit_class_gpr|flags);
2004 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
2008 assert(node->flag & jit_flag_node);
2009 if (node->code == jit_code_movi)
2010 flag = node->v.n->flag;
2012 flag = node->u.n->flag;
2013 assert(!(flag & jit_flag_patch));
2014 if (_jitc->patches.offset >= _jitc->patches.length) {
2015 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
2016 _jitc->patches.length * sizeof(jit_patch_t),
2017 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
2018 _jitc->patches.length += 1024;
2020 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
2021 _jitc->patches.ptr[_jitc->patches.offset].node = node;
2022 ++_jitc->patches.offset;