1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-08 10:50:21 +02:00

Implement new synthesized IR codes sequences

* lib/jit_rewind.c: New file implementing generic functions
	to "rewind", or rewrite IR code sequences.

	* include/lightning.h: Add several new codes, that previously
	were a function call, that would synthesize the operation.
	Now, there is a code for the operation, and a new flag to
	know an operation is synthesized.

	* include/lightning/jit_private.h: Add several new macros to
	help construct synthesized IR code sequences.

	* lib/Makefile.am: Update for lib/jit_rewind.c.

	* lib/jit_disasm.c: Update for a small rework on jit_node_t,
	so that --enable-devel-disassembler does not need a change
	in the layout of jit_node_t.

	* lib/jit_names.c: Update for the new codes.

	* lib/jit_print.c: Update to print more readable output, and
	flag synthesized IR code sequences.

	* lib/jit_aarch64-sz.c, lib/jit_aarch64.c,
	lib/jit_arm-sz.c, lib/jit_arm.c, lib/jit_x86-sz.c,
	lib/jit_x86.c: Update for new synthesized IR code sequences.

	* lib/jit_ppc-cpu.c, lib/jit_ppc-fpu., lib/jit_ppc-sz.c,
	lib/jit_ppc.c, lib/jit_mips-cpu.c, lib/jit_mips-fpu.c,
	lib/jit_mips-sz.c, lib/jit_mips.c, lib/jit_s390-fpu.c,
	lib/jit_s390-sz.c, lib/jit_s390.c: Update for new synthesized
	IR code sequences and correct bugs in the initial varargs
	implementation support.

	* lib/jit_alpha-sz.c, lib/jit_alpha.c, lib/jit_hppa-sz.c,
	lib/jit_hppa.c, lib/jit_ia64-sz.c, lib/jit_ia64.c,
	lib/jit_sparc-sz.c, lib/jit_sparc.c: Add generic, untested
	support for the new synthesized	IR code sequences. Known
	most likely broken right now, and should be corrected once
	access to these hosts is available.

	* lib/lightning.c: Update for new IR codes, and add support
	for not yet existing instructions that change third argument.

	* size.c: Change to use different tables for LE and BE PowerPC.
	Correct a wrong endif for x32.
This commit is contained in:
pcpa 2015-06-04 18:53:07 -03:00
parent 7f1e0dfb34
commit d0a5bd8d3d
35 changed files with 4397 additions and 1152 deletions

View file

@ -1,4 +1,52 @@
2015-06-25 Paulo Andrade <pcpa@gnu.org>
2015-06-04 Paulo Andrade <pcpa@gnu.org>
* lib/jit_rewind.c: New file implementing generic functions
to "rewind", or rewrite IR code sequences.
* include/lightning.h: Add several new codes, that previously
were a function call, that would synthesize the operation.
Now, there is a code for the operation, and a new flag to
know an operation is synthesized.
* include/lightning/jit_private.h: Add several new macros to
help construct synthesized IR code sequences.
* lib/Makefile.am: Update for lib/jit_rewind.c.
* lib/jit_disasm.c: Update for a small rework on jit_node_t,
so that --enable-devel-disassembler does not need a change
in the layout of jit_node_t.
* lib/jit_names.c: Update for the new codes.
* lib/jit_print.c: Update to print more readable output, and
flag synthesized IR code sequences.
* lib/jit_aarch64-sz.c, lib/jit_aarch64.c,
lib/jit_arm-sz.c, lib/jit_arm.c, lib/jit_x86-sz.c,
lib/jit_x86.c: Update for new synthesized IR code sequences.
* lib/jit_ppc-cpu.c, lib/jit_ppc-fpu., lib/jit_ppc-sz.c,
lib/jit_ppc.c, lib/jit_mips-cpu.c, lib/jit_mips-fpu.c,
lib/jit_mips-sz.c, lib/jit_mips.c, lib/jit_s390-fpu.c,
lib/jit_s390-sz.c, lib/jit_s390.c: Update for new synthesized
IR code sequences and correct bugs in the initial varargs
implementation support.
* lib/jit_alpha-sz.c, lib/jit_alpha.c, lib/jit_hppa-sz.c,
lib/jit_hppa.c, lib/jit_ia64-sz.c, lib/jit_ia64.c,
lib/jit_sparc-sz.c, lib/jit_sparc.c: Add generic, untested
support for the new synthesized IR code sequences. Known
most likely broken right now, and should be corrected once
access to these hosts is available.
* lib/lightning.c: Update for new IR codes, and add support
for not yet existing instructions that change third argument.
* size.c: Change to use different tables for LE and BE PowerPC.
Correct a wrong endif for x32.
2015-05-25 Paulo Andrade <pcpa@gnu.org>
* check/cva_list.c: New file implementing a test to ensure
the value returned by jit_va_start is a valid C va_list.
@ -20,7 +68,7 @@
lib/jit_x86-cpu.c, lib/jit_x86-sz.c, lib/jit_x86.c: Correct
the jit_va_list_t semantics to match C va_list.
2015-06-24 Paulo Andrade <pcpa@gnu.org>
2015-05-24 Paulo Andrade <pcpa@gnu.org>
* lib/Makefile.am: Bump library major. This is a preparation
for a rework that was due for quite some time, but that is
@ -40,78 +88,78 @@
make that call after jit_ellipsis, but documentation
should be updated for it.
2015-06-24 Paulo Andrade <pcpa@gnu.org>
2015-05-24 Paulo Andrade <pcpa@gnu.org>
* lib/jit_aarch64-fpu.c, lib/jit_aarch64.c: Correct base
aarch64 varargs code.
2015-06-24 Paulo Andrade <pcpa@gnu.org>
2015-05-24 Paulo Andrade <pcpa@gnu.org>
* check/lightning.c: Clearly run check if clang is the system
compiler.
2015-06-20 Paulo Andrade <pcpa@gnu.org>
2015-05-20 Paulo Andrade <pcpa@gnu.org>
* lib/jit_sparc-cpu.c, lib/jit_sparc-fpu.c, lib/jit_sparc.c:
Add base support to jit vararg functions to the sparc backend.
2015-06-20 Paulo Andrade <pcpa@gnu.org>
2015-05-20 Paulo Andrade <pcpa@gnu.org>
* lib/jit_alpha-cpu.c, lib/jit_alpha-fpu.c, lib/jit_alpha.c:
Add base support to jit vararg functions to the alpha backend.
2015-06-19 Paulo Andrade <pcpa@gnu.org>
2015-05-19 Paulo Andrade <pcpa@gnu.org>
* lib/jit_hppa-cpu.c, lib/jit_hppa-fpu.c, lib/jit_hppa.c:
Add base support to jit vararg functions to the hppa backend.
2015-06-10 Paulo Andrade <pcpa@gnu.org>
2015-05-10 Paulo Andrade <pcpa@gnu.org>
* lib/jit_ia64-cpu.c, lib/jit_ia64-fpu.c, lib/jit_ia64.c:
Add base support to jit vararg functions to the ia64 backend.
2015-06-10 Paulo Andrade <pcpa@gnu.org>
2015-05-10 Paulo Andrade <pcpa@gnu.org>
* lib/jit_ia64-fpu.c, lib/jit_ia64.c: Correct movi_d_w
and movi_f_w implementation to work when not using a
data buffer. This causes the check varargs.tst to
work when passing "-d" to the lightning test tool.
2015-06-10 Paulo Andrade <pcpa@gnu.org>
2015-05-10 Paulo Andrade <pcpa@gnu.org>
* lib/jit_ia64.c: Implement inline assembly cache flush,
required on multiprocessor systems.
2015-06-06 Paulo Andrade <pcpa@gnu.org>
2015-05-06 Paulo Andrade <pcpa@gnu.org>
* lib/jit_mips-cpu.c, lib/jit_mips-fpu.c, lib/jit_mips.c:
Add base support to jit vararg functions to the mips backend.
Currently only supported on the o32 abi, until access to a
n32 system is arranged.
2015-06-05 Paulo Andrade <pcpa@gnu.org>
2015-05-05 Paulo Andrade <pcpa@gnu.org>
* lib/jit_ppc-cpu.c, lib/jit_ppc-fpu.c, lib/jit_ppc.c:
Add base support to jit vararg functions to the PowerPC backend.
2015-06-02 Paulo Andrade <pcpa@gnu.org>
2015-05-02 Paulo Andrade <pcpa@gnu.org>
* lib/jit_s390-cpu.c, lib/jit_s390-fpu.c, lib/jit_s390.c:
Add base support to jit vararg functions to the s390 backend.
2015-06-01 Paulo Andrade <pcpa@gnu.org>
2015-05-01 Paulo Andrade <pcpa@gnu.org>
* lib/jit_arm-cpu.c, lib/jit_arm-swf.c, lib/jit_arm-vfp.c,
lib/jit_arm.c: Add base support to jit vararg
functions to the arm backend.
2015-05-30 Paulo Andrade <pcpa@gnu.org>
2015-04-30 Paulo Andrade <pcpa@gnu.org>
* lib/jit_aarch64-cpu.c, lib/jit_aarch64-fpu.c,
lib/jit_aarch64.c: Add base support to jit vararg
functions to the aarch64 backend.
2015-05-27 Paulo Andrade <pcpa@gnu.org>
2015-04-27 Paulo Andrade <pcpa@gnu.org>
* include/lightning.h, include/lightning/jit_private.h,
lib/jit_names.c, lib/lightning.c: Add initial support

View file

@ -154,11 +154,12 @@ typedef jit_int32_t jit_fpr_t;
# include <lightning/jit_alpha.h>
#endif
#define jit_flag_node 0x00000001 /* patch node not absolute */
#define jit_flag_patch 0x00000002 /* jump already patched */
#define jit_flag_data 0x00000004 /* data in the constant pool */
#define jit_flag_use 0x00000008 /* do not remove marker label */
#define jit_flag_head 0x00100000 /* label reached by normal flow */
#define jit_flag_node 0x0001 /* patch node not absolute */
#define jit_flag_patch 0x0002 /* jump already patched */
#define jit_flag_data 0x0004 /* data in the constant pool */
#define jit_flag_use 0x0008 /* do not remove marker label */
#define jit_flag_synth 0x0010 /* synthesized instruction */
#define jit_flag_head 0x1000 /* label reached by normal flow */
#define JIT_R(index) jit_r(index)
#define JIT_V(index) jit_v(index)
@ -200,14 +201,19 @@ typedef enum {
jit_code_prolog,
#define jit_ellipsis() _jit_ellipsis(_jit)
jit_code_ellipsis,
#define jit_allocai(u) _jit_allocai(_jit,u)
#define jit_allocar(u, v) _jit_allocar(_jit,u,v)
jit_code_allocai, jit_code_allocar,
#define jit_arg() _jit_arg(_jit)
jit_code_arg,
#define jit_getarg_c(u,v) _jit_getarg_c(_jit,u,v)
#define jit_getarg_uc(u,v) _jit_getarg_uc(_jit,u,v)
jit_code_getarg_c, jit_code_getarg_uc,
#define jit_getarg_s(u,v) _jit_getarg_s(_jit,u,v)
#define jit_getarg_us(u,v) _jit_getarg_us(_jit,u,v)
jit_code_getarg_s, jit_code_getarg_us,
#define jit_getarg_i(u,v) _jit_getarg_i(_jit,u,v)
#if __WORDSIZE == 32
# define jit_getarg(u,v) jit_getarg_i(u,v)
@ -216,9 +222,11 @@ typedef enum {
# define jit_getarg_ui(u,v) _jit_getarg_ui(_jit,u,v)
# define jit_getarg_l(u,v) _jit_getarg_l(_jit,u,v)
#endif
jit_code_getarg_i, jit_code_getarg_ui,
jit_code_getarg_l,
# define jit_putargr(u,v) _jit_putargr(_jit,u,v)
# define jit_putargi(u,v) _jit_putargi(_jit,u,v)
jit_code_arg,
jit_code_putargr, jit_code_putargi,
#define jit_va_start(u) jit_new_node_w(jit_code_va_start, u)
jit_code_va_start,
@ -532,17 +540,24 @@ typedef enum {
jit_code_callr, jit_code_calli,
#define jit_prepare() _jit_prepare(_jit)
jit_code_prepare,
#define jit_pushargr(u) _jit_pushargr(_jit,u)
#define jit_pushargi(u) _jit_pushargi(_jit,u)
jit_code_pushargr, jit_code_pushargi,
#define jit_finishr(u) _jit_finishr(_jit,u)
#define jit_finishi(u) _jit_finishi(_jit,u)
jit_code_finishr, jit_code_finishi,
#define jit_ret() _jit_ret(_jit)
jit_code_ret,
#define jit_retr(u) _jit_retr(_jit,u)
#define jit_reti(u) _jit_reti(_jit,u)
jit_code_retr, jit_code_reti,
#define jit_retval_c(u) _jit_retval_c(_jit,u)
#define jit_retval_uc(u) _jit_retval_uc(_jit,u)
jit_code_retval_c, jit_code_retval_uc,
#define jit_retval_s(u) _jit_retval_s(_jit,u)
#define jit_retval_us(u) _jit_retval_us(_jit,u)
jit_code_retval_s, jit_code_retval_us,
#define jit_retval_i(u) _jit_retval_i(_jit,u)
#if __WORDSIZE == 32
# define jit_retval(u) jit_retval_i(u)
@ -551,16 +566,19 @@ typedef enum {
# define jit_retval_ui(u) _jit_retval_ui(_jit,u)
# define jit_retval_l(u) _jit_retval_l(_jit,u)
#endif
/* Usually should not need to call directly, but useful if need
* to get a label just before a jit_prolog() call */
jit_code_retval_i, jit_code_retval_ui,
jit_code_retval_l,
#define jit_epilog() _jit_epilog(_jit)
jit_code_epilog,
#define jit_arg_f() _jit_arg_f(_jit)
jit_code_arg_f,
#define jit_getarg_f(u,v) _jit_getarg_f(_jit,u,v)
jit_code_getarg_f,
#define jit_putargr_f(u,v) _jit_putargr_f(_jit,u,v)
#define jit_putargi_f(u,v) _jit_putargi_f(_jit,u,v)
jit_code_arg_f,
jit_code_putargr_f, jit_code_putargi_f,
#define jit_addr_f(u,v,w) jit_new_node_www(jit_code_addr_f,u,v,w)
#define jit_addi_f(u,v,w) jit_new_node_wwf(jit_code_addi_f,u,v,w)
@ -699,15 +717,20 @@ typedef enum {
#define jit_pushargr_f(u) _jit_pushargr_f(_jit,u)
#define jit_pushargi_f(u) _jit_pushargi_f(_jit,u)
jit_code_pushargr_f, jit_code_pushargi_f,
#define jit_retr_f(u) _jit_retr_f(_jit,u)
#define jit_reti_f(u) _jit_reti_f(_jit,u)
jit_code_retr_f, jit_code_reti_f,
#define jit_retval_f(u) _jit_retval_f(_jit,u)
jit_code_retval_f,
#define jit_arg_d() _jit_arg_d(_jit)
jit_code_arg_d,
#define jit_getarg_d(u,v) _jit_getarg_d(_jit,u,v)
jit_code_getarg_d,
#define jit_putargr_d(u,v) _jit_putargr_d(_jit,u,v)
#define jit_putargi_d(u,v) _jit_putargi_d(_jit,u,v)
jit_code_arg_d,
jit_code_putargr_d, jit_code_putargi_d,
#define jit_addr_d(u,v,w) jit_new_node_www(jit_code_addr_d,u,v,w)
#define jit_addi_d(u,v,w) jit_new_node_wwd(jit_code_addi_d,u,v,w)
@ -847,9 +870,12 @@ typedef enum {
#define jit_pushargr_d(u) _jit_pushargr_d(_jit,u)
#define jit_pushargi_d(u) _jit_pushargi_d(_jit,u)
jit_code_pushargr_d, jit_code_pushargi_d,
#define jit_retr_d(u) _jit_retr_d(_jit,u)
#define jit_reti_d(u) _jit_reti_d(_jit,u)
jit_code_retr_d, jit_code_reti_d,
#define jit_retval_d(u) _jit_retval_d(_jit,u)
jit_code_retval_d,
/* Special internal backend specific codes */
jit_code_movr_w_f, jit_code_movr_ww_d, /* w* -> f|d */
@ -869,7 +895,6 @@ typedef enum {
#define jit_movr_d_w(u, v) jit_new_node_ww(jit_code_movr_d_w, u, v)
#define jit_movi_d_w(u, v) jit_new_node_wd(jit_code_movi_d_w, u, v)
jit_code_x86_retval_f, jit_code_x86_retval_d,
jit_code_last_code
} jit_code_t;
@ -994,6 +1019,12 @@ extern jit_node_t *_jit_new_node(jit_state_t*, jit_code_t);
#define jit_new_node_w(c,u) _jit_new_node_w(_jit,c,u)
extern jit_node_t *_jit_new_node_w(jit_state_t*, jit_code_t,
jit_word_t);
#define jit_new_node_f(c,u) _jit_new_node_f(_jit,c,u)
extern jit_node_t *_jit_new_node_f(jit_state_t*, jit_code_t,
jit_float32_t);
#define jit_new_node_d(c,u) _jit_new_node_d(_jit,c,u)
extern jit_node_t *_jit_new_node_d(jit_state_t*, jit_code_t,
jit_float64_t);
#define jit_new_node_p(c,u) _jit_new_node_p(_jit,c,u)
extern jit_node_t *_jit_new_node_p(jit_state_t*, jit_code_t,
jit_pointer_t);
@ -1003,6 +1034,12 @@ extern jit_node_t *_jit_new_node_ww(jit_state_t*,jit_code_t,
#define jit_new_node_wp(c,u,v) _jit_new_node_wp(_jit,c,u,v)
extern jit_node_t *_jit_new_node_wp(jit_state_t*,jit_code_t,
jit_word_t, jit_pointer_t);
#define jit_new_node_fp(c,u,v) _jit_new_node_fp(_jit,c,u,v)
extern jit_node_t *_jit_new_node_fp(jit_state_t*,jit_code_t,
jit_float32_t, jit_pointer_t);
#define jit_new_node_dp(c,u,v) _jit_new_node_dp(_jit,c,u,v)
extern jit_node_t *_jit_new_node_dp(jit_state_t*,jit_code_t,
jit_float64_t, jit_pointer_t);
#define jit_new_node_pw(c,u,v) _jit_new_node_pw(_jit,c,u,v)
extern jit_node_t *_jit_new_node_pw(jit_state_t*,jit_code_t,
jit_pointer_t, jit_word_t);

View file

@ -145,6 +145,70 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*,
(!jit_regset_tstbit(&_jitc->regarg, regno) && \
!jit_regset_tstbit(&_jitc->regsav, regno))
#define jit_inc_synth(code) \
do { \
(void)jit_new_node(jit_code_##code); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_w(code, u) \
do { \
(void)jit_new_node_w(jit_code_##code, u); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_f(code, u) \
do { \
(void)jit_new_node_f(jit_code_##code, u); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_d(code, u) \
do { \
(void)jit_new_node_d(jit_code_##code, u); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_ww(code, u, v) \
do { \
(void)jit_new_node_ww(jit_code_##code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_wp(code, u, v) \
do { \
(void)jit_new_node_wp(jit_code_##code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_fp(code, u, v) \
do { \
(void)jit_new_node_fp(jit_code_##code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_dp(code, u, v) \
do { \
(void)jit_new_node_dp(jit_code_##code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_dec_synth() jit_synth_dec()
#define jit_link_prolog() \
do { \
_jitc->tail->link = _jitc->function->prolog->link; \
_jitc->function->prolog->link = _jitc->tail; \
} while (0)
#define jit_link_prepare() \
do { \
_jitc->tail->link = _jitc->prepare->link; \
_jitc->prepare->link = _jitc->tail; \
} while (0)
#define jit_link_reverse(where) \
do { \
jit_node_t *tmp, *tail = 0; \
while (where) { \
tmp = (where)->link; \
(where)->link = tail; \
tail = where; \
where = tmp; \
} \
where = tail; \
} while (0);
/*
* Private jit_class bitmasks
*/
@ -173,11 +237,13 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*,
#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_a0_arg 0x00000080 /* arg1 is an argument int id */
#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_a1_arg 0x00008000 /* arg1 is an argument node */
#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 */
@ -301,14 +367,12 @@ struct jit_line {
struct jit_node {
jit_node_t *next;
jit_code_t code;
jit_int32_t flag;
jit_uint16_t flag;
jit_uint16_t offset; /* Used if DEVEL_DISASSEMBLER */
jit_data_t u;
jit_data_t v;
jit_data_t w;
jit_node_t *link;
#if DEVEL_DISASSEMBLER
jit_uword_t offset;
#endif
};
struct jit_block {
@ -347,6 +411,7 @@ struct jit_function {
jit_int32_t aoff;
jit_int32_t alen;
jit_int32_t call;
jit_int32_t argn; /* for debug output */
} self;
struct {
jit_int32_t argi;
@ -397,12 +462,13 @@ struct jit_compiler {
#endif
jit_node_t *head;
jit_node_t *tail;
jit_node_t *prepare; /* inside prepare/finish* block */
jit_uint32_t realize : 1; /* jit_realize() called? */
jit_uint32_t dataset : 1; /* jit_dataset() 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 */
jit_uint32_t synth : 8; /* emiting synthesized instructions */
#if DEBUG
jit_uint32_t getreg : 1;
#endif
@ -548,6 +614,9 @@ extern void jit_get_cpu(void);
#define jit_init() _jit_init(_jit)
extern void _jit_init(jit_state_t*);
#define jit_synth_inc() _jit_synth_inc(_jit)
extern void _jit_synth_inc(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);
@ -558,6 +627,9 @@ extern void _jit_link_node(jit_state_t*, jit_node_t*);
extern void
_jit_link_label(jit_state_t*,jit_node_t*);
#define jit_synth_dec() _jit_synth_dec(_jit)
extern void _jit_synth_dec(jit_state_t*);
#define jit_reglive(node) _jit_reglive(_jit, node)
extern void
_jit_reglive(jit_state_t*, jit_node_t*);

View file

@ -34,6 +34,7 @@ liblightning_la_SOURCES = \
lightning.c
EXTRA_DIST = \
jit_rewind.c \
jit_aarch64.c \
jit_aarch64-cpu.c \
jit_aarch64-fpu.c \

View file

@ -1,6 +1,6 @@
#if __WORDSIZE == 64
#define JIT_INSTR_MAX 64
#define JIT_INSTR_MAX 120
0, /* data */
0, /* live */
4, /* align */
@ -9,33 +9,45 @@
0, /* #name */
0, /* #note */
0, /* label */
64, /* prolog */
120, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
44, /* va_start */
64, /* va_arg */
72, /* va_arg_d */
0, /* va_end */
4, /* addr */
12, /* addi */
20, /* addi */
4, /* addcr */
12, /* addci */
4, /* addxr */
8, /* addxi */
4, /* subr */
16, /* subi */
20, /* subi */
4, /* subcr */
12, /* subci */
4, /* subxr */
8, /* subxi */
20, /* rsbi */
24, /* rsbi */
4, /* mulr */
12, /* muli */
20, /* muli */
12, /* qmulr */
20, /* qmuli */
12, /* qmulr_u */
20, /* qmuli_u */
4, /* divr */
12, /* divi */
20, /* divi */
4, /* divr_u */
12, /* divi_u */
20, /* qdivr */
@ -43,15 +55,15 @@
20, /* qdivr_u */
16, /* qdivi_u */
12, /* remr */
20, /* remi */
28, /* remi */
12, /* remr_u */
20, /* remi_u */
4, /* andr */
12, /* andi */
20, /* andi */
4, /* orr */
12, /* ori */
20, /* ori */
4, /* xorr */
12, /* xori */
20, /* xori */
4, /* lshr */
4, /* lshi */
4, /* rshr */
@ -106,19 +118,19 @@
4, /* ldr_l */
12, /* ldi_l */
8, /* ldxr_c */
8, /* ldxi_c */
20, /* ldxi_c */
4, /* ldxr_uc */
4, /* ldxi_uc */
20, /* ldxi_uc */
4, /* ldxr_s */
4, /* ldxi_s */
16, /* ldxi_s */
4, /* ldxr_us */
4, /* ldxi_us */
16, /* ldxi_us */
4, /* ldxr_i */
4, /* ldxi_i */
20, /* ldxi_i */
4, /* ldxr_ui */
4, /* ldxi_ui */
16, /* ldxi_ui */
4, /* ldxr_l */
4, /* ldxi_l */
20, /* ldxi_l */
4, /* str_c */
12, /* sti_c */
4, /* str_s */
@ -128,13 +140,13 @@
4, /* str_l */
12, /* sti_l */
4, /* stxr_c */
4, /* stxi_c */
20, /* stxi_c */
4, /* stxr_s */
4, /* stxi_s */
20, /* stxi_s */
4, /* stxr_i */
4, /* stxi_i */
20, /* stxi_i */
4, /* stxr_l */
4, /* stxi_l */
20, /* stxi_l */
8, /* bltr */
8, /* blti */
8, /* bltr_u */
@ -175,12 +187,30 @@
8, /* bxsubi */
8, /* bxsubr_u */
8, /* bxsubi_u */
0, /* jmpr */
4, /* jmpr */
20, /* jmpi */
4, /* callr */
20, /* calli */
64, /* epilog */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
96, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
12, /* addi_f */
4, /* subr_f */
@ -230,11 +260,11 @@
8, /* ldr_f */
16, /* ldi_f */
8, /* ldxr_f */
8, /* ldxi_f */
24, /* ldxi_f */
8, /* str_f */
16, /* sti_f */
8, /* stxr_f */
8, /* stxi_f */
24, /* stxi_f */
8, /* bltr_f */
16, /* blti_f */
8, /* bler_f */
@ -263,7 +293,15 @@
16, /* bordi_f */
8, /* bunordr_f */
16, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
12, /* addi_d */
4, /* subr_d */
@ -313,11 +351,11 @@
8, /* ldr_d */
16, /* ldi_d */
8, /* ldxr_d */
8, /* ldxi_d */
24, /* ldxi_d */
8, /* str_d */
16, /* sti_d */
8, /* stxr_d */
8, /* stxi_d */
24, /* stxi_d */
8, /* bltr_d */
16, /* blti_d */
8, /* bler_d */
@ -346,6 +384,11 @@
16, /* bordi_d */
8, /* bunordr_d */
16, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -355,6 +398,4 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */

View file

@ -177,6 +177,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
/* _no_link here does not mean the jit_link() call can be removed
* by rewriting as:
* _jitc->function->prolog = jit_new_node(jit_code_prolog);
*/
_jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset;
@ -201,6 +205,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
default: _jitc->function->self.aoff &= -8; break;
}
_jitc->function->self.aoff -= length;
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
return (_jitc->function->self.aoff);
}
@ -209,6 +217,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{
jit_int32_t r0, r1;
assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1;
@ -233,69 +242,82 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
#endif
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(r0);
jit_dec_synth();
}
void
_jit_ret(jit_state_t *_jit)
{
jit_node_t *instr;
assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */
instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr, u);
if (JIT_RET != u)
jit_movr(JIT_RET, u);
else
jit_live(JIT_RET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_f, u);
if (u != JIT_FRET)
jit_movr_f(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_inc_synth_f(reti_f, u);
jit_movi_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_d, u);
if (u != JIT_FRET)
jit_movr_d(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_inc_synth_d(reti_d, u);
jit_movi_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
@ -319,11 +341,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void
_jit_ellipsis(jit_state_t *_jit)
{
jit_inc_synth(ellipsis);
if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
}
else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
@ -344,12 +369,14 @@ _jit_ellipsis(jit_state_t *_jit)
else
_jitc->function->vafp = 0;
}
jit_dec_synth();
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs));
if (jit_arg_reg_p(_jitc->function->self.argi))
@ -358,13 +385,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
return (jit_new_node_w(jit_code_arg, offset));
node = jit_new_node_ww(jit_code_arg, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs));
if (jit_arg_f_reg_p(_jitc->function->self.argf))
@ -373,13 +404,17 @@ _jit_arg_f(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
return (jit_new_node_w(jit_code_arg_f, offset));
node = jit_new_node_ww(jit_code_arg_f, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs));
if (jit_arg_f_reg_p(_jitc->function->self.argf))
@ -388,87 +423,106 @@ _jit_arg_d(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
return (jit_new_node_w(jit_code_arg_d, offset));
node = jit_new_node_ww(jit_code_arg_d, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, JIT_RA0 - v->u.w);
else
jit_ldxi_c(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, JIT_RA0 - v->u.w);
else
jit_ldxi_uc(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, JIT_RA0 - v->u.w);
else
jit_ldxi_s(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, JIT_RA0 - v->u.w);
else
jit_ldxi_us(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_i(u, JIT_RA0 - v->u.w);
else
jit_ldxi_i(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, JIT_RA0 - v->u.w);
else
jit_ldxi_ui(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, JIT_RA0 - v->u.w);
else
jit_ldxi_l(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(JIT_RA0 - v->u.w, u);
else
jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -476,6 +530,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi(JIT_RA0 - v->u.w, u);
else {
@ -484,26 +539,31 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
jit_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr_f(u, JIT_FA0 - v->u.w);
else
jit_ldxi_f(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(JIT_FA0 - v->u.w, u);
else
jit_stxi_f(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -511,6 +571,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movi_f(JIT_FA0 - v->u.w, u);
else {
@ -519,26 +580,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
jit_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, JIT_FA0 - v->u.w);
else
jit_ldxi_d(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr_d(JIT_FA0 - v->u.w, u);
else
jit_stxi_d(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -546,6 +612,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi_d(JIT_FA0 - v->u.w, u);
else {
@ -554,12 +621,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -568,6 +638,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
jit_stxi(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
@ -575,6 +646,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -586,12 +659,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
@ -600,6 +676,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
@ -607,6 +684,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
@ -618,12 +697,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
@ -632,6 +714,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
@ -639,6 +722,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
@ -650,6 +735,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
jit_bool_t
@ -676,6 +762,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
node = jit_callr(r0);
@ -684,6 +771,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
}
jit_node_t *
@ -691,6 +779,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0);
@ -699,64 +788,83 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
return (node);
}
void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_c, r0);
jit_extr_c(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_uc, r0);
jit_extr_uc(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_s, r0);
jit_extr_s(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_us, r0);
jit_extr_us(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
jit_extr_i(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_ui, r0);
jit_extr_ui(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_l, r0);
if (r0 != JIT_RET)
jit_movr(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_f, r0);
if (r0 != JIT_FRET)
jit_movr_f(r0, JIT_FRET);
jit_dec_synth();
}
void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_d, r0);
if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
}
jit_pointer_t
@ -771,9 +879,15 @@ _emit_code(jit_state_t *_jit)
jit_node_t *node;
jit_uint8_t *data;
jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t const_offset;
jit_int32_t patch_offset;
} undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL;
@ -882,12 +996,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \
} \
break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end)
return (NULL);
#if DEVEL_DISASSEMBLER
node->offset = _jit->pc.w;
node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif
value = jit_classify(node->code);
jit_regarg_set(node, value);
@ -1293,6 +1411,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset;
restart_function:
_jitc->again = 0;
@ -1310,6 +1431,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset;
goto restart_function;
}
@ -1328,16 +1452,39 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_live: case jit_code_ellipsis:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i: case jit_code_getarg_ui:
case jit_code_getarg_l:
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
case jit_code_retval_ui: case jit_code_retval_l:
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
break;
default:
abort();
}
jit_regarg_clr(node, value);
assert(_jitc->regarg == 0);
assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */
jit_reglive(node);
}

View file

@ -10,7 +10,19 @@
0, /* #note */
0, /* label */
76, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
@ -179,8 +191,26 @@
36, /* jmpi */
8, /* callr */
36, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
68, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
8, /* addr_f */
32, /* addi_f */
8, /* subr_f */
@ -263,7 +293,15 @@
36, /* bordi_f */
12, /* bunordr_f */
36, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
8, /* addr_d */
28, /* addi_d */
8, /* subr_d */
@ -346,6 +384,11 @@
32, /* bordi_d */
12, /* bunordr_d */
32, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -355,6 +398,4 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */

View file

@ -177,6 +177,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
/* _no_link here does not mean the jit_link() call can be removed
* by rewriting as:
* _jitc->function->prolog = jit_new_node(jit_code_prolog);
*/
_jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset;
@ -201,6 +205,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
default: _jitc->function->self.aoff &= -8; break;
}
_jitc->function->self.aoff -= length;
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
return (_jitc->function->self.aoff);
}
@ -209,84 +217,95 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{
jit_int32_t reg;
assert(_jitc->function != NULL);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1;
}
reg = jit_get_reg(jit_class_gpr);
jit_negr(reg, v);
jit_andi(reg, reg, -8);
jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
jit_addr(u, u, reg);
jit_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg);
jit_dec_synth();
}
void
_jit_ret(jit_state_t *_jit)
{
jit_node_t *instr;
assert(_jitc->function != NULL);
jit_inc_synth(ret);
/* jump to epilog */
instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr, u);
if (JIT_RET != u)
jit_movr(JIT_RET, u);
else
jit_live(JIT_RET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_f, u);
if (u != JIT_FRET)
jit_movr_f(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_inc_synth_f(reti_f, u);
jit_movi_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_d, u);
if (u != JIT_FRET)
jit_movr_d(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_inc_synth_d(reti_d, u);
jit_movi_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
@ -310,11 +329,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void
_jit_ellipsis(jit_state_t *_jit)
{
jit_inc_synth(jit_code_ellipsis);
if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
}
else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
@ -322,12 +344,14 @@ _jit_ellipsis(jit_state_t *_jit)
_jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
_jitc->function->vagp = _jitc->function->self.argi;
}
jit_dec_synth();
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function != NULL);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -335,13 +359,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += 8;
}
return (jit_new_node_w(jit_code_arg, offset));
node = jit_new_node_ww(jit_code_arg, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function != NULL);
if (jit_arg_f_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -349,13 +377,17 @@ _jit_arg_f(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += 8;
}
return (jit_new_node_w(jit_code_arg_f, offset));
node = jit_new_node_ww(jit_code_arg_f, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function != NULL);
if (jit_arg_f_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -363,87 +395,106 @@ _jit_arg_d(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += 8;
}
return (jit_new_node_w(jit_code_arg_d, offset));
node = jit_new_node_ww(jit_code_arg_d, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _A0 - v->u.w);
else
jit_ldxi_c(u, _FP, v->u.w + C_DISP);
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _A0 - v->u.w);
else
jit_ldxi_uc(u, _FP, v->u.w + C_DISP);
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _A0 - v->u.w);
else
jit_ldxi_s(u, _FP, v->u.w + S_DISP);
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _A0 - v->u.w);
else
jit_ldxi_us(u, _FP, v->u.w + S_DISP);
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_i(u, _A0 - v->u.w);
else
jit_ldxi_i(u, _FP, v->u.w + I_DISP);
jit_dec_synth();
}
void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _A0 - v->u.w);
else
jit_ldxi_ui(u, _FP, v->u.w + I_DISP);
jit_dec_synth();
}
void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, _A0 - v->u.w);
else
jit_ldxi_l(u, _FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(_A0 - v->u.w, u);
else
jit_stxi(v->u.w, _FP, u);
jit_dec_synth();
}
void
@ -451,6 +502,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi(_A0 - v->u.w, u);
else {
@ -459,26 +511,31 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
jit_stxi(v->u.w, _FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(u, _F16 - v->u.w);
else
jit_ldxi_f(u, _FP, v->u.w + F_DISP);
jit_dec_synth();
}
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(_F16 - v->u.w, u);
else
jit_stxi_f(v->u.w, _FP, u + F_DISP);
jit_dec_synth();
}
void
@ -486,6 +543,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movi_f(_F16 - v->u.w, u);
else {
@ -494,26 +552,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
jit_stxi_f(v->u.w, _FP, regno + F_DISP);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, _F16 - v->u.w);
else
jit_ldxi_d(u, _FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(_F16 - v->u.w, u);
else
jit_stxi_d(v->u.w, _FP, u);
jit_dec_synth();
}
void
@ -521,6 +584,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movi_d(_F16 - v->u.w, u);
else {
@ -529,12 +593,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_stxi_d(v->u.w, _FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function != NULL);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_A0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -543,6 +610,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
jit_stxi(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += 8;
}
jit_dec_synth();
}
void
@ -550,6 +618,8 @@ _jit_pushargi(jit_state_t *_jit, jit_int64_t u)
{
jit_int32_t regno;
assert(_jitc->function != NULL);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_A0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -561,12 +631,15 @@ _jit_pushargi(jit_state_t *_jit, jit_int64_t u)
_jitc->function->call.size += 8;
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function != NULL);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
jit_movr_f(_F16 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -575,6 +648,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
jit_stxi_f(_jitc->function->call.size + F_DISP, JIT_SP, u);
_jitc->function->call.size += 8;
}
jit_dec_synth();
}
void
@ -582,6 +656,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{
jit_int32_t regno;
assert(_jitc->function != NULL);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
jit_movi_f(_F16 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -593,12 +669,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
_jitc->function->call.size += 8;
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function != NULL);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
jit_movr_d(_F16 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -607,6 +686,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += 8;
}
jit_dec_synth();
}
void
@ -614,6 +694,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{
jit_int32_t regno;
assert(_jitc->function != NULL);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
jit_movi_d(_F16 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -625,6 +707,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
_jitc->function->call.size += 8;
jit_unget_reg(regno);
}
jit_dec_synth();
}
jit_bool_t
@ -653,86 +736,106 @@ void
_jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{
jit_node_t *call;
assert(_jitc->function != NULL);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0);
call->v.w = call->w.w = _jitc->function->self.argi;
_jitc->function->call.argi = _jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
}
jit_node_t *
_jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{
jit_node_t *call;
assert(_jitc->function != NULL);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
call = jit_calli(i0);
call->v.w = call->w.w = _jitc->function->self.argf;
_jitc->function->call.argi = _jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
return (call);
}
void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_c, r0);
jit_extr_c(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_uc, r0);
jit_extr_uc(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_s, r0);
jit_extr_s(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_us, r0);
jit_extr_us(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
jit_extr_i(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_ui, r0);
jit_extr_ui(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_l, r0);
if (r0 != JIT_RET)
jit_movr(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_f, r0);
if (r0 != JIT_FRET)
jit_movr_f(r0, JIT_FRET);
jit_dec_synth();
}
void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_d, r0);
if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
}
jit_pointer_t
@ -747,9 +850,15 @@ _emit_code(jit_state_t *_jit)
jit_node_t *node;
jit_uint8_t *data;
jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t const_offset;
jit_int32_t patch_offset;
} undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL;
@ -841,12 +950,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \
} \
break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end)
return (NULL);
#if DEVEL_DISASSEMBLER
node->offset = _jit->pc.w;
node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif
value = jit_classify(node->code);
jit_regarg_set(node, value);
@ -1252,6 +1365,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset;
restart_function:
_jitc->again = 0;
@ -1269,6 +1385,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset;
goto restart_function;
}
@ -1287,10 +1406,33 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_live: case jit_code_ellipsis:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i: case jit_code_getarg_ui:
case jit_code_getarg_l:
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
case jit_code_retval_ui: case jit_code_retval_l:
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
break;
default:
abort();
@ -1311,6 +1453,7 @@ _emit_code(jit_state_t *_jit)
}
jit_regarg_clr(node, value);
assert(_jitc->regarg == (jit_carry == _NOREG) ? 0 : (1 << jit_carry));
assert(_jitc->synth == 0);
/* update register live state */
jit_reglive(node);
}

