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