2 * Copyright (C) 2013-2019 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>
23 #define jit_arg_reg_p(i) (i >= 0 && i < 4)
26 # include "jit_hppa-cpu.c"
27 # include "jit_hppa-fpu.c"
33 typedef jit_pointer_t jit_va_list;
38 #define patch(instr, node) _patch(_jit, instr, node)
39 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
42 extern void __clear_cache(void *, void *);
47 jit_register_t _rvs[] = {
48 { 0, "r0" }, /* Zero */
49 /* Not register starved, so, avoid allocating r1 and rp
50 * due to being implicit target of ADDIL and B,L */
51 { 1, "r1" }, /* Scratch */
52 { 2, "rp" }, /* Return Pointer and scratch */
53 { rc(sav) | 3, "r3" },
54 { 19, "r19" }, /* Linkage Table */
55 { rc(gpr) | 20, "r20" },
56 { rc(gpr) | 21, "r21" },
57 { rc(gpr) | 22, "r22" },
58 { rc(gpr) | 29, "ret1" },
59 { rc(gpr) | 28, "ret0" },
60 /* JIT_Rx in callee save registers due to need to call
61 * functions to implement some instructions */
63 { rc(gpr) | rc(sav) | 4, "r4" },
64 { rc(gpr) | rc(sav) | 5, "r5" },
65 { rc(gpr) | rc(sav) | 6, "r6" },
67 { rc(gpr) | rc(sav) | 7, "r7" },
68 { rc(sav) | rc(sav) | 8, "r8" },
69 { rc(gpr) | rc(sav) | 9, "r9" },
71 { rc(gpr) | rc(sav) | 10, "r10" },
73 { rc(gpr) | rc(sav) | 11, "r11" },
74 { rc(gpr) | rc(sav) | 12, "r12" },
75 { rc(gpr) | rc(sav) | 13, "r13" },
76 { rc(gpr) | rc(sav) | 14, "r14" },
77 { rc(gpr) | rc(sav) | 15, "r15" },
78 { rc(gpr) | rc(sav) | 16, "r16" },
79 { rc(gpr) | rc(sav) | 17, "r17" },
80 { rc(gpr) | rc(sav) | 18, "r18" },
82 { rc(gpr) | rc(arg) | 23, "r23" },
83 { rc(gpr) | rc(arg) | 24, "r24" },
84 { rc(gpr) | rc(arg) | 25, "r25" },
85 { rc(gpr) | rc(arg) | 26, "r26" },
86 { 27, "dp" }, /* Data Pointer */
88 { 31, "r31" }, /* Link Register */
89 { rc(fpr) | 31, "fr31" },
90 { rc(fpr) | 30, "fr30" },
91 { rc(fpr) | 29, "fr29" },
92 { rc(fpr) | 28, "fr28" },
93 { rc(fpr) | 27, "fr27" },
94 { rc(fpr) | 26, "fr26" },
95 { rc(fpr) | 25, "fr25" },
96 { rc(fpr) | 24, "fr24" },
97 { rc(fpr) | 23, "fr23" },
98 { rc(fpr) | 22, "fr22" },
99 { rc(fpr) | 11, "fr11" },
100 { rc(fpr) | 10, "fr10" },
101 { rc(fpr) | 9, "fr9" },
102 { rc(fpr) | 8, "fr8" },
104 { rc(fpr) | rc(arg) | 7, "fr7" },
105 { rc(fpr) | rc(arg) | 6, "fr6" },
106 { rc(fpr) | rc(arg) | 5, "fr5" },
107 { rc(fpr) | rc(arg) | 4, "fr4" },
109 { rc(fpr) | rc(sav) | 21, "fr21" },
110 { rc(fpr) | rc(sav) | 20, "fr20" },
111 { rc(fpr) | rc(sav) | 19, "fr19" },
112 { rc(fpr) | rc(sav) | 18, "fr18" },
113 { rc(fpr) | rc(sav) | 17, "fr17" },
114 { rc(fpr) | rc(sav) | 16, "fr16" },
115 { rc(fpr) | rc(sav) | 15, "fr15" },
116 { rc(fpr) | rc(sav) | 14, "fr14" },
117 { rc(fpr) | rc(sav) | 13, "fr13" },
118 { rc(fpr) | rc(sav) | 12, "fr12" },
123 { _NOREG, "<none>" },
132 /* FIXME Expecting PARISC 2.0, for PARISC 1.0 should not use fr16-fr31 */
136 _jit_init(jit_state_t *_jit)
138 _jitc->reglen = jit_size(_rvs) - 1;
142 _jit_prolog(jit_state_t *_jit)
148 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
149 jit_regset_set_ui(&_jitc->regsav, 0);
150 offset = _jitc->functions.offset;
151 if (offset >= _jitc->functions.length) {
152 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
153 _jitc->functions.length * sizeof(jit_function_t),
154 (_jitc->functions.length + 16) * sizeof(jit_function_t));
155 _jitc->functions.length += 16;
157 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
158 _jitc->function->self.size = params_offset;
159 _jitc->function->self.argi = _jitc->function->self.alen = 0;
160 /* float conversion */
161 _jitc->function->self.aoff = alloca_offset;
162 _jitc->function->self.call = jit_call_default;
163 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
164 _jitc->reglen * sizeof(jit_int32_t));
166 /* _no_link here does not mean the jit_link() call can be removed
168 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
170 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
171 jit_link(_jitc->function->prolog);
172 _jitc->function->prolog->w.w = offset;
173 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
175 * v: offset in blocks vector
176 * w: offset in functions vector
178 _jitc->function->epilog->w.w = offset;
180 jit_regset_new(&_jitc->function->regset);
184 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
187 assert(_jitc->function);
192 _jitc->function->self.aoff = (_jitc->function->self.aoff + 1) & -2;
195 _jitc->function->self.aoff = (_jitc->function->self.aoff + 3) & -4;
198 _jitc->function->self.aoff = (_jitc->function->self.aoff + 7) & -8;
201 if (!_jitc->realize) {
202 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
205 offset = _jitc->function->self.aoff;
206 _jitc->function->self.aoff += length;
211 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
214 assert(_jitc->function);
215 jit_inc_synth_ww(allocar, u, v);
216 if (!_jitc->function->allocar) {
217 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
218 _jitc->function->allocar = 1;
220 reg = jit_get_reg(jit_class_gpr);
221 jit_addi(reg, v, 63);
222 jit_andi(reg, reg, -64);
223 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 assert(u->code == jit_code_arg ||
309 u->code == jit_code_arg_f || u->code == jit_code_arg_d);
310 return (jit_arg_reg_p(u->u.w));
314 _jit_ellipsis(jit_state_t *_jit)
316 jit_inc_synth(ellipsis);
317 if (_jitc->prepare) {
319 assert(!(_jitc->function->call.call & jit_call_varargs));
320 _jitc->function->call.call |= jit_call_varargs;
324 assert(!(_jitc->function->self.call & jit_call_varargs));
325 _jitc->function->self.call |= jit_call_varargs;
327 _jitc->function->vagp = _jitc->function->self.argi;
333 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
335 jit_inc_synth_w(va_push, u);
341 _jit_arg(jit_state_t *_jit)
345 assert(_jitc->function);
346 _jitc->function->self.size -= sizeof(jit_word_t);
347 if (jit_arg_reg_p(_jitc->function->self.argi))
348 offset = _jitc->function->self.argi++;
350 offset = _jitc->function->self.size;
351 node = jit_new_node_ww(jit_code_arg, offset,
352 ++_jitc->function->self.argn);
358 _jit_arg_f(jit_state_t *_jit)
362 assert(_jitc->function);
363 _jitc->function->self.size -= sizeof(jit_word_t);
364 if (jit_arg_reg_p(_jitc->function->self.argi))
365 offset = _jitc->function->self.argi++;
367 offset = _jitc->function->self.size;
368 node = jit_new_node_ww(jit_code_arg_f, offset,
369 ++_jitc->function->self.argn);
375 _jit_arg_d(jit_state_t *_jit)
379 assert(_jitc->function);
380 if (_jitc->function->self.argi & 1) {
381 ++_jitc->function->self.argi;
382 _jitc->function->self.size -= sizeof(jit_word_t);
384 _jitc->function->self.size -= sizeof(jit_float64_t);
385 if (jit_arg_reg_p(_jitc->function->self.argi)) {
386 offset = _jitc->function->self.argi + 1;
387 _jitc->function->self.argi += 2;
390 /* "Standard" initial value (-52) is unaligned */
391 if (_jitc->function->self.size & 7)
392 _jitc->function->self.size -= sizeof(jit_word_t);
393 offset = _jitc->function->self.size;
395 node = jit_new_node_ww(jit_code_arg_d, offset,
396 ++_jitc->function->self.argn);
402 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
404 assert(v->code == jit_code_arg);
405 jit_inc_synth_wp(getarg_c, u, v);
407 jit_extr_c(u, _R26 - v->u.w);
409 jit_ldxi_c(u, JIT_FP, v->u.w + 3);
414 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
416 assert(v->code == jit_code_arg);
417 jit_inc_synth_wp(getarg_uc, u, v);
419 jit_extr_uc(u, _R26 - v->u.w);
421 jit_ldxi_uc(u, JIT_FP, v->u.w + 3);
426 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
428 assert(v->code == jit_code_arg);
429 jit_inc_synth_wp(getarg_s, u, v);
431 jit_extr_s(u, _R26 - v->u.w);
433 jit_ldxi_s(u, JIT_FP, v->u.w + 2);
438 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
440 assert(v->code == jit_code_arg);
441 jit_inc_synth_wp(getarg_us, u, v);
443 jit_extr_us(u, _R26 - v->u.w);
445 jit_ldxi_us(u, JIT_FP, v->u.w + 2);
450 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
452 assert(v->code == jit_code_arg);
453 jit_inc_synth_wp(getarg_i, u, v);
455 jit_movr(u, _R26 - v->u.w);
457 jit_ldxi_i(u, JIT_FP, v->u.w);
462 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
464 assert(v->code == jit_code_arg);
465 jit_inc_synth_wp(putargr, u, v);
467 jit_movr(_R26 - v->u.w, u);
469 jit_stxi(v->u.w, JIT_FP, u);
474 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
477 assert(v->code == jit_code_arg);
478 jit_inc_synth_wp(putargi, u, v);
480 jit_movi(_R26 - v->u.w, u);
482 regno = jit_get_reg(jit_class_gpr);
484 jit_stxi(v->u.w, JIT_FP, regno);
485 jit_unget_reg(regno);
491 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
493 assert(v->code == jit_code_arg_f);
494 jit_inc_synth_wp(getarg_f, u, v);
496 jit_movr_f(u, _F4 - v->u.w);
498 jit_ldxi_f(u, JIT_FP, v->u.w);
503 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
505 assert(v->code == jit_code_arg_f);
506 jit_inc_synth_wp(putargr_f, u, v);
508 jit_movr_f(_F4 - v->u.w, u);
510 jit_stxi_f(v->u.w, JIT_FP, u);
515 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
518 assert(v->code == jit_code_arg_f);
519 jit_inc_synth_fp(putargi_f, u, v);
521 jit_movi_f(_R26 - v->u.w, u);
523 regno = jit_get_reg(jit_class_fpr);
524 jit_movi_f(regno, u);
525 jit_stxi_f(v->u.w, JIT_FP, regno);
526 jit_unget_reg(regno);
532 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
534 assert(v->code == jit_code_arg_d);
535 jit_inc_synth_wp(getarg_d, u, v);
537 jit_movr_d(u, _F4 - v->u.w);
539 jit_ldxi_d(u, JIT_FP, v->u.w);
544 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
546 assert(v->code == jit_code_arg_d);
547 jit_inc_synth_wp(putargr_d, u, v);
549 jit_movr_d(_F4 - v->u.w, u);
551 jit_stxi_d(v->u.w, JIT_FP, u);
556 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
559 assert(v->code == jit_code_arg_d);
560 jit_inc_synth_dp(putargi_d, u, v);
562 jit_movi_d(_R26 - v->u.w, u);
564 regno = jit_get_reg(jit_class_fpr);
565 jit_movi_d(regno, u);
566 jit_stxi_d(v->u.w, JIT_FP, regno);
567 jit_unget_reg(regno);
573 _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
575 assert(_jitc->function);
576 jit_inc_synth_w(pushargr, u);
578 _jitc->function->call.size -= sizeof(jit_word_t);
579 if (jit_arg_reg_p(_jitc->function->call.argi)) {
580 jit_movr(_R26 - _jitc->function->call.argi, u);
581 ++_jitc->function->call.argi;
584 jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
589 _jit_pushargi(jit_state_t *_jit, jit_word_t u)
592 assert(_jitc->function);
593 jit_inc_synth_w(pushargi, u);
595 _jitc->function->call.size -= sizeof(jit_word_t);
596 if (jit_arg_reg_p(_jitc->function->call.argi)) {
597 jit_movi(_R26 - _jitc->function->call.argi, u);
598 ++_jitc->function->call.argi;
601 regno = jit_get_reg(jit_class_gpr);
603 jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno);
604 jit_unget_reg(regno);
610 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
612 assert(_jitc->function);
613 jit_inc_synth_w(pushargr_f, u);
615 _jitc->function->call.size -= sizeof(jit_word_t);
616 if (jit_arg_reg_p(_jitc->function->call.argi)) {
617 jit_movr_f(_F4 - _jitc->function->call.argi, u);
619 /* HP-UX appears to always pass float arguments in gpr registers */
620 if (_jitc->function->call.call & jit_call_varargs)
623 jit_stxi_f(alloca_offset - 8, JIT_FP, u);
624 jit_ldxi(_R26 - _jitc->function->call.argi, JIT_FP,
627 ++_jitc->function->call.argi;
630 jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, u);
635 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
638 assert(_jitc->function);
639 jit_inc_synth_f(pushargi_f, u);
641 _jitc->function->call.size -= sizeof(jit_word_t);
642 if (jit_arg_reg_p(_jitc->function->call.argi)) {
643 jit_movi_f(_F4 - _jitc->function->call.argi, u);
645 /* HP-UX appears to always pass float arguments in gpr registers */
646 if (_jitc->function->call.call & jit_call_varargs)
649 jit_stxi_f(alloca_offset - 8, JIT_FP,
650 _F4 - _jitc->function->call.argi);
651 jit_ldxi(_R26 - _jitc->function->call.argi,
652 JIT_FP, alloca_offset - 8);
654 ++_jitc->function->call.argi;
657 regno = jit_get_reg(jit_class_fpr);
658 jit_movi_f(regno, u);
659 jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, regno);
660 jit_unget_reg(regno);
666 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
668 assert(_jitc->function);
669 jit_inc_synth_w(pushargr_d, u);
671 _jitc->function->call.size -= sizeof(jit_float64_t);
672 if (_jitc->function->call.argi & 1) {
673 ++_jitc->function->call.argi;
674 _jitc->function->call.size -= sizeof(jit_word_t);
676 if (jit_arg_reg_p(_jitc->function->call.argi)) {
677 jit_movr_d(_F4 - (_jitc->function->call.argi + 1), u);
679 /* HP-UX appears to always pass float arguments in gpr registers */
680 if (_jitc->function->call.call & jit_call_varargs)
683 jit_stxi_d(alloca_offset - 8, JIT_FP, u);
684 jit_ldxi(_R26 - _jitc->function->call.argi,
685 JIT_FP, alloca_offset - 4);
686 jit_ldxi(_R25 - _jitc->function->call.argi,
687 JIT_FP, alloca_offset - 8);
689 _jitc->function->call.argi += 2;
692 /* "Standard" initial value (-52) is unaligned */
693 if ((_jitc->function->call.size + params_offset) & 7)
694 _jitc->function->call.size -= sizeof(jit_word_t);
695 jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
701 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
704 assert(_jitc->function);
705 jit_inc_synth_d(pushargi_d, u);
707 _jitc->function->call.size -= sizeof(jit_float64_t);
708 if (_jitc->function->call.argi & 1) {
709 ++_jitc->function->call.argi;
710 _jitc->function->call.size -= sizeof(jit_word_t);
712 if (jit_arg_reg_p(_jitc->function->call.argi)) {
713 jit_movi_d(_F4 - (_jitc->function->call.argi + 1), u);
715 /* HP-UX appears to always pass float arguments in gpr registers */
716 if (_jitc->function->call.call & jit_call_varargs)
719 jit_stxi_d(alloca_offset - 8, JIT_FP,
720 _F4 - (_jitc->function->call.argi + 1));
721 jit_ldxi(_R26 - _jitc->function->call.argi,
722 JIT_FP, alloca_offset - 4);
723 jit_ldxi(_R25 - _jitc->function->call.argi,
724 JIT_FP, alloca_offset - 8);
726 _jitc->function->call.argi += 2;
729 regno = jit_get_reg(jit_class_fpr);
730 jit_movi_d(regno, u);
731 if ((_jitc->function->call.size + params_offset) & 7)
732 _jitc->function->call.size -= sizeof(jit_word_t);
733 jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno);
734 jit_unget_reg(regno);
740 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
743 spec = jit_class(_rvs[regno].spec);
744 if (spec & jit_class_arg) {
745 if (spec & jit_class_gpr) {
747 if (regno >= 0 && regno < node->v.w)
750 else if (spec & jit_class_fpr) {
752 if (regno >= 0 && regno < node->w.w)
760 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
763 assert(_jitc->function);
764 jit_inc_synth_w(finishr, r0);
765 if (_jitc->function->self.alen > _jitc->function->call.size)
766 _jitc->function->self.alen = _jitc->function->call.size;
767 call = jit_callr(r0);
768 call->v.w = call->w.w = _jitc->function->call.argi;
769 _jitc->function->call.argi = _jitc->function->call.size = 0;
775 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
778 assert(_jitc->function);
779 jit_inc_synth_w(finishi, (jit_word_t)i0);
780 if (_jitc->function->self.alen > _jitc->function->call.size)
781 _jitc->function->self.alen = _jitc->function->call.size;
782 node = jit_calli(i0);
783 node->v.w = node->w.w = _jitc->function->call.argi;
784 _jitc->function->call.argi = _jitc->function->call.size = 0;
791 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
793 jit_inc_synth_w(retval_c, r0);
794 jit_extr_c(r0, JIT_RET);
799 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
801 jit_inc_synth_w(retval_uc, r0);
802 jit_extr_uc(r0, JIT_RET);
807 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
809 jit_inc_synth_w(retval_s, r0);
810 jit_extr_s(r0, JIT_RET);
815 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
817 jit_inc_synth_w(retval_us, r0);
818 jit_extr_us(r0, JIT_RET);
823 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
825 jit_inc_synth_w(retval_i, r0);
826 jit_movr(r0, JIT_RET);
831 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
833 jit_inc_synth_w(retval_f, r0);
834 jit_movr_f(r0, JIT_FRET);
839 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
841 jit_inc_synth_w(retval_d, r0);
842 jit_movr_d(r0, JIT_FRET);
847 _emit_code(jit_state_t *_jit)
857 #if DEVEL_DISASSEMBLER
860 jit_int32_t patch_offset;
862 #if DEVEL_DISASSEMBLER
866 _jitc->function = NULL;
872 undo.patch_offset = 0;
874 #define case_rr(name, type) \
875 case jit_code_##name##r##type: \
876 name##r##type(rn(node->u.w), rn(node->v.w)); \
878 #define case_rw(name, type) \
879 case jit_code_##name##i##type: \
880 name##i##type(rn(node->u.w), node->v.w); \
882 #define case_wr(name, type) \
883 case jit_code_##name##i##type: \
884 name##i##type(node->u.w, rn(node->v.w)); \
886 #define case_rrr(name, type) \
887 case jit_code_##name##r##type: \
888 name##r##type(rn(node->u.w), \
889 rn(node->v.w), rn(node->w.w)); \
891 #define case_rrrr(name, type) \
892 case jit_code_##name##r##type: \
893 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
894 rn(node->v.w), rn(node->w.w)); \
896 #define case_rrw(name, type) \
897 case jit_code_##name##i##type: \
898 name##i##type(rn(node->u.w),rn(node->v.w), node->w.w); \
900 #define case_rrrw(name, type) \
901 case jit_code_##name##i##type: \
902 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
903 rn(node->v.w), node->w.w); \
905 #define case_rrf(name, type, size) \
906 case jit_code_##name##i##type: \
907 assert(node->flag & jit_flag_data); \
908 name##i##type(rn(node->u.w), rn(node->v.w), \
909 (jit_float##size##_t *)node->w.n->u.w); \
911 #define case_wrr(name, type) \
912 case jit_code_##name##i##type: \
913 name##i##type(node->u.w,rn(node->v.w), rn(node->w.w)); \
915 #define case_brr(name, type) \
916 case jit_code_##name##r##type: \
918 assert(temp->code == jit_code_label || \
919 temp->code == jit_code_epilog); \
920 if (temp->flag & jit_flag_patch) \
921 name##r##type(temp->u.w, rn(node->v.w), \
924 word = name##r##type(_jit->pc.w, \
925 rn(node->v.w), rn(node->w.w)); \
929 #define case_brw(name, type) \
930 case jit_code_##name##i##type: \
932 assert(temp->code == jit_code_label || \
933 temp->code == jit_code_epilog); \
934 if (temp->flag & jit_flag_patch) \
935 name##i##type(temp->u.w, \
936 rn(node->v.w), node->w.w); \
938 word = name##i##type(_jit->pc.w, \
939 rn(node->v.w), node->w.w); \
943 #define case_brf(name, type, size) \
944 case jit_code_##name##i##type: \
946 assert(temp->code == jit_code_label || \
947 temp->code == jit_code_epilog); \
948 if (temp->flag & jit_flag_patch) \
949 name##i##type(temp->u.w, rn(node->v.w), \
950 (jit_float##size##_t *)node->w.n->u.w); \
952 word = name##i##type(_jit->pc.w, rn(node->v.w), \
953 (jit_float##size##_t *)node->w.n->u.w); \
957 #if DEVEL_DISASSEMBLER
960 for (node = _jitc->head; node; node = node->next) {
961 if (_jit->pc.uc >= _jitc->code.end)
964 #if DEVEL_DISASSEMBLER
965 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
968 value = jit_classify(node->code);
969 jit_regarg_set(node, value);
970 switch (node->code) {
972 assert(!(node->u.w & (node->u.w - 1)) &&
973 node->u.w <= sizeof(jit_word_t));
974 if (node->u.w == sizeof(jit_word_t) &&
975 (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
976 nop(sizeof(jit_word_t) - word);
978 case jit_code_note: case jit_code_name:
979 node->u.w = _jit->pc.w;
982 /* remember label is defined */
983 node->flag |= jit_flag_patch;
984 node->u.w = _jit->pc.w;
1003 case_rrrr(qmul, _u);
1004 case_rrrw(qmul, _u);
1015 case_rrrr(qdiv, _u);
1016 case_rrrw(qdiv, _u);
1033 if (node->flag & jit_flag_node) {
1035 if (temp->code == jit_code_data ||
1036 (temp->code == jit_code_label &&
1037 (temp->flag & jit_flag_patch)))
1038 movi(rn(node->u.w), temp->u.w);
1040 assert(temp->code == jit_code_label ||
1041 temp->code == jit_code_epilog);
1042 word = movi_p(rn(node->u.w), node->v.w);
1047 movi(rn(node->u.w), node->v.w);
1057 case_rr(bswap, _us);
1058 case_rr(bswap, _ui);
1137 case_brr(boadd, _u);
1138 case_brw(boadd, _u);
1141 case_brr(bxadd, _u);
1142 case_brw(bxadd, _u);
1145 case_brr(bosub, _u);
1146 case_brw(bosub, _u);
1149 case_brr(bxsub, _u);
1150 case_brw(bxsub, _u);
1152 case jit_code_movi_f:
1153 assert(node->flag & jit_flag_data);
1154 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1157 case jit_code_movi_d:
1158 assert(node->flag & jit_flag_data);
1159 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1161 case_rr(trunc, _f_i);
1162 case_rr(trunc, _d_i);
1174 case_rrf(add, _f, 32);
1176 case_rrf(add, _d, 64);
1178 case_rrf(sub, _f, 32);
1179 case_rrf(rsb, _f, 32);
1181 case_rrf(sub, _d, 64);
1182 case_rrf(rsb, _d, 64);
1184 case_rrf(mul, _f, 32);
1186 case_rrf(mul, _d, 64);
1188 case_rrf(div, _f, 32);
1190 case_rrf(div, _d, 64);
1192 case_rrf(lt, _f, 32);
1194 case_rrf(lt, _d, 64);
1196 case_rrf(le, _f, 32);
1198 case_rrf(le, _d, 64);
1200 case_rrf(eq, _f, 32);
1202 case_rrf(eq, _d, 64);
1204 case_rrf(ge, _f, 32);
1206 case_rrf(ge, _d, 64);
1208 case_rrf(gt, _f, 32);
1210 case_rrf(gt, _d, 64);
1212 case_rrf(ne, _f, 32);
1214 case_rrf(ne, _d, 64);
1216 case_rrf(unlt, _f, 32);
1218 case_rrf(unlt, _d, 64);
1220 case_rrf(unle, _f, 32);
1222 case_rrf(unle, _d, 64);
1224 case_rrf(uneq, _f, 32);
1226 case_rrf(uneq, _d, 64);
1228 case_rrf(unge, _f, 32);
1230 case_rrf(unge, _d, 64);
1232 case_rrf(ungt, _f, 32);
1234 case_rrf(ungt, _d, 64);
1236 case_rrf(ltgt, _f, 32);
1238 case_rrf(ltgt, _d, 64);
1240 case_rrf(ord, _f, 32);
1242 case_rrf(ord, _d, 64);
1243 case_rrr(unord, _f);
1244 case_rrf(unord, _f, 32);
1245 case_rrr(unord, _d);
1246 case_rrf(unord, _d, 64);
1264 case_brf(blt, _f, 32);
1266 case_brf(blt, _d, 64);
1268 case_brf(ble, _f, 32);
1270 case_brf(ble, _d, 64);
1272 case_brf(beq, _f, 32);
1274 case_brf(beq, _d, 64);
1276 case_brf(bge, _f, 32);
1278 case_brf(bge, _d, 64);
1280 case_brf(bgt, _f, 32);
1282 case_brf(bgt, _d, 64);
1284 case_brf(bne, _f, 32);
1286 case_brf(bne, _d, 64);
1287 case_brr(bunlt, _f);
1288 case_brf(bunlt, _f, 32);
1289 case_brr(bunlt, _d);
1290 case_brf(bunlt, _d, 64);
1291 case_brr(bunle, _f);
1292 case_brf(bunle, _f, 32);
1293 case_brr(bunle, _d);
1294 case_brf(bunle, _d, 64);
1295 case_brr(buneq, _f);
1296 case_brf(buneq, _f, 32);
1297 case_brr(buneq, _d);
1298 case_brf(buneq, _d, 64);
1299 case_brr(bunge, _f);
1300 case_brf(bunge, _f, 32);
1301 case_brr(bunge, _d);
1302 case_brf(bunge, _d, 64);
1303 case_brr(bungt, _f);
1304 case_brf(bungt, _f, 32);
1305 case_brr(bungt, _d);
1306 case_brf(bungt, _d, 64);
1307 case_brr(bltgt, _f);
1308 case_brf(bltgt, _f, 32);
1309 case_brr(bltgt, _d);
1310 case_brf(bltgt, _d, 64);
1312 case_brf(bord, _f, 32);
1314 case_brf(bord, _d, 64);
1315 case_brr(bunord, _f);
1316 case_brf(bunord, _f, 32);
1317 case_brr(bunord, _d);
1318 case_brf(bunord, _d, 64);
1320 jmpr(rn(node->u.w));
1323 if (node->flag & jit_flag_node) {
1325 assert(temp->code == jit_code_label ||
1326 temp->code == jit_code_epilog);
1327 if (temp->flag & jit_flag_patch)
1330 word = jmpi_p(_jit->pc.w);
1337 case jit_code_callr:
1338 callr(rn(node->u.w));
1340 case jit_code_calli:
1341 if (node->flag & jit_flag_node) {
1343 assert(temp->code == jit_code_label ||
1344 temp->code == jit_code_epilog);
1345 if (!(temp->flag & jit_flag_patch)) {
1346 word = calli_p(temp->u.w);
1355 case jit_code_prolog:
1356 _jitc->function = _jitc->functions.ptr + node->w.w;
1358 undo.word = _jit->pc.w;
1359 #if DEVEL_DISASSEMBLER
1362 undo.patch_offset = _jitc->patches.offset;
1367 case jit_code_epilog:
1368 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1370 for (temp = undo.node->next;
1371 temp != node; temp = temp->next) {
1372 if (temp->code == jit_code_label ||
1373 temp->code == jit_code_epilog)
1374 temp->flag &= ~jit_flag_patch;
1376 temp->flag &= ~jit_flag_patch;
1378 _jit->pc.w = undo.word;
1379 #if DEVEL_DISASSEMBLER
1382 _jitc->patches.offset = undo.patch_offset;
1383 goto restart_function;
1385 /* remember label is defined */
1386 node->flag |= jit_flag_patch;
1387 node->u.w = _jit->pc.w;
1389 _jitc->function = NULL;
1391 case jit_code_va_start:
1392 vastart(rn(node->u.w));
1394 case jit_code_va_arg:
1395 vaarg(rn(node->u.w), rn(node->v.w));
1397 case jit_code_va_arg_d:
1398 vaarg_d(rn(node->u.w), rn(node->v.w));
1401 case jit_code_arg: case jit_code_ellipsis:
1402 case jit_code_va_push:
1403 case jit_code_allocai: case jit_code_allocar:
1404 case jit_code_arg_f: case jit_code_arg_d:
1405 case jit_code_va_end:
1407 case jit_code_retr: case jit_code_reti:
1408 case jit_code_retr_f: case jit_code_reti_f:
1409 case jit_code_retr_d: case jit_code_reti_d:
1410 case jit_code_getarg_c: case jit_code_getarg_uc:
1411 case jit_code_getarg_s: case jit_code_getarg_us:
1412 case jit_code_getarg_i:
1413 case jit_code_getarg_f: case jit_code_getarg_d:
1414 case jit_code_putargr: case jit_code_putargi:
1415 case jit_code_putargr_f: case jit_code_putargi_f:
1416 case jit_code_putargr_d: case jit_code_putargi_d:
1417 case jit_code_pushargr: case jit_code_pushargi:
1418 case jit_code_pushargr_f: case jit_code_pushargi_f:
1419 case jit_code_pushargr_d: case jit_code_pushargi_d:
1420 case jit_code_retval_c: case jit_code_retval_uc:
1421 case jit_code_retval_s: case jit_code_retval_us:
1422 case jit_code_retval_i:
1423 case jit_code_retval_f: case jit_code_retval_d:
1424 case jit_code_prepare:
1425 case jit_code_finishr: case jit_code_finishi:
1430 jit_regarg_clr(node, value);
1431 assert(_jitc->regarg == 0 && _jitc->synth == 0);
1432 /* update register live state */
1448 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1449 node = _jitc->patches.ptr[offset].node;
1450 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1451 patch_at(_jitc->patches.ptr[offset].inst, word);
1454 jit_flush(_jit->code.ptr, _jit->pc.uc);
1456 return (_jit->code.ptr);
1460 # include "jit_hppa-cpu.c"
1461 # include "jit_hppa-fpu.c"
1465 jit_flush(void *fptr, void *tptr)
1468 s = sysconf(_SC_PAGE_SIZE);
1469 f = (jit_word_t)fptr & -s;
1470 t = (((jit_word_t)tptr) + s - 1) & -s;
1472 /* --- parisc2.0.pdf ---
1475 The minimum spacing that is guaranteed to work for "self-modifying code" is
1476 shown in the code segment below. Since instruction prefetching is permitted,
1477 any data cache flushes must be separated from any instruction cache flushes
1478 by a SYNC. This will ensure that the "new" instruction will be written to
1479 memory prior to any attempts at prefetching it as an instruction.
1481 LDIL l%newinstr,rnew
1482 LDW r%newinstr(0,rnew),temp
1484 STW temp,r%instr(0,rinstr)
1485 FDC r%instr(0,rinstr)
1490 (at least seven instructions)
1492 This sequence assumes a uniprocessor system. In a multiprocessor system,
1493 software must ensure no processor is executing code which is in the process
1498 Adapted from ffcall/trampoline/cache-hppa.c:__TR_clear_cache to
1499 loop over addresses as it is unlikely from and to addresses would fit in
1500 at most two cachelines.
1501 FIXME A cache line can be 16, 32, or 64 bytes.
1504 * Copyright 1995-1997 Bruno Haible, <bruno@clisp.org>
1506 * This is free software distributed under the GNU General Public Licence
1507 * described in the file COPYING. Contact the author if you don't have this
1508 * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
1512 jit_word_t n = f + 32;
1514 for (; f <= t; n = f + 32, f += 64) {
1515 asm volatile ("fdc 0(0,%0)"
1516 "\n\t" "fdc 0(0,%1)"
1521 asm volatile ("mfsp %%sr0,%1"
1522 "\n\t" "ldsid (0,%4),%0"
1523 "\n\t" "mtsp %0,%%sr0"
1524 "\n\t" "fic 0(%%sr0,%2)"
1525 "\n\t" "fic 0(%%sr0,%3)"
1527 "\n\t" "mtsp %1,%%sr0"
1534 : "=r" (u), "=r" (v)
1535 : "r" (f), "r" (n), "r" (f)
1540 /* This is supposed to work but appears to fail on multiprocessor systems */
1541 __clear_cache((void *)f, (void *)t);
1546 _emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0)
1548 ldxi(rn(r0), rn(r1), i0);
1552 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1)
1554 stxi(i0, rn(r0), rn(r1));
1558 _emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0)
1560 ldxi_d(rn(r0), rn(r1), i0);
1564 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1)
1566 stxi_d(i0, rn(r0), rn(r1));
1570 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
1574 assert(node->flag & jit_flag_node);
1575 if (node->code == jit_code_movi)
1576 flag = node->v.n->flag;
1578 flag = node->u.n->flag;
1579 assert(!(flag & jit_flag_patch));
1580 if (_jitc->patches.offset >= _jitc->patches.length) {
1581 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
1582 _jitc->patches.length * sizeof(jit_patch_t),
1583 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
1584 _jitc->patches.length += 1024;
1586 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
1587 _jitc->patches.ptr[_jitc->patches.offset].node = node;
1588 ++_jitc->patches.offset;