View file

@ -10,11 +10,23 @@
2, /* #name */
0, /* #note */
0, /* label */
26, /* prolog */
34, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
4, /* va_start */
8, /* va_arg */
16, /* va_arg_d */
0, /* va_end */
4, /* addr */
12, /* addi */
@ -176,12 +188,30 @@
8, /* bxsubi */
8, /* bxsubr_u */
8, /* bxsubi_u */
8, /* jmpr */
4, /* jmpr */
8, /* jmpi */
4, /* callr */
12, /* calli */
20, /* epilog */
20, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
24, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
8, /* addi_f */
4, /* subr_f */
@ -264,7 +294,15 @@
24, /* bordi_f */
12, /* bunordr_f */
24, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
20, /* addi_d */
4, /* subr_d */
@ -347,58 +385,73 @@
28, /* bordi_d */
12, /* bunordr_d */
28, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
4, /* movr_ww_d */
0, /* movr_w_d */
0, /* movr_f_w */
0, /* movi_f_w */
4, /* movr_d_ww */
10, /* movi_d_ww */
12, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __ARM_PCS_VFP */
#endif /* __WORDSIZE */
#if __WORDSIZE == 32
#if !defined(__ARM_PCS_VFP)
#define JIT_INSTR_MAX 90
#define JIT_INSTR_MAX 160
0, /* data */
0, /* live */
2, /* align */
0, /* save */
0, /* load */
0, /* #name */
2, /* #name */
0, /* #note */
0, /* label */
18, /* prolog */
30, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
4, /* va_start */
8, /* va_arg */
28, /* va_arg_d */
0, /* va_end */
4, /* addr */
8, /* addi */
12, /* addi */
4, /* addcr */
8, /* addci */
4, /* addxr */
4, /* addxi */
4, /* subr */
8, /* subi */
12, /* subi */
4, /* subcr */
8, /* subci */
4, /* subxr */
4, /* subxi */
12, /* rsbi */
4, /* mulr */
8, /* muli */
16, /* rsbi */
8, /* mulr */
12, /* muli */
4, /* qmulr */
12, /* qmuli */
4, /* qmulr_u */
8, /* qmuli_u */
40, /* divr */
44, /* divi */
48, /* divi */
40, /* divr_u */
44, /* divi_u */
34, /* qdivr */
@ -406,15 +459,15 @@
34, /* qdivr_u */
38, /* qdivi_u */
40, /* remr */
44, /* remi */
48, /* remi */
40, /* remr_u */
44, /* remi_u */
4, /* andr */
4, /* andi */
12, /* andi */
4, /* orr */
8, /* ori */
12, /* ori */
4, /* xorr */
8, /* xori */
12, /* xori */
4, /* lshr */
4, /* lshi */
4, /* rshr */
@ -445,10 +498,10 @@
14, /* nei */
4, /* movr */
8, /* movi */
4, /* extr_c */
8, /* extr_c */
4, /* extr_uc */
4, /* extr_s */
4, /* extr_us */
8, /* extr_s */
8, /* extr_us */
0, /* extr_i */
0, /* extr_ui */
20, /* htonr_us */
@ -469,15 +522,15 @@
0, /* ldr_l */
0, /* ldi_l */
4, /* ldxr_c */
4, /* ldxi_c */
12, /* ldxi_c */
4, /* ldxr_uc */
4, /* ldxi_uc */
12, /* ldxi_uc */
4, /* ldxr_s */
4, /* ldxi_s */
12, /* ldxi_s */
4, /* ldxr_us */
4, /* ldxi_us */
12, /* ldxi_us */
4, /* ldxr_i */
4, /* ldxi_i */
12, /* ldxi_i */
0, /* ldxr_ui */
0, /* ldxi_ui */
0, /* ldxr_l */
@ -491,11 +544,11 @@
0, /* str_l */
0, /* sti_l */
4, /* stxr_c */
4, /* stxi_c */
12, /* stxi_c */
4, /* stxr_s */
4, /* stxi_s */
12, /* stxi_s */
4, /* stxr_i */
4, /* stxi_i */
12, /* stxi_i */
0, /* stxr_l */
0, /* stxi_l */
8, /* bltr */
@ -538,95 +591,121 @@
8, /* bxsubi */
8, /* bxsubr_u */
8, /* bxsubi_u */
0, /* jmpr */
4, /* jmpi */
12, /* jmpr */
72, /* jmpi */
4, /* callr */
12, /* calli */
12, /* epilog */
20, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
160, /* epilog */
0, /* arg_f */
38, /* addr_f */
38, /* addi_f */
38, /* subr_f */
38, /* subi_f */
38, /* rsbi_f */
38, /* mulr_f */
38, /* muli_f */
38, /* divr_f */
38, /* divi_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
40, /* addr_f */
40, /* addi_f */
40, /* subr_f */
40, /* subi_f */
40, /* rsbi_f */
40, /* mulr_f */
40, /* muli_f */
40, /* divr_f */
40, /* divi_f */
12, /* negr_f */
12, /* absr_f */
34, /* sqrtr_f */
36, /* ltr_f */
40, /* lti_f */
36, /* ler_f */
40, /* lei_f */
36, /* eqr_f */
40, /* eqi_f */
36, /* ger_f */
40, /* gei_f */
36, /* gtr_f */
40, /* gti_f */
40, /* ner_f */
44, /* nei_f */
66, /* unltr_f */
74, /* unlti_f */
66, /* unler_f */
74, /* unlei_f */
66, /* uneqr_f */
74, /* uneqi_f */
66, /* unger_f */
74, /* ungei_f */
66, /* ungtr_f */
74, /* ungti_f */
70, /* ltgtr_f */
78, /* ltgti_f */
40, /* ordr_f */
44, /* ordi_f */
66, /* unordr_f */
74, /* unordi_f */
32, /* truncr_f_i */
36, /* sqrtr_f */
40, /* ltr_f */
44, /* lti_f */
40, /* ler_f */
44, /* lei_f */
40, /* eqr_f */
44, /* eqi_f */
40, /* ger_f */
44, /* gei_f */
40, /* gtr_f */
44, /* gti_f */
44, /* ner_f */
48, /* nei_f */
72, /* unltr_f */
80, /* unlti_f */
72, /* unler_f */
80, /* unlei_f */
72, /* uneqr_f */
80, /* uneqi_f */
72, /* unger_f */
80, /* ungei_f */
72, /* ungtr_f */
80, /* ungti_f */
76, /* ltgtr_f */
84, /* ltgti_f */
44, /* ordr_f */
48, /* ordi_f */
72, /* unordr_f */
80, /* unordi_f */
36, /* truncr_f_i */
0, /* truncr_f_l */
32, /* extr_f */
36, /* extr_f */
38, /* extr_d_f */
8, /* movr_f */
12, /* movi_f */
8, /* ldr_f */
16, /* ldi_f */
8, /* ldxr_f */
8, /* ldxi_f */
16, /* ldxi_f */
8, /* str_f */
16, /* sti_f */
8, /* stxr_f */
8, /* stxi_f */
40, /* bltr_f */
40, /* blti_f */
40, /* bler_f */
44, /* blei_f */
40, /* beqr_f */
44, /* beqi_f */
40, /* bger_f */
44, /* bgei_f */
40, /* bgtr_f */
44, /* bgti_f */
40, /* bner_f */
44, /* bnei_f */
40, /* bunltr_f */
44, /* bunlti_f */
40, /* bunler_f */
44, /* bunlei_f */
68, /* buneqr_f */
76, /* buneqi_f */
40, /* bunger_f */
44, /* bungei_f */
40, /* bungtr_f */
44, /* bungti_f */
68, /* bltgtr_f */
76, /* bltgti_f */
40, /* bordr_f */
44, /* bordi_f */
40, /* bunordr_f */
44, /* bunordi_f */
16, /* stxi_f */
44, /* bltr_f */
48, /* blti_f */
44, /* bler_f */
48, /* blei_f */
44, /* beqr_f */
52, /* beqi_f */
44, /* bger_f */
48, /* bgei_f */
44, /* bgtr_f */
48, /* bgti_f */
44, /* bner_f */
48, /* bnei_f */
44, /* bunltr_f */
48, /* bunlti_f */
44, /* bunler_f */
48, /* bunlei_f */
76, /* buneqr_f */
84, /* buneqi_f */
44, /* bunger_f */
48, /* bungei_f */
44, /* bungtr_f */
48, /* bungti_f */
76, /* bltgtr_f */
84, /* bltgti_f */
44, /* bordr_f */
48, /* bordi_f */
44, /* bunordr_f */
48, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
50, /* addr_d */
52, /* addi_d */
50, /* subr_d */
@ -640,33 +719,33 @@
20, /* absr_d */
42, /* sqrtr_d */
44, /* ltr_d */
46, /* lti_d */
48, /* lti_d */
44, /* ler_d */
46, /* lei_d */
48, /* lei_d */
44, /* eqr_d */
46, /* eqi_d */
48, /* eqi_d */
44, /* ger_d */
46, /* gei_d */
48, /* gei_d */
44, /* gtr_d */
46, /* gti_d */
48, /* gti_d */
48, /* ner_d */
50, /* nei_d */
52, /* nei_d */
82, /* unltr_d */
86, /* unlti_d */
88, /* unlti_d */
82, /* unler_d */
86, /* unlei_d */
88, /* unlei_d */
82, /* uneqr_d */
86, /* uneqi_d */
88, /* uneqi_d */
82, /* unger_d */
86, /* ungei_d */
88, /* ungei_d */
82, /* ungtr_d */
86, /* ungti_d */
88, /* ungti_d */
86, /* ltgtr_d */
90, /* ltgti_d */
92, /* ltgti_d */
48, /* ordr_d */
50, /* ordi_d */
52, /* ordi_d */
82, /* unordr_d */
86, /* unordi_d */
88, /* unordi_d */
36, /* truncr_d_i */
0, /* truncr_d_l */
36, /* extr_d */
@ -676,49 +755,52 @@
16, /* ldr_d */
24, /* ldi_d */
20, /* ldxr_d */
16, /* ldxi_d */
28, /* ldxi_d */
16, /* str_d */
24, /* sti_d */
20, /* stxr_d */
16, /* stxi_d */
28, /* stxi_d */
48, /* bltr_d */
50, /* blti_d */
52, /* blti_d */
48, /* bler_d */
50, /* blei_d */
52, /* blei_d */
48, /* beqr_d */
50, /* beqi_d */
60, /* beqi_d */
48, /* bger_d */
50, /* bgei_d */
52, /* bgei_d */
48, /* bgtr_d */
50, /* bgti_d */
52, /* bgti_d */
48, /* bner_d */
50, /* bnei_d */
52, /* bnei_d */
48, /* bunltr_d */
50, /* bunlti_d */
52, /* bunlti_d */
48, /* bunler_d */
50, /* bunlei_d */
52, /* bunlei_d */
84, /* buneqr_d */
88, /* buneqi_d */
92, /* buneqi_d */
48, /* bunger_d */
50, /* bungei_d */
52, /* bungei_d */
48, /* bungtr_d */
50, /* bungti_d */
52, /* bungti_d */
84, /* bltgtr_d */
88, /* bltgti_d */
92, /* bltgti_d */
48, /* bordr_d */
50, /* bordi_d */
52, /* bordi_d */
48, /* bunordr_d */
50, /* bunordi_d */
52, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
4, /* movr_w_f */
8, /* movr_ww_d */
0, /* movr_w_d */
6, /* movr_f_w */
8, /* movr_f_w */
8, /* movi_f_w */
12, /* movr_d_ww */
16, /* movr_d_ww */
12, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __ARM_PCS_VFP */
#endif /* __WORDSIZE */

