try a new github issue template
[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
ba86ff93
PC
1300#define case_rqr(name, type) \
1301 case jit_code_##name##r##type: \
1302 name##r##type(rn(node->u.w), rn(node->v.q.l), \
1303 rn(node->v.q.h), rn(node->w.w)); \
1304 case jit_code_##name##i##type: \
1305 break;
4a71579b
PC
1306#define case_rrw(name, type) \
1307 case jit_code_##name##i##type: \
1308 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
1309 break
1310#define case_rrrw(name, type) \
1311 case jit_code_##name##i##type: \
1312 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
1313 rn(node->v.w), node->w.w); \
1314 break
1315#define case_rrf(name) \
1316 case jit_code_##name##i_f: \
1317 assert_data(node); \
1318 name##i_f(rn(node->u.w), rn(node->v.w), node->w.f); \
1319 break
1320#define case_rrd(name) \
1321 case jit_code_##name##i_d: \
1322 assert_data(node); \
1323 name##i_d(rn(node->u.w), rn(node->v.w), node->w.d); \
1324 break
1325#define case_wrr(name, type) \
1326 case jit_code_##name##i##type: \
1327 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
1328 break
1329#define case_brr(name, type) \
1330 case jit_code_##name##r##type: \
1331 temp = node->u.n; \
1332 assert(temp->code == jit_code_label || \
1333 temp->code == jit_code_epilog); \
1334 if (temp->flag & jit_flag_patch) \
1335 name##r##type(temp->u.w, rn(node->v.w), \
1336 rn(node->w.w)); \
1337 else { \
1338 word = name##r##type(_jit->pc.w, \
1339 rn(node->v.w), rn(node->w.w)); \
1340 patch(word, node); \
1341 } \
1342 break
1343#define case_brw(name, type) \
1344 case jit_code_##name##i##type: \
1345 temp = node->u.n; \
1346 assert(temp->code == jit_code_label || \
1347 temp->code == jit_code_epilog); \
1348 if (temp->flag & jit_flag_patch) \
1349 name##i##type(temp->u.w, \
1350 rn(node->v.w), node->w.w); \
1351 else { \
1352 word = name##i##type(_jit->pc.w, \
1353 rn(node->v.w), node->w.w); \
1354 patch(word, node); \
1355 } \
1356 break;
1357#define case_brf(name) \
1358 case jit_code_##name##i_f: \
1359 temp = node->u.n; \
1360 assert(temp->code == jit_code_label || \
1361 temp->code == jit_code_epilog); \
1362 if (temp->flag & jit_flag_patch) \
1363 name##i_f(temp->u.w, rn(node->v.w), node->w.f); \
1364 else { \
1365 word = name##i_f(_jit->pc.w, rn(node->v.w), \
1366 node->w.f); \
1367 patch(word, node); \
1368 } \
1369 break
1370#define case_brd(name) \
1371 case jit_code_##name##i_d: \
1372 temp = node->u.n; \
1373 assert(temp->code == jit_code_label || \
1374 temp->code == jit_code_epilog); \
1375 if (temp->flag & jit_flag_patch) \
1376 name##i_d(temp->u.w, rn(node->v.w), node->w.d); \
1377 else { \
1378 word = name##i_d(_jit->pc.w, rn(node->v.w), \
1379 node->w.d); \
1380 patch(word, node); \
1381 } \
1382 break
1383#if DEVEL_DISASSEMBLER
1384 prevw = _jit->pc.w;
1385#endif
1386 for (node = _jitc->head; node; node = node->next) {
1387 if (_jit->pc.uc >= _jitc->code.end)
1388 return (NULL);
1389
1390#if DEVEL_DISASSEMBLER
1391 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1392 prevw = _jit->pc.w;
1393#endif
1394 value = jit_classify(node->code);
1395 jit_regarg_set(node, value);
1396 switch (node->code) {
1397 case jit_code_align:
c0c16242
PC
1398 /* Must align to a power of two */
1399 assert(!(node->u.w & (node->u.w - 1)));
1400 if ((word = _jit->pc.w & (node->u.w - 1)))
1401 nop(node->u.w - word);
4a71579b 1402 break;
79bfeef6
PC
1403 case jit_code_skip:
1404 nop((node->u.w + 3) & ~3);
1405 break;
4a71579b
PC
1406 case jit_code_note: case jit_code_name:
1407 node->u.w = _jit->pc.w;
1408 break;
1409 case jit_code_label:
1410 /* remember label is defined */
1411 node->flag |= jit_flag_patch;
1412 node->u.w = _jit->pc.w;
1413 break;
1414 case_rrr(add,);
1415 case_rrw(add,);
1416 case_rrr(addc,);
1417 case_rrw(addc,);
1418 case_rrr(addx,);
1419 case_rrw(addx,);
1420 case_rrr(sub,);
1421 case_rrw(sub,);
1422 case_rrr(subc,);
1423 case_rrw(subc,);
1424 case_rrr(subx,);
1425 case_rrw(subx,);
1426 case_rrw(rsb,);
1427 case_rrr(mul,);
1428 case_rrw(mul,);
ba86ff93
PC
1429 case_rrr(hmul,);
1430 case_rrw(hmul,);
1431 case_rrr(hmul, _u);
1432 case_rrw(hmul, _u);
4a71579b
PC
1433 case_rrrr(qmul,);
1434 case_rrrw(qmul,);
1435 case_rrrr(qmul, _u);
1436 case_rrrw(qmul, _u);
1437 case_rrr(div,);
1438 case_rrw(div,);
1439 case_rrr(div, _u);
1440 case_rrw(div, _u);
1441 case_rrrr(qdiv,);
1442 case_rrrw(qdiv,);
1443 case_rrrr(qdiv, _u);
1444 case_rrrw(qdiv, _u);
1445 case_rrr(rem,);
1446 case_rrw(rem,);
1447 case_rrr(rem, _u);
1448 case_rrw(rem, _u);
1449 case_rrr(lsh,);
1450 case_rrw(lsh,);
ba86ff93
PC
1451 case_rrrr(qlsh,);
1452 case_rrrw(qlsh,);
1453 case_rrrr(qlsh, _u);
1454 case_rrrw(qlsh, _u);
4a71579b
PC
1455 case_rrr(rsh,);
1456 case_rrw(rsh,);
1457 case_rrr(rsh, _u);
1458 case_rrw(rsh, _u);
ba86ff93
PC
1459 case_rrrr(qrsh,);
1460 case_rrrw(qrsh,);
1461 case_rrrr(qrsh, _u);
1462 case_rrrw(qrsh, _u);
1463 case_rrr(lrot,);
1464 case_rrw(lrot,);
1465 case_rrr(rrot,);
1466 case_rrw(rrot,);
4a71579b
PC
1467 case_rr(neg,);
1468 case_rr(com,);
79bfeef6
PC
1469 case_rr(clo,);
1470 case_rr(clz,);
1471 case_rr(cto,);
1472 case_rr(ctz,);
ba86ff93
PC
1473 case_rr(rbit,);
1474 case_rr(popcnt,);
4a71579b
PC
1475 case_rrr(and,);
1476 case_rrw(and,);
1477 case_rrr(or,);
1478 case_rrw(or,);
1479 case_rrr(xor,);
1480 case_rrw(xor,);
1481 case_rr(trunc, _f_i);
1482 case_rr(trunc, _d_i);
1483 case_rr(trunc, _f_l);
1484 case_rr(trunc, _d_l);
1485 case_rr(ld, _c);
1486 case_rw(ld, _c);
1487 case_rr(ld, _uc);
1488 case_rw(ld, _uc);
1489 case_rr(ld, _s);
1490 case_rw(ld, _s);
1491 case_rr(ld, _us);
1492 case_rw(ld, _us);
1493 case_rr(ld, _i);
1494 case_rw(ld, _i);
1495 case_rr(ld, _ui);
1496 case_rw(ld, _ui);
1497 case_rr(ld, _l);
1498 case_rw(ld, _l);
1499 case_rrr(ldx, _c);
1500 case_rrw(ldx, _c);
1501 case_rrr(ldx, _uc);
1502 case_rrw(ldx, _uc);
1503 case_rrr(ldx, _s);
1504 case_rrw(ldx, _s);
1505 case_rrr(ldx, _us);
1506 case_rrw(ldx, _us);
1507 case_rrr(ldx, _i);
1508 case_rrw(ldx, _i);
1509 case_rrr(ldx, _ui);
1510 case_rrw(ldx, _ui);
1511 case_rrr(ldx, _l);
1512 case_rrw(ldx, _l);
ba86ff93
PC
1513 case jit_code_unldr:
1514 unldr(rn(node->u.w), rn(node->v.w), node->w.w);
1515 break;
1516 case jit_code_unldi:
1517 unldi(rn(node->u.w), node->v.w, node->w.w);
1518 break;
1519 case jit_code_unldr_u:
1520 unldr_u(rn(node->u.w), rn(node->v.w), node->w.w);
1521 break;
1522 case jit_code_unldi_u:
1523 unldi_u(rn(node->u.w), node->v.w, node->w.w);
1524 break;
4a71579b
PC
1525 case_rr(st, _c);
1526 case_wr(st, _c);
1527 case_rr(st, _s);
1528 case_wr(st, _s);
1529 case_rr(st, _i);
1530 case_wr(st, _i);
1531 case_rr(st, _l);
1532 case_wr(st, _l);
1533 case_rrr(stx, _c);
1534 case_wrr(stx, _c);
1535 case_rrr(stx, _s);
1536 case_wrr(stx, _s);
1537 case_rrr(stx, _i);
1538 case_wrr(stx, _i);
1539 case_rrr(stx, _l);
1540 case_wrr(stx, _l);
ba86ff93
PC
1541 case jit_code_unstr:
1542 unstr(rn(node->u.w), rn(node->v.w), node->w.w);
1543 break;
1544 case jit_code_unsti:
1545 unsti(node->u.w, rn(node->v.w), node->w.w);
1546 break;
4a71579b
PC
1547 case_rr(hton, _us);
1548 case_rr(hton, _ui);
1549 case_rr(hton, _ul);
40a44dcb
PC
1550 case_rr(bswap, _us);
1551 case_rr(bswap, _ui);
1552 case_rr(bswap, _ul);
ba86ff93
PC
1553 case jit_code_extr:
1554 extr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1555 break;
1556 case jit_code_extr_u:
1557 extr_u(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1558 break;
1559 case jit_code_depr:
1560 depr(rn(node->u.w), rn(node->v.w), node->w.q.l, node->w.q.h);
1561 break;
1562 case jit_code_depi:
1563 depi(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
1564 break;
4a71579b
PC
1565 case_rr(ext, _c);
1566 case_rr(ext, _uc);
1567 case_rr(ext, _s);
1568 case_rr(ext, _us);
1569 case_rr(ext, _i);
1570 case_rr(ext, _ui);
ba3814c1
PC
1571 case jit_code_casr:
1572 casr(rn(node->u.w), rn(node->v.w),
1573 rn(node->w.q.l), rn(node->w.q.h));
1574 break;
1575 case jit_code_casi:
1576 casi(rn(node->u.w), node->v.w,
1577 rn(node->w.q.l), rn(node->w.q.h));
1578 break;
4a71579b 1579 case_rr(mov,);
e0659411
PC
1580 case_rrr(movn,);
1581 case_rrr(movz,);
4a71579b
PC
1582 case jit_code_movi:
1583 if (node->flag & jit_flag_node) {
1584 temp = node->v.n;
1585 if (temp->code == jit_code_data ||
1586 (temp->code == jit_code_label &&
1587 (temp->flag & jit_flag_patch)))
1588 movi(rn(node->u.w), temp->u.w);
1589 else {
1590 assert(temp->code == jit_code_label ||
1591 temp->code == jit_code_epilog);
1592 word = movi_p(rn(node->u.w), temp->u.w);
1593 patch(word, node);
1594 }
1595 }
1596 else
1597 movi(rn(node->u.w), node->v.w);
1598 break;
1599 case_rrr(lt,);
1600 case_rrw(lt,);
1601 case_rrr(lt, _u);
1602 case_rrw(lt, _u);
1603 case_rrr(le,);
1604 case_rrw(le,);
1605 case_rrr(le, _u);
1606 case_rrw(le, _u);
1607 case_rrr(eq,);
1608 case_rrw(eq,);
1609 case_rrr(ge,);
1610 case_rrw(ge,);
1611 case_rrr(ge, _u);
1612 case_rrw(ge, _u);
1613 case_rrr(gt,);
1614 case_rrw(gt,);
1615 case_rrr(gt, _u);
1616 case_rrw(gt, _u);
1617 case_rrr(ne,);
1618 case_rrw(ne,);
1619 case_brr(blt,);
1620 case_brw(blt,);
1621 case_brr(blt, _u);
1622 case_brw(blt, _u);
1623 case_brr(ble,);
1624 case_brw(ble,);
1625 case_brr(ble, _u);
1626 case_brw(ble, _u);
1627 case_brr(beq,);
1628 case_brw(beq,);
1629 case_brr(bge,);
1630 case_brw(bge,);
1631 case_brr(bge, _u);
1632 case_brw(bge, _u);
1633 case_brr(bgt,);
1634 case_brw(bgt,);
1635 case_brr(bgt, _u);
1636 case_brw(bgt, _u);
1637 case_brr(bne,);
1638 case_brw(bne,);
1639 case_brr(boadd,);
1640 case_brw(boadd,);
1641 case_brr(boadd, _u);
1642 case_brw(boadd, _u);
1643 case_brr(bxadd,);
1644 case_brw(bxadd,);
1645 case_brr(bxadd, _u);
1646 case_brw(bxadd, _u);
1647 case_brr(bosub,);
1648 case_brw(bosub,);
1649 case_brr(bosub, _u);
1650 case_brw(bosub, _u);
1651 case_brr(bxsub,);
1652 case_brw(bxsub,);
1653 case_brr(bxsub, _u);
1654 case_brw(bxsub, _u);
1655 case_brr(bms,);
1656 case_brw(bms,);
1657 case_brr(bmc,);
1658 case_brw(bmc,);
1659 case_rrr(add, _f);
1660 case_rrf(add);
1661 case_rrr(sub, _f);
1662 case_rrf(sub);
1663 case_rrf(rsb);
1664 case_rrr(mul, _f);
1665 case_rrf(mul);
1666 case_rrr(div, _f);
1667 case_rrf(div);
1668 case_rr(abs, _f);
1669 case_rr(neg, _f);
1670 case_rr(sqrt, _f);
ba86ff93
PC
1671 case_rqr(fma, _f);
1672 case_rqr(fms, _f);
1673 case_rqr(fnma, _f);
1674 case_rqr(fnms, _f);
4a71579b
PC
1675 case_rr(ext, _f);
1676 case_rr(ld, _f);
1677 case_rw(ld, _f);
1678 case_rrr(ldx, _f);
1679 case_rrw(ldx, _f);
ba86ff93
PC
1680 case jit_code_unldr_x:
1681 unldr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1682 break;
1683 case jit_code_unldi_x:
1684 unldi_x(rn(node->u.w), node->v.w, node->w.w);
1685 break;
4a71579b
PC
1686 case_rr(st, _f);
1687 case_wr(st, _f);
1688 case_rrr(stx, _f);
1689 case_wrr(stx, _f);
ba86ff93
PC
1690 case jit_code_unstr_x:
1691 unstr_x(rn(node->u.w), rn(node->v.w), node->w.w);
1692 break;
1693 case jit_code_unsti_x:
1694 unsti_x(node->u.w, rn(node->v.w), node->w.w);
1695 break;
4a71579b
PC
1696 case_rr(mov, _f);
1697 case jit_code_movi_f:
1698 assert_data(node);
1699 movi_f(rn(node->u.w), node->v.f);
1700 break;
1701 case_rr(ext, _d_f);
1702 case_rrr(lt, _f);
1703 case_rrf(lt);
1704 case_rrr(le, _f);
1705 case_rrf(le);
1706 case_rrr(eq, _f);
1707 case_rrf(eq);
1708 case_rrr(ge, _f);
1709 case_rrf(ge);
1710 case_rrr(gt, _f);
1711 case_rrf(gt);
1712 case_rrr(ne, _f);
1713 case_rrf(ne);
1714 case_rrr(unlt, _f);
1715 case_rrf(unlt);
1716 case_rrr(unle, _f);
1717 case_rrf(unle);
1718 case_rrr(uneq, _f);
1719 case_rrf(uneq);
1720 case_rrr(unge, _f);
1721 case_rrf(unge);
1722 case_rrr(ungt, _f);
1723 case_rrf(ungt);
1724 case_rrr(ltgt, _f);
1725 case_rrf(ltgt);
1726 case_rrr(ord, _f);
1727 case_rrf(ord);
1728 case_rrr(unord, _f);
1729 case_rrf(unord);
1730 case_brr(blt, _f);
1731 case_brf(blt);
1732 case_brr(ble, _f);
1733 case_brf(ble);
1734 case_brr(beq, _f);
1735 case_brf(beq);
1736 case_brr(bge, _f);
1737 case_brf(bge);
1738 case_brr(bgt, _f);
1739 case_brf(bgt);
1740 case_brr(bne, _f);
1741 case_brf(bne);
1742 case_brr(bunlt, _f);
1743 case_brf(bunlt);
1744 case_brr(bunle, _f);
1745 case_brf(bunle);
1746 case_brr(buneq, _f);
1747 case_brf(buneq);
1748 case_brr(bunge, _f);
1749 case_brf(bunge);
1750 case_brr(bungt, _f);
1751 case_brf(bungt);
1752 case_brr(bltgt, _f);
1753 case_brf(bltgt);
1754 case_brr(bord, _f);
1755 case_brf(bord);
1756 case_brr(bunord, _f);
1757 case_brf(bunord);
1758 case_rrr(add, _d);
1759 case_rrd(add);
1760 case_rrr(sub, _d);
1761 case_rrd(sub);
1762 case_rrd(rsb);
1763 case_rrr(mul, _d);
1764 case_rrd(mul);
1765 case_rrr(div, _d);
1766 case_rrd(div);
1767 case_rr(abs, _d);
1768 case_rr(neg, _d);
1769 case_rr(sqrt, _d);
ba86ff93
PC
1770 case_rqr(fma, _d);
1771 case_rqr(fms, _d);
1772 case_rqr(fnma, _d);
1773 case_rqr(fnms, _d);
4a71579b
PC
1774 case_rr(ext, _d);
1775 case_rr(ld, _d);
1776 case_rw(ld, _d);
1777 case_rrr(ldx, _d);
1778 case_rrw(ldx, _d);
1779 case_rr(st, _d);
1780 case_wr(st, _d);
1781 case_rrr(stx, _d);
1782 case_wrr(stx, _d);
1783 case_rr(mov, _d);
1784 case jit_code_movi_d:
1785 assert_data(node);
1786 movi_d(rn(node->u.w), node->v.d);
1787 break;
1788 case_rr(ext, _f_d);
1789 case_rrr(lt, _d);
1790 case_rrd(lt);
1791 case_rrr(le, _d);
1792 case_rrd(le);
1793 case_rrr(eq, _d);
1794 case_rrd(eq);
1795 case_rrr(ge, _d);
1796 case_rrd(ge);
1797 case_rrr(gt, _d);
1798 case_rrd(gt);
1799 case_rrr(ne, _d);
1800 case_rrd(ne);
1801 case_rrr(unlt, _d);
1802 case_rrd(unlt);
1803 case_rrr(unle, _d);
1804 case_rrd(unle);
1805 case_rrr(uneq, _d);
1806 case_rrd(uneq);
1807 case_rrr(unge, _d);
1808 case_rrd(unge);
1809 case_rrr(ungt, _d);
1810 case_rrd(ungt);
1811 case_rrr(ltgt, _d);
1812 case_rrd(ltgt);
1813 case_rrr(ord, _d);
1814 case_rrd(ord);
1815 case_rrr(unord, _d);
1816 case_rrd(unord);
1817 case_brr(blt, _d);
1818 case_brd(blt);
1819 case_brr(ble, _d);
1820 case_brd(ble);
1821 case_brr(beq, _d);
1822 case_brd(beq);
1823 case_brr(bge, _d);
1824 case_brd(bge);
1825 case_brr(bgt, _d);
1826 case_brd(bgt);
1827 case_brr(bne, _d);
1828 case_brd(bne);
1829 case_brr(bunlt, _d);
1830 case_brd(bunlt);
1831 case_brr(bunle, _d);
1832 case_brd(bunle);
1833 case_brr(buneq, _d);
1834 case_brd(buneq);
1835 case_brr(bunge, _d);
1836 case_brd(bunge);
1837 case_brr(bungt, _d);
1838 case_brd(bungt);
1839 case_brr(bltgt, _d);
1840 case_brd(bltgt);
1841 case_brr(bord, _d);
1842 case_brd(bord);
1843 case_brr(bunord, _d);
1844 case_brd(bunord);
1845 case jit_code_jmpr:
79bfeef6 1846 jit_check_frame();
4a71579b
PC
1847 jmpr(rn(node->u.w));
1848 break;
1849 case jit_code_jmpi:
1850 if (node->flag & jit_flag_node) {
1851 temp = node->u.n;
1852 assert(temp->code == jit_code_label ||
1853 temp->code == jit_code_epilog);
1854 if (temp->flag & jit_flag_patch)
1855 jmpi(temp->u.w);
1856 else {
79bfeef6
PC
1857 word = _jit->code.length -
1858 (_jit->pc.uc - _jit->code.ptr);
1859 if (s26_p(word))
1860 word = jmpi(_jit->pc.w);
1861 else
1862 word = jmpi_p(_jit->pc.w);
4a71579b
PC
1863 patch(word, node);
1864 }
1865 }
79bfeef6
PC
1866 else {
1867 jit_check_frame();
4a71579b 1868 jmpi(node->u.w);
79bfeef6 1869 }
4a71579b
PC
1870 break;
1871 case jit_code_callr:
79bfeef6 1872 jit_check_frame();
4a71579b
PC
1873 callr(rn(node->u.w));
1874 break;
1875 case jit_code_calli:
79bfeef6 1876 jit_check_frame();
4a71579b
PC
1877 if (node->flag & jit_flag_node) {
1878 temp = node->u.n;
1879 assert(temp->code == jit_code_label ||
1880 temp->code == jit_code_epilog);
1881 if (temp->flag & jit_flag_patch)
1882 calli(temp->u.w);
1883 else {
79bfeef6
PC
1884 word = _jit->code.length -
1885 (_jit->pc.uc - _jit->code.ptr);
1886 if (s26_p(word))
1887 word = calli(_jit->pc.w);
1888 else
1889 word = calli_p(_jit->pc.w);
4a71579b
PC
1890 patch(word, node);
1891 }
1892 }
1893 else
1894 calli(node->u.w);
1895 break;
1896 case jit_code_prolog:
1897 _jitc->function = _jitc->functions.ptr + node->w.w;
1898 undo.node = node;
1899 undo.word = _jit->pc.w;
79bfeef6 1900 memcpy(&undo.func, _jitc->function, sizeof(undo.func));
4a71579b
PC
1901#if DEVEL_DISASSEMBLER
1902 undo.prevw = prevw;
1903#endif
1904 undo.patch_offset = _jitc->patches.offset;
1905 restart_function:
79bfeef6
PC
1906 compute_framesize();
1907 patch_alist(0);
4a71579b
PC
1908 _jitc->again = 0;
1909 prolog(node);
1910 break;
1911 case jit_code_epilog:
1912 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1913 if (_jitc->again) {
1914 for (temp = undo.node->next;
1915 temp != node; temp = temp->next) {
1916 if (temp->code == jit_code_label ||
1917 temp->code == jit_code_epilog)
1918 temp->flag &= ~jit_flag_patch;
1919 }
1920 temp->flag &= ~jit_flag_patch;
1921 node = undo.node;
1922 _jit->pc.w = undo.word;
79bfeef6
PC
1923 /* undo.func.self.aoff and undo.func.regset should not
1924 * be undone, as they will be further updated, and are
1925 * the reason of the undo. */
1926 undo.func.self.aoff = _jitc->function->frame +
1927 _jitc->function->self.aoff;
1928 undo.func.need_frame = _jitc->function->need_frame;
1929 jit_regset_set(&undo.func.regset, &_jitc->function->regset);
1930 /* allocar information also does not need to be undone */
1931 undo.func.aoffoff = _jitc->function->aoffoff;
1932 undo.func.allocar = _jitc->function->allocar;
1933 memcpy(_jitc->function, &undo.func, sizeof(undo.func));
4a71579b
PC
1934#if DEVEL_DISASSEMBLER
1935 prevw = undo.prevw;
1936#endif
1937 _jitc->patches.offset = undo.patch_offset;
79bfeef6 1938 patch_alist(1);
4a71579b
PC
1939 goto restart_function;
1940 }
1941 /* remember label is defined */
1942 node->flag |= jit_flag_patch;
1943 node->u.w = _jit->pc.w;
1944 epilog(node);
1945 _jitc->function = NULL;
1946 break;
ba86ff93
PC
1947 case jit_code_movr_w_f:
1948 movr_w_f(rn(node->u.w), rn(node->v.w));
1949 break;
1950 case jit_code_movr_f_w:
1951 movr_f_w(rn(node->u.w), rn(node->v.w));
1952 break;
1953 case jit_code_movi_f_w:
1954 movi_f_w(rn(node->u.w), node->v.f);
1955 break;
1956 case jit_code_movi_w_f:
1957 movi_w_f(rn(node->u.w), node->v.w);
1958 break;
1959 case jit_code_movr_w_d:
1960 movr_w_d(rn(node->u.w), rn(node->v.w));
1961 break;
1962 case jit_code_movr_d_w:
1963 movr_d_w(rn(node->u.w), rn(node->v.w));
1964 break;
1965 case jit_code_movi_d_w:
1966 movi_d_w(rn(node->u.w), node->v.d);
1967 break;
1968 case jit_code_movi_w_d:
1969 movi_w_d(rn(node->u.w), node->v.w);
1970 break;
4a71579b
PC
1971 case jit_code_va_start:
1972 vastart(rn(node->u.w));
1973 break;
1974 case jit_code_va_arg:
1975 vaarg(rn(node->u.w), rn(node->v.w));
1976 break;
1977 case jit_code_va_arg_d:
1978 vaarg_d(rn(node->u.w), rn(node->v.w));
1979 break;
1980 case jit_code_live: case jit_code_ellipsis:
1981 case jit_code_va_push:
1982 case jit_code_allocai: case jit_code_allocar:
79bfeef6
PC
1983 case jit_code_arg_c: case jit_code_arg_s:
1984 case jit_code_arg_i:
1985# if __WORDSIZE == 64
1986 case jit_code_arg_l:
1987# endif
4a71579b
PC
1988 case jit_code_arg_f: case jit_code_arg_d:
1989 case jit_code_va_end:
1990 case jit_code_ret:
79bfeef6
PC
1991 case jit_code_retr_c: case jit_code_reti_c:
1992 case jit_code_retr_uc: case jit_code_reti_uc:
1993 case jit_code_retr_s: case jit_code_reti_s:
1994 case jit_code_retr_us: case jit_code_reti_us:
1995 case jit_code_retr_i: case jit_code_reti_i:
1996#if __WORDSIZE == 64
1997 case jit_code_retr_ui: case jit_code_reti_ui:
1998 case jit_code_retr_l: case jit_code_reti_l:
1999#endif
4a71579b
PC
2000 case jit_code_retr_f: case jit_code_reti_f:
2001 case jit_code_retr_d: case jit_code_reti_d:
2002 case jit_code_getarg_c: case jit_code_getarg_uc:
2003 case jit_code_getarg_s: case jit_code_getarg_us:
2004 case jit_code_getarg_i: case jit_code_getarg_ui:
2005 case jit_code_getarg_l:
2006 case jit_code_getarg_f: case jit_code_getarg_d:
79bfeef6
PC
2007 case jit_code_putargr_c: case jit_code_putargi_c:
2008 case jit_code_putargr_uc: case jit_code_putargi_uc:
2009 case jit_code_putargr_s: case jit_code_putargi_s:
2010 case jit_code_putargr_us: case jit_code_putargi_us:
2011 case jit_code_putargr_i: case jit_code_putargi_i:
2012#if __WORDSIZE == 64
2013 case jit_code_putargr_ui: case jit_code_putargi_ui:
2014 case jit_code_putargr_l: case jit_code_putargi_l:
2015#endif
4a71579b
PC
2016 case jit_code_putargr_f: case jit_code_putargi_f:
2017 case jit_code_putargr_d: case jit_code_putargi_d:
79bfeef6
PC
2018 case jit_code_pushargr_c: case jit_code_pushargi_c:
2019 case jit_code_pushargr_uc: case jit_code_pushargi_uc:
2020 case jit_code_pushargr_s: case jit_code_pushargi_s:
2021 case jit_code_pushargr_us: case jit_code_pushargi_us:
2022 case jit_code_pushargr_i: case jit_code_pushargi_i:
2023#if __WORDSIZE == 64
2024 case jit_code_pushargr_ui: case jit_code_pushargi_ui:
2025 case jit_code_pushargr_l: case jit_code_pushargi_l:
2026#endif
4a71579b
PC
2027 case jit_code_pushargr_f: case jit_code_pushargi_f:
2028 case jit_code_pushargr_d: case jit_code_pushargi_d:
2029 case jit_code_retval_c: case jit_code_retval_uc:
2030 case jit_code_retval_s: case jit_code_retval_us:
2031 case jit_code_retval_i:
79bfeef6 2032#if __WORDSIZE == 64
4a71579b 2033 case jit_code_retval_ui: case jit_code_retval_l:
79bfeef6 2034#endif
4a71579b
PC
2035 case jit_code_retval_f: case jit_code_retval_d:
2036 case jit_code_prepare:
2037 case jit_code_finishr: case jit_code_finishi:
ba86ff93
PC
2038 case jit_code_negi_f: case jit_code_absi_f:
2039 case jit_code_sqrti_f: case jit_code_negi_d:
2040 case jit_code_absi_d: case jit_code_sqrti_d:
2041 break;
2042 case jit_code_negi:
2043 negi(rn(node->u.w), node->v.w);
2044 break;
2045 case jit_code_comi:
2046 comi(rn(node->u.w), node->v.w);
2047 break;
2048 case jit_code_exti_c:
2049 exti_c(rn(node->u.w), node->v.w);
2050 break;
2051 case jit_code_exti_uc:
2052 exti_uc(rn(node->u.w), node->v.w);
2053 break;
2054 case jit_code_exti_s:
2055 exti_s(rn(node->u.w), node->v.w);
2056 break;
2057 case jit_code_exti_us:
2058 exti_us(rn(node->u.w), node->v.w);
2059 break;
2060 case jit_code_bswapi_us:
2061 bswapi_us(rn(node->u.w), node->v.w);
2062 break;
2063 case jit_code_bswapi_ui:
2064 bswapi_ui(rn(node->u.w), node->v.w);
2065 break;
2066 case jit_code_htoni_us:
2067 htoni_us(rn(node->u.w), node->v.w);
2068 break;
2069 case jit_code_htoni_ui:
2070 htoni_ui(rn(node->u.w), node->v.w);
2071 break;
2072#if __WORDSIZE == 64
2073 case jit_code_exti_i:
2074 exti_i(rn(node->u.w), node->v.w);
2075 break;
2076 case jit_code_exti_ui:
2077 exti_ui(rn(node->u.w), node->v.w);
2078 break;
2079 case jit_code_bswapi_ul:
2080 bswapi_ul(rn(node->u.w), node->v.w);
2081 break;
2082 case jit_code_htoni_ul:
2083 htoni_ul(rn(node->u.w), node->v.w);
2084 break;
2085#endif
2086 case jit_code_cloi:
2087 cloi(rn(node->u.w), node->v.w);
2088 break;
2089 case jit_code_clzi:
2090 clzi(rn(node->u.w), node->v.w);
2091 break;
2092 case jit_code_ctoi:
2093 ctoi(rn(node->u.w), node->v.w);
2094 break;
2095 case jit_code_ctzi:
2096 ctzi(rn(node->u.w), node->v.w);
2097 break;
2098 case jit_code_rbiti:
2099 rbiti(rn(node->u.w), node->v.w);
2100 break;
2101 case jit_code_popcnti:
2102 popcnti(rn(node->u.w), node->v.w);
2103 break;
2104 case jit_code_exti:
2105 exti(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
2106 break;
2107 case jit_code_exti_u:
2108 exti_u(rn(node->u.w), node->v.w, node->w.q.l, node->w.q.h);
4a71579b
PC
2109 break;
2110 default:
2111 abort();
2112 }
2113 jit_regarg_clr(node, value);
2114 assert(_jitc->regarg == 0 && _jitc->synth == 0);
2115 /* update register live state */
2116 jit_reglive(node);
2117 }
2118#undef case_brw
2119#undef case_brr
2120#undef case_wrr
2121#undef case_rrw
2122#undef case_rrr
2123#undef case_wr
2124#undef case_rw
2125#undef case_rr
2126
2127 for (offset = 0; offset < _jitc->patches.offset; offset++) {
2128 node = _jitc->patches.ptr[offset].node;
2129 word = _jitc->patches.ptr[offset].inst;
2130 value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
2131 patch_at(word, value);
2132 }
2133
2134 jit_flush(_jit->code.ptr, _jit->pc.uc);
2135
2136 return (_jit->code.ptr);
2137}
2138
2139#define CODE 1
2140# include "jit_aarch64-cpu.c"
2141# include "jit_aarch64-fpu.c"
2142#undef CODE
2143
2144void
2145jit_flush(void *fptr, void *tptr)
2146{
2147#if defined(__GNUC__)
2148 jit_word_t f, t, s;
2149
2150 s = sysconf(_SC_PAGE_SIZE);
2151 f = (jit_word_t)fptr & -s;
2152 t = (((jit_word_t)tptr) + s - 1) & -s;
2153 __clear_cache((void *)f, (void *)t);
2154#endif
2155}
2156
2157void
2158_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2159{
2160 ldxi(rn(r0), rn(r1), i0);
2161}
2162
2163void
2164_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2165{
2166 stxi(i0, rn(r0), rn(r1));
2167}
2168
2169void
2170_emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
2171{
2172 ldxi_d(rn(r0), rn(r1), i0);
2173}
2174
2175void
2176_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
2177{
2178 stxi_d(i0, rn(r0), rn(r1));
2179}
2180
79bfeef6
PC
2181static void
2182_compute_framesize(jit_state_t *_jit)
2183{
2184 jit_int32_t reg;
2185 _jitc->framesize = 16; /* ra+fp */
2186 for (reg = 0; reg < jit_size(iregs); reg++)
2187 if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg]))
2188 _jitc->framesize += sizeof(jit_word_t);
2189
2190 for (reg = 0; reg < jit_size(fregs); reg++)
2191 if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg]))
2192 _jitc->framesize += sizeof(jit_float64_t);
2193
2194 /* Make sure functions called have a 16 byte aligned stack */
2195 _jitc->framesize = (_jitc->framesize + 15) & -16;
2196}
2197
4a71579b
PC
2198static void
2199_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
2200{
2201 jit_int32_t flag;
2202
2203 assert(node->flag & jit_flag_node);
2204 if (node->code == jit_code_movi)
2205 flag = node->v.n->flag;
2206 else
2207 flag = node->u.n->flag;
2208 assert(!(flag & jit_flag_patch));
2209 if (_jitc->patches.offset >= _jitc->patches.length) {
2210 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
2211 _jitc->patches.length * sizeof(jit_patch_t),
2212 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
2213 _jitc->patches.length += 1024;
2214 }
2215 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
2216 _jitc->patches.ptr[_jitc->patches.offset].node = node;
2217 ++_jitc->patches.offset;
2218}