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
20 #include <lightning.h>
21 #include <lightning/jit_private.h>
22 #if defined(__linux__)
23 # include <sys/syscall.h>
27 #define jit_arg_reg_p(i) (i >= 0 && i < 4)
30 # include "jit_hppa-cpu.c"
31 # include "jit_hppa-fpu.c"
32 # include "jit_fallback.c"
38 typedef jit_pointer_t jit_va_list;
43 #define patch(instr, node) _patch(_jit, instr, node)
44 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
47 extern void __clear_cache(void *, void *);
52 jit_register_t _rvs[] = {
53 { 0, "r0" }, /* Zero */
54 /* Not register starved, so, avoid allocating r1 and rp
55 * due to being implicit target of ADDIL and B,L */
56 { 1, "r1" }, /* Scratch */
57 { 2, "rp" }, /* Return Pointer and scratch */
58 { rc(sav) | 3, "r3" },
59 { 19, "r19" }, /* Linkage Table */
60 { rc(gpr) | 20, "r20" },
61 { rc(gpr) | 21, "r21" },
62 { rc(gpr) | 22, "r22" },
63 { rc(gpr) | 29, "ret1" },
64 { rc(gpr) | 28, "ret0" },
65 /* JIT_Rx in callee save registers due to need to call
66 * functions to implement some instructions */
68 { rc(gpr) | rc(sav) | 4, "r4" },
69 { rc(gpr) | rc(sav) | 5, "r5" },
70 { rc(gpr) | rc(sav) | 6, "r6" },
72 { rc(gpr) | rc(sav) | 7, "r7" },
73 { rc(sav) | rc(sav) | 8, "r8" },
74 { rc(gpr) | rc(sav) | 9, "r9" },
76 { rc(gpr) | rc(sav) | 10, "r10" },
78 { rc(gpr) | rc(sav) | 11, "r11" },
79 { rc(gpr) | rc(sav) | 12, "r12" },
80 { rc(gpr) | rc(sav) | 13, "r13" },
81 { rc(gpr) | rc(sav) | 14, "r14" },
82 { rc(gpr) | rc(sav) | 15, "r15" },
83 { rc(gpr) | rc(sav) | 16, "r16" },
84 { rc(gpr) | rc(sav) | 17, "r17" },
85 { rc(gpr) | rc(sav) | 18, "r18" },
87 { rc(gpr) | rc(arg) | 23, "r23" },
88 { rc(gpr) | rc(arg) | 24, "r24" },
89 { rc(gpr) | rc(arg) | 25, "r25" },
90 { rc(gpr) | rc(arg) | 26, "r26" },
91 { 27, "dp" }, /* Data Pointer */
93 { 31, "r31" }, /* Link Register */
94 { rc(fpr) | 31, "fr31" },
95 { rc(fpr) | 30, "fr30" },
96 { rc(fpr) | 29, "fr29" },
97 { rc(fpr) | 28, "fr28" },
98 { rc(fpr) | 27, "fr27" },
99 { rc(fpr) | 26, "fr26" },
100 { rc(fpr) | 25, "fr25" },
101 { rc(fpr) | 24, "fr24" },
102 { rc(fpr) | 23, "fr23" },
103 { rc(fpr) | 22, "fr22" },
104 { rc(fpr) | 11, "fr11" },
105 { rc(fpr) | 10, "fr10" },
106 { rc(fpr) | 9, "fr9" },
107 { rc(fpr) | 8, "fr8" },
109 { rc(fpr) | rc(arg) | 7, "fr7" },
110 { rc(fpr) | rc(arg) | 6, "fr6" },
111 { rc(fpr) | rc(arg) | 5, "fr5" },
112 { rc(fpr) | rc(arg) | 4, "fr4" },
114 { rc(fpr) | rc(sav) | 21, "fr21" },
115 { rc(fpr) | rc(sav) | 20, "fr20" },
116 { rc(fpr) | rc(sav) | 19, "fr19" },
117 { rc(fpr) | rc(sav) | 18, "fr18" },
118 { rc(fpr) | rc(sav) | 17, "fr17" },
119 { rc(fpr) | rc(sav) | 16, "fr16" },
120 { rc(fpr) | rc(sav) | 15, "fr15" },
121 { rc(fpr) | rc(sav) | 14, "fr14" },
122 { rc(fpr) | rc(sav) | 13, "fr13" },
123 { rc(fpr) | rc(sav) | 12, "fr12" },
128 { _NOREG, "<none>" },
137 /* FIXME Expecting PARISC 2.0, for PARISC 1.0 should not use fr16-fr31 */
141 _jit_init(jit_state_t *_jit)
143 _jitc->reglen = jit_size(_rvs) - 1;
147 _jit_prolog(jit_state_t *_jit)
153 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
154 jit_regset_set_ui(&_jitc->regsav, 0);
155 offset = _jitc->functions.offset;
156 if (offset >= _jitc->functions.length) {
157 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
158 _jitc->functions.length * sizeof(jit_function_t),
159 (_jitc->functions.length + 16) * sizeof(jit_function_t));
160 _jitc->functions.length += 16;
162 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
163 _jitc->function->self.size = params_offset;
164 _jitc->function->self.argi = _jitc->function->self.alen = 0;
165 /* float conversion */
166 _jitc->function->self.aoff = alloca_offset;
167 _jitc->function->self.call = jit_call_default;
168 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
169 _jitc->reglen * sizeof(jit_int32_t));
171 /* _no_link here does not mean the jit_link() call can be removed
173 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
175 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
176 jit_link(_jitc->function->prolog);
177 _jitc->function->prolog->w.w = offset;
178 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
180 * v: offset in blocks vector
181 * w: offset in functions vector
183 _jitc->function->epilog->w.w = offset;
185 jit_regset_new(&_jitc->function->regset);
189 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
192 assert(_jitc->function);
197 _jitc->function->self.aoff = (_jitc->function->self.aoff + 1) & -2;
200 _jitc->function->self.aoff = (_jitc->function->self.aoff + 3) & -4;
203 _jitc->function->self.aoff = (_jitc->function->self.aoff + 7) & -8;
206 if (!_jitc->realize) {
207 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
210 offset = _jitc->function->self.aoff;
211 _jitc->function->self.aoff += length;
216 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
219 assert(_jitc->function);
220 jit_inc_synth_ww(allocar, u, v);
221 if (!_jitc->function->allocar) {
222 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
223 _jitc->function->allocar = 1;
225 reg = jit_get_reg(jit_class_gpr);
226 jit_addi(reg, v, 63);
227 jit_andi(reg, reg, -64);
228 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
229 jit_addr(JIT_SP, JIT_SP, reg);
230 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
236 _jit_ret(jit_state_t *_jit)
239 assert(_jitc->function);
243 jit_patch_at(instr, _jitc->function->epilog);
248 _jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
250 jit_code_inc_synth_w(code, u);
251 jit_movr(JIT_RET, u);
257 _jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
259 jit_code_inc_synth_w(code, u);
260 jit_movi(JIT_RET, u);
266 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
268 jit_inc_synth_w(retr_f, u);
269 jit_movr_f(JIT_FRET, u);
275 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
277 jit_inc_synth_f(reti_f, u);
278 jit_movi_f(JIT_FRET, u);
284 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
286 jit_inc_synth_w(retr_d, u);
287 jit_movr_d(JIT_FRET, u);
293 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
295 jit_inc_synth_d(reti_d, u);
296 jit_movi_d(JIT_FRET, u);
302 _jit_epilog(jit_state_t *_jit)
304 assert(_jitc->function);
305 assert(_jitc->function->epilog->next == NULL);
306 jit_link(_jitc->function->epilog);
307 _jitc->function = NULL;
311 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
313 assert((u->code >= jit_code_arg_c && u->code <= jit_code_arg) ||
314 u->code == jit_code_arg_f || u->code == jit_code_arg_d);
315 return (jit_arg_reg_p(u->u.w));
319 _jit_ellipsis(jit_state_t *_jit)
321 jit_inc_synth(ellipsis);
322 if (_jitc->prepare) {
324 assert(!(_jitc->function->call.call & jit_call_varargs));
325 _jitc->function->call.call |= jit_call_varargs;
329 assert(!(_jitc->function->self.call & jit_call_varargs));
330 _jitc->function->self.call |= jit_call_varargs;
332 _jitc->function->vagp = _jitc->function->self.argi;
338 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
340 jit_inc_synth_w(va_push, u);
346 _jit_arg(jit_state_t *_jit, jit_code_t code)
350 assert(_jitc->function);
351 assert(!(_jitc->function->self.call & jit_call_varargs));
352 #if STRONG_TYPE_CHECKING
353 assert(code >= jit_code_arg_c && code <= jit_code_arg);
355 _jitc->function->self.size -= sizeof(jit_word_t);
356 if (jit_arg_reg_p(_jitc->function->self.argi))
357 offset = _jitc->function->self.argi++;
359 offset = _jitc->function->self.size;
360 node = jit_new_node_ww(code, offset,
361 ++_jitc->function->self.argn);
367 _jit_arg_f(jit_state_t *_jit)
371 assert(_jitc->function);
372 _jitc->function->self.size -= sizeof(jit_word_t);
373 if (jit_arg_reg_p(_jitc->function->self.argi))
374 offset = _jitc->function->self.argi++;
376 offset = _jitc->function->self.size;
377 node = jit_new_node_ww(jit_code_arg_f, offset,
378 ++_jitc->function->self.argn);
384 _jit_arg_d(jit_state_t *_jit)
388 assert(_jitc->function);
389 if (_jitc->function->self.argi & 1) {
390 ++_jitc->function->self.argi;
391 _jitc->function->self.size -= sizeof(jit_word_t);
393 _jitc->function->self.size -= sizeof(jit_float64_t);
394 if (jit_arg_reg_p(_jitc->function->self.argi)) {
395 offset = _jitc->function->self.argi + 1;
396 _jitc->function->self.argi += 2;
399 /* "Standard" initial value (-52) is unaligned */
400 if (_jitc->function->self.size & 7)
401 _jitc->function->self.size -= sizeof(jit_word_t);
402 offset = _jitc->function->self.size;
404 node = jit_new_node_ww(jit_code_arg_d, offset,
405 ++_jitc->function->self.argn);
411 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
413 assert_arg_type(v->code, jit_code_arg_c);
414 jit_inc_synth_wp(getarg_c, u, v);
416 jit_extr_c(u, _R26 - v->u.w);
418 jit_ldxi_c(u, JIT_FP, v->u.w + 3);
423 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
425 assert_arg_type(v->code, jit_code_arg_c);
426 jit_inc_synth_wp(getarg_uc, u, v);
428 jit_extr_uc(u, _R26 - v->u.w);
430 jit_ldxi_uc(u, JIT_FP, v->u.w + 3);
435 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
437 assert_arg_type(v->code, jit_code_arg_s);
438 jit_inc_synth_wp(getarg_s, u, v);
440 jit_extr_s(u, _R26 - v->u.w);
442 jit_ldxi_s(u, JIT_FP, v->u.w + 2);
447 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
449 assert_arg_type(v->code, jit_code_arg_s);
450 jit_inc_synth_wp(getarg_us, u, v);
452 jit_extr_us(u, _R26 - v->u.w);
454 jit_ldxi_us(u, JIT_FP, v->u.w + 2);
459 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
461 assert_arg_type(v->code, jit_code_arg_i);
462 jit_inc_synth_wp(getarg_i, u, v);
464 jit_movr(u, _R26 - v->u.w);
466 jit_ldxi_i(u, JIT_FP, v->u.w);
471 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
473 assert_putarg_type(code, v->code);
474 jit_code_inc_synth_wp(code, u, v);
476 jit_movr(_R26 - v->u.w, u);
478 jit_stxi(v->u.w, JIT_FP, u);
483 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
486 assert_putarg_type(code, v->code);
487 jit_code_inc_synth_wp(code, u, v);
489 jit_movi(_R26 - v->u.w, u);
491 regno = jit_get_reg(jit_class_gpr);
493 jit_stxi(v->u.w, JIT_FP, regno);
494 jit_unget_reg(regno);
500 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
502 assert(v->code == jit_code_arg_f);
503 jit_inc_synth_wp(getarg_f, u, v);
505 jit_movr_f(u, _F4 - v->u.w);
507 jit_ldxi_f(u, JIT_FP, v->u.w);
512 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
514 assert(v->code == jit_code_arg_f);
515 jit_inc_synth_wp(putargr_f, u, v);
517 jit_movr_f(_F4 - v->u.w, u);
519 jit_stxi_f(v->u.w, JIT_FP, u);
524 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
527 assert(v->code == jit_code_arg_f);
528 jit_inc_synth_fp(putargi_f, u, v);
530 jit_movi_f(_R26 - v->u.w, u);
532 regno = jit_get_reg(jit_class_fpr);
533 jit_movi_f(regno, u);
534 jit_stxi_f(v->u.w, JIT_FP, regno);
535 jit_unget_reg(regno);
541 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
543 assert(v->code == jit_code_arg_d);
544 jit_inc_synth_wp(getarg_d, u, v);
546 jit_movr_d(u, _F4 - v->u.w);
548 jit_ldxi_d(u, JIT_FP, v->u.w);
553 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
555 assert(v->code == jit_code_arg_d);
556 jit_inc_synth_wp(putargr_d, u, v);
558 jit_movr_d(_F4 - v->u.w, u);
560 jit_stxi_d(v->u.w, JIT_FP, u);
565 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
568 assert(v->code == jit_code_arg_d);
569 jit_inc_synth_dp(putargi_d, u, v);
571 jit_movi_d(_R26 - v->u.w, u);
573 regno = jit_get_reg(jit_class_fpr);
574 jit_movi_d(regno, u);
575 jit_stxi_d(v->u.w, JIT_FP, regno);
576 jit_unget_reg(regno);
582 _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
584 assert(_jitc->function);
585 jit_code_inc_synth_w(code, u);
587 _jitc->function->call.size -= sizeof(jit_word_t);
588 if (jit_arg_reg_p(_jitc->function->call.argi)) {
589 jit_movr(_R26 - _jitc->function->call.argi, u);
590 ++_jitc->function->call.argi;
593 jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
598 _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
601 assert(_jitc->function);
602 jit_code_inc_synth_w(code, u);
604 _jitc->function->call.size -= sizeof(jit_word_t);
605 if (jit_arg_reg_p(_jitc->function->call.argi)) {
606 jit_movi(_R26 - _jitc->function->call.argi, u);
607 ++_jitc->function->call.argi;
610 regno = jit_get_reg(jit_class_gpr);
612 jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno);
613 jit_unget_reg(regno);
619 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
621 assert(_jitc->function);
622 jit_inc_synth_w(pushargr_f, u);
624 _jitc->function->call.size -= sizeof(jit_word_t);
625 if (jit_arg_reg_p(_jitc->function->call.argi)) {
626 jit_movr_f(_F4 - _jitc->function->call.argi, u);
628 /* HP-UX appears to always pass float arguments in gpr registers */
629 if (_jitc->function->call.call & jit_call_varargs)
632 jit_stxi_f(alloca_offset - 8, JIT_FP, u);
633 jit_ldxi(_R26 - _jitc->function->call.argi, JIT_FP,
636 ++_jitc->function->call.argi;
639 jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, u);
644 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
647 assert(_jitc->function);
648 jit_inc_synth_f(pushargi_f, u);
650 _jitc->function->call.size -= sizeof(jit_word_t);
651 if (jit_arg_reg_p(_jitc->function->call.argi)) {
652 jit_movi_f(_F4 - _jitc->function->call.argi, u);
654 /* HP-UX appears to always pass float arguments in gpr registers */
655 if (_jitc->function->call.call & jit_call_varargs)
658 jit_stxi_f(alloca_offset - 8, JIT_FP,
659 _F4 - _jitc->function->call.argi);
660 jit_ldxi(_R26 - _jitc->function->call.argi,
661 JIT_FP, alloca_offset - 8);
663 ++_jitc->function->call.argi;
666 regno = jit_get_reg(jit_class_fpr);
667 jit_movi_f(regno, u);
668 jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, regno);
669 jit_unget_reg(regno);
675 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
677 assert(_jitc->function);
678 jit_inc_synth_w(pushargr_d, u);
680 _jitc->function->call.size -= sizeof(jit_float64_t);
681 if (_jitc->function->call.argi & 1) {
682 ++_jitc->function->call.argi;
683 _jitc->function->call.size -= sizeof(jit_word_t);
685 if (jit_arg_reg_p(_jitc->function->call.argi)) {
686 jit_movr_d(_F4 - (_jitc->function->call.argi + 1), u);
688 /* HP-UX appears to always pass float arguments in gpr registers */
689 if (_jitc->function->call.call & jit_call_varargs)
692 jit_stxi_d(alloca_offset - 8, JIT_FP, u);
693 jit_ldxi(_R26 - _jitc->function->call.argi,
694 JIT_FP, alloca_offset - 4);
695 jit_ldxi(_R25 - _jitc->function->call.argi,
696 JIT_FP, alloca_offset - 8);
698 _jitc->function->call.argi += 2;
701 /* "Standard" initial value (-52) is unaligned */
702 if ((_jitc->function->call.size + params_offset) & 7)
703 _jitc->function->call.size -= sizeof(jit_word_t);
704 jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
710 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
713 assert(_jitc->function);
714 jit_inc_synth_d(pushargi_d, u);
716 _jitc->function->call.size -= sizeof(jit_float64_t);
717 if (_jitc->function->call.argi & 1) {
718 ++_jitc->function->call.argi;
719 _jitc->function->call.size -= sizeof(jit_word_t);
721 if (jit_arg_reg_p(_jitc->function->call.argi)) {
722 jit_movi_d(_F4 - (_jitc->function->call.argi + 1), u);
724 /* HP-UX appears to always pass float arguments in gpr registers */
725 if (_jitc->function->call.call & jit_call_varargs)
728 jit_stxi_d(alloca_offset - 8, JIT_FP,
729 _F4 - (_jitc->function->call.argi + 1));
730 jit_ldxi(_R26 - _jitc->function->call.argi,
731 JIT_FP, alloca_offset - 4);
732 jit_ldxi(_R25 - _jitc->function->call.argi,
733 JIT_FP, alloca_offset - 8);
735 _jitc->function->call.argi += 2;
738 regno = jit_get_reg(jit_class_fpr);
739 jit_movi_d(regno, u);
740 if ((_jitc->function->call.size + params_offset) & 7)
741 _jitc->function->call.size -= sizeof(jit_word_t);
742 jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno);
743 jit_unget_reg(regno);
749 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
752 spec = jit_class(_rvs[regno].spec);
753 if (spec & jit_class_arg) {
754 if (spec & jit_class_gpr) {
756 if (regno >= 0 && regno < node->v.w)
759 else if (spec & jit_class_fpr) {
761 if (regno >= 0 && regno < node->w.w)
769 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
772 assert(_jitc->function);
773 jit_inc_synth_w(finishr, r0);
774 if (_jitc->function->self.alen > _jitc->function->call.size)
775 _jitc->function->self.alen = _jitc->function->call.size;
776 call = jit_callr(r0);
777 call->v.w = call->w.w = _jitc->function->call.argi;
778 _jitc->function->call.argi = _jitc->function->call.size = 0;
784 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
787 assert(_jitc->function);
788 jit_inc_synth_w(finishi, (jit_word_t)i0);
789 if (_jitc->function->self.alen > _jitc->function->call.size)
790 _jitc->function->self.alen = _jitc->function->call.size;
791 node = jit_calli(i0);
792 node->v.w = node->w.w = _jitc->function->call.argi;
793 _jitc->function->call.argi = _jitc->function->call.size = 0;
800 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
802 jit_inc_synth_w(retval_c, r0);
803 jit_extr_c(r0, JIT_RET);
808 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
810 jit_inc_synth_w(retval_uc, r0);
811 jit_extr_uc(r0, JIT_RET);
816 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
818 jit_inc_synth_w(retval_s, r0);
819 jit_extr_s(r0, JIT_RET);
824 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
826 jit_inc_synth_w(retval_us, r0);
827 jit_extr_us(r0, JIT_RET);
832 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
834 jit_inc_synth_w(retval_i, r0);
835 jit_movr(r0, JIT_RET);
840 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
842 jit_inc_synth_w(retval_f, r0);
843 jit_movr_f(r0, JIT_FRET);
848 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
850 jit_inc_synth_w(retval_d, r0);
851 jit_movr_d(r0, JIT_FRET);
856 _emit_code(jit_state_t *_jit)
867 #if DEVEL_DISASSEMBLER
870 jit_int32_t patch_offset;
872 #if DEVEL_DISASSEMBLER
876 _jitc->function = NULL;
882 undo.patch_offset = 0;
884 #define case_rr(name, type) \
885 case jit_code_##name##r##type: \
886 name##r##type(rn(node->u.w), rn(node->v.w)); \
888 #define case_rw(name, type) \
889 case jit_code_##name##i##type: \
890 name##i##type(rn(node->u.w), node->v.w); \
892 #define case_wr(name, type) \
893 case jit_code_##name##i##type: \
894 name##i##type(node->u.w, rn(node->v.w)); \
896 #define case_rrr(name, type) \
897 case jit_code_##name##r##type: \
898 name##r##type(rn(node->u.w), \
899 rn(node->v.w), rn(node->w.w)); \
901 #define case_rrrr(name, type) \
902 case jit_code_##name##r##type: \
903 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
904 rn(node->v.w), rn(node->w.w)); \
906 #define case_rrw(name, type) \
907 case jit_code_##name##i##type: \
908 name##i##type(rn(node->u.w),rn(node->v.w), node->w.w); \
910 #define case_rrrw(name, type) \
911 case jit_code_##name##i##type: \
912 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
913 rn(node->v.w), node->w.w); \
915 #define case_rrf(name, type, size) \
916 case jit_code_##name##i##type: \
917 assert(node->flag & jit_flag_data); \
918 name##i##type(rn(node->u.w), rn(node->v.w), \
919 (jit_float##size##_t *)node->w.n->u.w); \
921 #define case_wrr(name, type) \
922 case jit_code_##name##i##type: \
923 name##i##type(node->u.w,rn(node->v.w), rn(node->w.w)); \
925 #define case_brr(name, type) \
926 case jit_code_##name##r##type: \
928 assert(temp->code == jit_code_label || \
929 temp->code == jit_code_epilog); \
930 if (temp->flag & jit_flag_patch) \
931 name##r##type(temp->u.w, rn(node->v.w), \
934 word = name##r##type(_jit->pc.w, \
935 rn(node->v.w), rn(node->w.w)); \
939 #define case_brw(name, type) \
940 case jit_code_##name##i##type: \
942 assert(temp->code == jit_code_label || \
943 temp->code == jit_code_epilog); \
944 if (temp->flag & jit_flag_patch) \
945 name##i##type(temp->u.w, \
946 rn(node->v.w), node->w.w); \
948 word = name##i##type(_jit->pc.w, \
949 rn(node->v.w), node->w.w); \
953 #define case_brf(name, type, size) \
954 case jit_code_##name##i##type: \
956 assert(temp->code == jit_code_label || \
957 temp->code == jit_code_epilog); \
958 if (temp->flag & jit_flag_patch) \
959 name##i##type(temp->u.w, rn(node->v.w), \
960 (jit_float##size##_t *)node->w.n->u.w); \
962 word = name##i##type(_jit->pc.w, rn(node->v.w), \
963 (jit_float##size##_t *)node->w.n->u.w); \
967 #if DEVEL_DISASSEMBLER
970 for (node = _jitc->head; node; node = node->next) {
971 if (_jit->pc.uc >= _jitc->code.end)
974 #if DEVEL_DISASSEMBLER
975 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
978 value = jit_classify(node->code);
979 jit_regarg_set(node, value);
980 switch (node->code) {
982 /* Must align to a power of two */
983 assert(!(node->u.w & (node->u.w - 1)));
984 if ((word = _jit->pc.w & (node->u.w - 1)))
985 nop(node->u.w - word);
988 nop((node->u.w + 3) & ~3);
990 case jit_code_note: case jit_code_name:
991 node->u.w = _jit->pc.w;
994 /* remember label is defined */
995 node->flag |= jit_flag_patch;
996 node->u.w = _jit->pc.w;
1015 case_rrrr(qmul, _u);
1016 case_rrrw(qmul, _u);
1027 case_rrrr(qdiv, _u);
1028 case_rrrw(qdiv, _u);
1044 casr(rn(node->u.w), rn(node->v.w),
1045 rn(node->w.q.l), rn(node->w.q.h));
1048 casi(rn(node->u.w), node->v.w,
1049 rn(node->w.q.l), rn(node->w.q.h));
1053 if (node->flag & jit_flag_node) {
1055 if (temp->code == jit_code_data ||
1056 (temp->code == jit_code_label &&
1057 (temp->flag & jit_flag_patch)))
1058 movi(rn(node->u.w), temp->u.w);
1060 assert(temp->code == jit_code_label ||
1061 temp->code == jit_code_epilog);
1062 word = movi_p(rn(node->u.w), node->v.w);
1067 movi(rn(node->u.w), node->v.w);
1071 #define clor(r0, r1) fallback_clo(r0, r1)
1072 #define clzr(r0, r1) fallback_clz(r0, r1)
1073 #define ctor(r0, r1) fallback_cto(r0, r1)
1074 #define ctzr(r0, r1) fallback_ctz(r0, r1)
1085 case_rr(bswap, _us);
1086 case_rr(bswap, _ui);
1165 case_brr(boadd, _u);
1166 case_brw(boadd, _u);
1169 case_brr(bxadd, _u);
1170 case_brw(bxadd, _u);
1173 case_brr(bosub, _u);
1174 case_brw(bosub, _u);
1177 case_brr(bxsub, _u);
1178 case_brw(bxsub, _u);
1180 case jit_code_movi_f:
1181 assert(node->flag & jit_flag_data);
1182 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1185 case jit_code_movi_d:
1186 assert(node->flag & jit_flag_data);
1187 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1189 case_rr(trunc, _f_i);
1190 case_rr(trunc, _d_i);
1202 case_rrf(add, _f, 32);
1204 case_rrf(add, _d, 64);
1206 case_rrf(sub, _f, 32);
1207 case_rrf(rsb, _f, 32);
1209 case_rrf(sub, _d, 64);
1210 case_rrf(rsb, _d, 64);
1212 case_rrf(mul, _f, 32);
1214 case_rrf(mul, _d, 64);
1216 case_rrf(div, _f, 32);
1218 case_rrf(div, _d, 64);
1220 case_rrf(lt, _f, 32);
1222 case_rrf(lt, _d, 64);
1224 case_rrf(le, _f, 32);
1226 case_rrf(le, _d, 64);
1228 case_rrf(eq, _f, 32);
1230 case_rrf(eq, _d, 64);
1232 case_rrf(ge, _f, 32);
1234 case_rrf(ge, _d, 64);
1236 case_rrf(gt, _f, 32);
1238 case_rrf(gt, _d, 64);
1240 case_rrf(ne, _f, 32);
1242 case_rrf(ne, _d, 64);
1244 case_rrf(unlt, _f, 32);
1246 case_rrf(unlt, _d, 64);
1248 case_rrf(unle, _f, 32);
1250 case_rrf(unle, _d, 64);
1252 case_rrf(uneq, _f, 32);
1254 case_rrf(uneq, _d, 64);
1256 case_rrf(unge, _f, 32);
1258 case_rrf(unge, _d, 64);
1260 case_rrf(ungt, _f, 32);
1262 case_rrf(ungt, _d, 64);
1264 case_rrf(ltgt, _f, 32);
1266 case_rrf(ltgt, _d, 64);
1268 case_rrf(ord, _f, 32);
1270 case_rrf(ord, _d, 64);
1271 case_rrr(unord, _f);
1272 case_rrf(unord, _f, 32);
1273 case_rrr(unord, _d);
1274 case_rrf(unord, _d, 64);
1292 case_brf(blt, _f, 32);
1294 case_brf(blt, _d, 64);
1296 case_brf(ble, _f, 32);
1298 case_brf(ble, _d, 64);
1300 case_brf(beq, _f, 32);
1302 case_brf(beq, _d, 64);
1304 case_brf(bge, _f, 32);
1306 case_brf(bge, _d, 64);
1308 case_brf(bgt, _f, 32);
1310 case_brf(bgt, _d, 64);
1312 case_brf(bne, _f, 32);
1314 case_brf(bne, _d, 64);
1315 case_brr(bunlt, _f);
1316 case_brf(bunlt, _f, 32);
1317 case_brr(bunlt, _d);
1318 case_brf(bunlt, _d, 64);
1319 case_brr(bunle, _f);
1320 case_brf(bunle, _f, 32);
1321 case_brr(bunle, _d);
1322 case_brf(bunle, _d, 64);
1323 case_brr(buneq, _f);
1324 case_brf(buneq, _f, 32);
1325 case_brr(buneq, _d);
1326 case_brf(buneq, _d, 64);
1327 case_brr(bunge, _f);
1328 case_brf(bunge, _f, 32);
1329 case_brr(bunge, _d);
1330 case_brf(bunge, _d, 64);
1331 case_brr(bungt, _f);
1332 case_brf(bungt, _f, 32);
1333 case_brr(bungt, _d);
1334 case_brf(bungt, _d, 64);
1335 case_brr(bltgt, _f);
1336 case_brf(bltgt, _f, 32);
1337 case_brr(bltgt, _d);
1338 case_brf(bltgt, _d, 64);
1340 case_brf(bord, _f, 32);
1342 case_brf(bord, _d, 64);
1343 case_brr(bunord, _f);
1344 case_brf(bunord, _f, 32);
1345 case_brr(bunord, _d);
1346 case_brf(bunord, _d, 64);
1348 jmpr(rn(node->u.w));
1351 if (node->flag & jit_flag_node) {
1353 assert(temp->code == jit_code_label ||
1354 temp->code == jit_code_epilog);
1355 if (temp->flag & jit_flag_patch)
1358 word = _jit->code.length -
1359 (_jit->pc.uc - _jit->code.ptr);
1360 if (word >= -32768 && word <= 32767)
1361 word = jmpi(_jit->pc.w);
1363 word = jmpi_p(_jit->pc.w);
1370 case jit_code_callr:
1371 callr(rn(node->u.w));
1373 case jit_code_calli:
1374 if (node->flag & jit_flag_node) {
1376 assert(temp->code == jit_code_label ||
1377 temp->code == jit_code_epilog);
1378 if (!(temp->flag & jit_flag_patch)) {
1379 word = calli_p(temp->u.w);
1388 case jit_code_prolog:
1389 _jitc->function = _jitc->functions.ptr + node->w.w;
1391 undo.word = _jit->pc.w;
1392 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
1393 #if DEVEL_DISASSEMBLER
1396 undo.patch_offset = _jitc->patches.offset;
1401 case jit_code_epilog:
1402 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1404 for (temp = undo.node->next;
1405 temp != node; temp = temp->next) {
1406 if (temp->code == jit_code_label ||
1407 temp->code == jit_code_epilog)
1408 temp->flag &= ~jit_flag_patch;
1410 temp->flag &= ~jit_flag_patch;
1412 _jit->pc.w = undo.word;
1413 /* undo.func.self.aoff and undo.func.regset should not
1414 * be undone, as they will be further updated, and are
1415 * the reason of the undo.
1416 * Note that for hppa use '-' instead of '+' as hppa
1418 undo.func.self.aoff = _jitc->function->frame -
1419 _jitc->function->self.aoff;
1420 jit_regset_set(&undo.func.regset, &_jitc->function->regset);
1421 /* allocar information also does not need to be undone */
1422 undo.func.aoffoff = _jitc->function->aoffoff;
1423 undo.func.allocar = _jitc->function->allocar;
1424 memcpy(_jitc->function, &undo.func, sizeof(undo.func));
1425 #if DEVEL_DISASSEMBLER
1428 _jitc->patches.offset = undo.patch_offset;
1429 goto restart_function;
1431 /* remember label is defined */
1432 node->flag |= jit_flag_patch;
1433 node->u.w = _jit->pc.w;
1435 _jitc->function = NULL;
1437 case jit_code_va_start:
1438 vastart(rn(node->u.w));
1440 case jit_code_va_arg:
1441 vaarg(rn(node->u.w), rn(node->v.w));
1443 case jit_code_va_arg_d:
1444 vaarg_d(rn(node->u.w), rn(node->v.w));
1446 case jit_code_live: case jit_code_ellipsis:
1447 case jit_code_va_push:
1448 case jit_code_allocai: case jit_code_allocar:
1449 case jit_code_arg_c: case jit_code_arg_s:
1450 case jit_code_arg_i:
1451 case jit_code_arg_f: case jit_code_arg_d:
1452 case jit_code_va_end:
1454 case jit_code_retr_c: case jit_code_reti_c:
1455 case jit_code_retr_uc: case jit_code_reti_uc:
1456 case jit_code_retr_s: case jit_code_reti_s:
1457 case jit_code_retr_us: case jit_code_reti_us:
1458 case jit_code_retr_i: case jit_code_reti_i:
1459 case jit_code_retr_f: case jit_code_reti_f:
1460 case jit_code_retr_d: case jit_code_reti_d:
1461 case jit_code_getarg_c: case jit_code_getarg_uc:
1462 case jit_code_getarg_s: case jit_code_getarg_us:
1463 case jit_code_getarg_i:
1464 case jit_code_getarg_f: case jit_code_getarg_d:
1465 case jit_code_putargr_c: case jit_code_putargi_c:
1466 case jit_code_putargr_uc: case jit_code_putargi_uc:
1467 case jit_code_putargr_s: case jit_code_putargi_s:
1468 case jit_code_putargr_us: case jit_code_putargi_us:
1469 case jit_code_putargr_i: case jit_code_putargi_i:
1470 case jit_code_putargr_f: case jit_code_putargi_f:
1471 case jit_code_putargr_d: case jit_code_putargi_d:
1472 case jit_code_pushargr_c: case jit_code_pushargi_c:
1473 case jit_code_pushargr_uc: case jit_code_pushargi_uc:
1474 case jit_code_pushargr_s: case jit_code_pushargi_s:
1475 case jit_code_pushargr_us: case jit_code_pushargi_us:
1476 case jit_code_pushargr_i: case jit_code_pushargi_i:
1477 case jit_code_pushargr_f: case jit_code_pushargi_f:
1478 case jit_code_pushargr_d: case jit_code_pushargi_d:
1479 case jit_code_retval_c: case jit_code_retval_uc:
1480 case jit_code_retval_s: case jit_code_retval_us:
1481 case jit_code_retval_i:
1482 case jit_code_retval_f: case jit_code_retval_d:
1483 case jit_code_prepare:
1484 case jit_code_finishr: case jit_code_finishi:
1489 jit_regarg_clr(node, value);
1490 assert(_jitc->regarg == 0 && _jitc->synth == 0);
1491 /* update register live state */
1507 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1508 node = _jitc->patches.ptr[offset].node;
1509 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1510 patch_at(_jitc->patches.ptr[offset].inst, word);
1513 jit_flush(_jit->code.ptr, _jit->pc.uc);
1515 return (_jit->code.ptr);
1519 # include "jit_hppa-cpu.c"
1520 # include "jit_hppa-fpu.c"
1521 # include "jit_fallback.c"
1525 jit_flush(void *fptr, void *tptr)
1528 s = sysconf(_SC_PAGE_SIZE);
1529 f = (jit_word_t)fptr & -s;
1530 t = (((jit_word_t)tptr) + s - 1) & -s;
1532 /* --- parisc2.0.pdf ---
1535 The minimum spacing that is guaranteed to work for "self-modifying code" is
1536 shown in the code segment below. Since instruction prefetching is permitted,
1537 any data cache flushes must be separated from any instruction cache flushes
1538 by a SYNC. This will ensure that the "new" instruction will be written to
1539 memory prior to any attempts at prefetching it as an instruction.
1541 LDIL l%newinstr,rnew
1542 LDW r%newinstr(0,rnew),temp
1544 STW temp,r%instr(0,rinstr)
1545 FDC r%instr(0,rinstr)
1550 (at least seven instructions)
1552 This sequence assumes a uniprocessor system. In a multiprocessor system,
1553 software must ensure no processor is executing code which is in the process
1558 Adapted from ffcall/trampoline/cache-hppa.c:__TR_clear_cache to
1559 loop over addresses as it is unlikely from and to addresses would fit in
1560 at most two cachelines.
1561 FIXME A cache line can be 16, 32, or 64 bytes.
1564 * Copyright 1995-1997 Bruno Haible, <bruno@clisp.org>
1566 * This is free software distributed under the GNU General Public Licence
1567 * described in the file COPYING. Contact the author if you don't have this
1568 * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
1572 jit_word_t n = f + 32;
1574 for (; f <= t; n = f + 32, f += 64) {
1575 asm volatile ("fdc 0(0,%0)"
1576 "\n\t" "fdc 0(0,%1)"
1581 asm volatile ("mfsp %%sr0,%1"
1582 "\n\t" "ldsid (0,%4),%0"
1583 "\n\t" "mtsp %0,%%sr0"
1584 "\n\t" "fic 0(%%sr0,%2)"
1585 "\n\t" "fic 0(%%sr0,%3)"
1587 "\n\t" "mtsp %1,%%sr0"
1594 : "=r" (u), "=r" (v)
1595 : "r" (f), "r" (n), "r" (f)
1600 /* This is supposed to work but appears to fail on multiprocessor systems */
1601 __clear_cache((void *)f, (void *)t);
1606 _emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0)
1608 ldxi(rn(r0), rn(r1), i0);
1612 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1)
1614 stxi(i0, rn(r0), rn(r1));
1618 _emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0)
1620 ldxi_d(rn(r0), rn(r1), i0);
1624 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1)
1626 stxi_d(i0, rn(r0), rn(r1));
1630 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
1634 assert(node->flag & jit_flag_node);
1635 if (node->code == jit_code_movi)
1636 flag = node->v.n->flag;
1638 flag = node->u.n->flag;
1639 assert(!(flag & jit_flag_patch));
1640 if (_jitc->patches.offset >= _jitc->patches.length) {
1641 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
1642 _jitc->patches.length * sizeof(jit_patch_t),
1643 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
1644 _jitc->patches.length += 1024;
1646 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
1647 _jitc->patches.ptr[_jitc->patches.offset].node = node;
1648 ++_jitc->patches.offset;