2 * Copyright (C) 2012-2019 Free Software Foundation, Inc.
4 * This file is part of GNU lightning.
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)
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.
17 * Paulo Cesar Pereira de Andrade
20 #ifndef _jit_private_h
21 #define _jit_private_h
34 # if !defined(offsetof)
35 # define offsetof(type, field) ((char *)&((type *)0)->field - (char *)0)
40 # define maybe_unused __attribute__ ((unused))
41 # define unlikely(exprn) __builtin_expect(!!(exprn), 0)
42 # define likely(exprn) __builtin_expect(!!(exprn), 1)
44 # define PUBLIC __attribute__ ((visibility("default")))
45 # define HIDDEN __attribute__ ((visibility("hidden")))
51 # define maybe_unused /**/
52 # define unlikely(exprn) exprn
53 # define likely(exprn) exprn
58 #define rc(value) jit_class_##value
59 #define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec))
61 #if defined(__i386__) || defined(__x86_64__)
65 # define JIT_FRET _ST0
66 typedef jit_uint32_t jit_regset_t;
68 # if __CYGWIN__ || _WIN32
73 # define JIT_FA0 _XMM0
74 # define JIT_FRET _XMM0
75 typedef jit_uint64_t jit_regset_t;
77 #elif defined(__mips__)
83 typedef jit_uint64_t jit_regset_t;
84 #elif defined(__arm__)
89 # if defined(__ARM_PCS_VFP)
94 typedef jit_uint64_t jit_regset_t;
95 #elif defined(__powerpc__)
100 # define JIT_FRET _F1
101 typedef jit_uint64_t jit_regset_t;
102 #elif defined(__sparc__)
105 # define JIT_FRET _F0
106 # if __WORDSIZE == 32
107 typedef jit_uint64_t jit_regset_t;
114 #elif defined(__ia64__)
117 # define JIT_FRET _F8
124 #elif defined(__hppa__)
126 # define JIT_RET _R28
127 # define JIT_FRET _F4
128 typedef jit_uint64_t jit_regset_t;
129 #elif defined(__aarch64__)
134 # define JIT_FRET _V0
135 typedef jit_uint64_t jit_regset_t;
136 #elif defined(__s390__) || defined(__s390x__)
139 # define JIT_FRET _F0
140 typedef jit_uint32_t jit_regset_t;
141 #elif defined(__alpha__)
144 # define JIT_FRET _F0
145 typedef jit_uint64_t jit_regset_t;
146 #elif defined(__riscv)
148 # define JIT_FA0 _FA0
151 # define JIT_FRET _FA0
152 typedef jit_uint64_t jit_regset_t;
155 #define jit_data(u,v,w) _jit_data(_jit,u,v,w)
156 extern jit_node_t *_jit_data(jit_state_t*, const void*,
157 jit_word_t, jit_int32_t);
159 #define jit_size(vector) (sizeof(vector) / sizeof((vector)[0]))
161 #define jit_reg_free_p(regno) \
162 (!jit_regset_tstbit(&_jitc->reglive, regno) && \
163 !jit_regset_tstbit(&_jitc->regarg, regno) && \
164 !jit_regset_tstbit(&_jitc->regsav, regno))
166 #define jit_reg_free_if_spill_p(regno) \
167 (!jit_regset_tstbit(&_jitc->regarg, regno) && \
168 !jit_regset_tstbit(&_jitc->regsav, regno))
170 #define jit_inc_synth(code) \
172 (void)jit_new_node(jit_code_##code); \
175 #define jit_inc_synth_w(code, u) \
177 (void)jit_new_node_w(jit_code_##code, u); \
180 #define jit_inc_synth_f(code, u) \
182 (void)jit_new_node_f(jit_code_##code, u); \
185 #define jit_inc_synth_d(code, u) \
187 (void)jit_new_node_d(jit_code_##code, u); \
190 #define jit_inc_synth_ww(code, u, v) \
192 (void)jit_new_node_ww(jit_code_##code, u, v); \
195 #define jit_inc_synth_wp(code, u, v) \
197 (void)jit_new_node_wp(jit_code_##code, u, v); \
200 #define jit_inc_synth_fp(code, u, v) \
202 (void)jit_new_node_fp(jit_code_##code, u, v); \
205 #define jit_inc_synth_dp(code, u, v) \
207 (void)jit_new_node_dp(jit_code_##code, u, v); \
210 #define jit_dec_synth() jit_synth_dec()
212 #define jit_link_prolog() \
214 _jitc->tail->link = _jitc->function->prolog->link; \
215 _jitc->function->prolog->link = _jitc->tail; \
217 #define jit_link_prepare() \
219 _jitc->tail->link = _jitc->prepare->link; \
220 _jitc->prepare->link = _jitc->tail; \
222 #define jit_link_reverse(where) \
224 jit_node_t *tmp, *tail = 0; \
226 tmp = (where)->link; \
227 (where)->link = tail; \
235 * Private jit_class bitmasks
237 #define jit_class_named 0x00400000 /* hit must be the named reg */
238 #define jit_class_nospill 0x00800000 /* hint to fail if need spill */
239 #define jit_class_sft 0x01000000 /* not a hardware register */
240 #define jit_class_rg8 0x04000000 /* x86 8 bits */
241 #define jit_class_xpr 0x80000000 /* float / vector */
242 /* Used on sparc64 where %f0-%f31 can be encode for single float
243 * but %f32 to %f62 only as double precision */
244 #define jit_class_sng 0x10000000 /* Single precision float */
245 #define jit_class_dbl 0x20000000 /* Only double precision float */
246 #define jit_regno_patch 0x00008000 /* this is a register
247 * returned by a "user" call
248 * to jit_get_reg() */
250 #define jit_call_default 0
251 #define jit_call_varargs 1
253 #define jit_kind_register 1
254 #define jit_kind_code 2
255 #define jit_kind_word 3
256 #define jit_kind_float32 4
257 #define jit_kind_float64 5
259 #define jit_cc_a0_reg 0x00000001 /* arg0 is a register */
260 #define jit_cc_a0_chg 0x00000002 /* arg0 is modified */
261 #define jit_cc_a0_jmp 0x00000004 /* arg0 is a jump target */
262 #define jit_cc_a0_rlh 0x00000008 /* arg0 is a register pair */
263 #define jit_cc_a0_int 0x00000010 /* arg0 is immediate word */
264 #define jit_cc_a0_flt 0x00000020 /* arg0 is immediate float */
265 #define jit_cc_a0_dbl 0x00000040 /* arg0 is immediate double */
266 #define jit_cc_a0_arg 0x00000080 /* arg1 is an argument int id */
267 #define jit_cc_a1_reg 0x00000100 /* arg1 is a register */
268 #define jit_cc_a1_chg 0x00000200 /* arg1 is modified */
269 #define jit_cc_a1_int 0x00001000 /* arg1 is immediate word */
270 #define jit_cc_a1_flt 0x00002000 /* arg1 is immediate float */
271 #define jit_cc_a1_dbl 0x00004000 /* arg1 is immediate double */
272 #define jit_cc_a1_arg 0x00008000 /* arg1 is an argument node */
273 #define jit_cc_a2_reg 0x00010000 /* arg2 is a register */
274 #define jit_cc_a2_chg 0x00020000 /* arg2 is modified */
275 #define jit_cc_a2_int 0x00100000 /* arg2 is immediate word */
276 #define jit_cc_a2_flt 0x00200000 /* arg2 is immediate float */
277 #define jit_cc_a2_dbl 0x00400000 /* arg2 is immediate double */
279 #if __ia64__ || (__sparc__ && __WORDSIZE == 64)
281 jit_regset_com(jit_regset_t*, jit_regset_t*);
284 jit_regset_and(jit_regset_t*, jit_regset_t*, jit_regset_t*);
287 jit_regset_ior(jit_regset_t*, jit_regset_t*, jit_regset_t*);
290 jit_regset_xor(jit_regset_t*, jit_regset_t*, jit_regset_t*);
293 jit_regset_set(jit_regset_t*, jit_regset_t*);
296 jit_regset_set_mask(jit_regset_t*, jit_int32_t);
299 jit_regset_cmp_ui(jit_regset_t*, jit_word_t);
302 jit_regset_set_ui(jit_regset_t*, jit_word_t);
305 jit_regset_set_p(jit_regset_t*);
308 jit_regset_clrbit(jit_regset_t*, jit_int32_t);
311 jit_regset_setbit(jit_regset_t*, jit_int32_t);
314 jit_regset_tstbit(jit_regset_t*, jit_int32_t);
315 # if __sparc__ && __WORDSIZE == 64
316 # define jit_regset_new(set) \
317 do { (set)->rl = (set)->rh = 0; } while (0)
318 # define jit_regset_del(set) \
319 do { (set)->rl = (set)->rh = 0; } while (0)
321 # define jit_regset_new(set) \
322 do { (set)->rl = (set)->rh = (set)->fl = (set)->fh = 0; } while (0)
323 # define jit_regset_del(set) \
324 do { (set)->rl = (set)->rh = (set)->fl = (set)->fh = 0; } while (0)
327 # define jit_regset_com(u, v) (*(u) = ~*(v))
328 # define jit_regset_and(u, v, w) (*(u) = *(v) & *(w))
329 # define jit_regset_ior(u, v, w) (*(u) = *(v) | *(w))
330 # define jit_regset_xor(u, v, w) (*(u) = *(v) ^ *(w))
331 # define jit_regset_set(u, v) (*(u) = *(v))
332 # define jit_regset_set_mask(u, v) (*(u) = (1LL << (v)) - 1)
333 # define jit_regset_cmp_ui(u, v) (*(u) != (v))
334 # define jit_regset_set_ui(u, v) (*(u) = (v))
335 # define jit_regset_set_p(set) (*set)
336 # define jit_regset_clrbit(set, bit) (*(set) &= ~(1LL << (bit)))
337 # define jit_regset_setbit(set, bit) (*(set) |= 1LL << (bit))
338 # define jit_regset_tstbit(set, bit) (*(set) & (1LL << (bit)))
339 # define jit_regset_new(set) (*(set) = 0)
340 # define jit_regset_del(set) (*(set) = 0)
343 jit_regset_scan1(jit_regset_t*, jit_int32_t);
345 #define jit_reglive_setup() \
347 jit_regset_set_ui(&_jitc->reglive, 0); \
348 jit_regset_set_ui(&_jitc->regmask, 0); \
354 typedef union jit_data jit_data_t;
355 typedef struct jit_note jit_note_t;
356 typedef struct jit_line jit_line_t;
357 typedef struct jit_block jit_block_t;
358 typedef struct jit_value jit_value_t;
359 typedef struct jit_compiler jit_compiler_t;
360 typedef struct jit_function jit_function_t;
361 typedef struct jit_register jit_register_t;
364 typedef struct jit_data_info jit_data_info_t;
370 #if __BYTE_ORDER == __LITTLE_ENDIAN
390 jit_word_t size; /* of code */
395 jit_int32_t *linenos;
396 jit_int32_t *offsets;
404 jit_uint16_t offset; /* Used if DEVEL_DISASSEMBLER */
413 jit_regset_t reglive;
414 jit_regset_t regmask;
432 #if __arm__ && DISASSEMBLER
433 struct jit_data_info {
434 jit_uword_t code; /* pointer in code buffer */
435 jit_word_t length; /* length of constant vector */
439 struct jit_function {
447 jit_int32_t argn; /* for debug output */
461 /* Helper for common jit generation pattern, used in GNU Smalltalk
462 * and possibly others, where a static frame layout is required or
465 jit_uint32_t define_frame : 1;
466 jit_uint32_t assume_frame : 1;
468 /* alloca offset offset */
470 /* uses allocar flag */
471 jit_uint32_t allocar : 1;
473 /* varargs state offsets */
474 jit_int32_t vaoff; /* offset of jit_va_list */
475 jit_int32_t vagp; /* first gp va argument */
476 jit_int32_t vafp; /* first fp va argument */
479 /* data used only during jit generation */
480 struct jit_compiler {
486 jit_regset_t regs; /* changed regs since last stop */
487 jit_int32_t pred; /* changed preds last stop */
488 jit_int32_t ioff; /* offset in inst vector */
489 jit_int32_t rout; /* first output register */
490 jit_int32_t breg; /* base register for prolog/epilog */
492 #if __mips__ || __ia64__ || __alpha__ || \
493 (__sparc__ && __WORDSIZE == 64) || __riscv
495 #define jit_carry _jitc->carry
499 jit_node_t *prepare; /* inside prepare/finish* block */
500 jit_uint32_t realize : 1; /* jit_realize() called? */
501 jit_uint32_t dataset : 1; /* jit_dataset() called? */
502 jit_uint32_t done : 1; /* emit state finished */
503 jit_uint32_t emit : 1; /* emit state entered */
504 jit_uint32_t again : 1; /* start over emiting function */
505 jit_uint32_t synth : 8; /* emiting synthesized instructions */
507 jit_uint32_t getreg : 1;
509 jit_uint32_t no_data : 1;
510 jit_uint32_t no_note : 1;
511 jit_int32_t reglen; /* number of registers */
512 jit_regset_t regarg; /* cannot allocate */
513 jit_regset_t regsav; /* automatic spill only once */
514 jit_regset_t reglive; /* known live registers at some point */
515 jit_regset_t regmask; /* register mask to update reglive */
521 jit_node_t **table; /* very simple hash table */
522 jit_word_t size; /* number of vectors in table */
523 jit_word_t count; /* number of hash table entries */
524 jit_word_t offset; /* offset in bytes in ptr */
527 jit_int32_t *gen; /* ssa like "register version" */
528 jit_value_t *values; /* temporary jit_value_t vector */
533 } blocks; /* basic blocks */
538 } patches; /* forward patch information */
539 jit_function_t *function; /* current function */
544 } functions; /* prolog/epilogue offsets in code */
552 jit_node_t *head; /* first note node */
553 jit_node_t *tail; /* linked list insertion */
554 /* fields to store temporary state information */
561 /* prevent using thumb instructions that set flags? */
562 jit_uint32_t no_set_flags : 1;
565 jit_data_info_t *ptr;
568 } data_info; /* constant pools information */
570 /* Note that this field is somewhat hackish, but required by most
571 * ways to implement jit, unless implementing a pure one function
572 * per jit, as most times it needs to start the jit buffer with a
573 * jump where the "main" prolog starts, and because the initial
574 * code is in "arm mode", need to make an "arm mode" patch on that
575 * jump. A good example is the test suite assembler, where most
576 * test cases start with a "jmpi main" call. */
579 jit_uint8_t *data; /* pointer to code */
580 jit_word_t size; /* size data */
581 jit_word_t offset; /* pending patches */
582 jit_word_t length; /* number of pending constants */
583 jit_int32_t values[1024]; /* pending constants */
584 jit_word_t patches[2048];
586 #elif (__powerpc__ && _CALL_AIXDESC) || __ia64__
587 /* Keep track of prolog addresses, just for the sake of making
588 * jit that starts with a jump to a "main" label work like other
598 /* Temporary storage to calculate instructions length */
600 /* Global flag for code buffer heuristic size computation */
602 /* Pointer to code to prevent miscalculation if reallocating buffer */
607 #define _jitc _jit->comp
628 jit_compiler_t *comp;
629 /* Flags to know if user did set the code and data buffers */
630 jit_uint32_t user_code : 1;
631 jit_uint32_t user_data : 1;
634 struct jit_register {
642 extern void jit_get_cpu(void);
644 #define jit_init() _jit_init(_jit)
645 extern void _jit_init(jit_state_t*);
647 #define jit_synth_inc() _jit_synth_inc(_jit)
648 extern void _jit_synth_inc(jit_state_t*);
650 #define jit_new_node_no_link(u) _jit_new_node_no_link(_jit, u)
651 extern jit_node_t *_jit_new_node_no_link(jit_state_t*, jit_code_t);
653 #define jit_link_node(u) _jit_link_node(_jit, u)
654 extern void _jit_link_node(jit_state_t*, jit_node_t*);
656 #define jit_link_label(l) _jit_link_label(_jit,l)
658 _jit_link_label(jit_state_t*,jit_node_t*);
660 #define jit_synth_dec() _jit_synth_dec(_jit)
661 extern void _jit_synth_dec(jit_state_t*);
663 #define jit_reglive(node) _jit_reglive(_jit, node)
665 _jit_reglive(jit_state_t*, jit_node_t*);
667 #define jit_regarg_set(n,v) _jit_regarg_set(_jit,n,v)
669 _jit_regarg_set(jit_state_t*, jit_node_t*, jit_int32_t);
671 #define jit_regarg_clr(n,v) _jit_regarg_clr(_jit,n,v)
673 _jit_regarg_clr(jit_state_t*, jit_node_t*, jit_int32_t);
675 #define jit_get_reg(s) _jit_get_reg(_jit,s)
677 _jit_get_reg(jit_state_t*, jit_int32_t);
679 #define jit_unget_reg(r) _jit_unget_reg(_jit,r)
681 _jit_unget_reg(jit_state_t*, jit_int32_t);
683 #define jit_save(reg) _jit_save(_jit, reg)
685 _jit_save(jit_state_t*, jit_int32_t);
687 #define jit_load(reg) _jit_load(_jit, reg)
689 _jit_load(jit_state_t*, jit_int32_t);
691 #define jit_trampoline(u,v) _jit_trampoline(_jit, u, v)
692 extern void _jit_trampoline(jit_state_t*, jit_int32_t, jit_bool_t);
694 #define jit_optimize() _jit_optimize(_jit)
696 _jit_optimize(jit_state_t*);
698 #define jit_classify(code) _jit_classify(_jit, code)
700 _jit_classify(jit_state_t*, jit_code_t);
702 #define jit_regarg_p(n, r) _jit_regarg_p(_jit, n, r)
704 _jit_regarg_p(jit_state_t*, jit_node_t*, jit_int32_t);
706 #define emit_code() _emit_code(_jit)
708 _emit_code(jit_state_t*);
711 jit_flush(void *fptr, void *tptr);
713 #define emit_ldxi(r0, r1, i0) _emit_ldxi(_jit, r0, r1, i0)
715 _emit_ldxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
717 #define emit_stxi(i0, r0, r1) _emit_stxi(_jit, i0, r0, r1)
719 _emit_stxi(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
721 #define emit_ldxi_d(r0, r1, i0) _emit_ldxi_d(_jit, r0, r1, i0)
723 _emit_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
725 #define emit_stxi_d(i0, r0, r1) _emit_stxi_d(_jit, i0, r0, r1)
727 _emit_stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
729 extern void jit_init_debug(const char*);
730 extern void jit_finish_debug(void);
732 extern void jit_init_note(void);
733 extern void jit_finish_note(void);
734 #define jit_set_note(n,u,v,w) _jit_set_note(_jit, n, u, v, w)
735 extern void _jit_set_note(jit_state_t*, jit_note_t*, char*, int, jit_int32_t);
736 #define jit_annotate() _jit_annotate(_jit)
737 extern void _jit_annotate(jit_state_t*);
739 #define jit_print_node(u) _jit_print_node(_jit,u)
740 extern void _jit_print_node(jit_state_t*,jit_node_t*);
742 extern jit_pointer_t jit_memcpy(jit_pointer_t,const void*,jit_word_t);
743 extern jit_pointer_t jit_memmove(jit_pointer_t,const void*,jit_word_t);
744 extern void jit_alloc(jit_pointer_t*, jit_word_t);
745 extern void jit_realloc(jit_pointer_t*, jit_word_t, jit_word_t);
746 void jit_free(jit_pointer_t*);
748 extern void jit_init_size(void);
749 extern void jit_finish_size(void);
752 # define jit_size_prepare() _jit_size_prepare(_jit)
754 _jit_size_prepare(jit_state_t*);
756 # define jit_size_collect(node) _jit_size_collect(_jit, node)
758 _jit_size_collect(jit_state_t*, jit_node_t*);
760 # define jit_get_size() _jit_get_size(_jit)
762 _jit_get_size(jit_state_t*);
766 jit_get_max_instr(void);
771 extern jit_register_t _rvs[];
773 #endif /* _jit_private_h */