View file

@ -59,6 +59,12 @@ typedef jit_pointer_t jit_va_list;
/*
* Prototypes
*/
#define jit_make_arg(node) _jit_make_arg(_jit,node)
static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*);
#define jit_make_arg_f(node) _jit_make_arg_f(_jit,node)
static jit_node_t *_jit_make_arg_f(jit_state_t*,jit_node_t*);
#define jit_make_arg_d(node) _jit_make_arg_d(_jit,node)
static jit_node_t *_jit_make_arg_d(jit_state_t*,jit_node_t*);
#define jit_get_reg_pair() _jit_get_reg_pair(_jit)
static jit_int32_t _jit_get_reg_pair(jit_state_t*);
#define jit_unget_reg_pair(rn) _jit_unget_reg_pair(_jit,rn)
@ -80,6 +86,7 @@ extern void __clear_cache(void *, void *);
#endif
#define PROTO 1
# include "jit_rewind.c"
# include "jit_arm-cpu.c"
# include "jit_arm-swf.c"
# include "jit_arm-vfp.c"
@ -250,6 +257,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
/* _no_link here does not mean the jit_link() call can be removed
* by rewriting as:
* _jitc->function->prolog = jit_new_node(jit_code_prolog);
*/
_jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset;
@ -274,6 +285,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
default: _jitc->function->self.aoff &= -8; break;
}
_jitc->function->self.aoff -= length;
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
return (_jitc->function->self.aoff);
}
@ -282,55 +297,59 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{
jit_int32_t reg;
assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1;
}
reg = jit_get_reg(jit_class_gpr);
jit_negr(reg, v);
jit_andi(reg, reg, -8);
jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
jit_addr(u, u, reg);
jit_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg);
jit_dec_synth();
}
void
_jit_ret(jit_state_t *_jit)
{
jit_node_t *instr;
assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */
instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr, u);
if (JIT_RET != u)
jit_movr(JIT_RET, u);
else
jit_live(JIT_RET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_f, u);
if (jit_cpu.abi) {
if (u != JIT_FRET)
jit_movr_f(JIT_FRET, u);
@ -344,21 +363,25 @@ _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
jit_live(JIT_RET);
}
jit_ret();
jit_dec_synth();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_inc_synth_f(reti_f, u);
if (jit_cpu.abi)
jit_movi_f(JIT_FRET, u);
else
jit_movi_f_w(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_d, u);
if (jit_cpu.abi) {
if (u != JIT_FRET)
jit_movr_d(JIT_FRET, u);
@ -372,16 +395,19 @@ _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
jit_live(JIT_RET);
}
jit_ret();
jit_dec_synth();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_inc_synth_d(reti_d, u);
if (jit_cpu.abi)
jit_movi_d(JIT_FRET, u);
else
jit_movi_d_ww(JIT_RET, _R1, u);
jit_ret();
jit_dec_synth();
}
void
@ -410,44 +436,30 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
return (jit_arg_reg_p(u->u.w));
}
void
_jit_ellipsis(jit_state_t *_jit)
static jit_node_t *
_jit_make_arg(jit_state_t *_jit, jit_node_t *node)
{
if (_jitc->prepare) {
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
}
else {
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
/* First 4 stack addresses are always spilled r0-r3 */
if (jit_arg_reg_p(_jitc->function->self.argi))
_jitc->function->vagp = _jitc->function->self.argi * 4;
else
_jitc->function->vagp = 16;
}
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
assert(_jitc->function);
jit_int32_t offset;
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else {
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
return (jit_new_node_w(jit_code_arg, offset));
if (node == (jit_node_t *)0)
node = jit_new_node(jit_code_arg);
else
link_node(node);
node->u.w = offset;
node->v.w = ++_jitc->function->self.argn;
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
_jit_make_arg_f(jit_state_t *_jit, jit_node_t *node)
{
jit_int32_t offset;
assert(_jitc->function);
jit_int32_t offset;
if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
if (jit_arg_f_reg_p(_jitc->function->self.argf)) {
offset = _jitc->function->self.argf++;
@ -463,14 +475,20 @@ _jit_arg_f(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float32_t);
done:
return (jit_new_node_w(jit_code_arg_f, offset));
if (node == (jit_node_t *)0)
node = jit_new_node(jit_code_arg_f);
else
link_node(node);
node->u.w = offset;
node->v.w = ++_jitc->function->self.argn;
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
_jit_make_arg_d(jit_state_t *_jit, jit_node_t *node)
{
jit_int32_t offset;
assert(_jitc->function);
jit_int32_t offset;
if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
if (jit_arg_d_reg_p(_jitc->function->self.argf)) {
if (_jitc->function->self.argf & 1)
@ -494,79 +512,147 @@ _jit_arg_d(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t);
done:
return (jit_new_node_w(jit_code_arg_d, offset));
if (node == (jit_node_t *)0)
node = jit_new_node(jit_code_arg_d);
else
link_node(node);
node->u.w = offset;
node->v.w = ++_jitc->function->self.argn;
jit_link_prolog();
return (node);
}
void
_jit_ellipsis(jit_state_t *_jit)
{
if (_jitc->prepare) {
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
if (jit_cpu.abi && _jitc->function->call.argf)
rewind_prepare();
}
else {
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
if (jit_cpu.abi && _jitc->function->self.argf)
rewind_prolog();
/* First 4 stack addresses are always spilled r0-r3 */
if (jit_arg_reg_p(_jitc->function->self.argi))
_jitc->function->vagp = _jitc->function->self.argi * 4;
else
_jitc->function->vagp = 16;
}
jit_inc_synth(ellipsis);
if (_jitc->prepare)
jit_link_prepare();
else
jit_link_prolog();
jit_dec_synth();
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
assert(_jitc->function);
return (jit_make_arg((jit_node_t*)0));
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
assert(_jitc->function);
return (jit_make_arg_f((jit_node_t*)0));
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
assert(_jitc->function);
return (jit_make_arg_d((jit_node_t*)0));
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_swf_p())
jit_ldxi_c(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, JIT_RA0 - v->u.w);
else
jit_ldxi_c(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_swf_p())
jit_ldxi_uc(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, JIT_RA0 - v->u.w);
else
jit_ldxi_uc(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_swf_p())
jit_ldxi_s(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, JIT_RA0 - v->u.w);
else
jit_ldxi_s(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_swf_p())
jit_ldxi_us(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, JIT_RA0 - v->u.w);
else
jit_ldxi_us(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_swf_p())
jit_ldxi_i(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_movr(u, JIT_RA0 - v->u.w);
else
jit_ldxi_i(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_swf_p())
jit_stxi(arg_offset(v->u.w), JIT_FP, u);
else if (jit_arg_reg_p(v->u.w))
jit_movr(JIT_RA0 - v->u.w, u);
else
jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -574,6 +660,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_swf_p()) {
regno = jit_get_reg(jit_class_gpr);
jit_movi(regno, u);
@ -588,13 +675,15 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
jit_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
if (jit_cpu.abi) {
jit_inc_synth_wp(getarg_f, u, v);
if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(u, JIT_FA0 - v->u.w);
else
@ -608,12 +697,14 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
else
jit_ldxi_f(u, JIT_FP, v->u.w);
}
jit_dec_synth();
}
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_cpu.abi) {
if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(JIT_FA0 - v->u.w, u);
@ -628,6 +719,7 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
else
jit_stxi_f(v->u.w, JIT_FP, u);
}
jit_dec_synth();
}
void
@ -635,6 +727,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_cpu.abi) {
if (jit_arg_f_reg_p(v->u.w))
jit_movi_f(JIT_FA0 - v->u.w, u);
@ -660,13 +753,15 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
jit_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
if (jit_cpu.abi) {
jit_inc_synth_wp(getarg_d, u, v);
if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, JIT_FA0 - v->u.w);
else
@ -680,12 +775,14 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
else
jit_ldxi_d(u, JIT_FP, v->u.w);
}
jit_dec_synth();
}
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_cpu.abi) {
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(JIT_FA0 - v->u.w, u);
@ -700,6 +797,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
else
jit_stxi_d(v->u.w, JIT_FP, u);
}
jit_dec_synth();
}
void
@ -707,6 +805,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_cpu.abi) {
if (jit_arg_f_reg_p(v->u.w))
jit_movi_d(JIT_FA0 - v->u.w, u);
@ -732,12 +831,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -746,6 +848,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
jit_stxi(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
@ -753,6 +856,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -764,28 +869,33 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
return;
goto done;
}
}
else {
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr_f_w(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
return;
goto done;
}
}
jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
done:
jit_dec_synth();
}
void
@ -793,6 +903,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
/* cannot jit_movi_f in the argument register because
@ -804,14 +916,14 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_movr_f(JIT_FA0 - _jitc->function->call.argf, regno);
jit_unget_reg(regno);
++_jitc->function->call.argf;
return;
goto done;
}
}
else {
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi_f_w(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
return;
goto done;
}
}
regno = jit_get_reg(jit_class_fpr);
@ -819,19 +931,23 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t);
done:
jit_dec_synth();
}
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
if (jit_arg_d_reg_p(_jitc->function->call.argf)) {
if (_jitc->function->call.argf & 1)
++_jitc->function->call.argf;
jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
_jitc->function->call.argf += 2;
return;
goto done;
}
}
else {
@ -842,13 +958,15 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
JIT_RA0 - (_jitc->function->call.argi + 1),
u);
_jitc->function->call.argi += 2;
return;
goto done;
}
}
if (_jitc->function->call.size & 7)
_jitc->function->call.size += 4;
jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float64_t);
done:
jit_dec_synth();
}
void
@ -856,13 +974,15 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
if (jit_arg_d_reg_p(_jitc->function->call.argf)) {
if (_jitc->function->call.argf & 1)
++_jitc->function->call.argf;
jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
_jitc->function->call.argf += 2;
return;
goto done;
}
}
else {
@ -873,7 +993,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
JIT_RA0 - (_jitc->function->call.argi + 1),
u);
_jitc->function->call.argi += 2;
return;
goto done;
}
}
if (_jitc->function->call.size & 7)
@ -883,6 +1003,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_float64_t);
done:
jit_dec_synth();
}
jit_bool_t
@ -909,6 +1031,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
node = jit_callr(r0);
@ -917,6 +1040,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
}
jit_node_t *
@ -924,6 +1048,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0);
@ -932,60 +1057,75 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
return (node);
}
void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_c, r0);
jit_extr_c(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_uc, r0);
jit_extr_uc(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_s, r0);
jit_extr_s(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_us, r0);
jit_extr_us(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
if (r0 != JIT_RET)
jit_movr(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_f, r0);
if (jit_cpu.abi) {
if (r0 != JIT_FRET)
jit_movr_f(r0, JIT_FRET);
}
else if (r0 != JIT_RET)
jit_movr_w_f(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_d, r0);
if (jit_cpu.abi) {
if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET);
}
else if (r0 != JIT_RET)
jit_movr_ww_d(r0, JIT_RET, _R1);
jit_dec_synth();
}
jit_pointer_t
@ -1000,6 +1140,9 @@ _emit_code(jit_state_t *_jit)
jit_node_t *node;
jit_uint8_t *data;
jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_uword_t thumb;
#if DISASSEMBLER
jit_int32_t info_offset;
@ -1007,12 +1150,18 @@ _emit_code(jit_state_t *_jit)
jit_int32_t const_offset;
jit_int32_t patch_offset;
} undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL;
_jitc->thumb = 0;
jit_reglive_setup();
_jitc->consts.data = NULL;
_jitc->consts.offset = _jitc->consts.length = 0;
undo.word = 0;
undo.node = NULL;
undo.data = NULL;
@ -1228,12 +1377,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \
} \
break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end)
return (NULL);
#if DEVEL_DISASSEMBLER
node->offset = _jit->pc.w;
node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif
value = jit_classify(node->code);
jit_regarg_set(node, value);
@ -1634,6 +1787,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.data = _jitc->consts.data;
undo.thumb = _jitc->thumb;
undo.const_offset = _jitc->consts.offset;
@ -1658,6 +1814,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
invalidate_consts();
_jitc->consts.data = undo.data;
_jitc->thumb = undo.thumb;
@ -1726,16 +1885,37 @@ _emit_code(jit_state_t *_jit)
else
vfp_vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_live: case jit_code_ellipsis:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i:
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
break;
default:
abort();
}
jit_regarg_clr(node, value);
assert(_jitc->regarg == 0);
assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */
jit_reglive(node);
@ -1807,6 +1987,7 @@ _emit_code(jit_state_t *_jit)
}
#define CODE 1
# include "jit_rewind.c"
# include "jit_arm-cpu.c"
# include "jit_arm-swf.c"
# include "jit_arm-vfp.c"

View file

@ -329,6 +329,7 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length)
char buffer[address_buffer_length];
#if DEVEL_DISASSEMBLER
jit_node_t *node;
jit_uword_t prevw;
#endif
#if __arm__
@ -343,14 +344,18 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length)
disasm_jit = _jit;
#if DEVEL_DISASSEMBLER
node = _jitc->head;
prevw = pc;
#endif
while (pc < end) {
#if DEVEL_DISASSEMBLER
while (node && node->offset < (jit_uword_t)pc)
while (node && (jit_uword_t)(prevw + node->offset) < (jit_uword_t)pc) {
prevw += node->offset;
node = node->next;
while (node && node->offset == (jit_uword_t)pc) {
}
while (node && (jit_uword_t)(prevw + node->offset) == (jit_uword_t)pc) {
jit_print_node(node);
fputc('\n', stdout);
prevw += node->offset;
node = node->next;
}
#endif

View file

@ -10,7 +10,19 @@
0, /* #note */
0, /* label */
64, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
@ -179,8 +191,26 @@
12, /* jmpi */
40, /* callr */
44, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
64, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
16, /* addi_f */
4, /* subr_f */
@ -263,7 +293,15 @@
28, /* bordi_f */
16, /* bunordr_f */
28, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
24, /* addi_d */
4, /* subr_d */
@ -346,6 +384,11 @@
36, /* bordi_d */
16, /* bunordr_d */
36, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -355,6 +398,4 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */

View file

@ -163,6 +163,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
/* _no_link here does not mean the jit_link() call can be removed
* by rewriting as:
* _jitc->function->prolog = jit_new_node(jit_code_prolog);
*/
_jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset;
@ -194,6 +198,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
_jitc->function->self.aoff = (_jitc->function->self.aoff + 7) & -8;
break;
}
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
offset = _jitc->function->self.aoff;
_jitc->function->self.aoff += length;
return (offset);
@ -204,6 +212,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{
jit_int32_t reg;
assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1;
@ -215,60 +224,73 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
jit_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg);
jit_dec_synth();
}
void
_jit_ret(jit_state_t *_jit)
{
jit_node_t *instr;
assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */
instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr, u);
jit_movr(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_f, u);
jit_movr_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_inc_synth_f(reti_f, u);
jit_movi_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_d, u);
jit_movr_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_inc_synth_d(reti_d, u);
jit_movi_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
@ -291,48 +313,61 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void
_jit_ellipsis(jit_state_t *_jit)
{
jit_inc_synth(ellipsis);
if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
}
else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
_jitc->function->vagp = _jitc->function->self.argi;
}
jit_dec_synth();
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
_jitc->function->self.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else
offset = _jitc->function->self.size;
return (jit_new_node_w(jit_code_arg, offset));
node = jit_new_node_ww(jit_code_arg, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
_jitc->function->self.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else
offset = _jitc->function->self.size;
return (jit_new_node_w(jit_code_arg_f, offset));
node = jit_new_node_ww(jit_code_arg_f, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (_jitc->function->self.argi & 1) {
++_jitc->function->self.argi;
@ -349,67 +384,82 @@ _jit_arg_d(jit_state_t *_jit)
_jitc->function->self.size -= sizeof(jit_word_t);
offset = _jitc->function->self.size;
}
return (jit_new_node_w(jit_code_arg_d, offset));
node = jit_new_node_ww(jit_code_arg_d, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (v->u.w >= 0)
jit_extr_c(u, _R26 - v->u.w);
else
jit_ldxi_c(u, JIT_FP, v->u.w + 3);
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (v->u.w >= 0)
jit_extr_uc(u, _R26 - v->u.w);
else
jit_ldxi_uc(u, JIT_FP, v->u.w + 3);
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (v->u.w >= 0)
jit_extr_s(u, _R26 - v->u.w);
else
jit_ldxi_s(u, JIT_FP, v->u.w + 2);
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (v->u.w >= 0)
jit_extr_us(u, _R26 - v->u.w);
else
jit_ldxi_us(u, JIT_FP, v->u.w + 2);
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (v->u.w >= 0)
jit_movr(u, _R26 - v->u.w);
else
jit_ldxi_i(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (v->u.w >= 0)
jit_movr(_R26 - v->u.w, u);
else
jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -417,6 +467,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (v->u.w >= 0)
jit_movi(_R26 - v->u.w, u);
else {
@ -425,26 +476,31 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
jit_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (v->u.w >= 0)
jit_movr_f(u, _F4 - v->u.w);
else
jit_ldxi_f(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (v->u.w >= 0)
jit_movr_f(_F4 - v->u.w, u);
else
jit_stxi_f(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -452,6 +508,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (v->u.w >= 0)
jit_movi_f(_R26 - v->u.w, u);
else {
@ -460,26 +517,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
jit_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (v->u.w >= 0)
jit_movr_d(u, _F4 - v->u.w);
else
jit_ldxi_d(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (v->u.w >= 0)
jit_movr_d(_F4 - v->u.w, u);
else
jit_stxi_d(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -487,6 +549,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (v->u.w >= 0)
jit_movi_d(_R26 - v->u.w, u);
else {
@ -495,12 +558,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_R26 - _jitc->function->call.argi, u);
@ -508,6 +574,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
}
else
jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
jit_dec_synth();
}
void
@ -515,6 +582,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_R26 - _jitc->function->call.argi, u);
@ -526,12 +595,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr_f(_F4 - _jitc->function->call.argi, u);
@ -548,6 +620,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
}
else
jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, u);
jit_dec_synth();
}
void
@ -555,6 +628,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi_f(_F4 - _jitc->function->call.argi, u);
@ -576,12 +651,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_float64_t);
if (_jitc->function->call.argi & 1) {
++_jitc->function->call.argi;
@ -608,6 +686,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
_jitc->function->call.size -= sizeof(jit_word_t);
jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
}
jit_dec_synth();
}
void
@ -615,6 +694,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_float64_t);
if (_jitc->function->call.argi & 1) {
++_jitc->function->call.argi;
@ -644,6 +725,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
jit_bool_t
@ -671,12 +753,14 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{
jit_node_t *call;
assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen > _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0);
call->v.w = call->w.w = _jitc->function->call.argi;
_jitc->function->call.argi = _jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
}
jit_node_t *
@ -684,55 +768,71 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen > _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0);
node->v.w = node->w.w = _jitc->function->call.argi;
_jitc->function->call.argi = _jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
return (node);
}
void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_c, r0);
jit_extr_c(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_uc, r0);
jit_extr_uc(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_s, r0);
jit_extr_s(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_us, r0);
jit_extr_us(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
jit_movr(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_f, r0);
jit_movr_f(r0, JIT_FRET);
jit_dec_synth();
}
void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_d, r0);
jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
}
jit_pointer_t
@ -746,8 +846,14 @@ _emit_code(jit_state_t *_jit)
struct {
jit_node_t *node;
jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset;
} undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL;
@ -840,12 +946,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \
} \
break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end)
return (NULL);
#if DEVEL_DISASSEMBLER
node->offset = _jit->pc.w;
node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif
value = jit_classify(node->code);
jit_regarg_set(node, value);
@ -1234,6 +1344,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset;
restart_function:
_jitc->again = 0;
@ -1251,6 +1364,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset;
goto restart_function;
}
@ -1270,15 +1386,36 @@ _emit_code(jit_state_t *_jit)
vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_arg:
case jit_code_arg: case jit_code_ellipsis:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i:
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
break;
default:
abort();
}
jit_regarg_clr(node, value);
assert(_jitc->regarg == 0);
assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */
jit_reglive(node);
}

View file

@ -10,7 +10,19 @@
16, /* #note */
48, /* label */
128, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
@ -179,8 +191,26 @@
48, /* jmpi */
32, /* callr */
64, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
144, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
0, /* addr_f */
32, /* addi_f */
16, /* subr_f */
@ -263,7 +293,15 @@
64, /* bordi_f */
32, /* bunordr_f */
64, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
0, /* addr_d */
32, /* addi_d */
16, /* subr_d */
@ -346,6 +384,11 @@
64, /* bordi_d */
32, /* bunordr_d */
64, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -355,6 +398,4 @@
0, /* movi_d_ww */
16, /* movr_d_w */
32, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */

View file

@ -277,6 +277,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
/* _no_link here does not mean the jit_link() call can be removed
* by rewriting as:
* _jitc->function->prolog = jit_new_node(jit_code_prolog);
*/
_jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset;
@ -301,6 +305,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
default: _jitc->function->self.aoff &= -8; break;
}
_jitc->function->self.aoff -= length;
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
return (_jitc->function->self.aoff);
}
@ -309,75 +317,86 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{
jit_int32_t reg;
assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1;
}
reg = jit_get_reg(jit_class_gpr);
jit_negr(reg, v);
jit_andi(reg, reg, -16);
jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
jit_addr(u, u, reg);
jit_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg);
jit_dec_synth();
}
void
_jit_ret(jit_state_t *_jit)
{
jit_node_t *instr;
assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */
instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr, u);
jit_movr(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_f, u);
jit_movr_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_inc_synth_f(reti_f, u);
jit_movi_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_d, u);
jit_movr_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_inc_synth_d(reti_d, u);
jit_movi_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
@ -400,11 +419,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void
_jit_ellipsis(jit_state_t *_jit)
{
jit_inc_synth(ellipsis);
if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
}
else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
@ -413,13 +435,14 @@ _jit_ellipsis(jit_state_t *_jit)
_jitc->function->vagp = _jitc->function->self.argi;
}
jit_dec_synth();
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -427,14 +450,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
return (jit_new_node_w(jit_code_arg, offset));
node = jit_new_node_ww(jit_code_arg, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -442,14 +468,17 @@ _jit_arg_f(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
return (jit_new_node_w(jit_code_arg_f, offset));
node = jit_new_node_ww(jit_code_arg_f, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -457,87 +486,106 @@ _jit_arg_d(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
return (jit_new_node_w(jit_code_arg_d, offset));
node = jit_new_node_ww(jit_code_arg_d, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _R32 + v->u.w);
else
jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP);
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _R32 + v->u.w);
else
jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP);
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _R32 + v->u.w);
else
jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP);
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _R32 + v->u.w);
else
jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP);
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_i(u, _R32 + v->u.w);
else
jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP);
jit_dec_synth();
}
void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _R32 + v->u.w);
else
jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP);
jit_dec_synth();
}
void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, _R32 + v->u.w);
else
jit_ldxi(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(_R32 + v->u.w, u);
else
jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -545,6 +593,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi(_R32 + v->u.w, u);
else {
@ -553,26 +602,31 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
jit_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr_f(u, _F8 + v->u.w);
else
jit_ldxi_f(u, JIT_FP, v->u.w + F_DISP);
jit_dec_synth();
}
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr_f(_F8 + v->u.w, u);
else
jit_stxi_f(v->u.w, JIT_FP, u + F_DISP);
jit_dec_synth();
}
void
@ -580,6 +634,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi_f(_F8 + v->u.w, u);
else {
@ -588,26 +643,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
jit_stxi_f(v->u.w, JIT_FP, regno + F_DISP);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr_d(u, _F8 + v->u.w);
else
jit_ldxi_d(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr_d(_F8 + v->u.w, u);
else
jit_stxi_d(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -615,6 +675,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi_d(_F8 + v->u.w, u);
else {
@ -623,12 +684,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_OUT0 + _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -637,6 +701,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
@ -644,6 +709,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_OUT0 + _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -655,12 +722,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
_jitc->function->call.size += sizeof(jit_word_t);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs))
jit_movr_f(_F8 + _jitc->function->call.argi, u);
@ -673,6 +743,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
@ -680,6 +751,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs))
jit_movi_f(_F8 + _jitc->function->call.argi, u);
@ -695,12 +768,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
_jitc->function->call.size += sizeof(jit_word_t);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs))
jit_movr_d(_F8 + _jitc->function->call.argi, u);
@ -712,6 +788,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
@ -719,6 +796,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs))
jit_movi_d(_F8 + _jitc->function->call.argi, u);
@ -733,6 +812,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
_jitc->function->call.size += sizeof(jit_word_t);
jit_unget_reg(regno);
}
jit_dec_synth();
}
jit_bool_t
@ -747,6 +827,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{
jit_node_t *call;
assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0);
@ -755,6 +836,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
}
jit_node_t *
@ -762,6 +844,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0);
@ -770,61 +853,80 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
return (node);
}
void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_c, r0);
jit_extr_c(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_uc, r0);
jit_extr_uc(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_s, r0);
jit_extr_s(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_us, r0);
jit_extr_us(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
jit_extr_i(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_ui, r0);
jit_extr_ui(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_l, r0);
jit_movr(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_l, r0);
jit_movr_f(r0, JIT_FRET);
jit_dec_synth();
}
void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_d, r0);
jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
}
jit_pointer_t
@ -838,9 +940,15 @@ _emit_code(jit_state_t *_jit)
struct {
jit_node_t *node;
jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset;
jit_word_t prolog_offset;
} undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL;
@ -855,6 +963,9 @@ _emit_code(jit_state_t *_jit)
undo.node = NULL;
undo.patch_offset = 0;
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
undo.prolog_offset = 0;
for (node = _jitc->head; node; node = node->next)
if (node->code != jit_code_label &&
@ -961,7 +1072,8 @@ _emit_code(jit_state_t *_jit)
#endif
#if DEVEL_DISASSEMBLER
sync();
node->offset = _jit->pc.w;
node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif
jit_regarg_set(node, value);
switch (node->code) {
@ -1368,6 +1480,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset;
undo.prolog_offset = _jitc->prolog.offset;
restart_function:
@ -1403,6 +1518,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset;
_jitc->prolog.offset = undo.prolog_offset;
_jitc->ioff = 0;
@ -1429,9 +1547,32 @@ _emit_code(jit_state_t *_jit)
vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_arg:
case jit_code_arg: case jit_code_ellipsis:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i: case jit_code_getarg_ui:
case jit_code_getarg_l:
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
case jit_code_retval_ui: case jit_code_retval_l:
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
break;
case jit_code_movr_f_w:
movr_f_w(rn(node->u.w), rn(node->v.w));
@ -1472,6 +1613,7 @@ _emit_code(jit_state_t *_jit)
assert(jit_regset_scan1(&_jitc->regarg, 0) == jit_carry);
assert(jit_regset_scan1(&_jitc->regarg, jit_carry + 1) == ULONG_MAX);
}
assert(_jitc->synth == 0);
/* update register live state */
jit_reglive(node);
}

