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