Update lightrec 20220910 (#686)
[pcsx_rearmed.git] / deps / lightning / lib / jit_arm.c
1 /*
2  * Copyright (C) 2012-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 #if defined(__linux__)
21 #  include <stdio.h>
22 #endif
23
24 #define jit_arg_reg_p(i)                ((i) >= 0 && (i) < 4)
25 #define jit_arg_f_reg_p(i)              ((i) >= 0 && (i) < 16)
26 #define jit_arg_d_reg_p(i)              ((i) >= 0 && (i) < 15)
27
28 #define arm_patch_node                  0x80000000
29 #define arm_patch_word                  0x40000000
30 #define arm_patch_jump                  0x20000000
31 #define arm_patch_load                  0x00000000
32
33 #define jit_fpr_p(rn)                   ((rn) > 15)
34
35 #define arg_base()                                                      \
36     (stack_framesize - 16 + (jit_cpu.abi ? 64 : 0))
37 #define arg_offset(n)                                                   \
38     ((n) < 4 ? arg_base() + ((n) << 2) : (n))
39
40 /* Assume functions called never match jit instruction set, that is
41  * libc, gmp, mpfr, etc functions are in thumb mode and jit is in
42  * arm mode, what may cause a crash upon return of that function
43  * if generating jit for a relative jump.
44  */
45 #define jit_exchange_p()                1
46
47 /* FIXME is it really required to not touch _R10? */
48
49 /*
50  * Types
51  */
52 typedef union _jit_thumb_t {
53     jit_int32_t         i;
54     jit_int16_t         s[2];
55 } jit_thumb_t;
56
57 typedef jit_pointer_t   jit_va_list;
58
59 /*
60  * Prototypes
61  */
62 #define jit_make_arg(node)              _jit_make_arg(_jit,node)
63 static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*);
64 #define jit_make_arg_f(node)            _jit_make_arg_f(_jit,node)
65 static jit_node_t *_jit_make_arg_f(jit_state_t*,jit_node_t*);
66 #define jit_make_arg_d(node)            _jit_make_arg_d(_jit,node)
67 static jit_node_t *_jit_make_arg_d(jit_state_t*,jit_node_t*);
68 #define jit_get_reg_pair()              _jit_get_reg_pair(_jit)
69 static jit_int32_t _jit_get_reg_pair(jit_state_t*);
70 #define jit_unget_reg_pair(rn)          _jit_unget_reg_pair(_jit,rn)
71 static void _jit_unget_reg_pair(jit_state_t*,jit_int32_t);
72 # define must_align_p(node)             _must_align_p(_jit, node)
73 static jit_bool_t _must_align_p(jit_state_t*,jit_node_t*);
74 #define load_const(uniq,r0,i0)          _load_const(_jit,uniq,r0,i0)
75 static void _load_const(jit_state_t*,jit_bool_t,jit_int32_t,jit_word_t);
76 #define flush_consts()                  _flush_consts(_jit)
77 static void _flush_consts(jit_state_t*);
78 #define invalidate_consts()             _invalidate_consts(_jit)
79 static void _invalidate_consts(jit_state_t*);
80 #define patch(instr, node)              _patch(_jit, instr, node)
81 static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
82
83 #if defined(__GNUC__)
84 /* libgcc */
85 extern void __clear_cache(void *, void *);
86 #endif
87
88 #define PROTO                           1
89 #  include "jit_rewind.c"
90 #  include "jit_arm-cpu.c"
91 #  include "jit_arm-swf.c"
92 #  include "jit_arm-vfp.c"
93 #  include "jit_fallback.c"
94 #undef PROTO
95
96 /*
97  * Initialization
98  */
99 jit_cpu_t               jit_cpu;
100 jit_register_t          _rvs[] = {
101     { rc(gpr) | 0x0c,                   "ip" },
102     { rc(sav) | rc(gpr) | 0x04,         "r4" },
103     { rc(sav) | rc(gpr) | 0x05,         "r5" },
104     { rc(sav) | rc(gpr) | 0x06,         "r6" },
105     { rc(sav) | rc(gpr) | 0x07,         "r7" },
106     { rc(sav) | rc(gpr) | 0x08,         "r8" },
107     { rc(sav) | rc(gpr) | 0x09,         "r9" },
108     { rc(sav) | 0x0a,                   "sl" },
109     { rc(sav) | 0x0b,                   "fp" },
110     { rc(sav) | 0x0d,                   "sp" },
111     { rc(sav) | 0x0e,                   "lr" },
112     { 0x0f,                             "pc" },
113     { rc(arg) | rc(gpr) | 0x03,         "r3" },
114     { rc(arg) | rc(gpr) | 0x02,         "r2" },
115     { rc(arg) | rc(gpr) | 0x01,         "r1" },
116     { rc(arg) | rc(gpr) | 0x00,         "r0" },
117     { rc(fpr) | 0x20,                   "d8" },
118     { 0x21,                             "s17" },
119     { rc(fpr) | 0x22,                   "d9" },
120     { 0x23,                             "s19" },
121     { rc(fpr) | 0x24,                   "d10" },
122     { 0x25,                             "s21" },
123     { rc(fpr) | 0x26,                   "d11" },
124     { 0x27,                             "s23" },
125     { rc(fpr) | 0x28,                   "d12" },
126     { 0x29,                             "s25" },
127     { rc(fpr) | 0x2a,                   "d13" },
128     { 0x2b,                             "s27" },
129     { rc(fpr) | 0x2c,                   "d14" },
130     { 0x2d,                             "s29" },
131     { rc(fpr) | 0x2e,                   "d15" },
132     { 0x2f,                             "s31" },
133     { rc(arg) | 0x1f,                   "s15" },
134     { rc(arg)|rc(sft)|rc(fpr)|0x1e,     "d7" },
135     { rc(arg) | 0x1d,                   "s13" },
136     { rc(arg)|rc(sft)|rc(fpr)|0x1c,     "d6" },
137     { rc(arg) | 0x1b,                   "s11" },
138     { rc(arg)|rc(sft)|rc(fpr)|0x1a,     "d5" },
139     { rc(arg) | 0x19,                   "s9" },
140     { rc(arg)|rc(sft)|rc(fpr)|0x18,     "d4" },
141     { rc(arg) | 0x17,                   "s7" },
142     { rc(arg)|rc(sft)|rc(fpr)|0x16,     "d3" },
143     { rc(arg) | 0x15,                   "s5" },
144     { rc(arg)|rc(sft)|rc(fpr)|0x14,     "d2" },
145     { rc(arg) | 0x13,                   "s3" },
146     { rc(arg)|rc(sft)|rc(fpr)|0x12,     "d1" },
147     { rc(arg) | 0x11,                   "s1" },
148     { rc(arg)|rc(sft)|rc(fpr)|0x10,     "d0" },
149     { _NOREG,                           "<none>" },
150 };
151
152 /*
153  * Implementation
154  */
155 void
156 jit_get_cpu(void)
157 {
158 #if defined(__linux__)
159     FILE        *fp;
160     char        *ptr;
161     char         buf[128];
162
163     if ((fp = fopen("/proc/cpuinfo", "r")) != NULL) {
164         while (fgets(buf, sizeof(buf), fp)) {
165             if (strncmp(buf, "CPU architecture:", 17) == 0) {
166                 jit_cpu.version = strtol(buf + 17, &ptr, 10);
167                 while (*ptr) {
168                     if (*ptr == 'T' || *ptr == 't') {
169                         ++ptr;
170                         jit_cpu.thumb = 1;
171                     }
172                     else if (*ptr == 'E' || *ptr == 'e') {
173                         jit_cpu.extend = 1;
174                         ++ptr;
175                     }
176                     else
177                         ++ptr;
178                 }
179             }
180             else if (strncmp(buf, "Features\t:", 10) == 0) {
181                 if ((ptr = strstr(buf + 10, "vfpv")))
182                     jit_cpu.vfp = strtol(ptr + 4, NULL, 0);
183                 if ((ptr = strstr(buf + 10, "neon")))
184                     jit_cpu.neon = 1;
185                 if ((ptr = strstr(buf + 10, "thumb")))
186                     jit_cpu.thumb = 1;
187             }
188         }
189         fclose(fp);
190     }
191 #endif
192 #if defined(__ARM_PCS_VFP)
193     if (!jit_cpu.vfp)
194         jit_cpu.vfp = 3;
195     if (!jit_cpu.version)
196         jit_cpu.version = 7;
197     jit_cpu.abi = 1;
198 #endif
199 #if defined(__thumb2__)
200     jit_cpu.thumb = 1;
201 #endif
202     /* armv6t2 todo (software float and thumb2) */
203     if (!jit_cpu.vfp && jit_cpu.thumb)
204         jit_cpu.thumb = 0;
205 }
206
207 void
208 _jit_init(jit_state_t *_jit)
209 {
210     jit_int32_t         regno;
211     static jit_bool_t   first = 1;
212
213     _jitc->reglen = jit_size(_rvs) - 1;
214     if (first) {
215         /* jit_get_cpu() should have been already called, and only once */
216         if (!jit_cpu.vfp) {
217             /* cause register to never be allocated, because simple
218              * software float only allocates stack space for 8 slots  */
219             for (regno = _D8; regno < _D7; regno++)
220                 _rvs[regno].spec = 0;
221         }
222         if (!jit_cpu.abi) {
223             for (regno = _S15; regno <= _D0; regno++)
224                 _rvs[regno].spec &= ~rc(arg);
225         }
226         first = 0;
227     }
228 }
229
230 void
231 _jit_prolog(jit_state_t *_jit)
232 {
233     jit_int32_t          offset;
234
235     if (_jitc->function)
236         jit_epilog();
237     assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
238     jit_regset_set_ui(&_jitc->regsav, 0);
239     offset = _jitc->functions.offset;
240     if (offset >= _jitc->functions.length) {
241         jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
242                     _jitc->functions.length * sizeof(jit_function_t),
243                     (_jitc->functions.length + 16) * sizeof(jit_function_t));
244         _jitc->functions.length += 16;
245     }
246     _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
247     _jitc->function->self.size = stack_framesize;
248     if (jit_cpu.abi)
249         _jitc->function->self.size += 64;
250     _jitc->function->self.argi = _jitc->function->self.argf =
251         _jitc->function->self.alen = 0;
252     if (jit_swf_p())
253         /* 8 soft float registers */
254         _jitc->function->self.aoff = -64;
255     else
256         _jitc->function->self.aoff = 0;
257     _jitc->function->self.call = jit_call_default;
258     jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
259               _jitc->reglen * sizeof(jit_int32_t));
260
261     /* _no_link here does not mean the jit_link() call can be removed
262      * by rewriting as:
263      * _jitc->function->prolog = jit_new_node(jit_code_prolog);
264      */
265     _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
266     jit_link(_jitc->function->prolog);
267     _jitc->function->prolog->w.w = offset;
268     _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
269     /*  u:      label value
270      *  v:      offset in blocks vector
271      *  w:      offset in functions vector
272      */
273     _jitc->function->epilog->w.w = offset;
274
275     jit_regset_new(&_jitc->function->regset);
276 }
277
278 jit_int32_t
279 _jit_allocai(jit_state_t *_jit, jit_int32_t length)
280 {
281     assert(_jitc->function);
282     switch (length) {
283         case 0: case 1:                                         break;
284         case 2:         _jitc->function->self.aoff &= -2;       break;
285         case 3: case 4: _jitc->function->self.aoff &= -4;       break;
286         default:        _jitc->function->self.aoff &= -8;       break;
287     }
288     _jitc->function->self.aoff -= length;
289     if (!_jitc->realize) {
290         jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
291         jit_dec_synth();
292     }
293     return (_jitc->function->self.aoff);
294 }
295
296 void
297 _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
298 {
299     jit_int32_t          reg;
300     assert(_jitc->function);
301     jit_inc_synth_ww(allocar, u, v);
302     if (!_jitc->function->allocar) {
303         _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
304         _jitc->function->allocar = 1;
305     }
306     reg = jit_get_reg(jit_class_gpr);
307     jit_negr(reg, v);
308     jit_andi(reg, reg, -8);
309     jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
310     jit_addr(u, u, reg);
311     jit_addr(JIT_SP, JIT_SP, reg);
312     jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
313     jit_unget_reg(reg);
314     jit_dec_synth();
315 }
316
317 void
318 _jit_ret(jit_state_t *_jit)
319 {
320     jit_node_t          *instr;
321     assert(_jitc->function);
322     jit_inc_synth(ret);
323     /* jump to epilog */
324     instr = jit_jmpi();
325     jit_patch_at(instr, _jitc->function->epilog);
326     jit_dec_synth();
327 }
328
329 void
330 _jit_retr(jit_state_t *_jit, jit_int32_t u)
331 {
332     jit_inc_synth_w(retr, u);
333     if (JIT_RET != u)
334         jit_movr(JIT_RET, u);
335     jit_live(JIT_RET);
336     jit_ret();
337     jit_dec_synth();
338 }
339
340 void
341 _jit_reti(jit_state_t *_jit, jit_word_t u)
342 {
343     jit_inc_synth_w(reti, u);
344     jit_movi(JIT_RET, u);
345     jit_ret();
346     jit_dec_synth();
347 }
348
349 void
350 _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
351 {
352     jit_inc_synth_w(retr_f, u);
353     if (jit_cpu.abi) {
354         if (u != JIT_FRET)
355             jit_movr_f(JIT_FRET, u);
356         else
357             jit_live(JIT_FRET);
358     }
359     else {
360         if (u != JIT_RET)
361             jit_movr_f_w(JIT_RET, u);
362         else
363             jit_live(JIT_RET);
364     }
365     jit_ret();
366     jit_dec_synth();
367 }
368
369 void
370 _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
371 {
372     jit_inc_synth_f(reti_f, u);
373     if (jit_cpu.abi)
374         jit_movi_f(JIT_FRET, u);
375     else
376         jit_movi_f_w(JIT_RET, u);
377     jit_ret();
378     jit_dec_synth();
379 }
380
381 void
382 _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
383 {
384     jit_inc_synth_w(retr_d, u);
385     if (jit_cpu.abi) {
386         if (u != JIT_FRET)
387             jit_movr_d(JIT_FRET, u);
388         else
389             jit_live(JIT_FRET);
390     }
391     else {
392         if (u != JIT_RET)
393             jit_movr_d_ww(JIT_RET, _R1, u);
394         else
395             jit_live(JIT_RET);
396     }
397     jit_ret();
398     jit_dec_synth();
399 }
400
401 void
402 _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
403 {
404     jit_inc_synth_d(reti_d, u);
405     if (jit_cpu.abi)
406         jit_movi_d(JIT_FRET, u);
407     else
408         jit_movi_d_ww(JIT_RET, _R1, u);
409     jit_ret();
410     jit_dec_synth();
411 }
412
413 void
414 _jit_epilog(jit_state_t *_jit)
415 {
416     assert(_jitc->function);
417     assert(_jitc->function->epilog->next == NULL);
418     jit_link(_jitc->function->epilog);
419     _jitc->function = NULL;
420 }
421
422 jit_bool_t
423 _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
424 {
425     if (u->code != jit_code_arg) {
426         if (u->code == jit_code_arg_f) {
427             if (jit_cpu.abi)
428                 return (jit_arg_f_reg_p(u->u.w));
429         }
430         else {
431             assert(u->code == jit_code_arg_d);
432             if (jit_cpu.abi)
433                 return (jit_arg_d_reg_p(u->u.w));
434         }
435     }
436     return (jit_arg_reg_p(u->u.w));
437 }
438
439 static jit_node_t *
440 _jit_make_arg(jit_state_t *_jit, jit_node_t *node)
441 {
442     jit_int32_t          offset;
443     if (jit_arg_reg_p(_jitc->function->self.argi))
444         offset = _jitc->function->self.argi++;
445     else {
446         offset = _jitc->function->self.size;
447         _jitc->function->self.size += sizeof(jit_word_t);
448     }
449     if (node == (jit_node_t *)0)
450         node = jit_new_node(jit_code_arg);
451     else
452         link_node(node);
453     node->u.w = offset;
454     node->v.w = ++_jitc->function->self.argn;
455     jit_link_prolog();
456     return (node);
457 }
458
459 jit_node_t *
460 _jit_make_arg_f(jit_state_t *_jit, jit_node_t *node)
461 {
462     jit_int32_t          offset;
463     if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
464         if (jit_arg_f_reg_p(_jitc->function->self.argf)) {
465             offset = _jitc->function->self.argf++;
466             goto done;
467         }
468     }
469     else {
470         if (jit_arg_reg_p(_jitc->function->self.argi)) {
471             offset = _jitc->function->self.argi++;
472             goto done;
473         }
474     }
475     offset = _jitc->function->self.size;
476     _jitc->function->self.size += sizeof(jit_float32_t);
477 done:
478     if (node == (jit_node_t *)0)
479         node = jit_new_node(jit_code_arg_f);
480     else
481         link_node(node);
482     node->u.w = offset;
483     node->v.w = ++_jitc->function->self.argn;
484     jit_link_prolog();
485     return (node);
486 }
487
488 jit_node_t *
489 _jit_make_arg_d(jit_state_t *_jit, jit_node_t *node)
490 {
491     jit_int32_t          offset;
492     if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
493         if (jit_arg_d_reg_p(_jitc->function->self.argf)) {
494             if (_jitc->function->self.argf & 1)
495                 ++_jitc->function->self.argf;
496             offset = _jitc->function->self.argf;
497             _jitc->function->self.argf += 2;
498             goto done;
499         }
500     }
501     else {
502         if (_jitc->function->self.argi & 1)
503             ++_jitc->function->self.argi;
504         if (jit_arg_reg_p(_jitc->function->self.argi)) {
505             offset = _jitc->function->self.argi;
506             _jitc->function->self.argi += 2;
507             goto done;
508         }
509     }
510     if (_jitc->function->self.size & 7)
511         _jitc->function->self.size += 4;
512     offset = _jitc->function->self.size;
513     _jitc->function->self.size += sizeof(jit_float64_t);
514 done:
515     if (node == (jit_node_t *)0)
516         node = jit_new_node(jit_code_arg_d);
517     else
518         link_node(node);
519     node->u.w = offset;
520     node->v.w = ++_jitc->function->self.argn;
521     jit_link_prolog();
522     return (node);
523 }
524
525 void
526 _jit_ellipsis(jit_state_t *_jit)
527 {
528     if (_jitc->prepare) {
529         assert(!(_jitc->function->call.call & jit_call_varargs));
530         _jitc->function->call.call |= jit_call_varargs;
531         if (jit_cpu.abi && _jitc->function->call.argf)
532             rewind_prepare();
533     }
534     else {
535         assert(!(_jitc->function->self.call & jit_call_varargs));
536         _jitc->function->self.call |= jit_call_varargs;
537         if (jit_cpu.abi &&  _jitc->function->self.argf)
538             rewind_prolog();
539         /* First 4 stack addresses are always spilled r0-r3 */
540         if (jit_arg_reg_p(_jitc->function->self.argi))
541             _jitc->function->vagp = _jitc->function->self.argi * 4;
542         else
543             _jitc->function->vagp = 16;
544     }
545     jit_inc_synth(ellipsis);
546     if (_jitc->prepare)
547         jit_link_prepare();
548     else
549         jit_link_prolog();
550     jit_dec_synth();
551 }
552
553 void
554 _jit_va_push(jit_state_t *_jit, jit_int32_t u)
555 {
556     jit_inc_synth_w(va_push, u);
557     jit_pushargr(u);
558     jit_dec_synth();
559 }
560
561 jit_node_t *
562 _jit_arg(jit_state_t *_jit)
563 {
564     assert(_jitc->function);
565     return (jit_make_arg((jit_node_t*)0));
566 }
567
568 jit_node_t *
569 _jit_arg_f(jit_state_t *_jit)
570 {
571     assert(_jitc->function);
572     return (jit_make_arg_f((jit_node_t*)0));
573 }
574
575 jit_node_t *
576 _jit_arg_d(jit_state_t *_jit)
577 {
578     assert(_jitc->function);
579     return (jit_make_arg_d((jit_node_t*)0));
580 }
581
582 void
583 _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
584 {
585     assert(v->code == jit_code_arg);
586     jit_inc_synth_wp(getarg_c, u, v);
587     if (jit_swf_p())
588         jit_ldxi_c(u, JIT_FP, arg_offset(v->u.w));
589     else if (jit_arg_reg_p(v->u.w))
590         jit_extr_c(u, JIT_RA0 - v->u.w);
591     else
592         jit_ldxi_c(u, JIT_FP, v->u.w);
593     jit_dec_synth();
594 }
595
596 void
597 _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
598 {
599     assert(v->code == jit_code_arg);
600     jit_inc_synth_wp(getarg_uc, u, v);
601     if (jit_swf_p())
602         jit_ldxi_uc(u, JIT_FP, arg_offset(v->u.w));
603     else if (jit_arg_reg_p(v->u.w))
604         jit_extr_uc(u, JIT_RA0 - v->u.w);
605     else
606         jit_ldxi_uc(u, JIT_FP, v->u.w);
607     jit_dec_synth();
608 }
609
610 void
611 _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
612 {
613     assert(v->code == jit_code_arg);
614     jit_inc_synth_wp(getarg_s, u, v);
615     if (jit_swf_p())
616         jit_ldxi_s(u, JIT_FP, arg_offset(v->u.w));
617     else if (jit_arg_reg_p(v->u.w))
618         jit_extr_s(u, JIT_RA0 - v->u.w);
619     else
620         jit_ldxi_s(u, JIT_FP, v->u.w);
621     jit_dec_synth();
622 }
623
624 void
625 _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
626 {
627     assert(v->code == jit_code_arg);
628     jit_inc_synth_wp(getarg_us, u, v);
629     if (jit_swf_p())
630         jit_ldxi_us(u, JIT_FP, arg_offset(v->u.w));
631     else if (jit_arg_reg_p(v->u.w))
632         jit_extr_us(u, JIT_RA0 - v->u.w);
633     else
634         jit_ldxi_us(u, JIT_FP, v->u.w);
635     jit_dec_synth();
636 }
637
638 void
639 _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
640 {
641     assert(v->code == jit_code_arg);
642     jit_inc_synth_wp(getarg_i, u, v);
643     if (jit_swf_p())
644         jit_ldxi_i(u, JIT_FP, arg_offset(v->u.w));
645     else if (jit_arg_reg_p(v->u.w))
646         jit_movr(u, JIT_RA0 - v->u.w);
647     else
648         jit_ldxi_i(u, JIT_FP, v->u.w);
649     jit_dec_synth();
650 }
651
652 void
653 _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
654 {
655     assert(v->code == jit_code_arg);
656     jit_inc_synth_wp(putargr, u, v);
657     if (jit_swf_p())
658         jit_stxi(arg_offset(v->u.w), JIT_FP, u);
659     else if (jit_arg_reg_p(v->u.w))
660         jit_movr(JIT_RA0 - v->u.w, u);
661     else
662         jit_stxi(v->u.w, JIT_FP, u);
663     jit_dec_synth();
664 }
665
666 void
667 _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
668 {
669     jit_int32_t         regno;
670     assert(v->code == jit_code_arg);
671     jit_inc_synth_wp(putargi, u, v);
672     if (jit_swf_p()) {
673         regno = jit_get_reg(jit_class_gpr);
674         jit_movi(regno, u);
675         jit_stxi(arg_offset(v->u.w), JIT_FP, regno);
676         jit_unget_reg(regno);
677     }
678     else if (jit_arg_reg_p(v->u.w))
679         jit_movi(JIT_RA0 - v->u.w, u);
680     else {
681         regno = jit_get_reg(jit_class_gpr);
682         jit_movi(regno, u);
683         jit_stxi(v->u.w, JIT_FP, regno);
684         jit_unget_reg(regno);
685     }
686     jit_dec_synth();
687 }
688
689 void
690 _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
691 {
692     assert(v->code == jit_code_arg_f);
693     jit_inc_synth_wp(getarg_f, u, v);
694     if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
695         if (jit_arg_f_reg_p(v->u.w))
696             jit_movr_f(u, JIT_FA0 - v->u.w);
697         else
698             jit_ldxi_f(u, JIT_FP, v->u.w);
699     }
700     else if (jit_swf_p())
701         jit_ldxi_f(u, JIT_FP, arg_offset(v->u.w));
702     else {
703         if (jit_arg_reg_p(v->u.w))
704             jit_movr_w_f(u, JIT_RA0 - v->u.w);
705         else
706             jit_ldxi_f(u, JIT_FP, v->u.w);
707     }
708     jit_dec_synth();
709 }
710
711 void
712 _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
713 {
714     assert(v->code == jit_code_arg_f);
715     jit_inc_synth_wp(putargr_f, u, v);
716     if (jit_cpu.abi) {
717         if (jit_arg_f_reg_p(v->u.w))
718             jit_movr_f(JIT_FA0 - v->u.w, u);
719         else
720             jit_stxi_f(v->u.w, JIT_FP, u);
721     }
722     else if (jit_swf_p())
723         jit_stxi_f(arg_offset(v->u.w), JIT_FP, u);
724     else {
725         if (jit_arg_reg_p(v->u.w))
726             jit_movr_f_w(JIT_RA0 - v->u.w, u);
727         else
728             jit_stxi_f(v->u.w, JIT_FP, u);
729     }
730     jit_dec_synth();
731 }
732
733 void
734 _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
735 {
736     jit_int32_t         regno;
737     assert(v->code == jit_code_arg_f);
738     jit_inc_synth_fp(putargi_f, u, v);
739     if (jit_cpu.abi) {
740         if (jit_arg_f_reg_p(v->u.w))
741             jit_movi_f(JIT_FA0 - v->u.w, u);
742         else {
743             regno = jit_get_reg(jit_class_fpr);
744             jit_movi_f(regno, u);
745             jit_stxi_f(v->u.w, JIT_FP, regno);
746             jit_unget_reg(regno);
747         }
748     }
749     else if (jit_swf_p()) {
750         regno = jit_get_reg(jit_class_fpr);
751         jit_movi_f(regno, u);
752         jit_stxi_f(arg_offset(v->u.w), JIT_FP, regno);
753         jit_unget_reg(regno);
754     }
755     else {
756         regno = jit_get_reg(jit_class_fpr);
757         jit_movi_f(regno, u);
758         if (jit_arg_reg_p(v->u.w))
759             jit_movr_f_w(JIT_RA0 - v->u.w, regno);
760         else
761             jit_stxi_f(v->u.w, JIT_FP, regno);
762         jit_unget_reg(regno);
763     }
764     jit_dec_synth();
765 }
766
767 void
768 _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
769 {
770     assert(v->code == jit_code_arg_d);
771     jit_inc_synth_wp(getarg_d, u, v);
772     if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
773         if (jit_arg_f_reg_p(v->u.w))
774             jit_movr_d(u, JIT_FA0 - v->u.w);
775         else
776             jit_ldxi_d(u, JIT_FP, v->u.w);
777     }
778     else if (jit_swf_p())
779         jit_ldxi_d(u, JIT_FP, arg_offset(v->u.w));
780     else {
781         if (jit_arg_reg_p(v->u.w))
782             jit_movr_ww_d(u, JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1));
783         else
784             jit_ldxi_d(u, JIT_FP, v->u.w);
785     }
786     jit_dec_synth();
787 }
788
789 void
790 _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
791 {
792     assert(v->code == jit_code_arg_d);
793     jit_inc_synth_wp(putargr_d, u, v);
794     if (jit_cpu.abi) {
795         if (jit_arg_f_reg_p(v->u.w))
796             jit_movr_d(JIT_FA0 - v->u.w, u);
797         else
798             jit_stxi_d(v->u.w, JIT_FP, u);
799     }
800     else if (jit_swf_p())
801         jit_stxi_d(arg_offset(v->u.w), JIT_FP, u);
802     else {
803         if (jit_arg_reg_p(v->u.w))
804             jit_movr_d_ww(JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1), u);
805         else
806             jit_stxi_d(v->u.w, JIT_FP, u);
807     }
808     jit_dec_synth();
809 }
810
811 void
812 _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
813 {
814     jit_int32_t         regno;
815     assert(v->code == jit_code_arg_d);
816     jit_inc_synth_dp(putargi_d, u, v);
817     if (jit_cpu.abi) {
818         if (jit_arg_f_reg_p(v->u.w))
819             jit_movi_d(JIT_FA0 - v->u.w, u);
820         else {
821             regno = jit_get_reg(jit_class_fpr);
822             jit_movi_d(regno, u);
823             jit_stxi_d(v->u.w, JIT_FP, regno);
824             jit_unget_reg(regno);
825         }
826     }
827     else if (jit_swf_p()) {
828         regno = jit_get_reg(jit_class_fpr);
829         jit_movi_d(regno, u);
830         jit_stxi_d(arg_offset(v->u.w), JIT_FP, regno);
831         jit_unget_reg(regno);
832     }
833     else {
834         regno = jit_get_reg(jit_class_fpr);
835         jit_movi_d(regno, u);
836         if (jit_arg_reg_p(v->u.w))
837             jit_movr_d_ww(JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1), regno);
838         else
839             jit_stxi_d(v->u.w, JIT_FP, regno);
840         jit_unget_reg(regno);
841     }
842     jit_dec_synth();
843 }
844
845 void
846 _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
847 {
848     assert(_jitc->function);
849     jit_inc_synth_w(pushargr, u);
850     jit_link_prepare();
851     if (jit_arg_reg_p(_jitc->function->call.argi)) {
852         jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
853         ++_jitc->function->call.argi;
854     }
855     else {
856         jit_stxi(_jitc->function->call.size, JIT_SP, u);
857         _jitc->function->call.size += sizeof(jit_word_t);
858     }
859     jit_dec_synth();
860 }
861
862 void
863 _jit_pushargi(jit_state_t *_jit, jit_word_t u)
864 {
865     jit_int32_t          regno;
866     assert(_jitc->function);
867     jit_inc_synth_w(pushargi, u);
868     jit_link_prepare();
869     if (jit_arg_reg_p(_jitc->function->call.argi)) {
870         jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
871         ++_jitc->function->call.argi;
872     }
873     else {
874         regno = jit_get_reg(jit_class_gpr);
875         jit_movi(regno, u);
876         jit_stxi(_jitc->function->call.size, JIT_SP, regno);
877         jit_unget_reg(regno);
878         _jitc->function->call.size += sizeof(jit_word_t);
879     }
880     jit_dec_synth();
881 }
882
883 void
884 _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
885 {
886     assert(_jitc->function);
887     jit_inc_synth_w(pushargr_f, u);
888     jit_link_prepare();
889     if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
890         if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
891             jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u);
892             ++_jitc->function->call.argf;
893             goto done;
894         }
895     }
896     else {
897         if (jit_arg_reg_p(_jitc->function->call.argi)) {
898             jit_movr_f_w(JIT_RA0 - _jitc->function->call.argi, u);
899             ++_jitc->function->call.argi;
900             goto done;
901         }
902     }
903     jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
904     _jitc->function->call.size += sizeof(jit_word_t);
905 done:
906     jit_dec_synth();
907 }
908
909 void
910 _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
911 {
912     jit_int32_t         regno;
913     assert(_jitc->function);
914     jit_inc_synth_f(pushargi_f, u);
915     jit_link_prepare();
916     if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
917         if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
918             /* cannot jit_movi_f in the argument register because
919              * float arguments are packed, and that would cause
920              * either an assertion in debug mode, or overwritting
921              * two registers */
922             regno = jit_get_reg(jit_class_fpr);
923             jit_movi_f(regno, u);
924             jit_movr_f(JIT_FA0 - _jitc->function->call.argf, regno);
925             jit_unget_reg(regno);
926             ++_jitc->function->call.argf;
927             goto done;
928         }
929     }
930     else {
931         if (jit_arg_reg_p(_jitc->function->call.argi)) {
932             jit_movi_f_w(JIT_RA0 - _jitc->function->call.argi, u);
933             ++_jitc->function->call.argi;
934             goto done;
935         }
936     }
937     regno = jit_get_reg(jit_class_fpr);
938     jit_movi_f(regno, u);
939     jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
940     jit_unget_reg(regno);
941     _jitc->function->call.size += sizeof(jit_word_t);
942 done:
943     jit_dec_synth();
944 }
945
946 void
947 _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
948 {
949     assert(_jitc->function);
950     jit_inc_synth_w(pushargr_d, u);
951     jit_link_prepare();
952     if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
953         if (jit_arg_d_reg_p(_jitc->function->call.argf)) {
954             if (_jitc->function->call.argf & 1)
955                 ++_jitc->function->call.argf;
956             jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
957             _jitc->function->call.argf += 2;
958             goto done;
959         }
960     }
961     else {
962         if (_jitc->function->call.argi & 1)
963             ++_jitc->function->call.argi;
964         if (jit_arg_reg_p(_jitc->function->call.argi)) {
965             jit_movr_d_ww(JIT_RA0 - _jitc->function->call.argi,
966                           JIT_RA0 - (_jitc->function->call.argi + 1),
967                           u);
968             _jitc->function->call.argi += 2;
969             goto done;
970         }
971     }
972     if (_jitc->function->call.size & 7)
973         _jitc->function->call.size += 4;
974     jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
975     _jitc->function->call.size += sizeof(jit_float64_t);
976 done:
977     jit_dec_synth();
978 }
979
980 void
981 _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
982 {
983     jit_int32_t         regno;
984     assert(_jitc->function);
985     jit_inc_synth_d(pushargi_d, u);
986     jit_link_prepare();
987     if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
988         if (jit_arg_d_reg_p(_jitc->function->call.argf)) {
989             if (_jitc->function->call.argf & 1)
990                 ++_jitc->function->call.argf;
991             jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
992             _jitc->function->call.argf += 2;
993             goto done;
994         }
995     }
996     else {
997         if (_jitc->function->call.argi & 1)
998             ++_jitc->function->call.argi;
999         if (jit_arg_reg_p(_jitc->function->call.argi)) {
1000             jit_movi_d_ww(JIT_RA0 - _jitc->function->call.argi,
1001                           JIT_RA0 - (_jitc->function->call.argi + 1),
1002                           u);
1003             _jitc->function->call.argi += 2;
1004             goto done;
1005         }
1006     }
1007     if (_jitc->function->call.size & 7)
1008         _jitc->function->call.size += 4;
1009     regno = jit_get_reg(jit_class_fpr);
1010     jit_movi_d(regno, u);
1011     jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
1012     jit_unget_reg(regno);
1013     _jitc->function->call.size += sizeof(jit_float64_t);
1014 done:
1015     jit_dec_synth();
1016 }
1017
1018 jit_bool_t
1019 _jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
1020 {
1021     jit_int32_t         spec;
1022     spec = jit_class(_rvs[regno].spec);
1023     if (spec & jit_class_arg) {
1024         regno = JIT_RA0 - regno;
1025         if (regno >= 0 && regno < node->v.w)
1026             return (1);
1027         if (jit_cpu.abi && spec & jit_class_fpr) {
1028             regno = JIT_FA0 - regno;
1029             if (regno >= 0 && regno < node->w.w)
1030                 return (1);
1031         }
1032     }
1033
1034     return (0);
1035 }
1036
1037 void
1038 _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
1039 {
1040     jit_node_t          *node;
1041     assert(_jitc->function);
1042     jit_inc_synth_w(finishr, r0);
1043     if (_jitc->function->self.alen < _jitc->function->call.size)
1044         _jitc->function->self.alen = _jitc->function->call.size;
1045     node = jit_callr(r0);
1046     node->v.w = _jitc->function->self.argi;
1047     node->w.w = _jitc->function->call.argf;
1048     _jitc->function->call.argi = _jitc->function->call.argf =
1049         _jitc->function->call.size = 0;
1050     _jitc->prepare = 0;
1051     jit_dec_synth();
1052 }
1053
1054 jit_node_t *
1055 _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
1056 {
1057     jit_node_t          *node;
1058     assert(_jitc->function);
1059     jit_inc_synth_w(finishi, (jit_word_t)i0);
1060     if (_jitc->function->self.alen < _jitc->function->call.size)
1061         _jitc->function->self.alen = _jitc->function->call.size;
1062     node = jit_calli(i0);
1063     node->v.w = _jitc->function->call.argi;
1064     node->w.w = _jitc->function->call.argf;
1065     _jitc->function->call.argi = _jitc->function->call.argf =
1066         _jitc->function->call.size = 0;
1067     _jitc->prepare = 0;
1068     jit_dec_synth();
1069     return (node);
1070 }
1071
1072 void
1073 _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
1074 {
1075     jit_inc_synth_w(retval_c, r0);
1076     jit_extr_c(r0, JIT_RET);
1077     jit_dec_synth();
1078 }
1079
1080 void
1081 _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
1082 {
1083     jit_inc_synth_w(retval_uc, r0);
1084     jit_extr_uc(r0, JIT_RET);
1085     jit_dec_synth();
1086 }
1087
1088 void
1089 _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
1090 {
1091     jit_inc_synth_w(retval_s, r0);
1092     jit_extr_s(r0, JIT_RET);
1093     jit_dec_synth();
1094 }
1095
1096 void
1097 _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
1098 {
1099     jit_inc_synth_w(retval_us, r0);
1100     jit_extr_us(r0, JIT_RET);
1101     jit_dec_synth();
1102 }
1103
1104 void
1105 _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
1106 {
1107     jit_inc_synth_w(retval_i, r0);
1108     if (r0 != JIT_RET)
1109         jit_movr(r0, JIT_RET);
1110     jit_dec_synth();
1111 }
1112
1113 void
1114 _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
1115 {
1116     jit_inc_synth_w(retval_f, r0);
1117     if (jit_cpu.abi) {
1118         if (r0 != JIT_FRET)
1119             jit_movr_f(r0, JIT_FRET);
1120     }
1121     else if (r0 != JIT_RET)
1122         jit_movr_w_f(r0, JIT_RET);
1123     jit_dec_synth();
1124 }
1125
1126 void
1127 _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
1128 {
1129     jit_inc_synth_w(retval_d, r0);
1130     if (jit_cpu.abi) {
1131         if (r0 != JIT_FRET)
1132             jit_movr_d(r0, JIT_FRET);
1133     }
1134     else if (r0 != JIT_RET)
1135         jit_movr_ww_d(r0, JIT_RET, _R1);
1136     jit_dec_synth();
1137 }
1138
1139 jit_pointer_t
1140 _emit_code(jit_state_t *_jit)
1141 {
1142     jit_node_t          *node;
1143     jit_node_t          *temp;
1144     jit_word_t           word;
1145     jit_int32_t          value;
1146     jit_int32_t          offset;
1147     struct {
1148         jit_node_t      *node;
1149         jit_uint8_t     *data;
1150         jit_word_t       word;
1151 #if DEVEL_DISASSEMBLER
1152         jit_word_t       prevw;
1153 #endif
1154         jit_uword_t      thumb;
1155 #if DISASSEMBLER
1156         jit_int32_t      info_offset;
1157 #endif
1158         jit_int32_t      const_offset;
1159         jit_int32_t      patch_offset;
1160     } undo;
1161 #if DEVEL_DISASSEMBLER
1162     jit_word_t           prevw;
1163 #endif
1164
1165     _jitc->function = NULL;
1166     _jitc->thumb = 0;
1167
1168     jit_reglive_setup();
1169
1170     _jitc->consts.data = NULL;
1171     _jitc->consts.offset = _jitc->consts.length = 0;
1172
1173     undo.word = 0;
1174     undo.node = NULL;
1175     undo.data = NULL;
1176     undo.thumb = 0;
1177 #if DISASSEMBLER
1178     undo.info_offset =
1179 #endif
1180         undo.const_offset = undo.patch_offset = 0;
1181 #  define assert_data(node)             /**/
1182 #define case_rr(name, type)                                             \
1183             case jit_code_##name##r##type:                              \
1184                 name##r##type(rn(node->u.w), rn(node->v.w));            \
1185                 break
1186 #define case_rw(name, type)                                             \
1187             case jit_code_##name##i##type:                              \
1188                 name##i##type(rn(node->u.w), node->v.w);                \
1189                 break
1190 #define case_vv(name, type)                                             \
1191             case jit_code_##name##r##type:                              \
1192                 if (jit_swf_p())                                        \
1193                     swf_##name##r##type(rn(node->u.w), rn(node->v.w));  \
1194                 else                                                    \
1195                     vfp_##name##r##type(rn(node->u.w), rn(node->v.w));  \
1196                 break
1197 #define case_vw(name, type)                                             \
1198             case jit_code_##name##i##type:                              \
1199                 if (jit_swf_p())                                        \
1200                     swf_##name##i##type(rn(node->u.w), node->v.w);      \
1201                 else                                                    \
1202                     vfp_##name##i##type(rn(node->u.w), node->v.w);      \
1203                 break
1204 #define case_wr(name, type)                                             \
1205             case jit_code_##name##i##type:                              \
1206                 name##i##type(node->u.w, rn(node->v.w));                \
1207                 break
1208 #define case_wv(name, type)                                             \
1209             case jit_code_##name##i##type:                              \
1210                 if (jit_swf_p())                                        \
1211                     swf_##name##i##type(node->u.w, rn(node->v.w));      \
1212                 else                                                    \
1213                     vfp_##name##i##type(node->u.w, rn(node->v.w));      \
1214                 break
1215 #define case_rrr(name, type)                                            \
1216             case jit_code_##name##r##type:                              \
1217                 name##r##type(rn(node->u.w),                            \
1218                               rn(node->v.w), rn(node->w.w));            \
1219                 break
1220 #define case_rrrr(name, type)                                           \
1221             case jit_code_##name##r##type:                              \
1222                 name##r##type(rn(node->u.q.l), rn(node->u.q.h),         \
1223                               rn(node->v.w), rn(node->w.w));            \
1224                 break
1225 #define case_vvv(name, type)                                            \
1226             case jit_code_##name##r##type:                              \
1227                 if (jit_swf_p())                                        \
1228                     swf_##name##r##type(rn(node->u.w),                  \
1229                                         rn(node->v.w), rn(node->w.w));  \
1230                 else                                                    \
1231                     vfp_##name##r##type(rn(node->u.w),                  \
1232                                         rn(node->v.w), rn(node->w.w));  \
1233                 break
1234 #define case_rrw(name, type)                                            \
1235             case jit_code_##name##i##type:                              \
1236                 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
1237                 break
1238 #define case_rrrw(name, type)                                           \
1239             case jit_code_##name##i##type:                              \
1240                 name##i##type(rn(node->u.q.l), rn(node->u.q.h),         \
1241                               rn(node->v.w), node->w.w);                \
1242                 break
1243 #define case_vvw(name, type)                                            \
1244             case jit_code_##name##i##type:                              \
1245                 if (jit_swf_p())                                        \
1246                     swf_##name##i##type(rn(node->u.w),                  \
1247                                         rn(node->v.w), node->w.w);      \
1248                 else                                                    \
1249                     vfp_##name##i##type(rn(node->u.w),                  \
1250                                         rn(node->v.w), node->w.w);      \
1251                 break
1252 #define case_vvf(name)                                                  \
1253             case jit_code_##name##i_f:                                  \
1254                 assert_data(node);                                      \
1255                 if (jit_swf_p())                                        \
1256                     swf_##name##i_f(rn(node->u.w), rn(node->v.w),       \
1257                                     node->w.f);                         \
1258                 else                                                    \
1259                     vfp_##name##i_f(rn(node->u.w), rn(node->v.w),       \
1260                                     node->w.f);                         \
1261                 break
1262 #define case_vvd(name)                                                  \
1263             case jit_code_##name##i_d:                                  \
1264                 assert_data(node);                                      \
1265                 if (jit_swf_p())                                        \
1266                     swf_##name##i_d(rn(node->u.w), rn(node->v.w),       \
1267                                     node->w.d);                         \
1268                 else                                                    \
1269                     vfp_##name##i_d(rn(node->u.w), rn(node->v.w),       \
1270                                     node->w.d);                         \
1271                 break
1272 #define case_wrr(name, type)                                            \
1273             case jit_code_##name##i##type:                              \
1274                 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1275                 break
1276 #define case_wvv(name, type)                                            \
1277             case jit_code_##name##i##type:                              \
1278                 if (jit_swf_p())                                        \
1279                     swf_##name##i##type(node->u.w,                      \
1280                                         rn(node->v.w), rn(node->w.w));  \
1281                 else                                                    \
1282                     vfp_##name##i##type(node->u.w,                      \
1283                                         rn(node->v.w), rn(node->w.w));  \
1284                 break
1285 #define case_brr(name, type)                                            \
1286             case jit_code_##name##r##type:                              \
1287                 temp = node->u.n;                                       \
1288                 assert(temp->code == jit_code_label ||                  \
1289                        temp->code == jit_code_epilog);                  \
1290                 if (temp->flag & jit_flag_patch)                        \
1291                     name##r##type(temp->u.w, rn(node->v.w),             \
1292                                   rn(node->w.w));                       \
1293                 else {                                                  \
1294                     word = name##r##type(_jit->pc.w,                    \
1295                                          rn(node->v.w), rn(node->w.w)); \
1296                     patch(word, node);                                  \
1297                 }                                                       \
1298                 break
1299 #define case_bvv(name, type)                                            \
1300             case jit_code_##name##r##type:                              \
1301                 temp = node->u.n;                                       \
1302                 assert(temp->code == jit_code_label ||                  \
1303                        temp->code == jit_code_epilog);                  \
1304                 if (temp->flag & jit_flag_patch) {                      \
1305                     if (jit_swf_p())                                    \
1306                         swf_##name##r##type(temp->u.w, rn(node->v.w),   \
1307                                             rn(node->w.w));             \
1308                     else                                                \
1309                         vfp_##name##r##type(temp->u.w, rn(node->v.w),   \
1310                                             rn(node->w.w));             \
1311                 }                                                       \
1312                 else {                                                  \
1313                     if (jit_swf_p())                                    \
1314                         word = swf_##name##r##type(_jit->pc.w,          \
1315                                                    rn(node->v.w),       \
1316                                                    rn(node->w.w));      \
1317                     else                                                \
1318                         word = vfp_##name##r##type(_jit->pc.w,          \
1319                                                    rn(node->v.w),       \
1320                                                    rn(node->w.w));      \
1321                     patch(word, node);                                  \
1322                 }                                                       \
1323                 break
1324 #define case_brw(name, type)                                            \
1325             case jit_code_##name##i##type:                              \
1326                 temp = node->u.n;                                       \
1327                 assert(temp->code == jit_code_label ||                  \
1328                        temp->code == jit_code_epilog);                  \
1329                 if (temp->flag & jit_flag_patch)                        \
1330                     name##i##type(temp->u.w,                            \
1331                                   rn(node->v.w), node->w.w);            \
1332                 else {                                                  \
1333                     word = name##i##type(_jit->pc.w,                    \
1334                                          rn(node->v.w), node->w.w);     \
1335                     patch(word, node);                                  \
1336                 }                                                       \
1337                 break;
1338 #define case_bvf(name)                                                  \
1339             case jit_code_##name##i_f:                                  \
1340                 temp = node->u.n;                                       \
1341                 assert(temp->code == jit_code_label ||                  \
1342                        temp->code == jit_code_epilog);                  \
1343                 if (temp->flag & jit_flag_patch) {                      \
1344                     if (jit_swf_p())                                    \
1345                         swf_##name##i_f(temp->u.w, rn(node->v.w),       \
1346                                         node->w.f);                     \
1347                     else                                                \
1348                         vfp_##name##i_f(temp->u.w, rn(node->v.w),       \
1349                                         node->w.f);                     \
1350                 }                                                       \
1351                 else {                                                  \
1352                     if (jit_swf_p())                                    \
1353                         word = swf_##name##i_f(_jit->pc.w,              \
1354                                                rn(node->v.w),           \
1355                                                node->w.f);              \
1356                     else                                                \
1357                         word = vfp_##name##i_f(_jit->pc.w,              \
1358                                                rn(node->v.w),           \
1359                                                node->w.f);              \
1360                     patch(word, node);                                  \
1361                 }                                                       \
1362                 break
1363 #define case_bvd(name)                                                  \
1364             case jit_code_##name##i_d:                                  \
1365                 temp = node->u.n;                                       \
1366                 assert(temp->code == jit_code_label ||                  \
1367                        temp->code == jit_code_epilog);                  \
1368                 if (temp->flag & jit_flag_patch) {                      \
1369                     if (jit_swf_p())                                    \
1370                         swf_##name##i_d(temp->u.w, rn(node->v.w),       \
1371                                         node->w.d);                     \
1372                     else                                                \
1373                         vfp_##name##i_d(temp->u.w, rn(node->v.w),       \
1374                                         node->w.d);                     \
1375                 }                                                       \
1376                 else {                                                  \
1377                     if (jit_swf_p())                                    \
1378                         word = swf_##name##i_d(_jit->pc.w,              \
1379                                                rn(node->v.w),           \
1380                                                node->w.d);              \
1381                     else                                                \
1382                         word = vfp_##name##i_d(_jit->pc.w,              \
1383                                                rn(node->v.w),           \
1384                                                node->w.d);              \
1385                     patch(word, node);                                  \
1386                 }                                                       \
1387                 break
1388 #if DEVEL_DISASSEMBLER
1389     prevw = _jit->pc.w;
1390 #endif
1391     for (node = _jitc->head; node; node = node->next) {
1392         if (_jit->pc.uc >= _jitc->code.end)
1393             return (NULL);
1394
1395 #if DEVEL_DISASSEMBLER
1396         node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1397         prevw = _jit->pc.w;
1398 #endif
1399         value = jit_classify(node->code);
1400         jit_regarg_set(node, value);
1401         switch (node->code) {
1402             case jit_code_align:
1403                 assert(!(node->u.w & (node->u.w - 1)) &&
1404                        node->u.w <= sizeof(jit_word_t));
1405                 if (node->u.w == sizeof(jit_word_t) &&
1406                     (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
1407                     nop(sizeof(jit_word_t) - word);
1408                 break;
1409             case jit_code_note:         case jit_code_name:
1410                 if (must_align_p(node->next))
1411                     nop(2);
1412                 node->u.w = _jit->pc.w;
1413                 break;
1414             case jit_code_label:
1415                 if (must_align_p(node->next))
1416                     nop(2);
1417                 /* remember label is defined */
1418                 node->flag |= jit_flag_patch;
1419                 node->u.w = _jit->pc.w;
1420                 break;
1421                 case_rrr(add,);
1422                 case_rrw(add,);
1423                 case_rrr(addc,);
1424                 case_rrw(addc,);
1425                 case_rrr(addx,);
1426                 case_rrw(addx,);
1427                 case_rrr(sub,);
1428                 case_rrw(sub,);
1429                 case_rrr(subc,);
1430                 case_rrw(subc,);
1431                 case_rrr(subx,);
1432                 case_rrw(subx,);
1433                 case_rrw(rsb,);
1434                 case_rrr(mul,);
1435                 case_rrw(mul,);
1436                 case_rrrr(qmul,);
1437                 case_rrrw(qmul,);
1438                 case_rrrr(qmul, _u);
1439                 case_rrrw(qmul, _u);
1440                 case_rrr(div,);
1441                 case_rrw(div,);
1442                 case_rrr(div, _u);
1443                 case_rrw(div, _u);
1444                 case_rrrr(qdiv,);
1445                 case_rrrw(qdiv,);
1446                 case_rrrr(qdiv, _u);
1447                 case_rrrw(qdiv, _u);
1448                 case_rrr(rem,);
1449                 case_rrw(rem,);
1450                 case_rrr(rem, _u);
1451                 case_rrw(rem, _u);
1452                 case_rrr(lsh,);
1453                 case_rrw(lsh,);
1454                 case_rrr(rsh,);
1455                 case_rrw(rsh,);
1456                 case_rrr(rsh, _u);
1457                 case_rrw(rsh, _u);
1458                 case_rr(neg,);
1459                 case_rr(com,);
1460                 case_rrr(and,);
1461                 case_rrw(and,);
1462                 case_rrr(or,);
1463                 case_rrw(or,);
1464                 case_rrr(xor,);
1465                 case_rrw(xor,);
1466                 case_vv(trunc, _f_i);
1467                 case_vv(trunc, _d_i);
1468                 case_rr(ld, _c);
1469                 case_rw(ld, _c);
1470                 case_rr(ld, _uc);
1471                 case_rw(ld, _uc);
1472                 case_rr(ld, _s);
1473                 case_rw(ld, _s);
1474                 case_rr(ld, _us);
1475                 case_rw(ld, _us);
1476                 case_rr(ld, _i);
1477                 case_rw(ld, _i);
1478                 case_rrr(ldx, _c);
1479                 case_rrw(ldx, _c);
1480                 case_rrr(ldx, _uc);
1481                 case_rrw(ldx, _uc);
1482                 case_rrr(ldx, _s);
1483                 case_rrw(ldx, _s);
1484                 case_rrr(ldx, _us);
1485                 case_rrw(ldx, _us);
1486                 case_rrr(ldx, _i);
1487                 case_rrw(ldx, _i);
1488                 case_rr(st, _c);
1489                 case_wr(st, _c);
1490                 case_rr(st, _s);
1491                 case_wr(st, _s);
1492                 case_rr(st, _i);
1493                 case_wr(st, _i);
1494                 case_rrr(stx, _c);
1495                 case_wrr(stx, _c);
1496                 case_rrr(stx, _s);
1497                 case_wrr(stx, _s);
1498                 case_rrr(stx, _i);
1499                 case_wrr(stx, _i);
1500                 case_rr(hton, _us);
1501                 case_rr(hton, _ui);
1502                 case_rr(bswap, _us);
1503                 case_rr(bswap, _ui);
1504                 case_rr(ext, _c);
1505                 case_rr(ext, _uc);
1506                 case_rr(ext, _s);
1507                 case_rr(ext, _us);
1508             case jit_code_casr:
1509                 casr(rn(node->u.w), rn(node->v.w),
1510                      rn(node->w.q.l), rn(node->w.q.h));
1511                 break;
1512             case jit_code_casi:
1513                 casi(rn(node->u.w), node->v.w,
1514                      rn(node->w.q.l), rn(node->w.q.h));
1515                 break;
1516                 case_rr(mov,);
1517                 case_rrr(movn,);
1518                 case_rrr(movz,);
1519             case jit_code_movi:
1520                 if (node->flag & jit_flag_node) {
1521                     temp = node->v.n;
1522                     if (temp->code == jit_code_data ||
1523                         (temp->code == jit_code_label &&
1524                          (temp->flag & jit_flag_patch)))
1525                         movi(rn(node->u.w), temp->u.w);
1526                     else {
1527                         assert(temp->code == jit_code_label ||
1528                                temp->code == jit_code_epilog);
1529                         word = movi_p(rn(node->u.w), temp->u.w);
1530                         patch(word, node);
1531                     }
1532                 }
1533                 else
1534                     movi(rn(node->u.w), node->v.w);
1535                 break;
1536                 case_rrr(lt,);
1537                 case_rrw(lt,);
1538                 case_rrr(lt, _u);
1539                 case_rrw(lt, _u);
1540                 case_rrr(le,);
1541                 case_rrw(le,);
1542                 case_rrr(le, _u);
1543                 case_rrw(le, _u);
1544                 case_rrr(eq,);
1545                 case_rrw(eq,);
1546                 case_rrr(ge,);
1547                 case_rrw(ge,);
1548                 case_rrr(ge, _u);
1549                 case_rrw(ge, _u);
1550                 case_rrr(gt,);
1551                 case_rrw(gt,);
1552                 case_rrr(gt, _u);
1553                 case_rrw(gt, _u);
1554                 case_rrr(ne,);
1555                 case_rrw(ne,);
1556                 case_brr(blt,);
1557                 case_brw(blt,);
1558                 case_brr(blt, _u);
1559                 case_brw(blt, _u);
1560                 case_brr(ble,);
1561                 case_brw(ble,);
1562                 case_brr(ble, _u);
1563                 case_brw(ble, _u);
1564                 case_brr(beq,);
1565                 case_brw(beq,);
1566                 case_brr(bge,);
1567                 case_brw(bge,);
1568                 case_brr(bge, _u);
1569                 case_brw(bge, _u);
1570                 case_brr(bgt,);
1571                 case_brw(bgt,);
1572                 case_brr(bgt, _u);
1573                 case_brw(bgt, _u);
1574                 case_brr(bne,);
1575                 case_brw(bne,);
1576                 case_brr(boadd,);
1577                 case_brw(boadd,);
1578                 case_brr(boadd, _u);
1579                 case_brw(boadd, _u);
1580                 case_brr(bxadd,);
1581                 case_brw(bxadd,);
1582                 case_brr(bxadd, _u);
1583                 case_brw(bxadd, _u);
1584                 case_brr(bosub,);
1585                 case_brw(bosub,);
1586                 case_brr(bosub, _u);
1587                 case_brw(bosub, _u);
1588                 case_brr(bxsub,);
1589                 case_brw(bxsub,);
1590                 case_brr(bxsub, _u);
1591                 case_brw(bxsub, _u);
1592                 case_brr(bms,);
1593                 case_brw(bms,);
1594                 case_brr(bmc,);
1595                 case_brw(bmc,);
1596                 case_vvv(add, _f);
1597                 case_vvf(add);
1598                 case_vvv(sub, _f);
1599                 case_vvf(sub);
1600                 case_vvf(rsb);
1601                 case_vvv(mul, _f);
1602                 case_vvf(mul);
1603                 case_vvv(div, _f);
1604                 case_vvf(div);
1605                 case_vv(abs, _f);
1606                 case_vv(neg, _f);
1607                 case_vv(sqrt, _f);
1608                 case_vv(ext, _f);
1609                 case_vv(ld, _f);
1610                 case_vw(ld, _f);
1611                 case_vvv(ldx, _f);
1612                 case_vvw(ldx, _f);
1613                 case_vv(st, _f);
1614                 case_wv(st, _f);
1615                 case_vvv(stx, _f);
1616                 case_wvv(stx, _f);
1617                 case_vv(mov, _f);
1618             case jit_code_movi_f:
1619                 assert_data(node);
1620                 if (jit_swf_p())
1621                     swf_movi_f(rn(node->u.w), node->v.f);
1622                 else
1623                     vfp_movi_f(rn(node->u.w), node->v.f);
1624                 break;
1625                 case_vv(ext, _d_f);
1626                 case_vvv(lt, _f);
1627                 case_vvf(lt);
1628                 case_vvv(le, _f);
1629                 case_vvf(le);
1630                 case_vvv(eq, _f);
1631                 case_vvf(eq);
1632                 case_vvv(ge, _f);
1633                 case_vvf(ge);
1634                 case_vvv(gt, _f);
1635                 case_vvf(gt);
1636                 case_vvv(ne, _f);
1637                 case_vvf(ne);
1638                 case_vvv(unlt, _f);
1639                 case_vvf(unlt);
1640                 case_vvv(unle, _f);
1641                 case_vvf(unle);
1642                 case_vvv(uneq, _f);
1643                 case_vvf(uneq);
1644                 case_vvv(unge, _f);
1645                 case_vvf(unge);
1646                 case_vvv(ungt, _f);
1647                 case_vvf(ungt);
1648                 case_vvv(ltgt, _f);
1649                 case_vvf(ltgt);
1650                 case_vvv(ord, _f);
1651                 case_vvf(ord);
1652                 case_vvv(unord, _f);
1653                 case_vvf(unord);
1654                 case_bvv(blt, _f);
1655                 case_bvf(blt);
1656                 case_bvv(ble, _f);
1657                 case_bvf(ble);
1658                 case_bvv(beq, _f);
1659                 case_bvf(beq);
1660                 case_bvv(bge, _f);
1661                 case_bvf(bge);
1662                 case_bvv(bgt, _f);
1663                 case_bvf(bgt);
1664                 case_bvv(bne, _f);
1665                 case_bvf(bne);
1666                 case_bvv(bunlt, _f);
1667                 case_bvf(bunlt);
1668                 case_bvv(bunle, _f);
1669                 case_bvf(bunle);
1670                 case_bvv(buneq, _f);
1671                 case_bvf(buneq);
1672                 case_bvv(bunge, _f);
1673                 case_bvf(bunge);
1674                 case_bvv(bungt, _f);
1675                 case_bvf(bungt);
1676                 case_bvv(bltgt, _f);
1677                 case_bvf(bltgt);
1678                 case_bvv(bord, _f);
1679                 case_bvf(bord);
1680                 case_bvv(bunord, _f);
1681                 case_bvf(bunord);
1682                 case_vvv(add, _d);
1683                 case_vvd(add);
1684                 case_vvv(sub, _d);
1685                 case_vvd(sub);
1686                 case_vvd(rsb);
1687                 case_vvv(mul, _d);
1688                 case_vvd(mul);
1689                 case_vvv(div, _d);
1690                 case_vvd(div);
1691                 case_vv(abs, _d);
1692                 case_vv(neg, _d);
1693                 case_vv(sqrt, _d);
1694                 case_vv(ext, _d);
1695                 case_vv(ld, _d);
1696                 case_vw(ld, _d);
1697                 case_vvv(ldx, _d);
1698                 case_vvw(ldx, _d);
1699                 case_vv(st, _d);
1700                 case_wv(st, _d);
1701                 case_vvv(stx, _d);
1702                 case_wvv(stx, _d);
1703                 case_vv(mov, _d);
1704             case jit_code_movi_d:
1705                 assert_data(node);
1706                 if (jit_swf_p())
1707                     swf_movi_d(rn(node->u.w), node->v.d);
1708                 else
1709                     vfp_movi_d(rn(node->u.w), node->v.d);
1710                 break;
1711                 case_vv(ext, _f_d);
1712                 case_vvv(lt, _d);
1713                 case_vvd(lt);
1714                 case_vvv(le, _d);
1715                 case_vvd(le);
1716                 case_vvv(eq, _d);
1717                 case_vvd(eq);
1718                 case_vvv(ge, _d);
1719                 case_vvd(ge);
1720                 case_vvv(gt, _d);
1721                 case_vvd(gt);
1722                 case_vvv(ne, _d);
1723                 case_vvd(ne);
1724                 case_vvv(unlt, _d);
1725                 case_vvd(unlt);
1726                 case_vvv(unle, _d);
1727                 case_vvd(unle);
1728                 case_vvv(uneq, _d);
1729                 case_vvd(uneq);
1730                 case_vvv(unge, _d);
1731                 case_vvd(unge);
1732                 case_vvv(ungt, _d);
1733                 case_vvd(ungt);
1734                 case_vvv(ltgt, _d);
1735                 case_vvd(ltgt);
1736                 case_vvv(ord, _d);
1737                 case_vvd(ord);
1738                 case_vvv(unord, _d);
1739                 case_vvd(unord);
1740                 case_bvv(blt, _d);
1741                 case_bvd(blt);
1742                 case_bvv(ble, _d);
1743                 case_bvd(ble);
1744                 case_bvv(beq, _d);
1745                 case_bvd(beq);
1746                 case_bvv(bge, _d);
1747                 case_bvd(bge);
1748                 case_bvv(bgt, _d);
1749                 case_bvd(bgt);
1750                 case_bvv(bne, _d);
1751                 case_bvd(bne);
1752                 case_bvv(bunlt, _d);
1753                 case_bvd(bunlt);
1754                 case_bvv(bunle, _d);
1755                 case_bvd(bunle);
1756                 case_bvv(buneq, _d);
1757                 case_bvd(buneq);
1758                 case_bvv(bunge, _d);
1759                 case_bvd(bunge);
1760                 case_bvv(bungt, _d);
1761                 case_bvd(bungt);
1762                 case_bvv(bltgt, _d);
1763                 case_bvd(bltgt);
1764                 case_bvv(bord, _d);
1765                 case_bvd(bord);
1766                 case_bvv(bunord, _d);
1767                 case_bvd(bunord);
1768             case jit_code_jmpr:
1769                 jmpr(rn(node->u.w));
1770                 flush_consts();
1771                 break;
1772             case jit_code_jmpi:
1773                 if (node->flag & jit_flag_node) {
1774                     temp = node->u.n;
1775                     assert(temp->code == jit_code_label ||
1776                            temp->code == jit_code_epilog);
1777                     if (temp->flag & jit_flag_patch)
1778                         jmpi(temp->u.w);
1779                     else {
1780                         word = jmpi_p(_jit->pc.w, 1);
1781                         patch(word, node);
1782                     }
1783                 }
1784                 else
1785                     jmpi(node->u.w);
1786                 flush_consts();
1787                 break;
1788             case jit_code_callr:
1789                 callr(rn(node->u.w));
1790                 break;
1791             case jit_code_calli:
1792                 if (node->flag & jit_flag_node) {
1793                     temp = node->u.n;
1794                     assert(temp->code == jit_code_label ||
1795                            temp->code == jit_code_epilog);
1796                     if (temp->flag & jit_flag_patch)
1797                         calli(temp->u.w);
1798                     else {
1799                         word = calli_p(_jit->pc.w);
1800                         patch(word, node);
1801                     }
1802                 }
1803                 else
1804                     calli(node->u.w);
1805                 break;
1806             case jit_code_prolog:
1807                 _jitc->function = _jitc->functions.ptr + node->w.w;
1808                 undo.node = node;
1809                 undo.word = _jit->pc.w;
1810 #if DEVEL_DISASSEMBLER
1811                 undo.prevw = prevw;
1812 #endif
1813                 undo.data = _jitc->consts.data;
1814                 undo.thumb = _jitc->thumb;
1815                 undo.const_offset = _jitc->consts.offset;
1816                 undo.patch_offset = _jitc->patches.offset;
1817 #if DISASSEMBLER
1818                 if (_jitc->data_info.ptr)
1819                     undo.info_offset = _jitc->data_info.offset;
1820 #endif
1821             restart_function:
1822                 _jitc->again = 0;
1823                 prolog(node);
1824                 break;
1825             case jit_code_epilog:
1826                 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1827                 if (_jitc->again) {
1828                     for (temp = undo.node->next;
1829                          temp != node; temp = temp->next) {
1830                         if (temp->code == jit_code_label ||
1831                             temp->code == jit_code_epilog)
1832                             temp->flag &= ~jit_flag_patch;
1833                     }
1834                     temp->flag &= ~jit_flag_patch;
1835                     node = undo.node;
1836                     _jit->pc.w = undo.word;
1837 #if DEVEL_DISASSEMBLER
1838                     prevw = undo.prevw;
1839 #endif
1840                     invalidate_consts();
1841                     _jitc->consts.data = undo.data;
1842                     _jitc->thumb = undo.thumb;
1843                     _jitc->consts.offset = undo.const_offset;
1844                     _jitc->patches.offset = undo.patch_offset;
1845 #if DISASSEMBLER
1846                     if (_jitc->data_info.ptr)
1847                         _jitc->data_info.offset = undo.info_offset;
1848 #endif
1849                     goto restart_function;
1850                 }
1851                 /* remember label is defined */
1852                 node->flag |= jit_flag_patch;
1853                 node->u.w = _jit->pc.w;
1854                 epilog(node);
1855                 _jitc->function = NULL;
1856                 flush_consts();
1857                 break;
1858             case jit_code_movr_w_f:
1859                 if (jit_swf_p())
1860                     swf_movr_f(rn(node->u.w), rn(node->v.w));
1861                 else
1862                     vfp_movr_f(rn(node->u.w), rn(node->v.w));
1863                 break;
1864             case jit_code_movr_f_w:
1865                 if (jit_swf_p())
1866                     swf_movr_f(rn(node->u.w), rn(node->v.w));
1867                 else
1868                     vfp_movr_f(rn(node->u.w), rn(node->v.w));
1869                 break;
1870             case jit_code_movi_f_w:
1871                 assert_data(node);
1872                 if (jit_swf_p())
1873                     swf_movi_f(rn(node->u.w), node->v.f);
1874                 else
1875                     vfp_movi_f(rn(node->u.w), node->v.f);
1876                 break;
1877             case jit_code_movr_ww_d:
1878                 if (jit_swf_p())
1879                     swf_movr_d(rn(node->u.w), rn(node->v.w));
1880                 else
1881                     vfp_movr_d(rn(node->u.w), rn(node->v.w));
1882                 break;
1883             case jit_code_movr_d_ww:
1884                 if (jit_swf_p())
1885                     swf_movr_d(rn(node->u.w), rn(node->w.w));
1886                 else
1887                     vfp_movr_d(rn(node->u.w), rn(node->w.w));
1888                 break;
1889             case jit_code_movi_d_ww:
1890                 assert_data(node);
1891                 if (jit_swf_p())
1892                     swf_movi_d(rn(node->u.w), node->w.d);
1893                 else
1894                     vfp_movi_d(rn(node->u.w), node->w.d);
1895                 break;
1896             case jit_code_va_start:
1897                 vastart(rn(node->u.w));
1898                 break;
1899             case jit_code_va_arg:
1900                 vaarg(rn(node->u.w), rn(node->v.w));
1901                 break;
1902             case jit_code_va_arg_d:
1903                 if (jit_swf_p())
1904                     swf_vaarg_d(rn(node->u.w), rn(node->v.w));
1905                 else
1906                     vfp_vaarg_d(rn(node->u.w), rn(node->v.w));
1907                 break;
1908             case jit_code_live:                 case jit_code_ellipsis:
1909             case jit_code_va_push:
1910             case jit_code_allocai:              case jit_code_allocar:
1911             case jit_code_arg:
1912             case jit_code_arg_f:                case jit_code_arg_d:
1913             case jit_code_va_end:
1914             case jit_code_ret:
1915             case jit_code_retr:                 case jit_code_reti:
1916             case jit_code_retr_f:               case jit_code_reti_f:
1917             case jit_code_retr_d:               case jit_code_reti_d:
1918             case jit_code_getarg_c:             case jit_code_getarg_uc:
1919             case jit_code_getarg_s:             case jit_code_getarg_us:
1920             case jit_code_getarg_i:
1921             case jit_code_getarg_f:             case jit_code_getarg_d:
1922             case jit_code_putargr:              case jit_code_putargi:
1923             case jit_code_putargr_f:            case jit_code_putargi_f:
1924             case jit_code_putargr_d:            case jit_code_putargi_d:
1925             case jit_code_pushargr:             case jit_code_pushargi:
1926             case jit_code_pushargr_f:           case jit_code_pushargi_f:
1927             case jit_code_pushargr_d:           case jit_code_pushargi_d:
1928             case jit_code_retval_c:             case jit_code_retval_uc:
1929             case jit_code_retval_s:             case jit_code_retval_us:
1930             case jit_code_retval_i:
1931             case jit_code_retval_f:             case jit_code_retval_d:
1932             case jit_code_prepare:
1933             case jit_code_finishr:              case jit_code_finishi:
1934                 break;
1935             default:
1936                 abort();
1937         }
1938         jit_regarg_clr(node, value);
1939         assert(_jitc->regarg == 0 && _jitc->synth == 0);
1940         /* update register live state */
1941         jit_reglive(node);
1942
1943         if (_jitc->consts.length &&
1944             (_jit->pc.uc - _jitc->consts.data >= 3968 ||
1945              (jit_uword_t)_jit->pc.uc -
1946              (jit_uword_t)_jitc->consts.patches[0] >= 3968)) {
1947             /* longest sequence should be 64 bytes, but preventively
1948              * do not let it go past 128 remaining bytes before a flush */
1949             if (node->next &&
1950                 node->next->code != jit_code_jmpi &&
1951                 node->next->code != jit_code_jmpr &&
1952                 node->next->code != jit_code_epilog) {
1953                 /* insert a jump, flush constants and continue */
1954                 word = _jit->pc.w;
1955                 assert(!jit_thumb_p());
1956                 B(0);
1957                 flush_consts();
1958                 patch_at(arm_patch_jump, word, _jit->pc.w);
1959             }
1960         }
1961     }
1962 #undef case_bvd
1963 #undef case_bvf
1964 #undef case_brw
1965 #undef case_bvv
1966 #undef case_brr
1967 #undef case_wvv
1968 #undef case_wrr
1969 #undef case_vvd
1970 #undef case_vvf
1971 #undef case_vvw
1972 #undef case_rrw
1973 #undef case_vvv
1974 #undef case_rrr
1975 #undef case_wv
1976 #undef case_wr
1977 #undef case_vw
1978 #undef case_vv
1979 #undef case_rw
1980 #undef case_rr
1981
1982     flush_consts();
1983     for (offset = 0; offset < _jitc->patches.offset; offset++) {
1984         assert(_jitc->patches.ptr[offset].kind & arm_patch_node);
1985         node = _jitc->patches.ptr[offset].node;
1986         word = _jitc->patches.ptr[offset].inst;
1987         if (!jit_thumb_p() &&
1988             (node->code == jit_code_movi || node->code == jit_code_calli)) {
1989             /* calculate where to patch word */
1990             value = *(jit_int32_t *)word;
1991             assert((value & 0x0f700000) == ARM_LDRI);
1992             /* offset may become negative (-4) if last instruction
1993              * before unconditional branch and data following
1994              * FIXME can this cause issues in the preprocessor prefetch
1995              * or something else? should not, as the constants are after
1996              * an unconditional jump */
1997             if (value & ARM_P)  value =   value & 0x00000fff;
1998             else                value = -(value & 0x00000fff);
1999             word = word + 8 + value;
2000         }
2001         value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
2002         patch_at(_jitc->patches.ptr[offset].kind & ~arm_patch_node, word, value);
2003     }
2004
2005     jit_flush(_jit->code.ptr, _jit->pc.uc);
2006
2007     return (_jit->code.ptr);
2008 }
2009
2010 #define CODE                            1
2011 #  include "jit_rewind.c"
2012 #  include "jit_arm-cpu.c"
2013 #  include "jit_arm-swf.c"
2014 #  include "jit_arm-vfp.c"
2015 #  include "jit_fallback.c"
2016 #undef CODE
2017
2018 void
2019 jit_flush(void *fptr, void *tptr)
2020 {
2021 #if defined(__GNUC__)
2022     jit_uword_t         i, f, t, s;
2023
2024     s = sysconf(_SC_PAGE_SIZE);
2025     f = (jit_uword_t)fptr & -s;
2026     t = (((jit_uword_t)tptr) + s - 1) & -s;
2027     for (i = f; i < t; i += s)
2028         __clear_cache((void *)i, (void *)(i + s));
2029 #endif
2030 }
2031
2032 void
2033 _emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2034 {
2035     ldxi_i(rn(r0), rn(r1), i0);
2036 }
2037
2038 void
2039 _emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2040 {
2041     stxi_i(i0, rn(r0), rn(r1));
2042 }
2043
2044 void
2045 _emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2046 {
2047     if (jit_swf_p())
2048         swf_ldxi_d(rn(r0), rn(r1), i0);
2049     else
2050         vfp_ldxi_d(rn(r0), rn(r1), i0);
2051 }
2052
2053 void
2054 _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2055 {
2056     if (jit_swf_p())
2057         swf_stxi_d(i0, rn(r0), rn(r1));
2058     else
2059         vfp_stxi_d(i0, rn(r0), rn(r1));
2060 }
2061
2062 static jit_int32_t
2063 _jit_get_reg_pair(jit_state_t *_jit)
2064 {
2065     /*   bypass jit_get_reg() with argument or'ed with jit_class_chk
2066      * and try to find an consecutive, even free register pair, or
2067      * return JIT_NOREG if fail, as the cost of spills is greater
2068      * than splitting a double load/store in two operations. */
2069     if (jit_reg_free_p(_R0) && jit_reg_free_p(_R1)) {
2070         jit_regset_setbit(&_jitc->regarg, _R0);
2071         jit_regset_setbit(&_jitc->regarg, _R1);
2072         return (_R0);
2073     }
2074     if (jit_reg_free_p(_R2) && jit_reg_free_p(_R3)) {
2075         jit_regset_setbit(&_jitc->regarg, _R2);
2076         jit_regset_setbit(&_jitc->regarg, _R3);
2077         return (_R2);
2078     }
2079     if (jit_reg_free_p(_R4) && jit_reg_free_p(_R5)) {
2080         jit_regset_setbit(&_jitc->regarg, _R4);
2081         jit_regset_setbit(&_jitc->regarg, _R5);
2082         return (_R4);
2083     }
2084     if (jit_reg_free_p(_R6) && jit_reg_free_p(_R7)) {
2085         jit_regset_setbit(&_jitc->regarg, _R6);
2086         jit_regset_setbit(&_jitc->regarg, _R7);
2087         return (_R6);
2088     }
2089     if (jit_reg_free_p(_R8) && jit_reg_free_p(_R9)) {
2090         jit_regset_setbit(&_jitc->regarg, _R8);
2091         jit_regset_setbit(&_jitc->regarg, _R9);
2092         return (_R8);
2093     }
2094     return (JIT_NOREG);
2095 }
2096
2097 static void
2098 _jit_unget_reg_pair(jit_state_t *_jit, jit_int32_t reg)
2099 {
2100     jit_unget_reg(reg);
2101     switch (reg) {
2102         case _R0:       jit_unget_reg(_R1);     break;
2103         case _R2:       jit_unget_reg(_R3);     break;
2104         case _R4:       jit_unget_reg(_R5);     break;
2105         case _R6:       jit_unget_reg(_R7);     break;
2106         case _R8:       jit_unget_reg(_R9);     break;
2107         default:        abort();
2108     }
2109 }
2110
2111 /*   A prolog must be aligned at mod 4 bytes boundary.
2112  *   This condition was not being required to be tested by
2113  * accident previously, but with the jit_frame and jit_tramp
2114  * code it is required */
2115 static jit_bool_t
2116 _must_align_p(jit_state_t *_jit, jit_node_t *node)
2117 {
2118     if (jit_thumb_p() && (_jit->pc.w & 3)) {
2119         for (; node; node = node->next) {
2120             switch (node->code) {
2121                 case jit_code_note:
2122                 case jit_code_name:
2123                 case jit_code_label:
2124                     break;
2125                 case jit_code_prolog:
2126                     return (1);
2127                 default:
2128                     return (0);
2129             }
2130         }
2131     }
2132     return (0);
2133 }
2134
2135 static void
2136 _load_const(jit_state_t *_jit, jit_bool_t uniq, jit_int32_t r0, jit_word_t i0)
2137 {
2138     jit_word_t           w;
2139     jit_word_t           d;
2140     jit_word_t           base;
2141     jit_int32_t         *data;
2142     jit_int32_t          size;
2143     jit_int32_t          offset;
2144
2145     assert(!jit_thumb_p());
2146     if (!uniq) {
2147         /* use zero, a valid directly encoded immediate, to avoid the
2148          * need of a bitmask to know what offsets will be patched, so
2149          * that comparison will always fail for constants that cannot
2150          * be encoded */
2151         assert(i0 != 0);
2152
2153         /* Actually, code is (currently at least) not self modifying,
2154          * so, any value reachable backwards is valid as a constant. */
2155
2156         /* FIXME a quickly updateable/mutable hash table could be
2157          * better here, but most times only a few comparisons
2158          * should be done
2159          */
2160
2161         /* search in previous constant pool */
2162         if ((data = (jit_int32_t *)_jitc->consts.data)) {
2163             w = (jit_word_t)data;
2164             /* maximum backwards offset */
2165             base = (_jit->pc.w + 8) - 4092;
2166             if (base <= w)
2167                 /* can scan all possible available backward constants */
2168                 base = 0;
2169             else
2170                 base = (base - w) >> 2;
2171             size = _jitc->consts.size >> 2;
2172             for (offset = size - 1; offset >= base; offset--) {
2173                 if (data[offset] == i0) {
2174                     w = (jit_word_t)(data + offset);
2175                     d = (_jit->pc.w + 8) - w;
2176                     LDRIN(r0, _R15_REGNO, d);
2177                     return;
2178                 }
2179             }
2180         }
2181     }
2182     else
2183         assert(i0 == 0);
2184
2185     _jitc->consts.patches[_jitc->consts.offset++] = _jit->pc.w;
2186     /* (probably) positive forward offset */
2187     LDRI(r0, _R15_REGNO, 0);
2188
2189     if (!uniq) {
2190         /* search already requested values */
2191         for (offset = 0; offset < _jitc->consts.length; offset++) {
2192             if (_jitc->consts.values[offset] == i0) {
2193                 _jitc->consts.patches[_jitc->consts.offset++] = offset;
2194                 return;
2195             }
2196         }
2197     }
2198
2199 #if DEBUG
2200     /* cannot run out of space because of limited range
2201      * but assert anyway to catch logic errors */
2202     assert(_jitc->consts.length < 1024);
2203     assert(_jitc->consts.offset < 2048);
2204 #endif
2205     _jitc->consts.patches[_jitc->consts.offset++] = _jitc->consts.length;
2206     _jitc->consts.values[_jitc->consts.length++] = i0;
2207 }
2208
2209 static void
2210 _flush_consts(jit_state_t *_jit)
2211 {
2212     jit_word_t           word;
2213     jit_int32_t          offset;
2214
2215     /* if no forward constants */
2216     if (!_jitc->consts.length)
2217         return;
2218     assert(!jit_thumb_p());
2219     word = _jit->pc.w;
2220     _jitc->consts.data = _jit->pc.uc;
2221     _jitc->consts.size = _jitc->consts.length << 2;
2222     /* FIXME check will not overrun, otherwise, need to reallocate
2223      * code buffer and start over */
2224     jit_memcpy(_jitc->consts.data, _jitc->consts.values, _jitc->consts.size);
2225     _jit->pc.w += _jitc->consts.size;
2226
2227 #if DISASSEMBLER
2228     if (_jitc->data_info.ptr) {
2229         if (_jitc->data_info.offset >= _jitc->data_info.length) {
2230             jit_realloc((jit_pointer_t *)&_jitc->data_info.ptr,
2231                         _jitc->data_info.length * sizeof(jit_data_info_t),
2232                         (_jitc->data_info.length + 1024) *
2233                         sizeof(jit_data_info_t));
2234             _jitc->data_info.length += 1024;
2235         }
2236         _jitc->data_info.ptr[_jitc->data_info.offset].code = word;
2237         _jitc->data_info.ptr[_jitc->data_info.offset].length = _jitc->consts.size;
2238         ++_jitc->data_info.offset;
2239     }
2240 #endif
2241
2242     for (offset = 0; offset < _jitc->consts.offset; offset += 2)
2243         patch_at(arm_patch_load, _jitc->consts.patches[offset],
2244                  word + (_jitc->consts.patches[offset + 1] << 2));
2245     _jitc->consts.length = _jitc->consts.offset = 0;
2246 }
2247
2248 /* to be called if needing to start over a function */
2249 static void
2250 _invalidate_consts(jit_state_t *_jit)
2251 {
2252     /* if no forward constants */
2253     if (_jitc->consts.length)
2254         _jitc->consts.length = _jitc->consts.offset = 0;
2255 }
2256
2257 static void
2258 _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
2259 {
2260     jit_int32_t          flag;
2261     jit_int32_t          kind;
2262
2263     assert(node->flag & jit_flag_node);
2264     if (node->code == jit_code_movi) {
2265         flag = node->v.n->flag;
2266         kind = arm_patch_word;
2267     }
2268     else {
2269         flag = node->u.n->flag;
2270         if (node->code == jit_code_calli ||
2271             (node->code == jit_code_jmpi && !(node->flag & jit_flag_node)))
2272             kind = arm_patch_word;
2273         else
2274             kind = arm_patch_jump;
2275     }
2276     assert(!(flag & jit_flag_patch));
2277     kind |= arm_patch_node;
2278     if (_jitc->patches.offset >= _jitc->patches.length) {
2279         jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
2280                     _jitc->patches.length * sizeof(jit_patch_t),
2281                     (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
2282         _jitc->patches.length += 1024;
2283     }
2284     _jitc->patches.ptr[_jitc->patches.offset].kind = kind;
2285     _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
2286     _jitc->patches.ptr[_jitc->patches.offset].node = node;
2287     ++_jitc->patches.offset;
2288 }