mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-03 21:30:29 +02:00
Implementation of new design
Documentation to come, as tests get added and things settle down.
This commit is contained in:
parent
0d81c5c337
commit
bad7e34c83
18 changed files with 4333 additions and 7149 deletions
73
jit.h
73
jit.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU lightning.
|
||||
*
|
||||
|
@ -45,7 +45,23 @@ typedef void* jit_addr_t;
|
|||
typedef ptrdiff_t jit_off_t;
|
||||
typedef intptr_t jit_imm_t;
|
||||
typedef uintptr_t jit_uimm_t;
|
||||
typedef struct jit_reloc *jit_reloc_t;
|
||||
|
||||
enum jit_reloc_kind
|
||||
{
|
||||
JIT_RELOC_ABSOLUTE,
|
||||
JIT_RELOC_REL8,
|
||||
JIT_RELOC_REL16,
|
||||
JIT_RELOC_REL32,
|
||||
JIT_RELOC_REL64,
|
||||
};
|
||||
|
||||
typedef struct jit_reloc
|
||||
{
|
||||
uint8_t kind;
|
||||
uint8_t inst_start_offset;
|
||||
uint16_t flags;
|
||||
uint32_t offset;
|
||||
} jit_reloc_t;
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
# define JIT_API extern __attribute__ ((__visibility__("hidden")))
|
||||
|
@ -91,17 +107,32 @@ typedef struct jit_reloc *jit_reloc_t;
|
|||
#define jit_regno(reg) ((reg) & 0x00007fff)
|
||||
|
||||
typedef struct jit_state jit_state_t;
|
||||
enum jit_arg_kind
|
||||
enum jit_arg_loc
|
||||
{
|
||||
JIT_CALL_ARG_IMM,
|
||||
JIT_CALL_ARG_GPR,
|
||||
JIT_CALL_ARG_FPR,
|
||||
JIT_CALL_ARG_MEM
|
||||
JIT_ARG_LOC_IMM,
|
||||
JIT_ARG_LOC_GPR,
|
||||
JIT_ARG_LOC_FPR,
|
||||
JIT_ARG_LOC_MEM
|
||||
};
|
||||
|
||||
typedef enum jit_arg_abi
|
||||
{
|
||||
JIT_ARG_ABI_UINT8,
|
||||
JIT_ARG_ABI_INT8,
|
||||
JIT_ARG_ABI_UINT16,
|
||||
JIT_ARG_ABI_INT16,
|
||||
JIT_ARG_ABI_UINT32,
|
||||
JIT_ARG_ABI_INT32,
|
||||
JIT_ARG_ABI_UINT64,
|
||||
JIT_ARG_ABI_INT64,
|
||||
JIT_ARG_ABI_POINTER,
|
||||
JIT_ARG_ABI_FLOAT,
|
||||
JIT_ARG_ABI_DOUBLE
|
||||
} jit_arg_abi_t;
|
||||
|
||||
typedef struct jit_arg
|
||||
{
|
||||
enum jit_arg_kind kind;
|
||||
enum jit_arg_loc kind;
|
||||
union
|
||||
{
|
||||
intptr_t imm;
|
||||
|
@ -111,28 +142,30 @@ typedef struct jit_arg
|
|||
} loc;
|
||||
} jit_arg_t;
|
||||
|
||||
JIT_API void init_jit(void);
|
||||
JIT_API jit_bool_t init_jit(void);
|
||||
|
||||
JIT_API jit_state_t *jit_new_state(void);
|
||||
JIT_API void jit_destroy_state(jit_state_t*);
|
||||
|
||||
JIT_API void jit_begin(jit_state_t*, jit_addr_t, size_t);
|
||||
JIT_API void jit_begin(jit_state_t*, uint8_t*, size_t);
|
||||
JIT_API jit_bool_t jit_has_overflow(jit_state_t*);
|
||||
JIT_API void jit_reset(jit_state_t*);
|
||||
JIT_API jit_addr_t jit_end(jit_state_t*, size_t*);
|
||||
JIT_API void* jit_end(jit_state_t*, size_t*);
|
||||
|
||||
JIT_API void jit_align(jit_state_t*, unsigned);
|
||||
JIT_API void jit_allocai(jit_state_t*, size_t);
|
||||
JIT_API void jit_allocar(jit_state_t*, jit_gpr_t, jit_gpr_t);
|
||||
|
||||
JIT_API jit_pointer_t jit_address(jit_state_t*);
|
||||
JIT_API void jit_patch_here(jit_state_t*, jit_reloc_t);
|
||||
JIT_API void jit_patch_there(jit_state_t*, jit_reloc_t, jit_pointer_t);
|
||||
|
||||
JIT_API void jit_calli(jit_state_t *, jit_pointer_t f,
|
||||
size_t argc, const jit_arg_t *argv);
|
||||
size_t argc, const jit_arg_abi_t abi[],
|
||||
const jit_arg_t args[]);
|
||||
JIT_API void jit_callr(jit_state_t *, jit_gpr_t f,
|
||||
size_t argc, const jit_arg_t *argv);
|
||||
JIT_API void jit_receive(jit_state_t*, size_t argc, jit_arg_t *argv);
|
||||
size_t argc, const jit_arg_abi_t abi[],
|
||||
const jit_arg_t args[]);
|
||||
JIT_API void jit_receive(jit_state_t*, size_t argc,
|
||||
const jit_arg_abi_t abi[], jit_arg_t args[]);
|
||||
|
||||
#define JIT_PROTO_0(stem, ret) \
|
||||
ret jit_##stem (jit_state_t* _jit)
|
||||
|
@ -164,8 +197,8 @@ JIT_API void jit_receive(jit_state_t*, size_t argc, jit_arg_t *argv);
|
|||
#define JIT_PROTO__GGF_(stem) JIT_PROTO_3(stem, void, gpr, gpr, fpr)
|
||||
#define JIT_PROTO__GGGG(stem) JIT_PROTO_4(stem, void, gpr, gpr, gpr, gpr)
|
||||
#define JIT_PROTO__GGG_(stem) JIT_PROTO_3(stem, void, gpr, gpr, gpr)
|
||||
#define JIT_PROTO__GGGi(stem) JIT_PROTO_3(stem, void, gpr, gpr, imm)
|
||||
#define JIT_PROTO__GGGu(stem) JIT_PROTO_3(stem, void, gpr, gpr, uimm)
|
||||
#define JIT_PROTO__GGGi(stem) JIT_PROTO_4(stem, void, gpr, gpr, gpr, imm)
|
||||
#define JIT_PROTO__GGGu(stem) JIT_PROTO_4(stem, void, gpr, gpr, gpr, uimm)
|
||||
#define JIT_PROTO__GG__(stem) JIT_PROTO_2(stem, void, gpr, gpr)
|
||||
#define JIT_PROTO__GGi_(stem) JIT_PROTO_3(stem, void, gpr, gpr, imm)
|
||||
#define JIT_PROTO__GGo_(stem) JIT_PROTO_3(stem, void, gpr, gpr, off)
|
||||
|
@ -192,7 +225,7 @@ JIT_API void jit_receive(jit_state_t*, size_t argc, jit_arg_t *argv);
|
|||
M(_GGi_, addxi) \
|
||||
M(_GGG_, subr) \
|
||||
M(_FFF_, subr_f) \
|
||||
M(_FFF_, subr_f) \
|
||||
M(_FFF_, subr_d) \
|
||||
M(_GGi_, subi) \
|
||||
M(_GGG_, subcr) \
|
||||
M(_GGi_, subci) \
|
||||
|
@ -388,6 +421,8 @@ JIT_API void jit_receive(jit_state_t*, size_t argc, jit_arg_t *argv);
|
|||
M(RGG__, bxsubr_u) \
|
||||
M(RGu__, bxsubi_u) \
|
||||
\
|
||||
M(_i___, nop) \
|
||||
\
|
||||
M(_G___, jmpr) \
|
||||
M(_p___, jmpi) \
|
||||
M(R____, jmp) \
|
||||
|
|
|
@ -658,15 +658,15 @@ static void _stxi_i(jit_state_t*,jit_word_t,int32_t,int32_t);
|
|||
# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1)
|
||||
static void _stxi_l(jit_state_t*,jit_word_t,int32_t,int32_t);
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
|
||||
static void _htonr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
|
||||
static void _htonr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# define htonr_ul(r0,r1) REV(r0,r1)
|
||||
# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
|
||||
static void _bswapr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
|
||||
static void _bswapr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ul(r0,r1) REV(r0,r1)
|
||||
# else
|
||||
# define htonr_us(r0,r1) extr_us(r0,r1)
|
||||
# define htonr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define htonr_ul(r0,r1) movr(r0,r1)
|
||||
# define bswapr_us(r0,r1) extr_us(r0,r1)
|
||||
# define bswapr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define bswapr_ul(r0,r1) movr(r0,r1)
|
||||
# endif
|
||||
# define extr_c(r0,r1) SXTB(r0,r1)
|
||||
# define extr_uc(r0,r1) UXTB(r0,r1)
|
||||
|
@ -1443,16 +1443,16 @@ _xori(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static void
|
||||
_htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
htonr_ul(r0, r1);
|
||||
bswapr_ul(r0, r1);
|
||||
rshi_u(r0, r0, 48);
|
||||
}
|
||||
|
||||
static void
|
||||
_htonr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
htonr_ul(r0, r1);
|
||||
bswapr, 2019_ul(r0, r1);
|
||||
rshi_u(r0, r0, 32);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2014, 2017 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2014, 2017, 2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU lightning.
|
||||
*
|
||||
|
@ -623,16 +623,16 @@ static void _extr_i(jit_state_t*,int32_t,int32_t);
|
|||
# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1)
|
||||
static void _extr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
|
||||
static void _htonr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
|
||||
static void _htonr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# define htonr_ul(r0,r1) _htonr_ul(_jit,r0,r1)
|
||||
static void _htonr_ul(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
|
||||
static void _bswapr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
|
||||
static void _bswapr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ul(r0,r1) _bswapr_ul(_jit,r0,r1)
|
||||
static void _bswapr_ul(jit_state_t*,int32_t,int32_t);
|
||||
# else
|
||||
# define htonr_us(r0,r1) extr_us(r0,r1)
|
||||
# define htonr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define htonr_ul(r0,r1) movr(r0,r1)
|
||||
# define bswapr_us(r0,r1) extr_us(r0,r1)
|
||||
# define bswapr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define bswapr_ul(r0,r1) movr(r0,r1)
|
||||
# endif
|
||||
# define jmpr(r0) JMP(_R31_REGNO,r0,0)
|
||||
# define jmpi(i0) _jmpi(_jit,i0)
|
||||
|
@ -2453,7 +2453,7 @@ _extr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|||
}
|
||||
|
||||
static void
|
||||
_htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t t0;
|
||||
t0 = jit_get_reg(jit_class_gpr);
|
||||
|
@ -2465,7 +2465,7 @@ _htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|||
}
|
||||
|
||||
static void
|
||||
_htonr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t t0;
|
||||
int32_t t1;
|
||||
|
@ -2491,7 +2491,7 @@ _htonr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|||
}
|
||||
|
||||
static void
|
||||
_htonr_ul(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_ul(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t t0;
|
||||
int32_t t1;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2017 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2012-2017, 2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU lightning.
|
||||
*
|
||||
|
@ -1092,13 +1092,13 @@ static void _stxr_i(jit_state_t*,jit_word_t,int32_t,int32_t);
|
|||
# define stxi_i(r0,r1,i0) _stxi_i(_jit,r0,r1,i0)
|
||||
static void _stxi_i(jit_state_t*,jit_word_t,int32_t,int32_t);
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
|
||||
static void _htonr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
|
||||
static void _htonr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
|
||||
static void _bswapr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
|
||||
static void _bswapr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# else
|
||||
# define htonr_us(r0,r1) extr_us(r0,r1)
|
||||
# define htonr(r0,r1) movr(r0,r1)
|
||||
# define bswapr_us(r0,r1) extr_us(r0,r1)
|
||||
# define bswapr(r0,r1) movr(r0,r1)
|
||||
# endif
|
||||
# define extr_c(r0,r1) _extr_c(_jit,r0,r1)
|
||||
static void _extr_c(jit_state_t*,int32_t,int32_t);
|
||||
|
@ -3578,7 +3578,7 @@ _stxi_i(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
|
|||
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static void
|
||||
_htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t t0;
|
||||
if (jit_thumb_p()) {
|
||||
|
@ -3607,7 +3607,7 @@ _htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|||
|
||||
/* inline glibc htonl (without register clobber) */
|
||||
static void
|
||||
_htonr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t reg;
|
||||
if (jit_thumb_p()) {
|
||||
|
|
|
@ -655,10 +655,10 @@ static jit_word_t _movi_p(jit_state_t*,int32_t,jit_word_t);
|
|||
#define extr_s(r0,r1) EXTRWR(r1,31,16,r0)
|
||||
#define extr_us(r0,r1) EXTRWR_U(r1,31,16,r0)
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define htonr_us(r0,r1) extr_us(r0,r1)
|
||||
# define htonr_ui(r0,r1) movr(r0,r1)
|
||||
# define bswapr_us(r0,r1) extr_us(r0,r1)
|
||||
# define bswapr_ui(r0,r1) movr(r0,r1)
|
||||
#else
|
||||
# error need htonr implementation
|
||||
# error need bswapr implementation
|
||||
#endif
|
||||
#define addr(r0,r1,r2) ADD(r1,r2,r0)
|
||||
#define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2013-2017, 2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU lightning.
|
||||
*
|
||||
|
@ -1308,15 +1308,15 @@ static void _movi(jit_state_t*,int32_t,jit_word_t);
|
|||
#define movi_p(r0,i0) _movi_p(_jit,r0,i0)
|
||||
static jit_word_t _movi_p(jit_state_t*,int32_t,jit_word_t);
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
|
||||
static void _htonr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
|
||||
static void _htonr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# define htonr_ul(r0,r1) MUX1(r0,r1,MUX_REV)
|
||||
# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
|
||||
static void _bswapr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
|
||||
static void _bswapr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ul(r0,r1) MUX1(r0,r1,MUX_REV)
|
||||
#else
|
||||
# define htonr_us(r0,r1) extr_us(r0,r1)
|
||||
# define htonr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define htonr_ul(r0,r1) movr(r0,r1)
|
||||
# define bswapr_us(r0,r1) extr_us(r0,r1)
|
||||
# define bswapr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define bswapr_ul(r0,r1) movr(r0,r1)
|
||||
#endif
|
||||
#define extr_c(r0,r1) SXT1(r0,r1)
|
||||
#define extr_uc(r0,r1) ZXT1(r0,r1)
|
||||
|
@ -3951,7 +3951,7 @@ _xori(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static void
|
||||
_htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t t0;
|
||||
t0 = jit_get_reg(jit_class_gpr);
|
||||
|
@ -3964,7 +3964,7 @@ _htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|||
}
|
||||
|
||||
static void
|
||||
_htonr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t t0;
|
||||
int32_t t1;
|
||||
|
|
491
jit/jit.c
491
jit/jit.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU lightning.
|
||||
*
|
||||
|
@ -14,7 +14,7 @@
|
|||
* License for more details.
|
||||
*
|
||||
* Authors:
|
||||
* Paulo Cesar Pereira de Andrade
|
||||
* Paulo Cesar Pereira de Andrade
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
|
@ -30,107 +30,118 @@
|
|||
#include "../jit.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define maybe_unused __attribute__ ((unused))
|
||||
# define maybe_unused __attribute__ ((unused))
|
||||
#else
|
||||
# define maybe_unused /**/
|
||||
# define maybe_unused /**/
|
||||
#endif
|
||||
|
||||
#define rc(value) jit_class_##value
|
||||
#define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec))
|
||||
#define rc(value) jit_class_##value
|
||||
#define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec))
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
# define JIT_SP _RSP
|
||||
# define JIT_RET _RAX
|
||||
# if __X32
|
||||
# define JIT_FRET _ST0
|
||||
# define JIT_SP _RSP
|
||||
# define JIT_RET _RAX
|
||||
# if __X32
|
||||
# define JIT_FRET _ST0
|
||||
# else
|
||||
# if __CYGWIN__
|
||||
# define JIT_RA0 _RCX
|
||||
# else
|
||||
# if __CYGWIN__
|
||||
# define JIT_RA0 _RCX
|
||||
# else
|
||||
# define JIT_RA0 _RDI
|
||||
# endif
|
||||
# define JIT_FA0 _XMM0
|
||||
# define JIT_FRET _XMM0
|
||||
# define JIT_RA0 _RDI
|
||||
# endif
|
||||
# define JIT_FA0 _XMM0
|
||||
# define JIT_FRET _XMM0
|
||||
# endif
|
||||
#elif defined(__mips__)
|
||||
# define JIT_RA0 _A0
|
||||
# define JIT_FA0 _F12
|
||||
# define JIT_SP _SP
|
||||
# define JIT_RET _V0
|
||||
# define JIT_FRET _F0
|
||||
# define JIT_RA0 _A0
|
||||
# define JIT_FA0 _F12
|
||||
# define JIT_SP _SP
|
||||
# define JIT_RET _V0
|
||||
# define JIT_FRET _F0
|
||||
#elif defined(__arm__)
|
||||
# define JIT_RA0 _R0
|
||||
# define JIT_FA0 _D0
|
||||
# define JIT_SP _R13
|
||||
# define JIT_RET _R0
|
||||
# if defined(__ARM_PCS_VFP)
|
||||
# define JIT_FRET _D0
|
||||
# else
|
||||
# define JIT_FRET _R0
|
||||
# endif
|
||||
# define JIT_RA0 _R0
|
||||
# define JIT_FA0 _D0
|
||||
# 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_RA0 _R3
|
||||
# define JIT_FA0 _F1
|
||||
# define JIT_SP _R1
|
||||
# define JIT_RET _R3
|
||||
# define JIT_FRET _F1
|
||||
# define JIT_RA0 _R3
|
||||
# define JIT_FA0 _F1
|
||||
# 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
|
||||
# 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
|
||||
# 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
|
||||
# define JIT_SP _R30
|
||||
# define JIT_RET _R28
|
||||
# define JIT_FRET _F4
|
||||
#elif defined(__aarch64__)
|
||||
# define JIT_RA0 _R0
|
||||
# define JIT_FA0 _V0
|
||||
# define JIT_SP _SP
|
||||
# define JIT_RET _R0
|
||||
# define JIT_FRET _V0
|
||||
# define JIT_RA0 _R0
|
||||
# define JIT_FA0 _V0
|
||||
# define JIT_SP _SP
|
||||
# define JIT_RET _R0
|
||||
# define JIT_FRET _V0
|
||||
#elif defined(__s390__) || defined(__s390x__)
|
||||
# define JIT_SP _R15
|
||||
# define JIT_RET _R2
|
||||
# define JIT_FRET _F0
|
||||
# define JIT_SP _R15
|
||||
# define JIT_RET _R2
|
||||
# define JIT_FRET _F0
|
||||
#elif defined(__alpha__)
|
||||
# define JIT_SP _SP
|
||||
# define JIT_RET _V0
|
||||
# define JIT_FRET _F0
|
||||
# define JIT_SP _SP
|
||||
# define JIT_RET _V0
|
||||
# define JIT_FRET _F0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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_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 */
|
||||
/* Used on sparc64 where %f0-%f31 can be encode for single float
|
||||
* but %f32 to %f62 only as double precision */
|
||||
#define jit_class_sng 0x10000000 /* Single precision float */
|
||||
#define jit_class_dbl 0x20000000 /* Only double precision float */
|
||||
#define jit_regno_patch 0x00008000 /* this is a register
|
||||
* returned by a "user" call
|
||||
* to jit_get_reg() */
|
||||
#define jit_class_sng 0x10000000 /* Single precision float */
|
||||
#define jit_class_dbl 0x20000000 /* Only double precision float */
|
||||
#define jit_regno_patch 0x00008000 /* this is a register
|
||||
* returned by a "user" call
|
||||
* to jit_get_reg() */
|
||||
|
||||
union jit_pc
|
||||
{
|
||||
uint8_t *uc;
|
||||
uint16_t *us;
|
||||
uint32_t *ui;
|
||||
uint64_t *ul;
|
||||
intptr_t w;
|
||||
uintptr_t uw;
|
||||
};
|
||||
|
||||
struct jit_state
|
||||
{
|
||||
union {
|
||||
uint8_t *uc;
|
||||
uint16_t *us;
|
||||
uint32_t *ui;
|
||||
uint64_t *ul;
|
||||
intptr_t w;
|
||||
uintptr_t uw;
|
||||
} pc;
|
||||
union jit_pc pc;
|
||||
uint8_t *start;
|
||||
uint8_t *last_instruction_start;
|
||||
uint8_t *limit;
|
||||
uint8_t temp_gpr_saved;
|
||||
uint8_t temp_fpr_saved;
|
||||
uint8_t overflow;
|
||||
};
|
||||
|
||||
enum jit_reloc_flags
|
||||
{
|
||||
JIT_RELOC_CAN_SHORTEN = 1<<0
|
||||
};
|
||||
|
||||
struct jit_register
|
||||
|
@ -143,45 +154,40 @@ typedef struct jit_register jit_register_t;
|
|||
|
||||
static const jit_register_t _rvs[];
|
||||
|
||||
#define jit_regload_reload 0 /* convert to reload */
|
||||
#define jit_regload_delete 1 /* just remove node */
|
||||
#define jit_regload_isdead 2 /* delete and unset live bit */
|
||||
#define jit_regload_reload 0 /* convert to reload */
|
||||
#define jit_regload_delete 1 /* just remove node */
|
||||
#define jit_regload_isdead 2 /* delete and unset live bit */
|
||||
|
||||
#define ASSERT(x) do { if (!(x)) abort(); } while (0)
|
||||
#if defined(__GNUC__)
|
||||
# define UNLIKELY(exprn) __builtin_expect(exprn, 0)
|
||||
#else
|
||||
# define UNLIKELY(exprn) exprn
|
||||
#endif
|
||||
|
||||
static inline uint8_t*
|
||||
jit_reloc_instruction (jit_reloc_t reloc)
|
||||
{
|
||||
return (uint8_t*) reloc;
|
||||
}
|
||||
|
||||
static void jit_get_cpu(void);
|
||||
static void jit_init(jit_state_t *);
|
||||
static void jit_nop(jit_state_t *, unsigned);
|
||||
static void jit_patch(jit_state_t *, const uint8_t *loc, const uint8_t *addr);
|
||||
static void jit_patch_last(jit_state_t *, const uint8_t *loc, const uint8_t *addr);
|
||||
static jit_bool_t jit_get_cpu(void);
|
||||
static jit_bool_t jit_init(jit_state_t *);
|
||||
static void jit_flush(void *fptr, void *tptr);
|
||||
static void jit_try_shorten(jit_state_t *_jit, jit_reloc_t reloc);
|
||||
|
||||
void
|
||||
jit_bool_t
|
||||
init_jit(void)
|
||||
{
|
||||
jit_get_cpu();
|
||||
return jit_get_cpu ();
|
||||
}
|
||||
|
||||
jit_state_t *
|
||||
jit_new_state(void)
|
||||
{
|
||||
jit_state_t *_jit;
|
||||
jit_state_t *_jit = malloc (sizeof (*_jit));
|
||||
if (!_jit)
|
||||
abort ();
|
||||
|
||||
_jit = malloc (sizeof (*_jit));
|
||||
if (!_jit)
|
||||
abort ();
|
||||
memset(_jit, 0, sizeof (*_jit));
|
||||
|
||||
memset(_jit, 0, sizeof (*_jit));
|
||||
if (!jit_init (_jit));
|
||||
|
||||
jit_init (_jit);
|
||||
|
||||
return _jit;
|
||||
return _jit;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -193,36 +199,44 @@ jit_destroy_state(jit_state_t *_jit)
|
|||
jit_pointer_t
|
||||
jit_address(jit_state_t *_jit)
|
||||
{
|
||||
/* TODO: FIXME */
|
||||
abort ();
|
||||
return _jit->pc.uc;
|
||||
}
|
||||
|
||||
void
|
||||
jit_begin(jit_state_t *_jit, jit_addr_t addr, size_t length)
|
||||
jit_begin(jit_state_t *_jit, uint8_t* buf, size_t length)
|
||||
{
|
||||
ASSERT (!_jit->start);
|
||||
|
||||
_jit->start = addr;
|
||||
_jit->limit = _jit->start + length;
|
||||
_jit->start = buf;
|
||||
_jit->limit = buf + length;
|
||||
jit_reset(_jit);
|
||||
}
|
||||
|
||||
jit_bool_t
|
||||
jit_has_overflow(jit_state_t *_jit)
|
||||
{
|
||||
ASSERT (_jit->start);
|
||||
return _jit->overflow;
|
||||
}
|
||||
|
||||
void
|
||||
jit_reset(jit_state_t *_jit)
|
||||
{
|
||||
ASSERT (_jit->start);
|
||||
_jit->pc.uc = _jit->start = _jit->limit = NULL;
|
||||
_jit->pc.uc = _jit->start;
|
||||
_jit->overflow = 0;
|
||||
}
|
||||
|
||||
jit_addr_t
|
||||
void*
|
||||
jit_end(jit_state_t *_jit, size_t *length)
|
||||
{
|
||||
uint8_t *code = _jit->start;
|
||||
uint8_t *end = _jit->pc.uc;
|
||||
|
||||
ASSERT (code);
|
||||
ASSERT (end > code);
|
||||
ASSERT (code <= end);
|
||||
ASSERT (end <= _jit->limit);
|
||||
ASSERT (!_jit->overflow);
|
||||
|
||||
jit_flush (code, end);
|
||||
|
||||
|
@ -230,7 +244,8 @@ jit_end(jit_state_t *_jit, size_t *length)
|
|||
*length = end - code;
|
||||
}
|
||||
|
||||
jit_reset (_jit);
|
||||
_jit->pc.uc = _jit->start = _jit->limit = NULL;
|
||||
_jit->overflow = 0;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -251,6 +266,79 @@ jit_align(jit_state_t *_jit, unsigned align)
|
|||
jit_nop(_jit, there - here);
|
||||
}
|
||||
|
||||
static inline void emit_u8(jit_state_t *_jit, uint8_t u8) {
|
||||
if (UNLIKELY(_jit->pc.uc + 1 > _jit->limit)) {
|
||||
_jit->overflow = 1;
|
||||
} else {
|
||||
*_jit->pc.uc++ = u8;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void emit_u16(jit_state_t *_jit, uint16_t u16) {
|
||||
if (UNLIKELY(_jit->pc.us + 1 > (uint16_t*)_jit->limit)) {
|
||||
_jit->overflow = 1;
|
||||
} else {
|
||||
*_jit->pc.us++ = u16;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void emit_u32(jit_state_t *_jit, uint32_t u32) {
|
||||
if (UNLIKELY(_jit->pc.ui + 1 > (uint32_t*)_jit->limit)) {
|
||||
_jit->overflow = 1;
|
||||
} else {
|
||||
*_jit->pc.ui++ = u32;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void emit_u64(jit_state_t *_jit, uint64_t u64) {
|
||||
if (UNLIKELY(_jit->pc.ul + 1 > (uint64_t*)_jit->limit)) {
|
||||
_jit->overflow = 1;
|
||||
} else {
|
||||
*_jit->pc.ul++ = u64;
|
||||
}
|
||||
}
|
||||
|
||||
static inline jit_reloc_t
|
||||
jit_reloc (jit_state_t *_jit, enum jit_reloc_kind kind,
|
||||
uint8_t inst_start_offset, uint16_t flags, intptr_t addend)
|
||||
{
|
||||
jit_reloc_t ret;
|
||||
|
||||
ret.kind = kind;
|
||||
ret.inst_start_offset = inst_start_offset;
|
||||
ret.flags = 0;
|
||||
ret.offset = _jit->pc.uc - _jit->start;
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case JIT_RELOC_ABSOLUTE:
|
||||
if (sizeof(intptr_t) == 4)
|
||||
emit_u32 (_jit, addend);
|
||||
else
|
||||
emit_u64 (_jit, addend);
|
||||
break;
|
||||
case JIT_RELOC_REL8:
|
||||
ASSERT (INT8_MIN <= addend && addend <= INT8_MAX);
|
||||
emit_u8 (_jit, addend - 1);
|
||||
break;
|
||||
case JIT_RELOC_REL16:
|
||||
ASSERT (INT16_MIN <= addend && addend <= INT16_MAX);
|
||||
emit_u16 (_jit, addend - 2);
|
||||
break;
|
||||
case JIT_RELOC_REL32:
|
||||
ASSERT (INT32_MIN <= addend && addend <= INT32_MAX);
|
||||
emit_u32 (_jit, addend - 4);
|
||||
break;
|
||||
case JIT_RELOC_REL64:
|
||||
emit_u64 (_jit, addend - 8);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
jit_patch_here(jit_state_t *_jit, jit_reloc_t reloc)
|
||||
{
|
||||
|
@ -260,82 +348,145 @@ jit_patch_here(jit_state_t *_jit, jit_reloc_t reloc)
|
|||
void
|
||||
jit_patch_there(jit_state_t* _jit, jit_reloc_t reloc, jit_pointer_t addr)
|
||||
{
|
||||
const uint8_t *loc = jit_reloc_instruction (reloc);
|
||||
if (_jit->overflow)
|
||||
return;
|
||||
union jit_pc loc;
|
||||
loc.uc = _jit->start + reloc.offset;
|
||||
ptrdiff_t diff = addr - ((void*) 0);
|
||||
|
||||
if (loc == _jit->last_instruction_start)
|
||||
jit_patch_last (_jit, loc, addr);
|
||||
else
|
||||
jit_patch (_jit, loc, addr);
|
||||
switch (reloc.kind)
|
||||
{
|
||||
case JIT_RELOC_ABSOLUTE:
|
||||
if (sizeof(diff) == 4)
|
||||
*loc.ui = diff + (int32_t)*loc.ui;
|
||||
else
|
||||
*loc.ul = diff + (int64_t)*loc.ul;
|
||||
if (loc.uc + sizeof(diff) == _jit->pc.uc &&
|
||||
(reloc.flags & JIT_RELOC_CAN_SHORTEN))
|
||||
jit_try_shorten (_jit, reloc);
|
||||
break;
|
||||
case JIT_RELOC_REL8:
|
||||
diff += (int8_t)*loc.uc;
|
||||
ASSERT (INT8_MIN <= diff && diff <= INT8_MAX);
|
||||
*loc.uc = diff;
|
||||
break;
|
||||
case JIT_RELOC_REL16:
|
||||
diff += (int16_t)*loc.us;
|
||||
ASSERT (INT16_MIN <= diff && diff <= INT16_MAX);
|
||||
*loc.us = diff;
|
||||
if ((loc.uc + 1) == _jit->pc.uc && (reloc.flags & JIT_RELOC_CAN_SHORTEN))
|
||||
jit_try_shorten (_jit, reloc);
|
||||
break;
|
||||
case JIT_RELOC_REL32:
|
||||
diff += (int32_t)*loc.ui;
|
||||
ASSERT (INT32_MIN <= diff && diff <= INT32_MAX);
|
||||
*loc.ui = diff;
|
||||
if ((loc.ui + 1) == _jit->pc.ui && (reloc.flags & JIT_RELOC_CAN_SHORTEN))
|
||||
jit_try_shorten (_jit, reloc);
|
||||
break;
|
||||
case JIT_RELOC_REL64:
|
||||
*loc.ul = diff + (int64_t)*loc.ul;
|
||||
if ((loc.ul + 1) == _jit->pc.ul && (reloc.flags & JIT_RELOC_CAN_SHORTEN))
|
||||
jit_try_shorten (_jit, reloc);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
# include "x86.c"
|
||||
# include "x86.c"
|
||||
#elif defined(__mips__)
|
||||
# include "mips.c"
|
||||
# include "mips.c"
|
||||
#elif defined(__arm__)
|
||||
# include "arm.c"
|
||||
# include "arm.c"
|
||||
#elif defined(__ppc__) || defined(__powerpc__)
|
||||
# include "ppc.c"
|
||||
# include "ppc.c"
|
||||
#elif defined(__sparc__)
|
||||
# include "sparc.c"
|
||||
# include "sparc.c"
|
||||
#elif defined(__ia64__)
|
||||
# include "ia64.c"
|
||||
# include "ia64.c"
|
||||
#elif defined(__hppa__)
|
||||
# include "hppa.c"
|
||||
# include "hppa.c"
|
||||
#elif defined(__aarch64__)
|
||||
# include "aarch64.c"
|
||||
# include "aarch64.c"
|
||||
#elif defined(__s390__) || defined(__s390x__)
|
||||
# include "s390.c"
|
||||
# include "s390.c"
|
||||
#elif defined(__alpha__)
|
||||
# include "alpha.c"
|
||||
# include "alpha.c"
|
||||
#endif
|
||||
|
||||
#define JIT_CALL_0(stem) _jit_##stem (_jit)
|
||||
#define JIT_CALL_1(stem) _jit_##stem (_jit, a)
|
||||
#define JIT_CALL_2(stem) _jit_##stem (_jit, a, b)
|
||||
#define JIT_CALL_3(stem) _jit_##stem (_jit, a, b, c)
|
||||
#define JIT_CALL_4(stem) _jit_##stem (_jit, a, b, c, d)
|
||||
|
||||
#define JIT_TAIL_CALL_RFF__(stem) return JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL_RGG__(stem) return JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL_RG___(stem) return JIT_CALL_1(stem)
|
||||
#define JIT_TAIL_CALL_RGi__(stem) return JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL_RGu__(stem) return JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL_R____(stem) return JIT_CALL_0(stem)
|
||||
#define JIT_TAIL_CALL__FFF_(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__FF__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL__FGG_(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__FG__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL__FGo_(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__F___(stem) JIT_CALL_1(stem)
|
||||
#define JIT_TAIL_CALL__Fd__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL__Ff__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL__Fp__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL__GF__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL__GGF_(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__GGGG(stem) JIT_CALL_4(stem)
|
||||
#define JIT_TAIL_CALL__GGG_(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__GGGi(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__GGGu(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__GG__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL__GGi_(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__GGo_(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__GGu_(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__G___(stem) JIT_CALL_1(stem)
|
||||
#define JIT_TAIL_CALL__Gi__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL__Gp__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL______(stem) JIT_CALL_0(stem)
|
||||
#define JIT_TAIL_CALL__i___(stem) JIT_CALL_1(stem)
|
||||
#define JIT_TAIL_CALL__oGF_(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__oGG_(stem) JIT_CALL_3(stem)
|
||||
#define JIT_TAIL_CALL__pF__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL__pG__(stem) JIT_CALL_2(stem)
|
||||
#define JIT_TAIL_CALL__p___(stem) JIT_CALL_1(stem)
|
||||
|
||||
#define DEFINE_INSTRUCTION(kind, stem) \
|
||||
JIT_PROTO_##kind(stem) \
|
||||
{ \
|
||||
JIT_TAIL_CALL_##kind(stem); \
|
||||
#define JIT_IMPL_0(stem, ret) \
|
||||
ret jit_##stem (jit_state_t* _jit) \
|
||||
{ \
|
||||
return stem(_jit); \
|
||||
}
|
||||
FOR_EACH_INSTRUCTION(DEFINE_INSTRUCTION)
|
||||
#undef DEFINE_INSTRUCTION
|
||||
#define JIT_IMPL_1(stem, ret, ta) \
|
||||
ret jit_##stem (jit_state_t* _jit, jit_##ta##_t a) \
|
||||
{ \
|
||||
return stem(_jit, unwrap_##ta(a)); \
|
||||
}
|
||||
#define JIT_IMPL_2(stem, ret, ta, tb) \
|
||||
ret jit_##stem (jit_state_t* _jit, jit_##ta##_t a, jit_##tb##_t b) \
|
||||
{ \
|
||||
return stem(_jit, unwrap_##ta(a), unwrap_##tb(b)); \
|
||||
}
|
||||
#define JIT_IMPL_3(stem, ret, ta, tb, tc) \
|
||||
ret jit_##stem (jit_state_t* _jit, jit_##ta##_t a, jit_##tb##_t b, jit_##tc##_t c) \
|
||||
{ \
|
||||
return stem(_jit, unwrap_##ta(a), unwrap_##tb(b), unwrap_##tc(c)); \
|
||||
}
|
||||
#define JIT_IMPL_4(stem, ret, ta, tb, tc, td) \
|
||||
ret jit_##stem (jit_state_t* _jit, jit_##ta##_t a, jit_##tb##_t b, jit_##tc##_t c, jit_##td##_t d) \
|
||||
{ \
|
||||
return stem(_jit, unwrap_##ta(a), unwrap_##tb(b), unwrap_##tc(c), unwrap_##td(d)); \
|
||||
}
|
||||
|
||||
#define JIT_IMPL_RFF__(stem) JIT_IMPL_2(stem, jit_reloc_t, fpr, fpr)
|
||||
#define JIT_IMPL_RGG__(stem) JIT_IMPL_2(stem, jit_reloc_t, gpr, gpr)
|
||||
#define JIT_IMPL_RG___(stem) JIT_IMPL_1(stem, jit_reloc_t, gpr)
|
||||
#define JIT_IMPL_RGi__(stem) JIT_IMPL_2(stem, jit_reloc_t, gpr, imm)
|
||||
#define JIT_IMPL_RGu__(stem) JIT_IMPL_2(stem, jit_reloc_t, gpr, uimm)
|
||||
#define JIT_IMPL_R____(stem) JIT_IMPL_0(stem, jit_reloc_t)
|
||||
#define JIT_IMPL__FFF_(stem) JIT_IMPL_3(stem, void, fpr, fpr, fpr)
|
||||
#define JIT_IMPL__FF__(stem) JIT_IMPL_2(stem, void, fpr, fpr)
|
||||
#define JIT_IMPL__FGG_(stem) JIT_IMPL_3(stem, void, fpr, gpr, gpr)
|
||||
#define JIT_IMPL__FG__(stem) JIT_IMPL_2(stem, void, fpr, gpr)
|
||||
#define JIT_IMPL__FGo_(stem) JIT_IMPL_3(stem, void, fpr, gpr, off)
|
||||
#define JIT_IMPL__F___(stem) JIT_IMPL_1(stem, void, fpr)
|
||||
#define JIT_IMPL__Fd__(stem) JIT_IMPL_2(stem, void, fpr, float64)
|
||||
#define JIT_IMPL__Ff__(stem) JIT_IMPL_2(stem, void, fpr, float32)
|
||||
#define JIT_IMPL__Fp__(stem) JIT_IMPL_2(stem, void, fpr, pointer)
|
||||
#define JIT_IMPL__GF__(stem) JIT_IMPL_2(stem, void, gpr, fpr)
|
||||
#define JIT_IMPL__GGF_(stem) JIT_IMPL_3(stem, void, gpr, gpr, fpr)
|
||||
#define JIT_IMPL__GGGG(stem) JIT_IMPL_4(stem, void, gpr, gpr, gpr, gpr)
|
||||
#define JIT_IMPL__GGG_(stem) JIT_IMPL_3(stem, void, gpr, gpr, gpr)
|
||||
#define JIT_IMPL__GGGi(stem) JIT_IMPL_4(stem, void, gpr, gpr, gpr, imm)
|
||||
#define JIT_IMPL__GGGu(stem) JIT_IMPL_4(stem, void, gpr, gpr, gpr, uimm)
|
||||
#define JIT_IMPL__GG__(stem) JIT_IMPL_2(stem, void, gpr, gpr)
|
||||
#define JIT_IMPL__GGi_(stem) JIT_IMPL_3(stem, void, gpr, gpr, imm)
|
||||
#define JIT_IMPL__GGo_(stem) JIT_IMPL_3(stem, void, gpr, gpr, off)
|
||||
#define JIT_IMPL__GGu_(stem) JIT_IMPL_3(stem, void, gpr, gpr, uimm)
|
||||
#define JIT_IMPL__G___(stem) JIT_IMPL_1(stem, void, gpr)
|
||||
#define JIT_IMPL__Gi__(stem) JIT_IMPL_2(stem, void, gpr, imm)
|
||||
#define JIT_IMPL__Gp__(stem) JIT_IMPL_2(stem, void, gpr, pointer)
|
||||
#define JIT_IMPL______(stem) JIT_IMPL_0(stem, void)
|
||||
#define JIT_IMPL__i___(stem) JIT_IMPL_1(stem, void, imm)
|
||||
#define JIT_IMPL__oGF_(stem) JIT_IMPL_3(stem, void, off, gpr, fpr)
|
||||
#define JIT_IMPL__oGG_(stem) JIT_IMPL_3(stem, void, off, gpr, gpr)
|
||||
#define JIT_IMPL__pF__(stem) JIT_IMPL_2(stem, void, pointer, fpr)
|
||||
#define JIT_IMPL__pG__(stem) JIT_IMPL_2(stem, void, pointer, gpr)
|
||||
#define JIT_IMPL__p___(stem) JIT_IMPL_1(stem, void, pointer)
|
||||
|
||||
#define unwrap_gpr(r) rn(r)
|
||||
#define unwrap_fpr(r) rn(r)
|
||||
#define unwrap_imm(i) i
|
||||
#define unwrap_uimm(u) u
|
||||
#define unwrap_off(o) o
|
||||
#define unwrap_pointer(p) ((uintptr_t) p)
|
||||
#define unwrap_float32(f) f
|
||||
#define unwrap_float64(d) d
|
||||
|
||||
#define IMPL_INSTRUCTION(kind, stem) JIT_IMPL_##kind(stem)
|
||||
FOR_EACH_INSTRUCTION(IMPL_INSTRUCTION)
|
||||
#undef IMPL_INSTRUCTION
|
||||
|
|
|
@ -581,21 +581,21 @@ static void _stxr_l(jit_state_t*,int32_t,int32_t,int32_t);
|
|||
static void _stxi_l(jit_state_t*,jit_word_t,int32_t,int32_t);
|
||||
# endif
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
|
||||
static void _htonr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
|
||||
static void _htonr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
|
||||
static void _bswapr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
|
||||
static void _bswapr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# if __WORDSIZE == 64
|
||||
# define htonr_ul(r0,r1) _htonr_ul(_jit,r0,r1)
|
||||
static void _htonr_ul(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ul(r0,r1) _bswapr_ul(_jit,r0,r1)
|
||||
static void _bswapr_ul(jit_state_t*,int32_t,int32_t);
|
||||
# endif
|
||||
# else
|
||||
# define htonr_us(r0,r1) extr_us(r0,r1)
|
||||
# define bswapr_us(r0,r1) extr_us(r0,r1)
|
||||
# if __WORDSIZE == 32
|
||||
# define htonr_ui(r0,r1) movr(r0,r1)
|
||||
# define bswapr_ui(r0,r1) movr(r0,r1)
|
||||
# else
|
||||
# define htonr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define htonr_ul(r0,r1) movr(r0,r1)
|
||||
# define bswapr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define bswapr_ul(r0,r1) movr(r0,r1)
|
||||
# endif
|
||||
# endif
|
||||
# define extr_c(r0,r1) _extr_c(_jit,r0,r1)
|
||||
|
@ -1676,7 +1676,7 @@ _stxi_l(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
|
|||
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static void
|
||||
_htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t t0;
|
||||
t0 = jit_get_reg(jit_class_gpr);
|
||||
|
@ -1689,7 +1689,7 @@ _htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|||
}
|
||||
|
||||
static void
|
||||
_htonr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t t0;
|
||||
int32_t t1;
|
||||
|
@ -1716,13 +1716,13 @@ _htonr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|||
}
|
||||
|
||||
static void
|
||||
_htonr_ul(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_ul(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t reg;
|
||||
reg = jit_get_reg(jit_class_gpr);
|
||||
rshi_u(rn(reg), r1, 32);
|
||||
htonr_ui(r0, r1);
|
||||
htonr_ui(rn(reg), rn(reg));
|
||||
bswapr_ui(r0, r1);
|
||||
bswapr, 2019_ui(rn(reg), rn(reg));
|
||||
lshi(r0, r0, 32);
|
||||
orr(r0, r0, rn(reg));
|
||||
jit_unget_reg(reg);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2017 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2012-2017, 2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU lightning.
|
||||
*
|
||||
|
@ -510,21 +510,21 @@ static jit_word_t _movi_p(jit_state_t*,int32_t,jit_word_t);
|
|||
# define extr_ui(r0,r1) CLRLDI(r0,r1,32)
|
||||
# endif
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define htonr_us(r0,r1) extr_us(r0,r1)
|
||||
# define bswapr_us(r0,r1) extr_us(r0,r1)
|
||||
# if __WORDSIZE == 32
|
||||
# define htonr_ui(r0,r1) movr(r0,r1)
|
||||
# define bswapr_ui(r0,r1) movr(r0,r1)
|
||||
# else
|
||||
# define htonr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define htonr_ul(r0,r1) movr(r0,r1)
|
||||
# define bswapr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define bswapr_ul(r0,r1) movr(r0,r1)
|
||||
# endif
|
||||
# else
|
||||
# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
|
||||
static void _htonr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
|
||||
static void _htonr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
|
||||
static void _bswapr_us(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
|
||||
static void _bswapr_ui(jit_state_t*,int32_t,int32_t);
|
||||
# if __WORDSIZE == 64
|
||||
# define htonr_ul(r0,r1) _htonr_ul(_jit,r0,r1)
|
||||
static void _htonr_ul(jit_state_t*,int32_t,int32_t);
|
||||
# define bswapr_ul(r0,r1) _bswapr_ul(_jit,r0,r1)
|
||||
static void _bswapr_ul(jit_state_t*,int32_t,int32_t);
|
||||
# endif
|
||||
# endif
|
||||
# define addr(r0,r1,r2) ADD(r0,r1,r2)
|
||||
|
@ -1121,7 +1121,7 @@ _movi_p(jit_state_t *_jit, int32_t r0, jit_word_t i0)
|
|||
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static void
|
||||
_htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t t0;
|
||||
t0 = jit_get_reg(jit_class_gpr);
|
||||
|
@ -1134,7 +1134,7 @@ _htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|||
}
|
||||
|
||||
static void
|
||||
_htonr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t reg;
|
||||
reg = jit_get_reg(jit_class_gpr);
|
||||
|
@ -1147,13 +1147,13 @@ _htonr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|||
|
||||
# if __WORDSIZE == 64
|
||||
static void
|
||||
_htonr_ul(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
_bswapr_ul(jit_state_t *_jit, int32_t r0, int32_t r1)
|
||||
{
|
||||
int32_t reg;
|
||||
reg = jit_get_reg(jit_class_gpr);
|
||||
rshi_u(rn(reg), r1, 32);
|
||||
htonr_ui(r0, r1);
|
||||
htonr_ui(rn(reg), rn(reg));
|
||||
bswapr_ui(r0, r1);
|
||||
bswapr_ui(rn(reg), rn(reg));
|
||||
lshi(r0, r0, 32);
|
||||
orr(r0, r0, rn(reg));
|
||||
jit_unget_reg(reg);
|
||||
|
|
|
@ -1079,12 +1079,12 @@ static void _ori(jit_state_t*,int32_t,int32_t,jit_word_t);
|
|||
static void _xorr(jit_state_t*,int32_t,int32_t,int32_t);
|
||||
# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0)
|
||||
static void _xori(jit_state_t*,int32_t,int32_t,jit_word_t);
|
||||
# define htonr_us(r0,r1) extr_us(r0,r1)
|
||||
# define bswapr_us(r0,r1) extr_us(r0,r1)
|
||||
# if __WORDSIZE == 32
|
||||
# define htonr_ui(r0,r1) movr(r0,r1)
|
||||
# define bswapr_ui(r0,r1) movr(r0,r1)
|
||||
# else
|
||||
# define htonr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define htonr_ul(r0,r1) movr(r0,r1)
|
||||
# define bswapr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define bswapr, 2019_ul(r0,r1) movr(r0,r1)
|
||||
# endif
|
||||
# define extr_c(r0,r1) LGBR(r0,r1)
|
||||
# define extr_uc(r0,r1) LLGCR(r0,r1)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2013-2017, 2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU lightning.
|
||||
*
|
||||
|
@ -669,7 +669,7 @@ static void _xori(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|||
# define rshr_u(r0, r1, r2) SRLX(r1, r2, r0)
|
||||
# define rshi_u(r0, r1, i0) SRLXI(r1, i0, r0)
|
||||
# endif
|
||||
# define htonr_us(r0,r1) extr_us(r0,r1)
|
||||
# define bswapr_us(r0,r1) extr_us(r0,r1)
|
||||
# define extr_c(r0,r1) _extr_c(_jit,r0,r1)
|
||||
static void _extr_c(jit_state_t*,int32_t,int32_t);
|
||||
# define extr_uc(r0,r1) andi(r0, r1, 0xff)
|
||||
|
@ -678,10 +678,10 @@ static void _extr_s(jit_state_t*,int32_t,int32_t);
|
|||
# define extr_us(r0,r1) _extr_us(_jit,r0,r1)
|
||||
static void _extr_us(jit_state_t*,int32_t,int32_t);
|
||||
# if __WORDSIZE == 32
|
||||
# define htonr_ui(r0,r1) movr(r0,r1)
|
||||
# define bswapr_ui(r0,r1) movr(r0,r1)
|
||||
# else
|
||||
# define htonr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define htonr_ul(r0,r1) movr(r0,r1)
|
||||
# define bswapr_ui(r0,r1) extr_ui(r0,r1)
|
||||
# define bswapr_ul(r0,r1) movr(r0,r1)
|
||||
# define extr_i(r0,r1) _extr_i(_jit,r0,r1)
|
||||
static void _extr_i(jit_state_t*,int32_t,int32_t);
|
||||
# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1)
|
||||
|
|
5560
jit/x86-cpu.c
5560
jit/x86-cpu.c
File diff suppressed because it is too large
Load diff
2261
jit/x86-sse.c
2261
jit/x86-sse.c
File diff suppressed because it is too large
Load diff
324
jit/x86.h
324
jit/x86.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU lightning.
|
||||
*
|
||||
|
@ -14,186 +14,202 @@
|
|||
* License for more details.
|
||||
*
|
||||
* Authors:
|
||||
* Paulo Cesar Pereira de Andrade
|
||||
* Paulo Cesar Pereira de Andrade
|
||||
*/
|
||||
|
||||
#ifndef _jit_x86_h
|
||||
#define _jit_x86_h
|
||||
|
||||
#define JIT_HASH_CONSTS 1
|
||||
#define JIT_NUM_OPERANDS 2
|
||||
#define JIT_HASH_CONSTS 1
|
||||
#define JIT_NUM_OPERANDS 2
|
||||
|
||||
/*
|
||||
* Types
|
||||
*/
|
||||
#define jit_sse2_p() jit_cpu.sse2
|
||||
#define jit_x87_reg_p(reg) ((reg) >= _ST0 && (reg) <= _ST6)
|
||||
#define jit_sse2_p() jit_cpu.sse2
|
||||
#define jit_x87_reg_p(reg) ((reg) >= _ST0 && (reg) <= _ST6)
|
||||
#if __WORDSIZE == 32
|
||||
# if defined(__x86_64__)
|
||||
# define __X64_32 1
|
||||
# define __X64 1
|
||||
# else
|
||||
# define __X32 1
|
||||
# endif
|
||||
# if defined(__x86_64__)
|
||||
# define __X64 1
|
||||
# define __X64_32 1
|
||||
# define __X32 0
|
||||
# else
|
||||
# define __X64 0
|
||||
# define __X64_32 0
|
||||
# define __X32 1
|
||||
# endif
|
||||
#else
|
||||
# define __X64 1
|
||||
# define __X64 1
|
||||
# define __X64_32 0
|
||||
# define __X32 0
|
||||
#endif
|
||||
|
||||
#define JIT_FP _RBP
|
||||
#define JIT_FP _RBP
|
||||
typedef enum {
|
||||
#if __X32
|
||||
# define jit_r(i) (_RAX + (i))
|
||||
# define jit_r_num() 3
|
||||
# define jit_v(i) (_RBX + (i))
|
||||
# define jit_v_num() 3
|
||||
# define jit_f(i) (jit_cpu.sse2 ? _XMM0 + (i) : _ST0 + (i))
|
||||
# define jit_f_num() (jit_cpu.sse2 ? 8 : 6)
|
||||
# define JIT_R0 _RAX
|
||||
# define JIT_R1 _RCX
|
||||
# define JIT_R2 _RDX
|
||||
_RAX, _RCX, _RDX,
|
||||
# define JIT_V0 _RBX
|
||||
# define JIT_V1 _RSI
|
||||
# define JIT_V2 _RDI
|
||||
_RBX, _RSI, _RDI,
|
||||
_RSP, _RBP,
|
||||
# define JIT_F0 (jit_sse2_p() ? _XMM0 : _ST0)
|
||||
# define JIT_F1 (jit_sse2_p() ? _XMM1 : _ST1)
|
||||
# define JIT_F2 (jit_sse2_p() ? _XMM2 : _ST2)
|
||||
# define JIT_F3 (jit_sse2_p() ? _XMM3 : _ST3)
|
||||
# define JIT_F4 (jit_sse2_p() ? _XMM4 : _ST4)
|
||||
# define JIT_F5 (jit_sse2_p() ? _XMM5 : _ST5)
|
||||
# define JIT_F6 (jit_sse2_p() ? _XMM6 : _ST6)
|
||||
_XMM0, _XMM1, _XMM2, _XMM3, _XMM4, _XMM5, _XMM6, _XMM7,
|
||||
# define jit_sse_reg_p(reg) ((reg) >= _XMM0 && (reg) <= _XMM7)
|
||||
# define jit_r(i) (_RAX + (i))
|
||||
# define jit_r_num() 3
|
||||
# define jit_v(i) (_RBX + (i))
|
||||
# define jit_v_num() 3
|
||||
# define jit_f(i) (jit_cpu.sse2 ? _XMM0 + (i) : _ST0 + (i))
|
||||
# define jit_f_num() (jit_cpu.sse2 ? 8 : 6)
|
||||
# define JIT_R0 _RAX
|
||||
# define JIT_R1 _RCX
|
||||
# define JIT_R2 _RDX
|
||||
_RAX, _RCX, _RDX,
|
||||
# define JIT_V0 _RBX
|
||||
# define JIT_V1 _RSI
|
||||
# define JIT_V2 _RDI
|
||||
_RBX, _RSI, _RDI,
|
||||
_RSP, _RBP,
|
||||
# define JIT_F0 _XMM0
|
||||
# define JIT_F1 _XMM1
|
||||
# define JIT_F2 _XMM2
|
||||
# define JIT_F3 _XMM3
|
||||
# define JIT_F4 _XMM4
|
||||
# define JIT_F5 _XMM5
|
||||
# define JIT_F6 _XMM6
|
||||
_XMM0, _XMM1, _XMM2, _XMM3, _XMM4, _XMM5, _XMM6, _XMM7,
|
||||
# define jit_sse_reg_p(reg) ((reg) >= _XMM0 && (reg) <= _XMM7)
|
||||
#else
|
||||
# if __CYGWIN__
|
||||
# define jit_r(i) (_RAX + (i))
|
||||
# define jit_r_num() 3
|
||||
# define jit_v(i) (_RBX + (i))
|
||||
# define jit_v_num() 7
|
||||
# define jit_f(index) (_XMM4 + (index))
|
||||
# define jit_f_num() 12
|
||||
# define JIT_R0 _RAX
|
||||
# define JIT_R1 _R10
|
||||
# define JIT_R2 _R11
|
||||
# define JIT_V0 _RBX
|
||||
# define JIT_V1 _RDI
|
||||
# define JIT_V2 _RSI
|
||||
# define JIT_V3 _R12
|
||||
# define JIT_V4 _R13
|
||||
# define JIT_V5 _R14
|
||||
# define JIT_V6 _R15
|
||||
/* Volatile - Return value register */
|
||||
_RAX,
|
||||
/* Volatile */
|
||||
_R10, _R11,
|
||||
/* Nonvolatile */
|
||||
_RBX, _RDI, _RSI,
|
||||
_R12, _R13, _R14, _R15,
|
||||
/* Volatile - Integer arguments (4 to 1) */
|
||||
_R9, _R8, _RDX, _RCX,
|
||||
/* Nonvolatile */
|
||||
_RSP, _RBP,
|
||||
# define JIT_F0 _XMM4
|
||||
# define JIT_F1 _XMM5
|
||||
# define JIT_F2 _XMM6
|
||||
# define JIT_F3 _XMM7
|
||||
# define JIT_F4 _XMM8
|
||||
# define JIT_F5 _XMM9
|
||||
# define JIT_F6 _XMM10
|
||||
# define JIT_F7 _XMM11
|
||||
# define JIT_F8 _XMM12
|
||||
# define JIT_F9 _XMM13
|
||||
# define JIT_F10 _XMM14
|
||||
# define JIT_F11 _XMM15
|
||||
/* Volatile */
|
||||
_XMM4, _XMM5,
|
||||
/* Nonvolatile */
|
||||
_XMM6, _XMM7, _XMM8, _XMM9, _XMM10,
|
||||
_XMM11, _XMM12, _XMM13, _XMM14, _XMM15,
|
||||
/* Volatile - FP arguments (4 to 1) */
|
||||
_XMM3, _XMM2, _XMM1, _XMM0,
|
||||
# define jit_sse_reg_p(reg) ((reg) >= _XMM4 && (reg) <= _XMM0)
|
||||
# define jit_r(i) (_RAX + (i))
|
||||
# define jit_r_num() 3
|
||||
# define jit_v(i) (_RBX + (i))
|
||||
# define jit_v_num() 7
|
||||
# define jit_f(index) (_XMM4 + (index))
|
||||
# define jit_f_num() 12
|
||||
# define JIT_R0 _RAX
|
||||
# define JIT_R1 _R10
|
||||
# define JIT_R2 _R11
|
||||
# define JIT_V0 _RBX
|
||||
# define JIT_V1 _RDI
|
||||
# define JIT_V2 _RSI
|
||||
# define JIT_V3 _R12
|
||||
# define JIT_V4 _R13
|
||||
# define JIT_V5 _R14
|
||||
# define JIT_V6 _R15
|
||||
/* Volatile - Return value register */
|
||||
_RAX,
|
||||
/* Volatile */
|
||||
_R10, _R11,
|
||||
/* Nonvolatile */
|
||||
_RBX, _RDI, _RSI,
|
||||
_R12, _R13, _R14, _R15,
|
||||
/* Volatile - Integer arguments (4 to 1) */
|
||||
_R9, _R8, _RDX, _RCX,
|
||||
/* Nonvolatile */
|
||||
_RSP, _RBP,
|
||||
# define JIT_F0 _XMM0
|
||||
# define JIT_F1 _XMM1
|
||||
# define JIT_F2 _XMM2
|
||||
# define JIT_F3 _XMM3
|
||||
# define JIT_F4 _XMM4
|
||||
# define JIT_F5 _XMM5
|
||||
# define JIT_F6 _XMM6
|
||||
# define JIT_F7 _XMM7
|
||||
# define JIT_F8 _XMM8
|
||||
# define JIT_F9 _XMM9
|
||||
# define JIT_F10 _XMM10
|
||||
# define JIT_F11 _XMM11
|
||||
# define JIT_F12 _XMM12
|
||||
# define JIT_F13 _XMM13
|
||||
# define JIT_F14 _XMM14
|
||||
# define JIT_F15 _XMM15
|
||||
/* Volatile */
|
||||
_XMM4, _XMM5,
|
||||
/* Nonvolatile */
|
||||
_XMM6, _XMM7, _XMM8, _XMM9, _XMM10,
|
||||
_XMM11, _XMM12, _XMM13, _XMM14, _XMM15,
|
||||
/* Volatile - FP arguments (4 to 1) */
|
||||
_XMM3, _XMM2, _XMM1, _XMM0,
|
||||
# define jit_sse_reg_p(reg) ((reg) >= _XMM4 && (reg) <= _XMM0)
|
||||
# else
|
||||
# define jit_r(i) (_RAX + (i))
|
||||
# define jit_r_num() 4
|
||||
# define jit_v(i) (_RBX + (i))
|
||||
# define jit_v_num() 4
|
||||
# define jit_f(index) (_XMM8 + (index))
|
||||
# define jit_f_num() 8
|
||||
# define JIT_R0 _RAX
|
||||
# define JIT_R1 _R10
|
||||
# define JIT_R2 _R11
|
||||
# define JIT_R3 _R12
|
||||
_RAX, _R10, _R11, _R12,
|
||||
# define JIT_V0 _RBX
|
||||
# define JIT_V1 _R13
|
||||
# define JIT_V2 _R14
|
||||
# define JIT_V3 _R15
|
||||
_RBX, _R13, _R14, _R15,
|
||||
_R9, _R8, _RCX, _RDX, _RSI, _RDI,
|
||||
_RSP, _RBP,
|
||||
# define JIT_F0 _XMM8
|
||||
# define JIT_F1 _XMM9
|
||||
# define JIT_F2 _XMM10
|
||||
# define JIT_F3 _XMM11
|
||||
# define JIT_F4 _XMM12
|
||||
# define JIT_F5 _XMM13
|
||||
# define JIT_F6 _XMM14
|
||||
# define JIT_F7 _XMM15
|
||||
_XMM8, _XMM9, _XMM10, _XMM11, _XMM12, _XMM13, _XMM14, _XMM15,
|
||||
_XMM7, _XMM6, _XMM5, _XMM4, _XMM3, _XMM2, _XMM1, _XMM0,
|
||||
# define jit_sse_reg_p(reg) ((reg) >= _XMM8 && (reg) <= _XMM0)
|
||||
# define jit_r(i) (_RAX + (i))
|
||||
# define jit_r_num() 4
|
||||
# define jit_v(i) (_RBX + (i))
|
||||
# define jit_v_num() 4
|
||||
# define jit_f(index) (_XMM8 + (index))
|
||||
# define jit_f_num() 8
|
||||
# define JIT_R0 _RAX
|
||||
# define JIT_R1 _R10
|
||||
# define JIT_R2 _R11
|
||||
# define JIT_R3 _R12
|
||||
_RAX, _R10, _R11, _R12,
|
||||
# define JIT_V0 _RBX
|
||||
# define JIT_V1 _R13
|
||||
# define JIT_V2 _R14
|
||||
# define JIT_V3 _R15
|
||||
_RBX, _R13, _R14, _R15,
|
||||
_R9, _R8, _RCX, _RDX, _RSI, _RDI,
|
||||
_RSP, _RBP,
|
||||
# define JIT_F0 _XMM0
|
||||
# define JIT_F1 _XMM1
|
||||
# define JIT_F2 _XMM2
|
||||
# define JIT_F3 _XMM3
|
||||
# define JIT_F4 _XMM4
|
||||
# define JIT_F5 _XMM5
|
||||
# define JIT_F6 _XMM6
|
||||
# define JIT_F7 _XMM7
|
||||
# define JIT_F8 _XMM8
|
||||
# define JIT_F9 _XMM9
|
||||
# define JIT_F10 _XMM10
|
||||
# define JIT_F11 _XMM11
|
||||
# define JIT_F12 _XMM12
|
||||
# define JIT_F13 _XMM13
|
||||
# define JIT_F14 _XMM14
|
||||
# define JIT_F15 _XMM15
|
||||
_XMM8, _XMM9, _XMM10, _XMM11, _XMM12, _XMM13, _XMM14, _XMM15,
|
||||
_XMM7, _XMM6, _XMM5, _XMM4, _XMM3, _XMM2, _XMM1, _XMM0,
|
||||
# define jit_sse_reg_p(reg) ((reg) >= _XMM8 && (reg) <= _XMM0)
|
||||
# endif
|
||||
#endif
|
||||
_ST0, _ST1, _ST2, _ST3, _ST4, _ST5, _ST6,
|
||||
# define JIT_NOREG _NOREG
|
||||
_NOREG,
|
||||
# define JIT_NOREG _NOREG
|
||||
_NOREG,
|
||||
} jit_reg_t;
|
||||
|
||||
typedef struct {
|
||||
/* x87 present */
|
||||
uint32_t fpu : 1;
|
||||
/* cmpxchg8b instruction */
|
||||
uint32_t cmpxchg8b : 1;
|
||||
/* cmov and fcmov branchless conditional mov */
|
||||
uint32_t cmov : 1;
|
||||
/* mmx registers/instructions available */
|
||||
uint32_t mmx : 1;
|
||||
/* sse registers/instructions available */
|
||||
uint32_t sse : 1;
|
||||
/* sse2 registers/instructions available */
|
||||
uint32_t sse2 : 1;
|
||||
/* sse3 instructions available */
|
||||
uint32_t sse3 : 1;
|
||||
/* pcmulqdq instruction */
|
||||
uint32_t pclmulqdq : 1;
|
||||
/* ssse3 suplemental sse3 instructions available */
|
||||
uint32_t ssse3 : 1;
|
||||
/* fused multiply/add using ymm state */
|
||||
uint32_t fma : 1;
|
||||
/* cmpxchg16b instruction */
|
||||
uint32_t cmpxchg16b : 1;
|
||||
/* sse4.1 instructions available */
|
||||
uint32_t sse4_1 : 1;
|
||||
/* sse4.2 instructions available */
|
||||
uint32_t sse4_2 : 1;
|
||||
/* movbe instruction available */
|
||||
uint32_t movbe : 1;
|
||||
/* popcnt instruction available */
|
||||
uint32_t popcnt : 1;
|
||||
/* aes instructions available */
|
||||
uint32_t aes : 1;
|
||||
/* avx instructions available */
|
||||
uint32_t avx : 1;
|
||||
/* lahf/sahf available in 64 bits mode */
|
||||
uint32_t lahf : 1;
|
||||
/* x87 present */
|
||||
uint32_t fpu : 1;
|
||||
/* cmpxchg8b instruction */
|
||||
uint32_t cmpxchg8b : 1;
|
||||
/* cmov and fcmov branchless conditional mov */
|
||||
uint32_t cmov : 1;
|
||||
/* mmx registers/instructions available */
|
||||
uint32_t mmx : 1;
|
||||
/* sse registers/instructions available */
|
||||
uint32_t sse : 1;
|
||||
/* sse2 registers/instructions available */
|
||||
uint32_t sse2 : 1;
|
||||
/* sse3 instructions available */
|
||||
uint32_t sse3 : 1;
|
||||
/* pcmulqdq instruction */
|
||||
uint32_t pclmulqdq : 1;
|
||||
/* ssse3 suplemental sse3 instructions available */
|
||||
uint32_t ssse3 : 1;
|
||||
/* fused multiply/add using ymm state */
|
||||
uint32_t fma : 1;
|
||||
/* cmpxchg16b instruction */
|
||||
uint32_t cmpxchg16b : 1;
|
||||
/* sse4.1 instructions available */
|
||||
uint32_t sse4_1 : 1;
|
||||
/* sse4.2 instructions available */
|
||||
uint32_t sse4_2 : 1;
|
||||
/* movbe instruction available */
|
||||
uint32_t movbe : 1;
|
||||
/* popcnt instruction available */
|
||||
uint32_t popcnt : 1;
|
||||
/* aes instructions available */
|
||||
uint32_t aes : 1;
|
||||
/* avx instructions available */
|
||||
uint32_t avx : 1;
|
||||
/* lahf/sahf available in 64 bits mode */
|
||||
uint32_t lahf : 1;
|
||||
} jit_cpu_t;
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
JIT_API jit_cpu_t jit_cpu;
|
||||
JIT_API jit_cpu_t jit_cpu;
|
||||
|
||||
#endif /* _jit_x86_h */
|
||||
|
|
16
tests/Makefile
Normal file
16
tests/Makefile
Normal file
|
@ -0,0 +1,16 @@
|
|||
TESTS = addr
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -O0 -g
|
||||
|
||||
all: $(addprefix test-,$(TESTS))
|
||||
|
||||
jit.o: ../jit.h ../jit/*.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -flto -I.. -o jit.o -c ../jit/jit.c
|
||||
|
||||
test-%: test-%.c jit.o test.h
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -flto -I.. -o $@ jit.o $<
|
||||
|
||||
clean:
|
||||
rm -f $(addprefix test-,$(TESTS))
|
||||
rm -f jit.o
|
27
tests/test-addr.c
Normal file
27
tests/test-addr.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include "test.h"
|
||||
|
||||
static void
|
||||
run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
|
||||
{
|
||||
jit_begin(j, arena_base, arena_size);
|
||||
|
||||
jit_arg_abi_t abi[] = { JIT_ARG_ABI_INT32, JIT_ARG_ABI_INT32 };
|
||||
jit_arg_t args[2];
|
||||
jit_receive(j, 2, abi, args);
|
||||
ASSERT(args[0].kind == JIT_ARG_LOC_GPR);
|
||||
ASSERT(args[1].kind == JIT_ARG_LOC_GPR);
|
||||
jit_addr(j, JIT_R0, args[0].loc.gpr, args[1].loc.gpr);
|
||||
jit_retr(j, JIT_R0);
|
||||
|
||||
size_t size = 0;
|
||||
void* ret = jit_end(j, &size);
|
||||
|
||||
int (*f)(int, int) = ret;
|
||||
ASSERT(f(42, 69) == 111);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
return main_helper(argc, argv, run_test);
|
||||
}
|
42
tests/test.h
Normal file
42
tests/test.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <jit.h>
|
||||
|
||||
#define ASSERT(x) \
|
||||
do { \
|
||||
if (!(x)) { \
|
||||
fprintf(stderr, "%s:%d: assertion failed: " #x "\n", \
|
||||
__FILE__, __LINE__); \
|
||||
abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline int
|
||||
main_helper (int argc, char *argv[],
|
||||
void (*run_test)(jit_state_t*, uint8_t*, size_t))
|
||||
{
|
||||
ASSERT(init_jit());
|
||||
jit_state_t *j = jit_new_state();
|
||||
ASSERT(j);
|
||||
|
||||
const size_t arena_size = 4096;
|
||||
char *arena_base = mmap (NULL, arena_size,
|
||||
PROT_EXEC | PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
|
||||
if (arena_base == MAP_FAILED)
|
||||
{
|
||||
perror ("allocating JIT code buffer failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
run_test(j, (uint8_t*)arena_base, arena_size);
|
||||
|
||||
jit_destroy_state(j);
|
||||
|
||||
munmap(arena_base, arena_size);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue