Update lightrec 20220910 (#686)
[pcsx_rearmed.git] / deps / lightning / lib / jit_riscv.c
CommitLineData
4a71579b
PC
1/*
2 * Copyright (C) 2019 Free Software Foundation, Inc.
3 *
4 * This file is part of GNU lightning.
5 *
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
15 *
16 * Authors:
17 * Paulo Cesar Pereira de Andrade
18 */
19
20#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8)
21#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8)
22
23/*
24 * Types
25 */
26typedef jit_pointer_t jit_va_list_t;
27
28/*
29 * Prototypes
30 */
31#define patch(instr, node) _patch(_jit, instr, node)
32static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
33
34#define PROTO 1
35# include "jit_riscv-cpu.c"
36# include "jit_riscv-fpu.c"
ba3814c1 37# include "jit_fallback.c"
4a71579b
PC
38#undef PROTO
39
40/*
41 * Initialization
42 */
43jit_register_t _rvs[] = {
44 { 0x00, "zero" },
45 { 0x01, "ra" },
46 { 0x02, "sp" },
47 { 0x03, "gp" },
48#if 0 /* Pretend it does not exist, so _NOREG can be used in
49 * a 64 bit bitmask */
50 { 0x04, "tp" },
51#endif
52 { rc(gpr) | 0x05, "t0" },
53 { rc(gpr) | 0x06, "t1" },
54 { rc(gpr) | 0x07, "t2" },
55 { rc(gpr) | 0x1c, "t3" },
56 { rc(gpr) | 0x1d, "t4" },
57 { rc(gpr) | 0x1e, "t5" },
58 { rc(gpr) | 0x1f, "t6" },
59 { 0x08, "fp" },
60 { rc(sav) | rc(gpr) | 0x09, "s1" },
61 { rc(sav) | rc(gpr) | 0x12, "s2" },
62 { rc(sav) | rc(gpr) | 0x13, "s3" },
63 { rc(sav) | rc(gpr) | 0x14, "s4" },
64 { rc(sav) | rc(gpr) | 0x15, "s5" },
65 { rc(sav) | rc(gpr) | 0x16, "s6" },
66 { rc(sav) | rc(gpr) | 0x17, "s7" },
67 { rc(sav) | rc(gpr) | 0x18, "s8" },
68 { rc(sav) | rc(gpr) | 0x19, "s9" },
69 { rc(sav) | rc(gpr) | 0x1a, "s10" },
70 { rc(sav) | rc(gpr) | 0x1b, "s11" },
71 { rc(arg) | rc(gpr) | 0x11, "a7" },
72 { rc(arg) | rc(gpr) | 0x10, "a6" },
73 { rc(arg) | rc(gpr) | 0x0f, "a5" },
74 { rc(arg) | rc(gpr) | 0x0e, "a4" },
75 { rc(arg) | rc(gpr) | 0x0d, "a3" },
76 { rc(arg) | rc(gpr) | 0x0c, "a2" },
77 { rc(arg) | rc(gpr) | 0x0b, "a1" },
78 { rc(arg) | rc(gpr) | 0x0a, "a0" },
79 { rc(fpr) | 0x00, "ft0" },
80 { rc(fpr) | 0x01, "ft1" },
81 { rc(fpr) | 0x02, "ft2" },
82 { rc(fpr) | 0x03, "ft3" },
83 { rc(fpr) | 0x04, "ft4" },
84 { rc(fpr) | 0x05, "ft5" },
85 { rc(fpr) | 0x06, "ft6" },
86 { rc(fpr) | 0x07, "ft7" },
87 { rc(fpr) | 0x1c, "ft8" },
88 { rc(fpr) | 0x1d, "ft9" },
89 { rc(fpr) | 0x1e, "ft10" },
90 { rc(fpr) | 0x1f, "ft11" },
91 { rc(sav) | rc(fpr) | 0x08, "fs0" },
92 { rc(sav) | rc(fpr) | 0x09, "fs1" },
93 { rc(sav) | rc(fpr) | 0x12, "fs2" },
94 { rc(sav) | rc(fpr) | 0x13, "fs3" },
95 { rc(sav) | rc(fpr) | 0x14, "fs4" },
96 { rc(sav) | rc(fpr) | 0x15, "fs5" },
97 { rc(sav) | rc(fpr) | 0x16, "fs6" },
98 { rc(sav) | rc(fpr) | 0x17, "fs7" },
99 { rc(sav) | rc(fpr) | 0x18, "fs8" },
100 { rc(sav) | rc(fpr) | 0x19, "fs9" },
101 { rc(sav) | rc(fpr) | 0x1a, "fs10" },
102 { rc(sav) | rc(fpr) | 0x1b, "fs11" },
103 { rc(arg) | rc(fpr) | 0x11, "fa7" },
104 { rc(arg) | rc(fpr) | 0x10, "fa6" },
105 { rc(arg) | rc(fpr) | 0x0f, "fa5" },
106 { rc(arg) | rc(fpr) | 0x0e, "fa4" },
107 { rc(arg) | rc(fpr) | 0x0d, "fa3" },
108 { rc(arg) | rc(fpr) | 0x0c, "fa2" },
109 { rc(arg) | rc(fpr) | 0x0b, "fa1" },
110 { rc(arg) | rc(fpr) | 0x0a, "fa0" },
111 { _NOREG, "<none>" },
112};
113
114/*
115 * Implementation
116 */
117void
118jit_get_cpu(void)
119{
120}
121
122void
123_jit_init(jit_state_t *_jit)
124{
125 _jitc->reglen = jit_size(_rvs) - 1;
126 jit_carry = _NOREG;
127}
128
129void
130_jit_prolog(jit_state_t *_jit)
131{
132 jit_int32_t offset;
133
134 if (_jitc->function)
135 jit_epilog();
136 assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
137 jit_regset_set_ui(&_jitc->regsav, 0);
138 offset = _jitc->functions.offset;
139 if (offset >= _jitc->functions.length) {
140 jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
141 _jitc->functions.length * sizeof(jit_function_t),
142 (_jitc->functions.length + 16) * sizeof(jit_function_t));
143 _jitc->functions.length += 16;
144 }
145 _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
146 _jitc->function->self.size = stack_framesize;
147 _jitc->function->self.argi = _jitc->function->self.argf =
148 _jitc->function->self.alen = 0;
149 _jitc->function->self.aoff = 0;
150 _jitc->function->self.call = jit_call_default;
151 jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
152 _jitc->reglen * sizeof(jit_int32_t));
153
154 /* _no_link here does not mean the jit_link() call can be removed
155 * by rewriting as:
156 * _jitc->function->prolog = jit_new_node(jit_code_prolog);
157 */
158 _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
159 jit_link(_jitc->function->prolog);
160 _jitc->function->prolog->w.w = offset;
161 _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
162 /* u: label value
163 * v: offset in blocks vector
164 * w: offset in functions vector
165 */
166 _jitc->function->epilog->w.w = offset;
167
168 jit_regset_new(&_jitc->function->regset);
169}
170
171jit_int32_t
172_jit_allocai(jit_state_t *_jit, jit_int32_t length)
173{
174 assert(_jitc->function);
175 switch (length) {
176 case 0: case 1: break;
177 case 2: _jitc->function->self.aoff &= -2; break;
178 case 3: case 4: _jitc->function->self.aoff &= -4; break;
179 default: _jitc->function->self.aoff &= -8; break;
180 }
181 _jitc->function->self.aoff -= length;
182 if (!_jitc->realize) {
183 jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
184 jit_dec_synth();
185 }
186 return (_jitc->function->self.aoff);
187}
188
189void
190_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
191{
192 jit_int32_t r0;
193 assert(_jitc->function);
194 jit_inc_synth_ww(allocar, u, v);
195 if (!_jitc->function->allocar) {
196 _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
197 _jitc->function->allocar = 1;
198 }
199 r0 = jit_get_reg(jit_class_gpr);
200 jit_negr(r0, v);
201 jit_andi(r0, r0, -16);
202 jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
203 jit_addr(u, u, r0);
204 jit_addr(JIT_SP, JIT_SP, r0);
205 jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
206 jit_unget_reg(r0);
207 jit_dec_synth();
208}
209
210void
211_jit_ret(jit_state_t *_jit)
212{
213 jit_node_t *instr;
214 assert(_jitc->function);
215 jit_inc_synth(ret);
216 /* jump to epilog */
217 instr = jit_jmpi();
218 jit_patch_at(instr, _jitc->function->epilog);
219 jit_dec_synth();
220}
221
222void
223_jit_retr(jit_state_t *_jit, jit_int32_t u)
224{
225 jit_inc_synth_w(retr, u);
226 if (JIT_RET != u)
227 jit_movr(JIT_RET, u);
228 jit_live(JIT_RET);
229 jit_ret();
230 jit_dec_synth();
231}
232
233void
234_jit_reti(jit_state_t *_jit, jit_word_t u)
235{
236 jit_inc_synth_w(reti, u);
237 jit_movi(JIT_RET, u);
238 jit_ret();
239 jit_dec_synth();
240}
241
242void
243_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
244{
245 jit_inc_synth_w(retr_f, u);
246 if (u != JIT_FRET)
247 jit_movr_f(JIT_FRET, u);
248 else
249 jit_live(JIT_FRET);
250 jit_ret();
251 jit_dec_synth();
252}
253
254void
255_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
256{
257 jit_inc_synth_f(reti_f, u);
258 jit_movi_f(JIT_FRET, u);
259 jit_ret();
260 jit_dec_synth();
261}
262
263void
264_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
265{
266 jit_inc_synth_w(retr_d, u);
267 if (u != JIT_FRET)
268 jit_movr_d(JIT_FRET, u);
269 else
270 jit_live(JIT_FRET);
271 jit_ret();
272 jit_dec_synth();
273}
274
275void
276_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
277{
278 jit_inc_synth_d(reti_d, u);
279 jit_movi_d(JIT_FRET, u);
280 jit_ret();
281 jit_dec_synth();
282}
283
284void
285_jit_epilog(jit_state_t *_jit)
286{
287 assert(_jitc->function);
288 assert(_jitc->function->epilog->next == NULL);
289 jit_link(_jitc->function->epilog);
290 _jitc->function = NULL;
291}
292
293jit_bool_t
294_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
295{
296 if (u->code == jit_code_arg)
297 return (jit_arg_reg_p(u->u.w));
298 assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
299 return (jit_arg_f_reg_p(u->u.w));
300}
301
302void
303_jit_ellipsis(jit_state_t *_jit)
304{
305 jit_inc_synth(ellipsis);
306 if (_jitc->prepare) {
307 jit_link_prepare();
308 assert(!(_jitc->function->call.call & jit_call_varargs));
309 _jitc->function->call.call |= jit_call_varargs;
310 }
311 else {
312 jit_link_prolog();
313 assert(!(_jitc->function->self.call & jit_call_varargs));
314 _jitc->function->self.call |= jit_call_varargs;
315 _jitc->function->vagp = _jitc->function->self.argi;
316 }
317 jit_dec_synth();
318}
319
320void
321_jit_va_push(jit_state_t *_jit, jit_int32_t u)
322{
323 jit_inc_synth_w(va_push, u);
324 jit_pushargr(u);
325 jit_dec_synth();
326}
327
328jit_node_t *
329_jit_arg(jit_state_t *_jit)
330{
331 jit_node_t *node;
332 jit_int32_t offset;
333 assert(_jitc->function);
334 assert(!(_jitc->function->self.call & jit_call_varargs));
335 if (jit_arg_reg_p(_jitc->function->self.argi))
336 offset = _jitc->function->self.argi++;
337 else {
338 offset = _jitc->function->self.size;
339 _jitc->function->self.size += sizeof(jit_word_t);
340 }
341 node = jit_new_node_ww(jit_code_arg, offset,
342 ++_jitc->function->self.argn);
343 jit_link_prolog();
344 return (node);
345}
346
347jit_node_t *
348_jit_arg_f(jit_state_t *_jit)
349{
350 jit_node_t *node;
351 jit_int32_t offset;
352 assert(_jitc->function);
353 assert(!(_jitc->function->self.call & jit_call_varargs));
354 if (jit_arg_f_reg_p(_jitc->function->self.argf))
355 offset = _jitc->function->self.argf++;
356 else if (jit_arg_reg_p(_jitc->function->self.argi)) {
357 offset = _jitc->function->self.argi++;
358 offset += 8;
359 }
360 else {
361 offset = _jitc->function->self.size;
362 _jitc->function->self.size += sizeof(jit_word_t);
363 }
364 node = jit_new_node_ww(jit_code_arg_f, offset,
365 ++_jitc->function->self.argn);
366 jit_link_prolog();
367 return (node);
368}
369
370jit_node_t *
371_jit_arg_d(jit_state_t *_jit)
372{
373 jit_node_t *node;
374 jit_int32_t offset;
375 assert(_jitc->function);
376 assert(!(_jitc->function->self.call & jit_call_varargs));
377 if (jit_arg_f_reg_p(_jitc->function->self.argf))
378 offset = _jitc->function->self.argf++;
379 else if (jit_arg_reg_p(_jitc->function->self.argi)) {
380 offset = _jitc->function->self.argi++;
381 offset += 8;
382 }
383 else {
384 offset = _jitc->function->self.size;
385 _jitc->function->self.size += sizeof(jit_word_t);
386 }
387 node = jit_new_node_ww(jit_code_arg_d, offset,
388 ++_jitc->function->self.argn);
389 jit_link_prolog();
390 return (node);
391}
392
393void
394_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
395{
396 assert(v->code == jit_code_arg);
397 jit_inc_synth_wp(getarg_c, u, v);
398 if (jit_arg_reg_p(v->u.w))
399 jit_extr_c(u, JIT_RA0 - v->u.w);
400 else
401 jit_ldxi_c(u, JIT_FP, v->u.w);
402 jit_dec_synth();
403}
404
405void
406_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
407{
408 assert(v->code == jit_code_arg);
409 jit_inc_synth_wp(getarg_uc, u, v);
410 if (jit_arg_reg_p(v->u.w))
411 jit_extr_uc(u, JIT_RA0 - v->u.w);
412 else
413 jit_ldxi_uc(u, JIT_FP, v->u.w);
414 jit_dec_synth();
415}
416
417void
418_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
419{
420 assert(v->code == jit_code_arg);
421 jit_inc_synth_wp(getarg_s, u, v);
422 if (jit_arg_reg_p(v->u.w))
423 jit_extr_s(u, JIT_RA0 - v->u.w);
424 else
425 jit_ldxi_s(u, JIT_FP, v->u.w);
426 jit_dec_synth();
427}
428
429void
430_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
431{
432 assert(v->code == jit_code_arg);
433 jit_inc_synth_wp(getarg_us, u, v);
434 if (jit_arg_reg_p(v->u.w))
435 jit_extr_us(u, JIT_RA0 - v->u.w);
436 else
437 jit_ldxi_us(u, JIT_FP, v->u.w);
438 jit_dec_synth();
439}
440
441void
442_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
443{
444 assert(v->code == jit_code_arg);
445 jit_inc_synth_wp(getarg_i, u, v);
446 if (jit_arg_reg_p(v->u.w))
447 jit_extr_i(u, JIT_RA0 - v->u.w);
448 else
449 jit_ldxi_i(u, JIT_FP, v->u.w);
450 jit_dec_synth();
451}
452
453void
454_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
455{
456 assert(v->code == jit_code_arg);
457 jit_inc_synth_wp(getarg_ui, u, v);
458 if (jit_arg_reg_p(v->u.w))
459 jit_extr_ui(u, JIT_RA0 - v->u.w);
460 else
461 jit_ldxi_ui(u, JIT_FP, v->u.w);
462 jit_dec_synth();
463}
464
465void
466_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
467{
468 assert(v->code == jit_code_arg);
469 jit_inc_synth_wp(getarg_l, u, v);
470 if (jit_arg_reg_p(v->u.w))
471 jit_movr(u, JIT_RA0 - v->u.w);
472 else
473 jit_ldxi_l(u, JIT_FP, v->u.w);
474 jit_dec_synth();
475}
476
477void
478_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
479{
480 assert(v->code == jit_code_arg);
481 jit_inc_synth_wp(putargr, u, v);
482 if (jit_arg_reg_p(v->u.w))
483 jit_movr(JIT_RA0 - v->u.w, u);
484 else
485 jit_stxi(v->u.w, JIT_FP, u);
486 jit_dec_synth();
487}
488
489void
490_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
491{
492 jit_int32_t regno;
493 assert(v->code == jit_code_arg);
494 jit_inc_synth_wp(putargi, u, v);
495 if (jit_arg_reg_p(v->u.w))
496 jit_movi(JIT_RA0 - v->u.w, u);
497 else {
498 regno = jit_get_reg(jit_class_gpr);
499 jit_movi(regno, u);
500 jit_stxi(v->u.w, JIT_FP, regno);
501 jit_unget_reg(regno);
502 }
503 jit_dec_synth();
504}
505
506void
507_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
508{
509 assert(v->code == jit_code_arg_f);
510 jit_inc_synth_wp(getarg_f, u, v);
511 if (jit_arg_f_reg_p(v->u.w))
512 jit_movr_f(u, JIT_FA0 - v->u.w);
513 else if (jit_arg_reg_p(v->u.w - 8))
514 jit_movr_w_f(u, JIT_RA0 - (v->u.w - 8));
515 else
516 jit_ldxi_f(u, JIT_FP, v->u.w);
517 jit_dec_synth();
518}
519
520void
521_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
522{
523 assert(v->code == jit_code_arg_f);
524 jit_inc_synth_wp(putargr_f, u, v);
525 if (jit_arg_f_reg_p(v->u.w))
526 jit_movr_f(JIT_FA0 - v->u.w, u);
527 else if (jit_arg_reg_p(v->u.w - 8))
528 jit_movr_f_w(JIT_RA0 - (v->u.w - 8), u);
529 else
530 jit_stxi_f(v->u.w, JIT_FP, u);
531 jit_dec_synth();
532}
533
534void
535_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
536{
537 jit_int32_t regno;
538 assert(v->code == jit_code_arg_f);
539 jit_inc_synth_fp(putargi_f, u, v);
540 if (jit_arg_f_reg_p(v->u.w))
541 jit_movi_f(JIT_FA0 - v->u.w, u);
542 else if (jit_arg_reg_p(v->u.w - 8)) {
543 union {
544 jit_float32_t f;
545 jit_int32_t i;
546 } uu;
547 uu.f = u;
548 jit_movi(JIT_RA0 - (v->u.w - 8), uu.i);
549 }
550 else {
551 regno = jit_get_reg(jit_class_fpr);
552 jit_movi_f(regno, u);
553 jit_stxi_f(v->u.w, JIT_FP, regno);
554 jit_unget_reg(regno);
555 }
556 jit_dec_synth();
557}
558
559void
560_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
561{
562 assert(v->code == jit_code_arg_d);
563 jit_inc_synth_wp(getarg_d, u, v);
564 if (jit_arg_f_reg_p(v->u.w))
565 jit_movr_d(u, JIT_FA0 - v->u.w);
566 else if (jit_arg_reg_p(v->u.w - 8))
567 jit_movr_w_d(u, JIT_RA0 - (v->u.w - 8));
568 else
569 jit_ldxi_d(u, JIT_FP, v->u.w);
570 jit_dec_synth();
571}
572
573void
574_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
575{
576 assert(v->code == jit_code_arg_d);
577 jit_inc_synth_wp(putargr_d, u, v);
578 if (jit_arg_reg_p(v->u.w))
579 jit_movr_d(JIT_FA0 - v->u.w, u);
580 else if (jit_arg_reg_p(v->u.w - 8))
581 jit_movr_d_w(JIT_RA0 - (v->u.w - 8), u);
582 else
583 jit_stxi_d(v->u.w, JIT_FP, u);
584 jit_dec_synth();
585}
586
587void
588_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
589{
590 jit_int32_t regno;
591 assert(v->code == jit_code_arg_d);
592 jit_inc_synth_dp(putargi_d, u, v);
593 if (jit_arg_reg_p(v->u.w))
594 jit_movi_d(JIT_FA0 - v->u.w, u);
595 else if (jit_arg_reg_p(v->u.w - 8)) {
596 union {
597 jit_float64_t d;
598 jit_int64_t w;
599 } uu;
600 uu.d = u;
601 jit_movi(JIT_RA0 - (v->u.w - 8), uu.w);
602 }
603 else {
604 regno = jit_get_reg(jit_class_fpr);
605 jit_movi_d(regno, u);
606 jit_stxi_d(v->u.w, JIT_FP, regno);
607 jit_unget_reg(regno);
608 }
609 jit_dec_synth();
610}
611
612void
613_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
614{
615 assert(_jitc->function);
616 jit_inc_synth_w(pushargr, u);
617 jit_link_prepare();
618 if (jit_arg_reg_p(_jitc->function->call.argi)) {
619 jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
620 ++_jitc->function->call.argi;
621 }
622 else {
623 jit_stxi(_jitc->function->call.size, JIT_SP, u);
624 _jitc->function->call.size += sizeof(jit_word_t);
625 }
626 jit_dec_synth();
627}
628
629void
630_jit_pushargi(jit_state_t *_jit, jit_word_t u)
631{
632 jit_int32_t regno;
633 assert(_jitc->function);
634 jit_inc_synth_w(pushargi, u);
635 jit_link_prepare();
636 if (jit_arg_reg_p(_jitc->function->call.argi)) {
637 jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
638 ++_jitc->function->call.argi;
639 }
640 else {
641 regno = jit_get_reg(jit_class_gpr);
642 jit_movi(regno, u);
643 jit_stxi(_jitc->function->call.size, JIT_SP, regno);
644 jit_unget_reg(regno);
645 _jitc->function->call.size += sizeof(jit_word_t);
646 }
647 jit_dec_synth();
648}
649
650void
651_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
652{
653 assert(_jitc->function);
654 jit_inc_synth_w(pushargr_f, u);
655 jit_link_prepare();
656 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
657 !(_jitc->function->call.call & jit_call_varargs)) {
658 jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u);
659 ++_jitc->function->call.argf;
660 }
661 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
662 jit_movr_f_w(JIT_RA0 - _jitc->function->call.argi, u);
663 ++_jitc->function->call.argi;
664 }
665 else {
666 jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
667 _jitc->function->call.size += sizeof(jit_word_t);
668 }
669 jit_dec_synth();
670}
671
672void
673_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
674{
675 jit_int32_t regno;
676 assert(_jitc->function);
677 jit_inc_synth_f(pushargi_f, u);
678 jit_link_prepare();
679 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
680 !(_jitc->function->call.call & jit_call_varargs)) {
681 jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u);
682 ++_jitc->function->call.argf;
683 }
684 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
685 jit_movi_f_w(JIT_RA0 - _jitc->function->call.argi, u);
686 ++_jitc->function->call.argi;
687 }
688 else {
689 regno = jit_get_reg(jit_class_fpr);
690 jit_movi_f(regno, u);
691 jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
692 jit_unget_reg(regno);
693 _jitc->function->call.size += sizeof(jit_word_t);
694 }
695 jit_dec_synth();
696}
697
698void
699_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
700{
701 assert(_jitc->function);
702 jit_inc_synth_w(pushargr_d, u);
703 jit_link_prepare();
704 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
705 !(_jitc->function->call.call & jit_call_varargs)) {
706 jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
707 ++_jitc->function->call.argf;
708 }
709 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
710 jit_movr_d_w(JIT_RA0 - _jitc->function->call.argi, u);
711 ++_jitc->function->call.argi;
712 }
713 else {
714 jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
715 _jitc->function->call.size += sizeof(jit_word_t);
716 }
717 jit_dec_synth();
718}
719
720void
721_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
722{
723 jit_int32_t regno;
724 assert(_jitc->function);
725 jit_inc_synth_d(pushargi_d, u);
726 jit_link_prepare();
727 if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
728 !(_jitc->function->call.call & jit_call_varargs)) {
729 jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
730 ++_jitc->function->call.argf;
731 }
732 else if (jit_arg_reg_p(_jitc->function->call.argi)) {
733 jit_movi_d_w(JIT_RA0 - _jitc->function->call.argi, u);
734 ++_jitc->function->call.argi;
735 }
736 else {
737 regno = jit_get_reg(jit_class_fpr);
738 jit_movi_d(regno, u);
739 jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
740 jit_unget_reg(regno);
741 _jitc->function->call.size += sizeof(jit_word_t);
742 }
743 jit_dec_synth();
744}
745
746jit_bool_t
747_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno)
748{
749 jit_int32_t spec;
750 spec = jit_class(_rvs[regno].spec);
751 if (spec & jit_class_arg) {
752 regno = JIT_RA0 - regno;
753 if (regno >= 0 && regno < node->v.w)
754 return (1);
755 if (spec & jit_class_fpr) {
756 regno = JIT_FA0 - regno;
757 if (regno >= 0 && regno < node->w.w)
758 return (1);
759 }
760 }
761
762 return (0);
763}
764
765void
766_jit_finishr(jit_state_t *_jit, jit_int32_t r0)
767{
768 jit_node_t *node;
769 assert(_jitc->function);
770 jit_inc_synth_w(finishr, r0);
771 if (_jitc->function->self.alen < _jitc->function->call.size)
772 _jitc->function->self.alen = _jitc->function->call.size;
773 node = jit_callr(r0);
774 node->v.w = _jitc->function->self.argi;
775 node->w.w = _jitc->function->call.argf;
776 _jitc->function->call.argi = _jitc->function->call.argf =
777 _jitc->function->call.size = 0;
778 _jitc->prepare = 0;
779 jit_dec_synth();
780}
781
782jit_node_t *
783_jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
784{
785 jit_node_t *node;
786 assert(_jitc->function);
787 jit_inc_synth_w(finishi, (jit_word_t)i0);
788 if (_jitc->function->self.alen < _jitc->function->call.size)
789 _jitc->function->self.alen = _jitc->function->call.size;
790 node = jit_calli(i0);
791 node->v.w = _jitc->function->call.argi;
792 node->w.w = _jitc->function->call.argf;
793 _jitc->function->call.argi = _jitc->function->call.argf =
794 _jitc->function->call.size = 0;
795 _jitc->prepare = 0;
796 jit_dec_synth();
797 return (node);
798}
799
800void
801_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
802{
803 jit_inc_synth_w(retval_c, r0);
804 jit_extr_c(r0, JIT_RET);
805 jit_dec_synth();
806}
807
808void
809_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
810{
811 jit_inc_synth_w(retval_uc, r0);
812 jit_extr_uc(r0, JIT_RET);
813 jit_dec_synth();
814}
815
816void
817_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
818{
819 jit_inc_synth_w(retval_s, r0);
820 jit_extr_s(r0, JIT_RET);
821 jit_dec_synth();
822}
823
824void
825_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
826{
827 jit_inc_synth_w(retval_us, r0);
828 jit_extr_us(r0, JIT_RET);
829 jit_dec_synth();
830}
831
832void
833_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
834{
835 jit_inc_synth_w(retval_i, r0);
836 jit_extr_i(r0, JIT_RET);
837 jit_dec_synth();
838}
839
840void
841_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
842{
843 jit_inc_synth_w(retval_ui, r0);
844 jit_extr_ui(r0, JIT_RET);
845 jit_dec_synth();
846}
847
848void
849_jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
850{
851 jit_inc_synth_w(retval_l, r0);
852 if (r0 != JIT_RET)
853 jit_movr(r0, JIT_RET);
854 jit_dec_synth();
855}
856
857void
858_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
859{
860 jit_inc_synth_w(retval_f, r0);
861 if (r0 != JIT_FRET)
862 jit_movr_f(r0, JIT_FRET);
863 jit_dec_synth();
864}
865
866void
867_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
868{
869 jit_inc_synth_w(retval_d, r0);
870 if (r0 != JIT_FRET)
871 jit_movr_d(r0, JIT_FRET);
872 jit_dec_synth();
873}
874
875jit_pointer_t
876_emit_code(jit_state_t *_jit)
877{
878 jit_node_t *node;
879 jit_node_t *temp;
880 jit_word_t word;
881 jit_word_t value;
882 jit_int32_t offset;
883 struct {
884 jit_node_t *node;
885 jit_uint8_t *data;
886 jit_word_t word;
887#if DEVEL_DISASSEMBLER
888 jit_word_t prevw;
889#endif
890 jit_int32_t const_offset;
891 jit_int32_t patch_offset;
892 } undo;
893#if DEVEL_DISASSEMBLER
894 jit_word_t prevw;
895#endif
896
897 _jitc->function = NULL;
898
899 jit_reglive_setup();
900
901 undo.word = 0;
902 undo.node = NULL;
903 undo.const_offset = undo.patch_offset = 0;
904# define assert_data(node) /**/
905#define case_rr(name, type) \
906 case jit_code_##name##r##type: \
907 name##r##type(rn(node->u.w), rn(node->v.w)); \
908 break
909#define case_rw(name, type) \
910 case jit_code_##name##i##type: \
911 name##i##type(rn(node->u.w), node->v.w); \
912 break
913#define case_wr(name, type) \
914 case jit_code_##name##i##type: \
915 name##i##type(node->u.w, rn(node->v.w)); \
916 break
917#define case_rrr(name, type) \
918 case jit_code_##name##r##type: \
919 name##r##type(rn(node->u.w), \
920 rn(node->v.w), rn(node->w.w)); \
921 break
922#define case_rrrr(name, type) \
923 case jit_code_##name##r##type: \
924 name##r##type(rn(node->u.q.l), rn(node->u.q.h), \
925 rn(node->v.w), rn(node->w.w)); \
926 break
927#define case_rrw(name, type) \
928 case jit_code_##name##i##type: \
929 name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \
930 break
931#define case_rrrw(name, type) \
932 case jit_code_##name##i##type: \
933 name##i##type(rn(node->u.q.l), rn(node->u.q.h), \
934 rn(node->v.w), node->w.w); \
935 break
936#define case_rrf(name) \
937 case jit_code_##name##i_f: \
938 assert_data(node); \
939 name##i_f(rn(node->u.w), rn(node->v.w), node->w.f); \
940 break
941#define case_rrd(name) \
942 case jit_code_##name##i_d: \
943 assert_data(node); \
944 name##i_d(rn(node->u.w), rn(node->v.w), node->w.d); \
945 break
946#define case_wrr(name, type) \
947 case jit_code_##name##i##type: \
948 name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \
949 break
950#define case_brr(name, type) \
951 case jit_code_##name##r##type: \
952 temp = node->u.n; \
953 assert(temp->code == jit_code_label || \
954 temp->code == jit_code_epilog); \
955 if (temp->flag & jit_flag_patch) \
956 name##r##type(temp->u.w, rn(node->v.w), \
957 rn(node->w.w)); \
958 else { \
959 word = name##r##type(_jit->pc.w, \
960 rn(node->v.w), rn(node->w.w)); \
961 patch(word, node); \
962 } \
963 break
964#define case_brw(name, type) \
965 case jit_code_##name##i##type: \
966 temp = node->u.n; \
967 assert(temp->code == jit_code_label || \
968 temp->code == jit_code_epilog); \
969 if (temp->flag & jit_flag_patch) \
970 name##i##type(temp->u.w, \
971 rn(node->v.w), node->w.w); \
972 else { \
973 word = name##i##type(_jit->pc.w, \
974 rn(node->v.w), node->w.w); \
975 patch(word, node); \
976 } \
977 break;
978#define case_brf(name) \
979 case jit_code_##name##i_f: \
980 temp = node->u.n; \
981 assert(temp->code == jit_code_label || \
982 temp->code == jit_code_epilog); \
983 if (temp->flag & jit_flag_patch) \
984 name##i_f(temp->u.w, rn(node->v.w), node->w.f); \
985 else { \
986 word = name##i_f(_jit->pc.w, rn(node->v.w), \
987 node->w.f); \
988 patch(word, node); \
989 } \
990 break
991#define case_brd(name) \
992 case jit_code_##name##i_d: \
993 temp = node->u.n; \
994 assert(temp->code == jit_code_label || \
995 temp->code == jit_code_epilog); \
996 if (temp->flag & jit_flag_patch) \
997 name##i_d(temp->u.w, rn(node->v.w), node->w.d); \
998 else { \
999 word = name##i_d(_jit->pc.w, rn(node->v.w), \
1000 node->w.d); \
1001 patch(word, node); \
1002 } \
1003 break
1004#if DEVEL_DISASSEMBLER
1005 prevw = _jit->pc.w;
1006#endif
1007 for (node = _jitc->head; node; node = node->next) {
1008 if (_jit->pc.uc >= _jitc->code.end)
1009 return (NULL);
1010
1011#if DEVEL_DISASSEMBLER
1012 node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
1013 prevw = _jit->pc.w;
1014#endif
1015 value = jit_classify(node->code);
1016 jit_regarg_set(node, value);
1017 switch (node->code) {
1018 case jit_code_align:
1019 assert(!(node->u.w & (node->u.w - 1)) &&
1020 node->u.w <= sizeof(jit_word_t));
1021 if (node->u.w == sizeof(jit_word_t) &&
1022 (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
1023 nop(sizeof(jit_word_t) - word);
1024 break;
1025 case jit_code_note: case jit_code_name:
1026 node->u.w = _jit->pc.w;
1027 break;
1028 case jit_code_label:
1029 /* remember label is defined */
1030 node->flag |= jit_flag_patch;
1031 node->u.w = _jit->pc.w;
1032 break;
1033 case_rrr(add,);
1034 case_rrw(add,);
1035 case_rrr(addc,);
1036 case_rrw(addc,);
1037 case_rrr(addx,);
1038 case_rrw(addx,);
1039 case_rrr(sub,);
1040 case_rrw(sub,);
1041 case_rrr(subc,);
1042 case_rrw(subc,);
1043 case_rrr(subx,);
1044 case_rrw(subx,);
1045 case_rrw(rsb,);
1046 case_rrr(mul,);
1047 case_rrw(mul,);
1048 case_rrrr(qmul,);
1049 case_rrrw(qmul,);
1050 case_rrrr(qmul, _u);
1051 case_rrrw(qmul, _u);
1052 case_rrr(div,);
1053 case_rrw(div,);
1054 case_rrr(div, _u);
1055 case_rrw(div, _u);
1056 case_rrrr(qdiv,);
1057 case_rrrw(qdiv,);
1058 case_rrrr(qdiv, _u);
1059 case_rrrw(qdiv, _u);
1060 case_rrr(rem,);
1061 case_rrw(rem,);
1062 case_rrr(rem, _u);
1063 case_rrw(rem, _u);
1064 case_rrr(lsh,);
1065 case_rrw(lsh,);
1066 case_rrr(rsh,);
1067 case_rrw(rsh,);
1068 case_rrr(rsh, _u);
1069 case_rrw(rsh, _u);
1070 case_rr(neg,);
1071 case_rr(com,);
1072 case_rrr(and,);
1073 case_rrw(and,);
1074 case_rrr(or,);
1075 case_rrw(or,);
1076 case_rrr(xor,);
1077 case_rrw(xor,);
1078 case_rr(trunc, _f_i);
1079 case_rr(trunc, _d_i);
1080 case_rr(trunc, _f_l);
1081 case_rr(trunc, _d_l);
1082 case_rr(ld, _c);
1083 case_rw(ld, _c);
1084 case_rr(ld, _uc);
1085 case_rw(ld, _uc);
1086 case_rr(ld, _s);
1087 case_rw(ld, _s);
1088 case_rr(ld, _us);
1089 case_rw(ld, _us);
1090 case_rr(ld, _i);
1091 case_rw(ld, _i);
1092 case_rr(ld, _ui);
1093 case_rw(ld, _ui);
1094 case_rr(ld, _l);
1095 case_rw(ld, _l);
1096 case_rrr(ldx, _c);
1097 case_rrw(ldx, _c);
1098 case_rrr(ldx, _uc);
1099 case_rrw(ldx, _uc);
1100 case_rrr(ldx, _s);
1101 case_rrw(ldx, _s);
1102 case_rrr(ldx, _us);
1103 case_rrw(ldx, _us);
1104 case_rrr(ldx, _i);
1105 case_rrw(ldx, _i);
1106 case_rrr(ldx, _ui);
1107 case_rrw(ldx, _ui);
1108 case_rrr(ldx, _l);
1109 case_rrw(ldx, _l);
1110 case_rr(st, _c);
1111 case_wr(st, _c);
1112 case_rr(st, _s);
1113 case_wr(st, _s);
1114 case_rr(st, _i);
1115 case_wr(st, _i);
1116 case_rr(st, _l);
1117 case_wr(st, _l);
1118 case_rrr(stx, _c);
1119 case_wrr(stx, _c);
1120 case_rrr(stx, _s);
1121 case_wrr(stx, _s);
1122 case_rrr(stx, _i);
1123 case_wrr(stx, _i);
1124 case_rrr(stx, _l);
1125 case_wrr(stx, _l);
1126 case_rr(hton, _us);
1127 case_rr(hton, _ui);
1128 case_rr(hton, _ul);
40a44dcb
PC
1129 case_rr(bswap, _us);
1130 case_rr(bswap, _ui);
1131 case_rr(bswap, _ul);
4a71579b
PC
1132 case_rr(ext, _c);
1133 case_rr(ext, _uc);
1134 case_rr(ext, _s);
1135 case_rr(ext, _us);
1136 case_rr(ext, _i);
1137 case_rr(ext, _ui);
ba3814c1
PC
1138 case jit_code_casr:
1139 casr(rn(node->u.w), rn(node->v.w),
1140 rn(node->w.q.l), rn(node->w.q.h));
1141 break;
1142 case jit_code_casi:
1143 casi(rn(node->u.w), node->v.w,
1144 rn(node->w.q.l), rn(node->w.q.h));
1145 break;
40a44dcb
PC
1146 case_rrr(movn,);
1147 case_rrr(movz,);
4a71579b
PC
1148 case_rr(mov,);
1149 case jit_code_movi:
1150 if (node->flag & jit_flag_node) {
1151 temp = node->v.n;
1152 if (temp->code == jit_code_data ||
1153 (temp->code == jit_code_label &&
1154 (temp->flag & jit_flag_patch)))
1155 movi(rn(node->u.w), temp->u.w);
1156 else {
1157 assert(temp->code == jit_code_label ||
1158 temp->code == jit_code_epilog);
1159 word = movi_p(rn(node->u.w), temp->u.w);
1160 patch(word, node);
1161 }
1162 }
1163 else
1164 movi(rn(node->u.w), node->v.w);
1165 break;
1166 case_rrr(lt,);
1167 case_rrw(lt,);
1168 case_rrr(lt, _u);
1169 case_rrw(lt, _u);
1170 case_rrr(le,);
1171 case_rrw(le,);
1172 case_rrr(le, _u);
1173 case_rrw(le, _u);
1174 case_rrr(eq,);
1175 case_rrw(eq,);
1176 case_rrr(ge,);
1177 case_rrw(ge,);
1178 case_rrr(ge, _u);
1179 case_rrw(ge, _u);
1180 case_rrr(gt,);
1181 case_rrw(gt,);
1182 case_rrr(gt, _u);
1183 case_rrw(gt, _u);
1184 case_rrr(ne,);
1185 case_rrw(ne,);
1186 case_brr(blt,);
1187 case_brw(blt,);
1188 case_brr(blt, _u);
1189 case_brw(blt, _u);
1190 case_brr(ble,);
1191 case_brw(ble,);
1192 case_brr(ble, _u);
1193 case_brw(ble, _u);
1194 case_brr(beq,);
1195 case_brw(beq,);
1196 case_brr(bge,);
1197 case_brw(bge,);
1198 case_brr(bge, _u);
1199 case_brw(bge, _u);
1200 case_brr(bgt,);
1201 case_brw(bgt,);
1202 case_brr(bgt, _u);
1203 case_brw(bgt, _u);
1204 case_brr(bne,);
1205 case_brw(bne,);
1206 case_brr(boadd,);
1207 case_brw(boadd,);
1208 case_brr(boadd, _u);
1209 case_brw(boadd, _u);
1210 case_brr(bxadd,);
1211 case_brw(bxadd,);
1212 case_brr(bxadd, _u);
1213 case_brw(bxadd, _u);
1214 case_brr(bosub,);
1215 case_brw(bosub,);
1216 case_brr(bosub, _u);
1217 case_brw(bosub, _u);
1218 case_brr(bxsub,);
1219 case_brw(bxsub,);
1220 case_brr(bxsub, _u);
1221 case_brw(bxsub, _u);
1222 case_brr(bms,);
1223 case_brw(bms,);
1224 case_brr(bmc,);
1225 case_brw(bmc,);
1226 case_rrr(add, _f);
1227 case_rrf(add);
1228 case_rrr(sub, _f);
1229 case_rrf(sub);
1230 case_rrf(rsb);
1231 case_rrr(mul, _f);
1232 case_rrf(mul);
1233 case_rrr(div, _f);
1234 case_rrf(div);
1235 case_rr(abs, _f);
1236 case_rr(neg, _f);
1237 case_rr(sqrt, _f);
1238 case_rr(ext, _f);
1239 case_rr(ld, _f);
1240 case_rw(ld, _f);
1241 case_rrr(ldx, _f);
1242 case_rrw(ldx, _f);
1243 case_rr(st, _f);
1244 case_wr(st, _f);
1245 case_rrr(stx, _f);
1246 case_wrr(stx, _f);
1247 case_rr(mov, _f);
1248 case jit_code_movi_f:
1249 assert_data(node);
1250 movi_f(rn(node->u.w), node->v.f);
1251 break;
1252 case_rr(ext, _d_f);
1253 case_rrr(lt, _f);
1254 case_rrf(lt);
1255 case_rrr(le, _f);
1256 case_rrf(le);
1257 case_rrr(eq, _f);
1258 case_rrf(eq);
1259 case_rrr(ge, _f);
1260 case_rrf(ge);
1261 case_rrr(gt, _f);
1262 case_rrf(gt);
1263 case_rrr(ne, _f);
1264 case_rrf(ne);
1265 case_rrr(unlt, _f);
1266 case_rrf(unlt);
1267 case_rrr(unle, _f);
1268 case_rrf(unle);
1269 case_rrr(uneq, _f);
1270 case_rrf(uneq);
1271 case_rrr(unge, _f);
1272 case_rrf(unge);
1273 case_rrr(ungt, _f);
1274 case_rrf(ungt);
1275 case_rrr(ltgt, _f);
1276 case_rrf(ltgt);
1277 case_rrr(ord, _f);
1278 case_rrf(ord);
1279 case_rrr(unord, _f);
1280 case_rrf(unord);
1281 case_brr(blt, _f);
1282 case_brf(blt);
1283 case_brr(ble, _f);
1284 case_brf(ble);
1285 case_brr(beq, _f);
1286 case_brf(beq);
1287 case_brr(bge, _f);
1288 case_brf(bge);
1289 case_brr(bgt, _f);
1290 case_brf(bgt);
1291 case_brr(bne, _f);
1292 case_brf(bne);
1293 case_brr(bunlt, _f);
1294 case_brf(bunlt);
1295 case_brr(bunle, _f);
1296 case_brf(bunle);
1297 case_brr(buneq, _f);
1298 case_brf(buneq);
1299 case_brr(bunge, _f);
1300 case_brf(bunge);
1301 case_brr(bungt, _f);
1302 case_brf(bungt);
1303 case_brr(bltgt, _f);
1304 case_brf(bltgt);
1305 case_brr(bord, _f);
1306 case_brf(bord);
1307 case_brr(bunord, _f);
1308 case_brf(bunord);
1309 case_rrr(add, _d);
1310 case_rrd(add);
1311 case_rrr(sub, _d);
1312 case_rrd(sub);
1313 case_rrd(rsb);
1314 case_rrr(mul, _d);
1315 case_rrd(mul);
1316 case_rrr(div, _d);
1317 case_rrd(div);
1318 case_rr(abs, _d);
1319 case_rr(neg, _d);
1320 case_rr(sqrt, _d);
1321 case_rr(ext, _d);
1322 case_rr(ld, _d);
1323 case_rw(ld, _d);
1324 case_rrr(ldx, _d);
1325 case_rrw(ldx, _d);
1326 case_rr(st, _d);
1327 case_wr(st, _d);
1328 case_rrr(stx, _d);
1329 case_wrr(stx, _d);
1330 case_rr(mov, _d);
1331 case jit_code_movi_d:
1332 assert_data(node);
1333 movi_d(rn(node->u.w), node->v.d);
1334 break;
1335 case_rr(ext, _f_d);
1336 case_rrr(lt, _d);
1337 case_rrd(lt);
1338 case_rrr(le, _d);
1339 case_rrd(le);
1340 case_rrr(eq, _d);
1341 case_rrd(eq);
1342 case_rrr(ge, _d);
1343 case_rrd(ge);
1344 case_rrr(gt, _d);
1345 case_rrd(gt);
1346 case_rrr(ne, _d);
1347 case_rrd(ne);
1348 case_rrr(unlt, _d);
1349 case_rrd(unlt);
1350 case_rrr(unle, _d);
1351 case_rrd(unle);
1352 case_rrr(uneq, _d);
1353 case_rrd(uneq);
1354 case_rrr(unge, _d);
1355 case_rrd(unge);
1356 case_rrr(ungt, _d);
1357 case_rrd(ungt);
1358 case_rrr(ltgt, _d);
1359 case_rrd(ltgt);
1360 case_rrr(ord, _d);
1361 case_rrd(ord);
1362 case_rrr(unord, _d);
1363 case_rrd(unord);
1364 case_brr(blt, _d);
1365 case_brd(blt);
1366 case_brr(ble, _d);
1367 case_brd(ble);
1368 case_brr(beq, _d);
1369 case_brd(beq);
1370 case_brr(bge, _d);
1371 case_brd(bge);
1372 case_brr(bgt, _d);
1373 case_brd(bgt);
1374 case_brr(bne, _d);
1375 case_brd(bne);
1376 case_brr(bunlt, _d);
1377 case_brd(bunlt);
1378 case_brr(bunle, _d);
1379 case_brd(bunle);
1380 case_brr(buneq, _d);
1381 case_brd(buneq);
1382 case_brr(bunge, _d);
1383 case_brd(bunge);
1384 case_brr(bungt, _d);
1385 case_brd(bungt);
1386 case_brr(bltgt, _d);
1387 case_brd(bltgt);
1388 case_brr(bord, _d);
1389 case_brd(bord);
1390 case_brr(bunord, _d);
1391 case_brd(bunord);
1392 case jit_code_jmpr:
1393 jmpr(rn(node->u.w));
1394 break;
1395 case jit_code_jmpi:
1396 if (node->flag & jit_flag_node) {
1397 temp = node->u.n;
1398 assert(temp->code == jit_code_label ||
1399 temp->code == jit_code_epilog);
1400 if (temp->flag & jit_flag_patch)
1401 jmpi(temp->u.w);
1402 else {
1403 word = jmpi_p(_jit->pc.w);
1404 patch(word, node);
1405 }
1406 }
1407 else
1408 jmpi(node->u.w);
1409 break;
1410 case jit_code_callr:
1411 callr(rn(node->u.w));
1412 break;
1413 case jit_code_calli:
1414 if (node->flag & jit_flag_node) {
1415 temp = node->u.n;
1416 assert(temp->code == jit_code_label ||
1417 temp->code == jit_code_epilog);
1418 if (temp->flag & jit_flag_patch)
1419 calli(temp->u.w);
1420 else {
1421 word = calli_p(_jit->pc.w);
1422 patch(word, node);
1423 }
1424 }
1425 else
1426 calli(node->u.w);
1427 break;
1428 case jit_code_prolog:
1429 _jitc->function = _jitc->functions.ptr + node->w.w;
1430 undo.node = node;
1431 undo.word = _jit->pc.w;
1432#if DEVEL_DISASSEMBLER
1433 undo.prevw = prevw;
1434#endif
1435 undo.patch_offset = _jitc->patches.offset;
1436 restart_function:
1437 _jitc->again = 0;
1438 prolog(node);
1439 break;
1440 case jit_code_epilog:
1441 assert(_jitc->function == _jitc->functions.ptr + node->w.w);
1442 if (_jitc->again) {
1443 for (temp = undo.node->next;
1444 temp != node; temp = temp->next) {
1445 if (temp->code == jit_code_label ||
1446 temp->code == jit_code_epilog)
1447 temp->flag &= ~jit_flag_patch;
1448 }
1449 temp->flag &= ~jit_flag_patch;
1450 node = undo.node;
1451 _jit->pc.w = undo.word;
1452#if DEVEL_DISASSEMBLER
1453 prevw = undo.prevw;
1454#endif
1455 _jitc->patches.offset = undo.patch_offset;
1456 goto restart_function;
1457 }
1458 /* remember label is defined */
1459 node->flag |= jit_flag_patch;
1460 node->u.w = _jit->pc.w;
1461 epilog(node);
1462 _jitc->function = NULL;
1463 break;
1464 case jit_code_movr_w_f:
1465 movr_w_f(rn(node->u.w), rn(node->v.w));
1466 break;
1467 case jit_code_movr_f_w:
1468 movr_f_w(rn(node->u.w), rn(node->v.w));
1469 break;
1470 case jit_code_movi_f_w:
1471 assert_data(node);
1472 movi_f_w(rn(node->u.w), node->v.f);
1473 break;
1474 case jit_code_movr_w_d:
1475 movr_w_d(rn(node->u.w), rn(node->v.w));
1476 break;
1477 case jit_code_movr_d_w:
1478 movr_d_w(rn(node->u.w), rn(node->v.w));
1479 break;
1480 case jit_code_movi_d_w:
1481 assert_data(node);
1482 movi_d_w(rn(node->u.w), node->v.d);
1483 break;
1484 case jit_code_va_start:
1485 vastart(rn(node->u.w));
1486 break;
1487 case jit_code_va_arg:
1488 vaarg(rn(node->u.w), rn(node->v.w));
1489 break;
1490 case jit_code_va_arg_d:
1491 vaarg_d(rn(node->u.w), rn(node->v.w));
1492 break;
1493 case jit_code_live: case jit_code_ellipsis:
1494 case jit_code_va_push:
1495 case jit_code_allocai: case jit_code_allocar:
1496 case jit_code_arg:
1497 case jit_code_arg_f: case jit_code_arg_d:
1498 case jit_code_va_end:
1499 case jit_code_ret:
1500 case jit_code_retr: case jit_code_reti:
1501 case jit_code_retr_f: case jit_code_reti_f:
1502 case jit_code_retr_d: case jit_code_reti_d:
1503 case jit_code_getarg_c: case jit_code_getarg_uc:
1504 case jit_code_getarg_s: case jit_code_getarg_us:
1505 case jit_code_getarg_i: case jit_code_getarg_ui:
1506 case jit_code_getarg_l:
1507 case jit_code_getarg_f: case jit_code_getarg_d:
1508 case jit_code_putargr: case jit_code_putargi:
1509 case jit_code_putargr_f: case jit_code_putargi_f:
1510 case jit_code_putargr_d: case jit_code_putargi_d:
1511 case jit_code_pushargr: case jit_code_pushargi:
1512 case jit_code_pushargr_f: case jit_code_pushargi_f:
1513 case jit_code_pushargr_d: case jit_code_pushargi_d:
1514 case jit_code_retval_c: case jit_code_retval_uc:
1515 case jit_code_retval_s: case jit_code_retval_us:
1516 case jit_code_retval_i:
1517 case jit_code_retval_ui: case jit_code_retval_l:
1518 case jit_code_retval_f: case jit_code_retval_d:
1519 case jit_code_prepare:
1520 case jit_code_finishr: case jit_code_finishi:
1521 break;
1522 default:
1523 abort();
1524 }
1525 if (jit_carry != _NOREG) {
1526 switch (node->code) {
1527 case jit_code_note:
1528 case jit_code_addcr: case jit_code_addci:
1529 case jit_code_addxr: case jit_code_addxi:
1530 case jit_code_subcr: case jit_code_subci:
1531 case jit_code_subxr: case jit_code_subxi:
1532 break;
1533 default:
1534 jit_unget_reg(jit_carry);
1535 jit_carry = _NOREG;
1536 break;
1537 }
1538 }
1539 jit_regarg_clr(node, value);
1540 assert(_jitc->regarg == 0 ||
1541 (jit_carry != _NOREG && _jitc->regarg == (1 << jit_carry)));
1542 assert(_jitc->synth == 0);
1543 /* update register live state */
1544 jit_reglive(node);
1545 }
1546#undef case_brw
1547#undef case_brr
1548#undef case_wrr
1549#undef case_rrw
1550#undef case_rrr
1551#undef case_wr
1552#undef case_rw
1553#undef case_rr
1554
1555 for (offset = 0; offset < _jitc->patches.offset; offset++) {
1556 node = _jitc->patches.ptr[offset].node;
1557 word = _jitc->patches.ptr[offset].inst;
1558 value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
1559 patch_at(word, value);
1560 }
1561
1562 jit_flush(_jit->code.ptr, _jit->pc.uc);
1563
1564 return (_jit->code.ptr);
1565}
1566
1567#define CODE 1
1568# include "jit_riscv-cpu.c"
1569# include "jit_riscv-fpu.c"
ba3814c1 1570# include "jit_fallback.c"
4a71579b
PC
1571#undef CODE
1572
1573void
1574jit_flush(void *fptr, void *tptr)
1575{
1576#if defined(__GNUC__)
1577 jit_word_t f, t, s;
1578
1579 s = sysconf(_SC_PAGE_SIZE);
1580 f = (jit_word_t)fptr & -s;
1581 t = (((jit_word_t)tptr) + s - 1) & -s;
1582 __clear_cache((void *)f, (void *)t);
1583#endif
1584}
1585
1586void
1587_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1588{
1589 ldxi(rn(r0), rn(r1), i0);
1590}
1591
1592void
1593_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1594{
1595 stxi(i0, rn(r0), rn(r1));
1596}
1597
1598void
1599_emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1600{
1601 ldxi_d(rn(r0), rn(r1), i0);
1602}
1603
1604void
1605_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1606{
1607 stxi_d(i0, rn(r0), rn(r1));
1608}
1609
1610static void
1611_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
1612{
1613 jit_int32_t flag;
1614
1615 assert(node->flag & jit_flag_node);
1616 if (node->code == jit_code_movi)
1617 flag = node->v.n->flag;
1618 else
1619 flag = node->u.n->flag;
1620 assert(!(flag & jit_flag_patch));
1621 if (_jitc->patches.offset >= _jitc->patches.length) {
1622 jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
1623 _jitc->patches.length * sizeof(jit_patch_t),
1624 (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
1625 _jitc->patches.length += 1024;
1626 }
1627 _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
1628 _jitc->patches.ptr[_jitc->patches.offset].node = node;
1629 ++_jitc->patches.offset;
1630}