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