mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-02 21:10:27 +02:00
* include/lightning.h, include/lightning/jit_private.h, lib/lightning.c: Implement the new jit_set_code() interface, that allows instructing lightning to use an alternate code buffer. The new jit_realize() function should be called before jit_set_code(), and usually call jit_get_code() to query the amount of bytes expected to be required for the code. * lib/jit_size.c: Minor update to have less chances of miscalculating the code buffer by starting the counter with the size of the longest instruction instead of zero, as code emit fails if at any moment less than the longest instruction bytes are available. * check/setcode.c: New file implementing some basic tests of the new jit_set_code() interface. * check/Makefile.am: Update for newer test case.
595 lines
16 KiB
C
595 lines
16 KiB
C
/*
|
|
* Copyright (C) 2012, 2013 Free Software Foundation, Inc.
|
|
*
|
|
* This file is part of GNU lightning.
|
|
*
|
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published
|
|
* by the Free Software Foundation; either version 3, or (at your option)
|
|
* any later version.
|
|
*
|
|
* GNU lightning is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
* License for more details.
|
|
*
|
|
* Authors:
|
|
* Paulo Cesar Pereira de Andrade
|
|
*/
|
|
|
|
#ifndef _jit_private_h
|
|
#define _jit_private_h
|
|
|
|
#if HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <assert.h>
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
|
|
#if defined(__GNUC__)
|
|
# define maybe_unused __attribute__ ((unused))
|
|
# define unlikely(exprn) __builtin_expect(!!(exprn), 0)
|
|
# define likely(exprn) __builtin_expect(!!(exprn), 1)
|
|
# if (__GNUC__ >= 4)
|
|
# define PUBLIC __attribute__ ((visibility("default")))
|
|
# define HIDDEN __attribute__ ((visibility("hidden")))
|
|
# else
|
|
# define PUBLIC /**/
|
|
# define HIDDEN /**/
|
|
# endif
|
|
#else
|
|
# define maybe_unused /**/
|
|
# define unlikely(exprn) exprn
|
|
# define likely(exprn) exprn
|
|
# define PUBLIC /**/
|
|
# define HIDDEN /**/
|
|
#endif
|
|
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
# define JIT_SP _RSP
|
|
# define JIT_RET _RAX
|
|
# if __WORDSIZE == 32
|
|
# define JIT_FRET _ST0
|
|
# else
|
|
# define JIT_FRET _XMM0
|
|
# endif
|
|
#elif defined(__mips__)
|
|
# define JIT_SP _SP
|
|
# define JIT_RET _V0
|
|
# define JIT_FRET _F0
|
|
#elif defined(__arm__)
|
|
# define JIT_SP _R13
|
|
# define JIT_RET _R0
|
|
# if defined(__ARM_PCS_VFP)
|
|
# define JIT_FRET _D0
|
|
# else
|
|
# define JIT_FRET _R0
|
|
# endif
|
|
#elif defined(__ppc__) || defined(__powerpc__)
|
|
# define JIT_SP _R1
|
|
# define JIT_RET _R3
|
|
# define JIT_FRET _F1
|
|
#elif defined(__sparc__)
|
|
# define JIT_SP _SP
|
|
# define JIT_RET _I0
|
|
# define JIT_FRET _F0
|
|
#elif defined(__ia64__)
|
|
# define JIT_SP _R12
|
|
# define JIT_RET _R8
|
|
# define JIT_FRET _F8
|
|
#elif defined(__hppa__)
|
|
# define JIT_SP _R30
|
|
# define JIT_RET _R28
|
|
# define JIT_FRET _F4
|
|
#elif defined(__aarch64__)
|
|
# define JIT_SP _SP
|
|
# define JIT_RET _R0
|
|
# define JIT_FRET _V0
|
|
#elif defined(__s390x__)
|
|
# define JIT_SP _R15
|
|
# define JIT_RET _R2
|
|
# define JIT_FRET _F0
|
|
#endif
|
|
|
|
#define jit_size(vector) (sizeof(vector) / sizeof((vector)[0]))
|
|
|
|
#define jit_reg_free_p(regno) \
|
|
(!jit_regset_tstbit(&_jitc->reglive, regno) && \
|
|
!jit_regset_tstbit(&_jitc->regarg, regno) && \
|
|
!jit_regset_tstbit(&_jitc->regsav, regno))
|
|
|
|
#define jit_reg_free_if_spill_p(regno) \
|
|
(!jit_regset_tstbit(&_jitc->regarg, regno) && \
|
|
!jit_regset_tstbit(&_jitc->regsav, regno))
|
|
|
|
/*
|
|
* Private jit_class bitmasks
|
|
*/
|
|
#define jit_class_named 0x00400000 /* hit must be the named reg */
|
|
#define jit_class_nospill 0x00800000 /* hint to fail if need spill */
|
|
#define jit_class_sft 0x01000000 /* not a hardware register */
|
|
#define jit_class_rg8 0x04000000 /* x86 8 bits */
|
|
#define jit_class_xpr 0x80000000 /* float / vector */
|
|
#define jit_regno_patch 0x00008000 /* this is a register
|
|
* returned by a "user" call
|
|
* to jit_get_reg() */
|
|
|
|
#define jit_call_default 0
|
|
#define jit_call_varargs 1
|
|
|
|
#define jit_kind_register 1
|
|
#define jit_kind_code 2
|
|
#define jit_kind_word 3
|
|
#define jit_kind_float32 4
|
|
#define jit_kind_float64 5
|
|
|
|
#define jit_cc_a0_reg 0x00000001 /* arg0 is a register */
|
|
#define jit_cc_a0_chg 0x00000002 /* arg0 is modified */
|
|
#define jit_cc_a0_jmp 0x00000004 /* arg0 is a jump target */
|
|
#define jit_cc_a0_rlh 0x00000008 /* arg0 is a register pair */
|
|
#define jit_cc_a0_int 0x00000010 /* arg0 is immediate word */
|
|
#define jit_cc_a0_flt 0x00000020 /* arg0 is immediate float */
|
|
#define jit_cc_a0_dbl 0x00000040 /* arg0 is immediate double */
|
|
#define jit_cc_a1_reg 0x00000100 /* arg1 is a register */
|
|
#define jit_cc_a1_chg 0x00000200 /* arg1 is modified */
|
|
#define jit_cc_a1_int 0x00001000 /* arg1 is immediate word */
|
|
#define jit_cc_a1_flt 0x00002000 /* arg1 is immediate float */
|
|
#define jit_cc_a1_dbl 0x00004000 /* arg1 is immediate double */
|
|
#define jit_cc_a2_reg 0x00010000 /* arg2 is a register */
|
|
#define jit_cc_a2_chg 0x00020000 /* arg2 is modified */
|
|
#define jit_cc_a2_int 0x00100000 /* arg2 is immediate word */
|
|
#define jit_cc_a2_flt 0x00200000 /* arg2 is immediate float */
|
|
#define jit_cc_a2_dbl 0x00400000 /* arg2 is immediate double */
|
|
|
|
#if __ia64__
|
|
extern void
|
|
jit_regset_com(jit_regset_t*, jit_regset_t*);
|
|
|
|
extern void
|
|
jit_regset_and(jit_regset_t*, jit_regset_t*, jit_regset_t*);
|
|
|
|
extern void
|
|
jit_regset_ior(jit_regset_t*, jit_regset_t*, jit_regset_t*);
|
|
|
|
extern void
|
|
jit_regset_xor(jit_regset_t*, jit_regset_t*, jit_regset_t*);
|
|
|
|
extern void
|
|
jit_regset_set(jit_regset_t*, jit_regset_t*);
|
|
|
|
extern void
|
|
jit_regset_set_mask(jit_regset_t*, jit_int32_t);
|
|
|
|
extern jit_bool_t
|
|
jit_regset_cmp_ui(jit_regset_t*, jit_word_t);
|
|
|
|
extern void
|
|
jit_regset_set_ui(jit_regset_t*, jit_word_t);
|
|
|
|
extern jit_bool_t
|
|
jit_regset_set_p(jit_regset_t*);
|
|
|
|
extern void
|
|
jit_regset_clrbit(jit_regset_t*, jit_int32_t);
|
|
|
|
extern void
|
|
jit_regset_setbit(jit_regset_t*, jit_int32_t);
|
|
|
|
extern jit_bool_t
|
|
jit_regset_tstbit(jit_regset_t*, jit_int32_t);
|
|
# define jit_regset_new(set) \
|
|
do { (set)->rl = (set)->rh = (set)->fl = (set)->fh = 0; } while (0)
|
|
# define jit_regset_del(set) \
|
|
do { (set)->rl = (set)->rh = (set)->fl = (set)->fh = 0; } while (0)
|
|
#else
|
|
# define jit_regset_com(u, v) (*(u) = ~*(v))
|
|
# define jit_regset_and(u, v, w) (*(u) = *(v) & *(w))
|
|
# define jit_regset_ior(u, v, w) (*(u) = *(v) | *(w))
|
|
# define jit_regset_xor(u, v, w) (*(u) = *(v) ^ *(w))
|
|
# define jit_regset_set(u, v) (*(u) = *(v))
|
|
# define jit_regset_set_mask(u, v) (*(u) = (1LL << (v)) - 1)
|
|
# define jit_regset_cmp_ui(u, v) (*(u) != (v))
|
|
# define jit_regset_set_ui(u, v) (*(u) = (v))
|
|
# define jit_regset_set_p(set) (*set)
|
|
# define jit_regset_clrbit(set, bit) (*(set) &= ~(1LL << (bit)))
|
|
# define jit_regset_setbit(set, bit) (*(set) |= 1LL << (bit))
|
|
# define jit_regset_tstbit(set, bit) (*(set) & (1LL << (bit)))
|
|
# define jit_regset_new(set) (*(set) = 0)
|
|
# define jit_regset_del(set) (*(set) = 0)
|
|
#endif
|
|
extern unsigned long
|
|
jit_regset_scan1(jit_regset_t*, jit_int32_t);
|
|
|
|
#define jit_reglive_setup() \
|
|
do { \
|
|
jit_regset_set_ui(&_jitc->reglive, 0); \
|
|
jit_regset_set_ui(&_jitc->regmask, 0); \
|
|
} while (0)
|
|
|
|
/*
|
|
* Types
|
|
*/
|
|
typedef union jit_data jit_data_t;
|
|
typedef struct jit_note jit_note_t;
|
|
typedef struct jit_line jit_line_t;
|
|
typedef struct jit_block jit_block_t;
|
|
typedef struct jit_value jit_value_t;
|
|
typedef struct jit_compiler jit_compiler_t;
|
|
typedef struct jit_function jit_function_t;
|
|
typedef struct jit_register jit_register_t;
|
|
#if __arm__
|
|
# if DISASSEMBLER
|
|
typedef struct jit_data_info jit_data_info_t;
|
|
# endif
|
|
#endif
|
|
|
|
union jit_data {
|
|
struct {
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
jit_int32_t l;
|
|
jit_int32_t h;
|
|
#else
|
|
jit_int32_t h;
|
|
jit_int32_t l;
|
|
#endif
|
|
} q;
|
|
jit_word_t w;
|
|
jit_float32_t f;
|
|
jit_float64_t d;
|
|
jit_pointer_t p;
|
|
jit_node_t *n;
|
|
};
|
|
|
|
struct jit_note {
|
|
jit_uint8_t *code;
|
|
char *name;
|
|
jit_line_t *lines;
|
|
jit_word_t length;
|
|
jit_word_t size; /* of code */
|
|
};
|
|
|
|
struct jit_line {
|
|
char *file;
|
|
jit_int32_t *linenos;
|
|
jit_int32_t *offsets;
|
|
jit_word_t length;
|
|
};
|
|
|
|
struct jit_node {
|
|
jit_node_t *next;
|
|
jit_code_t code;
|
|
jit_int32_t flag;
|
|
jit_data_t u;
|
|
jit_data_t v;
|
|
jit_data_t w;
|
|
jit_node_t *link;
|
|
};
|
|
|
|
struct jit_block {
|
|
jit_node_t *label;
|
|
jit_regset_t reglive;
|
|
jit_regset_t regmask;
|
|
};
|
|
|
|
struct jit_value {
|
|
jit_int32_t kind;
|
|
jit_code_t code;
|
|
jit_data_t base;
|
|
jit_data_t disp;
|
|
};
|
|
|
|
typedef struct {
|
|
#if __arm__
|
|
jit_word_t kind;
|
|
#endif
|
|
jit_word_t inst;
|
|
jit_node_t *node;
|
|
} jit_patch_t;
|
|
|
|
#if __arm__ && DISASSEMBLER
|
|
struct jit_data_info {
|
|
jit_uword_t code; /* pointer in code buffer */
|
|
jit_word_t length; /* length of constant vector */
|
|
};
|
|
#endif
|
|
|
|
struct jit_function {
|
|
struct {
|
|
jit_int32_t argi;
|
|
jit_int32_t argf;
|
|
jit_int32_t size;
|
|
jit_int32_t aoff;
|
|
jit_int32_t alen;
|
|
jit_int32_t call;
|
|
} self;
|
|
struct {
|
|
jit_int32_t argi;
|
|
jit_int32_t argf;
|
|
jit_int32_t size;
|
|
jit_int32_t call;
|
|
} call;
|
|
jit_node_t *prolog;
|
|
jit_node_t *epilog;
|
|
jit_int32_t *regoff;
|
|
jit_regset_t regset;
|
|
jit_int32_t stack;
|
|
};
|
|
|
|
/* data used only during jit generation */
|
|
struct jit_compiler {
|
|
#if __ia64__
|
|
struct {
|
|
jit_uint64_t i : 41;
|
|
jit_uint64_t t : 4;
|
|
} inst[3];
|
|
jit_regset_t regs; /* changed regs since last stop */
|
|
jit_int32_t pred; /* changed preds last stop */
|
|
jit_int32_t ioff; /* offset in inst vector */
|
|
jit_int32_t rout; /* first output register */
|
|
jit_int32_t breg; /* base register for prolog/epilog */
|
|
#endif
|
|
#if __mips__ || __ia64__
|
|
jit_int32_t carry;
|
|
#define jit_carry _jitc->carry
|
|
#endif
|
|
jit_node_t *head;
|
|
jit_node_t *tail;
|
|
jit_uint32_t realize : 1; /* jit_realize() called? */
|
|
jit_uint32_t done : 1; /* emit state finished */
|
|
jit_uint32_t emit : 1; /* emit state entered */
|
|
jit_uint32_t again : 1; /* start over emiting function */
|
|
jit_uint32_t prepare : 1; /* inside prepare/finish* block */
|
|
#if DEBUG
|
|
jit_uint32_t getreg : 1;
|
|
#endif
|
|
jit_int32_t reglen; /* number of registers */
|
|
jit_regset_t regarg; /* cannot allocate */
|
|
jit_regset_t regsav; /* automatic spill only once */
|
|
jit_regset_t reglive; /* known live registers at some point */
|
|
jit_regset_t regmask; /* register mask to update reglive */
|
|
struct {
|
|
jit_word_t *ptr;
|
|
jit_word_t length;
|
|
} blockmask; /* mask of visited basic blocks */
|
|
struct {
|
|
jit_uint8_t *end;
|
|
} code;
|
|
struct {
|
|
jit_node_t **table; /* very simple hash table */
|
|
jit_word_t size; /* number of vectors in table */
|
|
jit_word_t count; /* number of hash table entries */
|
|
jit_word_t offset; /* offset in bytes in ptr */
|
|
} data;
|
|
jit_node_t **spill;
|
|
jit_int32_t *gen; /* ssa like "register version" */
|
|
jit_value_t *values; /* temporary jit_value_t vector */
|
|
struct {
|
|
jit_block_t *ptr;
|
|
jit_word_t offset;
|
|
jit_word_t length;
|
|
} blocks; /* basic blocks */
|
|
struct {
|
|
jit_patch_t *ptr;
|
|
jit_word_t offset;
|
|
jit_word_t length;
|
|
} patches; /* forward patch information */
|
|
jit_function_t *function; /* current function */
|
|
struct {
|
|
jit_function_t *ptr;
|
|
jit_word_t offset;
|
|
jit_word_t length;
|
|
} functions; /* prolog/epilogue offsets in code */
|
|
struct {
|
|
jit_node_t **ptr;
|
|
jit_word_t offset;
|
|
jit_word_t length;
|
|
} pool;
|
|
jit_node_t *list;
|
|
struct {
|
|
jit_node_t *head; /* first note node */
|
|
jit_node_t *tail; /* linked list insertion */
|
|
/* fields to store temporary state information */
|
|
jit_word_t size;
|
|
jit_node_t *name;
|
|
jit_node_t *note;
|
|
jit_uint8_t *base;
|
|
} note;
|
|
#if __arm__
|
|
/* prevent using thumb instructions that set flags? */
|
|
jit_uint32_t no_set_flags : 1;
|
|
# if DISASSEMBLER
|
|
struct {
|
|
jit_data_info_t *ptr;
|
|
jit_word_t offset;
|
|
jit_word_t length;
|
|
} data_info; /* constant pools information */
|
|
# endif
|
|
/* Note that this field is somewhat hackish, but required by most
|
|
* ways to implement jit, unless implementing a pure one function
|
|
* per jit, as most times it needs to start the jit buffer with a
|
|
* jump where the "main" prolog starts, and because the initial
|
|
* code is in "arm mode", need to make an "arm mode" patch on that
|
|
* jump. A good example is the test suite assembler, where most
|
|
* test cases start with a "jmpi main" call. */
|
|
jit_uword_t thumb;
|
|
struct {
|
|
jit_uint8_t *data; /* pointer to code */
|
|
jit_word_t size; /* size data */
|
|
jit_word_t offset; /* pending patches */
|
|
jit_word_t length; /* number of pending constants */
|
|
jit_int32_t values[1024]; /* pending constants */
|
|
jit_word_t patches[2048];
|
|
} consts;
|
|
#elif __powerpc__ || __ia64__
|
|
/* Keep track of prolog addresses, just for the sake of making
|
|
* jit that starts with a jump to a "main" label work like other
|
|
* backends. */
|
|
struct {
|
|
jit_word_t *ptr;
|
|
jit_word_t offset;
|
|
jit_word_t length;
|
|
} prolog;
|
|
jit_bool_t jump;
|
|
#endif
|
|
#if GET_JIT_SIZE
|
|
/* Temporary storage to calculate instructions length */
|
|
jit_word_t size;
|
|
/* Global flag for code buffer heuristic size computation */
|
|
jit_word_t mult;
|
|
/* Pointer to code to prevent miscalculation if reallocating buffer */
|
|
jit_uint8_t *cptr;
|
|
#endif
|
|
};
|
|
|
|
#define _jitc _jit->comp
|
|
struct jit_state {
|
|
union {
|
|
jit_uint8_t *uc;
|
|
jit_uint16_t *us;
|
|
jit_uint32_t *ui;
|
|
jit_uint64_t *ul;
|
|
jit_word_t w;
|
|
} pc;
|
|
struct {
|
|
jit_uint8_t *ptr;
|
|
jit_word_t length;
|
|
} code;
|
|
struct {
|
|
jit_uint8_t *ptr;
|
|
jit_word_t length;
|
|
} data;
|
|
struct {
|
|
jit_note_t *ptr;
|
|
jit_word_t length;
|
|
} note;
|
|
jit_compiler_t *comp;
|
|
/* Flags to know if user did set the code and data buffers */
|
|
jit_uint32_t user_code : 1;
|
|
};
|
|
|
|
struct jit_register {
|
|
jit_reg_t spec;
|
|
char *name;
|
|
};
|
|
|
|
/*
|
|
* Prototypes
|
|
*/
|
|
extern void jit_get_cpu(void);
|
|
|
|
#define jit_init() _jit_init(_jit)
|
|
extern void _jit_init(jit_state_t*);
|
|
|
|
#define jit_new_node_no_link(u) _jit_new_node_no_link(_jit, u)
|
|
extern jit_node_t *_jit_new_node_no_link(jit_state_t*, jit_code_t);
|
|
|
|
#define jit_link_node(u) _jit_link_node(_jit, u)
|
|
extern void _jit_link_node(jit_state_t*, jit_node_t*);
|
|
|
|
#define jit_link_label(l) _jit_link_label(_jit,l)
|
|
extern void
|
|
_jit_link_label(jit_state_t*,jit_node_t*);
|
|
|
|
#define jit_reglive(node) _jit_reglive(_jit, node)
|
|
extern void
|
|
_jit_reglive(jit_state_t*, jit_node_t*);
|
|
|
|
#define jit_regarg_set(n,v) _jit_regarg_set(_jit,n,v)
|
|
extern void
|
|
_jit_regarg_set(jit_state_t*, jit_node_t*, jit_int32_t);
|
|
|
|
#define jit_regarg_clr(n,v) _jit_regarg_clr(_jit,n,v)
|
|
extern void
|
|
_jit_regarg_clr(jit_state_t*, jit_node_t*, jit_int32_t);
|
|
|
|
#define jit_get_reg(s) _jit_get_reg(_jit,s)
|
|
extern jit_int32_t
|
|
_jit_get_reg(jit_state_t*, jit_int32_t);
|
|
|
|
#define jit_unget_reg(r) _jit_unget_reg(_jit,r)
|
|
extern void
|
|
_jit_unget_reg(jit_state_t*, jit_int32_t);
|
|
|
|
#define jit_save(reg) _jit_save(_jit, reg)
|
|
extern void
|
|
_jit_save(jit_state_t*, jit_int32_t);
|
|
|
|
#define jit_load(reg) _jit_load(_jit, reg)
|
|
extern void
|
|
_jit_load(jit_state_t*, jit_int32_t);
|
|
|
|
#define jit_optimize() _jit_optimize(_jit)
|
|
extern void
|
|
_jit_optimize(jit_state_t*);
|
|
|
|
#define jit_classify(code) _jit_classify(_jit, code)
|
|
extern jit_int32_t
|
|
_jit_classify(jit_state_t*, jit_code_t);
|
|
|
|
#define jit_regarg_p(n, r) _jit_regarg_p(_jit, n, r)
|
|
extern jit_bool_t
|
|
_jit_regarg_p(jit_state_t*, jit_node_t*, jit_int32_t);
|
|
|
|
#define emit_code() _emit_code(_jit)
|
|
extern jit_pointer_t
|
|
_emit_code(jit_state_t*);
|
|
|
|
#define emit_ldxi(r0, r1, i0) _emit_ldxi(_jit, r0, r1, i0)
|
|
extern void
|
|
_emit_ldxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
|
|
#define emit_stxi(i0, r0, r1) _emit_stxi(_jit, i0, r0, r1)
|
|
extern void
|
|
_emit_stxi(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
|
|
|
|
#define emit_ldxi_d(r0, r1, i0) _emit_ldxi_d(_jit, r0, r1, i0)
|
|
extern void
|
|
_emit_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
|
|
#define emit_stxi_d(i0, r0, r1) _emit_stxi_d(_jit, i0, r0, r1)
|
|
extern void
|
|
_emit_stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
|
|
|
|
extern void jit_init_debug(void);
|
|
extern void jit_finish_debug(void);
|
|
|
|
extern void jit_init_note(void);
|
|
extern void jit_finish_note(void);
|
|
#define jit_set_note(n,u,v,w) _jit_set_note(_jit, n, u, v, w)
|
|
extern void _jit_set_note(jit_state_t*, jit_note_t*, char*, int, jit_int32_t);
|
|
#define jit_annotate() _jit_annotate(_jit)
|
|
extern void _jit_annotate(jit_state_t*);
|
|
|
|
extern void jit_alloc(jit_pointer_t*, jit_word_t);
|
|
extern void jit_realloc(jit_pointer_t*, jit_word_t, jit_word_t);
|
|
void jit_free(jit_pointer_t*);
|
|
|
|
extern void jit_init_size(void);
|
|
extern void jit_finish_size(void);
|
|
|
|
#if GET_JIT_SIZE
|
|
# define jit_size_prepare() _jit_size_prepare(_jit)
|
|
extern void
|
|
_jit_size_prepare(jit_state_t*);
|
|
|
|
# define jit_size_collect(node) _jit_size_collect(_jit, node)
|
|
extern void
|
|
_jit_size_collect(jit_state_t*, jit_node_t*);
|
|
#else
|
|
# define jit_get_size() _jit_get_size(_jit)
|
|
extern jit_word_t
|
|
_jit_get_size(jit_state_t*);
|
|
#endif
|
|
|
|
extern jit_word_t
|
|
jit_get_max_instr(void);
|
|
|
|
/*
|
|
* Externs
|
|
*/
|
|
extern jit_register_t _rvs[];
|
|
extern const char *jit_progname;
|
|
|
|
#endif /* _jit_private_h */
|