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