Update lightrec 20220910 (#686)
[pcsx_rearmed.git] / deps / lightning / lib / jit_hppa.c
CommitLineData
4a71579b
PC
1/*
2 * Copyright (C) 2013-2019 Free Software Foundation, Inc.
3 *
4 * This file is part of GNU lightning.
5 *
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)
9 * any later version.
10 *
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.
15 *
16 * Authors:
17 * Paulo Cesar Pereira de Andrade
18 */
19
20#include <lightning.h>
21#include <lightning/jit_private.h>
22
23#define jit_arg_reg_p(i) (i >= 0 && i < 4)
24
25#define PROTO 1
26# include "jit_hppa-cpu.c"
27# include "jit_hppa-fpu.c"
ba3814c1 28# include "jit_fallback.c"
4a71579b
PC
29#undef PROTO
30
31/*
32 * Types
33 */
34typedef jit_pointer_t jit_va_list;
35
36/*
37 * Prototypes
38 */
39#define patch(instr, node) _patch(_jit, instr, node)
40static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
41
42/* libgcc */
43extern void __clear_cache(void *, void *);
44
45/*
46 * Initialization
47 */
48jit_register_t _rvs[] = {
49 { 0, "r0" }, /* Zero */
50 /* Not register starved, so, avoid allocating r1 and rp
51 * due to being implicit target of ADDIL and B,L */
52 { 1, "r1" }, /* Scratch */
53 { 2, "rp" }, /* Return Pointer and scratch */
54 { rc(sav) | 3, "r3" },
55 { 19, "r19" }, /* Linkage Table */
56 { rc(gpr) | 20, "r20" },
57 { rc(gpr) | 21, "r21" },
58 { rc(gpr) | 22, "r22" },
59 { rc(gpr) | 29, "ret1" },
60 { rc(gpr) | 28, "ret0" },
61 /* JIT_Rx in callee save registers due to need to call
62 * functions to implement some instructions */
63 /* JIT_R0- JIT_R2 */
64 { rc(gpr) | rc(sav) | 4, "r4" },
65 { rc(gpr) | rc(sav) | 5, "r5" },
66 { rc(gpr) | rc(sav) | 6, "r6" },
67 /* JIT_V0- JIT_V2 */
68 { rc(gpr) | rc(sav) | 7, "r7" },
69 { rc(sav) | rc(sav) | 8, "r8" },
70 { rc(gpr) | rc(sav) | 9, "r9" },
71 /* JIT_R3 */
72 { rc(gpr) | rc(sav) | 10, "r10" },
73 /* JIT_V3+ */
74 { rc(gpr) | rc(sav) | 11, "r11" },
75 { rc(gpr) | rc(sav) | 12, "r12" },
76 { rc(gpr) | rc(sav) | 13, "r13" },
77 { rc(gpr) | rc(sav) | 14, "r14" },
78 { rc(gpr) | rc(sav) | 15, "r15" },
79 { rc(gpr) | rc(sav) | 16, "r16" },
80 { rc(gpr) | rc(sav) | 17, "r17" },
81 { rc(gpr) | rc(sav) | 18, "r18" },
82 /* Arguments */
83 { rc(gpr) | rc(arg) | 23, "r23" },
84 { rc(gpr) | rc(arg) | 24, "r24" },
85 { rc(gpr) | rc(arg) | 25, "r25" },
86 { rc(gpr) | rc(arg) | 26, "r26" },
87 { 27, "dp" }, /* Data Pointer */
88 { 30, "sp" },
89 { 31, "r31" }, /* Link Register */
90 { rc(fpr) | 31, "fr31" },
91 { rc(fpr) | 30, "fr30" },
92 { rc(fpr) | 29, "fr29" },
93 { rc(fpr) | 28, "fr28" },
94 { rc(fpr) | 27, "fr27" },
95 { rc(fpr) | 26, "fr26" },
96 { rc(fpr) | 25, "fr25" },
97 { rc(fpr) | 24, "fr24" },
98 { rc(fpr) | 23, "fr23" },
99 { rc(fpr) | 22, "fr22" },
100 { rc(fpr) | 11, "fr11" },
101 { rc(fpr) | 10, "fr10" },
102 { rc(fpr) | 9, "fr9" },
103 { rc(fpr) | 8, "fr8" },
104 /* Arguments */
105 { rc(fpr) | rc(arg) | 7, "fr7" },
106 { rc(fpr) | rc(arg) | 6, "fr6" },
107 { rc(fpr) | rc(arg) | 5, "fr5" },
108 { rc(fpr) | rc(arg) | 4, "fr4" },
109 /* Callee Saves */
110 { rc(fpr) | rc(sav) | 21, "fr21" },
111 { rc(fpr) | rc(sav) | 20, "fr20" },
112 { rc(fpr) | rc(sav) | 19, "fr19" },
113 { rc(fpr) | rc(sav) | 18, "fr18" },
114 { rc(fpr) | rc(sav) | 17, "fr17" },
115 { rc(fpr) | rc(sav) | 16, "fr16" },
116 { rc(fpr) | rc(sav) | 15, "fr15" },
117 { rc(fpr) | rc(sav) | 14, "fr14" },
118 { rc(fpr) | rc(sav) | 13, "fr13" },
119 { rc(fpr) | rc(sav) | 12, "fr12" },
120 { 0, "fpsr" },
121 { 1, "fpe2" },
122 { 2, "fpe4" },
123 { 3, "fpe6" },
124 { _NOREG, "<none>" },
125};
126
127/*
128 * Implementation
129 */
130void
131jit_get_cpu(void)
132{
133 /* FIXME Expecting PARISC 2.0, for PARISC 1.0 should not use fr16-fr31 */
134}
135
136void
137_jit_init(jit_state_t *_jit)
138{
139 _jitc->reglen = jit_size(_rvs) - 1;
140}
141
142void
143_jit_prolog(jit_state_t *_jit)
144{
145 jit_int32_t offset;
146
147 if (_jitc->function)
148 jit_epilog();
149 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
150 jit_regset_set_ui(&_jitc->regsav, 0);
151 offset = _jitc->functions.offset;
152 if (offset >= _jitc->functions.length) {
153 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
154 _jitc->functions.length * sizeof(jit_function_t),
155 (_jitc->functions.length + 16) * sizeof(jit_function_t));
156 _jitc->functions.length += 16;
157 }
158 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
159 _jitc->function->self.size = params_offset;
160 _jitc->function->self.argi = _jitc->function->self.alen = 0;
161 /* float conversion */
162 _jitc->function->self.aoff = alloca_offset;
163 _jitc->function->self.call = jit_call_default;
164 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
165 _jitc->reglen * sizeof(jit_int32_t));
166
167 /* _no_link here does not mean the jit_link() call can be removed
168 * by rewriting as:
169 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
170 */
171 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
172 jit_link(_jitc->function->prolog);
173 _jitc->function->prolog->w.w = offset;
174 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
175 /* u: label value
176 * v: offset in blocks vector
177 * w: offset in functions vector
178 */
179 _jitc->function->epilog->w.w = offset;
180
181 jit_regset_new(&_jitc->function->regset);
182}
183
184jit_int32_t
185_jit_allocai(jit_state_t *_jit, jit_int32_t length)
186{
187 jit_int32_t offset;
188 assert(_jitc->function);
189 switch (length) {
190 case 0: case 1:
191 break;
192 case 2:
193 _jitc->function->self.aoff = (_jitc->function->self.aoff + 1) & -2;
194 break;
195 case 3: case 4:
196 _jitc->function->self.aoff = (_jitc->function->self.aoff + 3) & -4;
197 break;
198 default:
199 _jitc->function->self.aoff = (_jitc->function->self.aoff + 7) & -8;
200 break;
201 }
202 if (!_jitc->realize) {
203 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
204 jit_dec_synth();
205 }
206 offset = _jitc->function->self.aoff;
207 _jitc->function->self.aoff += length;
208 return (offset);
209}
210
211void
212_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
213{
214 jit_int32_t reg;
215 assert(_jitc->function);
216 jit_inc_synth_ww(allocar, u, v);
217 if (!_jitc->function->allocar) {
218 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
219 _jitc->function->allocar = 1;
220 }
221 reg = jit_get_reg(jit_class_gpr);
222 jit_addi(reg, v, 63);
223 jit_andi(reg, reg, -64);
224 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
225 jit_addr(JIT_SP, JIT_SP, reg);
226 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
227 jit_unget_reg(reg);
228 jit_dec_synth();
229}
230
231void
232_jit_ret(jit_state_t *_jit)
233{
234 jit_node_t *instr;
235 assert(_jitc->function);
236 jit_inc_synth(ret);
237 /* jump to epilog */
238 instr = jit_jmpi();
239 jit_patch_at(instr, _jitc->function->epilog);
240 jit_dec_synth();
241}
242
243void
244_jit_retr(jit_state_t *_jit, jit_int32_t u)
245{
246 jit_inc_synth_w(retr, u);
247 jit_movr(JIT_RET, u);
248 jit_ret();
249 jit_dec_synth();
250}
251
252void
253_jit_reti(jit_state_t *_jit, jit_word_t u)
254{
255 jit_inc_synth_w(reti, u);
256 jit_movi(JIT_RET, u);
257 jit_ret();
258 jit_dec_synth();
259}
260
261void
262_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
263{
264 jit_inc_synth_w(retr_f, u);
265 jit_movr_f(JIT_FRET, u);
266 jit_ret();
267 jit_dec_synth();
268}
269
270void
271_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
272{
273 jit_inc_synth_f(reti_f, u);
274 jit_movi_f(JIT_FRET, u);
275 jit_ret();
276 jit_dec_synth();
277}
278
279void
280_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
281{
282 jit_inc_synth_w(retr_d, u);
283 jit_movr_d(JIT_FRET, u);
284 jit_ret();
285 jit_dec_synth();
286}
287
288void
289_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
290{
291 jit_inc_synth_d(reti_d, u);
292 jit_movi_d(JIT_FRET, u);
293 jit_ret();
294 jit_dec_synth();
295}
296
297void
298_jit_epilog(jit_state_t *_jit)
299{
300 assert(_jitc->function);
301 assert(_jitc->function->epilog->next == NULL);
302 jit_link(_jitc->function->epilog);
303 _jitc->function = NULL;
304}
305
306jit_bool_t
307_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
308{
309 assert(u->code == jit_code_arg ||
310 u->code == jit_code_arg_f || u->code == jit_code_arg_d);
311 return (jit_arg_reg_p(u->u.w));
312}
313
314void
315_jit_ellipsis(jit_state_t *_jit)
316{
317 jit_inc_synth(ellipsis);
318 if (_jitc->prepare) {
319 jit_link_prepare();
320 assert(!(_jitc->function->call.call & jit_call_varargs));
321 _jitc->function->call.call |= jit_call_varargs;
322 }
323 else {
324 jit_link_prolog();
325 assert(!(_jitc->function->self.call & jit_call_varargs));
326 _jitc->function->self.call |= jit_call_varargs;
327
328 _jitc->function->vagp = _jitc->function->self.argi;
329 }
330 jit_dec_synth();
331}
332
333void
334_jit_va_push(jit_state_t *_jit, jit_int32_t u)
335{
336 jit_inc_synth_w(va_push, u);
337 jit_pushargr(u);
338 jit_dec_synth();
339}
340
341jit_node_t *
342_jit_arg(jit_state_t *_jit)
343{
344 jit_node_t *node;
345 jit_int32_t offset;
346 assert(_jitc->function);
347 _jitc->function->self.size -= sizeof(jit_word_t);
348 if (jit_arg_reg_p(_jitc->function->self.argi))
349 offset = _jitc->function->self.argi++;
350 else
351 offset = _jitc->function->self.size;
352 node = jit_new_node_ww(jit_code_arg, offset,
353 ++_jitc->function->self.argn);
354 jit_link_prolog();
355 return (node);
356}
357
358jit_node_t *
359_jit_arg_f(jit_state_t *_jit)
360{
361 jit_node_t *node;
362 jit_int32_t offset;
363 assert(_jitc->function);
364 _jitc->function->self.size -= sizeof(jit_word_t);
365 if (jit_arg_reg_p(_jitc->function->self.argi))
366 offset = _jitc->function->self.argi++;
367 else
368 offset = _jitc->function->self.size;
369 node = jit_new_node_ww(jit_code_arg_f, offset,
370 ++_jitc->function->self.argn);
371 jit_link_prolog();
372 return (node);
373}
374
375jit_node_t *
376_jit_arg_d(jit_state_t *_jit)
377{
378 jit_node_t *node;
379 jit_int32_t offset;
380 assert(_jitc->function);
381 if (_jitc->function->self.argi & 1) {
382 ++_jitc->function->self.argi;
383 _jitc->function->self.size -= sizeof(jit_word_t);
384 }
385 _jitc->function->self.size -= sizeof(jit_float64_t);
386 if (jit_arg_reg_p(_jitc->function->self.argi)) {
387 offset = _jitc->function->self.argi + 1;
388 _jitc->function->self.argi += 2;
389 }
390 else {
391 /* "Standard" initial value (-52) is unaligned */
392 if (_jitc->function->self.size & 7)
393 _jitc->function->self.size -= sizeof(jit_word_t);
394 offset = _jitc->function->self.size;
395 }
396 node = jit_new_node_ww(jit_code_arg_d, offset,
397 ++_jitc->function->self.argn);
398 jit_link_prolog();
399 return (node);
400}
401
402void
403_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
404{
405 assert(v->code == jit_code_arg);
406 jit_inc_synth_wp(getarg_c, u, v);
407 if (v->u.w >= 0)
408 jit_extr_c(u, _R26 - v->u.w);
409 else
410 jit_ldxi_c(u, JIT_FP, v->u.w + 3);
411 jit_dec_synth();
412}
413
414void
415_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
416{
417 assert(v->code == jit_code_arg);
418 jit_inc_synth_wp(getarg_uc, u, v);
419 if (v->u.w >= 0)
420 jit_extr_uc(u, _R26 - v->u.w);
421 else
422 jit_ldxi_uc(u, JIT_FP, v->u.w + 3);
423 jit_dec_synth();
424}
425
426void
427_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
428{
429 assert(v->code == jit_code_arg);
430 jit_inc_synth_wp(getarg_s, u, v);
431 if (v->u.w >= 0)
432 jit_extr_s(u, _R26 - v->u.w);
433 else
434 jit_ldxi_s(u, JIT_FP, v->u.w + 2);
435 jit_dec_synth();
436}
437
438void
439_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
440{
441 assert(v->code == jit_code_arg);
442 jit_inc_synth_wp(getarg_us, u, v);
443 if (v->u.w >= 0)
444 jit_extr_us(u, _R26 - v->u.w);
445 else
446 jit_ldxi_us(u, JIT_FP, v->u.w + 2);
447 jit_dec_synth();
448}
449
450void
451_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
452{
453 assert(v->code == jit_code_arg);
454 jit_inc_synth_wp(getarg_i, u, v);
455 if (v->u.w >= 0)
456 jit_movr(u, _R26 - v->u.w);
457 else
458 jit_ldxi_i(u, JIT_FP, v->u.w);
459 jit_dec_synth();
460}
461
462void
463_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
464{
465 assert(v->code == jit_code_arg);
466 jit_inc_synth_wp(putargr, u, v);
467 if (v->u.w >= 0)
468 jit_movr(_R26 - v->u.w, u);
469 else
470 jit_stxi(v->u.w, JIT_FP, u);
471 jit_dec_synth();
472}
473
474void
475_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
476{
477 jit_int32_t regno;
478 assert(v->code == jit_code_arg);
479 jit_inc_synth_wp(putargi, u, v);
480 if (v->u.w >= 0)
481 jit_movi(_R26 - v->u.w, u);
482 else {
483 regno = jit_get_reg(jit_class_gpr);
484 jit_movi(regno, u);
485 jit_stxi(v->u.w, JIT_FP, regno);
486 jit_unget_reg(regno);
487 }
488 jit_dec_synth();
489}
490
491void
492_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
493{
494 assert(v->code == jit_code_arg_f);
495 jit_inc_synth_wp(getarg_f, u, v);
496 if (v->u.w >= 0)
497 jit_movr_f(u, _F4 - v->u.w);
498 else
499 jit_ldxi_f(u, JIT_FP, v->u.w);
500 jit_dec_synth();
501}
502
503void
504_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
505{
506 assert(v->code == jit_code_arg_f);
507 jit_inc_synth_wp(putargr_f, u, v);
508 if (v->u.w >= 0)
509 jit_movr_f(_F4 - v->u.w, u);
510 else
511 jit_stxi_f(v->u.w, JIT_FP, u);
512 jit_dec_synth();
513}
514
515void
516_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
517{
518 jit_int32_t regno;
519 assert(v->code == jit_code_arg_f);
520 jit_inc_synth_fp(putargi_f, u, v);
521 if (v->u.w >= 0)
522 jit_movi_f(_R26 - v->u.w, u);
523 else {
524 regno = jit_get_reg(jit_class_fpr);
525 jit_movi_f(regno, u);
526 jit_stxi_f(v->u.w, JIT_FP, regno);
527 jit_unget_reg(regno);
528 }
529 jit_dec_synth();
530}
531
532void
533_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
534{
535 assert(v->code == jit_code_arg_d);
536 jit_inc_synth_wp(getarg_d, u, v);
537 if (v->u.w >= 0)
538 jit_movr_d(u, _F4 - v->u.w);
539 else
540 jit_ldxi_d(u, JIT_FP, v->u.w);
541 jit_dec_synth();
542}
543
544void
545_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
546{
547 assert(v->code == jit_code_arg_d);
548 jit_inc_synth_wp(putargr_d, u, v);
549 if (v->u.w >= 0)
550 jit_movr_d(_F4 - v->u.w, u);
551 else
552 jit_stxi_d(v->u.w, JIT_FP, u);
553 jit_dec_synth();
554}
555
556void
557_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
558{
559 jit_int32_t regno;
560 assert(v->code == jit_code_arg_d);
561 jit_inc_synth_dp(putargi_d, u, v);
562 if (v->u.w >= 0)
563 jit_movi_d(_R26 - v->u.w, u);
564 else {
565 regno = jit_get_reg(jit_class_fpr);
566 jit_movi_d(regno, u);
567 jit_stxi_d(v->u.w, JIT_FP, regno);
568 jit_unget_reg(regno);
569 }
570 jit_dec_synth();
571}
572
573void
574_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
575{
576 assert(_jitc->function);
577 jit_inc_synth_w(pushargr, u);
578 jit_link_prepare();
579 _jitc->function->call.size -= sizeof(jit_word_t);
580 if (jit_arg_reg_p(_jitc->function->call.argi)) {
581 jit_movr(_R26 - _jitc->function->call.argi, u);
582 ++_jitc->function->call.argi;
583 }
584 else
585 jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
586 jit_dec_synth();
587}
588
589void
590_jit_pushargi(jit_state_t *_jit, jit_word_t u)
591{
592 jit_int32_t regno;
593 assert(_jitc->function);
594 jit_inc_synth_w(pushargi, u);
595 jit_link_prepare();
596 _jitc->function->call.size -= sizeof(jit_word_t);
597 if (jit_arg_reg_p(_jitc->function->call.argi)) {
598 jit_movi(_R26 - _jitc->function->call.argi, u);
599 ++_jitc->function->call.argi;
600 }
601 else {
602 regno = jit_get_reg(jit_class_gpr);
603 jit_movi(regno, u);
604 jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno);
605 jit_unget_reg(regno);
606 }
607 jit_dec_synth();
608}
609
610void
611_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
612{
613 assert(_jitc->function);
614 jit_inc_synth_w(pushargr_f, u);
615 jit_link_prepare();
616 _jitc->function->call.size -= sizeof(jit_word_t);
617 if (jit_arg_reg_p(_jitc->function->call.argi)) {
618 jit_movr_f(_F4 - _jitc->function->call.argi, u);
619#if !defined(__hpux)
620 /* HP-UX appears to always pass float arguments in gpr registers */
621 if (_jitc->function->call.call & jit_call_varargs)
622#endif
623 {
624 jit_stxi_f(alloca_offset - 8, JIT_FP, u);
625 jit_ldxi(_R26 - _jitc->function->call.argi, JIT_FP,
626 alloca_offset - 8);
627 }
628 ++_jitc->function->call.argi;
629 }
630 else
631 jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, u);
632 jit_dec_synth();
633}
634
635void
636_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
637{
638 jit_int32_t regno;
639 assert(_jitc->function);
640 jit_inc_synth_f(pushargi_f, u);
641 jit_link_prepare();
642 _jitc->function->call.size -= sizeof(jit_word_t);
643 if (jit_arg_reg_p(_jitc->function->call.argi)) {
644 jit_movi_f(_F4 - _jitc->function->call.argi, u);
645#if !defined(__hpux)
646 /* HP-UX appears to always pass float arguments in gpr registers */
647 if (_jitc->function->call.call & jit_call_varargs)
648#endif
649 {
650 jit_stxi_f(alloca_offset - 8, JIT_FP,
651 _F4 - _jitc->function->call.argi);
652 jit_ldxi(_R26 - _jitc->function->call.argi,
653 JIT_FP, alloca_offset - 8);
654 }
655 ++_jitc->function->call.argi;
656 }
657 else {
658 regno = jit_get_reg(jit_class_fpr);
659 jit_movi_f(regno, u);
660 jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, regno);
661 jit_unget_reg(regno);
662 }
663 jit_dec_synth();
664}
665
666void
667_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
668{
669 assert(_jitc->function);
670 jit_inc_synth_w(pushargr_d, u);
671 jit_link_prepare();
672 _jitc->function->call.size -= sizeof(jit_float64_t);
673 if (_jitc->function->call.argi & 1) {
674 ++_jitc->function->call.argi;
675 _jitc->function->call.size -= sizeof(jit_word_t);
676 }
677 if (jit_arg_reg_p(_jitc->function->call.argi)) {
678 jit_movr_d(_F4 - (_jitc->function->call.argi + 1), u);
679#if !defined(__hpux)
680 /* HP-UX appears to always pass float arguments in gpr registers */
681 if (_jitc->function->call.call & jit_call_varargs)
682#endif
683 {
684 jit_stxi_d(alloca_offset - 8, JIT_FP, u);
685 jit_ldxi(_R26 - _jitc->function->call.argi,
686 JIT_FP, alloca_offset - 4);
687 jit_ldxi(_R25 - _jitc->function->call.argi,
688 JIT_FP, alloca_offset - 8);
689 }
690 _jitc->function->call.argi += 2;
691 }
692 else {
693 /* "Standard" initial value (-52) is unaligned */
694 if ((_jitc->function->call.size + params_offset) & 7)
695 _jitc->function->call.size -= sizeof(jit_word_t);
696 jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
697 }
698 jit_dec_synth();
699}
700
701void
702_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
703{
704 jit_int32_t regno;
705 assert(_jitc->function);
706 jit_inc_synth_d(pushargi_d, u);
707 jit_link_prepare();
708 _jitc->function->call.size -= sizeof(jit_float64_t);
709 if (_jitc->function->call.argi & 1) {
710 ++_jitc->function->call.argi;
711 _jitc->function->call.size -= sizeof(jit_word_t);
712 }
713 if (jit_arg_reg_p(_jitc->function->call.argi)) {
714 jit_movi_d(_F4 - (_jitc->function->call.argi + 1), u);
715#if !defined(__hpux)
716 /* HP-UX appears to always pass float arguments in gpr registers */
717 if (_jitc->function->call.call & jit_call_varargs)
718#endif
719 {
720 jit_stxi_d(alloca_offset - 8, JIT_FP,
721 _F4 - (_jitc->function->call.argi + 1));
722 jit_ldxi(_R26 - _jitc->function->call.argi,
723 JIT_FP, alloca_offset - 4);
724 jit_ldxi(_R25 - _jitc->function->call.argi,
725 JIT_FP, alloca_offset - 8);
726 }
727 _jitc->function->call.argi += 2;
728 }
729 else {
730 regno = jit_get_reg(jit_class_fpr);
731 jit_movi_d(regno, u);
732 if ((_jitc->function->call.size + params_offset) & 7)
733 _jitc->function->call.size -= sizeof(jit_word_t);
734 jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno);
735 jit_unget_reg(regno);
736 }
737 jit_dec_synth();
738}
739
740jit_bool_t
741_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
742{
743 jit_int32_t spec;
744 spec = jit_class(_rvs[regno].spec);
745 if (spec & jit_class_arg) {
746 if (spec & jit_class_gpr) {
747 regno -= _R23;
748 if (regno >= 0 && regno < node->v.w)
749 return (1);
750 }
751 else if (spec & jit_class_fpr) {
752 regno = _F4 - regno;
753 if (regno >= 0 && regno < node->w.w)
754 return (1);
755 }
756 }
757 return (0);
758}
759
760void
761_jit_finishr(jit_state_t *_jit, jit_int32_t r0)
762{
763 jit_node_t *call;
764 assert(_jitc->function);
765 jit_inc_synth_w(finishr, r0);
766 if (_jitc->function->self.alen > _jitc->function->call.size)
767 _jitc->function->self.alen = _jitc->function->call.size;
768 call = jit_callr(r0);
769 call->v.w = call->w.w = _jitc->function->call.argi;
770 _jitc->function->call.argi = _jitc->function->call.size = 0;
771 _jitc->prepare = 0;
772 jit_dec_synth();
773}
774
775jit_node_t *
776_jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
777{
778 jit_node_t *node;
779 assert(_jitc->function);
780 jit_inc_synth_w(finishi, (jit_word_t)i0);
781 if (_jitc->function->self.alen > _jitc->function->call.size)
782 _jitc->function->self.alen = _jitc->function->call.size;
783 node = jit_calli(i0);
784 node->v.w = node->w.w = _jitc->function->call.argi;
785 _jitc->function->call.argi = _jitc->function->call.size = 0;
786 _jitc->prepare = 0;
787 jit_dec_synth();
788 return (node);
789}
790
791void
792_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
793{
794 jit_inc_synth_w(retval_c, r0);
795 jit_extr_c(r0, JIT_RET);
796 jit_dec_synth();
797}
798
799void
800_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
801{
802 jit_inc_synth_w(retval_uc, r0);
803 jit_extr_uc(r0, JIT_RET);
804 jit_dec_synth();
805}
806
807void
808_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
809{
810 jit_inc_synth_w(retval_s, r0);
811 jit_extr_s(r0, JIT_RET);
812 jit_dec_synth();
813}
814
815void
816_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
817{
818 jit_inc_synth_w(retval_us, r0);
819 jit_extr_us(r0, JIT_RET);
820 jit_dec_synth();
821}
822
823void
824_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
825{
826 jit_inc_synth_w(retval_i, r0);
827 jit_movr(r0, JIT_RET);
828 jit_dec_synth();
829}
830
831void
832_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
833{
834 jit_inc_synth_w(retval_f, r0);
835 jit_movr_f(r0, JIT_FRET);
836 jit_dec_synth();
837}
838
839void
840_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
841{
842 jit_inc_synth_w(retval_d, r0);
843 jit_movr_d(r0, JIT_FRET);
844 jit_dec_synth();
845}
846
847jit_pointer_t
848_emit_code(jit_state_t *_jit)
849{
850 jit_node_t *node;
851 jit_node_t *temp;
852 jit_word_t word;
853 jit_int32_t value;
854 jit_int32_t offset;
855 struct {
856 jit_node_t *node;
857 jit_word_t word;
858#if DEVEL_DISASSEMBLER
859 jit_word_t prevw;
860#endif
861 jit_int32_t patch_offset;
862 } undo;
863#if DEVEL_DISASSEMBLER
864 jit_word_t prevw;
865#endif
866
867 _jitc->function = NULL;
868
869 jit_reglive_setup();
870
871 undo.word = 0;
872 undo.node = NULL;
873 undo.patch_offset = 0;
874
875#define case_rr(name, type) \
876 case jit_code_##name##r##type: \
877 name##r##type(rn(node->u.w), rn(node->v.w)); \
878 break
879#define case_rw(name, type) \
880 case jit_code_##name##i##type: \
881 name##i##type(rn(node->u.w), node->v.w); \
882 break
883#define case_wr(name, type) \
884 case jit_code_##name##i##type: \
885 name##i##type(node->u.w, rn(node->v.w)); \
886 break
887#define case_rrr(name, type) \
888 case jit_code_##name##r##type: \
889 name##r##type(rn(node->u.w), \
890 rn(node->v.w), rn(node->w.w)); \
891 break
892#define case_rrrr(name, type) \
893 case jit_code_##name##r##type: \
894 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
895 rn(node->v.w), rn(node->w.w)); \
896 break
897#define case_rrw(name, type) \
898 case jit_code_##name##i##type: \
899 name##i##type(rn(node->u.w),rn(node->v.w), node->w.w); \
900 break
901#define case_rrrw(name, type) \
902 case jit_code_##name##i##type: \
903 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
904 rn(node->v.w), node->w.w); \
905 break
906#define case_rrf(name, type, size) \
907 case jit_code_##name##i##type: \
908 assert(node->flag & jit_flag_data); \
909 name##i##type(rn(node->u.w), rn(node->v.w), \
910 (jit_float##size##_t *)node->w.n->u.w); \
911 break
912#define case_wrr(name, type) \
913 case jit_code_##name##i##type: \
914 name##i##type(node->u.w,rn(node->v.w), rn(node->w.w)); \
915 break
916#define case_brr(name, type) \
917 case jit_code_##name##r##type: \
918 temp = node->u.n; \
919 assert(temp->code == jit_code_label || \
920 temp->code == jit_code_epilog); \
921 if (temp->flag & jit_flag_patch) \
922 name##r##type(temp->u.w, rn(node->v.w), \
923 rn(node->w.w)); \
924 else { \
925 word = name##r##type(_jit->pc.w, \
926 rn(node->v.w), rn(node->w.w)); \
927 patch(word, node); \
928 } \
929 break
930#define case_brw(name, type) \
931 case jit_code_##name##i##type: \
932 temp = node->u.n; \
933 assert(temp->code == jit_code_label || \
934 temp->code == jit_code_epilog); \
935 if (temp->flag & jit_flag_patch) \
936 name##i##type(temp->u.w, \
937 rn(node->v.w), node->w.w); \
938 else { \
939 word = name##i##type(_jit->pc.w, \
940 rn(node->v.w), node->w.w); \
941 patch(word, node); \
942 } \
943 break
944#define case_brf(name, type, size) \
945 case jit_code_##name##i##type: \
946 temp = node->u.n; \
947 assert(temp->code == jit_code_label || \
948 temp->code == jit_code_epilog); \
949 if (temp->flag & jit_flag_patch) \
950 name##i##type(temp->u.w, rn(node->v.w), \
951 (jit_float##size##_t *)node->w.n->u.w); \
952 else { \
953 word = name##i##type(_jit->pc.w, rn(node->v.w), \
954 (jit_float##size##_t *)node->w.n->u.w); \
955 patch(word, node); \
956 } \
957 break
958#if DEVEL_DISASSEMBLER
959 prevw = _jit->pc.w;
960#endif
961 for (node = _jitc->head; node; node = node->next) {
962 if (_jit->pc.uc >= _jitc->code.end)
963 return (NULL);
964
965#if DEVEL_DISASSEMBLER
966 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
967 prevw = _jit->pc.w;
968#endif
969 value = jit_classify(node->code);
970 jit_regarg_set(node, value);
971 switch (node->code) {
972 case jit_code_align:
973 assert(!(node->u.w & (node->u.w - 1)) &&
974 node->u.w <= sizeof(jit_word_t));
975 if (node->u.w == sizeof(jit_word_t) &&
976 (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
977 nop(sizeof(jit_word_t) - word);
978 break;
979 case jit_code_note: case jit_code_name:
980 node->u.w = _jit->pc.w;
981 break;
982 case jit_code_label:
983 /* remember label is defined */
984 node->flag |= jit_flag_patch;
985 node->u.w = _jit->pc.w;
986 break;
987 case_rrr(add,);
988 case_rrw(add,);
989 case_rrr(addc,);
990 case_rrw(addc,);
991 case_rrr(addx,);
992 case_rrw(addx,);
993 case_rrr(sub,);
994 case_rrw(sub,);
995 case_rrr(subc,);
996 case_rrw(subc,);
997 case_rrr(subx,);
998 case_rrw(subx,);
999 case_rrw(rsb,);
1000 case_rrr(mul,);
1001 case_rrw(mul,);
1002 case_rrrr(qmul,);
1003 case_rrrw(qmul,);
1004 case_rrrr(qmul, _u);
1005 case_rrrw(qmul, _u);
1006 case_rrr(div,);
1007 case_rrw(div,);
1008 case_rrr(div, _u);
1009 case_rrw(div, _u);
1010 case_rrr(rem,);
1011 case_rrw(rem,);
1012 case_rrr(rem, _u);
1013 case_rrw(rem, _u);
1014 case_rrrr(qdiv,);
1015 case_rrrw(qdiv,);
1016 case_rrrr(qdiv, _u);
1017 case_rrrw(qdiv, _u);
1018 case_rrr(and,);
1019 case_rrw(and,);
1020 case_rrr(or,);
1021 case_rrw(or,);
1022 case_rrr(xor,);
1023 case_rrw(xor,);
1024 case_rrr(lsh,);
1025 case_rrw(lsh,);
1026 case_rrr(rsh,);
1027 case_rrw(rsh,);
1028 case_rrr(rsh, _u);
1029 case_rrw(rsh, _u);
40a44dcb
PC
1030 case_rrr(movn,);
1031 case_rrr(movz,);
ba3814c1
PC
1032 case jit_code_casr:
1033 casr(rn(node->u.w), rn(node->v.w),
1034 rn(node->w.q.l), rn(node->w.q.h));
1035 break;
1036 case jit_code_casi:
1037 casi(rn(node->u.w), node->v.w,
1038 rn(node->w.q.l), rn(node->w.q.h));
1039 break;
4a71579b
PC
1040 case_rr(mov,);
1041 case jit_code_movi:
1042 if (node->flag & jit_flag_node) {
1043 temp = node->v.n;
1044 if (temp->code == jit_code_data ||
1045 (temp->code == jit_code_label &&
1046 (temp->flag & jit_flag_patch)))
1047 movi(rn(node->u.w), temp->u.w);
1048 else {
1049 assert(temp->code == jit_code_label ||
1050 temp->code == jit_code_epilog);
1051 word = movi_p(rn(node->u.w), node->v.w);
1052 patch(word, node);
1053 }
1054 }
1055 else
1056 movi(rn(node->u.w), node->v.w);
1057 break;
1058 case_rr(neg,);
1059 case_rr(com,);
1060 case_rr(ext, _c);
1061 case_rr(ext, _uc);
1062 case_rr(ext, _s);
1063 case_rr(ext, _us);
1064 case_rr(hton, _us);
1065 case_rr(hton, _ui);
40a44dcb
PC
1066 case_rr(bswap, _us);
1067 case_rr(bswap, _ui);
4a71579b
PC
1068 case_rrr(lt,);
1069 case_rrw(lt,);
1070 case_rrr(lt, _u);
1071 case_rrw(lt, _u);
1072 case_rrr(le,);
1073 case_rrw(le,);
1074 case_rrr(le, _u);
1075 case_rrw(le, _u);
1076 case_rrr(eq,);
1077 case_rrw(eq,);
1078 case_rrr(ge,);
1079 case_rrw(ge,);
1080 case_rrr(ge, _u);
1081 case_rrw(ge, _u);
1082 case_rrr(gt,);
1083 case_rrw(gt,);
1084 case_rrr(gt, _u);
1085 case_rrw(gt, _u);
1086 case_rrr(ne,);
1087 case_rrw(ne,);
1088 case_rr(ld, _c);
1089 case_rw(ld, _c);
1090 case_rr(ld, _uc);
1091 case_rw(ld, _uc);
1092 case_rr(ld, _s);
1093 case_rw(ld, _s);
1094 case_rr(ld, _us);
1095 case_rw(ld, _us);
1096 case_rr(ld, _i);
1097 case_rw(ld, _i);
1098 case_rrr(ldx, _c);
1099 case_rrw(ldx, _c);
1100 case_rrr(ldx, _uc);
1101 case_rrw(ldx, _uc);
1102 case_rrr(ldx, _s);
1103 case_rrw(ldx, _s);
1104 case_rrr(ldx, _us);
1105 case_rrw(ldx, _us);
1106 case_rrr(ldx, _i);
1107 case_rrw(ldx, _i);
1108 case_rr(st, _c);
1109 case_wr(st, _c);
1110 case_rr(st, _s);
1111 case_wr(st, _s);
1112 case_rr(st, _i);
1113 case_wr(st, _i);
1114 case_rrr(stx, _c);
1115 case_wrr(stx, _c);
1116 case_rrr(stx, _s);
1117 case_wrr(stx, _s);
1118 case_rrr(stx, _i);
1119 case_wrr(stx, _i);
1120 case_brr(blt,);
1121 case_brw(blt,);
1122 case_brr(blt, _u);
1123 case_brw(blt, _u);
1124 case_brr(ble,);
1125 case_brw(ble,);
1126 case_brr(ble, _u);
1127 case_brw(ble, _u);
1128 case_brr(beq,);
1129 case_brw(beq,);
1130 case_brr(bge,);
1131 case_brw(bge,);
1132 case_brr(bge, _u);
1133 case_brw(bge, _u);
1134 case_brr(bgt,);
1135 case_brw(bgt,);
1136 case_brr(bgt, _u);
1137 case_brw(bgt, _u);
1138 case_brr(bne,);
1139 case_brw(bne,);
1140 case_brr(bms,);
1141 case_brw(bms,);
1142 case_brr(bmc,);
1143 case_brw(bmc,);
1144 case_brr(boadd,);
1145 case_brw(boadd,);
1146 case_brr(boadd, _u);
1147 case_brw(boadd, _u);
1148 case_brr(bxadd,);
1149 case_brw(bxadd,);
1150 case_brr(bxadd, _u);
1151 case_brw(bxadd, _u);
1152 case_brr(bosub,);
1153 case_brw(bosub,);
1154 case_brr(bosub, _u);
1155 case_brw(bosub, _u);
1156 case_brr(bxsub,);
1157 case_brw(bxsub,);
1158 case_brr(bxsub, _u);
1159 case_brw(bxsub, _u);
1160 case_rr(mov, _f);
1161 case jit_code_movi_f:
1162 assert(node->flag & jit_flag_data);
1163 movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w);
1164 break;
1165 case_rr(mov, _d);
1166 case jit_code_movi_d:
1167 assert(node->flag & jit_flag_data);
1168 movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w);
1169 break;
1170 case_rr(trunc, _f_i);
1171 case_rr(trunc, _d_i);
1172 case_rr(ext, _f);
1173 case_rr(ext, _d);
1174 case_rr(ext, _d_f);
1175 case_rr(ext, _f_d);
1176 case_rr(abs, _f);
1177 case_rr(abs, _d);
1178 case_rr(neg, _f);
1179 case_rr(neg, _d);
1180 case_rr(sqrt, _f);
1181 case_rr(sqrt, _d);
1182 case_rrr(add, _f);
1183 case_rrf(add, _f, 32);
1184 case_rrr(add, _d);
1185 case_rrf(add, _d, 64);
1186 case_rrr(sub, _f);
1187 case_rrf(sub, _f, 32);
1188 case_rrf(rsb, _f, 32);
1189 case_rrr(sub, _d);
1190 case_rrf(sub, _d, 64);
1191 case_rrf(rsb, _d, 64);
1192 case_rrr(mul, _f);
1193 case_rrf(mul, _f, 32);
1194 case_rrr(mul, _d);
1195 case_rrf(mul, _d, 64);
1196 case_rrr(div, _f);
1197 case_rrf(div, _f, 32);
1198 case_rrr(div, _d);
1199 case_rrf(div, _d, 64);
1200 case_rrr(lt, _f);
1201 case_rrf(lt, _f, 32);
1202 case_rrr(lt, _d);
1203 case_rrf(lt, _d, 64);
1204 case_rrr(le, _f);
1205 case_rrf(le, _f, 32);
1206 case_rrr(le, _d);
1207 case_rrf(le, _d, 64);
1208 case_rrr(eq, _f);
1209 case_rrf(eq, _f, 32);
1210 case_rrr(eq, _d);
1211 case_rrf(eq, _d, 64);
1212 case_rrr(ge, _f);
1213 case_rrf(ge, _f, 32);
1214 case_rrr(ge, _d);
1215 case_rrf(ge, _d, 64);
1216 case_rrr(gt, _f);
1217 case_rrf(gt, _f, 32);
1218 case_rrr(gt, _d);
1219 case_rrf(gt, _d, 64);
1220 case_rrr(ne, _f);
1221 case_rrf(ne, _f, 32);
1222 case_rrr(ne, _d);
1223 case_rrf(ne, _d, 64);
1224 case_rrr(unlt, _f);
1225 case_rrf(unlt, _f, 32);
1226 case_rrr(unlt, _d);
1227 case_rrf(unlt, _d, 64);
1228 case_rrr(unle, _f);
1229 case_rrf(unle, _f, 32);
1230 case_rrr(unle, _d);
1231 case_rrf(unle, _d, 64);
1232 case_rrr(uneq, _f);
1233 case_rrf(uneq, _f, 32);
1234 case_rrr(uneq, _d);
1235 case_rrf(uneq, _d, 64);
1236 case_rrr(unge, _f);
1237 case_rrf(unge, _f, 32);
1238 case_rrr(unge, _d);
1239 case_rrf(unge, _d, 64);
1240 case_rrr(ungt, _f);
1241 case_rrf(ungt, _f, 32);
1242 case_rrr(ungt, _d);
1243 case_rrf(ungt, _d, 64);
1244 case_rrr(ltgt, _f);
1245 case_rrf(ltgt, _f, 32);
1246 case_rrr(ltgt, _d);
1247 case_rrf(ltgt, _d, 64);
1248 case_rrr(ord, _f);
1249 case_rrf(ord, _f, 32);
1250 case_rrr(ord, _d);
1251 case_rrf(ord, _d, 64);
1252 case_rrr(unord, _f);
1253 case_rrf(unord, _f, 32);
1254 case_rrr(unord, _d);
1255 case_rrf(unord, _d, 64);
1256 case_rr(ld, _f);
1257 case_rw(ld, _f);
1258 case_rr(ld, _d);
1259 case_rw(ld, _d);
1260 case_rrr(ldx, _f);
1261 case_rrw(ldx, _f);
1262 case_rrr(ldx, _d);
1263 case_rrw(ldx, _d);
1264 case_rr(st, _f);
1265 case_wr(st, _f);
1266 case_rr(st, _d);
1267 case_wr(st, _d);
1268 case_rrr(stx, _f);
1269 case_wrr(stx, _f);
1270 case_rrr(stx, _d);
1271 case_wrr(stx, _d);
1272 case_brr(blt, _f);
1273 case_brf(blt, _f, 32);
1274 case_brr(blt, _d);
1275 case_brf(blt, _d, 64);
1276 case_brr(ble, _f);
1277 case_brf(ble, _f, 32);
1278 case_brr(ble, _d);
1279 case_brf(ble, _d, 64);
1280 case_brr(beq, _f);
1281 case_brf(beq, _f, 32);
1282 case_brr(beq, _d);
1283 case_brf(beq, _d, 64);
1284 case_brr(bge, _f);
1285 case_brf(bge, _f, 32);
1286 case_brr(bge, _d);
1287 case_brf(bge, _d, 64);
1288 case_brr(bgt, _f);
1289 case_brf(bgt, _f, 32);
1290 case_brr(bgt, _d);
1291 case_brf(bgt, _d, 64);
1292 case_brr(bne, _f);
1293 case_brf(bne, _f, 32);
1294 case_brr(bne, _d);
1295 case_brf(bne, _d, 64);
1296 case_brr(bunlt, _f);
1297 case_brf(bunlt, _f, 32);
1298 case_brr(bunlt, _d);
1299 case_brf(bunlt, _d, 64);
1300 case_brr(bunle, _f);
1301 case_brf(bunle, _f, 32);
1302 case_brr(bunle, _d);
1303 case_brf(bunle, _d, 64);
1304 case_brr(buneq, _f);
1305 case_brf(buneq, _f, 32);
1306 case_brr(buneq, _d);
1307 case_brf(buneq, _d, 64);
1308 case_brr(bunge, _f);
1309 case_brf(bunge, _f, 32);
1310 case_brr(bunge, _d);
1311 case_brf(bunge, _d, 64);
1312 case_brr(bungt, _f);
1313 case_brf(bungt, _f, 32);
1314 case_brr(bungt, _d);
1315 case_brf(bungt, _d, 64);
1316 case_brr(bltgt, _f);
1317 case_brf(bltgt, _f, 32);
1318 case_brr(bltgt, _d);
1319 case_brf(bltgt, _d, 64);
1320 case_brr(bord, _f);
1321 case_brf(bord, _f, 32);
1322 case_brr(bord, _d);
1323 case_brf(bord, _d, 64);
1324 case_brr(bunord, _f);
1325 case_brf(bunord, _f, 32);
1326 case_brr(bunord, _d);
1327 case_brf(bunord, _d, 64);
1328 case jit_code_jmpr:
1329 jmpr(rn(node->u.w));
1330 break;
1331 case jit_code_jmpi:
1332 if (node->flag & jit_flag_node) {
1333 temp = node->u.n;
1334 assert(temp->code == jit_code_label ||
1335 temp->code == jit_code_epilog);
1336 if (temp->flag & jit_flag_patch)
1337 jmpi(temp->u.w);
1338 else {
1339 word = jmpi_p(_jit->pc.w);
1340 patch(word, node);
1341 }
1342 }
1343 else
1344 jmpi(node->u.w);
1345 break;
1346 case jit_code_callr:
1347 callr(rn(node->u.w));
1348 break;
1349 case jit_code_calli:
1350 if (node->flag & jit_flag_node) {
1351 temp = node->u.n;
1352 assert(temp->code == jit_code_label ||
1353 temp->code == jit_code_epilog);
1354 if (!(temp->flag & jit_flag_patch)) {
1355 word = calli_p(temp->u.w);
1356 patch(word, node);
1357 }
1358 else
1359 calli(temp->u.w);
1360 }
1361 else
1362 calli(node->u.w);
1363 break;
1364 case jit_code_prolog:
1365 _jitc->function = _jitc->functions.ptr + node->w.w;
1366 undo.node = node;
1367 undo.word = _jit->pc.w;
1368#if DEVEL_DISASSEMBLER
1369 undo.prevw = prevw;
1370#endif
1371 undo.patch_offset = _jitc->patches.offset;
1372 restart_function:
1373 _jitc->again = 0;
1374 prolog(node);
1375 break;
1376 case jit_code_epilog:
1377 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1378 if (_jitc->again) {
1379 for (temp = undo.node->next;
1380 temp != node; temp = temp->next) {
1381 if (temp->code == jit_code_label ||
1382 temp->code == jit_code_epilog)
1383 temp->flag &= ~jit_flag_patch;
1384 }
1385 temp->flag &= ~jit_flag_patch;
1386 node = undo.node;
1387 _jit->pc.w = undo.word;
1388#if DEVEL_DISASSEMBLER
1389 prevw = undo.prevw;
1390#endif
1391 _jitc->patches.offset = undo.patch_offset;
1392 goto restart_function;
1393 }
1394 /* remember label is defined */
1395 node->flag |= jit_flag_patch;
1396 node->u.w = _jit->pc.w;
1397 epilog(node);
1398 _jitc->function = NULL;
1399 break;
1400 case jit_code_va_start:
1401 vastart(rn(node->u.w));
1402 break;
1403 case jit_code_va_arg:
1404 vaarg(rn(node->u.w), rn(node->v.w));
1405 break;
1406 case jit_code_va_arg_d:
1407 vaarg_d(rn(node->u.w), rn(node->v.w));
1408 break;
1409 case jit_code_live:
1410 case jit_code_arg: case jit_code_ellipsis:
1411 case jit_code_va_push:
1412 case jit_code_allocai: case jit_code_allocar:
1413 case jit_code_arg_f: case jit_code_arg_d:
1414 case jit_code_va_end:
1415 case jit_code_ret:
1416 case jit_code_retr: case jit_code_reti:
1417 case jit_code_retr_f: case jit_code_reti_f:
1418 case jit_code_retr_d: case jit_code_reti_d:
1419 case jit_code_getarg_c: case jit_code_getarg_uc:
1420 case jit_code_getarg_s: case jit_code_getarg_us:
1421 case jit_code_getarg_i:
1422 case jit_code_getarg_f: case jit_code_getarg_d:
1423 case jit_code_putargr: case jit_code_putargi:
1424 case jit_code_putargr_f: case jit_code_putargi_f:
1425 case jit_code_putargr_d: case jit_code_putargi_d:
1426 case jit_code_pushargr: case jit_code_pushargi:
1427 case jit_code_pushargr_f: case jit_code_pushargi_f:
1428 case jit_code_pushargr_d: case jit_code_pushargi_d:
1429 case jit_code_retval_c: case jit_code_retval_uc:
1430 case jit_code_retval_s: case jit_code_retval_us:
1431 case jit_code_retval_i:
1432 case jit_code_retval_f: case jit_code_retval_d:
1433 case jit_code_prepare:
1434 case jit_code_finishr: case jit_code_finishi:
1435 break;
1436 default:
1437 abort();
1438 }
1439 jit_regarg_clr(node, value);
1440 assert(_jitc->regarg == 0 && _jitc->synth == 0);
1441 /* update register live state */
1442 jit_reglive(node);
1443 }
1444#undef case_brf
1445#undef case_brw
1446#undef case_brr
1447#undef case_wrr
1448#undef case_rrf
1449#undef case_rrrw
1450#undef case_rrw
1451#undef case_rrrr
1452#undef case_rrr
1453#undef case_wr
1454#undef case_rw
1455#undef case_rr
1456
1457 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1458 node = _jitc->patches.ptr[offset].node;
1459 word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1460 patch_at(_jitc->patches.ptr[offset].inst, word);
1461 }
1462
1463 jit_flush(_jit->code.ptr, _jit->pc.uc);
1464
1465 return (_jit->code.ptr);
1466}
1467
1468#define CODE 1
1469# include "jit_hppa-cpu.c"
1470# include "jit_hppa-fpu.c"
ba3814c1 1471# include "jit_fallback.c"
4a71579b
PC
1472#undef CODE
1473
1474void
1475jit_flush(void *fptr, void *tptr)
1476{
1477 jit_word_t f, t, s;
1478 s = sysconf(_SC_PAGE_SIZE);
1479 f = (jit_word_t)fptr & -s;
1480 t = (((jit_word_t)tptr) + s - 1) & -s;
1481#if defined(__hppa)
1482/* --- parisc2.0.pdf ---
1483 Programming Note
1484
1485The minimum spacing that is guaranteed to work for "self-modifying code" is
1486shown in the code segment below. Since instruction prefetching is permitted,
1487any data cache flushes must be separated from any instruction cache flushes
1488by a SYNC. This will ensure that the "new" instruction will be written to
1489memory prior to any attempts at prefetching it as an instruction.
1490
1491 LDIL l%newinstr,rnew
1492 LDW r%newinstr(0,rnew),temp
1493 LDIL l%instr,rinstr
1494 STW temp,r%instr(0,rinstr)
1495 FDC r%instr(0,rinstr)
1496 SYNC
1497 FIC r%instr(rinstr)
1498 SYNC
1499 instr ...
1500 (at least seven instructions)
1501
1502This sequence assumes a uniprocessor system. In a multiprocessor system,
1503software must ensure no processor is executing code which is in the process
1504of being modified.
1505*/
1506
1507/*
1508 Adapted from ffcall/trampoline/cache-hppa.c:__TR_clear_cache to
1509loop over addresses as it is unlikely from and to addresses would fit in
1510at most two cachelines.
1511 FIXME A cache line can be 16, 32, or 64 bytes.
1512 */
1513 /*
1514 * Copyright 1995-1997 Bruno Haible, <bruno@clisp.org>
1515 *
1516 * This is free software distributed under the GNU General Public Licence
1517 * described in the file COPYING. Contact the author if you don't have this
1518 * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
1519 * on this software.
1520 */
1521 {
1522 jit_word_t n = f + 32;
1523 register int u, v;
1524 for (; f <= t; n = f + 32, f += 64) {
1525 asm volatile ("fdc 0(0,%0)"
1526 "\n\t" "fdc 0(0,%1)"
1527 "\n\t" "sync"
1528 :
1529 : "r" (f), "r" (n)
1530 );
1531 asm volatile ("mfsp %%sr0,%1"
1532 "\n\t" "ldsid (0,%4),%0"
1533 "\n\t" "mtsp %0,%%sr0"
1534 "\n\t" "fic 0(%%sr0,%2)"
1535 "\n\t" "fic 0(%%sr0,%3)"
1536 "\n\t" "sync"
1537 "\n\t" "mtsp %1,%%sr0"
1538 "\n\t" "nop"
1539 "\n\t" "nop"
1540 "\n\t" "nop"
1541 "\n\t" "nop"
1542 "\n\t" "nop"
1543 "\n\t" "nop"
1544 : "=r" (u), "=r" (v)
1545 : "r" (f), "r" (n), "r" (f)
1546 );
1547 }
1548 }
1549#else
1550 /* This is supposed to work but appears to fail on multiprocessor systems */
1551 __clear_cache((void *)f, (void *)t);
1552#endif
1553}
1554
1555void
1556_emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0)
1557{
1558 ldxi(rn(r0), rn(r1), i0);
1559}
1560
1561void
1562_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1)
1563{
1564 stxi(i0, rn(r0), rn(r1));
1565}
1566
1567void
1568_emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0)
1569{
1570 ldxi_d(rn(r0), rn(r1), i0);
1571}
1572
1573void
1574_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1)
1575{
1576 stxi_d(i0, rn(r0), rn(r1));
1577}
1578
1579static void
1580_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
1581{
1582 jit_int32_t flag;
1583
1584 assert(node->flag & jit_flag_node);
1585 if (node->code == jit_code_movi)
1586 flag = node->v.n->flag;
1587 else
1588 flag = node->u.n->flag;
1589 assert(!(flag & jit_flag_patch));
1590 if (_jitc->patches.offset >= _jitc->patches.length) {
1591 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
1592 _jitc->patches.length * sizeof(jit_patch_t),
1593 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
1594 _jitc->patches.length += 1024;
1595 }
1596 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
1597 _jitc->patches.ptr[_jitc->patches.offset].node = node;
1598 ++_jitc->patches.offset;
1599}