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