2 * Copyright (C) 2013-2022 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 #include <lightning.h>
21 #include <lightning/jit_private.h>
24 # define NUM_FLOAT_REG_ARGS 2
26 # define NUM_FLOAT_REG_ARGS 4
28 #define jit_arg_reg_p(i) ((i) >= 0 && (i) < 5)
29 #define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < NUM_FLOAT_REG_ARGS)
34 typedef struct jit_va_list {
35 /* The offsets are "1" based, as addresses are fixed in the
36 * standard stack frame format. */
40 /* Easier when there is an explicitly defined type...
42 type = struct __va_list_tag {
45 void *__overflow_arg_area;
46 void *__reg_save_area;
48 Note that gopff (__gpr) and fpoff (__fpr) are jit_word_t equivalent
49 and, again, "1" (unit) based, so must be adjusted at va_arg time.
54 /* For variadic functions, always allocate space to save callee
56 * Note that s390 has a standard stack frame format that lightning
57 * does not fully comply with, but for variadic functions it must,
58 * for those (variadic) do not use the "empty" spaces for any
59 * callee save fpr register, but save them after the va_list
60 * space; and use the standard stack frame format, as required
61 * by variadic functions (and have a compatible va_list pointer). */
75 #define jit_get_reg_pair() _jit_get_reg_pair(_jit)
76 static jit_int32_t _jit_get_reg_pair(jit_state_t*);
77 #define jit_unget_reg_pair(regno) _jit_unget_reg_pair(_jit,regno)
78 static void _jit_unget_reg_pair(jit_state_t*,jit_int32_t);
79 #define jit_get_reg_but_zero(flags) _jit_get_reg_but_zero(_jit,flags)
80 static jit_int32_t _jit_get_reg_but_zero(jit_state_t*,jit_int32_t);
81 #define jit_unget_reg_but_zero(reg) jit_unget_reg(reg)
82 #define patch(instr, node) _patch(_jit, instr, node)
83 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
86 extern void __clear_cache(void *, void *);
89 # include "jit_s390-cpu.c"
90 # include "jit_s390-fpu.c"
96 jit_register_t _rvs[] = {
97 { rc(gpr) | 0x0, "%r0" },
98 { rc(gpr) | 0x1, "%r1" },
99 { rc(gpr) | rc(sav) | 0xc, "%r12" },
100 { rc(gpr) | rc(sav) | 0xb, "%r11" },
101 { rc(gpr) | rc(sav) | 0xa, "%r10" },
102 { rc(gpr) | rc(sav) | 0x9, "%r9" },
103 { rc(gpr) | rc(sav) | 0x8, "%r8" },
104 { rc(gpr) | rc(sav) | 0x7, "%r7" },
105 { rc(gpr) | rc(arg) | rc(sav) | 0x6,"%r6" },
106 { rc(gpr) | rc(arg) | 0x5, "%r5" },
107 { rc(gpr) | rc(arg) | 0x4, "%r4" },
108 { rc(gpr) | rc(arg) | 0x3, "%r3" },
109 { rc(gpr) | rc(arg) | 0x2, "%r2" },
110 { rc(sav) | 0xd, "%r13" }, /* used as JIT_FP */
112 { rc(sav) | 0xf, "%r15" },
113 { rc(fpr) | 0x1, "%f1" },
114 { rc(fpr) | 0x3, "%f3" },
115 { rc(fpr) | 0x5, "%f5" },
116 { rc(fpr) | 0x7, "%f7" },
117 { rc(fpr) | rc(sav) | 0xe, "%f14" },
118 /* Do not use as temporary to simplify stack layout */
120 { rc(fpr) | rc(sav) | 0x8, "%f8" },
121 { rc(fpr) | rc(sav) | 0x9, "%f9" },
122 { rc(fpr) | rc(sav) | 0xa, "%f10" },
123 { rc(fpr) | rc(sav) | 0xb, "%f11" },
124 { rc(fpr) | rc(sav) | 0xc, "%f12" },
125 { rc(fpr) | rc(sav) | 0xd, "%f13" },
126 { rc(fpr) | rc(arg) | 0x6, "%f6" },
127 { rc(fpr) | rc(arg) | 0x4, "%f4" },
128 { rc(fpr) | rc(arg) | 0x2, "%f2" },
129 { rc(fpr) | rc(arg) | 0x0, "%f0" },
130 { _NOREG, "<none>" },
142 _jit_init(jit_state_t *_jit)
144 _jitc->reglen = jit_size(_rvs) - 1;
148 _jit_prolog(jit_state_t *_jit)
154 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
155 jit_regset_set_ui(&_jitc->regsav, 0);
156 offset = _jitc->functions.offset;
157 if (offset >= _jitc->functions.length) {
158 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
159 _jitc->functions.length * sizeof(jit_function_t),
160 (_jitc->functions.length + 16) * sizeof(jit_function_t));
161 _jitc->functions.length += 16;
163 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
164 _jitc->function->self.size = stack_framesize;
165 _jitc->function->self.argi = _jitc->function->self.argf =
166 _jitc->function->self.aoff = _jitc->function->self.alen = 0;
167 /* preallocate 8 bytes if not using a constant data buffer */
169 _jitc->function->self.aoff = -8;
170 _jitc->function->self.call = jit_call_default;
171 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
172 _jitc->reglen * sizeof(jit_int32_t));
174 /* _no_link here does not mean the jit_link() call can be removed
176 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
178 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
179 jit_link(_jitc->function->prolog);
180 _jitc->function->prolog->w.w = offset;
181 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
183 * v: offset in blocks vector
184 * w: offset in functions vector
186 _jitc->function->epilog->w.w = offset;
188 jit_regset_new(&_jitc->function->regset);
192 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
194 assert(_jitc->function);
196 case 0: case 1: break;
197 case 2: _jitc->function->self.aoff &= -2; break;
198 case 3: case 4: _jitc->function->self.aoff &= -4; break;
199 default: _jitc->function->self.aoff &= -8; break;
201 _jitc->function->self.aoff -= length;
202 if (!_jitc->realize) {
203 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
206 return (_jitc->function->self.aoff);
210 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
213 assert(_jitc->function);
214 jit_inc_synth_ww(allocar, u, v);
215 if (!_jitc->function->allocar) {
216 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
217 _jitc->function->allocar = 1;
219 reg = jit_get_reg(jit_class_gpr);
221 jit_andi(reg, reg, -8);
222 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
224 jit_addr(JIT_SP, JIT_SP, reg);
225 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
231 _jit_ret(jit_state_t *_jit)
234 assert(_jitc->function);
238 jit_patch_at(instr, _jitc->function->epilog);
243 _jit_retr(jit_state_t *_jit, jit_int32_t u)
245 jit_inc_synth_w(retr, u);
246 jit_movr(JIT_RET, u);
252 _jit_reti(jit_state_t *_jit, jit_word_t u)
254 jit_inc_synth_w(reti, u);
255 jit_movi(JIT_RET, u);
261 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
263 jit_inc_synth_w(retr_f, u);
264 jit_movr_f(JIT_FRET, u);
270 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
272 jit_inc_synth_f(reti_f, u);
273 jit_movi_f(JIT_FRET, u);
279 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
281 jit_inc_synth_w(retr_d, u);
282 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)
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));
315 _jit_ellipsis(jit_state_t *_jit)
317 jit_inc_synth(ellipsis);
318 if (_jitc->prepare) {
320 assert(!(_jitc->function->call.call & jit_call_varargs));
321 _jitc->function->call.call |= jit_call_varargs;
325 assert(!(_jitc->function->self.call & jit_call_varargs));
326 _jitc->function->self.call |= jit_call_varargs;
328 /* Allocate va_list like object in the stack. */
329 _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
331 /* Initialize gp offset in save area. */
332 if (jit_arg_reg_p(_jitc->function->self.argi))
333 _jitc->function->vagp = _jitc->function->self.argi;
335 _jitc->function->vagp = 5;
337 /* Initialize fp offset in save area. */
338 if (jit_arg_f_reg_p(_jitc->function->self.argf))
339 _jitc->function->vafp = _jitc->function->self.argf;
341 _jitc->function->vafp = NUM_FLOAT_REG_ARGS;
347 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
349 jit_inc_synth_w(va_push, u);
355 _jit_arg(jit_state_t *_jit)
359 assert(_jitc->function);
360 if (jit_arg_reg_p(_jitc->function->self.argi))
361 offset = _jitc->function->self.argi++;
363 offset = _jitc->function->self.size;
364 _jitc->function->self.size += sizeof(jit_word_t);
366 node = jit_new_node_ww(jit_code_arg, offset,
367 ++_jitc->function->self.argn);
373 _jit_arg_f(jit_state_t *_jit)
377 assert(_jitc->function);
378 if (jit_arg_f_reg_p(_jitc->function->self.argf))
379 offset = _jitc->function->self.argf++;
381 offset = _jitc->function->self.size;
382 _jitc->function->self.size += sizeof(jit_word_t);
384 node = jit_new_node_ww(jit_code_arg_f, offset,
385 ++_jitc->function->self.argn);
391 _jit_arg_d(jit_state_t *_jit)
395 assert(_jitc->function);
396 if (jit_arg_f_reg_p(_jitc->function->self.argf))
397 offset = _jitc->function->self.argf++;
399 offset = _jitc->function->self.size;
400 _jitc->function->self.size += sizeof(jit_float64_t);
402 node = jit_new_node_ww(jit_code_arg_d, offset,
403 ++_jitc->function->self.argn);
409 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
411 assert(v->code == jit_code_arg);
412 jit_inc_synth_wp(getarg_c, u, v);
413 if (jit_arg_reg_p(v->u.w))
414 jit_extr_c(u, _R2 - v->u.w);
416 jit_ldxi_c(u, JIT_FP,
417 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t));
422 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
424 assert(v->code == jit_code_arg);
425 jit_inc_synth_wp(getarg_uc, u, v);
426 if (jit_arg_reg_p(v->u.w))
427 jit_extr_uc(u, _R2 - v->u.w);
429 jit_ldxi_uc(u, JIT_FP,
430 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t));
435 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
437 assert(v->code == jit_code_arg);
438 jit_inc_synth_wp(getarg_s, u, v);
439 if (jit_arg_reg_p(v->u.w))
440 jit_extr_s(u, _R2 - v->u.w);
442 jit_ldxi_s(u, JIT_FP,
443 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t));
448 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
450 assert(v->code == jit_code_arg);
451 jit_inc_synth_wp(getarg_us, u, v);
452 if (jit_arg_reg_p(v->u.w))
453 jit_extr_us(u, _R2 - v->u.w);
455 jit_ldxi_us(u, JIT_FP,
456 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t));
461 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
463 assert(v->code == jit_code_arg);
464 jit_inc_synth_wp(getarg_i, u, v);
465 if (jit_arg_reg_p(v->u.w)) {
467 jit_movr(u, _R2 - v->u.w);
469 jit_extr_i(u, _R2 - v->u.w);
473 jit_ldxi_i(u, JIT_FP,
474 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t));
480 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
482 assert(v->code == jit_code_arg);
483 jit_inc_synth_wp(getarg_ui, u, v);
484 if (jit_arg_reg_p(v->u.w))
485 jit_extr_ui(u, _R2 - v->u.w);
487 jit_ldxi_ui(u, JIT_FP,
488 v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint32_t));
493 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
495 assert(v->code == jit_code_arg);
496 jit_inc_synth_wp(getarg_l, u, v);
497 if (jit_arg_reg_p(v->u.w))
498 jit_movr(u, _R2 - v->u.w);
500 jit_ldxi_l(u, JIT_FP, v->u.w);
506 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
508 assert(v->code == jit_code_arg);
509 jit_inc_synth_wp(putargr, u, v);
510 if (jit_arg_reg_p(v->u.w))
511 jit_movr(_R2 - v->u.w, u);
513 jit_stxi(v->u.w, JIT_FP, u);
518 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
521 assert(v->code == jit_code_arg);
522 jit_inc_synth_wp(putargi, u, v);
523 if (jit_arg_reg_p(v->u.w))
524 jit_movi(_R2 - v->u.w, u);
526 regno = jit_get_reg(jit_class_gpr);
528 jit_stxi(v->u.w, JIT_FP, regno);
529 jit_unget_reg(regno);
535 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
537 assert(v->code == jit_code_arg_f);
538 jit_inc_synth_wp(getarg_f, u, v);
539 if (jit_arg_f_reg_p(v->u.w))
540 jit_movr_f(u, _F0 - v->u.w);
542 jit_ldxi_f(u, JIT_FP,
545 + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
552 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
554 assert(v->code == jit_code_arg_f);
555 jit_inc_synth_wp(putargr_f, u, v);
556 if (jit_arg_f_reg_p(v->u.w))
557 jit_movr_f(_F0 - v->u.w, u);
561 + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
568 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
571 assert(v->code == jit_code_arg_f);
572 jit_inc_synth_fp(putargi_f, u, v);
573 if (jit_arg_f_reg_p(v->u.w))
574 jit_movi_f(_F0 - v->u.w, u);
576 regno = jit_get_reg(jit_class_fpr);
577 jit_movi_f(regno, u);
580 + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
583 jit_unget_reg(regno);
589 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
591 assert(v->code == jit_code_arg_d);
592 jit_inc_synth_wp(getarg_d, u, v);
593 if (jit_arg_f_reg_p(v->u.w))
594 jit_movr_d(u, _F0 - v->u.w);
596 jit_ldxi_d(u, JIT_FP, v->u.w);
601 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
603 assert(v->code == jit_code_arg_d);
604 jit_inc_synth_wp(putargr_d, u, v);
605 if (jit_arg_f_reg_p(v->u.w))
606 jit_movr_d(_F0 - v->u.w, u);
608 jit_stxi_d(v->u.w, JIT_FP, u);
613 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
616 assert(v->code == jit_code_arg_d);
617 jit_inc_synth_dp(putargi_d, u, v);
618 if (jit_arg_f_reg_p(v->u.w))
619 jit_movi_d(_F0 - v->u.w, u);
621 regno = jit_get_reg(jit_class_fpr);
622 jit_movi_d(regno, u);
623 jit_stxi_d(v->u.w, JIT_FP, regno);
624 jit_unget_reg(regno);
630 _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
632 assert(_jitc->function);
633 jit_inc_synth_w(pushargr, u);
635 if (jit_arg_reg_p(_jitc->function->call.argi)) {
636 jit_movr(_R2 - _jitc->function->call.argi, u);
637 ++_jitc->function->call.argi;
640 jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u);
641 _jitc->function->call.size += sizeof(jit_word_t);
647 _jit_pushargi(jit_state_t *_jit, jit_word_t u)
650 assert(_jitc->function);
651 jit_inc_synth_w(pushargi, u);
653 if (jit_arg_reg_p(_jitc->function->call.argi)) {
654 jit_movi(_R2 - _jitc->function->call.argi, u);
655 ++_jitc->function->call.argi;
658 regno = jit_get_reg(jit_class_gpr);
660 jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, regno);
661 jit_unget_reg(regno);
662 _jitc->function->call.size += sizeof(jit_word_t);
668 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
670 assert(_jitc->function);
671 jit_inc_synth_w(pushargr_f, u);
673 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
674 jit_movr_f(_F0 - _jitc->function->call.argf, u);
675 ++_jitc->function->call.argf;
678 jit_stxi_f(_jitc->function->call.size + stack_framesize
680 + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
683 _jitc->function->call.size += sizeof(jit_word_t);
689 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
692 assert(_jitc->function);
693 jit_inc_synth_f(pushargi_f, u);
695 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
696 jit_movi_f(_F0 - _jitc->function->call.argf, u);
697 ++_jitc->function->call.argf;
700 regno = jit_get_reg(jit_class_fpr);
701 jit_movi_f(regno, u);
702 jit_stxi_f(_jitc->function->call.size + stack_framesize
704 + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
707 jit_unget_reg(regno);
708 _jitc->function->call.size += sizeof(jit_word_t);
714 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
716 assert(_jitc->function);
717 jit_inc_synth_w(pushargr_d, u);
719 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
720 jit_movr_d(_F0 - _jitc->function->call.argf, u);
721 ++_jitc->function->call.argf;
724 jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, u);
725 _jitc->function->call.size += sizeof(jit_float64_t);
731 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
734 assert(_jitc->function);
735 jit_inc_synth_d(pushargi_d, u);
737 if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
738 jit_movi_d(_F0 - _jitc->function->call.argf, u);
739 ++_jitc->function->call.argf;
742 regno = jit_get_reg(jit_class_fpr);
743 jit_movi_d(regno, u);
744 jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, regno);
745 jit_unget_reg(regno);
746 _jitc->function->call.size += sizeof(jit_float64_t);
752 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
755 spec = jit_class(_rvs[regno].spec);
756 if (spec & jit_class_arg) {
758 if (regno >= 0 && regno < node->v.w)
760 if (spec & jit_class_fpr) {
762 if (regno >= 0 && regno < node->w.w)
770 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
773 assert(_jitc->function);
774 jit_inc_synth_w(finishr, r0);
775 if (_jitc->function->self.alen < _jitc->function->call.size)
776 _jitc->function->self.alen = _jitc->function->call.size;
777 call = jit_callr(r0);
778 call->v.w = _jitc->function->call.argi;
779 call->w.w = _jitc->function->call.argf;
780 _jitc->function->call.argi = _jitc->function->call.argf =
781 _jitc->function->call.size = 0;
787 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
790 assert(_jitc->function);
791 jit_inc_synth_w(finishi, (jit_word_t)i0);
792 if (_jitc->function->self.alen < _jitc->function->call.size)
793 _jitc->function->self.alen = _jitc->function->call.size;
794 node = jit_calli(i0);
795 node->v.w = _jitc->function->call.argi;
796 node->w.w = _jitc->function->call.argf;
797 _jitc->function->call.argi = _jitc->function->call.argf =
798 _jitc->function->call.size = 0;
805 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
807 jit_inc_synth_w(retval_c, r0);
808 jit_extr_c(r0, JIT_RET);
813 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
815 jit_inc_synth_w(retval_uc, r0);
816 jit_extr_uc(r0, JIT_RET);
821 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
823 jit_inc_synth_w(retval_s, r0);
824 jit_extr_s(r0, JIT_RET);
829 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
831 jit_inc_synth_w(retval_us, r0);
832 jit_extr_us(r0, JIT_RET);
837 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
839 jit_inc_synth_w(retval_i, r0);
841 jit_extr_i(r0, JIT_RET);
843 jit_movr(r0, JIT_RET);
850 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
852 jit_inc_synth_w(retval_ui, r0);
853 jit_extr_ui(r0, JIT_RET);
858 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
860 jit_inc_synth_w(retval_l, r0);
861 jit_movr(r0, JIT_RET);
867 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
869 jit_inc_synth_w(retval_f, r0);
870 jit_movr_f(r0, JIT_FRET);
875 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
877 jit_inc_synth_w(retval_d, r0);
878 jit_movr_d(r0, JIT_FRET);
883 _emit_code(jit_state_t *_jit)
893 #if DEVEL_DISASSEMBLER
896 jit_int32_t patch_offset;
898 #if DEVEL_DISASSEMBLER
902 _jitc->function = NULL;
908 undo.patch_offset = 0;
910 #define assert_data(node) /**/
911 #define case_rr(name, type) \
912 case jit_code_##name##r##type: \
913 name##r##type(rn(node->u.w), rn(node->v.w)); \
915 #define case_rw(name, type) \
916 case jit_code_##name##i##type: \
917 name##i##type(rn(node->u.w), node->v.w); \
919 #define case_wr(name, type) \
920 case jit_code_##name##i##type: \
921 name##i##type(node->u.w, rn(node->v.w)); \
923 #define case_rrr(name, type) \
924 case jit_code_##name##r##type: \
925 name##r##type(rn(node->u.w), \
926 rn(node->v.w), rn(node->w.w)); \
928 #define case_rrrr(name, type) \
929 case jit_code_##name##r##type: \
930 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
931 rn(node->v.w), rn(node->w.w)); \
933 #define case_rrw(name, type) \
934 case jit_code_##name##i##type: \
935 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
937 #define case_rrrw(name, type) \
938 case jit_code_##name##i##type: \
939 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
940 rn(node->v.w), node->w.w); \
942 #define case_rrf(name) \
943 case jit_code_##name##i_f: \
945 name##i_f(rn(node->u.w), rn(node->v.w), \
946 (jit_float32_t *)node->w.n->u.w); \
948 #define case_rrd(name) \
949 case jit_code_##name##i_d: \
951 name##i_d(rn(node->u.w), rn(node->v.w), \
952 (jit_float64_t *)node->w.n->u.w); \
954 #define case_wrr(name, type) \
955 case jit_code_##name##i##type: \
956 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
958 #define case_brr(name, type) \
959 case jit_code_##name##r##type: \
961 assert(temp->code == jit_code_label || \
962 temp->code == jit_code_epilog); \
963 if (temp->flag & jit_flag_patch) \
964 name##r##type(temp->u.w, rn(node->v.w), \
967 word = name##r##type##_p(_jit->pc.w, \
973 #define case_brw(name, type) \
974 case jit_code_##name##i##type: \
976 assert(temp->code == jit_code_label || \
977 temp->code == jit_code_epilog); \
978 if (temp->flag & jit_flag_patch) \
979 name##i##type(temp->u.w, \
980 rn(node->v.w), node->w.w); \
982 word = name##i##type##_p(_jit->pc.w, \
983 rn(node->v.w), node->w.w); \
987 #define case_brf(name) \
988 case jit_code_##name##i_f: \
990 assert(temp->code == jit_code_label || \
991 temp->code == jit_code_epilog); \
992 if (temp->flag & jit_flag_patch) \
993 name##i_f(temp->u.w, rn(node->v.w), \
994 (jit_float32_t *)node->w.n->u.w); \
996 word = name##i_f_p(_jit->pc.w, rn(node->v.w), \
997 (jit_float32_t *)node->w.n->u.w);\
1001 #define case_brd(name) \
1002 case jit_code_##name##i_d: \
1004 assert(temp->code == jit_code_label || \
1005 temp->code == jit_code_epilog); \
1006 if (temp->flag & jit_flag_patch) \
1007 name##i_d(temp->u.w, rn(node->v.w), \
1008 (jit_float64_t *)node->w.n->u.w); \
1010 word = name##i_d_p(_jit->pc.w, rn(node->v.w), \
1011 (jit_float64_t *)node->w.n->u.w);\
1012 patch(word, node); \
1015 #if DEVEL_DISASSEMBLER
1018 for (node = _jitc->head; node; node = node->next) {
1019 if (_jit->pc.uc >= _jitc->code.end)
1022 #if DEVEL_DISASSEMBLER
1023 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1026 value = jit_classify(node->code);
1027 jit_regarg_set(node, value);
1028 switch (node->code) {
1029 case jit_code_align:
1030 /* Must align to a power of two */
1031 assert(!(node->u.w & (node->u.w - 1)));
1032 if ((word = _jit->pc.w & (node->u.w - 1)))
1033 nop(node->u.w - word);
1035 case jit_code_note: case jit_code_name:
1036 node->u.w = _jit->pc.w;
1038 case jit_code_label:
1039 if ((node->link || (node->flag & jit_flag_use)) &&
1040 (word = _jit->pc.w & 3))
1042 /* remember label is defined */
1043 node->flag |= jit_flag_patch;
1044 node->u.w = _jit->pc.w;
1063 case_rrrr(qmul, _u);
1064 case_rrrw(qmul, _u);
1075 case_rrrr(qdiv, _u);
1076 case_rrrw(qdiv, _u);
1091 case_rr(trunc, _f_i);
1092 case_rr(trunc, _d_i);
1093 #if __WORDSIZE == 64
1094 case_rr(trunc, _f_l);
1095 case_rr(trunc, _d_l);
1107 #if __WORDSIZE == 64
1123 #if __WORDSIZE == 64
1135 #if __WORDSIZE == 64
1145 #if __WORDSIZE == 64
1151 #if __WORDSIZE == 64
1154 case_rr(bswap, _us);
1155 case_rr(bswap, _ui);
1156 #if __WORDSIZE == 64
1157 case_rr(bswap, _ul);
1163 #if __WORDSIZE == 64
1168 casr(rn(node->u.w), rn(node->v.w),
1169 rn(node->w.q.l), rn(node->w.q.h));
1172 casi(rn(node->u.w), node->v.w,
1173 rn(node->w.q.l), rn(node->w.q.h));
1179 if (node->flag & jit_flag_node) {
1181 if (temp->code == jit_code_data ||
1182 (temp->code == jit_code_label &&
1183 (temp->flag & jit_flag_patch)))
1184 movi(rn(node->u.w), temp->u.w);
1186 assert(temp->code == jit_code_label ||
1187 temp->code == jit_code_epilog);
1188 word = movi_p(rn(node->u.w), temp->u.w);
1193 movi(rn(node->u.w), node->v.w);
1237 case_brr(boadd, _u);
1238 case_brw(boadd, _u);
1241 case_brr(bxadd, _u);
1242 case_brw(bxadd, _u);
1245 case_brr(bosub, _u);
1246 case_brw(bosub, _u);
1249 case_brr(bxsub, _u);
1250 case_brw(bxsub, _u);
1277 case jit_code_movi_f:
1279 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1308 case_rrr(unord, _f);
1322 case_brr(bunlt, _f);
1324 case_brr(bunle, _f);
1326 case_brr(buneq, _f);
1328 case_brr(bunge, _f);
1330 case_brr(bungt, _f);
1332 case_brr(bltgt, _f);
1336 case_brr(bunord, _f);
1360 case jit_code_movi_d:
1362 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1391 case_rrr(unord, _d);
1405 case_brr(bunlt, _d);
1407 case_brr(bunle, _d);
1409 case_brr(buneq, _d);
1411 case_brr(bunge, _d);
1413 case_brr(bungt, _d);
1415 case_brr(bltgt, _d);
1419 case_brr(bunord, _d);
1422 jmpr(rn(node->u.w));
1425 if (node->flag & jit_flag_node) {
1427 assert(temp->code == jit_code_label ||
1428 temp->code == jit_code_epilog);
1429 if (temp->flag & jit_flag_patch)
1432 word = jmpi_p(_jit->pc.w);
1439 case jit_code_callr:
1440 callr(rn(node->u.w));
1442 case jit_code_calli:
1443 if (node->flag & jit_flag_node) {
1445 assert(temp->code == jit_code_label ||
1446 temp->code == jit_code_epilog);
1447 if (temp->flag & jit_flag_patch)
1450 word = calli_p(_jit->pc.w);
1457 case jit_code_prolog:
1458 _jitc->function = _jitc->functions.ptr + node->w.w;
1460 undo.word = _jit->pc.w;
1461 #if DEVEL_DISASSEMBLER
1464 undo.patch_offset = _jitc->patches.offset;
1469 case jit_code_epilog:
1470 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1472 for (temp = undo.node->next;
1473 temp != node; temp = temp->next) {
1474 if (temp->code == jit_code_label ||
1475 temp->code == jit_code_epilog)
1476 temp->flag &= ~jit_flag_patch;
1478 temp->flag &= ~jit_flag_patch;
1480 _jit->pc.w = undo.word;
1481 #if DEVEL_DISASSEMBLER
1484 _jitc->patches.offset = undo.patch_offset;
1485 goto restart_function;
1487 if (node->link && (word = _jit->pc.w & 3))
1489 /* remember label is defined */
1490 node->flag |= jit_flag_patch;
1491 node->u.w = _jit->pc.w;
1493 _jitc->function = NULL;
1495 case jit_code_va_start:
1496 vastart(rn(node->u.w));
1498 case jit_code_va_arg:
1499 vaarg(rn(node->u.w), rn(node->v.w));
1501 case jit_code_va_arg_d:
1502 vaarg_d(rn(node->u.w), rn(node->v.w));
1504 case jit_code_live: case jit_code_ellipsis:
1505 case jit_code_va_push:
1506 case jit_code_allocai: case jit_code_allocar:
1508 case jit_code_arg_f: case jit_code_arg_d:
1509 case jit_code_va_end:
1511 case jit_code_retr: case jit_code_reti:
1512 case jit_code_retr_f: case jit_code_reti_f:
1513 case jit_code_retr_d: case jit_code_reti_d:
1514 case jit_code_getarg_c: case jit_code_getarg_uc:
1515 case jit_code_getarg_s: case jit_code_getarg_us:
1516 case jit_code_getarg_i:
1517 #if __WORDSIZE == 64
1518 case jit_code_getarg_ui: case jit_code_getarg_l:
1520 case jit_code_getarg_f: case jit_code_getarg_d:
1521 case jit_code_putargr: case jit_code_putargi:
1522 case jit_code_putargr_f: case jit_code_putargi_f:
1523 case jit_code_putargr_d: case jit_code_putargi_d:
1524 case jit_code_pushargr: case jit_code_pushargi:
1525 case jit_code_pushargr_f: case jit_code_pushargi_f:
1526 case jit_code_pushargr_d: case jit_code_pushargi_d:
1527 case jit_code_retval_c: case jit_code_retval_uc:
1528 case jit_code_retval_s: case jit_code_retval_us:
1529 case jit_code_retval_i:
1530 #if __WORDSIZE == 64
1531 case jit_code_retval_ui: case jit_code_retval_l:
1533 case jit_code_retval_f: case jit_code_retval_d:
1534 case jit_code_prepare:
1535 case jit_code_finishr: case jit_code_finishi:
1540 jit_regarg_clr(node, value);
1541 assert(_jitc->regarg == 0 && _jitc->synth == 0);
1542 /* update register live state */
1554 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1555 node = _jitc->patches.ptr[offset].node;
1556 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1557 patch_at(_jitc->patches.ptr[offset].inst, word);
1560 jit_flush(_jit->code.ptr, _jit->pc.uc);
1562 return (_jit->code.ptr);
1566 # include "jit_s390-cpu.c"
1567 # include "jit_s390-fpu.c"
1571 jit_flush(void *fptr, void *tptr)
1573 #if defined(__GNUC__)
1576 s = sysconf(_SC_PAGE_SIZE);
1577 f = (jit_word_t)fptr & -s;
1578 t = (((jit_word_t)tptr) + s - 1) & -s;
1579 __clear_cache((void *)f, (void *)t);
1584 _emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0)
1586 ldxi(rn(r0), rn(r1), i0);
1590 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1)
1592 stxi(i0, rn(r0), rn(r1));
1596 _emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0)
1598 ldxi_d(rn(r0), rn(r1), i0);
1602 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1)
1604 stxi_d(i0, rn(r0), rn(r1));
1608 _jit_get_reg_pair(jit_state_t *_jit)
1611 /* Try to find a register pair for use with operations that
1612 * require a odd based register pair. Search for the best
1613 * match to avoid spills or at least a valid operation.
1616 /* Try non callee save first */
1617 if (jit_reg_free_p(_R0) && jit_reg_free_p(_R1))
1619 else if (jit_reg_free_p(_R2) && jit_reg_free_p(_R3))
1621 else if (jit_reg_free_p(_R4) && jit_reg_free_p(_R5))
1623 /* Try callee save registers */
1624 else if (jit_reg_free_p(_R10) && jit_reg_free_p(_R11))
1625 r1 = _R10, r2 = _R11;
1626 else if (jit_reg_free_p(_R8) && jit_reg_free_p(_R9))
1628 else if (jit_reg_free_p(_R6) && jit_reg_free_p(_R7))
1631 /* We *must* find a register pair */
1632 else if (jit_reg_free_if_spill_p(_R0) && jit_reg_free_if_spill_p(_R1))
1634 else if (jit_reg_free_if_spill_p(_R2) && jit_reg_free_if_spill_p(_R3))
1636 else if (jit_reg_free_if_spill_p(_R4) && jit_reg_free_if_spill_p(_R5))
1638 else if (jit_reg_free_if_spill_p(_R10) && jit_reg_free_if_spill_p(_R11))
1639 r1 = _R10, r2 = _R11;
1640 else if (jit_reg_free_if_spill_p(_R8) && jit_reg_free_if_spill_p(_R9))
1642 else if (jit_reg_free_if_spill_p(_R6) && jit_reg_free_if_spill_p(_R7))
1645 /* Do not jit_get_reg() all registers to avoid it */
1648 (void)jit_get_reg(jit_class_gpr|jit_class_named|r1);
1649 (void)jit_get_reg(jit_class_gpr|jit_class_named|r2);
1655 _jit_unget_reg_pair(jit_state_t *_jit, jit_int32_t reg)
1660 case _R0: r2 = _R1; break;
1661 case _R2: r2 = _R3; break;
1662 case _R4: r2 = _R5; break;
1663 case _R6: r2 = _R7; break;
1664 case _R8: r2 = _R9; break;
1665 case _R10: r2 = _R11; break;
1673 _jit_get_reg_but_zero(jit_state_t *_jit, jit_int32_t flags)
1676 reg = jit_get_reg(jit_class_gpr);
1678 reg = jit_get_reg(jit_class_gpr|flags);
1685 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
1689 assert(node->flag & jit_flag_node);
1690 if (node->code == jit_code_movi)
1691 flag = node->v.n->flag;
1693 flag = node->u.n->flag;
1694 assert(!(flag & jit_flag_patch));
1695 if (_jitc->patches.offset >= _jitc->patches.length) {
1696 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
1697 _jitc->patches.length * sizeof(jit_patch_t),
1698 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
1699 _jitc->patches.length += 1024;
1701 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
1702 _jitc->patches.ptr[_jitc->patches.offset].node = node;
1703 ++_jitc->patches.offset;