243e677c8a6efb335174314e559e6ef4bd621dd8
[pcsx_rearmed.git] / deps / lightning / lib / jit_aarch64.c
1 /*
2  * Copyright (C) 2013-2023  Free Software Foundation, Inc.
3  *
4  * This file is part of GNU lightning.
5  *
6  * GNU lightning is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * GNU lightning is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14  * License for more details.
15  *
16  * Authors:
17  *      Paulo Cesar Pereira de Andrade
18  */
19
20 /* callee save
21  * align16(lr+fp+x19+x2[0-8]+v8+v9+v1[0-15]) */
22 #define stack_framesize                 160
23
24 #define jit_arg_reg_p(i)                ((i) >= 0 && (i) < 8)
25 #define jit_arg_f_reg_p(i)              ((i) >= 0 && (i) < 8)
26
27 #if __APPLE__
28 typedef jit_pointer_t jit_va_list_t;
29 #else
30 typedef struct jit_qreg {
31     jit_float64_t       l;
32     jit_float64_t       h;
33 } jit_qreg_t;
34
35 #define va_gp_top_offset                offsetof(jit_va_list_t, q0)
36 #define va_fp_top_offset                sizeof(jit_va_list_t)
37 typedef struct jit_va_list {
38     jit_pointer_t       stack;
39     jit_pointer_t       gptop;
40     jit_pointer_t       fptop;
41     jit_int32_t         gpoff;
42     jit_int32_t         fpoff;
43
44     jit_int64_t         x0;
45     jit_int64_t         x1;
46     jit_int64_t         x2;
47     jit_int64_t         x3;
48     jit_int64_t         x4;
49     jit_int64_t         x5;
50     jit_int64_t         x6;
51     jit_int64_t         x7;
52
53     jit_qreg_t          q0;
54     jit_qreg_t          q1;
55     jit_qreg_t          q2;
56     jit_qreg_t          q3;
57     jit_qreg_t          q4;
58     jit_qreg_t          q5;
59     jit_qreg_t          q6;
60     jit_qreg_t          q7;
61 } jit_va_list_t;
62 #endif
63
64 /*
65  * Prototypes
66  */
67 #define compute_framesize()             _compute_framesize(_jit)
68 static void _compute_framesize(jit_state_t*);
69 #define patch(instr, node)              _patch(_jit, instr, node)
70 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
71
72 /* libgcc */
73 extern void __clear_cache(void *, void *);
74
75 #define PROTO                           1
76 #  include "jit_aarch64-cpu.c"
77 #  include "jit_aarch64-fpu.c"
78 #undef PROTO
79
80 /*
81  * Initialization
82  */
83 jit_register_t          _rvs[] = {
84     { rc(gpr) | 0x08,                   "x8" },
85 #if __APPLE__
86     { 0x12,                             "x18" },
87 #else
88     { rc(gpr) | 0x12,                   "x18" },
89 #endif
90     { rc(gpr) | 0x11,                   "x17" },
91     { rc(gpr) | 0x10,                   "x16" },
92     { rc(gpr) | 0x09,                   "x9" },
93     { rc(gpr) | 0x0a,                   "x10" },
94     { rc(gpr) | 0x0b,                   "x11" },
95     { rc(gpr) | 0x0c,                   "x12" },
96     { rc(gpr) | 0x0d,                   "x13" },
97     { rc(gpr) | 0x0e,                   "x14" },
98     { rc(gpr) | 0x0f,                   "x15" },
99     { rc(sav) | rc(gpr) | 0x13,         "x19" },
100     { rc(sav) | rc(gpr) | 0x14,         "x20" },
101     { rc(sav) | rc(gpr) | 0x15,         "x21" },
102     { rc(sav) | rc(gpr) | 0x16,         "x22" },
103     { rc(sav) | rc(gpr) | 0x17,         "x23" },
104     { rc(sav) | rc(gpr) | 0x18,         "x24" },
105     { rc(sav) | rc(gpr) | 0x19,         "x25" },
106     { rc(sav) | rc(gpr) | 0x1a,         "x26" },
107     { rc(sav) | rc(gpr) | 0x1b,         "x27" },
108     { rc(sav) | rc(gpr) | 0x1c,         "x28" },
109     { 0x1f,                             "sp" },
110     { 0x1e,                             "lr" },
111     { 0x1d,                             "fp" },
112     { rc(arg) | rc(gpr) | 0x07,         "x7" },
113     { rc(arg) | rc(gpr) | 0x06,         "x6" },
114     { rc(arg) | rc(gpr) | 0x05,         "x5" },
115     { rc(arg) | rc(gpr) | 0x04,         "x4" },
116     { rc(arg) | rc(gpr) | 0x03,         "x3" },
117     { rc(arg) | rc(gpr) | 0x02,         "x2" },
118     { rc(arg) | rc(gpr) | 0x01,         "x1" },
119     { rc(arg) | rc(gpr) | 0x00,         "x0" },
120     { rc(fpr) | 0x1f,                   "v31" },
121     { rc(fpr) | 0x1e,                   "v30" },
122     { rc(fpr) | 0x1d,                   "v29" },
123     { rc(fpr) | 0x1c,                   "v28" },
124     { rc(fpr) | 0x1b,                   "v27" },
125     { rc(fpr) | 0x1a,                   "v26" },
126     { rc(fpr) | 0x19,                   "v25" },
127     { rc(fpr) | 0x18,                   "v24" },
128     { rc(fpr) | 0x17,                   "v23" },
129     { rc(fpr) | 0x16,                   "v22" },
130     { rc(fpr) | 0x15,                   "v21" },
131     { rc(fpr) | 0x14,                   "v20" },
132     { rc(fpr) | 0x13,                   "v19" },
133     { rc(fpr) | 0x12,                   "v18" },
134     { rc(fpr) | 0x11,                   "v17" },
135     { rc(fpr) | 0x10,                   "v16" },
136     { rc(sav) | rc(fpr) | 0x08,         "v8" },
137     { rc(sav) | rc(fpr) | 0x09,         "v9" },
138     { rc(sav) | rc(fpr) | 0x0a,         "v10" },
139     { rc(sav) | rc(fpr) | 0x0b,         "v11" },
140     { rc(sav) | rc(fpr) | 0x0c,         "v12" },
141     { rc(sav) | rc(fpr) | 0x0d,         "v13" },
142     { rc(sav) | rc(fpr) | 0x0e,         "v14" },
143     { rc(sav) | rc(fpr) | 0x0f,         "v15" },
144     { rc(arg) | rc(fpr) | 0x07,         "v7" },
145     { rc(arg) | rc(fpr) | 0x06,         "v6" },
146     { rc(arg) | rc(fpr) | 0x05,         "v5" },
147     { rc(arg) | rc(fpr) | 0x04,         "v4" },
148     { rc(arg) | rc(fpr) | 0x03,         "v3" },
149     { rc(arg) | rc(fpr) | 0x02,         "v2" },
150     { rc(arg) | rc(fpr) | 0x01,         "v1" },
151     { rc(arg) | rc(fpr) | 0x00,         "v0" },
152     { _NOREG,                           "<none>" },
153 };
154
155 static jit_int32_t iregs[] = {
156     _R19, _R20, _R21, _R22, _R23, _R24, _R25, _R26, _R27, _R28
157 };
158
159 static jit_int32_t fregs[] = {
160     _V8, _V9, _V10, _V11, _V12, _V13, _V14, _V15
161 };
162
163 /*
164  * Implementation
165  */
166 void
167 jit_get_cpu(void)
168 {
169 }
170
171 void
172 _jit_init(jit_state_t *_jit)
173 {
174     _jitc->reglen = jit_size(_rvs) - 1;
175 }
176
177 void
178 _jit_prolog(jit_state_t *_jit)
179 {
180     jit_int32_t          offset;
181
182     if (_jitc->function)
183         jit_epilog();
184     assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
185     jit_regset_set_ui(&_jitc->regsav, 0);
186     offset = _jitc->functions.offset;
187     if (offset >= _jitc->functions.length) {
188         jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
189                     _jitc->functions.length * sizeof(jit_function_t),
190                     (_jitc->functions.length + 16) * sizeof(jit_function_t));
191         _jitc->functions.length += 16;
192     }
193     _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
194     _jitc->function->self.size = stack_framesize;
195     _jitc->function->self.argi = _jitc->function->self.argf =
196         _jitc->function->self.alen = 0;
197     _jitc->function->self.aoff = 0;
198     _jitc->function->self.call = jit_call_default;
199     jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
200               _jitc->reglen * sizeof(jit_int32_t));
201
202     /* _no_link here does not mean the jit_link() call can be removed
203      * by rewriting as:
204      * _jitc->function->prolog = jit_new_node(jit_code_prolog);
205      */
206     _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
207     jit_link(_jitc->function->prolog);
208     _jitc->function->prolog->w.w = offset;
209     _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
210     /*  u:      label value
211      *  v:      offset in blocks vector
212      *  w:      offset in functions vector
213      */
214     _jitc->function->epilog->w.w = offset;
215
216     jit_regset_new(&_jitc->function->regset);
217 }
218
219 jit_int32_t
220 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
221 {
222     assert(_jitc->function);
223     jit_check_frame();
224     switch (length) {
225         case 0: case 1:                                         break;
226         case 2:         _jitc->function->self.aoff &= -2;       break;
227         case 3: case 4: _jitc->function->self.aoff &= -4;       break;
228         default:        _jitc->function->self.aoff &= -8;       break;
229     }
230     _jitc->function->self.aoff -= length;
231     if (!_jitc->realize) {
232         jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
233         jit_dec_synth();
234     }
235     return (_jitc->function->self.aoff);
236 }
237
238 void
239 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
240 {
241     jit_int32_t          r0, r1;
242     assert(_jitc->function);
243     jit_inc_synth_ww(allocar, u, v);
244     if (!_jitc->function->allocar) {
245         _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
246         _jitc->function->allocar = 1;
247     }
248     r0 = jit_get_reg(jit_class_gpr);
249     jit_negr(r0, v);
250     jit_andi(r0, r0, -16);
251     jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
252     jit_addr(u, u, r0);
253     /* Cannot "addr sp, sp, reg" because in this context "sp" is "[w|x]zr",
254      * the zero register */
255 #if 0
256     jit_addr(JIT_SP, JIT_SP, r0);
257 #else
258     r1 = jit_get_reg(jit_class_gpr);
259     /* note that "mov r1, sp" does not work, but the proper encoding
260      * can be triggered before actually emiting with "add r1, sp, 0" */
261     jit_addi(r1, JIT_SP, 0);
262     jit_addr(r1, r1, r0);
263     jit_addi(JIT_SP, r1, 0);
264     jit_unget_reg(r1);
265 #endif
266     jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
267     jit_unget_reg(r0);
268     jit_dec_synth();
269 }
270
271 void
272 _jit_ret(jit_state_t *_jit)
273 {
274     jit_node_t          *instr;
275     assert(_jitc->function);
276     jit_inc_synth(ret);
277     /* jump to epilog */
278     instr = jit_jmpi();
279     jit_patch_at(instr, _jitc->function->epilog);
280     jit_dec_synth();
281 }
282
283 void
284 _jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
285 {
286     jit_code_inc_synth_w(code, u);
287     jit_movr(JIT_RET, u);
288     jit_ret();
289     jit_dec_synth();
290 }
291
292 void
293 _jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
294 {
295     jit_code_inc_synth_w(code, u);
296     jit_movi(JIT_RET, u);
297     jit_ret();
298     jit_dec_synth();
299 }
300
301 void
302 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
303 {
304     jit_inc_synth_w(retr_f, u);
305     if (u != JIT_FRET)
306         jit_movr_f(JIT_FRET, u);
307     else
308         jit_live(JIT_FRET);
309     jit_ret();
310     jit_dec_synth();
311 }
312
313 void
314 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
315 {
316     jit_inc_synth_f(reti_f, u);
317     jit_movi_f(JIT_FRET, u);
318     jit_ret();
319     jit_dec_synth();
320 }
321
322 void
323 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
324 {
325     jit_inc_synth_w(retr_d, u);
326     if (u != JIT_FRET)
327         jit_movr_d(JIT_FRET, u);
328     else
329         jit_live(JIT_FRET);
330     jit_ret();
331     jit_dec_synth();
332 }
333
334 void
335 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
336 {
337     jit_inc_synth_d(reti_d, u);
338     jit_movi_d(JIT_FRET, u);
339     jit_ret();
340     jit_dec_synth();
341 }
342
343 void
344 _jit_epilog(jit_state_t *_jit)
345 {
346     assert(_jitc->function);
347     assert(_jitc->function->epilog->next == NULL);
348     jit_link(_jitc->function->epilog);
349     _jitc->function = NULL;
350 }
351
352 jit_bool_t
353 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
354 {
355     if (u->code >= jit_code_arg_c && u->code <= jit_code_arg)
356         return (jit_arg_reg_p(u->u.w));
357     assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
358     return (jit_arg_f_reg_p(u->u.w));
359 }
360
361 void
362 _jit_ellipsis(jit_state_t *_jit)
363 {
364     jit_inc_synth(ellipsis);
365     jit_check_frame();
366     if (_jitc->prepare) {
367         jit_link_prepare();
368         assert(!(_jitc->function->call.call & jit_call_varargs));
369         _jitc->function->call.call |= jit_call_varargs;
370     }
371     else {
372         jit_link_prolog();
373         assert(!(_jitc->function->self.call & jit_call_varargs));
374         _jitc->function->self.call |= jit_call_varargs;
375
376 #if !__APPLE_
377         /* Allocate va_list like object in the stack,
378          * with enough space to save all argument
379          * registers, and use fixed offsets for them. */
380         _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
381
382         /* Initialize gp offset in save area. */
383         if (jit_arg_reg_p(_jitc->function->self.argi))
384             _jitc->function->vagp = (8 - _jitc->function->self.argi) * -8;
385         else
386             _jitc->function->vagp = 0;
387
388         /* Initialize fp offset in save area. */
389         if (jit_arg_f_reg_p(_jitc->function->self.argf))
390             _jitc->function->vafp = (8 - _jitc->function->self.argf) * -16;
391         else
392             _jitc->function->vafp = 0;
393 #endif
394     }
395     jit_dec_synth();
396 }
397
398 void
399 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
400 {
401     jit_inc_synth_w(va_push, u);
402     jit_pushargr(u);
403     jit_dec_synth();
404 }
405
406 jit_node_t *
407 _jit_arg(jit_state_t *_jit, jit_code_t code)
408 {
409     jit_node_t          *node;
410     jit_int32_t          offset;
411     assert(_jitc->function);
412     assert(!(_jitc->function->self.call & jit_call_varargs));
413     if (jit_arg_reg_p(_jitc->function->self.argi))
414         offset = _jitc->function->self.argi++;
415     else {
416 #if PACKED_STACK || STRONG_TYPE_CHECKING
417         assert(code >= jit_code_arg_c && code <= jit_code_arg);
418 #endif
419 #if PACKED_STACK
420         _jitc->function->self.size +=
421             _jitc->function->self.size & ((1 << (code - jit_code_arg_c)) - 1);
422 #endif
423         offset = _jitc->function->self.size;
424 #if PACKED_STACK
425         _jitc->function->self.size += 1 << (code - jit_code_arg_c);
426 #else
427         _jitc->function->self.size += sizeof(jit_word_t);
428 #endif
429         jit_check_frame();
430     }
431     node = jit_new_node_ww(code, offset,
432                            ++_jitc->function->self.argn);
433     jit_link_prolog();
434     return (node);
435 }
436
437 jit_node_t *
438 _jit_arg_f(jit_state_t *_jit)
439 {
440     jit_node_t          *node;
441     jit_int32_t          offset;
442     assert(_jitc->function);
443     assert(!(_jitc->function->self.call & jit_call_varargs));
444     if (jit_arg_f_reg_p(_jitc->function->self.argf))
445         offset = _jitc->function->self.argf++;
446     else {
447 #if PACKED_STACK
448         _jitc->function->self.size +=
449             _jitc->function->self.size & (sizeof(jit_float32_t) - 1);
450 #endif
451         offset = _jitc->function->self.size;
452 #if PACKED_STACK
453         _jitc->function->self.size += sizeof(jit_float32_t);
454 #else
455         _jitc->function->self.size += sizeof(jit_word_t);
456 #endif
457         jit_check_frame();
458     }
459     node = jit_new_node_ww(jit_code_arg_f, offset,
460                            ++_jitc->function->self.argn);
461     jit_link_prolog();
462     return (node);
463 }
464
465 jit_node_t *
466 _jit_arg_d(jit_state_t *_jit)
467 {
468     jit_node_t          *node;
469     jit_int32_t          offset;
470     assert(_jitc->function);
471     assert(!(_jitc->function->self.call & jit_call_varargs));
472     if (jit_arg_f_reg_p(_jitc->function->self.argf))
473         offset = _jitc->function->self.argf++;
474     else {
475 #if PACKED_STACK
476         _jitc->function->self.size +=
477             _jitc->function->self.size & (sizeof(jit_float64_t) - 1);
478 #endif
479         offset = _jitc->function->self.size;
480         _jitc->function->self.size += sizeof(jit_float64_t);
481         jit_check_frame();
482     }
483     node = jit_new_node_ww(jit_code_arg_d, offset,
484                            ++_jitc->function->self.argn);
485     jit_link_prolog();
486     return (node);
487 }
488
489 void
490 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
491 {
492     assert_arg_type(v->code, jit_code_arg_c);
493     jit_inc_synth_wp(getarg_c, u, v);
494     if (jit_arg_reg_p(v->u.w)) {
495 #if PACKED_STACK
496         jit_movr(u, JIT_RA0 - v->u.w);
497 #else
498         jit_extr_c(u, JIT_RA0 - v->u.w);
499 #endif
500     }
501     else {
502         jit_node_t      *node = jit_ldxi_c(u, JIT_FP, v->u.w);
503         jit_link_alist(node);
504     }
505     jit_dec_synth();
506 }
507
508 void
509 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
510 {
511     assert_arg_type(v->code, jit_code_arg_c);
512     jit_inc_synth_wp(getarg_uc, u, v);
513     if (jit_arg_reg_p(v->u.w)) {
514 #if PACKED_STACK
515         jit_movr(u, JIT_RA0 - v->u.w);
516 #else
517         jit_extr_uc(u, JIT_RA0 - v->u.w);
518 #endif
519     }
520     else {
521         jit_node_t      *node = jit_ldxi_uc(u, JIT_FP, v->u.w);
522         jit_link_alist(node);
523     }
524     jit_dec_synth();
525 }
526
527 void
528 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
529 {
530     assert_arg_type(v->code, jit_code_arg_s);
531     jit_inc_synth_wp(getarg_s, u, v);
532     if (jit_arg_reg_p(v->u.w)) {
533 #if PACKED_STACK
534         jit_movr(u, JIT_RA0 - v->u.w);
535 #else
536         jit_extr_s(u, JIT_RA0 - v->u.w);
537 #endif
538     }
539     else {
540         jit_node_t      *node = jit_ldxi_s(u, JIT_FP, v->u.w);
541         jit_link_alist(node);
542     }
543     jit_dec_synth();
544 }
545
546 void
547 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
548 {
549     assert_arg_type(v->code, jit_code_arg_s);
550     jit_inc_synth_wp(getarg_us, u, v);
551     if (jit_arg_reg_p(v->u.w)) {
552 #if PACKED_STACK
553         jit_movr(u, JIT_RA0 - v->u.w);
554 #else
555         jit_extr_us(u, JIT_RA0 - v->u.w);
556 #endif
557     }
558     else {
559         jit_node_t      *node = jit_ldxi_us(u, JIT_FP, v->u.w);
560         jit_link_alist(node);
561     }
562     jit_dec_synth();
563 }
564
565 void
566 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
567 {
568     assert_arg_type(v->code, jit_code_arg_i);
569     jit_inc_synth_wp(getarg_i, u, v);
570     if (jit_arg_reg_p(v->u.w)) {
571 #if PACKED_STACK || __WORDSIZE == 32
572         jit_movr(u, JIT_RA0 - v->u.w);
573 #else
574         jit_extr_i(u, JIT_RA0 - v->u.w);
575 #endif
576     }
577     else {
578         jit_node_t      *node = jit_ldxi_i(u, JIT_FP, v->u.w);
579         jit_link_alist(node);
580     }
581     jit_dec_synth();
582 }
583
584 #if __WORDSIZE == 64
585 void
586 _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
587 {
588     assert_arg_type(v->code, jit_code_arg_i);
589     jit_inc_synth_wp(getarg_ui, u, v);
590     if (jit_arg_reg_p(v->u.w)) {
591 #if PACKED_STACK
592         jit_movr(u, JIT_RA0 - v->u.w);
593 #else
594         jit_extr_ui(u, JIT_RA0 - v->u.w);
595 #endif
596     }
597     else {
598         jit_node_t      *node = jit_ldxi_ui(u, JIT_FP, v->u.w);
599         jit_link_alist(node);
600     }
601     jit_dec_synth();
602 }
603
604 void
605 _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
606 {
607     assert_arg_type(v->code, jit_code_arg_l);
608     jit_inc_synth_wp(getarg_l, u, v);
609     if (jit_arg_reg_p(v->u.w))
610         jit_movr(u, JIT_RA0 - v->u.w);
611     else {
612         jit_node_t      *node = jit_ldxi_l(u, JIT_FP, v->u.w);
613         jit_link_alist(node);
614     }
615     jit_dec_synth();
616 }
617 #endif
618
619 void
620 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
621 {
622     assert_putarg_type(code, v->code);
623     jit_code_inc_synth_wp(code, u, v);
624     if (jit_arg_reg_p(v->u.w)) {
625         jit_int32_t     regno = JIT_RA0 - v->u.w;
626 #if PACKED_STACK
627         switch (code) {
628             case jit_code_putargr_c:    jit_extr_c(regno, u);   break;
629             case jit_code_putargr_uc:   jit_extr_uc(regno, u);  break;
630             case jit_code_putargr_s:    jit_extr_s(regno, u);   break;
631             case jit_code_putargr_us:   jit_extr_us(regno, u);  break;
632 #  if __WORDISZE == 32
633             case jit_code_putargr_i:    jit_movr(regno, u);     break;
634 #  else
635             case jit_code_putargr_i:    jit_extr_i(regno, u);   break;
636             case jit_code_putargr_ui:   jit_extr_ui(regno, u);  break;
637             case jit_code_putargr_l:    jit_movr(regno, u);     break;
638 #  endif
639             default:                    abort();                break;
640         }
641 #else
642         jit_movr(regno, u);
643 #endif
644     }
645     else {
646         jit_node_t      *node;
647 #if PACKED_STACK
648         switch (code) {
649             case jit_code_putargr_c:    case jit_code_putargr_uc:
650                 node = jit_stxi_c(v->u.w, JIT_FP, u);           break;
651             case jit_code_putargr_s:    case jit_code_putargr_us:
652                 node = jit_stxi_s(v->u.w, JIT_FP, u);           break;
653 #  if __WORDSIZE == 32
654             case jit_code_putargr_i:
655                 node = jit_stxi(v->u.w, JIT_FP, u);             break;
656 #  else
657             case jit_code_putargr_i:    case jit_code_putargr_ui:
658                 node = jit_stxi_i(v->u.w, JIT_FP, u);           break;
659             case jit_code_putargr_l:
660                 node = jit_stxi(v->u.w, JIT_FP, u);             break;
661 #  endif
662             default:                    abort();                break;
663         }
664 #else
665         node = jit_stxi(v->u.w, JIT_FP, u);
666 #endif
667         jit_link_alist(node);
668     }
669     jit_dec_synth();
670 }
671
672 void
673 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
674 {
675     jit_int32_t         regno;
676     assert_putarg_type(code, v->code);
677     jit_code_inc_synth_wp(code, u, v);
678 #if PACKED_STACK
679     switch (code) {
680         case jit_code_putargi_c:        u = (jit_int8_t)u;      break;
681         case jit_code_putargi_uc:       u = (jit_uint8_t)u;     break;
682         case jit_code_putargi_s:        u = (jit_int16_t)u;     break;
683         case jit_code_putargi_us:       u = (jit_uint16_t)u;    break;
684 #  if __WORDSIZE == 32
685         case jit_code_putargi_i:                                break;
686 #  else
687         case jit_code_putargi_i:        u = (jit_int32_t)u;     break;
688         case jit_code_putargi_ui:       u = (jit_uint32_t)u;    break;
689         case jit_code_putargi_l:                                break;
690 #  endif
691         default:                        abort();                break;
692     }
693 #endif
694     if (jit_arg_reg_p(v->u.w))
695         jit_movi(JIT_RA0 - v->u.w, u);
696     else {
697         jit_node_t      *node;
698         regno = jit_get_reg(jit_class_gpr);
699         jit_movi(regno, u);
700 #if PACKED_STACK
701         switch (code) {
702             case jit_code_putargi_c:    case jit_code_putargi_uc:
703                 node = jit_stxi_c(v->u.w, JIT_FP, regno);       break;
704             case jit_code_putargi_s:    case jit_code_putargi_us:
705                 node = jit_stxi_s(v->u.w, JIT_FP, regno);       break;
706 #  if __WORDSIZE == 32
707             case jit_code_putargi_i:
708                 node = jit_stxi(v->u.w, JIT_FP, regno);         break;
709 #  else
710             case jit_code_putargi_i:    case jit_code_putargi_ui:
711                 node = jit_stxi_i(v->u.w, JIT_FP, regno);       break;
712             case jit_code_putargi_l:
713                 node = jit_stxi(v->u.w, JIT_FP, regno);         break;
714 #  endif
715             default:                    abort();                break;
716         }
717 #else
718         node = jit_stxi(v->u.w, JIT_FP, regno);
719 #endif
720         jit_link_alist(node);
721         jit_unget_reg(regno);
722     }
723     jit_dec_synth();
724 }
725
726 void
727 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
728 {
729     assert(v->code == jit_code_arg_f);
730     jit_inc_synth_wp(getarg_f, u, v);
731     if (jit_arg_reg_p(v->u.w))
732         jit_movr_f(u, JIT_FA0 - v->u.w);
733     else {
734         jit_node_t      *node = jit_ldxi_f(u, JIT_FP, v->u.w);
735         jit_link_alist(node);
736     }
737     jit_dec_synth();
738 }
739
740 void
741 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
742 {
743     assert(v->code == jit_code_arg_f);
744     jit_inc_synth_wp(putargr_f, u, v);
745     if (jit_arg_f_reg_p(v->u.w))
746         jit_movr_f(JIT_FA0 - v->u.w, u);
747     else {
748         jit_node_t      *node = jit_stxi_f(v->u.w, JIT_FP, u);
749         jit_link_alist(node);
750     }
751     jit_dec_synth();
752 }
753
754 void
755 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
756 {
757     jit_int32_t         regno;
758     assert(v->code == jit_code_arg_f);
759     jit_inc_synth_fp(putargi_f, u, v);
760     if (jit_arg_f_reg_p(v->u.w))
761         jit_movi_f(JIT_FA0 - v->u.w, u);
762     else {
763         jit_node_t      *node;
764         regno = jit_get_reg(jit_class_fpr);
765         jit_movi_f(regno, u);
766         node = jit_stxi_f(v->u.w, JIT_FP, regno);
767         jit_link_alist(node);
768         jit_unget_reg(regno);
769     }
770     jit_dec_synth();
771 }
772
773 void
774 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
775 {
776     assert(v->code == jit_code_arg_d);
777     jit_inc_synth_wp(getarg_d, u, v);
778     if (jit_arg_f_reg_p(v->u.w))
779         jit_movr_d(u, JIT_FA0 - v->u.w);
780     else {
781         jit_node_t      *node = jit_ldxi_d(u, JIT_FP, v->u.w);
782         jit_link_alist(node);
783     }
784     jit_dec_synth();
785 }
786
787 void
788 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
789 {
790     assert(v->code == jit_code_arg_d);
791     jit_inc_synth_wp(putargr_d, u, v);
792     if (jit_arg_reg_p(v->u.w))
793         jit_movr_d(JIT_FA0 - v->u.w, u);
794     else {
795         jit_node_t      *node = jit_stxi_d(v->u.w, JIT_FP, u);
796         jit_link_alist(node);
797     }
798     jit_dec_synth();
799 }
800
801 void
802 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
803 {
804     jit_int32_t         regno;
805     assert(v->code == jit_code_arg_d);
806     jit_inc_synth_dp(putargi_d, u, v);
807     if (jit_arg_reg_p(v->u.w))
808         jit_movi_d(JIT_FA0 - v->u.w, u);
809     else {
810         jit_node_t      *node;
811         regno = jit_get_reg(jit_class_fpr);
812         jit_movi_d(regno, u);
813         node = jit_stxi_d(v->u.w, JIT_FP, regno);
814         jit_link_alist(node);
815         jit_unget_reg(regno);
816     }
817     jit_dec_synth();
818 }
819
820 void
821 _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
822 {
823     assert(_jitc->function);
824     jit_code_inc_synth_w(code, u);
825     jit_link_prepare();
826     if (jit_arg_reg_p(_jitc->function->call.argi)) {
827         jit_int32_t     regno = JIT_RA0 - _jitc->function->call.argi;
828 #if PACKED_STACK
829         switch (code) {
830             case jit_code_pushargr_c:   jit_extr_c(regno, u);   break;
831             case jit_code_pushargr_uc:  jit_extr_uc(regno, u);  break;
832             case jit_code_pushargr_s:   jit_extr_s(regno, u);   break;
833             case jit_code_pushargr_us:  jit_extr_us(regno, u);  break;
834 #  if __WORDISZE == 32
835             case jit_code_pushargr_i:   jit_movr(regno, u);     break;
836 #  else
837             case jit_code_pushargr_i:   jit_extr_i(regno, u);   break;
838             case jit_code_pushargr_ui:  jit_extr_ui(regno, u);  break;
839             case jit_code_pushargr_l:   jit_movr(regno, u);     break;
840 #  endif
841             default:                    abort();                break;
842         }
843 #else
844         jit_movr(regno, u);
845 #endif
846 #if __APPLE__
847         if (_jitc->function->call.call & jit_call_varargs) {
848             assert(code == jit_code_pushargr);
849             jit_stxi(_jitc->function->call.size, JIT_SP, u);
850             _jitc->function->call.size += sizeof(jit_word_t);
851         }
852 #endif
853         ++_jitc->function->call.argi;
854     }
855     else {
856 #if PACKED_STACK
857         _jitc->function->call.size +=
858             _jitc->function->call.size &
859                 ((1 << ((code - jit_code_pushargr_c) >> 2)) - 1);
860         switch (code) {
861             case jit_code_pushargr_c:   case jit_code_pushargr_uc:
862                 jit_stxi_c(_jitc->function->call.size, JIT_SP, u);
863                 break;
864             case jit_code_pushargr_s:   case jit_code_pushargr_us:
865                 jit_stxi_s(_jitc->function->call.size, JIT_SP, u);
866                 break;
867 #  if __WORDSIZE == 32
868             case jit_code_pushargr_i:
869                 jit_stxi(_jitc->function->call.size, JIT_SP, u);
870                 break;
871 #  else
872             case jit_code_pushargr_i:   case jit_code_pushargr_ui:
873                 jit_stxi_i(_jitc->function->call.size, JIT_SP, u);
874                 break;
875             case jit_code_pushargr_l:
876                 jit_stxi(_jitc->function->call.size, JIT_SP, u);
877                 break;
878 #  endif
879             default:
880                 abort();
881                 break;
882         }
883         _jitc->function->call.size += 1 << ((code - jit_code_pushargr_c) >> 2);
884 #else
885         jit_stxi(_jitc->function->call.size, JIT_SP, u);
886         _jitc->function->call.size += sizeof(jit_word_t);
887 #endif
888         jit_check_frame();
889     }
890     jit_dec_synth();
891 }
892
893 void
894 _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
895 {
896     jit_int32_t          regno;
897     assert(_jitc->function);
898     jit_code_inc_synth_w(code, u);
899     jit_link_prepare();
900 #if PACKED_STACK
901     switch (code) {
902         case jit_code_pushargi_c:       u = (jit_int8_t)u;      break;
903         case jit_code_pushargi_uc:      u = (jit_uint8_t)u;     break;
904         case jit_code_pushargi_s:       u = (jit_int16_t)u;     break;
905         case jit_code_pushargi_us:      u = (jit_uint16_t)u;    break;
906 #  if __WORDSIZE == 32
907         case jit_code_pushargi_i:                               break;
908 #  else
909         case jit_code_pushargi_i:       u = (jit_int32_t)u;     break;
910         case jit_code_pushargi_ui:      u = (jit_uint32_t)u;    break;
911         case jit_code_pushargi_l:                               break;
912 #  endif
913         default:                        abort();                break;
914     }
915 #endif
916     if (jit_arg_reg_p(_jitc->function->call.argi)) {
917         regno = JIT_RA0 - _jitc->function->call.argi;
918         jit_movi(regno, u);
919 #if __APPLE__
920         if (_jitc->function->call.call & jit_call_varargs) {
921             assert(code == jit_code_pushargi);
922             jit_stxi(_jitc->function->call.size, JIT_SP, regno);
923             _jitc->function->call.size += sizeof(jit_word_t);
924         }
925 #endif
926         ++_jitc->function->call.argi;
927     }
928     else {
929         regno = jit_get_reg(jit_class_gpr);
930         jit_movi(regno, u);
931 #if PACKED_STACK
932         _jitc->function->call.size +=
933             _jitc->function->call.size &
934                 ((1 << ((code - jit_code_pushargr_c) >> 2)) - 1);
935         switch (code) {
936             case jit_code_pushargi_c:   case jit_code_pushargi_uc:
937                 jit_stxi_c(_jitc->function->call.size, JIT_SP, regno);
938                 break;
939             case jit_code_pushargi_s:   case jit_code_pushargi_us:
940                 jit_stxi_s(_jitc->function->call.size, JIT_SP, regno);
941                 break;
942 #  if __WORDSIZE == 32
943             case jit_code_pushargi_i:
944                 jit_stxi(_jitc->function->call.size, JIT_SP, regno);
945                 break;
946 #  else
947             case jit_code_pushargi_i:   case jit_code_pushargi_ui:
948                 jit_stxi_i(_jitc->function->call.size, JIT_SP, regno);
949                 break;
950             case jit_code_pushargi_l:
951                 jit_stxi(_jitc->function->call.size, JIT_SP, regno);
952                 break;
953 #  endif
954             default:
955                 abort();
956                 break;
957         }
958         _jitc->function->call.size += 1 << ((code - jit_code_pushargr_c) >> 2);
959 #else
960         jit_stxi(_jitc->function->call.size, JIT_SP, regno);
961         _jitc->function->call.size += sizeof(jit_word_t);
962 #endif
963         jit_unget_reg(regno);
964         jit_check_frame();
965     }
966     jit_dec_synth();
967 }
968
969 void
970 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
971 {
972     assert(_jitc->function);
973     jit_inc_synth_w(pushargr_f, u);
974     jit_link_prepare();
975     if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
976         jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u);
977 #if __APPLE__
978         if (_jitc->function->call.call & jit_call_varargs) {
979             assert(sizeof(jit_float32_t) == sizeof(jit_word_t));
980             jit_stxi_f(_jitc->function->call.size, JIT_SP,
981                        JIT_FA0 - _jitc->function->call.argf);
982             _jitc->function->call.size += sizeof(jit_word_t);
983         }
984 #endif
985         ++_jitc->function->call.argf;
986     }
987     else {
988 #if PACKED_STACK
989         _jitc->function->call.size +=
990             _jitc->function->call.size & (sizeof(jit_float32_t) - 1);
991         jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
992         _jitc->function->call.size += sizeof(jit_float32_t);
993 #else
994         jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
995         _jitc->function->call.size += sizeof(jit_word_t);
996 #endif
997         jit_check_frame();
998     }
999     jit_dec_synth();
1000 }
1001
1002 void
1003 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
1004 {
1005     jit_int32_t         regno;
1006     assert(_jitc->function);
1007     jit_inc_synth_f(pushargi_f, u);
1008     jit_link_prepare();
1009     if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
1010         jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u);
1011 #if __APPLE__
1012         if (_jitc->function->call.call & jit_call_varargs) {
1013             assert(sizeof(jit_float32_t) == sizeof(jit_word_t));
1014             jit_stxi_f(_jitc->function->call.size, JIT_SP,
1015                        JIT_FA0 - _jitc->function->call.argf);
1016             _jitc->function->call.size += sizeof(jit_word_t);
1017         }
1018 #endif
1019         ++_jitc->function->call.argf;
1020     }
1021     else {
1022         regno = jit_get_reg(jit_class_fpr);
1023         jit_movi_f(regno, u);
1024 #if PACKED_STACK
1025         _jitc->function->call.size +=
1026             _jitc->function->call.size & (sizeof(jit_float32_t) - 1);
1027         jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
1028         _jitc->function->call.size += sizeof(jit_float32_t);
1029 #else
1030         jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
1031         _jitc->function->call.size += sizeof(jit_word_t);
1032 #endif
1033         jit_unget_reg(regno);
1034         jit_check_frame();
1035     }
1036     jit_dec_synth();
1037 }
1038
1039 void
1040 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
1041 {
1042     assert(_jitc->function);
1043     jit_inc_synth_w(pushargr_d, u);
1044     jit_link_prepare();
1045     if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
1046         jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
1047 #if __APPLE__
1048         if (_jitc->function->call.call & jit_call_varargs) {
1049             assert(sizeof(jit_float64_t) == sizeof(jit_word_t));
1050             jit_stxi_d(_jitc->function->call.size, JIT_SP,
1051                        JIT_FA0 - _jitc->function->call.argf);
1052             _jitc->function->call.size += sizeof(jit_float64_t);
1053         }
1054 #endif
1055         ++_jitc->function->call.argf;
1056     }
1057     else {
1058 #if PACKED_STACK
1059         _jitc->function->call.size +=
1060             _jitc->function->call.size & (sizeof(jit_float64_t) - 1);
1061 #endif
1062         jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
1063         _jitc->function->call.size += sizeof(jit_float64_t);
1064         jit_check_frame();
1065     }
1066     jit_dec_synth();
1067 }
1068
1069 void
1070 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
1071 {
1072     jit_int32_t         regno;
1073     assert(_jitc->function);
1074     jit_inc_synth_d(pushargi_d, u);
1075     jit_link_prepare();
1076     if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
1077         jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
1078 #if __APPLE__
1079         if (_jitc->function->call.call & jit_call_varargs) {
1080             assert(sizeof(jit_float64_t) == sizeof(jit_word_t));
1081             jit_stxi_d(_jitc->function->call.size, JIT_SP,
1082                        JIT_FA0 - _jitc->function->call.argf);
1083             _jitc->function->call.size += sizeof(jit_float64_t);
1084         }
1085 #endif
1086         ++_jitc->function->call.argf;
1087     }
1088     else {
1089         regno = jit_get_reg(jit_class_fpr);
1090         jit_movi_d(regno, u);
1091 #if PACKED_STACK
1092         _jitc->function->call.size +=
1093             _jitc->function->call.size & (sizeof(jit_float64_t) - 1);
1094 #endif
1095         jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
1096         jit_unget_reg(regno);
1097         _jitc->function->call.size += sizeof(jit_float64_t);
1098         jit_check_frame();
1099     }
1100     jit_dec_synth();
1101 }
1102
1103 jit_bool_t
1104 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
1105 {
1106     jit_int32_t         spec;
1107     spec = jit_class(_rvs[regno].spec);
1108     if (spec & jit_class_arg) {
1109         regno = JIT_RA0 - regno;
1110         if (regno >= 0 && regno < node->v.w)
1111             return (1);
1112         if (spec & jit_class_fpr) {
1113             regno = JIT_FA0 - regno;
1114             if (regno >= 0 && regno < node->w.w)
1115                 return (1);
1116         }
1117     }
1118
1119     return (0);
1120 }
1121
1122 void
1123 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
1124 {
1125     jit_node_t          *node;
1126     assert(_jitc->function);
1127     jit_check_frame();
1128     jit_inc_synth_w(finishr, r0);
1129 #if PACKED_STACK
1130     _jitc->function->call.size +=
1131         _jitc->function->call.size & (sizeof(jit_word_t) - 1);
1132 #endif
1133     if (_jitc->function->self.alen < _jitc->function->call.size)
1134         _jitc->function->self.alen = _jitc->function->call.size;
1135     node = jit_callr(r0);
1136     node->v.w = _jitc->function->self.argi;
1137     node->w.w = _jitc->function->call.argf;
1138     _jitc->function->call.argi = _jitc->function->call.argf =
1139         _jitc->function->call.size = 0;
1140     _jitc->prepare = 0;
1141     jit_dec_synth();
1142 }
1143
1144 jit_node_t *
1145 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
1146 {
1147     jit_node_t          *node;
1148     assert(_jitc->function);
1149     jit_check_frame();
1150     jit_inc_synth_w(finishi, (jit_word_t)i0);
1151 #if PACKED_STACK
1152     _jitc->function->call.size +=
1153         _jitc->function->call.size & (sizeof(jit_word_t) - 1);
1154 #endif
1155     if (_jitc->function->self.alen < _jitc->function->call.size)
1156         _jitc->function->self.alen = _jitc->function->call.size;
1157     node = jit_calli(i0);
1158     node->v.w = _jitc->function->call.argi;
1159     node->w.w = _jitc->function->call.argf;
1160     _jitc->function->call.argi = _jitc->function->call.argf =
1161         _jitc->function->call.size = 0;
1162     _jitc->prepare = 0;
1163     jit_dec_synth();
1164     return (node);
1165 }
1166
1167 void
1168 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
1169 {
1170     jit_inc_synth_w(retval_c, r0);
1171     jit_extr_c(r0, JIT_RET);
1172     jit_dec_synth();
1173 }
1174
1175 void
1176 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
1177 {
1178     jit_inc_synth_w(retval_uc, r0);
1179     jit_extr_uc(r0, JIT_RET);
1180     jit_dec_synth();
1181 }
1182
1183 void
1184 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
1185 {
1186     jit_inc_synth_w(retval_s, r0);
1187     jit_extr_s(r0, JIT_RET);
1188     jit_dec_synth();
1189 }
1190
1191 void
1192 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
1193 {
1194     jit_inc_synth_w(retval_us, r0);
1195     jit_extr_us(r0, JIT_RET);
1196     jit_dec_synth();
1197 }
1198
1199 void
1200 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
1201 {
1202     jit_inc_synth_w(retval_i, r0);
1203 #if __WORDSIZE == 32
1204     jit_movr(r0, JIT_RET);
1205 #else
1206     jit_extr_i(r0, JIT_RET);
1207 #endif
1208     jit_dec_synth();
1209 }
1210
1211 #if __WORDSIZE == 64
1212 void
1213 _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
1214 {
1215     jit_inc_synth_w(retval_ui, r0);
1216     jit_extr_ui(r0, JIT_RET);
1217     jit_dec_synth();
1218 }
1219
1220 void
1221 _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
1222 {
1223     jit_inc_synth_w(retval_l, r0);
1224     jit_movr(r0, JIT_RET);
1225     jit_dec_synth();
1226 }
1227 #endif
1228
1229 void
1230 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
1231 {
1232     jit_inc_synth_w(retval_f, r0);
1233     if (r0 != JIT_FRET)
1234         jit_movr_f(r0, JIT_FRET);
1235     jit_dec_synth();
1236 }
1237
1238 void
1239 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
1240 {
1241     jit_inc_synth_w(retval_d, r0);
1242     if (r0 != JIT_FRET)
1243         jit_movr_d(r0, JIT_FRET);
1244     jit_dec_synth();
1245 }
1246
1247 jit_pointer_t
1248 _emit_code(jit_state_t *_jit)
1249 {
1250     jit_node_t          *node;
1251     jit_node_t          *temp;
1252     jit_word_t           word;
1253     jit_word_t           value;
1254     jit_int32_t          offset;
1255     struct {
1256         jit_node_t      *node;
1257         jit_uint8_t     *data;
1258         jit_word_t       word;
1259         jit_function_t   func;
1260 #if DEVEL_DISASSEMBLER
1261         jit_word_t       prevw;
1262 #endif
1263         jit_int32_t      const_offset;
1264         jit_int32_t      patch_offset;
1265     } undo;
1266 #if DEVEL_DISASSEMBLER
1267     jit_word_t           prevw;
1268 #endif
1269
1270     _jitc->function = NULL;
1271
1272     jit_reglive_setup();
1273
1274     undo.word = 0;
1275     undo.node = NULL;
1276     undo.const_offset = undo.patch_offset = 0;
1277 #  define assert_data(node)             /**/
1278 #define case_rr(name, type)                                             \
1279             case jit_code_##name##r##type:                              \
1280                 name##r##type(rn(node->u.w), rn(node->v.w));            \
1281                 break
1282 #define case_rw(name, type)                                             \
1283             case jit_code_##name##i##type:                              \
1284                 name##i##type(rn(node->u.w), node->v.w);                \
1285                 break
1286 #define case_wr(name, type)                                             \
1287             case jit_code_##name##i##type:                              \
1288                 name##i##type(node->u.w, rn(node->v.w));                \
1289                 break
1290 #define case_rrr(name, type)                                            \
1291             case jit_code_##name##r##type:                              \
1292                 name##r##type(rn(node->u.w),                            \
1293                               rn(node->v.w), rn(node->w.w));            \
1294                 break
1295 #define case_rrrr(name, type)                                           \
1296             case jit_code_##name##r##type:                              \
1297                 name##r##type(rn(node->u.q.l), rn(node->u.q.h),         \
1298                               rn(node->v.w), rn(node->w.w));            \
1299                 break
1300 #define case_rrw(name, type)                                            \
1301             case jit_code_##name##i##type:                              \
1302                 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
1303                 break
1304 #define case_rrrw(name, type)                                           \
1305             case jit_code_##name##i##type:                              \
1306                 name##i##type(rn(node->u.q.l), rn(node->u.q.h),         \
1307                               rn(node->v.w), node->w.w);                \
1308                 break
1309 #define case_rrf(name)                                                  \
1310             case jit_code_##name##i_f:                                  \
1311                 assert_data(node);                                      \
1312                 name##i_f(rn(node->u.w), rn(node->v.w), node->w.f);     \
1313                 break
1314 #define case_rrd(name)                                                  \
1315             case jit_code_##name##i_d:                                  \
1316                 assert_data(node);                                      \
1317                 name##i_d(rn(node->u.w), rn(node->v.w), node->w.d);     \
1318                 break
1319 #define case_wrr(name, type)                                            \
1320             case jit_code_##name##i##type:                              \
1321                 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1322                 break
1323 #define case_brr(name, type)                                            \
1324             case jit_code_##name##r##type:                              \
1325                 temp = node->u.n;                                       \
1326                 assert(temp->code == jit_code_label ||                  \
1327                        temp->code == jit_code_epilog);                  \
1328                 if (temp->flag & jit_flag_patch)                        \
1329                     name##r##type(temp->u.w, rn(node->v.w),             \
1330                                   rn(node->w.w));                       \
1331                 else {                                                  \
1332                     word = name##r##type(_jit->pc.w,                    \
1333                                          rn(node->v.w), rn(node->w.w)); \
1334                     patch(word, node);                                  \
1335                 }                                                       \
1336                 break
1337 #define case_brw(name, type)                                            \
1338             case jit_code_##name##i##type:                              \
1339                 temp = node->u.n;                                       \
1340                 assert(temp->code == jit_code_label ||                  \
1341                        temp->code == jit_code_epilog);                  \
1342                 if (temp->flag & jit_flag_patch)                        \
1343                     name##i##type(temp->u.w,                            \
1344                                   rn(node->v.w), node->w.w);            \
1345                 else {                                                  \
1346                     word = name##i##type(_jit->pc.w,                    \
1347                                          rn(node->v.w), node->w.w);     \
1348                     patch(word, node);                                  \
1349                 }                                                       \
1350                 break;
1351 #define case_brf(name)                                                  \
1352             case jit_code_##name##i_f:                                  \
1353                 temp = node->u.n;                                       \
1354                 assert(temp->code == jit_code_label ||                  \
1355                        temp->code == jit_code_epilog);                  \
1356                 if (temp->flag & jit_flag_patch)                        \
1357                     name##i_f(temp->u.w, rn(node->v.w), node->w.f);     \
1358                 else {                                                  \
1359                     word = name##i_f(_jit->pc.w, rn(node->v.w),         \
1360                                      node->w.f);                        \
1361                     patch(word, node);                                  \
1362                 }                                                       \
1363                 break
1364 #define case_brd(name)                                                  \
1365             case jit_code_##name##i_d:                                  \
1366                 temp = node->u.n;                                       \
1367                 assert(temp->code == jit_code_label ||                  \
1368                        temp->code == jit_code_epilog);                  \
1369                 if (temp->flag & jit_flag_patch)                        \
1370                     name##i_d(temp->u.w, rn(node->v.w), node->w.d);     \
1371                 else {                                                  \
1372                     word = name##i_d(_jit->pc.w, rn(node->v.w),         \
1373                                      node->w.d);                        \
1374                     patch(word, node);                                  \
1375                 }                                                       \
1376                 break
1377 #if DEVEL_DISASSEMBLER
1378     prevw = _jit->pc.w;
1379 #endif
1380     for (node = _jitc->head; node; node = node->next) {
1381         if (_jit->pc.uc >= _jitc->code.end)
1382             return (NULL);
1383
1384 #if DEVEL_DISASSEMBLER
1385         node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1386         prevw = _jit->pc.w;
1387 #endif
1388         value = jit_classify(node->code);
1389         jit_regarg_set(node, value);
1390         switch (node->code) {
1391             case jit_code_align:
1392                 /* Must align to a power of two */
1393                 assert(!(node->u.w & (node->u.w - 1)));
1394                 if ((word = _jit->pc.w & (node->u.w - 1)))
1395                     nop(node->u.w - word);
1396                 break;
1397             case jit_code_skip:
1398                 nop((node->u.w + 3) & ~3);
1399                 break;
1400             case jit_code_note:         case jit_code_name:
1401                 node->u.w = _jit->pc.w;
1402                 break;
1403             case jit_code_label:
1404                 /* remember label is defined */
1405                 node->flag |= jit_flag_patch;
1406                 node->u.w = _jit->pc.w;
1407                 break;
1408                 case_rrr(add,);
1409                 case_rrw(add,);
1410                 case_rrr(addc,);
1411                 case_rrw(addc,);
1412                 case_rrr(addx,);
1413                 case_rrw(addx,);
1414                 case_rrr(sub,);
1415                 case_rrw(sub,);
1416                 case_rrr(subc,);
1417                 case_rrw(subc,);
1418                 case_rrr(subx,);
1419                 case_rrw(subx,);
1420                 case_rrw(rsb,);
1421                 case_rrr(mul,);
1422                 case_rrw(mul,);
1423                 case_rrrr(qmul,);
1424                 case_rrrw(qmul,);
1425                 case_rrrr(qmul, _u);
1426                 case_rrrw(qmul, _u);
1427                 case_rrr(div,);
1428                 case_rrw(div,);
1429                 case_rrr(div, _u);
1430                 case_rrw(div, _u);
1431                 case_rrrr(qdiv,);
1432                 case_rrrw(qdiv,);
1433                 case_rrrr(qdiv, _u);
1434                 case_rrrw(qdiv, _u);
1435                 case_rrr(rem,);
1436                 case_rrw(rem,);
1437                 case_rrr(rem, _u);
1438                 case_rrw(rem, _u);
1439                 case_rrr(lsh,);
1440                 case_rrw(lsh,);
1441                 case_rrr(rsh,);
1442                 case_rrw(rsh,);
1443                 case_rrr(rsh, _u);
1444                 case_rrw(rsh, _u);
1445                 case_rr(neg,);
1446                 case_rr(com,);
1447                 case_rr(clo,);
1448                 case_rr(clz,);
1449                 case_rr(cto,);
1450                 case_rr(ctz,);
1451                 case_rrr(and,);
1452                 case_rrw(and,);
1453                 case_rrr(or,);
1454                 case_rrw(or,);
1455                 case_rrr(xor,);
1456                 case_rrw(xor,);
1457                 case_rr(trunc, _f_i);
1458                 case_rr(trunc, _d_i);
1459                 case_rr(trunc, _f_l);
1460                 case_rr(trunc, _d_l);
1461                 case_rr(ld, _c);
1462                 case_rw(ld, _c);
1463                 case_rr(ld, _uc);
1464                 case_rw(ld, _uc);
1465                 case_rr(ld, _s);
1466                 case_rw(ld, _s);
1467                 case_rr(ld, _us);
1468                 case_rw(ld, _us);
1469                 case_rr(ld, _i);
1470                 case_rw(ld, _i);
1471                 case_rr(ld, _ui);
1472                 case_rw(ld, _ui);
1473                 case_rr(ld, _l);
1474                 case_rw(ld, _l);
1475                 case_rrr(ldx, _c);
1476                 case_rrw(ldx, _c);
1477                 case_rrr(ldx, _uc);
1478                 case_rrw(ldx, _uc);
1479                 case_rrr(ldx, _s);
1480                 case_rrw(ldx, _s);
1481                 case_rrr(ldx, _us);
1482                 case_rrw(ldx, _us);
1483                 case_rrr(ldx, _i);
1484                 case_rrw(ldx, _i);
1485                 case_rrr(ldx, _ui);
1486                 case_rrw(ldx, _ui);
1487                 case_rrr(ldx, _l);
1488                 case_rrw(ldx, _l);
1489                 case_rr(st, _c);
1490                 case_wr(st, _c);
1491                 case_rr(st, _s);
1492                 case_wr(st, _s);
1493                 case_rr(st, _i);
1494                 case_wr(st, _i);
1495                 case_rr(st, _l);
1496                 case_wr(st, _l);
1497                 case_rrr(stx, _c);
1498                 case_wrr(stx, _c);
1499                 case_rrr(stx, _s);
1500                 case_wrr(stx, _s);
1501                 case_rrr(stx, _i);
1502                 case_wrr(stx, _i);
1503                 case_rrr(stx, _l);
1504                 case_wrr(stx, _l);
1505                 case_rr(hton, _us);
1506                 case_rr(hton, _ui);
1507                 case_rr(hton, _ul);
1508                 case_rr(bswap, _us);
1509                 case_rr(bswap, _ui);
1510                 case_rr(bswap, _ul);
1511                 case_rr(ext, _c);
1512                 case_rr(ext, _uc);
1513                 case_rr(ext, _s);
1514                 case_rr(ext, _us);
1515                 case_rr(ext, _i);
1516                 case_rr(ext, _ui);
1517             case jit_code_casr:
1518                 casr(rn(node->u.w), rn(node->v.w),
1519                      rn(node->w.q.l), rn(node->w.q.h));
1520                 break;
1521             case jit_code_casi:
1522                 casi(rn(node->u.w), node->v.w,
1523                      rn(node->w.q.l), rn(node->w.q.h));
1524                 break;
1525                 case_rr(mov,);
1526                 case_rrr(movn,);
1527                 case_rrr(movz,);
1528             case jit_code_movi:
1529                 if (node->flag & jit_flag_node) {
1530                     temp = node->v.n;
1531                     if (temp->code == jit_code_data ||
1532                         (temp->code == jit_code_label &&
1533                          (temp->flag & jit_flag_patch)))
1534                         movi(rn(node->u.w), temp->u.w);
1535                     else {
1536                         assert(temp->code == jit_code_label ||
1537                                temp->code == jit_code_epilog);
1538                         word = movi_p(rn(node->u.w), temp->u.w);
1539                         patch(word, node);
1540                     }
1541                 }
1542                 else
1543                     movi(rn(node->u.w), node->v.w);
1544                 break;
1545                 case_rrr(lt,);
1546                 case_rrw(lt,);
1547                 case_rrr(lt, _u);
1548                 case_rrw(lt, _u);
1549                 case_rrr(le,);
1550                 case_rrw(le,);
1551                 case_rrr(le, _u);
1552                 case_rrw(le, _u);
1553                 case_rrr(eq,);
1554                 case_rrw(eq,);
1555                 case_rrr(ge,);
1556                 case_rrw(ge,);
1557                 case_rrr(ge, _u);
1558                 case_rrw(ge, _u);
1559                 case_rrr(gt,);
1560                 case_rrw(gt,);
1561                 case_rrr(gt, _u);
1562                 case_rrw(gt, _u);
1563                 case_rrr(ne,);
1564                 case_rrw(ne,);
1565                 case_brr(blt,);
1566                 case_brw(blt,);
1567                 case_brr(blt, _u);
1568                 case_brw(blt, _u);
1569                 case_brr(ble,);
1570                 case_brw(ble,);
1571                 case_brr(ble, _u);
1572                 case_brw(ble, _u);
1573                 case_brr(beq,);
1574                 case_brw(beq,);
1575                 case_brr(bge,);
1576                 case_brw(bge,);
1577                 case_brr(bge, _u);
1578                 case_brw(bge, _u);
1579                 case_brr(bgt,);
1580                 case_brw(bgt,);
1581                 case_brr(bgt, _u);
1582                 case_brw(bgt, _u);
1583                 case_brr(bne,);
1584                 case_brw(bne,);
1585                 case_brr(boadd,);
1586                 case_brw(boadd,);
1587                 case_brr(boadd, _u);
1588                 case_brw(boadd, _u);
1589                 case_brr(bxadd,);
1590                 case_brw(bxadd,);
1591                 case_brr(bxadd, _u);
1592                 case_brw(bxadd, _u);
1593                 case_brr(bosub,);
1594                 case_brw(bosub,);
1595                 case_brr(bosub, _u);
1596                 case_brw(bosub, _u);
1597                 case_brr(bxsub,);
1598                 case_brw(bxsub,);
1599                 case_brr(bxsub, _u);
1600                 case_brw(bxsub, _u);
1601                 case_brr(bms,);
1602                 case_brw(bms,);
1603                 case_brr(bmc,);
1604                 case_brw(bmc,);
1605                 case_rrr(add, _f);
1606                 case_rrf(add);
1607                 case_rrr(sub, _f);
1608                 case_rrf(sub);
1609                 case_rrf(rsb);
1610                 case_rrr(mul, _f);
1611                 case_rrf(mul);
1612                 case_rrr(div, _f);
1613                 case_rrf(div);
1614                 case_rr(abs, _f);
1615                 case_rr(neg, _f);
1616                 case_rr(sqrt, _f);
1617                 case_rr(ext, _f);
1618                 case_rr(ld, _f);
1619                 case_rw(ld, _f);
1620                 case_rrr(ldx, _f);
1621                 case_rrw(ldx, _f);
1622                 case_rr(st, _f);
1623                 case_wr(st, _f);
1624                 case_rrr(stx, _f);
1625                 case_wrr(stx, _f);
1626                 case_rr(mov, _f);
1627             case jit_code_movi_f:
1628                 assert_data(node);
1629                 movi_f(rn(node->u.w), node->v.f);
1630                 break;
1631                 case_rr(ext, _d_f);
1632                 case_rrr(lt, _f);
1633                 case_rrf(lt);
1634                 case_rrr(le, _f);
1635                 case_rrf(le);
1636                 case_rrr(eq, _f);
1637                 case_rrf(eq);
1638                 case_rrr(ge, _f);
1639                 case_rrf(ge);
1640                 case_rrr(gt, _f);
1641                 case_rrf(gt);
1642                 case_rrr(ne, _f);
1643                 case_rrf(ne);
1644                 case_rrr(unlt, _f);
1645                 case_rrf(unlt);
1646                 case_rrr(unle, _f);
1647                 case_rrf(unle);
1648                 case_rrr(uneq, _f);
1649                 case_rrf(uneq);
1650                 case_rrr(unge, _f);
1651                 case_rrf(unge);
1652                 case_rrr(ungt, _f);
1653                 case_rrf(ungt);
1654                 case_rrr(ltgt, _f);
1655                 case_rrf(ltgt);
1656                 case_rrr(ord, _f);
1657                 case_rrf(ord);
1658                 case_rrr(unord, _f);
1659                 case_rrf(unord);
1660                 case_brr(blt, _f);
1661                 case_brf(blt);
1662                 case_brr(ble, _f);
1663                 case_brf(ble);
1664                 case_brr(beq, _f);
1665                 case_brf(beq);
1666                 case_brr(bge, _f);
1667                 case_brf(bge);
1668                 case_brr(bgt, _f);
1669                 case_brf(bgt);
1670                 case_brr(bne, _f);
1671                 case_brf(bne);
1672                 case_brr(bunlt, _f);
1673                 case_brf(bunlt);
1674                 case_brr(bunle, _f);
1675                 case_brf(bunle);
1676                 case_brr(buneq, _f);
1677                 case_brf(buneq);
1678                 case_brr(bunge, _f);
1679                 case_brf(bunge);
1680                 case_brr(bungt, _f);
1681                 case_brf(bungt);
1682                 case_brr(bltgt, _f);
1683                 case_brf(bltgt);
1684                 case_brr(bord, _f);
1685                 case_brf(bord);
1686                 case_brr(bunord, _f);
1687                 case_brf(bunord);
1688                 case_rrr(add, _d);
1689                 case_rrd(add);
1690                 case_rrr(sub, _d);
1691                 case_rrd(sub);
1692                 case_rrd(rsb);
1693                 case_rrr(mul, _d);
1694                 case_rrd(mul);
1695                 case_rrr(div, _d);
1696                 case_rrd(div);
1697                 case_rr(abs, _d);
1698                 case_rr(neg, _d);
1699                 case_rr(sqrt, _d);
1700                 case_rr(ext, _d);
1701                 case_rr(ld, _d);
1702                 case_rw(ld, _d);
1703                 case_rrr(ldx, _d);
1704                 case_rrw(ldx, _d);
1705                 case_rr(st, _d);
1706                 case_wr(st, _d);
1707                 case_rrr(stx, _d);
1708                 case_wrr(stx, _d);
1709                 case_rr(mov, _d);
1710             case jit_code_movi_d:
1711                 assert_data(node);
1712                 movi_d(rn(node->u.w), node->v.d);
1713                 break;
1714                 case_rr(ext, _f_d);
1715                 case_rrr(lt, _d);
1716                 case_rrd(lt);
1717                 case_rrr(le, _d);
1718                 case_rrd(le);
1719                 case_rrr(eq, _d);
1720                 case_rrd(eq);
1721                 case_rrr(ge, _d);
1722                 case_rrd(ge);
1723                 case_rrr(gt, _d);
1724                 case_rrd(gt);
1725                 case_rrr(ne, _d);
1726                 case_rrd(ne);
1727                 case_rrr(unlt, _d);
1728                 case_rrd(unlt);
1729                 case_rrr(unle, _d);
1730                 case_rrd(unle);
1731                 case_rrr(uneq, _d);
1732                 case_rrd(uneq);
1733                 case_rrr(unge, _d);
1734                 case_rrd(unge);
1735                 case_rrr(ungt, _d);
1736                 case_rrd(ungt);
1737                 case_rrr(ltgt, _d);
1738                 case_rrd(ltgt);
1739                 case_rrr(ord, _d);
1740                 case_rrd(ord);
1741                 case_rrr(unord, _d);
1742                 case_rrd(unord);
1743                 case_brr(blt, _d);
1744                 case_brd(blt);
1745                 case_brr(ble, _d);
1746                 case_brd(ble);
1747                 case_brr(beq, _d);
1748                 case_brd(beq);
1749                 case_brr(bge, _d);
1750                 case_brd(bge);
1751                 case_brr(bgt, _d);
1752                 case_brd(bgt);
1753                 case_brr(bne, _d);
1754                 case_brd(bne);
1755                 case_brr(bunlt, _d);
1756                 case_brd(bunlt);
1757                 case_brr(bunle, _d);
1758                 case_brd(bunle);
1759                 case_brr(buneq, _d);
1760                 case_brd(buneq);
1761                 case_brr(bunge, _d);
1762                 case_brd(bunge);
1763                 case_brr(bungt, _d);
1764                 case_brd(bungt);
1765                 case_brr(bltgt, _d);
1766                 case_brd(bltgt);
1767                 case_brr(bord, _d);
1768                 case_brd(bord);
1769                 case_brr(bunord, _d);
1770                 case_brd(bunord);
1771             case jit_code_jmpr:
1772                 jit_check_frame();
1773                 jmpr(rn(node->u.w));
1774                 break;
1775             case jit_code_jmpi:
1776                 if (node->flag & jit_flag_node) {
1777                     temp = node->u.n;
1778                     assert(temp->code == jit_code_label ||
1779                            temp->code == jit_code_epilog);
1780                     if (temp->flag & jit_flag_patch)
1781                         jmpi(temp->u.w);
1782                     else {
1783                         word = _jit->code.length -
1784                             (_jit->pc.uc - _jit->code.ptr);
1785                         if (s26_p(word))
1786                             word = jmpi(_jit->pc.w);
1787                         else
1788                             word = jmpi_p(_jit->pc.w);
1789                         patch(word, node);
1790                     }
1791                 }
1792                 else {
1793                     jit_check_frame();
1794                     jmpi(node->u.w);
1795                 }
1796                 break;
1797             case jit_code_callr:
1798                 jit_check_frame();
1799                 callr(rn(node->u.w));
1800                 break;
1801             case jit_code_calli:
1802                 jit_check_frame();
1803                 if (node->flag & jit_flag_node) {
1804                     temp = node->u.n;
1805                     assert(temp->code == jit_code_label ||
1806                            temp->code == jit_code_epilog);
1807                     if (temp->flag & jit_flag_patch)
1808                         calli(temp->u.w);
1809                     else {
1810                         word = _jit->code.length -
1811                             (_jit->pc.uc - _jit->code.ptr);
1812                         if (s26_p(word))
1813                             word = calli(_jit->pc.w);
1814                         else
1815                             word = calli_p(_jit->pc.w);
1816                         patch(word, node);
1817                     }
1818                 }
1819                 else
1820                     calli(node->u.w);
1821                 break;
1822             case jit_code_prolog:
1823                 _jitc->function = _jitc->functions.ptr + node->w.w;
1824                 undo.node = node;
1825                 undo.word = _jit->pc.w;
1826                 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
1827 #if DEVEL_DISASSEMBLER
1828                 undo.prevw = prevw;
1829 #endif
1830                 undo.patch_offset = _jitc->patches.offset;
1831             restart_function:
1832                 compute_framesize();
1833                 patch_alist(0);
1834                 _jitc->again = 0;
1835                 prolog(node);
1836                 break;
1837             case jit_code_epilog:
1838                 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1839                 if (_jitc->again) {
1840                     for (temp = undo.node->next;
1841                          temp != node; temp = temp->next) {
1842                         if (temp->code == jit_code_label ||
1843                             temp->code == jit_code_epilog)
1844                             temp->flag &= ~jit_flag_patch;
1845                     }
1846                     temp->flag &= ~jit_flag_patch;
1847                     node = undo.node;
1848                     _jit->pc.w = undo.word;
1849                     /* undo.func.self.aoff and undo.func.regset should not
1850                      * be undone, as they will be further updated, and are
1851                      * the reason of the undo. */
1852                     undo.func.self.aoff = _jitc->function->frame +
1853                         _jitc->function->self.aoff;
1854                     undo.func.need_frame = _jitc->function->need_frame;
1855                     jit_regset_set(&undo.func.regset, &_jitc->function->regset);
1856                     /* allocar information also does not need to be undone */
1857                     undo.func.aoffoff = _jitc->function->aoffoff;
1858                     undo.func.allocar = _jitc->function->allocar;
1859                     memcpy(_jitc->function, &undo.func, sizeof(undo.func));
1860 #if DEVEL_DISASSEMBLER
1861                     prevw = undo.prevw;
1862 #endif
1863                     _jitc->patches.offset = undo.patch_offset;
1864                     patch_alist(1);
1865                     goto restart_function;
1866                 }
1867                 /* remember label is defined */
1868                 node->flag |= jit_flag_patch;
1869                 node->u.w = _jit->pc.w;
1870                 epilog(node);
1871                 _jitc->function = NULL;
1872                 break;
1873             case jit_code_va_start:
1874                 vastart(rn(node->u.w));
1875                 break;
1876             case jit_code_va_arg:
1877                 vaarg(rn(node->u.w), rn(node->v.w));
1878                 break;
1879             case jit_code_va_arg_d:
1880                 vaarg_d(rn(node->u.w), rn(node->v.w));
1881                 break;
1882             case jit_code_live:                 case jit_code_ellipsis:
1883             case jit_code_va_push:
1884             case jit_code_allocai:              case jit_code_allocar:
1885             case jit_code_arg_c:                case jit_code_arg_s:
1886             case jit_code_arg_i:
1887 #  if __WORDSIZE == 64
1888             case jit_code_arg_l:
1889 #  endif
1890             case jit_code_arg_f:                case jit_code_arg_d:
1891             case jit_code_va_end:
1892             case jit_code_ret:
1893             case jit_code_retr_c:               case jit_code_reti_c:
1894             case jit_code_retr_uc:              case jit_code_reti_uc:
1895             case jit_code_retr_s:               case jit_code_reti_s:
1896             case jit_code_retr_us:              case jit_code_reti_us:
1897             case jit_code_retr_i:               case jit_code_reti_i:
1898 #if __WORDSIZE == 64
1899             case jit_code_retr_ui:              case jit_code_reti_ui:
1900             case jit_code_retr_l:               case jit_code_reti_l:
1901 #endif
1902             case jit_code_retr_f:               case jit_code_reti_f:
1903             case jit_code_retr_d:               case jit_code_reti_d:
1904             case jit_code_getarg_c:             case jit_code_getarg_uc:
1905             case jit_code_getarg_s:             case jit_code_getarg_us:
1906             case jit_code_getarg_i:             case jit_code_getarg_ui:
1907             case jit_code_getarg_l:
1908             case jit_code_getarg_f:             case jit_code_getarg_d:
1909             case jit_code_putargr_c:            case jit_code_putargi_c:
1910             case jit_code_putargr_uc:           case jit_code_putargi_uc:
1911             case jit_code_putargr_s:            case jit_code_putargi_s:
1912             case jit_code_putargr_us:           case jit_code_putargi_us:
1913             case jit_code_putargr_i:            case jit_code_putargi_i:
1914 #if __WORDSIZE == 64
1915             case jit_code_putargr_ui:           case jit_code_putargi_ui:
1916             case jit_code_putargr_l:            case jit_code_putargi_l:
1917 #endif
1918             case jit_code_putargr_f:            case jit_code_putargi_f:
1919             case jit_code_putargr_d:            case jit_code_putargi_d:
1920             case jit_code_pushargr_c:           case jit_code_pushargi_c:
1921             case jit_code_pushargr_uc:          case jit_code_pushargi_uc:
1922             case jit_code_pushargr_s:           case jit_code_pushargi_s:
1923             case jit_code_pushargr_us:          case jit_code_pushargi_us:
1924             case jit_code_pushargr_i:           case jit_code_pushargi_i:
1925 #if __WORDSIZE == 64
1926             case jit_code_pushargr_ui:          case jit_code_pushargi_ui:
1927             case jit_code_pushargr_l:           case jit_code_pushargi_l:
1928 #endif
1929             case jit_code_pushargr_f:           case jit_code_pushargi_f:
1930             case jit_code_pushargr_d:           case jit_code_pushargi_d:
1931             case jit_code_retval_c:             case jit_code_retval_uc:
1932             case jit_code_retval_s:             case jit_code_retval_us:
1933             case jit_code_retval_i:
1934 #if __WORDSIZE == 64
1935             case jit_code_retval_ui:            case jit_code_retval_l:
1936 #endif
1937             case jit_code_retval_f:             case jit_code_retval_d:
1938             case jit_code_prepare:
1939             case jit_code_finishr:              case jit_code_finishi:
1940                 break;
1941             default:
1942                 abort();
1943         }
1944         jit_regarg_clr(node, value);
1945         assert(_jitc->regarg == 0 && _jitc->synth == 0);
1946         /* update register live state */
1947         jit_reglive(node);
1948     }
1949 #undef case_brw
1950 #undef case_brr
1951 #undef case_wrr
1952 #undef case_rrw
1953 #undef case_rrr
1954 #undef case_wr
1955 #undef case_rw
1956 #undef case_rr
1957
1958     for (offset = 0; offset < _jitc->patches.offset; offset++) {
1959         node = _jitc->patches.ptr[offset].node;
1960         word = _jitc->patches.ptr[offset].inst;
1961         value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1962         patch_at(word, value);
1963     }
1964
1965     jit_flush(_jit->code.ptr, _jit->pc.uc);
1966
1967     return (_jit->code.ptr);
1968 }
1969
1970 #define CODE                            1
1971 #  include "jit_aarch64-cpu.c"
1972 #  include "jit_aarch64-fpu.c"
1973 #undef CODE
1974
1975 void
1976 jit_flush(void *fptr, void *tptr)
1977 {
1978 #if defined(__GNUC__)
1979     jit_word_t          f, t, s;
1980
1981     s = sysconf(_SC_PAGE_SIZE);
1982     f = (jit_word_t)fptr & -s;
1983     t = (((jit_word_t)tptr) + s - 1) & -s;
1984     __clear_cache((void *)f, (void *)t);
1985 #endif
1986 }
1987
1988 void
1989 _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1990 {
1991     ldxi(rn(r0), rn(r1), i0);
1992 }
1993
1994 void
1995 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1996 {
1997     stxi(i0, rn(r0), rn(r1));
1998 }
1999
2000 void
2001 _emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2002 {
2003     ldxi_d(rn(r0), rn(r1), i0);
2004 }
2005
2006 void
2007 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2008 {
2009     stxi_d(i0, rn(r0), rn(r1));
2010 }
2011
2012 static void
2013 _compute_framesize(jit_state_t *_jit)
2014 {
2015     jit_int32_t         reg;
2016     _jitc->framesize = 16;      /* ra+fp */
2017     for (reg = 0; reg < jit_size(iregs); reg++)
2018         if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg]))
2019             _jitc->framesize += sizeof(jit_word_t);
2020
2021     for (reg = 0; reg < jit_size(fregs); reg++)
2022         if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg]))
2023             _jitc->framesize += sizeof(jit_float64_t);
2024
2025     /* Make sure functions called have a 16 byte aligned stack */
2026     _jitc->framesize = (_jitc->framesize + 15) & -16;
2027 }
2028
2029 static void
2030 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
2031 {
2032     jit_int32_t          flag;
2033
2034     assert(node->flag & jit_flag_node);
2035     if (node->code == jit_code_movi)
2036         flag = node->v.n->flag;
2037     else
2038         flag = node->u.n->flag;
2039     assert(!(flag & jit_flag_patch));
2040     if (_jitc->patches.offset >= _jitc->patches.length) {
2041         jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
2042                     _jitc->patches.length * sizeof(jit_patch_t),
2043                     (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
2044         _jitc->patches.length += 1024;
2045     }
2046     _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
2047     _jitc->patches.ptr[_jitc->patches.offset].node = node;
2048     ++_jitc->patches.offset;
2049 }