View file

@ -2956,7 +2956,7 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
}
if (_jitc->function->self.call & jit_call_varargs) {
index = _jitc->function->vagp;
index = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT;
offset = stack_framesize + index * sizeof(jit_word_t);
for (; jit_arg_reg_p(index); ++index, offset += sizeof(jit_word_t))
stxi(offset, _BP_REGNO, rn(_A0 - index));
@ -2993,41 +2993,19 @@ _epilog(jit_state_t *_jit, jit_node_t *node)
static void
_vastart(jit_state_t *_jit, jit_int32_t r0)
{
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs);
/* Return jit_va_list_t in the register argument */
addi(r0, _BP_REGNO, _jitc->function->vaoff);
reg = jit_get_reg(jit_class_gpr);
/* Initialize stack pointer to the first stack argument. */
addi(rn(reg), _BP_REGNO, stack_framesize +
_jitc->function->vagp * sizeof(jit_word_t));
stxi(offsetof(jit_va_list_t, stack), r0, rn(reg));
jit_unget_reg(reg);
/* Initialize va_list to the first stack argument. */
addi(r0, _BP_REGNO, _jitc->function->self.size);
}
static void
_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs);
reg = jit_get_reg(jit_class_gpr);
/* Load varargs stack pointer. */
ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack));
/* Load argument. */
ldr(r0, rn(reg));
ldr(r0, r1);
/* Update vararg stack pointer. */
addi(rn(reg), rn(reg), sizeof(jit_word_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
jit_unget_reg(reg);
/* Update va_list. */
addi(r1, r1, sizeof(jit_word_t));
}
static void

View file

@ -1780,28 +1780,19 @@ dbopi(unord)
static void
_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg, aln;
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs);
reg = jit_get_reg(jit_class_gpr);
/* Load varargs stack pointer. */
ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack));
/* Align, if required. */
aln = jit_get_reg(jit_class_gpr);
andi(rn(aln), rn(reg), 7);
addr(rn(reg), rn(reg), rn(aln));
jit_unget_reg(aln);
reg = jit_get_reg(jit_class_gpr);
andi(rn(reg), r1, 7);
addr(r1, r1, rn(reg));
jit_unget_reg(reg);
/* Load argument. */
ldr_d(r0, rn(reg));
ldr_d(r0, r1);
/* Update vararg stack pointer. */
addi(rn(reg), rn(reg), sizeof(jit_float64_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
jit_unget_reg(reg);
/* Update va_list. */
addi(r1, r1, sizeof(jit_float64_t));
}
# undef fopi

View file

@ -11,7 +11,19 @@
0, /* #note */
0, /* label */
44, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
@ -180,8 +192,26 @@
8, /* jmpi */
12, /* callr */
16, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
44, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
16, /* addi_f */
4, /* subr_f */
@ -264,7 +294,15 @@
24, /* bordi_f */
12, /* bunordr_f */
24, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
16, /* addi_d */
4, /* subr_d */
@ -347,6 +385,11 @@
24, /* bordi_d */
12, /* bunordr_d */
24, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -356,14 +399,12 @@
0, /* movi_d_ww */
4, /* movr_d_w */
12, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* NEW_ABI */
#endif /* __WORDSIZE */
#if __WORDSIZE == 32
#if !NEW_ABI
#define JIT_INSTR_MAX 96
#define JIT_INSTR_MAX 116
0, /* data */
0, /* live */
0, /* align */
@ -372,11 +413,23 @@
0, /* #name */
0, /* #note */
0, /* label */
96, /* prolog */
116, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
4, /* va_start */
8, /* va_arg */
20, /* va_arg_d */
0, /* va_end */
4, /* addr */
12, /* addi */
@ -469,15 +522,15 @@
0, /* ldr_l */
0, /* ldi_l */
8, /* ldxr_c */
4, /* ldxi_c */
16, /* ldxi_c */
8, /* ldxr_uc */
4, /* ldxi_uc */
16, /* ldxi_uc */
8, /* ldxr_s */
4, /* ldxi_s */
16, /* ldxi_s */
8, /* ldxr_us */
4, /* ldxi_us */
16, /* ldxi_us */
8, /* ldxr_i */
4, /* ldxi_i */
16, /* ldxi_i */
0, /* ldxr_ui */
0, /* ldxi_ui */
0, /* ldxr_l */
@ -491,11 +544,11 @@
0, /* str_l */
0, /* sti_l */
8, /* stxr_c */
4, /* stxi_c */
16, /* stxi_c */
8, /* stxr_s */
4, /* stxi_s */
16, /* stxi_s */
8, /* stxr_i */
4, /* stxi_i */
16, /* stxi_i */
0, /* stxr_l */
0, /* stxi_l */
12, /* bltr */
@ -538,12 +591,30 @@
28, /* bxsubi */
16, /* bxsubr_u */
20, /* bxsubi_u */
0, /* jmpr */
8, /* jmpr */
8, /* jmpi */
12, /* callr */
16, /* calli */
96, /* epilog */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
116, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
16, /* addi_f */
4, /* subr_f */
@ -593,11 +664,11 @@
4, /* ldr_f */
12, /* ldi_f */
8, /* ldxr_f */
4, /* ldxi_f */
16, /* ldxi_f */
4, /* str_f */
12, /* sti_f */
8, /* stxr_f */
4, /* stxi_f */
16, /* stxi_f */
12, /* bltr_f */
24, /* blti_f */
12, /* bler_f */
@ -626,7 +697,15 @@
24, /* bordi_f */
12, /* bunordr_f */
24, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
20, /* addi_d */
4, /* subr_d */
@ -676,11 +755,11 @@
8, /* ldr_d */
16, /* ldi_d */
12, /* ldxr_d */
8, /* ldxi_d */
20, /* ldxi_d */
8, /* str_d */
16, /* sti_d */
12, /* stxr_d */
8, /* stxi_d */
20, /* stxi_d */
12, /* bltr_d */
28, /* blti_d */
12, /* bler_d */
@ -709,17 +788,20 @@
28, /* bordi_d */
12, /* bunordr_d */
36, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
4, /* movr_w_f */
8, /* movr_ww_d */
0, /* movr_w_d */
0, /* movr_f_w */
4, /* movr_f_w */
4, /* movi_f_w */
8, /* movr_d_ww */
8, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* NEW_ABI */
#endif /* __WORDSIZE */
@ -734,7 +816,19 @@
0, /* #note */
0, /* label */
44, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
@ -903,8 +997,26 @@
8, /* jmpi */
12, /* callr */
32, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
44, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
16, /* addi_f */
4, /* subr_f */
@ -987,7 +1099,15 @@
24, /* bordi_f */
12, /* bunordr_f */
24, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
16, /* addi_d */
4, /* subr_d */
@ -1070,6 +1190,11 @@
24, /* bordi_d */
12, /* bunordr_d */
24, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -1079,6 +1204,4 @@
0, /* movi_d_ww */
4, /* movr_d_w */
12, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */

View file

@ -53,17 +53,22 @@
/*
* Types
*/
typedef struct jit_va_list {
jit_pointer_t stack;
} jit_va_list_t;
typedef struct jit_pointer_t jit_va_list_t;
/*
* Prototypes
*/
# define patch(instr, node) _patch(_jit, instr, node)
#define jit_make_arg(node) _jit_make_arg(_jit,node)
static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*);
#define jit_make_arg_f(node) _jit_make_arg_f(_jit,node)
static jit_node_t *_jit_make_arg_f(jit_state_t*,jit_node_t*);
#define jit_make_arg_d(node) _jit_make_arg_d(_jit,node)
static jit_node_t *_jit_make_arg_d(jit_state_t*,jit_node_t*);
#define patch(instr, node) _patch(_jit, instr, node)
static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
#define PROTO 1
# include "jit_rewind.c"
# include "jit_mips-cpu.c"
# include "jit_mips-fpu.c"
#undef PROTO
@ -189,6 +194,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
/* _no_link here does not mean the jit_link() call can be removed
* by rewriting as:
* _jitc->function->prolog = jit_new_node(jit_code_prolog);
*/
_jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset;
@ -213,6 +222,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
default: _jitc->function->self.aoff &= -8; break;
}
_jitc->function->self.aoff -= length;
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
return (_jitc->function->self.aoff);
}
@ -221,6 +234,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{
jit_int32_t reg;
assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1;
@ -233,69 +247,82 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
jit_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg);
jit_dec_synth();
}
void
_jit_ret(jit_state_t *_jit)
{
jit_node_t *instr;
assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */
instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr, u);
if (JIT_RET != u)
jit_movr(JIT_RET, u);
else
jit_live(JIT_RET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_f, u);
if (JIT_FRET != u)
jit_movr_f(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_inc_synth_f(reti_f, u);
jit_movi_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_d, u);
if (JIT_FRET != u)
jit_movr_d(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_inc_synth_d(reti_d, u);
jit_movi_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
@ -320,29 +347,10 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
#endif
}
void
_jit_ellipsis(jit_state_t *_jit)
static jit_node_t *
_jit_make_arg(jit_state_t *_jit, jit_node_t *node)
{
if (_jitc->prepare) {
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
}
else {
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
/* Allocate va_list like object in the stack. */
_jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
_jitc->function->vagp = _jitc->function->self.argi;
}
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
assert(_jitc->function);
jit_int32_t offset;
#if NEW_ABI
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -357,14 +365,20 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += STACK_SLOT;
#endif
return (jit_new_node_w(jit_code_arg, offset));
if (node == (jit_node_t *)0)
node = jit_new_node(jit_code_arg);
else
link_node(node);
node->u.w = offset;
node->v.w = ++_jitc->function->self.argn;
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
static jit_node_t *
_jit_make_arg_f(jit_state_t *_jit, jit_node_t *node)
{
jit_int32_t offset;
assert(_jitc->function);
jit_int32_t offset;
#if NEW_ABI
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -375,27 +389,36 @@ _jit_arg_f(jit_state_t *_jit)
#else
offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT;
if (offset < NUM_WORD_ARGS) {
if (!_jitc->function->self.argi) {
if (!_jitc->function->self.argi &&
!(_jitc->function->self.call & jit_call_varargs)) {
if (offset == 0)
offset = 4;
else {
offset = 6;
_jitc->function->self.argi = 1;
}
/* Use as flag to rewind in case of varargs function */
++_jitc->function->self.argf;
}
}
else
offset = _jitc->function->self.size;
_jitc->function->self.size += STACK_SLOT;
#endif
return (jit_new_node_w(jit_code_arg_f, offset));
if (node == (jit_node_t *)0)
node = jit_new_node(jit_code_arg_f);
else
link_node(node);
node->u.w = offset;
node->v.w = ++_jitc->function->self.argn;
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
static jit_node_t *
_jit_make_arg_d(jit_state_t *_jit, jit_node_t *node)
{
jit_int32_t offset;
assert(_jitc->function);
jit_int32_t offset;
#if NEW_ABI
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -410,60 +433,124 @@ _jit_arg_d(jit_state_t *_jit)
}
offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT;
if (offset < NUM_WORD_ARGS) {
if (!_jitc->function->self.argi)
if (!_jitc->function->self.argi &&
!(_jitc->function->self.call & jit_call_varargs)) {
offset += 4;
/* Use as flag to rewind in case of varargs function */
++_jitc->function->self.argf;
}
}
else
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t);
#endif
return (jit_new_node_w(jit_code_arg_d, offset));
if (node == (jit_node_t *)0)
node = jit_new_node(jit_code_arg_d);
else
link_node(node);
node->u.w = offset;
node->v.w = ++_jitc->function->self.argn;
jit_link_prolog();
return (node);
}
void
_jit_ellipsis(jit_state_t *_jit)
{
if (_jitc->prepare) {
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
if (_jitc->function->call.argf)
rewind_prepare();
}
else {
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
if (_jitc->function->self.argf)
rewind_prolog();
}
jit_inc_synth(ellipsis);
if (_jitc->prepare)
jit_link_prepare();
else
jit_link_prolog();
jit_dec_synth();
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
assert(_jitc->function);
return (jit_make_arg((jit_node_t*)0));
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
assert(_jitc->function);
return (jit_make_arg_f((jit_node_t*)0));
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
assert(_jitc->function);
return (jit_make_arg_d((jit_node_t*)0));
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _A0 - v->u.w);
else
jit_ldxi_c(u, _FP, v->u.w + C_DISP);
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _A0 - v->u.w);
else
jit_ldxi_uc(u, _FP, v->u.w + C_DISP);
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _A0 - v->u.w);
else
jit_ldxi_s(u, _FP, v->u.w + S_DISP);
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _A0 - v->u.w);
else
jit_ldxi_us(u, _FP, v->u.w + S_DISP);
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) {
#if __WORDSIZE == 64
jit_extr_i(u, _A0 - v->u.w);
@ -473,6 +560,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
}
else
jit_ldxi_i(u, _FP, v->u.w + I_DISP);
jit_dec_synth();
}
#if __WORDSIZE == 64
@ -480,31 +568,37 @@ void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _A0 - v->u.w);
else
jit_ldxi_ui(u, _FP, v->u.w + I_DISP);
jit_dec_synth();
}
void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, _A0 - v->u.w);
else
jit_ldxi_l(u, _FP, v->u.w);
jit_dec_synth();
}
#endif
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
jit_inc_synth_wp(putargr, u, v);
assert(v->code == jit_code_arg);
if (jit_arg_reg_p(v->u.w))
jit_movr(_A0 - v->u.w, u);
else
jit_stxi(v->u.w, _FP, u);
jit_dec_synth();
}
void
@ -512,6 +606,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi(_A0 - v->u.w, u);
else {
@ -520,12 +615,14 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
jit_stxi(v->u.w, _FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
#if NEW_ABI
if (jit_arg_reg_p(v->u.w))
jit_movr_f(u, _F12 - v->u.w);
@ -537,12 +634,14 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
#endif
else
jit_ldxi_f(u, _FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
#if NEW_ABI
if (jit_arg_reg_p(v->u.w))
jit_movr_f(_F12 - v->u.w, u);
@ -554,6 +653,7 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
#endif
else
jit_stxi_f(v->u.w, _FP, u);
jit_dec_synth();
}
void
@ -561,6 +661,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
#if NEW_ABI
if (jit_arg_reg_p(v->u.w))
jit_movi_f(_F12 - v->u.w, u);
@ -580,12 +681,14 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
jit_stxi_f(v->u.w, _FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
#if NEW_ABI
if (jit_arg_reg_p(v->u.w))
jit_movr_d(u, _F12 - v->u.w);
@ -597,12 +700,14 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
#endif
else
jit_ldxi_d(u, _FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
#if NEW_ABI
if (jit_arg_reg_p(v->u.w))
jit_movr_d(_F12 - v->u.w, u);
@ -614,6 +719,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
#endif
else
jit_stxi_d(v->u.w, _FP, u);
jit_dec_synth();
}
void
@ -621,6 +727,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
#if NEW_ABI
if (jit_arg_reg_p(v->u.w))
jit_movi_d(_F12 - v->u.w, u);
@ -640,11 +747,14 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_stxi_d(v->u.w, _FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
#if NEW_ABI
assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
@ -666,14 +776,20 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
jit_stxi(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += STACK_SLOT;
#endif
jit_dec_synth();
}
void
_jit_pushargi(jit_state_t *_jit, jit_word_t u)
{
#if NEW_ABI
jit_int32_t regno;
#if !NEW_ABI
jit_word_t offset;
#endif
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
#if NEW_ABI
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_A0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -686,9 +802,6 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno);
}
#else
jit_int32_t regno;
jit_word_t offset;
assert(_jitc->function);
offset = _jitc->function->call.size >> STACK_SHIFT;
++_jitc->function->call.argi;
if (jit_arg_reg_p(offset))
@ -701,13 +814,19 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
}
_jitc->function->call.size += STACK_SLOT;
#endif
jit_dec_synth();
}
void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
#if NEW_ABI
#if !NEW_ABI
jit_word_t offset;
#endif
assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
#if NEW_ABI
if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs))
jit_movr_f(_F12 - _jitc->function->call.argi, u);
@ -720,10 +839,9 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
_jitc->function->call.size += STACK_SLOT;
}
#else
jit_word_t offset;
assert(_jitc->function);
offset = _jitc->function->call.size >> STACK_SHIFT;
if (offset < 2 && !_jitc->function->call.argi) {
if (offset < 2 && !_jitc->function->call.argi &&
!(_jitc->function->call.call & jit_call_varargs)) {
++_jitc->function->call.argf;
jit_movr_f(_F12 - offset, u);
}
@ -735,14 +853,20 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += STACK_SLOT;
#endif
jit_dec_synth();
}
void
_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{
jit_int32_t regno;
#if NEW_ABI
#if !NEW_ABI
jit_word_t offset;
#endif
assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
#if NEW_ABI
if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs))
jit_movi_f(_F12 - _jitc->function->call.argi, u);
@ -758,10 +882,9 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_unget_reg(regno);
}
#else
jit_word_t offset;
assert(_jitc->function);
offset = _jitc->function->call.size >> STACK_SHIFT;
if (offset < 2 && !_jitc->function->call.argi) {
if (offset < 2 && !_jitc->function->call.argi &&
!(_jitc->function->call.call & jit_call_varargs)) {
++_jitc->function->call.argf;
jit_movi_f(_F12 - offset, u);
}
@ -777,13 +900,20 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
}
_jitc->function->call.size += STACK_SLOT;
#endif
jit_dec_synth();
}
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
#if NEW_ABI
#if !NEW_ABI
jit_bool_t adjust;
jit_word_t offset;
#endif
assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
#if NEW_ABI
if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs))
jit_movr_d(_F12 - _jitc->function->call.argi, u);
@ -796,9 +926,6 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
_jitc->function->call.size += STACK_SLOT;
}
#else
jit_bool_t adjust;
jit_word_t offset;
assert(_jitc->function);
adjust = !!_jitc->function->call.argi;
if (_jitc->function->call.size & 7) {
_jitc->function->call.size += 4;
@ -806,7 +933,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
}
offset = _jitc->function->call.size >> STACK_SHIFT;
if (offset < 3) {
if (adjust) {
if (adjust || (_jitc->function->call.call & jit_call_varargs)) {
jit_movr_d_ww(_A0 - offset, _A0 - (offset + 1), u);
_jitc->function->call.argi += 2;
}
@ -819,14 +946,21 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float64_t);
#endif
jit_dec_synth();
}
void
_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{
jit_int32_t regno;
#if NEW_ABI
#if !NEW_ABI
jit_bool_t adjust;
jit_word_t offset;
#endif
assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
#if NEW_ABI
if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs))
jit_movi_d(_F12 - _jitc->function->call.argi, u);
@ -842,9 +976,6 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
jit_unget_reg(regno);
}
#else
jit_bool_t adjust;
jit_word_t offset;
assert(_jitc->function);
adjust = !!_jitc->function->call.argi;
if (_jitc->function->call.size & 7) {
_jitc->function->call.size += 4;
@ -852,7 +983,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
}
offset = _jitc->function->call.size >> STACK_SHIFT;
if (offset < 3) {
if (adjust) {
if (adjust || (_jitc->function->call.call & jit_call_varargs)) {
jit_movi_d_ww(_A0 - offset, _A0 - (offset + 1), u);
_jitc->function->call.argi += 2;
}
@ -869,6 +1000,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
}
_jitc->function->call.size += sizeof(jit_float64_t);
#endif
jit_dec_synth();
}
jit_bool_t
@ -897,8 +1029,8 @@ void
_jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{
jit_node_t *call;
assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
jit_movr(_T9, r0);
@ -912,6 +1044,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
}
jit_node_t *
@ -919,8 +1052,8 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{
jit_node_t *call;
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishr, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
node = jit_movi(_T9, (jit_word_t)i0);
@ -934,6 +1067,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
return (node);
}
@ -1012,8 +1146,14 @@ _emit_code(jit_state_t *_jit)
struct {
jit_node_t *node;
jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset;
} undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL;
@ -1105,12 +1245,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \
} \
break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end)
return (NULL);
#if DEVEL_DISASSEMBLER
node->offset = _jit->pc.w;
node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif
value = jit_classify(node->code);
jit_regarg_set(node, value);
@ -1527,6 +1671,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset;
restart_function:
_jitc->again = 0;
@ -1544,6 +1691,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset;
goto restart_function;
}
@ -1596,9 +1746,36 @@ _emit_code(jit_state_t *_jit)
vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_arg:
case jit_code_arg: case jit_code_ellipsis:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i:
#if __WORDSIZE == 64
case jit_code_getarg_ui: case jit_code_getarg_l:
#endif
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
#if __WORDSIZE == 64
case jit_code_retval_ui: case jit_code_retval_l:
#endif
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
break;
default:
abort();
@ -1619,6 +1796,7 @@ _emit_code(jit_state_t *_jit)
}
jit_regarg_clr(node, value);
assert(_jitc->regarg == jit_carry == _NOREG ? 0 : (1 << jit_carry));
assert(_jitc->synth == 0);
/* update register live state */
jit_reglive(node);
}
@ -1645,6 +1823,7 @@ _emit_code(jit_state_t *_jit)
}
#define CODE 1
# include "jit_rewind.c"
# include "jit_mips-cpu.c"
# include "jit_mips-fpu.c"
#undef CODE

View file

