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