git subrepo pull (merge) --force deps/lightning
[pcsx_rearmed.git] / deps / lightning / include / lightning / jit_private.h
CommitLineData
4a71579b 1/*
79bfeef6 2 * Copyright (C) 2012-2023 Free Software Foundation, Inc.
4a71579b
PC
3 *
4 * This file is part of GNU lightning.
5 *
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
15 *
16 * Authors:
17 * Paulo Cesar Pereira de Andrade
18 */
19
20#ifndef _jit_private_h
21#define _jit_private_h
22
23#if HAVE_CONFIG_H
24# include "config.h"
25#endif
26
27#include <assert.h>
28#include <limits.h>
29#include <stdio.h>
30
31#ifdef STDC_HEADERS
32# include <stddef.h>
33#else
34# if !defined(offsetof)
35# define offsetof(type, field) ((char *)&((type *)0)->field - (char *)0)
36# endif
37#endif
38
39#if defined(__GNUC__)
40# define maybe_unused __attribute__ ((unused))
41# define unlikely(exprn) __builtin_expect(!!(exprn), 0)
42# define likely(exprn) __builtin_expect(!!(exprn), 1)
43# if (__GNUC__ >= 4)
44# define PUBLIC __attribute__ ((visibility("default")))
45# define HIDDEN __attribute__ ((visibility("hidden")))
46# else
47# define PUBLIC /**/
48# define HIDDEN /**/
49# endif
50#else
51# define maybe_unused /**/
52# define unlikely(exprn) exprn
53# define likely(exprn) exprn
54# define PUBLIC /**/
55# define HIDDEN /**/
56#endif
57
79bfeef6
PC
58#if PACKED_STACK || STRONG_TYPE_CHECKING
59# define assert_arg_type(code, expect) \
60 do assert((code) == (expect)); while (0)
61# define assert_putarg_type(code, expect) \
62 do \
63 assert((((code) - jit_code_putargr_c) >> 2) == \
64 ((expect) - jit_code_arg_c)); \
65 while (0)
66#else
67# define assert_arg_type(code, expect) \
68 do assert((int)(code) == (int)(expect) || \
69 (code) == jit_code_arg); while (0)
70# define assert_putarg_type(code, expect) \
71 do \
72 assert(((((code) - jit_code_putargr_c) >> 2) == \
73 ((expect) - jit_code_arg_c)) || \
74 ((code) == jit_code_arg)); \
75 while (0)
76#endif
77
4a71579b
PC
78#define rc(value) jit_class_##value
79#define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec))
80
81#if defined(__i386__) || defined(__x86_64__)
82# define JIT_SP _RSP
83# define JIT_RET _RAX
84# if __X32
85# define JIT_FRET _ST0
86typedef jit_uint32_t jit_regset_t;
87# else
88# if __CYGWIN__ || _WIN32
89# define JIT_RA0 _RCX
90# else
91# define JIT_RA0 _RDI
92# endif
93# define JIT_FA0 _XMM0
94# define JIT_FRET _XMM0
95typedef jit_uint64_t jit_regset_t;
96# endif
97#elif defined(__mips__)
98# define JIT_RA0 _A0
99# define JIT_FA0 _F12
100# define JIT_SP _SP
101# define JIT_RET _V0
102# define JIT_FRET _F0
103typedef jit_uint64_t jit_regset_t;
104#elif defined(__arm__)
105# define JIT_RA0 _R0
106# define JIT_FA0 _D0
107# define JIT_SP _R13
108# define JIT_RET _R0
109# if defined(__ARM_PCS_VFP)
110# define JIT_FRET _D0
111# else
112# define JIT_FRET _R0
113# endif
114typedef jit_uint64_t jit_regset_t;
115#elif defined(__powerpc__)
116# define JIT_RA0 _R3
117# define JIT_FA0 _F1
118# define JIT_SP _R1
119# define JIT_RET _R3
120# define JIT_FRET _F1
121typedef jit_uint64_t jit_regset_t;
122#elif defined(__sparc__)
123# define JIT_SP _SP
124# define JIT_RET _I0
125# define JIT_FRET _F0
126# if __WORDSIZE == 32
127typedef jit_uint64_t jit_regset_t;
128# else
129typedef struct {
130 jit_uint64_t rl;
131 jit_uint64_t rh;
132} jit_regset_t;
133# endif
134#elif defined(__ia64__)
135# define JIT_SP _R12
136# define JIT_RET _R8
137# define JIT_FRET _F8
138typedef struct {
139 jit_uint64_t rl;
140 jit_uint64_t rh;
141 jit_uint64_t fl;
142 jit_uint64_t fh;
143} jit_regset_t;
144#elif defined(__hppa__)
145# define JIT_SP _R30
146# define JIT_RET _R28
147# define JIT_FRET _F4
148typedef jit_uint64_t jit_regset_t;
149#elif defined(__aarch64__)
150# define JIT_RA0 _R0
151# define JIT_FA0 _V0
152# define JIT_SP _SP
153# define JIT_RET _R0
154# define JIT_FRET _V0
155typedef jit_uint64_t jit_regset_t;
156#elif defined(__s390__) || defined(__s390x__)
157# define JIT_SP _R15
158# define JIT_RET _R2
159# define JIT_FRET _F0
160typedef jit_uint32_t jit_regset_t;
161#elif defined(__alpha__)
162# define JIT_SP _SP
163# define JIT_RET _V0
164# define JIT_FRET _F0
165typedef jit_uint64_t jit_regset_t;
166#elif defined(__riscv)
167# define JIT_RA0 _A0
168# define JIT_FA0 _FA0
169# define JIT_SP _SP
170# define JIT_RET _A0
171# define JIT_FRET _FA0
172typedef jit_uint64_t jit_regset_t;
24d91c0d
PC
173#elif defined(__loongarch__)
174# define JIT_RA0 _A0
175# define JIT_FA0 _FA0
176# define JIT_SP _SP
177# define JIT_RET _A0
178# define JIT_FRET _FA0
179typedef jit_uint64_t jit_regset_t;
4a71579b
PC
180#endif
181
182#define jit_data(u,v,w) _jit_data(_jit,u,v,w)
183extern jit_node_t *_jit_data(jit_state_t*, const void*,
184 jit_word_t, jit_int32_t);
185
186#define jit_size(vector) (sizeof(vector) / sizeof((vector)[0]))
187
188#define jit_reg_free_p(regno) \
189 (!jit_regset_tstbit(&_jitc->reglive, regno) && \
190 !jit_regset_tstbit(&_jitc->regarg, regno) && \
191 !jit_regset_tstbit(&_jitc->regsav, regno))
192
193#define jit_reg_free_if_spill_p(regno) \
194 (!jit_regset_tstbit(&_jitc->regarg, regno) && \
195 !jit_regset_tstbit(&_jitc->regsav, regno))
196
79bfeef6 197#define jit_code_inc_synth(code) \
4a71579b 198 do { \
79bfeef6 199 (void)jit_new_node(code); \
4a71579b
PC
200 jit_synth_inc(); \
201 } while (0)
79bfeef6
PC
202#define jit_inc_synth(name) \
203 jit_code_inc_synth(jit_code_##name)
204#define jit_code_inc_synth_w(code, u) \
4a71579b 205 do { \
79bfeef6 206 (void)jit_new_node_w(code, u); \
4a71579b
PC
207 jit_synth_inc(); \
208 } while (0)
79bfeef6
PC
209#define jit_inc_synth_w(name, u) \
210 jit_code_inc_synth_w(jit_code_##name, u)
211#define jit_code_inc_synth_f(code, u) \
4a71579b 212 do { \
79bfeef6 213 (void)jit_new_node_f(code, u); \
4a71579b
PC
214 jit_synth_inc(); \
215 } while (0)
79bfeef6
PC
216#define jit_inc_synth_f(name, u) \
217 jit_code_inc_synth_f(jit_code_##name, u)
218#define jit_code_inc_synth_d(code, u) \
4a71579b 219 do { \
79bfeef6 220 (void)jit_new_node_d(code, u); \
4a71579b
PC
221 jit_synth_inc(); \
222 } while (0)
79bfeef6
PC
223#define jit_inc_synth_d(name, u) \
224 jit_code_inc_synth_d(jit_code_##name, u)
225#define jit_code_inc_synth_ww(code, u, v) \
4a71579b 226 do { \
79bfeef6 227 (void)jit_new_node_ww(code, u, v); \
4a71579b
PC
228 jit_synth_inc(); \
229 } while (0)
79bfeef6
PC
230#define jit_inc_synth_ww(name, u, v) \
231 jit_code_inc_synth_ww(jit_code_##name, u, v)
232#define jit_code_inc_synth_wp(code, u, v) \
4a71579b 233 do { \
79bfeef6 234 (void)jit_new_node_wp(code, u, v); \
4a71579b
PC
235 jit_synth_inc(); \
236 } while (0)
79bfeef6
PC
237#define jit_inc_synth_wp(name, u, v) \
238 jit_code_inc_synth_wp(jit_code_##name, u, v)
239#define jit_code_inc_synth_fp(code, u, v) \
4a71579b 240 do { \
79bfeef6 241 (void)jit_new_node_fp(code, u, v); \
4a71579b
PC
242 jit_synth_inc(); \
243 } while (0)
79bfeef6
PC
244#define jit_inc_synth_fp(name, u, v) \
245 jit_code_inc_synth_fp(jit_code_##name, u, v)
246#define jit_code_inc_synth_dp(code, u, v) \
4a71579b 247 do { \
79bfeef6 248 (void)jit_new_node_dp(code, u, v); \
4a71579b
PC
249 jit_synth_inc(); \
250 } while (0)
79bfeef6
PC
251#define jit_inc_synth_dp(name, u, v) \
252 jit_code_inc_synth_dp(jit_code_##name, u, v)
ba86ff93
PC
253#define jit_inc_synth_wf(name, u, v) \
254 jit_code_inc_synth_wf(jit_code_##name, u, v)
255#define jit_code_inc_synth_wf(code, u, v) \
256 do { \
257 (void)jit_new_node_wf(code, u, v); \
258 jit_synth_inc(); \
259 } while (0)
260#define jit_inc_synth_wqf(name, u, v, w, x) \
261 do { \
262 (void)jit_new_node_wqf(jit_code_##name, u, v, w, x); \
263 jit_synth_inc(); \
264 } while (0)
265#define jit_inc_synth_wd(name, u, v) \
266 jit_code_inc_synth_wd(jit_code_##name, u, v)
267#define jit_inc_synth_wqd(name, u, v, w, x) \
268 do { \
269 (void)jit_new_node_wqd(jit_code_##name, u, v, w, x); \
270 jit_synth_inc(); \
271 } while (0)
272#define jit_code_inc_synth_wd(code, u, v) \
273 do { \
274 (void)jit_new_node_wd(code, u, v); \
275 jit_synth_inc(); \
276 } while (0)
4a71579b
PC
277#define jit_dec_synth() jit_synth_dec()
278
79bfeef6
PC
279#define jit_link_alist(node) \
280 do { \
281 node->link = _jitc->function->alist; \
282 _jitc->function->alist = node; \
283 } while (0)
284#define jit_check_frame() \
285 do { \
286 if (!_jitc->function->need_frame) { \
287 _jitc->again = 1; \
288 _jitc->function->need_frame = 1; \
289 } \
290 } while (0)
291#define jit_diffsize() (stack_framesize - _jitc->framesize)
292#define jit_framesize() (stack_framesize - jit_diffsize())
293#define jit_selfsize() (_jitc->function->self.size - jit_diffsize())
294
4a71579b
PC
295#define jit_link_prolog() \
296 do { \
297 _jitc->tail->link = _jitc->function->prolog->link; \
298 _jitc->function->prolog->link = _jitc->tail; \
299 } while (0)
300#define jit_link_prepare() \
301 do { \
302 _jitc->tail->link = _jitc->prepare->link; \
303 _jitc->prepare->link = _jitc->tail; \
304 } while (0)
305#define jit_link_reverse(where) \
306 do { \
307 jit_node_t *tmp, *tail = 0; \
308 while (where) { \
309 tmp = (where)->link; \
310 (where)->link = tail; \
311 tail = where; \
312 where = tmp; \
313 } \
314 where = tail; \
315 } while (0);
316
317/*
318 * Private jit_class bitmasks
319 */
320#define jit_class_named 0x00400000 /* hit must be the named reg */
321#define jit_class_nospill 0x00800000 /* hint to fail if need spill */
322#define jit_class_sft 0x01000000 /* not a hardware register */
323#define jit_class_rg8 0x04000000 /* x86 8 bits */
324#define jit_class_xpr 0x80000000 /* float / vector */
325/* Used on sparc64 where %f0-%f31 can be encode for single float
326 * but %f32 to %f62 only as double precision */
79bfeef6
PC
327#define jit_class_sng 0x00010000 /* Single precision float */
328#define jit_class_dbl 0x00020000 /* Only double precision float */
4a71579b
PC
329#define jit_regno_patch 0x00008000 /* this is a register
330 * returned by a "user" call
331 * to jit_get_reg() */
332
333#define jit_call_default 0
334#define jit_call_varargs 1
335
336#define jit_kind_register 1
337#define jit_kind_code 2
338#define jit_kind_word 3
339#define jit_kind_float32 4
340#define jit_kind_float64 5
341
342#define jit_cc_a0_reg 0x00000001 /* arg0 is a register */
343#define jit_cc_a0_chg 0x00000002 /* arg0 is modified */
344#define jit_cc_a0_jmp 0x00000004 /* arg0 is a jump target */
345#define jit_cc_a0_rlh 0x00000008 /* arg0 is a register pair */
346#define jit_cc_a0_int 0x00000010 /* arg0 is immediate word */
347#define jit_cc_a0_flt 0x00000020 /* arg0 is immediate float */
348#define jit_cc_a0_dbl 0x00000040 /* arg0 is immediate double */
349#define jit_cc_a0_arg 0x00000080 /* arg1 is an argument int id */
40a44dcb
PC
350#define jit_cc_a0_cnd 0x00000100 /* arg1 is a conditinally set register */
351#define jit_cc_a1_reg 0x00000200 /* arg1 is a register */
352#define jit_cc_a1_chg 0x00000400 /* arg1 is modified */
ba86ff93
PC
353#define jit_cc_a1_int 0x00000800 /* arg1 is immediate word */
354#define jit_cc_a1_flt 0x00001000 /* arg1 is immediate float */
355#define jit_cc_a1_dbl 0x00002000 /* arg1 is immediate double */
356#define jit_cc_a1_arg 0x00004000 /* arg1 is an argument node */
357#define jit_cc_a1_rlh 0x00008000 /* arg1 is a register pair */
4a71579b
PC
358#define jit_cc_a2_reg 0x00010000 /* arg2 is a register */
359#define jit_cc_a2_chg 0x00020000 /* arg2 is modified */
360#define jit_cc_a2_int 0x00100000 /* arg2 is immediate word */
361#define jit_cc_a2_flt 0x00200000 /* arg2 is immediate float */
362#define jit_cc_a2_dbl 0x00400000 /* arg2 is immediate double */
ba3814c1 363#define jit_cc_a2_rlh 0x00800000 /* arg2 is a register pair */
4a71579b
PC
364
365#if __ia64__ || (__sparc__ && __WORDSIZE == 64)
366extern void
367jit_regset_com(jit_regset_t*, jit_regset_t*);
368
369extern void
370jit_regset_and(jit_regset_t*, jit_regset_t*, jit_regset_t*);
371
372extern void
373jit_regset_ior(jit_regset_t*, jit_regset_t*, jit_regset_t*);
374
375extern void
376jit_regset_xor(jit_regset_t*, jit_regset_t*, jit_regset_t*);
377
378extern void
379jit_regset_set(jit_regset_t*, jit_regset_t*);
380
381extern void
382jit_regset_set_mask(jit_regset_t*, jit_int32_t);
383
384extern jit_bool_t
385jit_regset_cmp_ui(jit_regset_t*, jit_word_t);
386
387extern void
388jit_regset_set_ui(jit_regset_t*, jit_word_t);
389
390extern jit_bool_t
391jit_regset_set_p(jit_regset_t*);
392
393extern void
394jit_regset_clrbit(jit_regset_t*, jit_int32_t);
395
396extern void
397jit_regset_setbit(jit_regset_t*, jit_int32_t);
398
399extern jit_bool_t
400jit_regset_tstbit(jit_regset_t*, jit_int32_t);
401# if __sparc__ && __WORDSIZE == 64
402# define jit_regset_new(set) \
403 do { (set)->rl = (set)->rh = 0; } while (0)
404# define jit_regset_del(set) \
405 do { (set)->rl = (set)->rh = 0; } while (0)
406# else
407# define jit_regset_new(set) \
408 do { (set)->rl = (set)->rh = (set)->fl = (set)->fh = 0; } while (0)
409# define jit_regset_del(set) \
410 do { (set)->rl = (set)->rh = (set)->fl = (set)->fh = 0; } while (0)
411# endif
412#else
413# define jit_regset_com(u, v) (*(u) = ~*(v))
414# define jit_regset_and(u, v, w) (*(u) = *(v) & *(w))
415# define jit_regset_ior(u, v, w) (*(u) = *(v) | *(w))
416# define jit_regset_xor(u, v, w) (*(u) = *(v) ^ *(w))
417# define jit_regset_set(u, v) (*(u) = *(v))
418# define jit_regset_set_mask(u, v) (*(u) = (1LL << (v)) - 1)
419# define jit_regset_cmp_ui(u, v) (*(u) != (v))
420# define jit_regset_set_ui(u, v) (*(u) = (v))
421# define jit_regset_set_p(set) (*set)
422# define jit_regset_clrbit(set, bit) (*(set) &= ~(1LL << (bit)))
423# define jit_regset_setbit(set, bit) (*(set) |= 1LL << (bit))
424# define jit_regset_tstbit(set, bit) (*(set) & (1LL << (bit)))
425# define jit_regset_new(set) (*(set) = 0)
426# define jit_regset_del(set) (*(set) = 0)
427#endif
428extern unsigned long
429jit_regset_scan1(jit_regset_t*, jit_int32_t);
430
431#define jit_reglive_setup() \
432 do { \
433 jit_regset_set_ui(&_jitc->reglive, 0); \
434 jit_regset_set_ui(&_jitc->regmask, 0); \
435 } while (0)
436
437/*
438 * Types
439 */
440typedef union jit_data jit_data_t;
441typedef struct jit_note jit_note_t;
442typedef struct jit_line jit_line_t;
443typedef struct jit_block jit_block_t;
444typedef struct jit_value jit_value_t;
445typedef struct jit_compiler jit_compiler_t;
446typedef struct jit_function jit_function_t;
447typedef struct jit_register jit_register_t;
448#if __arm__
449# if DISASSEMBLER
450typedef struct jit_data_info jit_data_info_t;
451# endif
c0c16242
PC
452#elif __riscv
453typedef struct jit_const jit_const_t;
4a71579b
PC
454#endif
455
456union jit_data {
457 struct {
458#if __BYTE_ORDER == __LITTLE_ENDIAN
459 jit_int32_t l;
460 jit_int32_t h;
461#else
462 jit_int32_t h;
463 jit_int32_t l;
464#endif
465 } q;
466 jit_word_t w;
467 jit_float32_t f;
468 jit_float64_t d;
469 jit_pointer_t p;
470 jit_node_t *n;
471};
472
473struct jit_note {
474 jit_uint8_t *code;
475 char *name;
476 jit_line_t *lines;
477 jit_word_t length;
478 jit_word_t size; /* of code */
479};
480
481struct jit_line {
482 char *file;
483 jit_int32_t *linenos;
484 jit_int32_t *offsets;
485 jit_word_t length;
486};
487
488struct jit_node {
489 jit_node_t *next;
490 jit_code_t code;
491 jit_uint16_t flag;
492 jit_uint16_t offset; /* Used if DEVEL_DISASSEMBLER */
493 jit_data_t u;
494 jit_data_t v;
495 jit_data_t w;
496 jit_node_t *link;
497};
498
499struct jit_block {
500 jit_node_t *label;
501 jit_regset_t reglive;
502 jit_regset_t regmask;
c0c16242
PC
503 jit_bool_t again; /* Flag need to rebuild regset masks
504 * due to changes in live and unknown
505 * state. */
4a71579b
PC
506};
507
508struct jit_value {
509 jit_int32_t kind;
510 jit_code_t code;
511 jit_data_t base;
512 jit_data_t disp;
513};
514
515typedef struct {
516#if __arm__
517 jit_word_t kind;
518#endif
519 jit_word_t inst;
520 jit_node_t *node;
521} jit_patch_t;
522
523#if __arm__ && DISASSEMBLER
524struct jit_data_info {
525 jit_uword_t code; /* pointer in code buffer */
526 jit_word_t length; /* length of constant vector */
527};
c0c16242
PC
528#elif __riscv && __WORDSIZE == 64
529struct jit_const {
530 jit_word_t value;
531 jit_word_t address;
532 jit_const_t *next;
533};
4a71579b
PC
534#endif
535
536struct jit_function {
537 struct {
538 jit_int32_t argi;
539 jit_int32_t argf;
540 jit_int32_t size;
541 jit_int32_t aoff;
542 jit_int32_t alen;
543 jit_int32_t call;
544 jit_int32_t argn; /* for debug output */
545 } self;
546 struct {
547 jit_int32_t argi;
548 jit_int32_t argf;
549 jit_int32_t size;
550 jit_int32_t call;
551 } call;
552 jit_node_t *prolog;
553 jit_node_t *epilog;
79bfeef6 554 jit_node_t *alist;
4a71579b
PC
555 jit_int32_t *regoff;
556 jit_regset_t regset;
557 jit_int32_t stack;
d481fb64 558#if !defined(__arm__)
79bfeef6
PC
559 jit_int32_t cvt_offset; /* allocai'd offset for x87<->xmm or
560 * fpr<->gpr transfer using the stack */
561#endif
4a71579b
PC
562
563 /* Helper for common jit generation pattern, used in GNU Smalltalk
564 * and possibly others, where a static frame layout is required or
565 * assumed. */
566 jit_int32_t frame;
567 jit_uint32_t define_frame : 1;
568 jit_uint32_t assume_frame : 1;
569
79bfeef6
PC
570 jit_uint32_t need_frame : 1; /* need frame pointer? */
571 jit_uint32_t need_stack : 1; /* need stack pointer? */
572 jit_uint32_t need_return : 1; /* not a leaf function */
573
4a71579b
PC
574 /* alloca offset offset */
575 jit_int32_t aoffoff;
576 /* uses allocar flag */
577 jit_uint32_t allocar : 1;
578
79bfeef6
PC
579#if __arm__
580 /* If will, or might use float registers and vfp is not available.
581 * Use the first 64 bytes always, as the access to the virtual float
582 * registers use hardcoded instructions that can only reach 64 byte
583 * displacements, and to keep code simpler, do not use temporaries. */
584 jit_uint32_t swf_offset : 1;
585 /* If need to call C functions for some operation, or variadic function */
586 jit_uint32_t save_reg_args : 1;
587#endif
588
4a71579b
PC
589 /* varargs state offsets */
590 jit_int32_t vaoff; /* offset of jit_va_list */
591 jit_int32_t vagp; /* first gp va argument */
592 jit_int32_t vafp; /* first fp va argument */
593};
594
595/* data used only during jit generation */
596struct jit_compiler {
597#if __ia64__
598 struct {
599 jit_uint64_t i : 41;
600 jit_uint64_t t : 4;
601 } inst[3];
602 jit_regset_t regs; /* changed regs since last stop */
603 jit_int32_t pred; /* changed preds last stop */
604 jit_int32_t ioff; /* offset in inst vector */
605 jit_int32_t rout; /* first output register */
606 jit_int32_t breg; /* base register for prolog/epilog */
607#endif
79bfeef6
PC
608#if __mips__
609 struct {
610 jit_int32_t op; /* pending instruction, candidate
611 * to be inserted in a delay slot */
612 jit_bool_t pend; /* non zero if need to emit op */
613 } inst;
614#endif
4a71579b 615#if __mips__ || __ia64__ || __alpha__ || \
24d91c0d 616 (__sparc__ && __WORDSIZE == 64) || __riscv || __loongarch__
4a71579b
PC
617 jit_int32_t carry;
618#define jit_carry _jitc->carry
619#endif
620 jit_node_t *head;
621 jit_node_t *tail;
622 jit_node_t *prepare; /* inside prepare/finish* block */
623 jit_uint32_t realize : 1; /* jit_realize() called? */
624 jit_uint32_t dataset : 1; /* jit_dataset() called? */
625 jit_uint32_t done : 1; /* emit state finished */
626 jit_uint32_t emit : 1; /* emit state entered */
627 jit_uint32_t again : 1; /* start over emiting function */
628 jit_uint32_t synth : 8; /* emiting synthesized instructions */
629#if DEBUG
630 jit_uint32_t getreg : 1;
631#endif
632 jit_uint32_t no_data : 1;
633 jit_uint32_t no_note : 1;
ba86ff93
PC
634 /* FIXME undocumented, might be moved to a jit_cpu field or a better
635 * configuration api.
636 * These are switches to a different unld* or unst*.
637 * Defaults are the algorithms that generate shorter code*/
638 jit_uint32_t unld_algorithm : 1;
639 jit_uint32_t unst_algorithm : 1;
79bfeef6
PC
640 jit_int32_t framesize; /* space for callee save registers,
641 * frame pointer and return address */
4a71579b
PC
642 jit_int32_t reglen; /* number of registers */
643 jit_regset_t regarg; /* cannot allocate */
644 jit_regset_t regsav; /* automatic spill only once */
645 jit_regset_t reglive; /* known live registers at some point */
646 jit_regset_t regmask; /* register mask to update reglive */
79bfeef6 647 jit_regset_t explive; /* explicitly marked as live */
4a71579b
PC
648 struct {
649 jit_uint8_t *end;
650 } code;
651 struct {
652 jit_uint8_t *ptr;
653 jit_node_t **table; /* very simple hash table */
654 jit_word_t size; /* number of vectors in table */
655 jit_word_t count; /* number of hash table entries */
656 jit_word_t offset; /* offset in bytes in ptr */
657 } data;
658 jit_node_t **spill;
659 jit_int32_t *gen; /* ssa like "register version" */
660 jit_value_t *values; /* temporary jit_value_t vector */
661 struct {
662 jit_block_t *ptr;
663 jit_word_t offset;
664 jit_word_t length;
665 } blocks; /* basic blocks */
666 struct {
667 jit_patch_t *ptr;
668 jit_word_t offset;
669 jit_word_t length;
670 } patches; /* forward patch information */
671 jit_function_t *function; /* current function */
672 struct {
673 jit_function_t *ptr;
674 jit_word_t offset;
675 jit_word_t length;
676 } functions; /* prolog/epilogue offsets in code */
677 struct {
678 jit_node_t **ptr;
679 jit_word_t offset;
680 jit_word_t length;
681 } pool;
682 jit_node_t *list;
683 struct {
684 jit_node_t *head; /* first note node */
685 jit_node_t *tail; /* linked list insertion */
686 /* fields to store temporary state information */
687 jit_word_t size;
688 jit_node_t *name;
689 jit_node_t *note;
690 jit_uint8_t *base;
691 } note;
692#if __arm__
693 /* prevent using thumb instructions that set flags? */
694 jit_uint32_t no_set_flags : 1;
695# if DISASSEMBLER
696 struct {
697 jit_data_info_t *ptr;
698 jit_word_t offset;
699 jit_word_t length;
700 } data_info; /* constant pools information */
701# endif
702 /* Note that this field is somewhat hackish, but required by most
703 * ways to implement jit, unless implementing a pure one function
704 * per jit, as most times it needs to start the jit buffer with a
705 * jump where the "main" prolog starts, and because the initial
706 * code is in "arm mode", need to make an "arm mode" patch on that
707 * jump. A good example is the test suite assembler, where most
708 * test cases start with a "jmpi main" call. */
709 jit_uword_t thumb;
710 struct {
711 jit_uint8_t *data; /* pointer to code */
712 jit_word_t size; /* size data */
713 jit_word_t offset; /* pending patches */
714 jit_word_t length; /* number of pending constants */
715 jit_int32_t values[1024]; /* pending constants */
716 jit_word_t patches[2048];
717 } consts;
718#elif (__powerpc__ && _CALL_AIXDESC) || __ia64__
719 /* Keep track of prolog addresses, just for the sake of making
720 * jit that starts with a jump to a "main" label work like other
721 * backends. */
722 struct {
723 jit_word_t *ptr;
724 jit_word_t offset;
725 jit_word_t length;
726 } prolog;
727 jit_bool_t jump;
c0c16242
PC
728#elif __riscv && __WORDSIZE == 64
729 struct {
730 /* Hash table for constants to be resolved and patched */
731 struct {
732 jit_const_t **table; /* very simple hash table */
733 jit_word_t size; /* number of vectors in table */
734 jit_word_t count; /* number of distinct entries */
735 } hash;
736 struct {
737 jit_const_t **ptr; /* keep a single pointer */
738 jit_const_t *list; /* free list */
739 jit_word_t length; /* length of pool */
740 } pool;
741 /* Linear list for constants that cannot be encoded easily */
742 struct {
743 jit_word_t *instrs; /* list of direct movi instructions */
744 jit_word_t *values; /* list of direct movi constants */
745 jit_word_t offset; /* offset in instrs/values vector */
746 jit_word_t length; /* length of instrs/values vector */
747 } vector;
748 } consts;
4a71579b
PC
749#endif
750#if GET_JIT_SIZE
751 /* Temporary storage to calculate instructions length */
752 jit_word_t size;
753 /* Global flag for code buffer heuristic size computation */
754 jit_word_t mult;
755 /* Pointer to code to prevent miscalculation if reallocating buffer */
756 jit_uint8_t *cptr;
757#endif
758};
759
760#define _jitc _jit->comp
761struct jit_state {
762 union {
763 jit_uint8_t *uc;
764 jit_uint16_t *us;
765 jit_uint32_t *ui;
766 jit_uint64_t *ul;
767 jit_word_t w;
768 } pc;
769 struct {
770 jit_uint8_t *ptr;
771 jit_word_t length;
79bfeef6 772 /* PROTECTED bytes starting at PTR are mprotect'd. */
ba86ff93 773 jit_word_t protect;
4a71579b
PC
774 } code;
775 struct {
776 jit_uint8_t *ptr;
777 jit_word_t length;
778 } data;
779 struct {
780 jit_note_t *ptr;
781 jit_word_t length;
782 } note;
783 jit_compiler_t *comp;
784 /* Flags to know if user did set the code and data buffers */
785 jit_uint32_t user_code : 1;
786 jit_uint32_t user_data : 1;
787};
788
789struct jit_register {
790 jit_reg_t spec;
791 char *name;
792};
793
794/*
795 * Prototypes
796 */
797extern void jit_get_cpu(void);
798
799#define jit_init() _jit_init(_jit)
800extern void _jit_init(jit_state_t*);
801
802#define jit_synth_inc() _jit_synth_inc(_jit)
803extern void _jit_synth_inc(jit_state_t*);
804
805#define jit_new_node_no_link(u) _jit_new_node_no_link(_jit, u)
806extern jit_node_t *_jit_new_node_no_link(jit_state_t*, jit_code_t);
807
808#define jit_link_node(u) _jit_link_node(_jit, u)
809extern void _jit_link_node(jit_state_t*, jit_node_t*);
810
811#define jit_link_label(l) _jit_link_label(_jit,l)
812extern void
813_jit_link_label(jit_state_t*,jit_node_t*);
814
815#define jit_synth_dec() _jit_synth_dec(_jit)
816extern void _jit_synth_dec(jit_state_t*);
817
818#define jit_reglive(node) _jit_reglive(_jit, node)
819extern void
820_jit_reglive(jit_state_t*, jit_node_t*);
821
822#define jit_regarg_set(n,v) _jit_regarg_set(_jit,n,v)
823extern void
824_jit_regarg_set(jit_state_t*, jit_node_t*, jit_int32_t);
825
826#define jit_regarg_clr(n,v) _jit_regarg_clr(_jit,n,v)
827extern void
828_jit_regarg_clr(jit_state_t*, jit_node_t*, jit_int32_t);
829
4a71579b
PC
830#define jit_save(reg) _jit_save(_jit, reg)
831extern void
832_jit_save(jit_state_t*, jit_int32_t);
833
834#define jit_load(reg) _jit_load(_jit, reg)
835extern void
836_jit_load(jit_state_t*, jit_int32_t);
837
838#define jit_trampoline(u,v) _jit_trampoline(_jit, u, v)
839extern void _jit_trampoline(jit_state_t*, jit_int32_t, jit_bool_t);
840
841#define jit_optimize() _jit_optimize(_jit)
842extern void
843_jit_optimize(jit_state_t*);
844
845#define jit_classify(code) _jit_classify(_jit, code)
846extern jit_int32_t
847_jit_classify(jit_state_t*, jit_code_t);
848
849#define jit_regarg_p(n, r) _jit_regarg_p(_jit, n, r)
850extern jit_bool_t
851_jit_regarg_p(jit_state_t*, jit_node_t*, jit_int32_t);
852
853#define emit_code() _emit_code(_jit)
854extern jit_pointer_t
855_emit_code(jit_state_t*);
856
857extern void
858jit_flush(void *fptr, void *tptr);
859
860#define emit_ldxi(r0, r1, i0) _emit_ldxi(_jit, r0, r1, i0)
861extern void
862_emit_ldxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
863
864#define emit_stxi(i0, r0, r1) _emit_stxi(_jit, i0, r0, r1)
865extern void
866_emit_stxi(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
867
868#define emit_ldxi_d(r0, r1, i0) _emit_ldxi_d(_jit, r0, r1, i0)
869extern void
870_emit_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
871
872#define emit_stxi_d(i0, r0, r1) _emit_stxi_d(_jit, i0, r0, r1)
873extern void
874_emit_stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
875
b68d544b
PC
876extern void jit_init_print(FILE*);
877extern void jit_init_debug(const char*, FILE*);
4a71579b
PC
878extern void jit_finish_debug(void);
879
880extern void jit_init_note(void);
881extern void jit_finish_note(void);
882#define jit_set_note(n,u,v,w) _jit_set_note(_jit, n, u, v, w)
883extern void _jit_set_note(jit_state_t*, jit_note_t*, char*, int, jit_int32_t);
884#define jit_annotate() _jit_annotate(_jit)
885extern void _jit_annotate(jit_state_t*);
886
887#define jit_print_node(u) _jit_print_node(_jit,u)
888extern void _jit_print_node(jit_state_t*,jit_node_t*);
889
890extern jit_pointer_t jit_memcpy(jit_pointer_t,const void*,jit_word_t);
891extern jit_pointer_t jit_memmove(jit_pointer_t,const void*,jit_word_t);
892extern void jit_alloc(jit_pointer_t*, jit_word_t);
893extern void jit_realloc(jit_pointer_t*, jit_word_t, jit_word_t);
894void jit_free(jit_pointer_t*);
895
896extern void jit_init_size(void);
897extern void jit_finish_size(void);
898
899#if GET_JIT_SIZE
900# define jit_size_prepare() _jit_size_prepare(_jit)
901extern void
902_jit_size_prepare(jit_state_t*);
903
904# define jit_size_collect(node) _jit_size_collect(_jit, node)
905extern void
906_jit_size_collect(jit_state_t*, jit_node_t*);
907#else
908# define jit_get_size() _jit_get_size(_jit)
909extern jit_word_t
910_jit_get_size(jit_state_t*);
911#endif
912
913extern jit_word_t
914jit_get_max_instr(void);
915
916/*
917 * Externs
918 */
919extern jit_register_t _rvs[];
920
921#endif /* _jit_private_h */