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