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