@ -24,7 +24,14 @@ static char *code_name[] = {
"#name", "#note",
"label",
"prolog",
"ellipsis",
"allocai", "allocar",
"arg",
"getarg_c", "getarg_uc",
"getarg_s", "getarg_us",
"getarg_i", "getarg_ui",
"getarg_l",
"putargr", "putargi",
"va_start",
"va_arg", "va_arg_d",
"va_end",
@ -111,8 +118,18 @@ static char *code_name[] = {
"bxsubr_u", "bxsubi_u",
"jmpr", "jmpi",
"callr", "calli",
"prepare",
"pushargr", "pushargi",
"finishr", "finishi",
"ret",
"retr", "reti",
"retval_c", "retval_uc",
"retval_s", "retval_us",
"retval_i", "retval_ui",
"retval_l",
"epilog",
"arg_f",
"arg_f", "getarg_f",
"putargr_f", "putargi_f",
"addr_f", "addi_f",
"subr_f", "subi_f",
"rsbi_f",
@ -155,7 +172,11 @@ static char *code_name[] = {
"bltgtr_f", "bltgti_f",
"bordr_f", "bordi_f",
"bunordr_f", "bunordi_f",
"arg_d",
"pushargr_f", "pushargi_f",
"retr_f", "reti_f",
"retval_f",
"arg_d", "getarg_d",
"putargr_d", "putargi_d",
"addr_d", "addi_d",
"subr_d", "subi_d",
"rsbi_d",
@ -198,10 +219,12 @@ static char *code_name[] = {
"bltgtr_d", "bltgti_d",
"bordr_d", "bordi_d",
"bunordr_d", "bunordi_d",
"pushargr_d", "pushargi_d",
"retr_d", "reti_d",
"retval_d",
"movr_w_f", "movr_ww_d",
"movr_w_d",
"movr_f_w", "movi_f_w",
"movr_d_ww", "movi_d_ww",
"movr_d_w", "movi_d_w",
"x86_retval_f", "x86_retval_d",
};

View file

@ -3287,7 +3287,7 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
if (_jitc->function->self.call & jit_call_varargs) {
for (regno = _jitc->function->vagp; jit_arg_reg_p(regno); ++regno)
stxi(gpr_save_area - (8 - regno) * sizeof(jit_word_t),
stxi(params_offset + regno * sizeof(jit_word_t),
_FP_REGNO, rn(JIT_RA0 - regno));
}
}
@ -3342,43 +3342,22 @@ _epilog(jit_state_t *_jit, jit_node_t *node)
static void
_vastart(jit_state_t *_jit, jit_int32_t r0)
{
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs);
/* Return jit_va_list_t in the register argument */
addi(r0, _FP_REGNO, _jitc->function->vaoff);
reg = jit_get_reg(jit_class_gpr);
/* Initialize stack pointer to the first stack argument. */
addi(rn(reg), _FP_REGNO, gpr_save_area -
8 * sizeof(jit_word_t) + _jitc->function->vagp * sizeof(jit_word_t));
stxi(offsetof(jit_va_list_t, stack), r0, rn(reg));
jit_unget_reg(reg);
addi(r0, _FP_REGNO, _jitc->function->self.size);
}
static void
_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t inv, reg;
assert(_jitc->function->self.call & jit_call_varargs);
reg = jit_get_reg(jit_class_gpr);
if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
/* Load varargs stack pointer. */
ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack));
/* Load argument. */
ldr(r0, rn(reg));
ldr(r0, r1);
/* Update vararg stack pointer. */
addi(rn(reg), rn(reg), sizeof(jit_word_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
jit_unget_reg(reg);
if (inv) jit_unget_reg(_R0);
/* Update va_list. */
addi(r1, r1, sizeof(jit_word_t));
}
static void

View file

@ -1185,23 +1185,10 @@ _stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
static void
_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t inv, reg;
assert(_jitc->function->self.call & jit_call_varargs);
reg = jit_get_reg(jit_class_gpr);
if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr);
/* Load varargs stack pointer. */
ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack));
/* Load argument. */
ldr_d(r0, rn(reg));
ldr_d(r0, r1);
/* Update vararg stack pointer. */
addi(rn(reg), rn(reg), sizeof(jit_float64_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
jit_unget_reg(reg);
if (inv) jit_unget_reg(_R0);
/* Update va_list. */
addi(r1, r1, sizeof(jit_float64_t));
}
#endif

View file

@ -11,7 +11,19 @@
0, /* #note */
0, /* label */
44, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
@ -180,8 +192,26 @@
4, /* jmpi */
8, /* callr */
16, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
44, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
12, /* addi_f */
4, /* subr_f */
@ -264,7 +294,15 @@
16, /* bordi_f */
8, /* bunordr_f */
16, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
12, /* addi_d */
4, /* subr_d */
@ -347,6 +385,11 @@
16, /* bordi_d */
8, /* bunordr_d */
16, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -356,14 +399,13 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __ppc__ */
#endif /* __WORDSIZE */
#if __WORDSIZE == 32
#if defined(__powerpc__)
#define JIT_INSTR_MAX 72
#if __BYTE_ORDER == __BIG_ENDIAN
#define JIT_INSTR_MAX 136
0, /* data */
0, /* live */
0, /* align */
@ -372,11 +414,23 @@
0, /* #name */
0, /* #note */
0, /* label */
72, /* prolog */
136, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
4, /* va_start */
8, /* va_arg */
8, /* va_arg_d */
0, /* va_end */
4, /* addr */
12, /* addi */
@ -469,15 +523,15 @@
0, /* ldr_l */
0, /* ldi_l */
8, /* ldxr_c */
8, /* ldxi_c */
16, /* ldxi_c */
4, /* ldxr_uc */
4, /* ldxi_uc */
12, /* ldxi_uc */
4, /* ldxr_s */
4, /* ldxi_s */
12, /* ldxi_s */
4, /* ldxr_us */
4, /* ldxi_us */
12, /* ldxi_us */
4, /* ldxr_i */
4, /* ldxi_i */
12, /* ldxi_i */
0, /* ldxr_ui */
0, /* ldxi_ui */
0, /* ldxr_l */
@ -491,11 +545,11 @@
0, /* str_l */
0, /* sti_l */
4, /* stxr_c */
4, /* stxi_c */
12, /* stxi_c */
4, /* stxr_s */
4, /* stxi_s */
12, /* stxi_s */
4, /* stxr_i */
4, /* stxi_i */
12, /* stxi_i */
0, /* stxr_l */
0, /* stxi_l */
8, /* bltr */
@ -538,12 +592,30 @@
16, /* bxsubi */
12, /* bxsubr_u */
16, /* bxsubi_u */
0, /* jmpr */
8, /* jmpr */
4, /* jmpi */
28, /* callr */
40, /* calli */
72, /* epilog */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
124, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
16, /* addi_f */
4, /* subr_f */
@ -593,11 +665,11 @@
4, /* ldr_f */
8, /* ldi_f */
4, /* ldxr_f */
4, /* ldxi_f */
12, /* ldxi_f */
4, /* str_f */
8, /* sti_f */
4, /* stxr_f */
4, /* stxi_f */
12, /* stxi_f */
8, /* bltr_f */
20, /* blti_f */
12, /* bler_f */
@ -626,7 +698,15 @@
20, /* bordi_f */
8, /* bunordr_f */
20, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
24, /* addi_d */
4, /* subr_d */
@ -676,11 +756,11 @@
4, /* ldr_d */
8, /* ldi_d */
4, /* ldxr_d */
4, /* ldxi_d */
12, /* ldxi_d */
4, /* str_d */
8, /* sti_d */
4, /* stxr_d */
4, /* stxi_d */
12, /* stxi_d */
8, /* bltr_d */
28, /* blti_d */
12, /* bler_d */
@ -709,6 +789,11 @@
28, /* bordi_d */
8, /* bunordr_d */
28, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -718,14 +803,14 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __BYTEORDER */
#endif /* __powerpc__ */
#endif /* __WORDSIZE */
#if __WORDSIZE == 64
#if defined(__powerpc__)
#define JIT_INSTR_MAX 72
#if __BYTE_ORDER == __BIG_ENDIAN
#define JIT_INSTR_MAX 148
0, /* data */
0, /* live */
4, /* align */
@ -734,11 +819,23 @@
0, /* #name */
0, /* #note */
0, /* label */
72, /* prolog */
148, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
4, /* va_start */
8, /* va_arg */
8, /* va_arg_d */
0, /* va_end */
4, /* addr */
28, /* addi */
@ -752,7 +849,7 @@
28, /* subci */
4, /* subxr */
8, /* subxi */
32, /* rsbi */
44, /* rsbi */
4, /* mulr */
28, /* muli */
12, /* qmulr */
@ -813,15 +910,9 @@
4, /* extr_us */
4, /* extr_i */
4, /* extr_ui */
# if __BYTE_ORDER == __BIG_ENDIAN
4, /* htonr_us */
4, /* htonr_ui */
4, /* htonr_ul */
#else
20, /* htonr_us */
16, /* htonr_ui */
44, /* htonr_ul */
#endif
8, /* ldr_c */
28, /* ldi_c */
4, /* ldr_uc */
@ -837,19 +928,19 @@
4, /* ldr_l */
24, /* ldi_l */
8, /* ldxr_c */
8, /* ldxi_c */
16, /* ldxi_c */
4, /* ldxr_uc */
4, /* ldxi_uc */
12, /* ldxi_uc */
4, /* ldxr_s */
4, /* ldxi_s */
12, /* ldxi_s */
4, /* ldxr_us */
4, /* ldxi_us */
12, /* ldxi_us */
4, /* ldxr_i */
4, /* ldxi_i */
12, /* ldxi_i */
4, /* ldxr_ui */
4, /* ldxi_ui */
12, /* ldxi_ui */
4, /* ldxr_l */
4, /* ldxi_l */
12, /* ldxi_l */
4, /* str_c */
24, /* sti_c */
4, /* str_s */
@ -859,13 +950,13 @@
4, /* str_l */
24, /* sti_l */
4, /* stxr_c */
4, /* stxi_c */
12, /* stxi_c */
4, /* stxr_s */
4, /* stxi_s */
12, /* stxi_s */
4, /* stxr_i */
4, /* stxi_i */
12, /* stxi_i */
4, /* stxr_l */
4, /* stxi_l */
12, /* stxi_l */
8, /* bltr */
8, /* blti */
8, /* bltr_u */
@ -906,12 +997,30 @@
16, /* bxsubi */
12, /* bxsubr_u */
16, /* bxsubi_u */
0, /* jmpr */
8, /* jmpr */
4, /* jmpi */
28, /* callr */
56, /* calli */
72, /* epilog */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
124, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
28, /* addi_f */
4, /* subr_f */
@ -961,11 +1070,11 @@
4, /* ldr_f */
24, /* ldi_f */
4, /* ldxr_f */
4, /* ldxi_f */
12, /* ldxi_f */
4, /* str_f */
24, /* sti_f */
4, /* stxr_f */
4, /* stxi_f */
12, /* stxi_f */
8, /* bltr_f */
32, /* blti_f */
12, /* bler_f */
@ -994,12 +1103,20 @@
32, /* bordi_f */
8, /* bunordr_f */
32, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
28, /* addi_d */
4, /* subr_d */
28, /* subi_d */
28, /* rsbi_d */
32, /* rsbi_d */
4, /* mulr_d */
28, /* muli_d */
4, /* divr_d */
@ -1044,11 +1161,11 @@
4, /* ldr_d */
24, /* ldi_d */
4, /* ldxr_d */
4, /* ldxi_d */
12, /* ldxi_d */
4, /* str_d */
24, /* sti_d */
4, /* stxr_d */
4, /* stxi_d */
12, /* stxi_d */
8, /* bltr_d */
32, /* blti_d */
12, /* bler_d */
@ -1077,6 +1194,11 @@
36, /* bordi_d */
8, /* bunordr_d */
32, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -1086,7 +1208,411 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __BYTEORDER */
#endif /* __powerpc__ */
#endif /* __WORDSIZE */
#if __WORDSIZE == 64
#if defined(__powerpc__)
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define JIT_INSTR_MAX 124
0, /* data */
0, /* live */
4, /* align */
0, /* save */
0, /* load */
0, /* #name */
0, /* #note */
0, /* label */
124, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
4, /* va_start */
8, /* va_arg */
8, /* va_arg_d */
0, /* va_end */
4, /* addr */
28, /* addi */
4, /* addcr */
28, /* addci */
4, /* addxr */
8, /* addxi */
4, /* subr */
28, /* subi */
4, /* subcr */
28, /* subci */
4, /* subxr */
8, /* subxi */
44, /* rsbi */
4, /* mulr */
28, /* muli */
12, /* qmulr */
28, /* qmuli */
12, /* qmulr_u */
28, /* qmuli_u */
4, /* divr */
28, /* divi */
4, /* divr_u */
28, /* divi_u */
20, /* qdivr */
16, /* qdivi */
20, /* qdivr_u */
16, /* qdivi_u */
12, /* remr */
36, /* remi */
12, /* remr_u */
36, /* remi_u */
4, /* andr */
28, /* andi */
4, /* orr */
28, /* ori */
4, /* xorr */
28, /* xori */
4, /* lshr */
4, /* lshi */
4, /* rshr */
4, /* rshi */
4, /* rshr_u */
4, /* rshi_u */
4, /* negr */
4, /* comr */
12, /* ltr */
12, /* lti */
12, /* ltr_u */
16, /* lti_u */
16, /* ler */
16, /* lei */
16, /* ler_u */
16, /* lei_u */
12, /* eqr */
12, /* eqi */
16, /* ger */
16, /* gei */
16, /* ger_u */
16, /* gei_u */
12, /* gtr */
12, /* gti */
12, /* gtr_u */
12, /* gti_u */
16, /* ner */
16, /* nei */
4, /* movr */
36, /* movi */
4, /* extr_c */
4, /* extr_uc */
4, /* extr_s */
4, /* extr_us */
4, /* extr_i */
4, /* extr_ui */
20, /* htonr_us */
16, /* htonr_ui */
44, /* htonr_ul */
8, /* ldr_c */
28, /* ldi_c */
4, /* ldr_uc */
24, /* ldi_uc */
4, /* ldr_s */
24, /* ldi_s */
4, /* ldr_us */
24, /* ldi_us */
4, /* ldr_i */
24, /* ldi_i */
4, /* ldr_ui */
24, /* ldi_ui */
4, /* ldr_l */
24, /* ldi_l */
8, /* ldxr_c */
16, /* ldxi_c */
4, /* ldxr_uc */
12, /* ldxi_uc */
4, /* ldxr_s */
12, /* ldxi_s */
4, /* ldxr_us */
12, /* ldxi_us */
4, /* ldxr_i */
12, /* ldxi_i */
4, /* ldxr_ui */
12, /* ldxi_ui */
4, /* ldxr_l */
12, /* ldxi_l */
4, /* str_c */
24, /* sti_c */
4, /* str_s */
24, /* sti_s */
4, /* str_i */
24, /* sti_i */
4, /* str_l */
24, /* sti_l */
4, /* stxr_c */
12, /* stxi_c */
4, /* stxr_s */
12, /* stxi_s */
4, /* stxr_i */
12, /* stxi_i */
4, /* stxr_l */
12, /* stxi_l */
8, /* bltr */
8, /* blti */
8, /* bltr_u */
12, /* blti_u */
8, /* bler */
8, /* blei */
8, /* bler_u */
12, /* blei_u */
8, /* beqr */
44, /* beqi */
8, /* bger */
8, /* bgei */
8, /* bger_u */
8, /* bgei_u */
8, /* bgtr */
8, /* bgti */
8, /* bgtr_u */
8, /* bgti_u */
8, /* bner */
36, /* bnei */
12, /* bmsr */
12, /* bmsi */
12, /* bmcr */
12, /* bmci */
12, /* boaddr */
16, /* boaddi */
12, /* boaddr_u */
12, /* boaddi_u */
12, /* bxaddr */
16, /* bxaddi */
12, /* bxaddr_u */
12, /* bxaddi_u */
12, /* bosubr */
16, /* bosubi */
12, /* bosubr_u */
16, /* bosubi_u */
12, /* bxsubr */
16, /* bxsubi */
12, /* bxsubr_u */
16, /* bxsubi_u */
8, /* jmpr */
4, /* jmpi */
12, /* callr */
36, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
124, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
28, /* addi_f */
4, /* subr_f */
28, /* subi_f */
28, /* rsbi_f */
4, /* mulr_f */
28, /* muli_f */
4, /* divr_f */
28, /* divi_f */
4, /* negr_f */
4, /* absr_f */
4, /* sqrtr_f */
12, /* ltr_f */
36, /* lti_f */
16, /* ler_f */
40, /* lei_f */
12, /* eqr_f */
36, /* eqi_f */
16, /* ger_f */
40, /* gei_f */
12, /* gtr_f */
36, /* gti_f */
16, /* ner_f */
40, /* nei_f */
16, /* unltr_f */
40, /* unlti_f */
16, /* unler_f */
40, /* unlei_f */
16, /* uneqr_f */
40, /* uneqi_f */
16, /* unger_f */
40, /* ungei_f */
16, /* ungtr_f */
40, /* ungti_f */
16, /* ltgtr_f */
40, /* ltgti_f */
16, /* ordr_f */
40, /* ordi_f */
12, /* unordr_f */
36, /* unordi_f */
12, /* truncr_f_i */
12, /* truncr_f_l */
12, /* extr_f */
4, /* extr_d_f */
4, /* movr_f */
24, /* movi_f */
4, /* ldr_f */
24, /* ldi_f */
4, /* ldxr_f */
12, /* ldxi_f */
4, /* str_f */
24, /* sti_f */
4, /* stxr_f */
12, /* stxi_f */
8, /* bltr_f */
32, /* blti_f */
12, /* bler_f */
36, /* blei_f */
8, /* beqr_f */
32, /* beqi_f */
12, /* bger_f */
36, /* bgei_f */
8, /* bgtr_f */
32, /* bgti_f */
8, /* bner_f */
32, /* bnei_f */
12, /* bunltr_f */
36, /* bunlti_f */
8, /* bunler_f */
32, /* bunlei_f */
12, /* buneqr_f */
36, /* buneqi_f */
8, /* bunger_f */
32, /* bungei_f */
12, /* bungtr_f */
36, /* bungti_f */
12, /* bltgtr_f */
36, /* bltgti_f */
8, /* bordr_f */
32, /* bordi_f */
8, /* bunordr_f */
32, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
28, /* addi_d */
4, /* subr_d */
28, /* subi_d */
32, /* rsbi_d */
4, /* mulr_d */
28, /* muli_d */
4, /* divr_d */
28, /* divi_d */
4, /* negr_d */
4, /* absr_d */
4, /* sqrtr_d */
12, /* ltr_d */
40, /* lti_d */
16, /* ler_d */
44, /* lei_d */
12, /* eqr_d */
40, /* eqi_d */
16, /* ger_d */
44, /* gei_d */
12, /* gtr_d */
40, /* gti_d */
16, /* ner_d */
44, /* nei_d */
16, /* unltr_d */
44, /* unlti_d */
16, /* unler_d */
44, /* unlei_d */
16, /* uneqr_d */
44, /* uneqi_d */
16, /* unger_d */
44, /* ungei_d */
16, /* ungtr_d */
44, /* ungti_d */
16, /* ltgtr_d */
44, /* ltgti_d */
16, /* ordr_d */
44, /* ordi_d */
12, /* unordr_d */
40, /* unordi_d */
12, /* truncr_d_i */
12, /* truncr_d_l */
12, /* extr_d */
4, /* extr_f_d */
4, /* movr_d */
32, /* movi_d */
4, /* ldr_d */
24, /* ldi_d */
4, /* ldxr_d */
12, /* ldxi_d */
4, /* str_d */
24, /* sti_d */
4, /* stxr_d */
12, /* stxi_d */
8, /* bltr_d */
32, /* blti_d */
12, /* bler_d */
36, /* blei_d */
8, /* beqr_d */
40, /* beqi_d */
12, /* bger_d */
40, /* bgei_d */
8, /* bgtr_d */
36, /* bgti_d */
8, /* bner_d */
36, /* bnei_d */
12, /* bunltr_d */
36, /* bunlti_d */
8, /* bunler_d */
32, /* bunlei_d */
12, /* buneqr_d */
36, /* buneqi_d */
8, /* bunger_d */
36, /* bungei_d */
12, /* bungtr_d */
40, /* bungti_d */
12, /* bltgtr_d */
40, /* bltgti_d */
8, /* bordr_d */
36, /* bordi_d */
8, /* bunordr_d */
32, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
0, /* movr_f_w */
0, /* movi_f_w */
0, /* movr_d_ww */
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
#endif /* __BYTE_ORDER */
#endif /* __powerpc__ */
#endif /* __WORDSIZE */

View file

@ -34,9 +34,7 @@
/*
* Types
*/
typedef struct jit_va_list {
jit_pointer_t stack;
} jit_va_list_t;
typedef jit_pointer_t jit_va_list_t;
/*
* Prototypes
@ -170,6 +168,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
/* _no_link here does not mean the jit_link() call can be removed
* by rewriting as:
* _jitc->function->prolog = jit_new_node(jit_code_prolog);
*/
_jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset;
@ -194,6 +196,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
default: _jitc->function->self.aoff &= -8; break;
}
_jitc->function->self.aoff -= length;
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
return (_jitc->function->self.aoff);
}
@ -202,6 +208,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{
jit_int32_t r0, r1;
assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1;
@ -218,69 +225,82 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
jit_str(JIT_SP, r0);
jit_unget_reg(r1);
jit_unget_reg(r0);
jit_dec_synth();
}
void
_jit_ret(jit_state_t *_jit)
{
jit_node_t *instr;
assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */
instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr, u);
if (JIT_RET != u)
jit_movr(JIT_RET, u);
else
jit_live(JIT_RET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_f, u);
if (JIT_RET != u)
jit_movr_f(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_inc_synth_f(reti_f, u);
jit_movi_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_d, u);
if (JIT_FRET != u)
jit_movr_d(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_inc_synth_d(reti_d, u);
jit_movi_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
@ -304,39 +324,45 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void
_jit_ellipsis(jit_state_t *_jit)
{
jit_inc_synth(ellipsis);
if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
}
else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
/* Allocate va_list like object in the stack. */
_jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
_jitc->function->vagp = _jitc->function->self.argi;
_jitc->function->vafp = _jitc->function->self.argf;
}
jit_dec_synth();
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
return (jit_new_node_w(jit_code_arg, offset));
node = jit_new_node_ww(jit_code_arg, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_f_reg_p(_jitc->function->self.argf))
offset = _jitc->function->self.argf++;
@ -350,13 +376,17 @@ _jit_arg_f(jit_state_t *_jit)
#endif
}
_jitc->function->self.size += sizeof(jit_word_t);
return (jit_new_node_w(jit_code_arg_f, offset));
node = jit_new_node_ww(jit_code_arg_f, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_f_reg_p(_jitc->function->self.argf))
offset = _jitc->function->self.argf++;
@ -370,53 +400,65 @@ _jit_arg_d(jit_state_t *_jit)
#endif
}
_jitc->function->self.size += sizeof(jit_float64_t);
return (jit_new_node_w(jit_code_arg_d, offset));
node = jit_new_node_ww(jit_code_arg_d, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, JIT_RA0 - v->u.w);
else
jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP);
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, JIT_RA0 - v->u.w);
else
jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP);
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, JIT_RA0 - v->u.w);
else
jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP);
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, JIT_RA0 - v->u.w);
else
jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP);
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) {
#if __WORDSIZE == 32
jit_movr(u, JIT_RA0 - v->u.w);
@ -426,6 +468,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
}
else
jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP);
jit_dec_synth();
}
#if __WORDSIZE == 64
@ -433,20 +476,24 @@ void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, JIT_RA0 - v->u.w);
else
jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP);
jit_dec_synth();
}
void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, JIT_RA0 - v->u.w);
else
jit_ldxi_l(u, JIT_FP, v->u.w);
jit_dec_synth();
}
#endif
@ -454,16 +501,19 @@ void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(JIT_RA0 - v->u.w, u);
else
jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{
jit_int32_t regno;
jit_inc_synth_wp(putargi, u, v);
assert(v->code == jit_code_arg);
if (jit_arg_reg_p(v->u.w))
jit_movi(JIT_RA0 - v->u.w, u);
@ -473,26 +523,31 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
jit_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, JIT_FA0 - v->u.w);
else
jit_ldxi_f(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(JIT_FA0 - v->u.w, u);
else
jit_stxi_f(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -500,6 +555,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movi_d(JIT_FA0 - v->u.w, u);
else {
@ -508,26 +564,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
jit_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, JIT_FA0 - v->u.w);
else
jit_ldxi_d(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(JIT_FA0 - v->u.w, u);
else
jit_stxi_d(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -535,6 +596,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movi_d(JIT_FA0 - v->u.w, u);
else {
@ -543,12 +605,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -556,6 +621,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
else
jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
jit_dec_synth();
}
void
@ -563,6 +629,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -574,29 +642,35 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno);
}
_jitc->function->call.size += sizeof(jit_word_t);
jit_dec_synth();
}
void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
!(_jitc->function->call.call & jit_call_varargs)) {
jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) {
/* in case of excess arguments */
if (jit_arg_reg_p(_jitc->function->call.argi)) {
/* in case of excess arguments */
if (jit_arg_reg_p(_jitc->function->call.argi)) {
#if __WORDSIZE == 32
_jitc->function->call.argi += 2;
_jitc->function->call.argi += 2;
if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
--_jitc->function->call.argi;
#else
_jitc->function->call.argi++;
_jitc->function->call.argi++;
#endif
}
_jitc->function->call.size += sizeof(jit_word_t);
return;
}
}
if (jit_arg_reg_p(_jitc->function->call.argi)) {
else if (jit_arg_reg_p(_jitc->function->call.argi
#if __WORDSIZE == 32
+ 1
#endif
)) {
/* use reserved 8 bytes area */
jit_stxi_d(alloca_offset - 8, JIT_FP, u);
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
@ -612,72 +686,81 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP,
JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
jit_dec_synth();
}
void
_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{
jit_int32_t regno;
assert(_jitc->function);
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
!(_jitc->function->call.call & jit_call_varargs)) {
jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) {
/* in case of excess arguments */
if (jit_arg_reg_p(_jitc->function->call.argi)) {
#if __WORDSIZE == 32
_jitc->function->call.argi += 2;
_jitc->function->call.argi += 2;
if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
--_jitc->function->call.argi;
#else
_jitc->function->call.argi++;
#endif
}
_jitc->function->call.size += sizeof(jit_word_t);
return;
}
}
regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
/* use reserved 8 bytes area */
jit_stxi_d(alloca_offset - 8, JIT_FP, regno);
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 8);
_jitc->function->call.argi++;
#endif
}
else {
regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u);
if (jit_arg_reg_p(_jitc->function->call.argi
#if __WORDSIZE == 32
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 4);
_jitc->function->call.argi++;
+ 1
#endif
)) {
/* use reserved 8 bytes area */
jit_stxi_d(alloca_offset - 8, JIT_FP, regno);
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 8);
_jitc->function->call.argi++;
#if __WORDSIZE == 32
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 4);
_jitc->function->call.argi++;
#endif
}
else
jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP,
JIT_SP, regno);
jit_unget_reg(regno);
}
else
jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP,
JIT_SP, regno);
_jitc->function->call.size += sizeof(jit_word_t);
jit_unget_reg(regno);
jit_dec_synth();
}
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
!(_jitc->function->call.call & jit_call_varargs)) {
jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) {
/* in case of excess arguments */
if (jit_arg_reg_p(_jitc->function->call.argi)) {
#if __WORDSIZE == 32
_jitc->function->call.argi += 2;
_jitc->function->call.argi += 2;
if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
--_jitc->function->call.argi;
#else
_jitc->function->call.argi++;
_jitc->function->call.argi++;
#endif
}
_jitc->function->call.size += sizeof(jit_float64_t);
return;
}
}
if (jit_arg_reg_p(_jitc->function->call.argi)) {
else if (jit_arg_reg_p(_jitc->function->call.argi
#if __WORDSIZE == 32
+ 1
#endif
)) {
/* use reserved 8 bytes area */
jit_stxi_d(alloca_offset - 8, JIT_FP, u);
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
@ -689,51 +772,76 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
_jitc->function->call.argi++;
#endif
}
else
else {
jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
#if __WORDSIZE == 32
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_SP,
_jitc->function->call.size + params_offset);
_jitc->function->call.argi++;
}
#endif
}
_jitc->function->call.size += sizeof(jit_float64_t);
jit_dec_synth();
}
void
_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{
jit_int32_t regno;
assert(_jitc->function);
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
!(_jitc->function->call.call & jit_call_varargs)) {
jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) {
/* in case of excess arguments */
if (jit_arg_reg_p(_jitc->function->call.argi)) {
/* in case of excess arguments */
if (jit_arg_reg_p(_jitc->function->call.argi)) {
#if __WORDSIZE == 32
_jitc->function->call.argi += 2;
_jitc->function->call.argi += 2;
if (!jit_arg_reg_p(_jitc->function->call.argi - 1))
--_jitc->function->call.argi;
#else
_jitc->function->call.argi++;
_jitc->function->call.argi++;
#endif
}
_jitc->function->call.size += sizeof(jit_float64_t);
return;
}
}
regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
/* use reserved 8 bytes area */
jit_stxi_d(alloca_offset - 8, JIT_FP, regno);
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 8);
_jitc->function->call.argi++;
else {
regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u);
if (jit_arg_reg_p(_jitc->function->call.argi
#if __WORDSIZE == 32
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 4);
_jitc->function->call.argi++;
+ 1
#endif
)) {
/* use reserved 8 bytes area */
jit_stxi_d(alloca_offset - 8, JIT_FP, regno);
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 8);
_jitc->function->call.argi++;
#if __WORDSIZE == 32
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP,
alloca_offset - 4);
_jitc->function->call.argi++;
#endif
}
else {
jit_stxi_d(_jitc->function->call.size + params_offset,
JIT_SP, regno);
#if __WORDSIZE == 32
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_SP,
_jitc->function->call.size + params_offset);
_jitc->function->call.argi++;
}
#endif
}
jit_unget_reg(regno);
}
else
jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno);
_jitc->function->call.size += sizeof(jit_float64_t);
jit_unget_reg(regno);
jit_dec_synth();
}
jit_bool_t
@ -761,6 +869,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{
jit_node_t *call;
assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0);
@ -768,6 +877,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
call->w.w = _jitc->function->call.argf;
_jitc->function->call.argi = _jitc->function->call.argf = 0;
_jitc->prepare = 0;
jit_dec_synth();
}
jit_node_t *
@ -775,6 +885,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0);
@ -782,70 +893,89 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
node->w.w = _jitc->function->call.argf;
_jitc->function->call.argi = _jitc->function->call.argf = 0;
_jitc->prepare = 0;
jit_dec_synth();
return (node);
}
void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth(retval_c);
jit_extr_c(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth(retval_uc);
jit_extr_uc(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth(retval_s);
jit_extr_s(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth(retval_us);
jit_extr_us(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth(retval_i);
#if __WORDSIZE == 32
if (r0 != JIT_RET)
jit_movr(r0, JIT_RET);
#else
jit_extr_i(r0, JIT_RET);
#endif
jit_dec_synth();
}
#if __WORDSIZE == 64
void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth(retval_ui);
jit_extr_ui(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth(retval_l);
if (r0 != JIT_RET)
jit_movr(r0, JIT_RET);
jit_dec_synth();
}
#endif
void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth(retval_f);
jit_retval_d(r0);
jit_dec_synth();
}
void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth(retval_d);
if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
}
jit_pointer_t
@ -859,11 +989,17 @@ _emit_code(jit_state_t *_jit)
struct {
jit_node_t *node;
jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_word_t patch_offset;
#if __powerpc__
jit_word_t prolog_offset;
#endif
} undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL;
@ -873,6 +1009,9 @@ _emit_code(jit_state_t *_jit)
undo.node = NULL;
undo.patch_offset = 0;
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
#if __powerpc__ && !ABI_ELFv2
undo.prolog_offset = 0;
for (node = _jitc->head; node; node = node->next)
@ -978,7 +1117,8 @@ _emit_code(jit_state_t *_jit)
return (NULL);
#if DEVEL_DISASSEMBLER
node->offset = _jit->pc.w;
node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif
value = jit_classify(node->code);
jit_regarg_set(node, value);
@ -1395,6 +1535,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset;
#if __powerpc__ && !ABI_ELFv2
undo.prolog_offset = _jitc->prolog.offset;
@ -1435,6 +1578,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset;
#if __powerpc__ && !ABI_ELFv2
_jitc->prolog.offset = undo.prolog_offset;
@ -1457,15 +1603,42 @@ _emit_code(jit_state_t *_jit)
vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_arg:
case jit_code_arg: case jit_code_ellipsis:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i:
#if __WORDSIZE == 64
case jit_code_getarg_ui: case jit_code_getarg_l:
#endif
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
#if __WORDSIZE == 64
case jit_code_retval_ui: case jit_code_retval_l:
#endif
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
break;
default:
abort();
}
jit_regarg_clr(node, value);
assert(_jitc->regarg == 0);
assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */
jit_reglive(node);
}

