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