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