View file

@ -32,6 +32,14 @@
print_chr('?'); \
print_str(_rvs[jit_regno(value)].name); \
} while (0)
#define print_arg(value) \
do { \
print_chr('#'); \
if (value) \
print_dec((value)->v.w); \
else \
print_chr('?'); \
} while (0)
/*
* Initialization
@ -84,19 +92,38 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
return;
}
value = jit_classify(node->code) &
(jit_cc_a0_int|jit_cc_a0_jmp|jit_cc_a0_reg|jit_cc_a0_rlh|
jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl|
(jit_cc_a0_int|jit_cc_a0_flt|jit_cc_a0_dbl|jit_cc_a0_jmp|
jit_cc_a0_reg|jit_cc_a0_rlh|jit_cc_a0_arg|
jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl|jit_cc_a1_arg|
jit_cc_a2_reg|jit_cc_a2_int|jit_cc_a2_flt|jit_cc_a2_dbl);
if (value & jit_cc_a0_jmp)
if (!(node->flag & jit_flag_synth) && ((value & jit_cc_a0_jmp) ||
node->code == jit_code_finishr ||
node->code == jit_code_finishi))
print_str(" ");
else
print_chr('\t');
if (node->flag & jit_flag_synth)
print_str(" \\__ ");
print_str(code_name[node->code]);
switch (node->code) {
r:
print_chr(' '); print_reg(node->u.w); return;
w:
print_chr(' '); print_hex(node->u.w); return;
f:
print_chr(' ');
if (node->flag & jit_flag_data)
print_flt(*(jit_float32_t *)node->u.n->u.w);
else
print_flt(node->u.f);
return;
d:
print_chr(' ');
if (node->flag & jit_flag_data)
print_flt(*(jit_float64_t *)node->u.n->u.w);
else
print_flt(node->u.d);
return;
n:
print_chr(' ');
if (!(node->flag & jit_flag_node))
@ -106,6 +133,8 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
print_dec(node->u.n->v.w);
}
return;
a:
print_chr(' '); print_arg(node); return;
r_r:
print_chr(' '); print_reg(node->u.w);
print_chr(' '); print_reg(node->v.w); return;
@ -128,9 +157,36 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
else
print_flt(node->v.d);
return;
r_a:
print_chr(' '); print_reg(node->u.w);
print_chr(' '); print_arg(node->v.n);
return;
w_r:
print_chr(' '); print_hex(node->u.w);
print_chr(' '); print_reg(node->v.w); return;
w_w:
print_chr(' '); print_hex(node->u.w);
print_chr(' '); print_hex(node->v.w); return;
w_a:
print_chr(' '); print_hex(node->u.w);
print_chr(' '); print_arg(node->v.n);
return;
f_a:
print_chr(' ');
if (node->flag & jit_flag_data)
print_flt(*(jit_float32_t *)node->u.n->u.w);
else
print_flt(node->u.f);
print_chr(' '); print_arg(node->v.n);
return;
d_a:
print_chr(' ');
if (node->flag & jit_flag_data)
print_flt(*(jit_float64_t *)node->u.n->u.w);
else
print_flt(node->u.d);
print_chr(' '); print_arg(node->v.n);
return;
r_r_r:
print_chr(' '); print_reg(node->u.w);
print_chr(' '); print_reg(node->v.w);
@ -237,7 +293,9 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
break;
case jit_code_data:
case jit_code_label:
case jit_code_ellipsis:
case jit_code_prolog: case jit_code_epilog:
case jit_code_ret: case jit_code_prepare:
break;
case jit_code_save: case jit_code_load:
goto r;
@ -249,8 +307,14 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
goto r;
case jit_cc_a0_int:
goto w;
case jit_cc_a0_flt:
goto f;
case jit_cc_a0_dbl:
goto d;
case jit_cc_a0_jmp:
goto n;
case jit_cc_a0_int|jit_cc_a0_arg:
goto a;
case jit_cc_a0_reg|jit_cc_a1_reg:
goto r_r;
case jit_cc_a0_reg|jit_cc_a1_int:
@ -259,8 +323,18 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
goto r_f;
case jit_cc_a0_reg|jit_cc_a1_dbl:
goto r_d;
case jit_cc_a0_reg|jit_cc_a1_arg:
goto r_a;
case jit_cc_a0_int|jit_cc_a1_reg:
goto w_r;
case jit_cc_a0_int|jit_cc_a1_int:
goto w_w;
case jit_cc_a0_int|jit_cc_a1_arg:
goto w_a;
case jit_cc_a0_flt|jit_cc_a1_arg:
goto f_a;
case jit_cc_a0_dbl|jit_cc_a1_arg:
goto d_a;
case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_reg:
goto r_r_r;
case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_int:

186
lib/jit_rewind.c Normal file
View file

@ -0,0 +1,186 @@
/*
* Copyright (C) 2015 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
*/
#include <lightning.h>
#include <lightning/jit_private.h>
#if PROTO
# define free_synth_list(node) _free_synth_list(_jit,node)
static jit_node_t *_free_synth_list(jit_state_t*,jit_node_t*);
#define rewind_prolog() _rewind_prolog(_jit)
static void _rewind_prolog(jit_state_t*);
#define rewind_prepare() _rewind_prepare(_jit)
static void _rewind_prepare(jit_state_t*);
#endif
#if CODE
/*
* Implementation
*/
static jit_node_t *
_free_synth_list(jit_state_t *_jit, jit_node_t *node)
{
jit_node_t *next;
next = node->next;
free_node(node);
for (node = next; node && (node->flag & jit_flag_synth); node = next) {
next = node->next;
free_node(node);
}
return (next);
}
static void
_rewind_prolog(jit_state_t *_jit)
{
jit_node_t *node;
jit_node_t *next;
_jitc->function->self.size = stack_framesize;
#if __arm__
assert(jit_cpu.abi);
_jitc->function->self.size += 64;
#endif
_jitc->function->self.argi =
_jitc->function->self.argf = _jitc->function->self.argn = 0;
_jitc->tail = _jitc->function->prolog;
node = _jitc->tail->next;
_jitc->tail->next = (jit_node_t *)0;
_jitc->tail->link = (jit_node_t *)0;
for (; node; node = next) {
next = node->next;
switch (node->code) {
case jit_code_arg:
node->next = (jit_node_t *)0;
jit_make_arg(node);
break;
case jit_code_arg_f:
node->next = (jit_node_t *)0;
jit_make_arg_f(node);
break;
case jit_code_arg_d:
node->next = (jit_node_t *)0;
jit_make_arg_d(node);
break;
case jit_code_getarg_c:
jit_getarg_c(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_getarg_uc:
jit_getarg_uc(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_getarg_s:
jit_getarg_s(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_getarg_us:
jit_getarg_us(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_getarg_i:
jit_getarg_i(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_getarg_f:
jit_getarg_f(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_getarg_d:
jit_getarg_d(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_putargr:
jit_putargr(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_putargi:
jit_putargi(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_putargr_f:
jit_putargr_f(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_putargi_f:
jit_putargi_f(node->u.f, node->v.n);
next = free_synth_list(node);
break;
case jit_code_putargr_d:
jit_putargr_d(node->u.w, node->v.n);
next = free_synth_list(node);
break;
case jit_code_putargi_d:
jit_putargi_d(node->u.d, node->v.n);
next = free_synth_list(node);
break;
default:
node->next = (jit_node_t *)0;
link_node(node);
break;
}
}
}
static void
_rewind_prepare(jit_state_t *_jit)
{
jit_node_t *node;
jit_node_t *next;
_jitc->function->call.argi =
_jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->tail = _jitc->prepare;
node = _jitc->tail->next;
_jitc->tail->next = (jit_node_t *)0;
_jitc->tail->link = (jit_node_t *)0;
for (; node; node = next) {
next = node->next;
switch (node->code) {
case jit_code_pushargr:
jit_pushargr(node->u.w);
next = free_synth_list(node);
break;
case jit_code_pushargi:
jit_pushargi(node->u.w);
next = free_synth_list(node);
break;
case jit_code_pushargr_f:
jit_pushargr_f(node->u.w);
next = free_synth_list(node);
break;
case jit_code_pushargi_f:
jit_pushargi_f(node->u.f);
next = free_synth_list(node);
break;
case jit_code_pushargr_d:
jit_pushargr_d(node->u.w);
next = free_synth_list(node);
break;
case jit_code_pushargi_d:
jit_pushargi_d(node->u.d);
next = free_synth_list(node);
break;
default:
node->next = (jit_node_t *)0;
link_node(node);
break;
}
}
}
#endif

View file

@ -1287,7 +1287,7 @@ _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
/* Update the fp offset. */
addi(rn(rg0), rn(rg0), 1);
stxi(offsetof(jit_va_list_t, gpoff), r1, rn(rg0));
stxi(offsetof(jit_va_list_t, fpoff), r1, rn(rg0));
/* Will only need one temporary register below. */
jit_unget_reg_but_zero(rg1);
@ -1305,7 +1305,7 @@ _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
ldr_d(r0, rn(rg0));
/* Update overflow pointer. */
addi(rn(rg0), rn(rg0), sizeof(jit_word_t));
addi(rn(rg0), rn(rg0), sizeof(jit_float64_t));
stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));
/* Where to land if argument is in save area. */

View file

@ -1,366 +1,6 @@
#if __WORDSIZE == 32
#define JIT_INSTR_MAX 50
0, /* data */
0, /* live */
2, /* align */
0, /* save */
0, /* load */
0, /* #name */
0, /* #note */
2, /* label */
38, /* prolog */
0, /* arg */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* va_end */
4, /* addr */
12, /* addi */
4, /* addcr */
10, /* addci */
6, /* addxr */
10, /* addxi */
6, /* subr */
12, /* subi */
6, /* subcr */
10, /* subci */
8, /* subxr */
10, /* subxi */
14, /* rsbi */
6, /* mulr */
14, /* muli */
46, /* qmulr */
50, /* qmuli */
10, /* qmulr_u */
18, /* qmuli_u */
10, /* divr */
18, /* divi */
16, /* divr_u */
24, /* divi_u */
12, /* qdivr */
16, /* qdivi */
18, /* qdivr_u */
22, /* qdivi_u */
10, /* remr */
18, /* remi */
16, /* remr_u */
24, /* remi_u */
4, /* andr */
10, /* andi */
4, /* orr */
10, /* ori */
4, /* xorr */
12, /* xori */
8, /* lshr */
10, /* lshi */
8, /* rshr */
10, /* rshi */
8, /* rshr_u */
10, /* rshi_u */
2, /* negr */
8, /* comr */
16, /* ltr */
20, /* lti */
16, /* ltr_u */
20, /* lti_u */
16, /* ler */
20, /* lei */
16, /* ler_u */
20, /* lei_u */
16, /* eqr */
20, /* eqi */
16, /* ger */
20, /* gei */
16, /* ger_u */
20, /* gei_u */
16, /* gtr */
20, /* gti */
16, /* gtr_u */
20, /* gti_u */
16, /* ner */
20, /* nei */
2, /* movr */
8, /* movi */
4, /* extr_c */
4, /* extr_uc */
4, /* extr_s */
4, /* extr_us */
0, /* extr_i */
0, /* extr_ui */
4, /* htonr_us */
2, /* htonr_ui */
0, /* htonr_ul */
6, /* ldr_c */
12, /* ldi_c */
6, /* ldr_uc */
14, /* ldi_uc */
6, /* ldr_s */
12, /* ldi_s */
6, /* ldr_us */
12, /* ldi_us */
6, /* ldr_i */
12, /* ldi_i */
0, /* ldr_ui */
0, /* ldi_ui */
0, /* ldr_l */
0, /* ldi_l */
10, /* ldxr_c */
16, /* ldxi_c */
10, /* ldxr_uc */
16, /* ldxi_uc */
10, /* ldxr_s */
16, /* ldxi_s */
10, /* ldxr_us */
16, /* ldxi_us */
10, /* ldxr_i */
16, /* ldxi_i */
0, /* ldxr_ui */
0, /* ldxi_ui */
0, /* ldxr_l */
0, /* ldxi_l */
4, /* str_c */
12, /* sti_c */
4, /* str_s */
10, /* sti_s */
4, /* str_i */
10, /* sti_i */
0, /* str_l */
0, /* sti_l */
8, /* stxr_c */
16, /* stxi_c */
8, /* stxr_s */
16, /* stxi_s */
8, /* stxr_i */
16, /* stxi_i */
0, /* stxr_l */
0, /* stxi_l */
8, /* bltr */
12, /* blti */
8, /* bltr_u */
12, /* blti_u */
8, /* bler */
12, /* blei */
8, /* bler_u */
12, /* blei_u */
8, /* beqr */
16, /* beqi */
8, /* bger */
12, /* bgei */
8, /* bger_u */
12, /* bgei_u */
8, /* bgtr */
12, /* bgti */
8, /* bgtr_u */
12, /* bgti_u */
8, /* bner */
16, /* bnei */
12, /* bmsr */
14, /* bmsi */
12, /* bmcr */
14, /* bmci */
8, /* boaddr */
12, /* boaddi */
8, /* boaddr_u */
12, /* boaddi_u */
8, /* bxaddr */
12, /* bxaddi */
8, /* bxaddr_u */
12, /* bxaddi_u */
8, /* bosubr */
12, /* bosubi */
8, /* bosubr_u */
12, /* bosubi_u */
8, /* bxsubr */
12, /* bxsubi */
8, /* bxsubr_u */
12, /* bxsubi_u */
2, /* jmpr */
10, /* jmpi */
2, /* callr */
10, /* calli */
36, /* epilog */
0, /* arg_f */
6, /* addr_f */
24, /* addi_f */
8, /* subr_f */
24, /* subi_f */
28, /* rsbi_f */
6, /* mulr_f */
24, /* muli_f */
8, /* divr_f */
24, /* divi_f */
4, /* negr_f */
4, /* absr_f */
4, /* sqrtr_f */
16, /* ltr_f */
36, /* lti_f */
16, /* ler_f */
36, /* lei_f */
16, /* eqr_f */
36, /* eqi_f */
16, /* ger_f */
36, /* gei_f */
16, /* gtr_f */
36, /* gti_f */
16, /* ner_f */
36, /* nei_f */
16, /* unltr_f */
36, /* unlti_f */
16, /* unler_f */
36, /* unlei_f */
20, /* uneqr_f */
40, /* uneqi_f */
16, /* unger_f */
36, /* ungei_f */
16, /* ungtr_f */
36, /* ungti_f */
20, /* ltgtr_f */
40, /* ltgti_f */
16, /* ordr_f */
36, /* ordi_f */
16, /* unordr_f */
36, /* unordi_f */
4, /* truncr_f_i */
0, /* truncr_f_l */
4, /* extr_f */
4, /* extr_d_f */
2, /* movr_f */
20, /* movi_f */
4, /* ldr_f */
10, /* ldi_f */
8, /* ldxr_f */
14, /* ldxi_f */
4, /* str_f */
10, /* sti_f */
8, /* stxr_f */
14, /* stxi_f */
10, /* bltr_f */
28, /* blti_f */
10, /* bler_f */
30, /* blei_f */
10, /* beqr_f */
30, /* beqi_f */
10, /* bger_f */
30, /* bgei_f */
10, /* bgtr_f */
30, /* bgti_f */
10, /* bner_f */
30, /* bnei_f */
10, /* bunltr_f */
28, /* bunlti_f */
10, /* bunler_f */
28, /* bunlei_f */
18, /* buneqr_f */
36, /* buneqi_f */
10, /* bunger_f */
30, /* bungei_f */
10, /* bungtr_f */
30, /* bungti_f */
18, /* bltgtr_f */
38, /* bltgti_f */
10, /* bordr_f */
30, /* bordi_f */
10, /* bunordr_f */
28, /* bunordi_f */
0, /* arg_d */
6, /* addr_d */
34, /* addi_d */
8, /* subr_d */
34, /* subi_d */
38, /* rsbi_d */
6, /* mulr_d */
34, /* muli_d */
8, /* divr_d */
34, /* divi_d */
4, /* negr_d */
4, /* absr_d */
4, /* sqrtr_d */
16, /* ltr_d */
46, /* lti_d */
16, /* ler_d */
46, /* lei_d */
16, /* eqr_d */
46, /* eqi_d */
16, /* ger_d */
46, /* gei_d */
16, /* gtr_d */
46, /* gti_d */
16, /* ner_d */
46, /* nei_d */
16, /* unltr_d */
46, /* unlti_d */
16, /* unler_d */
46, /* unlei_d */
20, /* uneqr_d */
50, /* uneqi_d */
16, /* unger_d */
46, /* ungei_d */
16, /* ungtr_d */
46, /* ungti_d */
20, /* ltgtr_d */
50, /* ltgti_d */
16, /* ordr_d */
46, /* ordi_d */
16, /* unordr_d */
46, /* unordi_d */
4, /* truncr_d_i */
0, /* truncr_d_l */
4, /* extr_d */
4, /* extr_f_d */
2, /* movr_d */
30, /* movi_d */
4, /* ldr_d */
10, /* ldi_d */
8, /* ldxr_d */
14, /* ldxi_d */
4, /* str_d */
10, /* sti_d */
8, /* stxr_d */
14, /* stxi_d */
10, /* bltr_d */
38, /* blti_d */
10, /* bler_d */
38, /* blei_d */
10, /* beqr_d */
40, /* beqi_d */
10, /* bger_d */
40, /* bgei_d */
10, /* bgtr_d */
40, /* bgti_d */
10, /* bner_d */
40, /* bnei_d */
10, /* bunltr_d */
38, /* bunlti_d */
10, /* bunler_d */
38, /* bunlei_d */
18, /* buneqr_d */
46, /* buneqi_d */
10, /* bunger_d */
40, /* bungei_d */
10, /* bungtr_d */
40, /* bungti_d */
18, /* bltgtr_d */
48, /* bltgti_d */
10, /* bordr_d */
40, /* bordi_d */
10, /* bunordr_d */
38, /* bunordi_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
0, /* movr_f_w */
0, /* movi_f_w */
0, /* movr_d_ww */
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */
#if __WORDSIZE == 64
#define JIT_INSTR_MAX 68
#define JIT_INSTR_MAX 104
0, /* data */
0, /* live */
6, /* align */
@ -369,11 +9,23 @@
0, /* #name */
0, /* #note */
2, /* label */
38, /* prolog */
42, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
44, /* va_start */
104, /* va_arg */
100, /* va_arg_d */
0, /* va_end */
8, /* addr */
24, /* addi */
@ -466,19 +118,19 @@
6, /* ldr_l */
18, /* ldi_l */
14, /* ldxr_c */
6, /* ldxi_c */
26, /* ldxi_c */
14, /* ldxr_uc */
6, /* ldxi_uc */
26, /* ldxi_uc */
14, /* ldxr_s */
6, /* ldxi_s */
26, /* ldxi_s */
14, /* ldxr_us */
6, /* ldxi_us */
26, /* ldxi_us */
14, /* ldxr_i */
6, /* ldxi_i */
26, /* ldxi_i */
14, /* ldxr_ui */
6, /* ldxi_ui */
26, /* ldxi_ui */
14, /* ldxr_l */
6, /* ldxi_l */
26, /* ldxi_l */
4, /* str_c */
16, /* sti_c */
4, /* str_s */
@ -488,13 +140,13 @@
6, /* str_l */
18, /* sti_l */
12, /* stxr_c */
4, /* stxi_c */
28, /* stxi_c */
12, /* stxr_s */
4, /* stxi_s */
28, /* stxi_s */
12, /* stxr_i */
6, /* stxi_i */
28, /* stxi_i */
14, /* stxr_l */
6, /* stxi_l */
30, /* stxi_l */
10, /* bltr */
14, /* blti */
10, /* bltr_u */
@ -535,17 +187,35 @@
14, /* bxsubi */
10, /* bxsubr_u */
14, /* bxsubi_u */
0, /* jmpr */
2, /* jmpr */
18, /* jmpi */
2, /* callr */
18, /* calli */
36, /* epilog */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
40, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
6, /* addr_f */
26, /* addi_f */
8, /* subr_f */
26, /* subi_f */
26, /* rsbi_f */
28, /* rsbi_f */
6, /* mulr_f */
26, /* muli_f */
8, /* divr_f */
@ -590,11 +260,11 @@
4, /* ldr_f */
16, /* ldi_f */
12, /* ldxr_f */
4, /* ldxi_f */
24, /* ldxi_f */
4, /* str_f */
16, /* sti_f */
12, /* stxr_f */
4, /* stxi_f */
24, /* stxi_f */
10, /* bltr_f */
30, /* blti_f */
10, /* bler_f */
@ -623,12 +293,20 @@
30, /* bordi_f */
10, /* bunordr_f */
30, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
6, /* addr_d */
26, /* addi_d */
8, /* subr_d */
26, /* subi_d */
26, /* rsbi_d */
28, /* rsbi_d */
6, /* mulr_d */
26, /* muli_d */
8, /* divr_d */
@ -673,11 +351,11 @@
4, /* ldr_d */
16, /* ldi_d */
12, /* ldxr_d */
4, /* ldxi_d */
24, /* ldxi_d */
4, /* str_d */
16, /* sti_d */
12, /* stxr_d */
4, /* stxi_d */
24, /* stxi_d */
10, /* bltr_d */
30, /* blti_d */
10, /* bler_d */
@ -706,6 +384,412 @@
30, /* bordi_d */
10, /* bunordr_d */
30, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
0, /* movr_f_w */
0, /* movi_f_w */
0, /* movr_d_ww */
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
#endif /* __WORDSIZE */
#if __WORDSIZE == 64
#define JIT_INSTR_MAX 104
0, /* data */
0, /* live */
6, /* align */
0, /* save */
0, /* load */
0, /* #name */
0, /* #note */
2, /* label */
42, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
44, /* va_start */
104, /* va_arg */
100, /* va_arg_d */
0, /* va_end */
8, /* addr */
24, /* addi */
8, /* addcr */
20, /* addci */
8, /* addxr */
12, /* addxi */
12, /* subr */
24, /* subi */
12, /* subcr */
20, /* subci */
12, /* subxr */
12, /* subxi */
28, /* rsbi */
8, /* mulr */
24, /* muli */
60, /* qmulr */
68, /* qmuli */
16, /* qmulr_u */
32, /* qmuli_u */
12, /* divr */
28, /* divi */
16, /* divr_u */
32, /* divi_u */
16, /* qdivr */
20, /* qdivi */
20, /* qdivr_u */
24, /* qdivi_u */
12, /* remr */
28, /* remi */
16, /* remr_u */
32, /* remi_u */
8, /* andr */
20, /* andi */
8, /* orr */
20, /* ori */
8, /* xorr */
24, /* xori */
6, /* lshr */
10, /* lshi */
6, /* rshr */
10, /* rshi */
6, /* rshr_u */
10, /* rshi_u */
4, /* negr */
12, /* comr */
20, /* ltr */
24, /* lti */
20, /* ltr_u */
24, /* lti_u */
20, /* ler */
24, /* lei */
20, /* ler_u */
24, /* lei_u */
20, /* eqr */
24, /* eqi */
20, /* ger */
24, /* gei */
20, /* ger_u */
24, /* gei_u */
20, /* gtr */
24, /* gti */
20, /* gtr_u */
24, /* gti_u */
20, /* ner */
24, /* nei */
4, /* movr */
16, /* movi */
4, /* extr_c */
4, /* extr_uc */
4, /* extr_s */
4, /* extr_us */
4, /* extr_i */
4, /* extr_ui */
4, /* htonr_us */
4, /* htonr_ui */
4, /* htonr_ul */
6, /* ldr_c */
18, /* ldi_c */
6, /* ldr_uc */
18, /* ldi_uc */
6, /* ldr_s */
18, /* ldi_s */
6, /* ldr_us */
18, /* ldi_us */
6, /* ldr_i */
18, /* ldi_i */
6, /* ldr_ui */
18, /* ldi_ui */
6, /* ldr_l */
18, /* ldi_l */
14, /* ldxr_c */
26, /* ldxi_c */
14, /* ldxr_uc */
26, /* ldxi_uc */
14, /* ldxr_s */
26, /* ldxi_s */
14, /* ldxr_us */
26, /* ldxi_us */
14, /* ldxr_i */
26, /* ldxi_i */
14, /* ldxr_ui */
26, /* ldxi_ui */
14, /* ldxr_l */
26, /* ldxi_l */
4, /* str_c */
16, /* sti_c */
4, /* str_s */
16, /* sti_s */
4, /* str_i */
16, /* sti_i */
6, /* str_l */
18, /* sti_l */
12, /* stxr_c */
28, /* stxi_c */
12, /* stxr_s */
28, /* stxi_s */
12, /* stxr_i */
28, /* stxi_i */
14, /* stxr_l */
30, /* stxi_l */
10, /* bltr */
14, /* blti */
10, /* bltr_u */
14, /* blti_u */
10, /* bler */
14, /* blei */
10, /* bler_u */
14, /* blei_u */
10, /* beqr */
26, /* beqi */
10, /* bger */
14, /* bgei */
10, /* bger_u */
14, /* bgei_u */
10, /* bgtr */
14, /* bgti */
10, /* bgtr_u */
14, /* bgti_u */
10, /* bner */
26, /* bnei */
18, /* bmsr */
18, /* bmsi */
18, /* bmcr */
18, /* bmci */
10, /* boaddr */
14, /* boaddi */
10, /* boaddr_u */
14, /* boaddi_u */
10, /* bxaddr */
14, /* bxaddi */
10, /* bxaddr_u */
14, /* bxaddi_u */
10, /* bosubr */
14, /* bosubi */
10, /* bosubr_u */
14, /* bosubi_u */
10, /* bxsubr */
14, /* bxsubi */
10, /* bxsubr_u */
14, /* bxsubi_u */
2, /* jmpr */
18, /* jmpi */
2, /* callr */
18, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
40, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
6, /* addr_f */
26, /* addi_f */
8, /* subr_f */
26, /* subi_f */
28, /* rsbi_f */
6, /* mulr_f */
26, /* muli_f */
8, /* divr_f */
26, /* divi_f */
4, /* negr_f */
4, /* absr_f */
4, /* sqrtr_f */
16, /* ltr_f */
36, /* lti_f */
16, /* ler_f */
36, /* lei_f */
16, /* eqr_f */
36, /* eqi_f */
16, /* ger_f */
36, /* gei_f */
16, /* gtr_f */
36, /* gti_f */
16, /* ner_f */
36, /* nei_f */
16, /* unltr_f */
36, /* unlti_f */
16, /* unler_f */
36, /* unlei_f */
20, /* uneqr_f */
40, /* uneqi_f */
16, /* unger_f */
36, /* ungei_f */
16, /* ungtr_f */
36, /* ungti_f */
20, /* ltgtr_f */
40, /* ltgti_f */
16, /* ordr_f */
36, /* ordi_f */
16, /* unordr_f */
36, /* unordi_f */
4, /* truncr_f_i */
4, /* truncr_f_l */
4, /* extr_f */
4, /* extr_d_f */
2, /* movr_f */
20, /* movi_f */
4, /* ldr_f */
16, /* ldi_f */
12, /* ldxr_f */
24, /* ldxi_f */
4, /* str_f */
16, /* sti_f */
12, /* stxr_f */
24, /* stxi_f */
10, /* bltr_f */
30, /* blti_f */
10, /* bler_f */
30, /* blei_f */
10, /* beqr_f */
30, /* beqi_f */
10, /* bger_f */
30, /* bgei_f */
10, /* bgtr_f */
30, /* bgti_f */
10, /* bner_f */
30, /* bnei_f */
10, /* bunltr_f */
30, /* bunlti_f */
10, /* bunler_f */
30, /* bunlei_f */
18, /* buneqr_f */
38, /* buneqi_f */
10, /* bunger_f */
30, /* bungei_f */
10, /* bungtr_f */
30, /* bungti_f */
18, /* bltgtr_f */
38, /* bltgti_f */
10, /* bordr_f */
30, /* bordi_f */
10, /* bunordr_f */
30, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
6, /* addr_d */
26, /* addi_d */
8, /* subr_d */
26, /* subi_d */
28, /* rsbi_d */
6, /* mulr_d */
26, /* muli_d */
8, /* divr_d */
26, /* divi_d */
4, /* negr_d */
4, /* absr_d */
4, /* sqrtr_d */
16, /* ltr_d */
36, /* lti_d */
16, /* ler_d */
36, /* lei_d */
16, /* eqr_d */
36, /* eqi_d */
16, /* ger_d */
36, /* gei_d */
16, /* gtr_d */
36, /* gti_d */
16, /* ner_d */
36, /* nei_d */
16, /* unltr_d */
36, /* unlti_d */
16, /* unler_d */
36, /* unlei_d */
20, /* uneqr_d */
40, /* uneqi_d */
16, /* unger_d */
36, /* ungei_d */
16, /* ungtr_d */
36, /* ungti_d */
20, /* ltgtr_d */
40, /* ltgti_d */
16, /* ordr_d */
36, /* ordi_d */
16, /* unordr_d */
36, /* unordi_d */
4, /* truncr_d_i */
4, /* truncr_d_l */
4, /* extr_d */
4, /* extr_f_d */
2, /* movr_d */
24, /* movi_d */
4, /* ldr_d */
16, /* ldi_d */
12, /* ldxr_d */
24, /* ldxi_d */
4, /* str_d */
16, /* sti_d */
12, /* stxr_d */
24, /* stxi_d */
10, /* bltr_d */
30, /* blti_d */
10, /* bler_d */
30, /* blei_d */
10, /* beqr_d */
34, /* beqi_d */
10, /* bger_d */
30, /* bgei_d */
10, /* bgtr_d */
30, /* bgti_d */
10, /* bner_d */
30, /* bnei_d */
10, /* bunltr_d */
30, /* bunlti_d */
10, /* bunler_d */
30, /* bunlei_d */
18, /* buneqr_d */
38, /* buneqi_d */
10, /* bunger_d */
30, /* bungei_d */
10, /* bungtr_d */
30, /* bungti_d */
18, /* bltgtr_d */
38, /* bltgti_d */
10, /* bordr_d */
30, /* bordi_d */
10, /* bunordr_d */
30, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -715,6 +799,4 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */

View file

@ -171,6 +171,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
/* _no_link here does not mean the jit_link() call can be removed
* by rewriting as:
* _jitc->function->prolog = jit_new_node(jit_code_prolog);
*/
_jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset;
@ -195,6 +199,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
default: _jitc->function->self.aoff &= -8; break;
}
_jitc->function->self.aoff -= length;
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
return (_jitc->function->self.aoff);
}
@ -203,6 +211,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{
jit_int32_t reg;
assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1;
@ -215,60 +224,73 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
jit_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg);
jit_dec_synth();
}
void
_jit_ret(jit_state_t *_jit)
{
jit_node_t *instr;
assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */
instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr, u);
jit_movr(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_f, u);
jit_movr_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_inc_synth_f(reti_f, u);
jit_movi_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_d, u);
jit_movr_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_inc_synth_d(reti_d, u);
jit_movi_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
@ -292,11 +314,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void
_jit_ellipsis(jit_state_t *_jit)
{
jit_inc_synth(ellipsis);
if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
}
else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
@ -315,12 +340,14 @@ _jit_ellipsis(jit_state_t *_jit)
else
_jitc->function->vafp = NUM_FLOAT_REG_ARGS;
}
jit_dec_synth();
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -328,13 +355,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
return (jit_new_node_w(jit_code_arg, offset));
node = jit_new_node_ww(jit_code_arg, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_f_reg_p(_jitc->function->self.argf))
offset = _jitc->function->self.argf++;
@ -342,13 +373,17 @@ _jit_arg_f(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
return (jit_new_node_w(jit_code_arg_f, offset));
node = jit_new_node_ww(jit_code_arg_f, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_f_reg_p(_jitc->function->self.argf))
offset = _jitc->function->self.argf++;
@ -356,57 +391,69 @@ _jit_arg_d(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t);
}
return (jit_new_node_w(jit_code_arg_d, offset));
node = jit_new_node_ww(jit_code_arg_d, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _R2 - v->u.w);
else
jit_ldxi_c(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t));
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _R2 - v->u.w);
else
jit_ldxi_uc(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t));
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _R2 - v->u.w);
else
jit_ldxi_s(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t));
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _R2 - v->u.w);
else
jit_ldxi_us(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t));
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) {
#if __WORDSIZE == 32
jit_movr(u, _R2 - v->u.w);
@ -417,6 +464,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
else
jit_ldxi_i(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t));
jit_dec_synth();
}
#if __WORDSIZE == 64
@ -424,21 +472,25 @@ void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _R2 - v->u.w);
else
jit_ldxi_ui(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint32_t));
jit_dec_synth();
}
void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, _R2 - v->u.w);
else
jit_ldxi_l(u, JIT_FP, v->u.w);
jit_dec_synth();
}
#endif
@ -446,10 +498,12 @@ void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(_R2 - v->u.w, u);
else
jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -457,6 +511,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi(_R2 - v->u.w, u);
else {
@ -465,12 +520,14 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
jit_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(u, _F0 - v->u.w);
else
@ -480,12 +537,14 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
+ (__WORDSIZE >> 3) - sizeof(jit_float32_t)
#endif
);
jit_dec_synth();
}
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(_F0 - v->u.w, u);
else
@ -494,6 +553,7 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
+ (__WORDSIZE >> 3) - sizeof(jit_float32_t)
#endif
, JIT_FP, u);
jit_dec_synth();
}
void
@ -501,6 +561,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movi_f(_F0 - v->u.w, u);
else {
@ -513,26 +574,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, _F0 - v->u.w);
else
jit_ldxi_d(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(_F0 - v->u.w, u);
else
jit_stxi_d(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -540,6 +606,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_arg_f_reg_p(v->u.w))
jit_movi_d(_F0 - v->u.w, u);
else {
@ -548,12 +615,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_R2 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -562,6 +632,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
@ -569,6 +640,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_R2 - _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -580,12 +653,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movr_f(_F0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
@ -598,6 +674,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
@ -605,6 +682,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movi_f(_F0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
@ -620,12 +699,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movr_d(_F0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
@ -634,6 +716,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float64_t);
}
jit_dec_synth();
}
void
@ -641,6 +724,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movi_d(_F0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf;
@ -652,6 +737,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_float64_t);
}
jit_dec_synth();
}
jit_bool_t
@ -677,6 +763,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{
jit_node_t *call;
assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0);
@ -685,6 +772,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
}
jit_node_t *
@ -692,6 +780,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0);
@ -700,67 +789,86 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
return (node);
}
void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_c, r0);
jit_extr_c(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_uc, r0);
jit_extr_uc(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_s, r0);
jit_extr_s(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_us, r0);
jit_extr_us(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
#if __WORDSIZE == 64
jit_extr_i(r0, JIT_RET);
#else
jit_movr(r0, JIT_RET);
#endif
jit_dec_synth();
}
#if __WORDSIZE == 64
void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_ui, r0);
jit_extr_ui(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_l, r0);
jit_movr(r0, JIT_RET);
jit_dec_synth();
}
#endif
void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_f, r0);
jit_movr_f(r0, JIT_FRET);
jit_dec_synth();
}
void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_d, r0);
jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
}
jit_pointer_t
@ -774,8 +882,14 @@ _emit_code(jit_state_t *_jit)
struct {
jit_node_t *node;
jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset;
} undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL;
@ -890,12 +1004,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \
} \
break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end)
return (NULL);
#if DEVEL_DISASSEMBLER
node->offset = _jit->pc.w;
node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif
value = jit_classify(node->code);
jit_regarg_set(node, value);
@ -1318,6 +1436,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset;
restart_function:
_jitc->again = 0;
@ -1335,6 +1456,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset;
goto restart_function;
}
@ -1355,16 +1479,43 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_live: case jit_code_ellipsis:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i:
#if __WORDSIZE == 64
case jit_code_getarg_ui: case jit_code_getarg_l:
#endif
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
#if __WORDSIZE == 64
case jit_code_retval_ui: case jit_code_retval_l:
#endif
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
break;
default:
abort();
}
jit_regarg_clr(node, value);
assert(_jitc->regarg == 0);
assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */
jit_reglive(node);
}

