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