View file

@ -10,7 +10,19 @@
0, /* #note */
0, /* label */
16, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
@ -179,8 +191,26 @@
16, /* jmpi */
8, /* callr */
16, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
24, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
16, /* addi_f */
4, /* subr_f */
@ -263,7 +293,15 @@
24, /* bordi_f */
12, /* bunordr_f */
28, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
24, /* addi_d */
4, /* subr_d */
@ -346,6 +384,11 @@
32, /* bordi_d */
12, /* bunordr_d */
36, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -355,6 +398,4 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */

View file

@ -131,6 +131,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
/* _no_link here does not mean the jit_link() call can be removed
* by rewriting as:
* _jitc->function->prolog = jit_new_node(jit_code_prolog);
*/
_jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset;
@ -155,6 +159,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
default: _jitc->function->self.aoff &= -8; break;
}
_jitc->function->self.aoff -= length;
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
return (_jitc->function->self.aoff);
}
@ -163,84 +171,95 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{
jit_int32_t reg;
assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1;
}
reg = jit_get_reg(jit_class_gpr);
jit_negr(reg, v);
jit_andi(reg, reg, -16);
jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
jit_addr(u, u, reg);
jit_addr(_SP, _SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg);
jit_dec_synth();
}
void
_jit_ret(jit_state_t *_jit)
{
jit_node_t *instr;
assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */
instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr, u);
if (JIT_RET != u)
jit_movr(JIT_RET, u);
else
jit_live(JIT_RET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_f, u);
if (JIT_FRET != u)
jit_movr_f(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_inc_synth_f(reti_f, u);
jit_movi_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_d, u);
if (JIT_FRET != u)
jit_movr_d(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_inc_synth_d(reti_d, u);
jit_movi_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
@ -264,22 +283,27 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void
_jit_ellipsis(jit_state_t *_jit)
{
jit_inc_synth(ellipsis);
if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
}
else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
_jitc->function->vagp = _jitc->function->self.argi;
}
jit_dec_synth();
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -287,13 +311,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
return (jit_new_node_w(jit_code_arg, offset));
node = jit_new_node_ww(jit_code_arg, offset,
++_jitc->function->self.argn);
jit_link_prepare();
return (node);
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
@ -301,13 +329,17 @@ _jit_arg_f(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float32_t);
}
return (jit_new_node_w(jit_code_arg_f, offset));
node = jit_new_node_ww(jit_code_arg_f, offset,
++_jitc->function->self.argn);
jit_link_prepare();
return (node);
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
if (jit_arg_d_reg_p(_jitc->function->self.argi)) {
offset = _jitc->function->self.argi;
@ -321,71 +353,86 @@ _jit_arg_d(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t);
}
return (jit_new_node_w(jit_code_arg_d, offset));
node = jit_new_node_ww(jit_code_arg_d, offset,
++_jitc->function->self.argn);
jit_link_prepare();
return (node);
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _I0 + v->u.w);
else
jit_ldxi_c(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t));
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _I0 + v->u.w);
else
jit_ldxi_uc(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t));
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _I0 + v->u.w);
else
jit_ldxi_s(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t));
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _I0 + v->u.w);
else
jit_ldxi_us(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t));
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, _I0 + v->u.w);
else
jit_ldxi_i(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(_I0 + v->u.w, u);
else
jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -393,6 +440,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi(_I0 + v->u.w, u);
else {
@ -401,6 +449,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
jit_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
@ -408,24 +457,28 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
assert(_jitc->function);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_reg_p(v->u.w)) {
jit_stxi(-4, JIT_FP, _I0 + v->u.w);
jit_ldxi_f(u, JIT_FP, -4);
}
else
jit_ldxi_f(u, JIT_FP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_reg_p(v->u.w)) {
jit_stxi_f(-4, JIT_FP, u);
jit_ldxi(_I0 + v->u.w, JIT_FP, -4);
}
else
jit_stxi_f(v->u.w, JIT_FP, u);
jit_dec_synth();
}
void
@ -433,6 +486,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u);
if (jit_arg_reg_p(v->u.w)) {
@ -442,6 +496,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
else
jit_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
jit_dec_synth();
}
void
@ -449,6 +504,7 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
assert(_jitc->function);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_d_reg_p(v->u.w)) {
jit_stxi(-8, JIT_FP, _I0 + v->u.w);
jit_stxi(-4, JIT_FP, _I0 + v->u.w + 1);
@ -463,6 +519,7 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
jit_ldxi_f(u, JIT_FP, v->u.w);
jit_ldxi_f(u + 1, JIT_FP, v->u.w + 4);
}
jit_dec_synth();
}
void
@ -470,6 +527,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_d_reg_p(v->u.w)) {
jit_stxi_d(-8, JIT_FP, u);
jit_ldxi(_I0 + v->u.w, JIT_FP, -8);
@ -494,6 +552,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
jit_stxi(v->u.w + 4, JIT_FP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
@ -501,6 +560,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno, gpr;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u);
if (jit_arg_d_reg_p(v->u.w)) {
@ -528,12 +588,14 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_unget_reg(gpr);
}
jit_unget_reg(regno);
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_O0 + _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -542,12 +604,15 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
_jit_pushargi(jit_state_t *_jit, jit_word_t u)
{
jit_int32_t regno;
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_O0 + _jitc->function->call.argi, u);
++_jitc->function->call.argi;
@ -559,11 +624,14 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t);
}
jit_dec_synth();
}
void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_stxi_f(-4, JIT_FP, u);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -4);
@ -573,12 +641,15 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
jit_stxi_f(_jitc->function->call.size + stack_framesize, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float32_t);
}
jit_dec_synth();
}
void
_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{
jit_int32_t regno;
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
@ -591,11 +662,14 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
_jitc->function->call.size += sizeof(jit_float32_t);
}
jit_unget_reg(regno);
jit_dec_synth();
}
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_arg_d_reg_p(_jitc->function->call.argi)) {
jit_stxi_d(-8, JIT_FP, u);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
@ -616,12 +690,15 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
JIT_SP, u + 1);
_jitc->function->call.size += sizeof(jit_float64_t);
}
jit_dec_synth();
}
void
_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{
jit_int32_t regno;
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u);
if (jit_arg_d_reg_p(_jitc->function->call.argi)) {
@ -645,6 +722,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
_jitc->function->call.size += sizeof(jit_float64_t);
}
jit_unget_reg(regno);
jit_dec_synth();
}
jit_bool_t
@ -667,8 +745,8 @@ void
_jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{
jit_node_t *call;
assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0);
@ -677,14 +755,15 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
}
jit_node_t *
_jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0);
@ -693,52 +772,67 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
return (node);
}
void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_c, r0);
jit_extr_c(r0, _O0);
jit_dec_synth();
}
void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_uc, r0);
jit_extr_uc(r0, _O0);
jit_dec_synth();
}
void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_s, r0);
jit_extr_s(r0, _O0);
jit_dec_synth();
}
void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_us, r0);
jit_extr_us(r0, _O0);
jit_dec_synth();
}
void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
if (r0 != _O0)
jit_movr(r0, _O0);
jit_dec_synth();
}
void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_f, r0);
if (r0 != JIT_FRET)
jit_movr_f(r0, JIT_FRET);
jit_dec_synth();
}
void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_d, r0);
if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
}
jit_pointer_t
@ -752,8 +846,14 @@ _emit_code(jit_state_t *_jit)
struct {
jit_node_t *node;
jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset;
} undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL;
@ -859,12 +959,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \
} \
break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end)
return (NULL);
#if DEVEL_DISASSEMBLER
node->offset = _jit->pc.w;
node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif
value = jit_classify(node->code);
jit_regarg_set(node, value);
@ -1253,6 +1357,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset;
restart_function:
_jitc->again = 0;
@ -1270,6 +1377,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset;
goto restart_function;
}
@ -1288,16 +1398,37 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_live: case jit_code_ellipsis:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i:
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
break;
default:
abort();
}
jit_regarg_clr(node, value);
assert(_jitc->regarg == 0);
assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */
jit_reglive(node);
}

View file

@ -10,7 +10,19 @@
0, /* #note */
3, /* label */
34, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
3, /* va_start */
5, /* va_arg */
7, /* va_arg_d */
@ -179,8 +191,26 @@
5, /* jmpi */
2, /* callr */
5, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
24, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
8, /* addr_f */
19, /* addi_f */
12, /* subr_f */
@ -263,7 +293,15 @@
23, /* bordi_f */
10, /* bunordr_f */
23, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
10, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
8, /* addr_d */
26, /* addi_d */
12, /* subr_d */
@ -346,6 +384,11 @@
28, /* bordi_d */
10, /* bunordr_d */
28, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
10, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -355,26 +398,36 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
10, /* x86_retval_f */
10, /* x86_retval_d */
#endif /* __X32 */
#endif
#if __X64
#if __CYGWIN__
#define JIT_INSTR_MAX 71
#define JIT_INSTR_MAX 130
0, /* data */
0, /* live */
7, /* align */
6, /* align */
0, /* save */
0, /* load */
0, /* #name */
0, /* #note */
7, /* label */
71, /* prolog */
130, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
7, /* va_start */
7, /* va_arg */
9, /* va_arg_d */
0, /* va_end */
4, /* addr */
13, /* addi */
@ -388,7 +441,7 @@
13, /* subci */
9, /* subxr */
7, /* subxi */
19, /* rsbi */
16, /* rsbi */
7, /* mulr */
14, /* muli */
20, /* qmulr */
@ -491,7 +544,7 @@
7, /* stxr_c */
7, /* stxi_c */
5, /* stxr_s */
5, /* stxi_s */
7, /* stxi_s */
4, /* stxr_i */
6, /* stxi_i */
4, /* stxr_l */
@ -540,13 +593,31 @@
5, /* jmpi */
3, /* callr */
13, /* calli */
68, /* epilog */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
124, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
10, /* addr_f */
21, /* addi_f */
15, /* subr_f */
21, /* subi_f */
21, /* rsbi_f */
27, /* rsbi_f */
10, /* mulr_f */
21, /* muli_f */
15, /* divr_f */
@ -624,12 +695,20 @@
25, /* bordi_f */
10, /* bunordr_f */
25, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
10, /* addr_d */
25, /* addi_d */
15, /* subr_d */
25, /* subi_d */
25, /* rsbi_d */
27, /* rsbi_d */
10, /* mulr_d */
25, /* muli_d */
15, /* divr_d */
@ -707,6 +786,11 @@
26, /* bordi_d */
11, /* bunordr_d */
26, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -716,8 +800,6 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#else
# if __X64_32
@ -731,7 +813,19 @@
0, /* #note */
3, /* label */
108, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
41, /* va_start */
45, /* va_arg */
54, /* va_arg_d */
@ -900,8 +994,26 @@
5, /* jmpi */
3, /* callr */
9, /* calli */
35, /* epilog */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
34, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
10, /* addr_f */
21, /* addi_f */
15, /* subr_f */
@ -984,7 +1096,15 @@
21, /* bordi_f */
10, /* bunordr_f */
21, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
10, /* addr_d */
33, /* addi_d */
15, /* subr_d */
@ -1067,6 +1187,11 @@
34, /* bordi_d */
11, /* bunordr_d */
34, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -1076,10 +1201,8 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
# else
# else
#define JIT_INSTR_MAX 115
0, /* data */
0, /* live */
@ -1090,7 +1213,19 @@
0, /* #note */
7, /* label */
115, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
42, /* va_start */
41, /* va_arg */
50, /* va_arg_d */
@ -1259,8 +1394,26 @@
5, /* jmpi */
3, /* callr */
13, /* calli */
38, /* epilog */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
37, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
10, /* addr_f */
21, /* addi_f */
15, /* subr_f */
@ -1343,7 +1496,15 @@
25, /* bordi_f */
10, /* bunordr_f */
25, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
10, /* addr_d */
25, /* addi_d */
15, /* subr_d */
@ -1426,6 +1587,11 @@
26, /* bordi_d */
11, /* bunordr_d */
26, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
@ -1435,8 +1601,6 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __CYGWIN__ */
# endif /* __X64_32 */
#endif /* __X64 */

View file

@ -423,6 +423,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
/* _no_link here does not mean the jit_link() call can be removed
* by rewriting as:
* _jitc->function->prolog = jit_new_node(jit_code_prolog);
*/
_jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset;
@ -447,6 +451,18 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length)
default: _jitc->function->self.aoff &= -8; break;
}
_jitc->function->self.aoff -= length;
/* jit_allocai() may be called from jit_x86-cpu.c, and force a function
* generation restart on some conditions: div/rem and qmul/qdiv, due
* to registers constraints.
* The check is to prevent an assertion of a jit_xyz() being called
* during code generation, and attempting to add a node to the tail
* of the current IR generation. */
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
return (_jitc->function->self.aoff);
}
@ -455,6 +471,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{
jit_int32_t reg;
assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1;
@ -467,23 +484,25 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
jit_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg);
jit_dec_synth();
}
void
_jit_ret(jit_state_t *_jit)
{
jit_node_t *instr;
assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */
instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr, u);
/* movr(%ret, %ret) would be optimized out */
if (JIT_RET != u)
jit_movr(JIT_RET, u);
@ -491,47 +510,58 @@ _jit_retr(jit_state_t *_jit, jit_int32_t u)
else
jit_live(JIT_RET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_f, u);
if (JIT_FRET != u)
jit_movr_f(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_inc_synth_f(reti_f, u);
jit_movi_f(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_inc_synth_w(retr_d, u);
if (JIT_FRET != u)
jit_movr_d(JIT_FRET, u);
else
jit_live(JIT_FRET);
jit_ret();
jit_dec_synth();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_inc_synth_d(reti_d, u);
jit_movi_d(JIT_FRET, u);
jit_ret();
jit_dec_synth();
}
void
@ -555,12 +585,15 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void
_jit_ellipsis(jit_state_t *_jit)
{
jit_inc_synth(ellipsis);
if (_jitc->prepare) {
jit_link_prepare();
/* Remember that a varargs function call is being constructed. */
assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs;
}
else {
jit_link_prolog();
/* Remember the current function is varargs. */
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
@ -585,13 +618,14 @@ _jit_ellipsis(jit_state_t *_jit)
_jitc->function->vafp = va_fp_max_offset;
#endif
}
jit_dec_synth();
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs));
#if __X64
@ -607,14 +641,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += REAL_WORDSIZE;
}
return (jit_new_node_w(jit_code_arg, offset));
node = jit_new_node_ww(jit_code_arg, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs));
#if __X64
@ -633,14 +670,17 @@ _jit_arg_f(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += REAL_WORDSIZE;
}
return (jit_new_node_w(jit_code_arg_f, offset));
node = jit_new_node_ww(jit_code_arg_f, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
jit_int32_t offset;
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs));
#if __X64
@ -659,61 +699,73 @@ _jit_arg_d(jit_state_t *_jit)
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t);
}
return (jit_new_node_w(jit_code_arg_d, offset));
node = jit_new_node_ww(jit_code_arg_d, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, JIT_RA0 - v->u.w);
else
#endif
jit_ldxi_c(u, _RBP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, JIT_RA0 - v->u.w);
else
#endif
jit_ldxi_uc(u, _RBP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, JIT_RA0 - v->u.w);
else
#endif
jit_ldxi_s(u, _RBP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, JIT_RA0 - v->u.w);
else
#endif
jit_ldxi_us(u, _RBP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w)) {
# if __X64_32
@ -725,6 +777,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
else
#endif
jit_ldxi_i(u, _RBP, v->u.w);
jit_dec_synth();
}
#if __X64 && !__X64_32
@ -732,20 +785,24 @@ void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, JIT_RA0 - v->u.w);
else
jit_ldxi_ui(u, _RBP, v->u.w);
jit_dec_synth();
}
void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, JIT_RA0 - v->u.w);
else
jit_ldxi_l(u, _RBP, v->u.w);
jit_dec_synth();
}
#endif
@ -753,12 +810,14 @@ void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w))
jit_movr(JIT_RA0 - v->u.w, u);
else
#endif
jit_stxi(v->u.w, _RBP, u);
jit_dec_synth();
}
void
@ -766,6 +825,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w))
jit_movi(JIT_RA0 - v->u.w, u);
@ -777,30 +837,35 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
jit_stxi(v->u.w, _RBP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
#if __X64
if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(u, _XMM0 - v->u.w);
else
#endif
jit_ldxi_f(u, _RBP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w))
jit_movr_f(_XMM0 - v->u.w, u);
else
#endif
jit_stxi_f(v->u.w, _RBP, u);
jit_dec_synth();
}
void
@ -808,6 +873,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w))
jit_movi_f(_XMM0 - v->u.w, u);
@ -819,30 +885,35 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
jit_stxi_f(v->u.w, _RBP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
#if __X64
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, _XMM0 - v->u.w);
else
#endif
jit_ldxi_d(u, _RBP, v->u.w);
jit_dec_synth();
}
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w))
jit_movr_d(_XMM0 - v->u.w, u);
else
#endif
jit_stxi_d(v->u.w, _RBP, u);
jit_dec_synth();
}
void
@ -850,6 +921,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
#if __X64
if (jit_arg_reg_p(v->u.w))
jit_movi_d(_XMM0 - v->u.w, u);
@ -861,12 +933,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
jit_stxi_d(v->u.w, _RBP, regno);
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
#if __X64
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
@ -883,14 +958,16 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
jit_stxi(_jitc->function->call.size, _RSP, u);
_jitc->function->call.size += REAL_WORDSIZE;
}
jit_dec_synth();
}
void
_jit_pushargi(jit_state_t *_jit, jit_word_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
#if __X64
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
@ -911,12 +988,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
_jitc->function->call.size += REAL_WORDSIZE;
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
#if __X64
# if __CYGWIN__
if (jit_arg_reg_p(_jitc->function->call.argi)) {
@ -942,14 +1022,16 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
jit_stxi_f(_jitc->function->call.size, _RSP, u);
_jitc->function->call.size += REAL_WORDSIZE;
}
jit_dec_synth();
}
void
_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
#if __X64
# if __CYGWIN__
if (jit_arg_reg_p(_jitc->function->call.argi)) {
@ -978,12 +1060,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
_jitc->function->call.size += REAL_WORDSIZE;
jit_unget_reg(regno);
}
jit_dec_synth();
}
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
#if __X64
# if __CYGWIN__
if (jit_arg_reg_p(_jitc->function->call.argi)) {
@ -1009,14 +1094,16 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
jit_stxi_d(_jitc->function->call.size, _RSP, u);
_jitc->function->call.size += sizeof(jit_float64_t);
}
jit_dec_synth();
}
void
_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
#if __X64
# if __CYGWIN__
if (jit_arg_reg_p(_jitc->function->call.argi)) {
@ -1045,6 +1132,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
_jitc->function->call.size += sizeof(jit_float64_t);
jit_unget_reg(regno);
}
jit_dec_synth();
}
jit_bool_t
@ -1075,9 +1163,9 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{
jit_int32_t reg;
jit_node_t *call;
reg = r0;
assert(_jitc->function);
reg = r0;
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
#if __X64
@ -1102,6 +1190,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
}
jit_node_t *
@ -1111,8 +1200,8 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
jit_int32_t reg;
#endif
jit_node_t *node;
assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size;
#if __X64
@ -1136,79 +1225,94 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
_jitc->function->call.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 0;
jit_dec_synth();
return (node);
}
void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_c, r0);
jit_extr_c(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_uc, r0);
jit_extr_uc(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_s, r0);
jit_extr_s(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_us, r0);
jit_extr_us(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_i, r0);
#if __X32 || __X64_32
if (r0 != JIT_RET)
jit_movr(r0, JIT_RET);
#else
jit_extr_i(r0, JIT_RET);
#endif
jit_dec_synth();
}
#if __X64 && !__X64_32
void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_ui, r0);
jit_extr_ui(r0, JIT_RET);
jit_dec_synth();
}
void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{
jit_inc_synth_w(retval_l, r0);
if (r0 != JIT_RET)
jit_movr(r0, JIT_RET);
jit_dec_synth();
}
#endif
void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{
# if __X32
jit_new_node_w(jit_code_x86_retval_f, r0);
# else
jit_inc_synth_w(retval_f, r0);
#if __X64
if (r0 != JIT_FRET)
jit_movr_f(r0, JIT_FRET);
# endif
#endif
jit_dec_synth();
}
void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{
# if __X32
jit_new_node_w(jit_code_x86_retval_d, r0);
# else
jit_inc_synth_w(retval_d, r0);
#if __X64
if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET);
# endif
#endif
jit_dec_synth();
}
jit_pointer_t
@ -1222,8 +1326,14 @@ _emit_code(jit_state_t *_jit)
struct {
jit_node_t *node;
jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset;
} undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL;
@ -1461,12 +1571,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \
} \
break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end)
return (NULL);
#if DEVEL_DISASSEMBLER
node->offset = _jit->pc.w;
node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif
value = jit_classify(node->code);
jit_regarg_set(node, value);
@ -1917,6 +2031,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset;
restart_function:
_jitc->again = 0;
@ -1934,6 +2051,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset;
goto restart_function;
}
@ -1946,24 +2066,6 @@ _emit_code(jit_state_t *_jit)
epilog(node);
_jitc->function = NULL;
break;
#if __X32
case jit_code_x86_retval_f:
if (jit_sse_reg_p(node->u.w)) {
fstpr(_ST1_REGNO);
sse_from_x87_f(rn(node->u.w), _ST0_REGNO);
}
else
fstpr(rn(node->u.w) + 1);
break;
case jit_code_x86_retval_d:
if (jit_sse_reg_p(node->u.w)) {
fstpr(_ST1_REGNO);
sse_from_x87_d(rn(node->u.w), _ST0_REGNO);
}
else
fstpr(rn(node->u.w) + 1);
break;
#endif
case jit_code_va_start:
vastart(rn(node->u.w));
break;
@ -1973,16 +2075,62 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w), jit_x87_reg_p(node->u.w));
break;
case jit_code_live:
case jit_code_live: case jit_code_ellipsis:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i:
#if __X64 && !__X64_32
case jit_code_getarg_ui: case jit_code_getarg_l:
#endif
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i:
#if __X64 && !__X32
case jit_code_retval_ui: case jit_code_retval_l:
#endif
case jit_code_prepare:
case jit_code_finishr: case jit_code_finishi:
break;
case jit_code_retval_f:
#if __X32
if (jit_sse_reg_p(node->u.w)) {
fstpr(_ST1_REGNO);
sse_from_x87_f(rn(node->u.w), _ST0_REGNO);
}
else
fstpr(rn(node->u.w) + 1);
#endif
break;
case jit_code_retval_d:
#if __X32
if (jit_sse_reg_p(node->u.w)) {
fstpr(_ST1_REGNO);
sse_from_x87_d(rn(node->u.w), _ST0_REGNO);
}
else
fstpr(rn(node->u.w) + 1);
#endif
break;
default:
abort();
}
jit_regarg_clr(node, value);
assert(_jitc->regarg == 0);
assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */
jit_reglive(node);
}

View file

@ -58,6 +58,9 @@ static inline jit_node_t *_link_node(jit_state_t*, jit_node_t*);
#define del_node(u, v) _del_node(_jit, u, v)
static inline void _del_node(jit_state_t*, jit_node_t*, jit_node_t*);
#define free_node(u) _free_node(_jit, u)
static inline void _free_node(jit_state_t*, jit_node_t*);
#define del_label(u, v) _del_label(_jit, u, v)
static void _del_label(jit_state_t*, jit_node_t*, jit_node_t*);
@ -681,6 +684,8 @@ _new_node(jit_state_t *_jit, jit_code_t code)
new_pool();
node = _jitc->list;
_jitc->list = node->next;
if (_jitc->synth)
node->flag |= jit_flag_synth;
node->next = NULL;
node->code = code;
@ -711,6 +716,14 @@ _del_node(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
_jitc->list = node;
}
static inline void
_free_node(jit_state_t *_jit, jit_node_t *node)
{
memset(node, 0, sizeof(jit_node_t));
node->next = _jitc->list;
_jitc->list = node;
}
static void
_del_label(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
{
@ -906,6 +919,13 @@ _jit_destroy_state(jit_state_t *_jit)
jit_free((jit_pointer_t *)&_jit);
}
void
_jit_synth_inc(jit_state_t *_jit)
{
assert(_jitc->synth < 8);
++_jitc->synth;
}
jit_node_t *
_jit_new_node(jit_state_t *_jit, jit_code_t code)
{
@ -927,6 +947,13 @@ _jit_link_node(jit_state_t *_jit, jit_node_t *node)
link_node(node);
}
void
_jit_synth_dec(jit_state_t *_jit)
{
assert(_jitc->synth > 0);
--_jitc->synth;
}
jit_node_t *
_jit_new_node_w(jit_state_t *_jit, jit_code_t code,
jit_word_t u)
@ -937,6 +964,26 @@ _jit_new_node_w(jit_state_t *_jit, jit_code_t code,
return (link_node(node));
}
jit_node_t *
_jit_new_node_f(jit_state_t *_jit, jit_code_t code,
jit_float32_t u)
{
jit_node_t *node = new_node(code);
assert(!_jitc->realize);
node->u.f = u;
return (link_node(node));
}
jit_node_t *
_jit_new_node_d(jit_state_t *_jit, jit_code_t code,
jit_float64_t u)
{
jit_node_t *node = new_node(code);
assert(!_jitc->realize);
node->u.d = u;
return (link_node(node));
}
jit_node_t *
_jit_new_node_p(jit_state_t *_jit, jit_code_t code,
jit_pointer_t u)
@ -965,6 +1012,28 @@ _jit_new_node_wp(jit_state_t *_jit, jit_code_t code,
return (jit_new_node_ww(code, u, (jit_word_t)v));
}
jit_node_t *
_jit_new_node_fp(jit_state_t *_jit, jit_code_t code,
jit_float32_t u, jit_pointer_t v)
{
jit_node_t *node = new_node(code);
assert(!_jitc->realize);
node->u.f = u;
node->v.w = (jit_word_t)v;
return (link_node(node));
}
jit_node_t *
_jit_new_node_dp(jit_state_t *_jit, jit_code_t code,
jit_float64_t u, jit_pointer_t v)
{
jit_node_t *node = new_node(code);
assert(!_jitc->realize);
node->u.d = u;
node->v.w = (jit_word_t)v;
return (link_node(node));
}
jit_node_t *
_jit_new_node_pw(jit_state_t *_jit, jit_code_t code,
jit_pointer_t u, jit_word_t v)
@ -1163,7 +1232,7 @@ _jit_prepare(jit_state_t *_jit)
_jitc->function->call.argi =
_jitc->function->call.argf =
_jitc->function->call.size = 0;
_jitc->prepare = 1;
_jitc->prepare = jit_new_node(jit_code_prepare);
}
void
@ -1182,28 +1251,69 @@ _jit_classify(jit_state_t *_jit, jit_code_t code)
jit_int32_t mask;
switch (code) {
case jit_code_data: case jit_code_align: case jit_code_save:
case jit_code_load: case jit_code_name: case jit_code_label:
case jit_code_note: case jit_code_prolog: case jit_code_epilog:
case jit_code_data: case jit_code_save: case jit_code_load:
case jit_code_name: case jit_code_label: case jit_code_note:
case jit_code_prolog: case jit_code_ellipsis: case jit_code_epilog:
case jit_code_ret: case jit_code_prepare:
mask = 0;
break;
case jit_code_live: case jit_code_va_end:
case jit_code_retr: case jit_code_retr_f: case jit_code_retr_d:
case jit_code_pushargr: case jit_code_pushargr_f:
case jit_code_pushargr_d:
case jit_code_finishr: /* synthesized will set jit_cc_a0_jmp */
mask = jit_cc_a0_reg;
break;
case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d:
case jit_code_align: case jit_code_reti: case jit_code_pushargi:
case jit_code_finishi: /* synthesized will set jit_cc_a0_jmp */
mask = jit_cc_a0_int;
break;
case jit_code_reti_f: case jit_code_pushargi_f:
mask = jit_cc_a0_flt;
break;
case jit_code_reti_d: case jit_code_pushargi_d:
mask = jit_cc_a0_dbl;
break;
case jit_code_allocai:
mask = jit_cc_a0_int|jit_cc_a1_int;
break;
case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d:
mask = jit_cc_a0_int|jit_cc_a0_arg;
break;
case jit_code_calli: case jit_code_jmpi:
mask = jit_cc_a0_jmp;
break;
case jit_code_callr: case jit_code_jmpr:
mask = jit_cc_a0_reg|jit_cc_a0_jmp;
break;
case jit_code_x86_retval_f:
case jit_code_x86_retval_d:
case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_retval_s: case jit_code_retval_us:
case jit_code_retval_i: case jit_code_retval_ui:
case jit_code_retval_l:
case jit_code_retval_f: case jit_code_retval_d:
case jit_code_va_start:
mask = jit_cc_a0_reg|jit_cc_a0_chg;
break;
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i: case jit_code_getarg_ui:
case jit_code_getarg_l:
case jit_code_getarg_f: case jit_code_getarg_d:
mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_arg;
break;
case jit_code_putargr: case jit_code_putargr_f:
case jit_code_putargr_d:
mask = jit_cc_a0_reg|jit_cc_a1_arg;
break;
case jit_code_putargi:
mask = jit_cc_a0_int|jit_cc_a1_arg;
break;
case jit_code_putargi_f:
mask = jit_cc_a0_flt|jit_cc_a1_arg;
break;
case jit_code_putargi_d:
mask = jit_cc_a0_dbl|jit_cc_a1_arg;
break;
case jit_code_movi: case jit_code_ldi_c: case jit_code_ldi_uc:
case jit_code_ldi_s: case jit_code_ldi_us: case jit_code_ldi_i:
case jit_code_ldi_ui: case jit_code_ldi_l: case jit_code_ldi_f:
@ -1337,6 +1447,8 @@ _jit_classify(jit_state_t *_jit, jit_code_t code)
case jit_code_bordi_d: case jit_code_bunordi_d:
mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl;
break;
case jit_code_allocar: /* synthesized instructions make it
* equivalent to jit_cc_a0_chg */
case jit_code_str_c: case jit_code_str_s: case jit_code_str_i:
case jit_code_str_l: case jit_code_str_f: case jit_code_str_d:
mask = jit_cc_a0_reg|jit_cc_a1_reg;
@ -1512,7 +1624,15 @@ _jit_optimize(jit_state_t *_jit)
break;
default:
#if JIT_HASH_CONSTS
if (mask & jit_cc_a1_flt) {
if (mask & jit_cc_a0_flt) {
node->u.p = jit_data(&node->u.f, sizeof(jit_float32_t), 4);
node->flag |= jit_flag_node | jit_flag_data;
}
else if (mask & jit_cc_a0_dbl) {
node->u.p = jit_data(&node->u.d, sizeof(jit_float64_t), 8);
node->flag |= jit_flag_node | jit_flag_data;
}
else if (mask & jit_cc_a1_flt) {
node->v.p = jit_data(&node->v.f, sizeof(jit_float32_t), 4);
node->flag |= jit_flag_node | jit_flag_data;
}
@ -1546,6 +1666,10 @@ _jit_optimize(jit_state_t *_jit)
(jit_cc_a1_reg|jit_cc_a1_chg))
jit_regset_setbit(&_jitc->function->regset,
jit_regno(node->v.w));
if ((mask & (jit_cc_a2_reg|jit_cc_a2_chg)) ==
(jit_cc_a2_reg|jit_cc_a2_chg))
jit_regset_setbit(&_jitc->function->regset,
jit_regno(node->w.w));
}
break;
}
@ -1632,8 +1756,14 @@ _jit_reglive(jit_state_t *_jit, jit_node_t *node)
else
jit_regset_setbit(&_jitc->reglive, node->v.w);
}
if ((value & jit_cc_a2_reg) && !(node->w.w & jit_regno_patch))
jit_regset_setbit(&_jitc->reglive, node->w.w);
if ((value & jit_cc_a2_reg) && !(node->w.w & jit_regno_patch)) {
if (value & jit_cc_a2_chg) {
jit_regset_clrbit(&_jitc->reglive, node->w.w);
jit_regset_setbit(&_jitc->regmask, node->w.w);
}
else
jit_regset_setbit(&_jitc->reglive, node->w.w);
}
if (jit_regset_set_p(&_jitc->regmask)) {
bmp_zero();
jit_update(node->next, &_jitc->reglive, &_jitc->regmask);
@ -2039,8 +2169,11 @@ _jit_setup(jit_state_t *_jit, jit_block_t *block)
if ((value & jit_cc_a2_reg) &&
!(node->w.w & jit_regno_patch) &&
jit_regset_tstbit(&regmask, node->w.w)) {
jit_regset_clrbit(&regmask, node->w.w);
jit_regset_setbit(&reglive, node->w.w);
live = !(value & jit_cc_a2_chg);
if (live || !jump)
jit_regset_clrbit(&regmask, node->w.w);
if (live)
jit_regset_setbit(&reglive, node->w.w);
}
if (value & jit_cc_a0_jmp)
jump = 1;
@ -2151,7 +2284,8 @@ _jit_update(jit_state_t *_jit, jit_node_t *node,
if (!(node->w.w & jit_regno_patch)) {
if (jit_regset_tstbit(mask, node->w.w)) {
jit_regset_clrbit(mask, node->w.w);
jit_regset_setbit(live, node->w.w);
if (!(value & jit_cc_a2_chg))
jit_regset_setbit(live, node->w.w);
}
}
}
@ -2654,6 +2788,11 @@ _redundant_store(jit_state_t *_jit, jit_node_t *node, jit_bool_t jump)
if (regno == jit_regno(iter->v.w))
return;
}
if ((spec & (jit_cc_a2_reg|jit_cc_a2_chg)) ==
(jit_cc_a2_reg|jit_cc_a2_chg)) {
if (regno == jit_regno(iter->w.w))
return;
}
break;
}
}
@ -2959,6 +3098,11 @@ _simplify(jit_state_t *_jit)
_jitc->values[regno].kind = 0;
++_jitc->gen[regno];
}
if (info & jit_cc_a2_chg) {
regno = jit_regno(node->w.w);
_jitc->values[regno].kind = 0;
++_jitc->gen[regno];
}
break;
}
}
@ -2994,6 +3138,9 @@ _register_change_p(jit_state_t *_jit, jit_node_t *node, jit_node_t *link,
else if ((value & jit_cc_a1_reg) && node->v.w == regno &&
(value & jit_cc_a1_chg))
return (jit_reg_change);
else if ((value & jit_cc_a2_reg) && node->w.w == regno &&
(value & jit_cc_a2_chg))
return (jit_reg_change);
}
}

5
size.c
View file

@ -80,6 +80,8 @@ main(int argc, char *argv[])
fprintf(fp, "#if defined(__ppc__)\n");
#elif defined(__powerpc__)
fprintf(fp, "#if defined(__powerpc__)\n");
fprintf(fp, "#if __BYTE_ORDER == %s\n",
__BYTE_ORDER == __BIG_ENDIAN ? "__BIG_ENDIAN" : "__LITTLE_ENDIAN");
#endif
fprintf(fp, "#define JIT_INSTR_MAX %d\n", max);
for (offset = 0; offset < jit_code_last_code; offset++)
@ -93,6 +95,7 @@ main(int argc, char *argv[])
#elif defined(__ppc__)
fprintf(fp, "#endif /* __ppc__ */\n");
#elif defined(__powerpc__)
fprintf(fp, "#endif /* __BYTE_ORDER */\n");
fprintf(fp, "#endif /* __powerpc__ */\n");
#endif
#if __X64 || __X32
@ -100,7 +103,7 @@ main(int argc, char *argv[])
fprintf(fp, "# endif /* __X64_32 */\n");
fprintf(fp, "#endif /* __X64 */\n");
# else
fprintf(fp, "#if __X32\n");
fprintf(fp, "#endif /* __X32 */\n");
# endif
#else
fprintf(fp, "#endif /* __WORDSIZE */\n");