1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-08 22:50:27 +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 * check/cva_list.c: New file implementing a test to ensure
the value returned by jit_va_start is a valid C va_list. 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 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. 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 * lib/Makefile.am: Bump library major. This is a preparation
for a rework that was due for quite some time, but that is 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 make that call after jit_ellipsis, but documentation
should be updated for it. 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 * lib/jit_aarch64-fpu.c, lib/jit_aarch64.c: Correct base
aarch64 varargs code. 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 * check/lightning.c: Clearly run check if clang is the system
compiler. 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: * 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. 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: * 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. 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: * 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. 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: * 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. 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 * lib/jit_ia64-fpu.c, lib/jit_ia64.c: Correct movi_d_w
and movi_f_w implementation to work when not using a and movi_f_w implementation to work when not using a
data buffer. This causes the check varargs.tst to data buffer. This causes the check varargs.tst to
work when passing "-d" to the lightning test tool. 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, * lib/jit_ia64.c: Implement inline assembly cache flush,
required on multiprocessor systems. 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: * 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. Add base support to jit vararg functions to the mips backend.
Currently only supported on the o32 abi, until access to a Currently only supported on the o32 abi, until access to a
n32 system is arranged. 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: * 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. 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: * 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. 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-cpu.c, lib/jit_arm-swf.c, lib/jit_arm-vfp.c,
lib/jit_arm.c: Add base support to jit vararg lib/jit_arm.c: Add base support to jit vararg
functions to the arm backend. 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-cpu.c, lib/jit_aarch64-fpu.c,
lib/jit_aarch64.c: Add base support to jit vararg lib/jit_aarch64.c: Add base support to jit vararg
functions to the aarch64 backend. 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, * include/lightning.h, include/lightning/jit_private.h,
lib/jit_names.c, lib/lightning.c: Add initial support 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> # include <lightning/jit_alpha.h>
#endif #endif
#define jit_flag_node 0x00000001 /* patch node not absolute */ #define jit_flag_node 0x0001 /* patch node not absolute */
#define jit_flag_patch 0x00000002 /* jump already patched */ #define jit_flag_patch 0x0002 /* jump already patched */
#define jit_flag_data 0x00000004 /* data in the constant pool */ #define jit_flag_data 0x0004 /* data in the constant pool */
#define jit_flag_use 0x00000008 /* do not remove marker label */ #define jit_flag_use 0x0008 /* do not remove marker label */
#define jit_flag_head 0x00100000 /* label reached by normal flow */ #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_R(index) jit_r(index)
#define JIT_V(index) jit_v(index) #define JIT_V(index) jit_v(index)
@ -200,14 +201,19 @@ typedef enum {
jit_code_prolog, jit_code_prolog,
#define jit_ellipsis() _jit_ellipsis(_jit) #define jit_ellipsis() _jit_ellipsis(_jit)
jit_code_ellipsis,
#define jit_allocai(u) _jit_allocai(_jit,u) #define jit_allocai(u) _jit_allocai(_jit,u)
#define jit_allocar(u, v) _jit_allocar(_jit,u,v) #define jit_allocar(u, v) _jit_allocar(_jit,u,v)
jit_code_allocai, jit_code_allocar,
#define jit_arg() _jit_arg(_jit) #define jit_arg() _jit_arg(_jit)
jit_code_arg,
#define jit_getarg_c(u,v) _jit_getarg_c(_jit,u,v) #define jit_getarg_c(u,v) _jit_getarg_c(_jit,u,v)
#define jit_getarg_uc(u,v) _jit_getarg_uc(_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_s(u,v) _jit_getarg_s(_jit,u,v)
#define jit_getarg_us(u,v) _jit_getarg_us(_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) #define jit_getarg_i(u,v) _jit_getarg_i(_jit,u,v)
#if __WORDSIZE == 32 #if __WORDSIZE == 32
# define jit_getarg(u,v) jit_getarg_i(u,v) # 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_ui(u,v) _jit_getarg_ui(_jit,u,v)
# define jit_getarg_l(u,v) _jit_getarg_l(_jit,u,v) # define jit_getarg_l(u,v) _jit_getarg_l(_jit,u,v)
#endif #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_putargr(u,v) _jit_putargr(_jit,u,v)
# define jit_putargi(u,v) _jit_putargi(_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) #define jit_va_start(u) jit_new_node_w(jit_code_va_start, u)
jit_code_va_start, jit_code_va_start,
@ -532,17 +540,24 @@ typedef enum {
jit_code_callr, jit_code_calli, jit_code_callr, jit_code_calli,
#define jit_prepare() _jit_prepare(_jit) #define jit_prepare() _jit_prepare(_jit)
jit_code_prepare,
#define jit_pushargr(u) _jit_pushargr(_jit,u) #define jit_pushargr(u) _jit_pushargr(_jit,u)
#define jit_pushargi(u) _jit_pushargi(_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_finishr(u) _jit_finishr(_jit,u)
#define jit_finishi(u) _jit_finishi(_jit,u) #define jit_finishi(u) _jit_finishi(_jit,u)
jit_code_finishr, jit_code_finishi,
#define jit_ret() _jit_ret(_jit) #define jit_ret() _jit_ret(_jit)
jit_code_ret,
#define jit_retr(u) _jit_retr(_jit,u) #define jit_retr(u) _jit_retr(_jit,u)
#define jit_reti(u) _jit_reti(_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_c(u) _jit_retval_c(_jit,u)
#define jit_retval_uc(u) _jit_retval_uc(_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_s(u) _jit_retval_s(_jit,u)
#define jit_retval_us(u) _jit_retval_us(_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) #define jit_retval_i(u) _jit_retval_i(_jit,u)
#if __WORDSIZE == 32 #if __WORDSIZE == 32
# define jit_retval(u) jit_retval_i(u) # 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_ui(u) _jit_retval_ui(_jit,u)
# define jit_retval_l(u) _jit_retval_l(_jit,u) # define jit_retval_l(u) _jit_retval_l(_jit,u)
#endif #endif
/* Usually should not need to call directly, but useful if need jit_code_retval_i, jit_code_retval_ui,
* to get a label just before a jit_prolog() call */ jit_code_retval_l,
#define jit_epilog() _jit_epilog(_jit) #define jit_epilog() _jit_epilog(_jit)
jit_code_epilog, jit_code_epilog,
#define jit_arg_f() _jit_arg_f(_jit) #define jit_arg_f() _jit_arg_f(_jit)
jit_code_arg_f,
#define jit_getarg_f(u,v) _jit_getarg_f(_jit,u,v) #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_putargr_f(u,v) _jit_putargr_f(_jit,u,v)
#define jit_putargi_f(u,v) _jit_putargi_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_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) #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_pushargr_f(u) _jit_pushargr_f(_jit,u)
#define jit_pushargi_f(u) _jit_pushargi_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_retr_f(u) _jit_retr_f(_jit,u)
#define jit_reti_f(u) _jit_reti_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) #define jit_retval_f(u) _jit_retval_f(_jit,u)
jit_code_retval_f,
#define jit_arg_d() _jit_arg_d(_jit) #define jit_arg_d() _jit_arg_d(_jit)
jit_code_arg_d,
#define jit_getarg_d(u,v) _jit_getarg_d(_jit,u,v) #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_putargr_d(u,v) _jit_putargr_d(_jit,u,v)
#define jit_putargi_d(u,v) _jit_putargi_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_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) #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_pushargr_d(u) _jit_pushargr_d(_jit,u)
#define jit_pushargi_d(u) _jit_pushargi_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_retr_d(u) _jit_retr_d(_jit,u)
#define jit_reti_d(u) _jit_reti_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) #define jit_retval_d(u) _jit_retval_d(_jit,u)
jit_code_retval_d,
/* Special internal backend specific codes */ /* Special internal backend specific codes */
jit_code_movr_w_f, jit_code_movr_ww_d, /* w* -> f|d */ 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_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) #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_last_code
} jit_code_t; } 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) #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, extern jit_node_t *_jit_new_node_w(jit_state_t*, jit_code_t,
jit_word_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) #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, extern jit_node_t *_jit_new_node_p(jit_state_t*, jit_code_t,
jit_pointer_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) #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, extern jit_node_t *_jit_new_node_wp(jit_state_t*,jit_code_t,
jit_word_t, jit_pointer_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) #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, extern jit_node_t *_jit_new_node_pw(jit_state_t*,jit_code_t,
jit_pointer_t, jit_word_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->regarg, regno) && \
!jit_regset_tstbit(&_jitc->regsav, 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 * 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_int 0x00000010 /* arg0 is immediate word */
#define jit_cc_a0_flt 0x00000020 /* arg0 is immediate float */ #define jit_cc_a0_flt 0x00000020 /* arg0 is immediate float */
#define jit_cc_a0_dbl 0x00000040 /* arg0 is immediate double */ #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_reg 0x00000100 /* arg1 is a register */
#define jit_cc_a1_chg 0x00000200 /* arg1 is modified */ #define jit_cc_a1_chg 0x00000200 /* arg1 is modified */
#define jit_cc_a1_int 0x00001000 /* arg1 is immediate word */ #define jit_cc_a1_int 0x00001000 /* arg1 is immediate word */
#define jit_cc_a1_flt 0x00002000 /* arg1 is immediate float */ #define jit_cc_a1_flt 0x00002000 /* arg1 is immediate float */
#define jit_cc_a1_dbl 0x00004000 /* arg1 is immediate double */ #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_reg 0x00010000 /* arg2 is a register */
#define jit_cc_a2_chg 0x00020000 /* arg2 is modified */ #define jit_cc_a2_chg 0x00020000 /* arg2 is modified */
#define jit_cc_a2_int 0x00100000 /* arg2 is immediate word */ #define jit_cc_a2_int 0x00100000 /* arg2 is immediate word */
@ -301,14 +367,12 @@ struct jit_line {
struct jit_node { struct jit_node {
jit_node_t *next; jit_node_t *next;
jit_code_t code; 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 u;
jit_data_t v; jit_data_t v;
jit_data_t w; jit_data_t w;
jit_node_t *link; jit_node_t *link;
#if DEVEL_DISASSEMBLER
jit_uword_t offset;
#endif
}; };
struct jit_block { struct jit_block {
@ -347,6 +411,7 @@ struct jit_function {
jit_int32_t aoff; jit_int32_t aoff;
jit_int32_t alen; jit_int32_t alen;
jit_int32_t call; jit_int32_t call;
jit_int32_t argn; /* for debug output */
} self; } self;
struct { struct {
jit_int32_t argi; jit_int32_t argi;
@ -397,12 +462,13 @@ struct jit_compiler {
#endif #endif
jit_node_t *head; jit_node_t *head;
jit_node_t *tail; jit_node_t *tail;
jit_node_t *prepare; /* inside prepare/finish* block */
jit_uint32_t realize : 1; /* jit_realize() called? */ jit_uint32_t realize : 1; /* jit_realize() called? */
jit_uint32_t dataset : 1; /* jit_dataset() called? */ jit_uint32_t dataset : 1; /* jit_dataset() called? */
jit_uint32_t done : 1; /* emit state finished */ jit_uint32_t done : 1; /* emit state finished */
jit_uint32_t emit : 1; /* emit state entered */ jit_uint32_t emit : 1; /* emit state entered */
jit_uint32_t again : 1; /* start over emiting function */ 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 #if DEBUG
jit_uint32_t getreg : 1; jit_uint32_t getreg : 1;
#endif #endif
@ -548,6 +614,9 @@ extern void jit_get_cpu(void);
#define jit_init() _jit_init(_jit) #define jit_init() _jit_init(_jit)
extern void _jit_init(jit_state_t*); 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) #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); 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 extern void
_jit_link_label(jit_state_t*,jit_node_t*); _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) #define jit_reglive(node) _jit_reglive(_jit, node)
extern void extern void
_jit_reglive(jit_state_t*, jit_node_t*); _jit_reglive(jit_state_t*, jit_node_t*);

View file

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

View file

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

View file

@ -177,6 +177,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff, jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t)); _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); _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog); jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset; _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; default: _jitc->function->self.aoff &= -8; break;
} }
_jitc->function->self.aoff -= length; _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); 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; jit_int32_t r0, r1;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) { if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1; _jitc->function->allocar = 1;
@ -233,69 +242,82 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
#endif #endif
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(r0); jit_unget_reg(r0);
jit_dec_synth();
} }
void void
_jit_ret(jit_state_t *_jit) _jit_ret(jit_state_t *_jit)
{ {
jit_node_t *instr; jit_node_t *instr;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */ /* jump to epilog */
instr = jit_jmpi(); instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog); jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
} }
void void
_jit_retr(jit_state_t *_jit, jit_int32_t u) _jit_retr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr, u);
if (JIT_RET != u) if (JIT_RET != u)
jit_movr(JIT_RET, u); jit_movr(JIT_RET, u);
else else
jit_live(JIT_RET); jit_live(JIT_RET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti(jit_state_t *_jit, jit_word_t u) _jit_reti(jit_state_t *_jit, jit_word_t u)
{ {
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u); jit_movi(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u) _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_f, u);
if (u != JIT_FRET) if (u != JIT_FRET)
jit_movr_f(JIT_FRET, u); jit_movr_f(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u) _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_movi_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u) _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_d, u);
if (u != JIT_FRET) if (u != JIT_FRET)
jit_movr_d(JIT_FRET, u); jit_movr_d(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u) _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_movi_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
@ -319,11 +341,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void void
_jit_ellipsis(jit_state_t *_jit) _jit_ellipsis(jit_state_t *_jit)
{ {
jit_inc_synth(ellipsis);
if (_jitc->prepare) { if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs)); assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs; _jitc->function->call.call |= jit_call_varargs;
} }
else { else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
_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 else
_jitc->function->vafp = 0; _jitc->function->vafp = 0;
} }
jit_dec_synth();
} }
jit_node_t * jit_node_t *
_jit_arg(jit_state_t *_jit) _jit_arg(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function); assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
@ -358,13 +385,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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_node_t *
_jit_arg_f(jit_state_t *_jit) _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);
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
if (jit_arg_f_reg_p(_jitc->function->self.argf)) 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; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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_node_t *
_jit_arg_d(jit_state_t *_jit) _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);
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
if (jit_arg_f_reg_p(_jitc->function->self.argf)) 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; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, JIT_RA0 - v->u.w); jit_extr_c(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_c(u, JIT_FP, v->u.w); jit_ldxi_c(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, JIT_RA0 - v->u.w); jit_extr_uc(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_uc(u, JIT_FP, v->u.w); jit_ldxi_uc(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, JIT_RA0 - v->u.w); jit_extr_s(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_s(u, JIT_FP, v->u.w); jit_ldxi_s(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, JIT_RA0 - v->u.w); jit_extr_us(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_us(u, JIT_FP, v->u.w); jit_ldxi_us(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_i(u, JIT_RA0 - v->u.w); jit_extr_i(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_i(u, JIT_FP, v->u.w); jit_ldxi_i(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, JIT_RA0 - v->u.w); jit_extr_ui(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_ui(u, JIT_FP, v->u.w); jit_ldxi_ui(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(u, JIT_RA0 - v->u.w); jit_movr(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_l(u, JIT_FP, v->u.w); jit_ldxi_l(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(JIT_RA0 - v->u.w, u); jit_movr(JIT_RA0 - v->u.w, u);
else else
jit_stxi(v->u.w, JIT_FP, u); jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -476,6 +530,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi(JIT_RA0 - v->u.w, u); jit_movi(JIT_RA0 - v->u.w, u);
else { 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_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_f(u, JIT_FA0 - v->u.w); jit_movr_f(u, JIT_FA0 - v->u.w);
else else
jit_ldxi_f(u, JIT_FP, v->u.w); jit_ldxi_f(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(JIT_FA0 - v->u.w, u); jit_movr_f(JIT_FA0 - v->u.w, u);
else else
jit_stxi_f(v->u.w, JIT_FP, u); jit_stxi_f(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -511,6 +571,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movi_f(JIT_FA0 - v->u.w, u); jit_movi_f(JIT_FA0 - v->u.w, u);
else { 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_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, JIT_FA0 - v->u.w); jit_movr_d(u, JIT_FA0 - v->u.w);
else else
jit_ldxi_d(u, JIT_FP, v->u.w); jit_ldxi_d(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_d(JIT_FA0 - v->u.w, u); jit_movr_d(JIT_FA0 - v->u.w, u);
else else
jit_stxi_d(v->u.w, JIT_FP, u); jit_stxi_d(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -546,6 +612,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi_d(JIT_FA0 - v->u.w, u); jit_movi_d(JIT_FA0 - v->u.w, u);
else { 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_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(JIT_RA0 - _jitc->function->call.argi, u); jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_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); jit_stxi(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
@ -575,6 +646,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(JIT_RA0 - _jitc->function->call.argi, u); jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
@ -586,12 +659,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno); jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u); jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_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); jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
@ -607,6 +684,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u); jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
@ -618,12 +697,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_unget_reg(regno); jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_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); jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
@ -639,6 +722,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
@ -650,6 +735,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
jit_unget_reg(regno); jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
jit_bool_t jit_bool_t
@ -676,6 +762,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
node = jit_callr(r0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
} }
jit_node_t * jit_node_t *
@ -691,6 +779,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{ {
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
return (node); return (node);
} }
void void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) _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_extr_c(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) _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_extr_uc(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) _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_extr_s(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) _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_extr_us(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) _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_extr_i(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) _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_extr_ui(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_l, r0);
if (r0 != JIT_RET) if (r0 != JIT_RET)
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_f, r0);
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_f(r0, JIT_FRET); jit_movr_f(r0, JIT_FRET);
jit_dec_synth();
} }
void void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_d, r0);
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET); jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
} }
jit_pointer_t jit_pointer_t
@ -771,9 +879,15 @@ _emit_code(jit_state_t *_jit)
jit_node_t *node; jit_node_t *node;
jit_uint8_t *data; jit_uint8_t *data;
jit_word_t word; jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t const_offset; jit_int32_t const_offset;
jit_int32_t patch_offset; jit_int32_t patch_offset;
} undo; } undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL; _jitc->function = NULL;
@ -882,12 +996,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \ patch(word, node); \
} \ } \
break break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) { for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end) if (_jit->pc.uc >= _jitc->code.end)
return (NULL); return (NULL);
#if DEVEL_DISASSEMBLER #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 #endif
value = jit_classify(node->code); value = jit_classify(node->code);
jit_regarg_set(node, value); jit_regarg_set(node, value);
@ -1293,6 +1411,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w; _jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node; undo.node = node;
undo.word = _jit->pc.w; undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset; undo.patch_offset = _jitc->patches.offset;
restart_function: restart_function:
_jitc->again = 0; _jitc->again = 0;
@ -1310,6 +1431,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch; temp->flag &= ~jit_flag_patch;
node = undo.node; node = undo.node;
_jit->pc.w = undo.word; _jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset; _jitc->patches.offset = undo.patch_offset;
goto restart_function; goto restart_function;
} }
@ -1328,16 +1452,39 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d: case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w)); vaarg_d(rn(node->u.w), rn(node->v.w));
break; 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:
case jit_code_arg_f: case jit_code_arg_d: case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end: 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; break;
default: default:
abort(); abort();
} }
jit_regarg_clr(node, value); jit_regarg_clr(node, value);
assert(_jitc->regarg == 0); assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */ /* update register live state */
jit_reglive(node); jit_reglive(node);
} }

View file

@ -10,7 +10,19 @@
0, /* #note */ 0, /* #note */
0, /* label */ 0, /* label */
76, /* prolog */ 76, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */ 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_start */
0, /* va_arg */ 0, /* va_arg */
0, /* va_arg_d */ 0, /* va_arg_d */
@ -179,8 +191,26 @@
36, /* jmpi */ 36, /* jmpi */
8, /* callr */ 8, /* callr */
36, /* calli */ 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 */ 68, /* epilog */
0, /* arg_f */ 0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
8, /* addr_f */ 8, /* addr_f */
32, /* addi_f */ 32, /* addi_f */
8, /* subr_f */ 8, /* subr_f */
@ -263,7 +293,15 @@
36, /* bordi_f */ 36, /* bordi_f */
12, /* bunordr_f */ 12, /* bunordr_f */
36, /* bunordi_f */ 36, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */ 0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
8, /* addr_d */ 8, /* addr_d */
28, /* addi_d */ 28, /* addi_d */
8, /* subr_d */ 8, /* subr_d */
@ -346,6 +384,11 @@
32, /* bordi_d */ 32, /* bordi_d */
12, /* bunordr_d */ 12, /* bunordr_d */
32, /* bunordi_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_w_f */
0, /* movr_ww_d */ 0, /* movr_ww_d */
0, /* movr_w_d */ 0, /* movr_w_d */
@ -355,6 +398,4 @@
0, /* movi_d_ww */ 0, /* movi_d_ww */
0, /* movr_d_w */ 0, /* movr_d_w */
0, /* movi_d_w */ 0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */ #endif /* __WORDSIZE */

View file

@ -177,6 +177,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff, jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t)); _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); _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog); jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset; _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; default: _jitc->function->self.aoff &= -8; break;
} }
_jitc->function->self.aoff -= length; _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); 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; jit_int32_t reg;
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) { if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1; _jitc->function->allocar = 1;
} }
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
jit_negr(reg, v); jit_negr(reg, v);
jit_andi(reg, reg, -8); jit_andi(reg, reg, -8);
jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
jit_addr(u, u, reg); jit_addr(u, u, reg);
jit_addr(JIT_SP, JIT_SP, reg); jit_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg); jit_unget_reg(reg);
jit_dec_synth();
} }
void void
_jit_ret(jit_state_t *_jit) _jit_ret(jit_state_t *_jit)
{ {
jit_node_t *instr; jit_node_t *instr;
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
jit_inc_synth(ret);
/* jump to epilog */ /* jump to epilog */
instr = jit_jmpi(); instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog); jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
} }
void void
_jit_retr(jit_state_t *_jit, jit_int32_t u) _jit_retr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr, u);
if (JIT_RET != u) if (JIT_RET != u)
jit_movr(JIT_RET, u); jit_movr(JIT_RET, u);
else else
jit_live(JIT_RET); jit_live(JIT_RET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti(jit_state_t *_jit, jit_word_t u) _jit_reti(jit_state_t *_jit, jit_word_t u)
{ {
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u); jit_movi(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u) _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_f, u);
if (u != JIT_FRET) if (u != JIT_FRET)
jit_movr_f(JIT_FRET, u); jit_movr_f(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u) _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_movi_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u) _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_d, u);
if (u != JIT_FRET) if (u != JIT_FRET)
jit_movr_d(JIT_FRET, u); jit_movr_d(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u) _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_movi_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
@ -310,11 +329,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void void
_jit_ellipsis(jit_state_t *_jit) _jit_ellipsis(jit_state_t *_jit)
{ {
jit_inc_synth(jit_code_ellipsis);
if (_jitc->prepare) { if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs)); assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs; _jitc->function->call.call |= jit_call_varargs;
} }
else { else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
_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->vaoff = jit_allocai(sizeof(jit_va_list_t));
_jitc->function->vagp = _jitc->function->self.argi; _jitc->function->vagp = _jitc->function->self.argi;
} }
jit_dec_synth();
} }
jit_node_t * jit_node_t *
_jit_arg(jit_state_t *_jit) _jit_arg(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++; offset = _jitc->function->self.argi++;
@ -335,13 +359,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += 8; _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_node_t *
_jit_arg_f(jit_state_t *_jit) _jit_arg_f(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
if (jit_arg_f_reg_p(_jitc->function->self.argi)) if (jit_arg_f_reg_p(_jitc->function->self.argi))
offset = _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; offset = _jitc->function->self.size;
_jitc->function->self.size += 8; _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_node_t *
_jit_arg_d(jit_state_t *_jit) _jit_arg_d(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
if (jit_arg_f_reg_p(_jitc->function->self.argi)) if (jit_arg_f_reg_p(_jitc->function->self.argi))
offset = _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; offset = _jitc->function->self.size;
_jitc->function->self.size += 8; _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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _A0 - v->u.w); jit_extr_c(u, _A0 - v->u.w);
else else
jit_ldxi_c(u, _FP, v->u.w + C_DISP); jit_ldxi_c(u, _FP, v->u.w + C_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _A0 - v->u.w); jit_extr_uc(u, _A0 - v->u.w);
else else
jit_ldxi_uc(u, _FP, v->u.w + C_DISP); jit_ldxi_uc(u, _FP, v->u.w + C_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _A0 - v->u.w); jit_extr_s(u, _A0 - v->u.w);
else else
jit_ldxi_s(u, _FP, v->u.w + S_DISP); jit_ldxi_s(u, _FP, v->u.w + S_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _A0 - v->u.w); jit_extr_us(u, _A0 - v->u.w);
else else
jit_ldxi_us(u, _FP, v->u.w + S_DISP); jit_ldxi_us(u, _FP, v->u.w + S_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_i(u, _A0 - v->u.w); jit_extr_i(u, _A0 - v->u.w);
else else
jit_ldxi_i(u, _FP, v->u.w + I_DISP); jit_ldxi_i(u, _FP, v->u.w + I_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _A0 - v->u.w); jit_extr_ui(u, _A0 - v->u.w);
else else
jit_ldxi_ui(u, _FP, v->u.w + I_DISP); jit_ldxi_ui(u, _FP, v->u.w + I_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(u, _A0 - v->u.w); jit_movr(u, _A0 - v->u.w);
else else
jit_ldxi_l(u, _FP, v->u.w); jit_ldxi_l(u, _FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(_A0 - v->u.w, u); jit_movr(_A0 - v->u.w, u);
else else
jit_stxi(v->u.w, _FP, u); jit_stxi(v->u.w, _FP, u);
jit_dec_synth();
} }
void void
@ -451,6 +502,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi(_A0 - v->u.w, u); jit_movi(_A0 - v->u.w, u);
else { 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_stxi(v->u.w, _FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(u, _F16 - v->u.w); jit_movr_f(u, _F16 - v->u.w);
else else
jit_ldxi_f(u, _FP, v->u.w + F_DISP); jit_ldxi_f(u, _FP, v->u.w + F_DISP);
jit_dec_synth();
} }
void void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(_F16 - v->u.w, u); jit_movr_f(_F16 - v->u.w, u);
else else
jit_stxi_f(v->u.w, _FP, u + F_DISP); jit_stxi_f(v->u.w, _FP, u + F_DISP);
jit_dec_synth();
} }
void void
@ -486,6 +543,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movi_f(_F16 - v->u.w, u); jit_movi_f(_F16 - v->u.w, u);
else { 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_stxi_f(v->u.w, _FP, regno + F_DISP);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, _F16 - v->u.w); jit_movr_d(u, _F16 - v->u.w);
else else
jit_ldxi_d(u, _FP, v->u.w); jit_ldxi_d(u, _FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(_F16 - v->u.w, u); jit_movr_d(_F16 - v->u.w, u);
else else
jit_stxi_d(v->u.w, _FP, u); jit_stxi_d(v->u.w, _FP, u);
jit_dec_synth();
} }
void void
@ -521,6 +584,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movi_d(_F16 - v->u.w, u); jit_movi_d(_F16 - v->u.w, u);
else { 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_stxi_d(v->u.w, _FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_A0 - _jitc->function->call.argi, u); jit_movr(_A0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_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); jit_stxi(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += 8; _jitc->function->call.size += 8;
} }
jit_dec_synth();
} }
void void
@ -550,6 +618,8 @@ _jit_pushargi(jit_state_t *_jit, jit_int64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_A0 - _jitc->function->call.argi, u); jit_movi(_A0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
@ -561,12 +631,15 @@ _jit_pushargi(jit_state_t *_jit, jit_int64_t u)
_jitc->function->call.size += 8; _jitc->function->call.size += 8;
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argi)) { if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
jit_movr_f(_F16 - _jitc->function->call.argi, u); jit_movr_f(_F16 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_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); jit_stxi_f(_jitc->function->call.size + F_DISP, JIT_SP, u);
_jitc->function->call.size += 8; _jitc->function->call.size += 8;
} }
jit_dec_synth();
} }
void void
@ -582,6 +656,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argi)) { if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
jit_movi_f(_F16 - _jitc->function->call.argi, u); jit_movi_f(_F16 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
@ -593,12 +669,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
_jitc->function->call.size += 8; _jitc->function->call.size += 8;
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argi)) { if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
jit_movr_d(_F16 - _jitc->function->call.argi, u); jit_movr_d(_F16 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_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); jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += 8; _jitc->function->call.size += 8;
} }
jit_dec_synth();
} }
void void
@ -614,6 +694,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argi)) { if (jit_arg_f_reg_p(_jitc->function->call.argi)) {
jit_movi_d(_F16 - _jitc->function->call.argi, u); jit_movi_d(_F16 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
@ -625,6 +707,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
_jitc->function->call.size += 8; _jitc->function->call.size += 8;
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
jit_bool_t jit_bool_t
@ -653,86 +736,106 @@ void
_jit_finishr(jit_state_t *_jit, jit_int32_t r0) _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_node_t *call; jit_node_t *call;
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0); call = jit_callr(r0);
call->v.w = call->w.w = _jitc->function->self.argi; call->v.w = call->w.w = _jitc->function->self.argi;
_jitc->function->call.argi = _jitc->function->call.size = 0; _jitc->function->call.argi = _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
} }
jit_node_t * jit_node_t *
_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{ {
jit_node_t *call; jit_node_t *call;
assert(_jitc->function != NULL); assert(_jitc->function != NULL);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
call = jit_calli(i0); call = jit_calli(i0);
call->v.w = call->w.w = _jitc->function->self.argf; call->v.w = call->w.w = _jitc->function->self.argf;
_jitc->function->call.argi = _jitc->function->call.size = 0; _jitc->function->call.argi = _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
return (call); return (call);
} }
void void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) _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_extr_c(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) _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_extr_uc(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) _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_extr_s(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) _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_extr_us(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) _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_extr_i(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) _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_extr_ui(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_l, r0);
if (r0 != JIT_RET) if (r0 != JIT_RET)
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_f, r0);
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_f(r0, JIT_FRET); jit_movr_f(r0, JIT_FRET);
jit_dec_synth();
} }
void void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_d, r0);
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET); jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
} }
jit_pointer_t jit_pointer_t
@ -747,9 +850,15 @@ _emit_code(jit_state_t *_jit)
jit_node_t *node; jit_node_t *node;
jit_uint8_t *data; jit_uint8_t *data;
jit_word_t word; jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t const_offset; jit_int32_t const_offset;
jit_int32_t patch_offset; jit_int32_t patch_offset;
} undo; } undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL; _jitc->function = NULL;
@ -841,12 +950,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \ patch(word, node); \
} \ } \
break break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) { for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end) if (_jit->pc.uc >= _jitc->code.end)
return (NULL); return (NULL);
#if DEVEL_DISASSEMBLER #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 #endif
value = jit_classify(node->code); value = jit_classify(node->code);
jit_regarg_set(node, value); jit_regarg_set(node, value);
@ -1252,6 +1365,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w; _jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node; undo.node = node;
undo.word = _jit->pc.w; undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset; undo.patch_offset = _jitc->patches.offset;
restart_function: restart_function:
_jitc->again = 0; _jitc->again = 0;
@ -1269,6 +1385,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch; temp->flag &= ~jit_flag_patch;
node = undo.node; node = undo.node;
_jit->pc.w = undo.word; _jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset; _jitc->patches.offset = undo.patch_offset;
goto restart_function; goto restart_function;
} }
@ -1287,10 +1406,33 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d: case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w)); vaarg_d(rn(node->u.w), rn(node->v.w));
break; 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:
case jit_code_arg_f: case jit_code_arg_d: case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end: 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; break;
default: default:
abort(); abort();
@ -1311,6 +1453,7 @@ _emit_code(jit_state_t *_jit)
} }
jit_regarg_clr(node, value); jit_regarg_clr(node, value);
assert(_jitc->regarg == (jit_carry == _NOREG) ? 0 : (1 << jit_carry)); assert(_jitc->regarg == (jit_carry == _NOREG) ? 0 : (1 << jit_carry));
assert(_jitc->synth == 0);
/* update register live state */ /* update register live state */
jit_reglive(node); jit_reglive(node);
} }

View file

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

View file

@ -59,6 +59,12 @@ typedef jit_pointer_t jit_va_list;
/* /*
* Prototypes * 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) #define jit_get_reg_pair() _jit_get_reg_pair(_jit)
static jit_int32_t _jit_get_reg_pair(jit_state_t*); static jit_int32_t _jit_get_reg_pair(jit_state_t*);
#define jit_unget_reg_pair(rn) _jit_unget_reg_pair(_jit,rn) #define jit_unget_reg_pair(rn) _jit_unget_reg_pair(_jit,rn)
@ -80,6 +86,7 @@ extern void __clear_cache(void *, void *);
#endif #endif
#define PROTO 1 #define PROTO 1
# include "jit_rewind.c"
# include "jit_arm-cpu.c" # include "jit_arm-cpu.c"
# include "jit_arm-swf.c" # include "jit_arm-swf.c"
# include "jit_arm-vfp.c" # include "jit_arm-vfp.c"
@ -250,6 +257,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff, jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t)); _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); _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog); jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset; _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; default: _jitc->function->self.aoff &= -8; break;
} }
_jitc->function->self.aoff -= length; _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); 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; jit_int32_t reg;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) { if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1; _jitc->function->allocar = 1;
} }
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
jit_negr(reg, v); jit_negr(reg, v);
jit_andi(reg, reg, -8); jit_andi(reg, reg, -8);
jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
jit_addr(u, u, reg); jit_addr(u, u, reg);
jit_addr(JIT_SP, JIT_SP, reg); jit_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg); jit_unget_reg(reg);
jit_dec_synth();
} }
void void
_jit_ret(jit_state_t *_jit) _jit_ret(jit_state_t *_jit)
{ {
jit_node_t *instr; jit_node_t *instr;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */ /* jump to epilog */
instr = jit_jmpi(); instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog); jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
} }
void void
_jit_retr(jit_state_t *_jit, jit_int32_t u) _jit_retr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr, u);
if (JIT_RET != u) if (JIT_RET != u)
jit_movr(JIT_RET, u); jit_movr(JIT_RET, u);
else else
jit_live(JIT_RET); jit_live(JIT_RET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti(jit_state_t *_jit, jit_word_t u) _jit_reti(jit_state_t *_jit, jit_word_t u)
{ {
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u); jit_movi(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u) _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_f, u);
if (jit_cpu.abi) { if (jit_cpu.abi) {
if (u != JIT_FRET) if (u != JIT_FRET)
jit_movr_f(JIT_FRET, u); 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_live(JIT_RET);
} }
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u) _jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_inc_synth_f(reti_f, u);
if (jit_cpu.abi) if (jit_cpu.abi)
jit_movi_f(JIT_FRET, u); jit_movi_f(JIT_FRET, u);
else else
jit_movi_f_w(JIT_RET, u); jit_movi_f_w(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u) _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_d, u);
if (jit_cpu.abi) { if (jit_cpu.abi) {
if (u != JIT_FRET) if (u != JIT_FRET)
jit_movr_d(JIT_FRET, u); 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_live(JIT_RET);
} }
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u) _jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_inc_synth_d(reti_d, u);
if (jit_cpu.abi) if (jit_cpu.abi)
jit_movi_d(JIT_FRET, u); jit_movi_d(JIT_FRET, u);
else else
jit_movi_d_ww(JIT_RET, _R1, u); jit_movi_d_ww(JIT_RET, _R1, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void 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)); return (jit_arg_reg_p(u->u.w));
} }
void static jit_node_t *
_jit_ellipsis(jit_state_t *_jit) _jit_make_arg(jit_state_t *_jit, jit_node_t *node)
{ {
if (_jitc->prepare) { jit_int32_t offset;
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);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++; offset = _jitc->function->self.argi++;
else { else {
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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_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; jit_int32_t offset;
assert(_jitc->function);
if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) { if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
if (jit_arg_f_reg_p(_jitc->function->self.argf)) { if (jit_arg_f_reg_p(_jitc->function->self.argf)) {
offset = _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; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float32_t); _jitc->function->self.size += sizeof(jit_float32_t);
done: 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_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; jit_int32_t offset;
assert(_jitc->function);
if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) { if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
if (jit_arg_d_reg_p(_jitc->function->self.argf)) { if (jit_arg_d_reg_p(_jitc->function->self.argf)) {
if (_jitc->function->self.argf & 1) if (_jitc->function->self.argf & 1)
@ -494,79 +512,147 @@ _jit_arg_d(jit_state_t *_jit)
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t); _jitc->function->self.size += sizeof(jit_float64_t);
done: 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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_swf_p()) if (jit_swf_p())
jit_ldxi_c(u, JIT_FP, arg_offset(v->u.w)); jit_ldxi_c(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w)) else if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, JIT_RA0 - v->u.w); jit_extr_c(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_c(u, JIT_FP, v->u.w); jit_ldxi_c(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_swf_p()) if (jit_swf_p())
jit_ldxi_uc(u, JIT_FP, arg_offset(v->u.w)); jit_ldxi_uc(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w)) else if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, JIT_RA0 - v->u.w); jit_extr_uc(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_uc(u, JIT_FP, v->u.w); jit_ldxi_uc(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_swf_p()) if (jit_swf_p())
jit_ldxi_s(u, JIT_FP, arg_offset(v->u.w)); jit_ldxi_s(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w)) else if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, JIT_RA0 - v->u.w); jit_extr_s(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_s(u, JIT_FP, v->u.w); jit_ldxi_s(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_swf_p()) if (jit_swf_p())
jit_ldxi_us(u, JIT_FP, arg_offset(v->u.w)); jit_ldxi_us(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w)) else if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, JIT_RA0 - v->u.w); jit_extr_us(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_us(u, JIT_FP, v->u.w); jit_ldxi_us(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_swf_p()) if (jit_swf_p())
jit_ldxi_i(u, JIT_FP, arg_offset(v->u.w)); jit_ldxi_i(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w)) else if (jit_arg_reg_p(v->u.w))
jit_movr(u, JIT_RA0 - v->u.w); jit_movr(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_i(u, JIT_FP, v->u.w); jit_ldxi_i(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_swf_p()) if (jit_swf_p())
jit_stxi(arg_offset(v->u.w), JIT_FP, u); jit_stxi(arg_offset(v->u.w), JIT_FP, u);
else if (jit_arg_reg_p(v->u.w)) else if (jit_arg_reg_p(v->u.w))
jit_movr(JIT_RA0 - v->u.w, u); jit_movr(JIT_RA0 - v->u.w, u);
else else
jit_stxi(v->u.w, JIT_FP, u); jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -574,6 +660,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_swf_p()) { if (jit_swf_p()) {
regno = jit_get_reg(jit_class_gpr); regno = jit_get_reg(jit_class_gpr);
jit_movi(regno, u); 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_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); 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)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(u, JIT_FA0 - v->u.w); jit_movr_f(u, JIT_FA0 - v->u.w);
else else
@ -608,12 +697,14 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
else else
jit_ldxi_f(u, JIT_FP, v->u.w); jit_ldxi_f(u, JIT_FP, v->u.w);
} }
jit_dec_synth();
} }
void void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_cpu.abi) { if (jit_cpu.abi) {
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(JIT_FA0 - v->u.w, u); 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 else
jit_stxi_f(v->u.w, JIT_FP, u); jit_stxi_f(v->u.w, JIT_FP, u);
} }
jit_dec_synth();
} }
void void
@ -635,6 +727,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_cpu.abi) { if (jit_cpu.abi) {
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movi_f(JIT_FA0 - v->u.w, u); 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_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); 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)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, JIT_FA0 - v->u.w); jit_movr_d(u, JIT_FA0 - v->u.w);
else else
@ -680,12 +775,14 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
else else
jit_ldxi_d(u, JIT_FP, v->u.w); jit_ldxi_d(u, JIT_FP, v->u.w);
} }
jit_dec_synth();
} }
void void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_cpu.abi) { if (jit_cpu.abi) {
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(JIT_FA0 - v->u.w, u); 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 else
jit_stxi_d(v->u.w, JIT_FP, u); jit_stxi_d(v->u.w, JIT_FP, u);
} }
jit_dec_synth();
} }
void void
@ -707,6 +805,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_cpu.abi) { if (jit_cpu.abi) {
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movi_d(JIT_FA0 - v->u.w, u); 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_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(JIT_RA0 - _jitc->function->call.argi, u); jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_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); jit_stxi(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
@ -753,6 +856,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(JIT_RA0 - _jitc->function->call.argi, u); jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
@ -764,28 +869,33 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno); jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); 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_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
if (jit_arg_f_reg_p(_jitc->function->call.argf)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u); jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
return; goto done;
} }
} }
else { else {
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr_f_w(JIT_RA0 - _jitc->function->call.argi, u); jit_movr_f_w(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
return; goto done;
} }
} }
jit_stxi_f(_jitc->function->call.size, JIT_SP, u); jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
done:
jit_dec_synth();
} }
void void
@ -793,6 +903,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); 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_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
if (jit_arg_f_reg_p(_jitc->function->call.argf)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
/* cannot jit_movi_f in the argument register because /* 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_movr_f(JIT_FA0 - _jitc->function->call.argf, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
return; goto done;
} }
} }
else { else {
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi_f_w(JIT_RA0 - _jitc->function->call.argi, u); jit_movi_f_w(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
return; goto done;
} }
} }
regno = jit_get_reg(jit_class_fpr); 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_stxi_f(_jitc->function->call.size, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
done:
jit_dec_synth();
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); 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_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
if (jit_arg_d_reg_p(_jitc->function->call.argf)) { if (jit_arg_d_reg_p(_jitc->function->call.argf)) {
if (_jitc->function->call.argf & 1) if (_jitc->function->call.argf & 1)
++_jitc->function->call.argf; ++_jitc->function->call.argf;
jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
_jitc->function->call.argf += 2; _jitc->function->call.argf += 2;
return; goto done;
} }
} }
else { else {
@ -842,13 +958,15 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
JIT_RA0 - (_jitc->function->call.argi + 1), JIT_RA0 - (_jitc->function->call.argi + 1),
u); u);
_jitc->function->call.argi += 2; _jitc->function->call.argi += 2;
return; goto done;
} }
} }
if (_jitc->function->call.size & 7) if (_jitc->function->call.size & 7)
_jitc->function->call.size += 4; _jitc->function->call.size += 4;
jit_stxi_d(_jitc->function->call.size, JIT_SP, u); jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float64_t); _jitc->function->call.size += sizeof(jit_float64_t);
done:
jit_dec_synth();
} }
void void
@ -856,13 +974,15 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); 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_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) {
if (jit_arg_d_reg_p(_jitc->function->call.argf)) { if (jit_arg_d_reg_p(_jitc->function->call.argf)) {
if (_jitc->function->call.argf & 1) if (_jitc->function->call.argf & 1)
++_jitc->function->call.argf; ++_jitc->function->call.argf;
jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
_jitc->function->call.argf += 2; _jitc->function->call.argf += 2;
return; goto done;
} }
} }
else { else {
@ -873,7 +993,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
JIT_RA0 - (_jitc->function->call.argi + 1), JIT_RA0 - (_jitc->function->call.argi + 1),
u); u);
_jitc->function->call.argi += 2; _jitc->function->call.argi += 2;
return; goto done;
} }
} }
if (_jitc->function->call.size & 7) 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_stxi_d(_jitc->function->call.size, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_float64_t); _jitc->function->call.size += sizeof(jit_float64_t);
done:
jit_dec_synth();
} }
jit_bool_t jit_bool_t
@ -909,6 +1031,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
node = jit_callr(r0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
} }
jit_node_t * jit_node_t *
@ -924,6 +1048,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{ {
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
return (node); return (node);
} }
void void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) _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_extr_c(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) _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_extr_uc(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) _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_extr_s(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) _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_extr_us(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_i, r0);
if (r0 != JIT_RET) if (r0 != JIT_RET)
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_f, r0);
if (jit_cpu.abi) { if (jit_cpu.abi) {
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_f(r0, JIT_FRET); jit_movr_f(r0, JIT_FRET);
} }
else if (r0 != JIT_RET) else if (r0 != JIT_RET)
jit_movr_w_f(r0, JIT_RET); jit_movr_w_f(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_d, r0);
if (jit_cpu.abi) { if (jit_cpu.abi) {
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET); jit_movr_d(r0, JIT_FRET);
} }
else if (r0 != JIT_RET) else if (r0 != JIT_RET)
jit_movr_ww_d(r0, JIT_RET, _R1); jit_movr_ww_d(r0, JIT_RET, _R1);
jit_dec_synth();
} }
jit_pointer_t jit_pointer_t
@ -1000,6 +1140,9 @@ _emit_code(jit_state_t *_jit)
jit_node_t *node; jit_node_t *node;
jit_uint8_t *data; jit_uint8_t *data;
jit_word_t word; jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_uword_t thumb; jit_uword_t thumb;
#if DISASSEMBLER #if DISASSEMBLER
jit_int32_t info_offset; jit_int32_t info_offset;
@ -1007,12 +1150,18 @@ _emit_code(jit_state_t *_jit)
jit_int32_t const_offset; jit_int32_t const_offset;
jit_int32_t patch_offset; jit_int32_t patch_offset;
} undo; } undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL; _jitc->function = NULL;
_jitc->thumb = 0; _jitc->thumb = 0;
jit_reglive_setup(); jit_reglive_setup();
_jitc->consts.data = NULL;
_jitc->consts.offset = _jitc->consts.length = 0;
undo.word = 0; undo.word = 0;
undo.node = NULL; undo.node = NULL;
undo.data = NULL; undo.data = NULL;
@ -1228,12 +1377,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \ patch(word, node); \
} \ } \
break break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) { for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end) if (_jit->pc.uc >= _jitc->code.end)
return (NULL); return (NULL);
#if DEVEL_DISASSEMBLER #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 #endif
value = jit_classify(node->code); value = jit_classify(node->code);
jit_regarg_set(node, value); jit_regarg_set(node, value);
@ -1634,6 +1787,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w; _jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node; undo.node = node;
undo.word = _jit->pc.w; undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.data = _jitc->consts.data; undo.data = _jitc->consts.data;
undo.thumb = _jitc->thumb; undo.thumb = _jitc->thumb;
undo.const_offset = _jitc->consts.offset; undo.const_offset = _jitc->consts.offset;
@ -1658,6 +1814,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch; temp->flag &= ~jit_flag_patch;
node = undo.node; node = undo.node;
_jit->pc.w = undo.word; _jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
invalidate_consts(); invalidate_consts();
_jitc->consts.data = undo.data; _jitc->consts.data = undo.data;
_jitc->thumb = undo.thumb; _jitc->thumb = undo.thumb;
@ -1726,16 +1885,37 @@ _emit_code(jit_state_t *_jit)
else else
vfp_vaarg_d(rn(node->u.w), rn(node->v.w)); vfp_vaarg_d(rn(node->u.w), rn(node->v.w));
break; 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:
case jit_code_arg_f: case jit_code_arg_d: case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end: 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; break;
default: default:
abort(); abort();
} }
jit_regarg_clr(node, value); jit_regarg_clr(node, value);
assert(_jitc->regarg == 0); assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */ /* update register live state */
jit_reglive(node); jit_reglive(node);
@ -1807,6 +1987,7 @@ _emit_code(jit_state_t *_jit)
} }
#define CODE 1 #define CODE 1
# include "jit_rewind.c"
# include "jit_arm-cpu.c" # include "jit_arm-cpu.c"
# include "jit_arm-swf.c" # include "jit_arm-swf.c"
# include "jit_arm-vfp.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]; char buffer[address_buffer_length];
#if DEVEL_DISASSEMBLER #if DEVEL_DISASSEMBLER
jit_node_t *node; jit_node_t *node;
jit_uword_t prevw;
#endif #endif
#if __arm__ #if __arm__
@ -343,14 +344,18 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length)
disasm_jit = _jit; disasm_jit = _jit;
#if DEVEL_DISASSEMBLER #if DEVEL_DISASSEMBLER
node = _jitc->head; node = _jitc->head;
prevw = pc;
#endif #endif
while (pc < end) { while (pc < end) {
#if DEVEL_DISASSEMBLER #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; 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); jit_print_node(node);
fputc('\n', stdout); fputc('\n', stdout);
prevw += node->offset;
node = node->next; node = node->next;
} }
#endif #endif

View file

@ -10,7 +10,19 @@
0, /* #note */ 0, /* #note */
0, /* label */ 0, /* label */
64, /* prolog */ 64, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */ 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_start */
0, /* va_arg */ 0, /* va_arg */
0, /* va_arg_d */ 0, /* va_arg_d */
@ -179,8 +191,26 @@
12, /* jmpi */ 12, /* jmpi */
40, /* callr */ 40, /* callr */
44, /* calli */ 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 */ 64, /* epilog */
0, /* arg_f */ 0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */ 4, /* addr_f */
16, /* addi_f */ 16, /* addi_f */
4, /* subr_f */ 4, /* subr_f */
@ -263,7 +293,15 @@
28, /* bordi_f */ 28, /* bordi_f */
16, /* bunordr_f */ 16, /* bunordr_f */
28, /* bunordi_f */ 28, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */ 0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */ 4, /* addr_d */
24, /* addi_d */ 24, /* addi_d */
4, /* subr_d */ 4, /* subr_d */
@ -346,6 +384,11 @@
36, /* bordi_d */ 36, /* bordi_d */
16, /* bunordr_d */ 16, /* bunordr_d */
36, /* bunordi_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_w_f */
0, /* movr_ww_d */ 0, /* movr_ww_d */
0, /* movr_w_d */ 0, /* movr_w_d */
@ -355,6 +398,4 @@
0, /* movi_d_ww */ 0, /* movi_d_ww */
0, /* movr_d_w */ 0, /* movr_d_w */
0, /* movi_d_w */ 0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */ #endif /* __WORDSIZE */

View file

@ -163,6 +163,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff, jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t)); _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); _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog); jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset; _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; _jitc->function->self.aoff = (_jitc->function->self.aoff + 7) & -8;
break; break;
} }
if (!_jitc->realize) {
jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length);
jit_dec_synth();
}
offset = _jitc->function->self.aoff; offset = _jitc->function->self.aoff;
_jitc->function->self.aoff += length; _jitc->function->self.aoff += length;
return (offset); return (offset);
@ -204,6 +212,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
{ {
jit_int32_t reg; jit_int32_t reg;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) { if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1; _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_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg); jit_unget_reg(reg);
jit_dec_synth();
} }
void void
_jit_ret(jit_state_t *_jit) _jit_ret(jit_state_t *_jit)
{ {
jit_node_t *instr; jit_node_t *instr;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */ /* jump to epilog */
instr = jit_jmpi(); instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog); jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
} }
void void
_jit_retr(jit_state_t *_jit, jit_int32_t u) _jit_retr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr, u);
jit_movr(JIT_RET, u); jit_movr(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti(jit_state_t *_jit, jit_word_t u) _jit_reti(jit_state_t *_jit, jit_word_t u)
{ {
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u); jit_movi(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u) _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_movr_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u) _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_movi_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u) _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_movr_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u) _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_movi_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
@ -291,48 +313,61 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void void
_jit_ellipsis(jit_state_t *_jit) _jit_ellipsis(jit_state_t *_jit)
{ {
jit_inc_synth(ellipsis);
if (_jitc->prepare) { if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs)); assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs; _jitc->function->call.call |= jit_call_varargs;
} }
else { else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs; _jitc->function->self.call |= jit_call_varargs;
_jitc->function->vagp = _jitc->function->self.argi; _jitc->function->vagp = _jitc->function->self.argi;
} }
jit_dec_synth();
} }
jit_node_t * jit_node_t *
_jit_arg(jit_state_t *_jit) _jit_arg(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function); assert(_jitc->function);
_jitc->function->self.size -= sizeof(jit_word_t); _jitc->function->self.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++; offset = _jitc->function->self.argi++;
else else
offset = _jitc->function->self.size; 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_node_t *
_jit_arg_f(jit_state_t *_jit) _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);
_jitc->function->self.size -= sizeof(jit_word_t); _jitc->function->self.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++; offset = _jitc->function->self.argi++;
else else
offset = _jitc->function->self.size; 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_node_t *
_jit_arg_d(jit_state_t *_jit) _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);
if (_jitc->function->self.argi & 1) { if (_jitc->function->self.argi & 1) {
++_jitc->function->self.argi; ++_jitc->function->self.argi;
@ -349,67 +384,82 @@ _jit_arg_d(jit_state_t *_jit)
_jitc->function->self.size -= sizeof(jit_word_t); _jitc->function->self.size -= sizeof(jit_word_t);
offset = _jitc->function->self.size; 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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_extr_c(u, _R26 - v->u.w); jit_extr_c(u, _R26 - v->u.w);
else else
jit_ldxi_c(u, JIT_FP, v->u.w + 3); jit_ldxi_c(u, JIT_FP, v->u.w + 3);
jit_dec_synth();
} }
void void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_extr_uc(u, _R26 - v->u.w); jit_extr_uc(u, _R26 - v->u.w);
else else
jit_ldxi_uc(u, JIT_FP, v->u.w + 3); jit_ldxi_uc(u, JIT_FP, v->u.w + 3);
jit_dec_synth();
} }
void void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_extr_s(u, _R26 - v->u.w); jit_extr_s(u, _R26 - v->u.w);
else else
jit_ldxi_s(u, JIT_FP, v->u.w + 2); jit_ldxi_s(u, JIT_FP, v->u.w + 2);
jit_dec_synth();
} }
void void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_extr_us(u, _R26 - v->u.w); jit_extr_us(u, _R26 - v->u.w);
else else
jit_ldxi_us(u, JIT_FP, v->u.w + 2); jit_ldxi_us(u, JIT_FP, v->u.w + 2);
jit_dec_synth();
} }
void void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_movr(u, _R26 - v->u.w); jit_movr(u, _R26 - v->u.w);
else else
jit_ldxi_i(u, JIT_FP, v->u.w); jit_ldxi_i(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_movr(_R26 - v->u.w, u); jit_movr(_R26 - v->u.w, u);
else else
jit_stxi(v->u.w, JIT_FP, u); jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -417,6 +467,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_movi(_R26 - v->u.w, u); jit_movi(_R26 - v->u.w, u);
else { 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_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_movr_f(u, _F4 - v->u.w); jit_movr_f(u, _F4 - v->u.w);
else else
jit_ldxi_f(u, JIT_FP, v->u.w); jit_ldxi_f(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_movr_f(_F4 - v->u.w, u); jit_movr_f(_F4 - v->u.w, u);
else else
jit_stxi_f(v->u.w, JIT_FP, u); jit_stxi_f(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -452,6 +508,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_movi_f(_R26 - v->u.w, u); jit_movi_f(_R26 - v->u.w, u);
else { 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_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_movr_d(u, _F4 - v->u.w); jit_movr_d(u, _F4 - v->u.w);
else else
jit_ldxi_d(u, JIT_FP, v->u.w); jit_ldxi_d(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_movr_d(_F4 - v->u.w, u); jit_movr_d(_F4 - v->u.w, u);
else else
jit_stxi_d(v->u.w, JIT_FP, u); jit_stxi_d(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -487,6 +549,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (v->u.w >= 0) if (v->u.w >= 0)
jit_movi_d(_R26 - v->u.w, u); jit_movi_d(_R26 - v->u.w, u);
else { 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_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_word_t); _jitc->function->call.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_R26 - _jitc->function->call.argi, u); jit_movr(_R26 - _jitc->function->call.argi, u);
@ -508,6 +574,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
} }
else else
jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u); jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
jit_dec_synth();
} }
void void
@ -515,6 +582,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_word_t); _jitc->function->call.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_R26 - _jitc->function->call.argi, u); 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_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_word_t); _jitc->function->call.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr_f(_F4 - _jitc->function->call.argi, u); 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 else
jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, u); jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, u);
jit_dec_synth();
} }
void void
@ -555,6 +628,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_word_t); _jitc->function->call.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi_f(_F4 - _jitc->function->call.argi, u); 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_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_float64_t); _jitc->function->call.size -= sizeof(jit_float64_t);
if (_jitc->function->call.argi & 1) { if (_jitc->function->call.argi & 1) {
++_jitc->function->call.argi; ++_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); _jitc->function->call.size -= sizeof(jit_word_t);
jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u); jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
} }
jit_dec_synth();
} }
void void
@ -615,6 +694,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_float64_t); _jitc->function->call.size -= sizeof(jit_float64_t);
if (_jitc->function->call.argi & 1) { if (_jitc->function->call.argi & 1) {
++_jitc->function->call.argi; ++_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_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
jit_bool_t jit_bool_t
@ -671,12 +753,14 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_node_t *call; jit_node_t *call;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen > _jitc->function->call.size) if (_jitc->function->self.alen > _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0); call = jit_callr(r0);
call->v.w = call->w.w = _jitc->function->call.argi; call->v.w = call->w.w = _jitc->function->call.argi;
_jitc->function->call.argi = _jitc->function->call.size = 0; _jitc->function->call.argi = _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
} }
jit_node_t * jit_node_t *
@ -684,55 +768,71 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{ {
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen > _jitc->function->call.size) if (_jitc->function->self.alen > _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0); node = jit_calli(i0);
node->v.w = node->w.w = _jitc->function->call.argi; node->v.w = node->w.w = _jitc->function->call.argi;
_jitc->function->call.argi = _jitc->function->call.size = 0; _jitc->function->call.argi = _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
return (node); return (node);
} }
void void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) _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_extr_c(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) _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_extr_uc(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) _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_extr_s(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) _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_extr_us(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_i, r0);
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) _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_movr_f(r0, JIT_FRET);
jit_dec_synth();
} }
void void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) _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_movr_d(r0, JIT_FRET);
jit_dec_synth();
} }
jit_pointer_t jit_pointer_t
@ -746,8 +846,14 @@ _emit_code(jit_state_t *_jit)
struct { struct {
jit_node_t *node; jit_node_t *node;
jit_word_t word; jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset; jit_int32_t patch_offset;
} undo; } undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL; _jitc->function = NULL;
@ -840,12 +946,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \ patch(word, node); \
} \ } \
break break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) { for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end) if (_jit->pc.uc >= _jitc->code.end)
return (NULL); return (NULL);
#if DEVEL_DISASSEMBLER #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 #endif
value = jit_classify(node->code); value = jit_classify(node->code);
jit_regarg_set(node, value); jit_regarg_set(node, value);
@ -1234,6 +1344,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w; _jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node; undo.node = node;
undo.word = _jit->pc.w; undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset; undo.patch_offset = _jitc->patches.offset;
restart_function: restart_function:
_jitc->again = 0; _jitc->again = 0;
@ -1251,6 +1364,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch; temp->flag &= ~jit_flag_patch;
node = undo.node; node = undo.node;
_jit->pc.w = undo.word; _jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset; _jitc->patches.offset = undo.patch_offset;
goto restart_function; goto restart_function;
} }
@ -1270,15 +1386,36 @@ _emit_code(jit_state_t *_jit)
vaarg_d(rn(node->u.w), rn(node->v.w)); vaarg_d(rn(node->u.w), rn(node->v.w));
break; break;
case jit_code_live: 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_arg_f: case jit_code_arg_d:
case jit_code_va_end: 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; break;
default: default:
abort(); abort();
} }
jit_regarg_clr(node, value); jit_regarg_clr(node, value);
assert(_jitc->regarg == 0); assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */ /* update register live state */
jit_reglive(node); jit_reglive(node);
} }

View file

@ -10,7 +10,19 @@
16, /* #note */ 16, /* #note */
48, /* label */ 48, /* label */
128, /* prolog */ 128, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */ 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_start */
0, /* va_arg */ 0, /* va_arg */
0, /* va_arg_d */ 0, /* va_arg_d */
@ -179,8 +191,26 @@
48, /* jmpi */ 48, /* jmpi */
32, /* callr */ 32, /* callr */
64, /* calli */ 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 */ 144, /* epilog */
0, /* arg_f */ 0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
0, /* addr_f */ 0, /* addr_f */
32, /* addi_f */ 32, /* addi_f */
16, /* subr_f */ 16, /* subr_f */
@ -263,7 +293,15 @@
64, /* bordi_f */ 64, /* bordi_f */
32, /* bunordr_f */ 32, /* bunordr_f */
64, /* bunordi_f */ 64, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */ 0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
0, /* addr_d */ 0, /* addr_d */
32, /* addi_d */ 32, /* addi_d */
16, /* subr_d */ 16, /* subr_d */
@ -346,6 +384,11 @@
64, /* bordi_d */ 64, /* bordi_d */
32, /* bunordr_d */ 32, /* bunordr_d */
64, /* bunordi_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_w_f */
0, /* movr_ww_d */ 0, /* movr_ww_d */
0, /* movr_w_d */ 0, /* movr_w_d */
@ -355,6 +398,4 @@
0, /* movi_d_ww */ 0, /* movi_d_ww */
16, /* movr_d_w */ 16, /* movr_d_w */
32, /* movi_d_w */ 32, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */ #endif /* __WORDSIZE */

View file

@ -277,6 +277,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff, jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t)); _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); _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog); jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset; _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; default: _jitc->function->self.aoff &= -8; break;
} }
_jitc->function->self.aoff -= length; _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); 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; jit_int32_t reg;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) { if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1; _jitc->function->allocar = 1;
} }
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
jit_negr(reg, v); jit_negr(reg, v);
jit_andi(reg, reg, -16); jit_andi(reg, reg, -16);
jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
jit_addr(u, u, reg); jit_addr(u, u, reg);
jit_addr(JIT_SP, JIT_SP, reg); jit_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg); jit_unget_reg(reg);
jit_dec_synth();
} }
void void
_jit_ret(jit_state_t *_jit) _jit_ret(jit_state_t *_jit)
{ {
jit_node_t *instr; jit_node_t *instr;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */ /* jump to epilog */
instr = jit_jmpi(); instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog); jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
} }
void void
_jit_retr(jit_state_t *_jit, jit_int32_t u) _jit_retr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr, u);
jit_movr(JIT_RET, u); jit_movr(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti(jit_state_t *_jit, jit_word_t u) _jit_reti(jit_state_t *_jit, jit_word_t u)
{ {
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u); jit_movi(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u) _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_movr_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u) _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_movi_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u) _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_movr_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u) _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_movi_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
@ -400,11 +419,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void void
_jit_ellipsis(jit_state_t *_jit) _jit_ellipsis(jit_state_t *_jit)
{ {
jit_inc_synth(ellipsis);
if (_jitc->prepare) { if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs)); assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs; _jitc->function->call.call |= jit_call_varargs;
} }
else { else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
_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; _jitc->function->vagp = _jitc->function->self.argi;
} }
jit_dec_synth();
} }
jit_node_t * jit_node_t *
_jit_arg(jit_state_t *_jit) _jit_arg(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function); assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++; offset = _jitc->function->self.argi++;
@ -427,14 +450,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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_node_t *
_jit_arg_f(jit_state_t *_jit) _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);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _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; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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_node_t *
_jit_arg_d(jit_state_t *_jit) _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);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _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; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _R32 + v->u.w); jit_extr_c(u, _R32 + v->u.w);
else else
jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP); jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _R32 + v->u.w); jit_extr_uc(u, _R32 + v->u.w);
else else
jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP); jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _R32 + v->u.w); jit_extr_s(u, _R32 + v->u.w);
else else
jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP); jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _R32 + v->u.w); jit_extr_us(u, _R32 + v->u.w);
else else
jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP); jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_i(u, _R32 + v->u.w); jit_extr_i(u, _R32 + v->u.w);
else else
jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP); jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _R32 + v->u.w); jit_extr_ui(u, _R32 + v->u.w);
else else
jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP); jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(u, _R32 + v->u.w); jit_movr(u, _R32 + v->u.w);
else else
jit_ldxi(u, JIT_FP, v->u.w); jit_ldxi(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(_R32 + v->u.w, u); jit_movr(_R32 + v->u.w, u);
else else
jit_stxi(v->u.w, JIT_FP, u); jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -545,6 +593,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi(_R32 + v->u.w, u); jit_movi(_R32 + v->u.w, u);
else { 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_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_f(u, _F8 + v->u.w); jit_movr_f(u, _F8 + v->u.w);
else else
jit_ldxi_f(u, JIT_FP, v->u.w + F_DISP); jit_ldxi_f(u, JIT_FP, v->u.w + F_DISP);
jit_dec_synth();
} }
void void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_f(_F8 + v->u.w, u); jit_movr_f(_F8 + v->u.w, u);
else else
jit_stxi_f(v->u.w, JIT_FP, u + F_DISP); jit_stxi_f(v->u.w, JIT_FP, u + F_DISP);
jit_dec_synth();
} }
void void
@ -580,6 +634,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi_f(_F8 + v->u.w, u); jit_movi_f(_F8 + v->u.w, u);
else { 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_stxi_f(v->u.w, JIT_FP, regno + F_DISP);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_d(u, _F8 + v->u.w); jit_movr_d(u, _F8 + v->u.w);
else else
jit_ldxi_d(u, JIT_FP, v->u.w); jit_ldxi_d(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_d(_F8 + v->u.w, u); jit_movr_d(_F8 + v->u.w, u);
else else
jit_stxi_d(v->u.w, JIT_FP, u); jit_stxi_d(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -615,6 +675,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi_d(_F8 + v->u.w, u); jit_movi_d(_F8 + v->u.w, u);
else { 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_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_OUT0 + _jitc->function->call.argi, u); jit_movr(_OUT0 + _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_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); jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
@ -644,6 +709,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_OUT0 + _jitc->function->call.argi, u); jit_movi(_OUT0 + _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_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); _jitc->function->call.size += sizeof(jit_word_t);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs)) if (!(_jitc->function->call.call & jit_call_varargs))
jit_movr_f(_F8 + _jitc->function->call.argi, u); 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); JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
@ -680,6 +751,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs)) if (!(_jitc->function->call.call & jit_call_varargs))
jit_movi_f(_F8 + _jitc->function->call.argi, u); 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); _jitc->function->call.size += sizeof(jit_word_t);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs)) if (!(_jitc->function->call.call & jit_call_varargs))
jit_movr_d(_F8 + _jitc->function->call.argi, u); 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); jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
@ -719,6 +796,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs)) if (!(_jitc->function->call.call & jit_call_varargs))
jit_movi_d(_F8 + _jitc->function->call.argi, u); 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); _jitc->function->call.size += sizeof(jit_word_t);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
jit_bool_t jit_bool_t
@ -747,6 +827,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_node_t *call; jit_node_t *call;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
} }
jit_node_t * jit_node_t *
@ -762,6 +844,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{ {
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
return (node); return (node);
} }
void void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) _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_extr_c(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) _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_extr_uc(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) _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_extr_s(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) _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_extr_us(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) _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_extr_i(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) _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_extr_ui(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_l, r0);
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) _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_movr_f(r0, JIT_FRET);
jit_dec_synth();
} }
void void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) _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_movr_d(r0, JIT_FRET);
jit_dec_synth();
} }
jit_pointer_t jit_pointer_t
@ -838,9 +940,15 @@ _emit_code(jit_state_t *_jit)
struct { struct {
jit_node_t *node; jit_node_t *node;
jit_word_t word; jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset; jit_int32_t patch_offset;
jit_word_t prolog_offset; jit_word_t prolog_offset;
} undo; } undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL; _jitc->function = NULL;
@ -855,6 +963,9 @@ _emit_code(jit_state_t *_jit)
undo.node = NULL; undo.node = NULL;
undo.patch_offset = 0; undo.patch_offset = 0;
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
undo.prolog_offset = 0; undo.prolog_offset = 0;
for (node = _jitc->head; node; node = node->next) for (node = _jitc->head; node; node = node->next)
if (node->code != jit_code_label && if (node->code != jit_code_label &&
@ -961,7 +1072,8 @@ _emit_code(jit_state_t *_jit)
#endif #endif
#if DEVEL_DISASSEMBLER #if DEVEL_DISASSEMBLER
sync(); sync();
node->offset = _jit->pc.w; node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
prevw = _jit->pc.w;
#endif #endif
jit_regarg_set(node, value); jit_regarg_set(node, value);
switch (node->code) { switch (node->code) {
@ -1368,6 +1480,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w; _jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node; undo.node = node;
undo.word = _jit->pc.w; undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset; undo.patch_offset = _jitc->patches.offset;
undo.prolog_offset = _jitc->prolog.offset; undo.prolog_offset = _jitc->prolog.offset;
restart_function: restart_function:
@ -1403,6 +1518,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch; temp->flag &= ~jit_flag_patch;
node = undo.node; node = undo.node;
_jit->pc.w = undo.word; _jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset; _jitc->patches.offset = undo.patch_offset;
_jitc->prolog.offset = undo.prolog_offset; _jitc->prolog.offset = undo.prolog_offset;
_jitc->ioff = 0; _jitc->ioff = 0;
@ -1429,9 +1547,32 @@ _emit_code(jit_state_t *_jit)
vaarg_d(rn(node->u.w), rn(node->v.w)); vaarg_d(rn(node->u.w), rn(node->v.w));
break; break;
case jit_code_live: 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_arg_f: case jit_code_arg_d:
case jit_code_va_end: 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; break;
case jit_code_movr_f_w: case jit_code_movr_f_w:
movr_f_w(rn(node->u.w), rn(node->v.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, 0) == jit_carry);
assert(jit_regset_scan1(&_jitc->regarg, jit_carry + 1) == ULONG_MAX); assert(jit_regset_scan1(&_jitc->regarg, jit_carry + 1) == ULONG_MAX);
} }
assert(_jitc->synth == 0);
/* update register live state */ /* update register live state */
jit_reglive(node); 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) { 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); offset = stack_framesize + index * sizeof(jit_word_t);
for (; jit_arg_reg_p(index); ++index, offset += sizeof(jit_word_t)) for (; jit_arg_reg_p(index); ++index, offset += sizeof(jit_word_t))
stxi(offset, _BP_REGNO, rn(_A0 - index)); stxi(offset, _BP_REGNO, rn(_A0 - index));
@ -2993,41 +2993,19 @@ _epilog(jit_state_t *_jit, jit_node_t *node)
static void static void
_vastart(jit_state_t *_jit, jit_int32_t r0) _vastart(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs); assert(_jitc->function->self.call & jit_call_varargs);
/* Initialize va_list to the first stack argument. */
/* Return jit_va_list_t in the register argument */ addi(r0, _BP_REGNO, _jitc->function->self.size);
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);
} }
static void static void
_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) _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. */ /* Load argument. */
ldr(r0, rn(reg)); ldr(r0, r1);
/* Update vararg stack pointer. */ /* Update va_list. */
addi(rn(reg), rn(reg), sizeof(jit_word_t)); addi(r1, r1, sizeof(jit_word_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
jit_unget_reg(reg);
} }
static void static void

View file

@ -1780,28 +1780,19 @@ dbopi(unord)
static void static void
_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) _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); 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. */ /* Align, if required. */
aln = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
andi(rn(aln), rn(reg), 7); andi(rn(reg), r1, 7);
addr(rn(reg), rn(reg), rn(aln)); addr(r1, r1, rn(reg));
jit_unget_reg(aln); jit_unget_reg(reg);
/* Load argument. */ /* Load argument. */
ldr_d(r0, rn(reg)); ldr_d(r0, r1);
/* Update vararg stack pointer. */ /* Update va_list. */
addi(rn(reg), rn(reg), sizeof(jit_float64_t)); addi(r1, r1, sizeof(jit_float64_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
jit_unget_reg(reg);
} }
# undef fopi # undef fopi

View file

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

View file

@ -53,17 +53,22 @@
/* /*
* Types * Types
*/ */
typedef struct jit_va_list { typedef struct jit_pointer_t jit_va_list_t;
jit_pointer_t stack;
} jit_va_list_t;
/* /*
* Prototypes * 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*); static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
#define PROTO 1 #define PROTO 1
# include "jit_rewind.c"
# include "jit_mips-cpu.c" # include "jit_mips-cpu.c"
# include "jit_mips-fpu.c" # include "jit_mips-fpu.c"
#undef PROTO #undef PROTO
@ -189,6 +194,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff, jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t)); _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); _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog); jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset; _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; default: _jitc->function->self.aoff &= -8; break;
} }
_jitc->function->self.aoff -= length; _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); 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; jit_int32_t reg;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) { if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1; _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_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg); jit_unget_reg(reg);
jit_dec_synth();
} }
void void
_jit_ret(jit_state_t *_jit) _jit_ret(jit_state_t *_jit)
{ {
jit_node_t *instr; jit_node_t *instr;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */ /* jump to epilog */
instr = jit_jmpi(); instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog); jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
} }
void void
_jit_retr(jit_state_t *_jit, jit_int32_t u) _jit_retr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr, u);
if (JIT_RET != u) if (JIT_RET != u)
jit_movr(JIT_RET, u); jit_movr(JIT_RET, u);
else else
jit_live(JIT_RET); jit_live(JIT_RET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti(jit_state_t *_jit, jit_word_t u) _jit_reti(jit_state_t *_jit, jit_word_t u)
{ {
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u); jit_movi(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u) _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_f, u);
if (JIT_FRET != u) if (JIT_FRET != u)
jit_movr_f(JIT_FRET, u); jit_movr_f(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u) _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_movi_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u) _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_d, u);
if (JIT_FRET != u) if (JIT_FRET != u)
jit_movr_d(JIT_FRET, u); jit_movr_d(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u) _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_movi_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
@ -320,29 +347,10 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
#endif #endif
} }
void static jit_node_t *
_jit_ellipsis(jit_state_t *_jit) _jit_make_arg(jit_state_t *_jit, jit_node_t *node)
{ {
if (_jitc->prepare) { jit_int32_t offset;
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);
#if NEW_ABI #if NEW_ABI
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++; offset = _jitc->function->self.argi++;
@ -357,14 +365,20 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += STACK_SLOT; _jitc->function->self.size += STACK_SLOT;
#endif #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 * static 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; jit_int32_t offset;
assert(_jitc->function);
#if NEW_ABI #if NEW_ABI
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++; offset = _jitc->function->self.argi++;
@ -375,27 +389,36 @@ _jit_arg_f(jit_state_t *_jit)
#else #else
offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT;
if (offset < NUM_WORD_ARGS) { 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) if (offset == 0)
offset = 4; offset = 4;
else { else {
offset = 6; offset = 6;
_jitc->function->self.argi = 1; _jitc->function->self.argi = 1;
} }
/* Use as flag to rewind in case of varargs function */
++_jitc->function->self.argf;
} }
} }
else else
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += STACK_SLOT; _jitc->function->self.size += STACK_SLOT;
#endif #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 * static 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; jit_int32_t offset;
assert(_jitc->function);
#if NEW_ABI #if NEW_ABI
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _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; offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT;
if (offset < NUM_WORD_ARGS) { if (offset < NUM_WORD_ARGS) {
if (!_jitc->function->self.argi) if (!_jitc->function->self.argi &&
!(_jitc->function->self.call & jit_call_varargs)) {
offset += 4; offset += 4;
/* Use as flag to rewind in case of varargs function */
++_jitc->function->self.argf;
}
} }
else else
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t); _jitc->function->self.size += sizeof(jit_float64_t);
#endif #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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _A0 - v->u.w); jit_extr_c(u, _A0 - v->u.w);
else else
jit_ldxi_c(u, _FP, v->u.w + C_DISP); jit_ldxi_c(u, _FP, v->u.w + C_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _A0 - v->u.w); jit_extr_uc(u, _A0 - v->u.w);
else else
jit_ldxi_uc(u, _FP, v->u.w + C_DISP); jit_ldxi_uc(u, _FP, v->u.w + C_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _A0 - v->u.w); jit_extr_s(u, _A0 - v->u.w);
else else
jit_ldxi_s(u, _FP, v->u.w + S_DISP); jit_ldxi_s(u, _FP, v->u.w + S_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _A0 - v->u.w); jit_extr_us(u, _A0 - v->u.w);
else else
jit_ldxi_us(u, _FP, v->u.w + S_DISP); jit_ldxi_us(u, _FP, v->u.w + S_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) { if (jit_arg_reg_p(v->u.w)) {
#if __WORDSIZE == 64 #if __WORDSIZE == 64
jit_extr_i(u, _A0 - v->u.w); 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 else
jit_ldxi_i(u, _FP, v->u.w + I_DISP); jit_ldxi_i(u, _FP, v->u.w + I_DISP);
jit_dec_synth();
} }
#if __WORDSIZE == 64 #if __WORDSIZE == 64
@ -480,31 +568,37 @@ void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _A0 - v->u.w); jit_extr_ui(u, _A0 - v->u.w);
else else
jit_ldxi_ui(u, _FP, v->u.w + I_DISP); jit_ldxi_ui(u, _FP, v->u.w + I_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(u, _A0 - v->u.w); jit_movr(u, _A0 - v->u.w);
else else
jit_ldxi_l(u, _FP, v->u.w); jit_ldxi_l(u, _FP, v->u.w);
jit_dec_synth();
} }
#endif #endif
void void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _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); assert(v->code == jit_code_arg);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(_A0 - v->u.w, u); jit_movr(_A0 - v->u.w, u);
else else
jit_stxi(v->u.w, _FP, u); jit_stxi(v->u.w, _FP, u);
jit_dec_synth();
} }
void void
@ -512,6 +606,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi(_A0 - v->u.w, u); jit_movi(_A0 - v->u.w, u);
else { 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_stxi(v->u.w, _FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
#if NEW_ABI #if NEW_ABI
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_f(u, _F12 - 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 #endif
else else
jit_ldxi_f(u, _FP, v->u.w); jit_ldxi_f(u, _FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
#if NEW_ABI #if NEW_ABI
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_f(_F12 - v->u.w, u); 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 #endif
else else
jit_stxi_f(v->u.w, _FP, u); jit_stxi_f(v->u.w, _FP, u);
jit_dec_synth();
} }
void void
@ -561,6 +661,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
#if NEW_ABI #if NEW_ABI
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi_f(_F12 - v->u.w, u); 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_stxi_f(v->u.w, _FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
#if NEW_ABI #if NEW_ABI
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_d(u, _F12 - 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 #endif
else else
jit_ldxi_d(u, _FP, v->u.w); jit_ldxi_d(u, _FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
#if NEW_ABI #if NEW_ABI
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_d(_F12 - v->u.w, u); 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 #endif
else else
jit_stxi_d(v->u.w, _FP, u); jit_stxi_d(v->u.w, _FP, u);
jit_dec_synth();
} }
void void
@ -621,6 +727,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
#if NEW_ABI #if NEW_ABI
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi_d(_F12 - v->u.w, u); 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_stxi_d(v->u.w, _FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
#if NEW_ABI #if NEW_ABI
assert(_jitc->function); assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->call.argi)) { 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); jit_stxi(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += STACK_SLOT; _jitc->function->call.size += STACK_SLOT;
#endif #endif
jit_dec_synth();
} }
void void
_jit_pushargi(jit_state_t *_jit, jit_word_t u) _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{ {
#if NEW_ABI
jit_int32_t regno; jit_int32_t regno;
#if !NEW_ABI
jit_word_t offset;
#endif
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
#if NEW_ABI
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_A0 - _jitc->function->call.argi, u); jit_movi(_A0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
@ -686,9 +802,6 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno); jit_unget_reg(regno);
} }
#else #else
jit_int32_t regno;
jit_word_t offset;
assert(_jitc->function);
offset = _jitc->function->call.size >> STACK_SHIFT; offset = _jitc->function->call.size >> STACK_SHIFT;
++_jitc->function->call.argi; ++_jitc->function->call.argi;
if (jit_arg_reg_p(offset)) 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; _jitc->function->call.size += STACK_SLOT;
#endif #endif
jit_dec_synth();
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _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); 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 (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs)) if (!(_jitc->function->call.call & jit_call_varargs))
jit_movr_f(_F12 - _jitc->function->call.argi, u); 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; _jitc->function->call.size += STACK_SLOT;
} }
#else #else
jit_word_t offset;
assert(_jitc->function);
offset = _jitc->function->call.size >> STACK_SHIFT; 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; ++_jitc->function->call.argf;
jit_movr_f(_F12 - offset, u); 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); jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += STACK_SLOT; _jitc->function->call.size += STACK_SLOT;
#endif #endif
jit_dec_synth();
} }
void void
_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
#if NEW_ABI #if !NEW_ABI
jit_word_t offset;
#endif
assert(_jitc->function); 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 (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs)) if (!(_jitc->function->call.call & jit_call_varargs))
jit_movi_f(_F12 - _jitc->function->call.argi, u); 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); jit_unget_reg(regno);
} }
#else #else
jit_word_t offset;
assert(_jitc->function);
offset = _jitc->function->call.size >> STACK_SHIFT; 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; ++_jitc->function->call.argf;
jit_movi_f(_F12 - offset, u); 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; _jitc->function->call.size += STACK_SLOT;
#endif #endif
jit_dec_synth();
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _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); 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 (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs)) if (!(_jitc->function->call.call & jit_call_varargs))
jit_movr_d(_F12 - _jitc->function->call.argi, u); 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; _jitc->function->call.size += STACK_SLOT;
} }
#else #else
jit_bool_t adjust;
jit_word_t offset;
assert(_jitc->function);
adjust = !!_jitc->function->call.argi; adjust = !!_jitc->function->call.argi;
if (_jitc->function->call.size & 7) { if (_jitc->function->call.size & 7) {
_jitc->function->call.size += 4; _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; offset = _jitc->function->call.size >> STACK_SHIFT;
if (offset < 3) { if (offset < 3) {
if (adjust) { if (adjust || (_jitc->function->call.call & jit_call_varargs)) {
jit_movr_d_ww(_A0 - offset, _A0 - (offset + 1), u); jit_movr_d_ww(_A0 - offset, _A0 - (offset + 1), u);
_jitc->function->call.argi += 2; _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); jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float64_t); _jitc->function->call.size += sizeof(jit_float64_t);
#endif #endif
jit_dec_synth();
} }
void void
_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
#if NEW_ABI #if !NEW_ABI
jit_bool_t adjust;
jit_word_t offset;
#endif
assert(_jitc->function); 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 (jit_arg_reg_p(_jitc->function->call.argi)) {
if (!(_jitc->function->call.call & jit_call_varargs)) if (!(_jitc->function->call.call & jit_call_varargs))
jit_movi_d(_F12 - _jitc->function->call.argi, u); 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); jit_unget_reg(regno);
} }
#else #else
jit_bool_t adjust;
jit_word_t offset;
assert(_jitc->function);
adjust = !!_jitc->function->call.argi; adjust = !!_jitc->function->call.argi;
if (_jitc->function->call.size & 7) { if (_jitc->function->call.size & 7) {
_jitc->function->call.size += 4; _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; offset = _jitc->function->call.size >> STACK_SHIFT;
if (offset < 3) { if (offset < 3) {
if (adjust) { if (adjust || (_jitc->function->call.call & jit_call_varargs)) {
jit_movi_d_ww(_A0 - offset, _A0 - (offset + 1), u); jit_movi_d_ww(_A0 - offset, _A0 - (offset + 1), u);
_jitc->function->call.argi += 2; _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); _jitc->function->call.size += sizeof(jit_float64_t);
#endif #endif
jit_dec_synth();
} }
jit_bool_t jit_bool_t
@ -897,8 +1029,8 @@ void
_jit_finishr(jit_state_t *_jit, jit_int32_t r0) _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_node_t *call; jit_node_t *call;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
jit_movr(_T9, r0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
} }
jit_node_t * jit_node_t *
@ -919,8 +1052,8 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{ {
jit_node_t *call; jit_node_t *call;
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishr, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
node = jit_movi(_T9, (jit_word_t)i0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
return (node); return (node);
} }
@ -1012,8 +1146,14 @@ _emit_code(jit_state_t *_jit)
struct { struct {
jit_node_t *node; jit_node_t *node;
jit_word_t word; jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset; jit_int32_t patch_offset;
} undo; } undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL; _jitc->function = NULL;
@ -1105,12 +1245,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \ patch(word, node); \
} \ } \
break break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) { for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end) if (_jit->pc.uc >= _jitc->code.end)
return (NULL); return (NULL);
#if DEVEL_DISASSEMBLER #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 #endif
value = jit_classify(node->code); value = jit_classify(node->code);
jit_regarg_set(node, value); jit_regarg_set(node, value);
@ -1527,6 +1671,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w; _jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node; undo.node = node;
undo.word = _jit->pc.w; undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset; undo.patch_offset = _jitc->patches.offset;
restart_function: restart_function:
_jitc->again = 0; _jitc->again = 0;
@ -1544,6 +1691,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch; temp->flag &= ~jit_flag_patch;
node = undo.node; node = undo.node;
_jit->pc.w = undo.word; _jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset; _jitc->patches.offset = undo.patch_offset;
goto restart_function; goto restart_function;
} }
@ -1596,9 +1746,36 @@ _emit_code(jit_state_t *_jit)
vaarg_d(rn(node->u.w), rn(node->v.w)); vaarg_d(rn(node->u.w), rn(node->v.w));
break; break;
case jit_code_live: 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_arg_f: case jit_code_arg_d:
case jit_code_va_end: 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; break;
default: default:
abort(); abort();
@ -1619,6 +1796,7 @@ _emit_code(jit_state_t *_jit)
} }
jit_regarg_clr(node, value); jit_regarg_clr(node, value);
assert(_jitc->regarg == jit_carry == _NOREG ? 0 : (1 << jit_carry)); assert(_jitc->regarg == jit_carry == _NOREG ? 0 : (1 << jit_carry));
assert(_jitc->synth == 0);
/* update register live state */ /* update register live state */
jit_reglive(node); jit_reglive(node);
} }
@ -1645,6 +1823,7 @@ _emit_code(jit_state_t *_jit)
} }
#define CODE 1 #define CODE 1
# include "jit_rewind.c"
# include "jit_mips-cpu.c" # include "jit_mips-cpu.c"
# include "jit_mips-fpu.c" # include "jit_mips-fpu.c"
#undef CODE #undef CODE

View file

@ -24,7 +24,14 @@ static char *code_name[] = {
"#name", "#note", "#name", "#note",
"label", "label",
"prolog", "prolog",
"ellipsis",
"allocai", "allocar",
"arg", "arg",
"getarg_c", "getarg_uc",
"getarg_s", "getarg_us",
"getarg_i", "getarg_ui",
"getarg_l",
"putargr", "putargi",
"va_start", "va_start",
"va_arg", "va_arg_d", "va_arg", "va_arg_d",
"va_end", "va_end",
@ -111,8 +118,18 @@ static char *code_name[] = {
"bxsubr_u", "bxsubi_u", "bxsubr_u", "bxsubi_u",
"jmpr", "jmpi", "jmpr", "jmpi",
"callr", "calli", "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", "epilog",
"arg_f", "arg_f", "getarg_f",
"putargr_f", "putargi_f",
"addr_f", "addi_f", "addr_f", "addi_f",
"subr_f", "subi_f", "subr_f", "subi_f",
"rsbi_f", "rsbi_f",
@ -155,7 +172,11 @@ static char *code_name[] = {
"bltgtr_f", "bltgti_f", "bltgtr_f", "bltgti_f",
"bordr_f", "bordi_f", "bordr_f", "bordi_f",
"bunordr_f", "bunordi_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", "addr_d", "addi_d",
"subr_d", "subi_d", "subr_d", "subi_d",
"rsbi_d", "rsbi_d",
@ -198,10 +219,12 @@ static char *code_name[] = {
"bltgtr_d", "bltgti_d", "bltgtr_d", "bltgti_d",
"bordr_d", "bordi_d", "bordr_d", "bordi_d",
"bunordr_d", "bunordi_d", "bunordr_d", "bunordi_d",
"pushargr_d", "pushargi_d",
"retr_d", "reti_d",
"retval_d",
"movr_w_f", "movr_ww_d", "movr_w_f", "movr_ww_d",
"movr_w_d", "movr_w_d",
"movr_f_w", "movi_f_w", "movr_f_w", "movi_f_w",
"movr_d_ww", "movi_d_ww", "movr_d_ww", "movi_d_ww",
"movr_d_w", "movi_d_w", "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) { if (_jitc->function->self.call & jit_call_varargs) {
for (regno = _jitc->function->vagp; jit_arg_reg_p(regno); ++regno) 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)); _FP_REGNO, rn(JIT_RA0 - regno));
} }
} }
@ -3342,43 +3342,22 @@ _epilog(jit_state_t *_jit, jit_node_t *node)
static void static void
_vastart(jit_state_t *_jit, jit_int32_t r0) _vastart(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs); 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. */ /* Initialize stack pointer to the first stack argument. */
addi(rn(reg), _FP_REGNO, gpr_save_area - addi(r0, _FP_REGNO, _jitc->function->self.size);
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);
} }
static void static void
_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) _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); 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. */ /* Load argument. */
ldr(r0, rn(reg)); ldr(r0, r1);
/* Update vararg stack pointer. */ /* Update va_list. */
addi(rn(reg), rn(reg), sizeof(jit_word_t)); addi(r1, r1, sizeof(jit_word_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
jit_unget_reg(reg);
if (inv) jit_unget_reg(_R0);
} }
static void 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 static void
_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) _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. */ /* Load argument. */
ldr_d(r0, rn(reg)); ldr_d(r0, r1);
/* Update vararg stack pointer. */ /* Update va_list. */
addi(rn(reg), rn(reg), sizeof(jit_float64_t)); addi(r1, r1, sizeof(jit_float64_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
jit_unget_reg(reg);
if (inv) jit_unget_reg(_R0);
} }
#endif #endif

View file

@ -11,7 +11,19 @@
0, /* #note */ 0, /* #note */
0, /* label */ 0, /* label */
44, /* prolog */ 44, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */ 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_start */
0, /* va_arg */ 0, /* va_arg */
0, /* va_arg_d */ 0, /* va_arg_d */
@ -180,8 +192,26 @@
4, /* jmpi */ 4, /* jmpi */
8, /* callr */ 8, /* callr */
16, /* calli */ 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 */ 44, /* epilog */
0, /* arg_f */ 0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */ 4, /* addr_f */
12, /* addi_f */ 12, /* addi_f */
4, /* subr_f */ 4, /* subr_f */
@ -264,7 +294,15 @@
16, /* bordi_f */ 16, /* bordi_f */
8, /* bunordr_f */ 8, /* bunordr_f */
16, /* bunordi_f */ 16, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */ 0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */ 4, /* addr_d */
12, /* addi_d */ 12, /* addi_d */
4, /* subr_d */ 4, /* subr_d */
@ -347,6 +385,11 @@
16, /* bordi_d */ 16, /* bordi_d */
8, /* bunordr_d */ 8, /* bunordr_d */
16, /* bunordi_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_w_f */
0, /* movr_ww_d */ 0, /* movr_ww_d */
0, /* movr_w_d */ 0, /* movr_w_d */
@ -356,14 +399,13 @@
0, /* movi_d_ww */ 0, /* movi_d_ww */
0, /* movr_d_w */ 0, /* movr_d_w */
0, /* movi_d_w */ 0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __ppc__ */ #endif /* __ppc__ */
#endif /* __WORDSIZE */ #endif /* __WORDSIZE */
#if __WORDSIZE == 32 #if __WORDSIZE == 32
#if defined(__powerpc__) #if defined(__powerpc__)
#define JIT_INSTR_MAX 72 #if __BYTE_ORDER == __BIG_ENDIAN
#define JIT_INSTR_MAX 136
0, /* data */ 0, /* data */
0, /* live */ 0, /* live */
0, /* align */ 0, /* align */
@ -372,11 +414,23 @@
0, /* #name */ 0, /* #name */
0, /* #note */ 0, /* #note */
0, /* label */ 0, /* label */
72, /* prolog */ 136, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */ 0, /* arg */
0, /* va_start */ 0, /* getarg_c */
0, /* va_arg */ 0, /* getarg_uc */
0, /* va_arg_d */ 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 */ 0, /* va_end */
4, /* addr */ 4, /* addr */
12, /* addi */ 12, /* addi */
@ -469,15 +523,15 @@
0, /* ldr_l */ 0, /* ldr_l */
0, /* ldi_l */ 0, /* ldi_l */
8, /* ldxr_c */ 8, /* ldxr_c */
8, /* ldxi_c */ 16, /* ldxi_c */
4, /* ldxr_uc */ 4, /* ldxr_uc */
4, /* ldxi_uc */ 12, /* ldxi_uc */
4, /* ldxr_s */ 4, /* ldxr_s */
4, /* ldxi_s */ 12, /* ldxi_s */
4, /* ldxr_us */ 4, /* ldxr_us */
4, /* ldxi_us */ 12, /* ldxi_us */
4, /* ldxr_i */ 4, /* ldxr_i */
4, /* ldxi_i */ 12, /* ldxi_i */
0, /* ldxr_ui */ 0, /* ldxr_ui */
0, /* ldxi_ui */ 0, /* ldxi_ui */
0, /* ldxr_l */ 0, /* ldxr_l */
@ -491,11 +545,11 @@
0, /* str_l */ 0, /* str_l */
0, /* sti_l */ 0, /* sti_l */
4, /* stxr_c */ 4, /* stxr_c */
4, /* stxi_c */ 12, /* stxi_c */
4, /* stxr_s */ 4, /* stxr_s */
4, /* stxi_s */ 12, /* stxi_s */
4, /* stxr_i */ 4, /* stxr_i */
4, /* stxi_i */ 12, /* stxi_i */
0, /* stxr_l */ 0, /* stxr_l */
0, /* stxi_l */ 0, /* stxi_l */
8, /* bltr */ 8, /* bltr */
@ -538,12 +592,30 @@
16, /* bxsubi */ 16, /* bxsubi */
12, /* bxsubr_u */ 12, /* bxsubr_u */
16, /* bxsubi_u */ 16, /* bxsubi_u */
0, /* jmpr */ 8, /* jmpr */
4, /* jmpi */ 4, /* jmpi */
28, /* callr */ 28, /* callr */
40, /* calli */ 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, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */ 4, /* addr_f */
16, /* addi_f */ 16, /* addi_f */
4, /* subr_f */ 4, /* subr_f */
@ -593,11 +665,11 @@
4, /* ldr_f */ 4, /* ldr_f */
8, /* ldi_f */ 8, /* ldi_f */
4, /* ldxr_f */ 4, /* ldxr_f */
4, /* ldxi_f */ 12, /* ldxi_f */
4, /* str_f */ 4, /* str_f */
8, /* sti_f */ 8, /* sti_f */
4, /* stxr_f */ 4, /* stxr_f */
4, /* stxi_f */ 12, /* stxi_f */
8, /* bltr_f */ 8, /* bltr_f */
20, /* blti_f */ 20, /* blti_f */
12, /* bler_f */ 12, /* bler_f */
@ -626,7 +698,15 @@
20, /* bordi_f */ 20, /* bordi_f */
8, /* bunordr_f */ 8, /* bunordr_f */
20, /* bunordi_f */ 20, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */ 0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */ 4, /* addr_d */
24, /* addi_d */ 24, /* addi_d */
4, /* subr_d */ 4, /* subr_d */
@ -676,11 +756,11 @@
4, /* ldr_d */ 4, /* ldr_d */
8, /* ldi_d */ 8, /* ldi_d */
4, /* ldxr_d */ 4, /* ldxr_d */
4, /* ldxi_d */ 12, /* ldxi_d */
4, /* str_d */ 4, /* str_d */
8, /* sti_d */ 8, /* sti_d */
4, /* stxr_d */ 4, /* stxr_d */
4, /* stxi_d */ 12, /* stxi_d */
8, /* bltr_d */ 8, /* bltr_d */
28, /* blti_d */ 28, /* blti_d */
12, /* bler_d */ 12, /* bler_d */
@ -709,6 +789,11 @@
28, /* bordi_d */ 28, /* bordi_d */
8, /* bunordr_d */ 8, /* bunordr_d */
28, /* bunordi_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_w_f */
0, /* movr_ww_d */ 0, /* movr_ww_d */
0, /* movr_w_d */ 0, /* movr_w_d */
@ -718,14 +803,14 @@
0, /* movi_d_ww */ 0, /* movi_d_ww */
0, /* movr_d_w */ 0, /* movr_d_w */
0, /* movi_d_w */ 0, /* movi_d_w */
0, /* x86_retval_f */ #endif /* __BYTEORDER */
0, /* x86_retval_d */
#endif /* __powerpc__ */ #endif /* __powerpc__ */
#endif /* __WORDSIZE */ #endif /* __WORDSIZE */
#if __WORDSIZE == 64 #if __WORDSIZE == 64
#if defined(__powerpc__) #if defined(__powerpc__)
#define JIT_INSTR_MAX 72 #if __BYTE_ORDER == __BIG_ENDIAN
#define JIT_INSTR_MAX 148
0, /* data */ 0, /* data */
0, /* live */ 0, /* live */
4, /* align */ 4, /* align */
@ -734,11 +819,23 @@
0, /* #name */ 0, /* #name */
0, /* #note */ 0, /* #note */
0, /* label */ 0, /* label */
72, /* prolog */ 148, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */ 0, /* arg */
0, /* va_start */ 0, /* getarg_c */
0, /* va_arg */ 0, /* getarg_uc */
0, /* va_arg_d */ 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 */ 0, /* va_end */
4, /* addr */ 4, /* addr */
28, /* addi */ 28, /* addi */
@ -752,7 +849,7 @@
28, /* subci */ 28, /* subci */
4, /* subxr */ 4, /* subxr */
8, /* subxi */ 8, /* subxi */
32, /* rsbi */ 44, /* rsbi */
4, /* mulr */ 4, /* mulr */
28, /* muli */ 28, /* muli */
12, /* qmulr */ 12, /* qmulr */
@ -813,15 +910,9 @@
4, /* extr_us */ 4, /* extr_us */
4, /* extr_i */ 4, /* extr_i */
4, /* extr_ui */ 4, /* extr_ui */
# if __BYTE_ORDER == __BIG_ENDIAN
4, /* htonr_us */ 4, /* htonr_us */
4, /* htonr_ui */ 4, /* htonr_ui */
4, /* htonr_ul */ 4, /* htonr_ul */
#else
20, /* htonr_us */
16, /* htonr_ui */
44, /* htonr_ul */
#endif
8, /* ldr_c */ 8, /* ldr_c */
28, /* ldi_c */ 28, /* ldi_c */
4, /* ldr_uc */ 4, /* ldr_uc */
@ -837,19 +928,19 @@
4, /* ldr_l */ 4, /* ldr_l */
24, /* ldi_l */ 24, /* ldi_l */
8, /* ldxr_c */ 8, /* ldxr_c */
8, /* ldxi_c */ 16, /* ldxi_c */
4, /* ldxr_uc */ 4, /* ldxr_uc */
4, /* ldxi_uc */ 12, /* ldxi_uc */
4, /* ldxr_s */ 4, /* ldxr_s */
4, /* ldxi_s */ 12, /* ldxi_s */
4, /* ldxr_us */ 4, /* ldxr_us */
4, /* ldxi_us */ 12, /* ldxi_us */
4, /* ldxr_i */ 4, /* ldxr_i */
4, /* ldxi_i */ 12, /* ldxi_i */
4, /* ldxr_ui */ 4, /* ldxr_ui */
4, /* ldxi_ui */ 12, /* ldxi_ui */
4, /* ldxr_l */ 4, /* ldxr_l */
4, /* ldxi_l */ 12, /* ldxi_l */
4, /* str_c */ 4, /* str_c */
24, /* sti_c */ 24, /* sti_c */
4, /* str_s */ 4, /* str_s */
@ -859,13 +950,13 @@
4, /* str_l */ 4, /* str_l */
24, /* sti_l */ 24, /* sti_l */
4, /* stxr_c */ 4, /* stxr_c */
4, /* stxi_c */ 12, /* stxi_c */
4, /* stxr_s */ 4, /* stxr_s */
4, /* stxi_s */ 12, /* stxi_s */
4, /* stxr_i */ 4, /* stxr_i */
4, /* stxi_i */ 12, /* stxi_i */
4, /* stxr_l */ 4, /* stxr_l */
4, /* stxi_l */ 12, /* stxi_l */
8, /* bltr */ 8, /* bltr */
8, /* blti */ 8, /* blti */
8, /* bltr_u */ 8, /* bltr_u */
@ -906,12 +997,30 @@
16, /* bxsubi */ 16, /* bxsubi */
12, /* bxsubr_u */ 12, /* bxsubr_u */
16, /* bxsubi_u */ 16, /* bxsubi_u */
0, /* jmpr */ 8, /* jmpr */
4, /* jmpi */ 4, /* jmpi */
28, /* callr */ 28, /* callr */
56, /* calli */ 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, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */ 4, /* addr_f */
28, /* addi_f */ 28, /* addi_f */
4, /* subr_f */ 4, /* subr_f */
@ -961,11 +1070,11 @@
4, /* ldr_f */ 4, /* ldr_f */
24, /* ldi_f */ 24, /* ldi_f */
4, /* ldxr_f */ 4, /* ldxr_f */
4, /* ldxi_f */ 12, /* ldxi_f */
4, /* str_f */ 4, /* str_f */
24, /* sti_f */ 24, /* sti_f */
4, /* stxr_f */ 4, /* stxr_f */
4, /* stxi_f */ 12, /* stxi_f */
8, /* bltr_f */ 8, /* bltr_f */
32, /* blti_f */ 32, /* blti_f */
12, /* bler_f */ 12, /* bler_f */
@ -994,12 +1103,20 @@
32, /* bordi_f */ 32, /* bordi_f */
8, /* bunordr_f */ 8, /* bunordr_f */
32, /* bunordi_f */ 32, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */ 0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */ 4, /* addr_d */
28, /* addi_d */ 28, /* addi_d */
4, /* subr_d */ 4, /* subr_d */
28, /* subi_d */ 28, /* subi_d */
28, /* rsbi_d */ 32, /* rsbi_d */
4, /* mulr_d */ 4, /* mulr_d */
28, /* muli_d */ 28, /* muli_d */
4, /* divr_d */ 4, /* divr_d */
@ -1044,11 +1161,11 @@
4, /* ldr_d */ 4, /* ldr_d */
24, /* ldi_d */ 24, /* ldi_d */
4, /* ldxr_d */ 4, /* ldxr_d */
4, /* ldxi_d */ 12, /* ldxi_d */
4, /* str_d */ 4, /* str_d */
24, /* sti_d */ 24, /* sti_d */
4, /* stxr_d */ 4, /* stxr_d */
4, /* stxi_d */ 12, /* stxi_d */
8, /* bltr_d */ 8, /* bltr_d */
32, /* blti_d */ 32, /* blti_d */
12, /* bler_d */ 12, /* bler_d */
@ -1077,6 +1194,11 @@
36, /* bordi_d */ 36, /* bordi_d */
8, /* bunordr_d */ 8, /* bunordr_d */
32, /* bunordi_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_w_f */
0, /* movr_ww_d */ 0, /* movr_ww_d */
0, /* movr_w_d */ 0, /* movr_w_d */
@ -1086,7 +1208,411 @@
0, /* movi_d_ww */ 0, /* movi_d_ww */
0, /* movr_d_w */ 0, /* movr_d_w */
0, /* movi_d_w */ 0, /* movi_d_w */
0, /* x86_retval_f */ #endif /* __BYTEORDER */
0, /* x86_retval_d */ #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 /* __powerpc__ */
#endif /* __WORDSIZE */ #endif /* __WORDSIZE */

View file

@ -34,9 +34,7 @@
/* /*
* Types * Types
*/ */
typedef struct jit_va_list { typedef jit_pointer_t jit_va_list_t;
jit_pointer_t stack;
} jit_va_list_t;
/* /*
* Prototypes * Prototypes
@ -170,6 +168,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff, jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t)); _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); _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog); jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset; _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; default: _jitc->function->self.aoff &= -8; break;
} }
_jitc->function->self.aoff -= length; _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); 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; jit_int32_t r0, r1;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) { if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1; _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_str(JIT_SP, r0);
jit_unget_reg(r1); jit_unget_reg(r1);
jit_unget_reg(r0); jit_unget_reg(r0);
jit_dec_synth();
} }
void void
_jit_ret(jit_state_t *_jit) _jit_ret(jit_state_t *_jit)
{ {
jit_node_t *instr; jit_node_t *instr;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */ /* jump to epilog */
instr = jit_jmpi(); instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog); jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
} }
void void
_jit_retr(jit_state_t *_jit, jit_int32_t u) _jit_retr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr, u);
if (JIT_RET != u) if (JIT_RET != u)
jit_movr(JIT_RET, u); jit_movr(JIT_RET, u);
else else
jit_live(JIT_RET); jit_live(JIT_RET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti(jit_state_t *_jit, jit_word_t u) _jit_reti(jit_state_t *_jit, jit_word_t u)
{ {
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u); jit_movi(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u) _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_f, u);
if (JIT_RET != u) if (JIT_RET != u)
jit_movr_f(JIT_FRET, u); jit_movr_f(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u) _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_movi_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u) _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_d, u);
if (JIT_FRET != u) if (JIT_FRET != u)
jit_movr_d(JIT_FRET, u); jit_movr_d(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u) _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_movi_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
@ -304,39 +324,45 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void void
_jit_ellipsis(jit_state_t *_jit) _jit_ellipsis(jit_state_t *_jit)
{ {
jit_inc_synth(ellipsis);
if (_jitc->prepare) { if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs)); assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs; _jitc->function->call.call |= jit_call_varargs;
} }
else { else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
_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->vagp = _jitc->function->self.argi;
_jitc->function->vafp = _jitc->function->self.argf; _jitc->function->vafp = _jitc->function->self.argf;
} }
jit_dec_synth();
} }
jit_node_t * jit_node_t *
_jit_arg(jit_state_t *_jit) _jit_arg(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function); assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++; offset = _jitc->function->self.argi++;
else else
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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_node_t *
_jit_arg_f(jit_state_t *_jit) _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);
if (jit_arg_f_reg_p(_jitc->function->self.argf)) if (jit_arg_f_reg_p(_jitc->function->self.argf))
offset = _jitc->function->self.argf++; offset = _jitc->function->self.argf++;
@ -350,13 +376,17 @@ _jit_arg_f(jit_state_t *_jit)
#endif #endif
} }
_jitc->function->self.size += sizeof(jit_word_t); _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_node_t *
_jit_arg_d(jit_state_t *_jit) _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);
if (jit_arg_f_reg_p(_jitc->function->self.argf)) if (jit_arg_f_reg_p(_jitc->function->self.argf))
offset = _jitc->function->self.argf++; offset = _jitc->function->self.argf++;
@ -370,53 +400,65 @@ _jit_arg_d(jit_state_t *_jit)
#endif #endif
} }
_jitc->function->self.size += sizeof(jit_float64_t); _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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, JIT_RA0 - v->u.w); jit_extr_c(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP); jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, JIT_RA0 - v->u.w); jit_extr_uc(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP); jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, JIT_RA0 - v->u.w); jit_extr_s(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP); jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, JIT_RA0 - v->u.w); jit_extr_us(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP); jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) { if (jit_arg_reg_p(v->u.w)) {
#if __WORDSIZE == 32 #if __WORDSIZE == 32
jit_movr(u, JIT_RA0 - v->u.w); 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 else
jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP); jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP);
jit_dec_synth();
} }
#if __WORDSIZE == 64 #if __WORDSIZE == 64
@ -433,20 +476,24 @@ void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, JIT_RA0 - v->u.w); jit_extr_ui(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP); jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP);
jit_dec_synth();
} }
void void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(u, JIT_RA0 - v->u.w); jit_movr(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_l(u, JIT_FP, v->u.w); jit_ldxi_l(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
#endif #endif
@ -454,16 +501,19 @@ void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(JIT_RA0 - v->u.w, u); jit_movr(JIT_RA0 - v->u.w, u);
else else
jit_stxi(v->u.w, JIT_FP, u); jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
jit_inc_synth_wp(putargi, u, v);
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi(JIT_RA0 - v->u.w, u); 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_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, JIT_FA0 - v->u.w); jit_movr_d(u, JIT_FA0 - v->u.w);
else else
jit_ldxi_f(u, JIT_FP, v->u.w); jit_ldxi_f(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(JIT_FA0 - v->u.w, u); jit_movr_d(JIT_FA0 - v->u.w, u);
else else
jit_stxi_f(v->u.w, JIT_FP, u); jit_stxi_f(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -500,6 +555,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movi_d(JIT_FA0 - v->u.w, u); jit_movi_d(JIT_FA0 - v->u.w, u);
else { 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_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, JIT_FA0 - v->u.w); jit_movr_d(u, JIT_FA0 - v->u.w);
else else
jit_ldxi_d(u, JIT_FP, v->u.w); jit_ldxi_d(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(JIT_FA0 - v->u.w, u); jit_movr_d(JIT_FA0 - v->u.w, u);
else else
jit_stxi_d(v->u.w, JIT_FP, u); jit_stxi_d(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -535,6 +596,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movi_d(JIT_FA0 - v->u.w, u); jit_movi_d(JIT_FA0 - v->u.w, u);
else { 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_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(JIT_RA0 - _jitc->function->call.argi, u); jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
@ -556,6 +621,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
else else
jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u); jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
jit_dec_synth();
} }
void void
@ -563,6 +629,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(JIT_RA0 - _jitc->function->call.argi, u); jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
@ -574,29 +642,35 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno); jit_unget_reg(regno);
} }
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
jit_dec_synth();
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); 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); jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) { /* in case of excess arguments */
/* in case of excess arguments */ if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (jit_arg_reg_p(_jitc->function->call.argi)) {
#if __WORDSIZE == 32 #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 #else
_jitc->function->call.argi++; _jitc->function->call.argi++;
#endif #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 */ /* use reserved 8 bytes area */
jit_stxi_d(alloca_offset - 8, JIT_FP, u); jit_stxi_d(alloca_offset - 8, JIT_FP, u);
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, 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_stxi_f(_jitc->function->call.size + params_offset + F_DISP,
JIT_SP, u); JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
jit_dec_synth();
} }
void void
_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); 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); jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) {
/* in case of excess arguments */ /* in case of excess arguments */
if (jit_arg_reg_p(_jitc->function->call.argi)) {
#if __WORDSIZE == 32 #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 #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++; _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 #if __WORDSIZE == 32
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + 1
alloca_offset - 4);
_jitc->function->call.argi++;
#endif #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); _jitc->function->call.size += sizeof(jit_word_t);
jit_unget_reg(regno); jit_dec_synth();
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); 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); jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) {
/* in case of excess arguments */ /* in case of excess arguments */
if (jit_arg_reg_p(_jitc->function->call.argi)) {
#if __WORDSIZE == 32 #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 #else
_jitc->function->call.argi++; _jitc->function->call.argi++;
#endif #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 */ /* use reserved 8 bytes area */
jit_stxi_d(alloca_offset - 8, JIT_FP, u); jit_stxi_d(alloca_offset - 8, JIT_FP, u);
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, 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++; _jitc->function->call.argi++;
#endif #endif
} }
else else {
jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u); 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); _jitc->function->call.size += sizeof(jit_float64_t);
jit_dec_synth();
} }
void void
_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); 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); jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
if (!(_jitc->function->call.call & jit_call_varargs)) { /* in case of excess arguments */
/* in case of excess arguments */ if (jit_arg_reg_p(_jitc->function->call.argi)) {
if (jit_arg_reg_p(_jitc->function->call.argi)) {
#if __WORDSIZE == 32 #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 #else
_jitc->function->call.argi++; _jitc->function->call.argi++;
#endif #endif
}
_jitc->function->call.size += sizeof(jit_float64_t);
return;
} }
} }
regno = jit_get_reg(jit_class_fpr); else {
jit_movi_d(regno, u); regno = jit_get_reg(jit_class_fpr);
if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi_d(regno, u);
/* use reserved 8 bytes area */ if (jit_arg_reg_p(_jitc->function->call.argi
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 #if __WORDSIZE == 32
jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + 1
alloca_offset - 4);
_jitc->function->call.argi++;
#endif #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); _jitc->function->call.size += sizeof(jit_float64_t);
jit_unget_reg(regno); jit_dec_synth();
} }
jit_bool_t jit_bool_t
@ -761,6 +869,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_node_t *call; jit_node_t *call;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0); 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; call->w.w = _jitc->function->call.argf;
_jitc->function->call.argi = _jitc->function->call.argf = 0; _jitc->function->call.argi = _jitc->function->call.argf = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
} }
jit_node_t * jit_node_t *
@ -775,6 +885,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{ {
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0); 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; node->w.w = _jitc->function->call.argf;
_jitc->function->call.argi = _jitc->function->call.argf = 0; _jitc->function->call.argi = _jitc->function->call.argf = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
return (node); return (node);
} }
void void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth(retval_c);
jit_extr_c(r0, JIT_RET); jit_extr_c(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth(retval_uc);
jit_extr_uc(r0, JIT_RET); jit_extr_uc(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth(retval_s);
jit_extr_s(r0, JIT_RET); jit_extr_s(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth(retval_us);
jit_extr_us(r0, JIT_RET); jit_extr_us(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth(retval_i);
#if __WORDSIZE == 32 #if __WORDSIZE == 32
if (r0 != JIT_RET) if (r0 != JIT_RET)
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
#else #else
jit_extr_i(r0, JIT_RET); jit_extr_i(r0, JIT_RET);
#endif #endif
jit_dec_synth();
} }
#if __WORDSIZE == 64 #if __WORDSIZE == 64
void void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth(retval_ui);
jit_extr_ui(r0, JIT_RET); jit_extr_ui(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth(retval_l);
if (r0 != JIT_RET) if (r0 != JIT_RET)
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
jit_dec_synth();
} }
#endif #endif
void void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth(retval_f);
jit_retval_d(r0); jit_retval_d(r0);
jit_dec_synth();
} }
void void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth(retval_d);
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET); jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
} }
jit_pointer_t jit_pointer_t
@ -859,11 +989,17 @@ _emit_code(jit_state_t *_jit)
struct { struct {
jit_node_t *node; jit_node_t *node;
jit_word_t word; jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_word_t patch_offset; jit_word_t patch_offset;
#if __powerpc__ #if __powerpc__
jit_word_t prolog_offset; jit_word_t prolog_offset;
#endif #endif
} undo; } undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL; _jitc->function = NULL;
@ -873,6 +1009,9 @@ _emit_code(jit_state_t *_jit)
undo.node = NULL; undo.node = NULL;
undo.patch_offset = 0; undo.patch_offset = 0;
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
#if __powerpc__ && !ABI_ELFv2 #if __powerpc__ && !ABI_ELFv2
undo.prolog_offset = 0; undo.prolog_offset = 0;
for (node = _jitc->head; node; node = node->next) for (node = _jitc->head; node; node = node->next)
@ -978,7 +1117,8 @@ _emit_code(jit_state_t *_jit)
return (NULL); return (NULL);
#if DEVEL_DISASSEMBLER #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 #endif
value = jit_classify(node->code); value = jit_classify(node->code);
jit_regarg_set(node, value); jit_regarg_set(node, value);
@ -1395,6 +1535,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w; _jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node; undo.node = node;
undo.word = _jit->pc.w; undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset; undo.patch_offset = _jitc->patches.offset;
#if __powerpc__ && !ABI_ELFv2 #if __powerpc__ && !ABI_ELFv2
undo.prolog_offset = _jitc->prolog.offset; undo.prolog_offset = _jitc->prolog.offset;
@ -1435,6 +1578,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch; temp->flag &= ~jit_flag_patch;
node = undo.node; node = undo.node;
_jit->pc.w = undo.word; _jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset; _jitc->patches.offset = undo.patch_offset;
#if __powerpc__ && !ABI_ELFv2 #if __powerpc__ && !ABI_ELFv2
_jitc->prolog.offset = undo.prolog_offset; _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)); vaarg_d(rn(node->u.w), rn(node->v.w));
break; break;
case jit_code_live: 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_arg_f: case jit_code_arg_d:
case jit_code_va_end: 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; break;
default: default:
abort(); abort();
} }
jit_regarg_clr(node, value); jit_regarg_clr(node, value);
assert(_jitc->regarg == 0); assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */ /* update register live state */
jit_reglive(node); jit_reglive(node);
} }

View file

@ -32,6 +32,14 @@
print_chr('?'); \ print_chr('?'); \
print_str(_rvs[jit_regno(value)].name); \ print_str(_rvs[jit_regno(value)].name); \
} while (0) } while (0)
#define print_arg(value) \
do { \
print_chr('#'); \
if (value) \
print_dec((value)->v.w); \
else \
print_chr('?'); \
} while (0)
/* /*
* Initialization * Initialization
@ -84,19 +92,38 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
return; return;
} }
value = jit_classify(node->code) & value = jit_classify(node->code) &
(jit_cc_a0_int|jit_cc_a0_jmp|jit_cc_a0_reg|jit_cc_a0_rlh| (jit_cc_a0_int|jit_cc_a0_flt|jit_cc_a0_dbl|jit_cc_a0_jmp|
jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl| 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); 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(" "); print_str(" ");
else else
print_chr('\t'); print_chr('\t');
if (node->flag & jit_flag_synth)
print_str(" \\__ ");
print_str(code_name[node->code]); print_str(code_name[node->code]);
switch (node->code) { switch (node->code) {
r: r:
print_chr(' '); print_reg(node->u.w); return; print_chr(' '); print_reg(node->u.w); return;
w: w:
print_chr(' '); print_hex(node->u.w); return; 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: n:
print_chr(' '); print_chr(' ');
if (!(node->flag & jit_flag_node)) 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); print_dec(node->u.n->v.w);
} }
return; return;
a:
print_chr(' '); print_arg(node); return;
r_r: r_r:
print_chr(' '); print_reg(node->u.w); print_chr(' '); print_reg(node->u.w);
print_chr(' '); print_reg(node->v.w); return; print_chr(' '); print_reg(node->v.w); return;
@ -128,9 +157,36 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
else else
print_flt(node->v.d); print_flt(node->v.d);
return; return;
r_a:
print_chr(' '); print_reg(node->u.w);
print_chr(' '); print_arg(node->v.n);
return;
w_r: w_r:
print_chr(' '); print_hex(node->u.w); print_chr(' '); print_hex(node->u.w);
print_chr(' '); print_reg(node->v.w); return; 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: r_r_r:
print_chr(' '); print_reg(node->u.w); print_chr(' '); print_reg(node->u.w);
print_chr(' '); print_reg(node->v.w); print_chr(' '); print_reg(node->v.w);
@ -237,7 +293,9 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
break; break;
case jit_code_data: case jit_code_data:
case jit_code_label: case jit_code_label:
case jit_code_ellipsis:
case jit_code_prolog: case jit_code_epilog: case jit_code_prolog: case jit_code_epilog:
case jit_code_ret: case jit_code_prepare:
break; break;
case jit_code_save: case jit_code_load: case jit_code_save: case jit_code_load:
goto r; goto r;
@ -249,8 +307,14 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
goto r; goto r;
case jit_cc_a0_int: case jit_cc_a0_int:
goto w; goto w;
case jit_cc_a0_flt:
goto f;
case jit_cc_a0_dbl:
goto d;
case jit_cc_a0_jmp: case jit_cc_a0_jmp:
goto n; goto n;
case jit_cc_a0_int|jit_cc_a0_arg:
goto a;
case jit_cc_a0_reg|jit_cc_a1_reg: case jit_cc_a0_reg|jit_cc_a1_reg:
goto r_r; goto r_r;
case jit_cc_a0_reg|jit_cc_a1_int: 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; goto r_f;
case jit_cc_a0_reg|jit_cc_a1_dbl: case jit_cc_a0_reg|jit_cc_a1_dbl:
goto r_d; goto r_d;
case jit_cc_a0_reg|jit_cc_a1_arg:
goto r_a;
case jit_cc_a0_int|jit_cc_a1_reg: case jit_cc_a0_int|jit_cc_a1_reg:
goto w_r; 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: case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_reg:
goto r_r_r; goto r_r_r;
case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_int: 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. */ /* Update the fp offset. */
addi(rn(rg0), rn(rg0), 1); 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. */ /* Will only need one temporary register below. */
jit_unget_reg_but_zero(rg1); 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)); ldr_d(r0, rn(rg0));
/* Update overflow pointer. */ /* 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)); stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));
/* Where to land if argument is in save area. */ /* Where to land if argument is in save area. */

View file

@ -1,366 +1,6 @@
#if __WORDSIZE == 32 #if __WORDSIZE == 32
#define JIT_INSTR_MAX 50 #define JIT_INSTR_MAX 104
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
0, /* data */ 0, /* data */
0, /* live */ 0, /* live */
6, /* align */ 6, /* align */
@ -369,11 +9,23 @@
0, /* #name */ 0, /* #name */
0, /* #note */ 0, /* #note */
2, /* label */ 2, /* label */
38, /* prolog */ 42, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */ 0, /* arg */
0, /* va_start */ 0, /* getarg_c */
0, /* va_arg */ 0, /* getarg_uc */
0, /* va_arg_d */ 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 */ 0, /* va_end */
8, /* addr */ 8, /* addr */
24, /* addi */ 24, /* addi */
@ -466,19 +118,19 @@
6, /* ldr_l */ 6, /* ldr_l */
18, /* ldi_l */ 18, /* ldi_l */
14, /* ldxr_c */ 14, /* ldxr_c */
6, /* ldxi_c */ 26, /* ldxi_c */
14, /* ldxr_uc */ 14, /* ldxr_uc */
6, /* ldxi_uc */ 26, /* ldxi_uc */
14, /* ldxr_s */ 14, /* ldxr_s */
6, /* ldxi_s */ 26, /* ldxi_s */
14, /* ldxr_us */ 14, /* ldxr_us */
6, /* ldxi_us */ 26, /* ldxi_us */
14, /* ldxr_i */ 14, /* ldxr_i */
6, /* ldxi_i */ 26, /* ldxi_i */
14, /* ldxr_ui */ 14, /* ldxr_ui */
6, /* ldxi_ui */ 26, /* ldxi_ui */
14, /* ldxr_l */ 14, /* ldxr_l */
6, /* ldxi_l */ 26, /* ldxi_l */
4, /* str_c */ 4, /* str_c */
16, /* sti_c */ 16, /* sti_c */
4, /* str_s */ 4, /* str_s */
@ -488,13 +140,13 @@
6, /* str_l */ 6, /* str_l */
18, /* sti_l */ 18, /* sti_l */
12, /* stxr_c */ 12, /* stxr_c */
4, /* stxi_c */ 28, /* stxi_c */
12, /* stxr_s */ 12, /* stxr_s */
4, /* stxi_s */ 28, /* stxi_s */
12, /* stxr_i */ 12, /* stxr_i */
6, /* stxi_i */ 28, /* stxi_i */
14, /* stxr_l */ 14, /* stxr_l */
6, /* stxi_l */ 30, /* stxi_l */
10, /* bltr */ 10, /* bltr */
14, /* blti */ 14, /* blti */
10, /* bltr_u */ 10, /* bltr_u */
@ -535,17 +187,35 @@
14, /* bxsubi */ 14, /* bxsubi */
10, /* bxsubr_u */ 10, /* bxsubr_u */
14, /* bxsubi_u */ 14, /* bxsubi_u */
0, /* jmpr */ 2, /* jmpr */
18, /* jmpi */ 18, /* jmpi */
2, /* callr */ 2, /* callr */
18, /* calli */ 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, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
6, /* addr_f */ 6, /* addr_f */
26, /* addi_f */ 26, /* addi_f */
8, /* subr_f */ 8, /* subr_f */
26, /* subi_f */ 26, /* subi_f */
26, /* rsbi_f */ 28, /* rsbi_f */
6, /* mulr_f */ 6, /* mulr_f */
26, /* muli_f */ 26, /* muli_f */
8, /* divr_f */ 8, /* divr_f */
@ -590,11 +260,11 @@
4, /* ldr_f */ 4, /* ldr_f */
16, /* ldi_f */ 16, /* ldi_f */
12, /* ldxr_f */ 12, /* ldxr_f */
4, /* ldxi_f */ 24, /* ldxi_f */
4, /* str_f */ 4, /* str_f */
16, /* sti_f */ 16, /* sti_f */
12, /* stxr_f */ 12, /* stxr_f */
4, /* stxi_f */ 24, /* stxi_f */
10, /* bltr_f */ 10, /* bltr_f */
30, /* blti_f */ 30, /* blti_f */
10, /* bler_f */ 10, /* bler_f */
@ -623,12 +293,20 @@
30, /* bordi_f */ 30, /* bordi_f */
10, /* bunordr_f */ 10, /* bunordr_f */
30, /* bunordi_f */ 30, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */ 0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
6, /* addr_d */ 6, /* addr_d */
26, /* addi_d */ 26, /* addi_d */
8, /* subr_d */ 8, /* subr_d */
26, /* subi_d */ 26, /* subi_d */
26, /* rsbi_d */ 28, /* rsbi_d */
6, /* mulr_d */ 6, /* mulr_d */
26, /* muli_d */ 26, /* muli_d */
8, /* divr_d */ 8, /* divr_d */
@ -673,11 +351,11 @@
4, /* ldr_d */ 4, /* ldr_d */
16, /* ldi_d */ 16, /* ldi_d */
12, /* ldxr_d */ 12, /* ldxr_d */
4, /* ldxi_d */ 24, /* ldxi_d */
4, /* str_d */ 4, /* str_d */
16, /* sti_d */ 16, /* sti_d */
12, /* stxr_d */ 12, /* stxr_d */
4, /* stxi_d */ 24, /* stxi_d */
10, /* bltr_d */ 10, /* bltr_d */
30, /* blti_d */ 30, /* blti_d */
10, /* bler_d */ 10, /* bler_d */
@ -706,6 +384,412 @@
30, /* bordi_d */ 30, /* bordi_d */
10, /* bunordr_d */ 10, /* bunordr_d */
30, /* bunordi_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_w_f */
0, /* movr_ww_d */ 0, /* movr_ww_d */
0, /* movr_w_d */ 0, /* movr_w_d */
@ -715,6 +799,4 @@
0, /* movi_d_ww */ 0, /* movi_d_ww */
0, /* movr_d_w */ 0, /* movr_d_w */
0, /* movi_d_w */ 0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */ #endif /* __WORDSIZE */

View file

@ -171,6 +171,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff, jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t)); _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); _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog); jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset; _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; default: _jitc->function->self.aoff &= -8; break;
} }
_jitc->function->self.aoff -= length; _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); 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; jit_int32_t reg;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) { if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1; _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_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg); jit_unget_reg(reg);
jit_dec_synth();
} }
void void
_jit_ret(jit_state_t *_jit) _jit_ret(jit_state_t *_jit)
{ {
jit_node_t *instr; jit_node_t *instr;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */ /* jump to epilog */
instr = jit_jmpi(); instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog); jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
} }
void void
_jit_retr(jit_state_t *_jit, jit_int32_t u) _jit_retr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr, u);
jit_movr(JIT_RET, u); jit_movr(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti(jit_state_t *_jit, jit_word_t u) _jit_reti(jit_state_t *_jit, jit_word_t u)
{ {
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u); jit_movi(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u) _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_movr_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u) _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_movi_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u) _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_movr_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u) _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_movi_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
@ -292,11 +314,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void void
_jit_ellipsis(jit_state_t *_jit) _jit_ellipsis(jit_state_t *_jit)
{ {
jit_inc_synth(ellipsis);
if (_jitc->prepare) { if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs)); assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs; _jitc->function->call.call |= jit_call_varargs;
} }
else { else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
_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 else
_jitc->function->vafp = NUM_FLOAT_REG_ARGS; _jitc->function->vafp = NUM_FLOAT_REG_ARGS;
} }
jit_dec_synth();
} }
jit_node_t * jit_node_t *
_jit_arg(jit_state_t *_jit) _jit_arg(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function); assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++; offset = _jitc->function->self.argi++;
@ -328,13 +355,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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_node_t *
_jit_arg_f(jit_state_t *_jit) _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);
if (jit_arg_f_reg_p(_jitc->function->self.argf)) if (jit_arg_f_reg_p(_jitc->function->self.argf))
offset = _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; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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_node_t *
_jit_arg_d(jit_state_t *_jit) _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);
if (jit_arg_f_reg_p(_jitc->function->self.argf)) if (jit_arg_f_reg_p(_jitc->function->self.argf))
offset = _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; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t); _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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _R2 - v->u.w); jit_extr_c(u, _R2 - v->u.w);
else else
jit_ldxi_c(u, JIT_FP, jit_ldxi_c(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t)); v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t));
jit_dec_synth();
} }
void void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _R2 - v->u.w); jit_extr_uc(u, _R2 - v->u.w);
else else
jit_ldxi_uc(u, JIT_FP, jit_ldxi_uc(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t)); v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t));
jit_dec_synth();
} }
void void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _R2 - v->u.w); jit_extr_s(u, _R2 - v->u.w);
else else
jit_ldxi_s(u, JIT_FP, jit_ldxi_s(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t)); v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t));
jit_dec_synth();
} }
void void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _R2 - v->u.w); jit_extr_us(u, _R2 - v->u.w);
else else
jit_ldxi_us(u, JIT_FP, jit_ldxi_us(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t)); v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t));
jit_dec_synth();
} }
void void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) { if (jit_arg_reg_p(v->u.w)) {
#if __WORDSIZE == 32 #if __WORDSIZE == 32
jit_movr(u, _R2 - v->u.w); 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 else
jit_ldxi_i(u, JIT_FP, jit_ldxi_i(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t)); v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t));
jit_dec_synth();
} }
#if __WORDSIZE == 64 #if __WORDSIZE == 64
@ -424,21 +472,25 @@ void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _R2 - v->u.w); jit_extr_ui(u, _R2 - v->u.w);
else else
jit_ldxi_ui(u, JIT_FP, jit_ldxi_ui(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint32_t)); v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint32_t));
jit_dec_synth();
} }
void void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(u, _R2 - v->u.w); jit_movr(u, _R2 - v->u.w);
else else
jit_ldxi_l(u, JIT_FP, v->u.w); jit_ldxi_l(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
#endif #endif
@ -446,10 +498,12 @@ void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(_R2 - v->u.w, u); jit_movr(_R2 - v->u.w, u);
else else
jit_stxi(v->u.w, JIT_FP, u); jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -457,6 +511,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi(_R2 - v->u.w, u); jit_movi(_R2 - v->u.w, u);
else { 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_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(u, _F0 - v->u.w); jit_movr_f(u, _F0 - v->u.w);
else 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) + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
#endif #endif
); );
jit_dec_synth();
} }
void void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(_F0 - v->u.w, u); jit_movr_f(_F0 - v->u.w, u);
else 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) + (__WORDSIZE >> 3) - sizeof(jit_float32_t)
#endif #endif
, JIT_FP, u); , JIT_FP, u);
jit_dec_synth();
} }
void void
@ -501,6 +561,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movi_f(_F0 - v->u.w, u); jit_movi_f(_F0 - v->u.w, u);
else { else {
@ -513,26 +574,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
, JIT_FP, regno); , JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, _F0 - v->u.w); jit_movr_d(u, _F0 - v->u.w);
else else
jit_ldxi_d(u, JIT_FP, v->u.w); jit_ldxi_d(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(_F0 - v->u.w, u); jit_movr_d(_F0 - v->u.w, u);
else else
jit_stxi_d(v->u.w, JIT_FP, u); jit_stxi_d(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -540,6 +606,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movi_d(_F0 - v->u.w, u); jit_movi_d(_F0 - v->u.w, u);
else { 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_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_R2 - _jitc->function->call.argi, u); jit_movr(_R2 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_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); jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
@ -569,6 +640,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_R2 - _jitc->function->call.argi, u); jit_movi(_R2 - _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
@ -580,12 +653,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno); jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movr_f(_F0 - _jitc->function->call.argf, u); jit_movr_f(_F0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
@ -598,6 +674,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
, JIT_SP, u); , JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
@ -605,6 +682,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movi_f(_F0 - _jitc->function->call.argf, u); jit_movi_f(_F0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
@ -620,12 +699,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_unget_reg(regno); jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movr_d(_F0 - _jitc->function->call.argf, u); jit_movr_d(_F0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_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); jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float64_t); _jitc->function->call.size += sizeof(jit_float64_t);
} }
jit_dec_synth();
} }
void void
@ -641,6 +724,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
if (jit_arg_f_reg_p(_jitc->function->call.argf)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) {
jit_movi_d(_F0 - _jitc->function->call.argf, u); jit_movi_d(_F0 - _jitc->function->call.argf, u);
++_jitc->function->call.argf; ++_jitc->function->call.argf;
@ -652,6 +737,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
jit_unget_reg(regno); jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_float64_t); _jitc->function->call.size += sizeof(jit_float64_t);
} }
jit_dec_synth();
} }
jit_bool_t jit_bool_t
@ -677,6 +763,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_node_t *call; jit_node_t *call;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
} }
jit_node_t * jit_node_t *
@ -692,6 +780,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{ {
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
return (node); return (node);
} }
void void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) _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_extr_c(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) _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_extr_uc(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) _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_extr_s(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) _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_extr_us(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_i, r0);
#if __WORDSIZE == 64 #if __WORDSIZE == 64
jit_extr_i(r0, JIT_RET); jit_extr_i(r0, JIT_RET);
#else #else
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
#endif #endif
jit_dec_synth();
} }
#if __WORDSIZE == 64 #if __WORDSIZE == 64
void void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) _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_extr_ui(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_l, r0);
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
jit_dec_synth();
} }
#endif #endif
void void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) _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_movr_f(r0, JIT_FRET);
jit_dec_synth();
} }
void void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) _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_movr_d(r0, JIT_FRET);
jit_dec_synth();
} }
jit_pointer_t jit_pointer_t
@ -774,8 +882,14 @@ _emit_code(jit_state_t *_jit)
struct { struct {
jit_node_t *node; jit_node_t *node;
jit_word_t word; jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset; jit_int32_t patch_offset;
} undo; } undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL; _jitc->function = NULL;
@ -890,12 +1004,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \ patch(word, node); \
} \ } \
break break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) { for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end) if (_jit->pc.uc >= _jitc->code.end)
return (NULL); return (NULL);
#if DEVEL_DISASSEMBLER #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 #endif
value = jit_classify(node->code); value = jit_classify(node->code);
jit_regarg_set(node, value); jit_regarg_set(node, value);
@ -1318,6 +1436,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w; _jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node; undo.node = node;
undo.word = _jit->pc.w; undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset; undo.patch_offset = _jitc->patches.offset;
restart_function: restart_function:
_jitc->again = 0; _jitc->again = 0;
@ -1335,6 +1456,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch; temp->flag &= ~jit_flag_patch;
node = undo.node; node = undo.node;
_jit->pc.w = undo.word; _jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset; _jitc->patches.offset = undo.patch_offset;
goto restart_function; goto restart_function;
} }
@ -1355,16 +1479,43 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d: case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w)); vaarg_d(rn(node->u.w), rn(node->v.w));
break; 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:
case jit_code_arg_f: case jit_code_arg_d: case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end: 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; break;
default: default:
abort(); abort();
} }
jit_regarg_clr(node, value); jit_regarg_clr(node, value);
assert(_jitc->regarg == 0); assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */ /* update register live state */
jit_reglive(node); jit_reglive(node);
} }

View file

@ -10,7 +10,19 @@
0, /* #note */ 0, /* #note */
0, /* label */ 0, /* label */
16, /* prolog */ 16, /* prolog */
0, /* ellipsis */
0, /* allocai */
0, /* allocar */
0, /* arg */ 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_start */
0, /* va_arg */ 0, /* va_arg */
0, /* va_arg_d */ 0, /* va_arg_d */
@ -179,8 +191,26 @@
16, /* jmpi */ 16, /* jmpi */
8, /* callr */ 8, /* callr */
16, /* calli */ 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 */ 24, /* epilog */
0, /* arg_f */ 0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */ 4, /* addr_f */
16, /* addi_f */ 16, /* addi_f */
4, /* subr_f */ 4, /* subr_f */
@ -263,7 +293,15 @@
24, /* bordi_f */ 24, /* bordi_f */
12, /* bunordr_f */ 12, /* bunordr_f */
28, /* bunordi_f */ 28, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */ 0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */ 4, /* addr_d */
24, /* addi_d */ 24, /* addi_d */
4, /* subr_d */ 4, /* subr_d */
@ -346,6 +384,11 @@
32, /* bordi_d */ 32, /* bordi_d */
12, /* bunordr_d */ 12, /* bunordr_d */
36, /* bunordi_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_w_f */
0, /* movr_ww_d */ 0, /* movr_ww_d */
0, /* movr_w_d */ 0, /* movr_w_d */
@ -355,6 +398,4 @@
0, /* movi_d_ww */ 0, /* movi_d_ww */
0, /* movr_d_w */ 0, /* movr_d_w */
0, /* movi_d_w */ 0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
#endif /* __WORDSIZE */ #endif /* __WORDSIZE */

View file

@ -131,6 +131,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff, jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t)); _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); _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog); jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset; _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; default: _jitc->function->self.aoff &= -8; break;
} }
_jitc->function->self.aoff -= length; _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); 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; jit_int32_t reg;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) { if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1; _jitc->function->allocar = 1;
} }
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
jit_negr(reg, v); jit_negr(reg, v);
jit_andi(reg, reg, -16); jit_andi(reg, reg, -16);
jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
jit_addr(u, u, reg); jit_addr(u, u, reg);
jit_addr(_SP, _SP, reg); jit_addr(_SP, _SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg); jit_unget_reg(reg);
jit_dec_synth();
} }
void void
_jit_ret(jit_state_t *_jit) _jit_ret(jit_state_t *_jit)
{ {
jit_node_t *instr; jit_node_t *instr;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */ /* jump to epilog */
instr = jit_jmpi(); instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog); jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
} }
void void
_jit_retr(jit_state_t *_jit, jit_int32_t u) _jit_retr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr, u);
if (JIT_RET != u) if (JIT_RET != u)
jit_movr(JIT_RET, u); jit_movr(JIT_RET, u);
else else
jit_live(JIT_RET); jit_live(JIT_RET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti(jit_state_t *_jit, jit_word_t u) _jit_reti(jit_state_t *_jit, jit_word_t u)
{ {
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u); jit_movi(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u) _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_f, u);
if (JIT_FRET != u) if (JIT_FRET != u)
jit_movr_f(JIT_FRET, u); jit_movr_f(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u) _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_movi_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u) _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_d, u);
if (JIT_FRET != u) if (JIT_FRET != u)
jit_movr_d(JIT_FRET, u); jit_movr_d(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u) _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_movi_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
@ -264,22 +283,27 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void void
_jit_ellipsis(jit_state_t *_jit) _jit_ellipsis(jit_state_t *_jit)
{ {
jit_inc_synth(ellipsis);
if (_jitc->prepare) { if (_jitc->prepare) {
jit_link_prepare();
assert(!(_jitc->function->call.call & jit_call_varargs)); assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs; _jitc->function->call.call |= jit_call_varargs;
} }
else { else {
jit_link_prolog();
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs; _jitc->function->self.call |= jit_call_varargs;
_jitc->function->vagp = _jitc->function->self.argi; _jitc->function->vagp = _jitc->function->self.argi;
} }
jit_dec_synth();
} }
jit_node_t * jit_node_t *
_jit_arg(jit_state_t *_jit) _jit_arg(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function); assert(_jitc->function);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++; offset = _jitc->function->self.argi++;
@ -287,13 +311,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t); _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_node_t *
_jit_arg_f(jit_state_t *_jit) _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);
if (jit_arg_reg_p(_jitc->function->self.argi)) if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _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; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float32_t); _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_node_t *
_jit_arg_d(jit_state_t *_jit) _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);
if (jit_arg_d_reg_p(_jitc->function->self.argi)) { if (jit_arg_d_reg_p(_jitc->function->self.argi)) {
offset = _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; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t); _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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _I0 + v->u.w); jit_extr_c(u, _I0 + v->u.w);
else else
jit_ldxi_c(u, JIT_FP, jit_ldxi_c(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t)); v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t));
jit_dec_synth();
} }
void void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _I0 + v->u.w); jit_extr_uc(u, _I0 + v->u.w);
else else
jit_ldxi_uc(u, JIT_FP, jit_ldxi_uc(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t)); v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t));
jit_dec_synth();
} }
void void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _I0 + v->u.w); jit_extr_s(u, _I0 + v->u.w);
else else
jit_ldxi_s(u, JIT_FP, jit_ldxi_s(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t)); v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t));
jit_dec_synth();
} }
void void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _I0 + v->u.w); jit_extr_us(u, _I0 + v->u.w);
else else
jit_ldxi_us(u, JIT_FP, jit_ldxi_us(u, JIT_FP,
v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t)); v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t));
jit_dec_synth();
} }
void void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(u, _I0 + v->u.w); jit_movr(u, _I0 + v->u.w);
else else
jit_ldxi_i(u, JIT_FP, v->u.w); jit_ldxi_i(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(_I0 + v->u.w, u); jit_movr(_I0 + v->u.w, u);
else else
jit_stxi(v->u.w, JIT_FP, u); jit_stxi(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -393,6 +440,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi(_I0 + v->u.w, u); jit_movi(_I0 + v->u.w, u);
else { 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_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void 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(v->code == jit_code_arg_f);
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_arg_reg_p(v->u.w)) { if (jit_arg_reg_p(v->u.w)) {
jit_stxi(-4, JIT_FP, _I0 + v->u.w); jit_stxi(-4, JIT_FP, _I0 + v->u.w);
jit_ldxi_f(u, JIT_FP, -4); jit_ldxi_f(u, JIT_FP, -4);
} }
else else
jit_ldxi_f(u, JIT_FP, v->u.w); jit_ldxi_f(u, JIT_FP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_arg_reg_p(v->u.w)) { if (jit_arg_reg_p(v->u.w)) {
jit_stxi_f(-4, JIT_FP, u); jit_stxi_f(-4, JIT_FP, u);
jit_ldxi(_I0 + v->u.w, JIT_FP, -4); jit_ldxi(_I0 + v->u.w, JIT_FP, -4);
} }
else else
jit_stxi_f(v->u.w, JIT_FP, u); jit_stxi_f(v->u.w, JIT_FP, u);
jit_dec_synth();
} }
void void
@ -433,6 +486,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
regno = jit_get_reg(jit_class_fpr); regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u); jit_movi_f(regno, u);
if (jit_arg_reg_p(v->u.w)) { 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 else
jit_stxi_f(v->u.w, JIT_FP, regno); jit_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
jit_dec_synth();
} }
void 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(v->code == jit_code_arg_d);
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_arg_d_reg_p(v->u.w)) { if (jit_arg_d_reg_p(v->u.w)) {
jit_stxi(-8, JIT_FP, _I0 + v->u.w); jit_stxi(-8, JIT_FP, _I0 + v->u.w);
jit_stxi(-4, JIT_FP, _I0 + v->u.w + 1); 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, JIT_FP, v->u.w);
jit_ldxi_f(u + 1, JIT_FP, v->u.w + 4); jit_ldxi_f(u + 1, JIT_FP, v->u.w + 4);
} }
jit_dec_synth();
} }
void void
@ -470,6 +527,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_arg_d_reg_p(v->u.w)) { if (jit_arg_d_reg_p(v->u.w)) {
jit_stxi_d(-8, JIT_FP, u); jit_stxi_d(-8, JIT_FP, u);
jit_ldxi(_I0 + v->u.w, JIT_FP, -8); 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_stxi(v->u.w + 4, JIT_FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void 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; jit_int32_t regno, gpr;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
regno = jit_get_reg(jit_class_fpr); regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u); jit_movi_d(regno, u);
if (jit_arg_d_reg_p(v->u.w)) { 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(gpr);
} }
jit_unget_reg(regno); jit_unget_reg(regno);
jit_dec_synth();
} }
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _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)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_O0 + _jitc->function->call.argi, u); jit_movr(_O0 + _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_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); jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
_jit_pushargi(jit_state_t *_jit, jit_word_t u) _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_O0 + _jitc->function->call.argi, u); jit_movi(_O0 + _jitc->function->call.argi, u);
++_jitc->function->call.argi; ++_jitc->function->call.argi;
@ -559,11 +624,14 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
jit_unget_reg(regno); jit_unget_reg(regno);
_jitc->function->call.size += sizeof(jit_word_t); _jitc->function->call.size += sizeof(jit_word_t);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _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)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_stxi_f(-4, JIT_FP, u); jit_stxi_f(-4, JIT_FP, u);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -4); 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); jit_stxi_f(_jitc->function->call.size + stack_framesize, JIT_SP, u);
_jitc->function->call.size += sizeof(jit_float32_t); _jitc->function->call.size += sizeof(jit_float32_t);
} }
jit_dec_synth();
} }
void void
_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
regno = jit_get_reg(jit_class_fpr); regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u); jit_movi_f(regno, u);
if (jit_arg_reg_p(_jitc->function->call.argi)) { 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); _jitc->function->call.size += sizeof(jit_float32_t);
} }
jit_unget_reg(regno); jit_unget_reg(regno);
jit_dec_synth();
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _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)) { if (jit_arg_d_reg_p(_jitc->function->call.argi)) {
jit_stxi_d(-8, JIT_FP, u); jit_stxi_d(-8, JIT_FP, u);
jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8); 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); JIT_SP, u + 1);
_jitc->function->call.size += sizeof(jit_float64_t); _jitc->function->call.size += sizeof(jit_float64_t);
} }
jit_dec_synth();
} }
void void
_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
regno = jit_get_reg(jit_class_fpr); regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u); jit_movi_d(regno, u);
if (jit_arg_d_reg_p(_jitc->function->call.argi)) { 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); _jitc->function->call.size += sizeof(jit_float64_t);
} }
jit_unget_reg(regno); jit_unget_reg(regno);
jit_dec_synth();
} }
jit_bool_t jit_bool_t
@ -667,8 +745,8 @@ void
_jit_finishr(jit_state_t *_jit, jit_int32_t r0) _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_node_t *call; jit_node_t *call;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
call = jit_callr(r0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
} }
jit_node_t * jit_node_t *
_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
{ {
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
node = jit_calli(i0); 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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
return (node); return (node);
} }
void void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) _jit_retval_c(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_c, r0);
jit_extr_c(r0, _O0); jit_extr_c(r0, _O0);
jit_dec_synth();
} }
void void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_uc, r0);
jit_extr_uc(r0, _O0); jit_extr_uc(r0, _O0);
jit_dec_synth();
} }
void void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) _jit_retval_s(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_s, r0);
jit_extr_s(r0, _O0); jit_extr_s(r0, _O0);
jit_dec_synth();
} }
void void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) _jit_retval_us(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_us, r0);
jit_extr_us(r0, _O0); jit_extr_us(r0, _O0);
jit_dec_synth();
} }
void void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_i, r0);
if (r0 != _O0) if (r0 != _O0)
jit_movr(r0, _O0); jit_movr(r0, _O0);
jit_dec_synth();
} }
void void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_f, r0);
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_f(r0, JIT_FRET); jit_movr_f(r0, JIT_FRET);
jit_dec_synth();
} }
void void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_d, r0);
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET); jit_movr_d(r0, JIT_FRET);
jit_dec_synth();
} }
jit_pointer_t jit_pointer_t
@ -752,8 +846,14 @@ _emit_code(jit_state_t *_jit)
struct { struct {
jit_node_t *node; jit_node_t *node;
jit_word_t word; jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset; jit_int32_t patch_offset;
} undo; } undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL; _jitc->function = NULL;
@ -859,12 +959,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \ patch(word, node); \
} \ } \
break break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) { for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end) if (_jit->pc.uc >= _jitc->code.end)
return (NULL); return (NULL);
#if DEVEL_DISASSEMBLER #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 #endif
value = jit_classify(node->code); value = jit_classify(node->code);
jit_regarg_set(node, value); jit_regarg_set(node, value);
@ -1253,6 +1357,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w; _jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node; undo.node = node;
undo.word = _jit->pc.w; undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset; undo.patch_offset = _jitc->patches.offset;
restart_function: restart_function:
_jitc->again = 0; _jitc->again = 0;
@ -1270,6 +1377,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch; temp->flag &= ~jit_flag_patch;
node = undo.node; node = undo.node;
_jit->pc.w = undo.word; _jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset; _jitc->patches.offset = undo.patch_offset;
goto restart_function; goto restart_function;
} }
@ -1288,16 +1398,37 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d: case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w)); vaarg_d(rn(node->u.w), rn(node->v.w));
break; 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:
case jit_code_arg_f: case jit_code_arg_d: case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end: 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; break;
default: default:
abort(); abort();
} }
jit_regarg_clr(node, value); jit_regarg_clr(node, value);
assert(_jitc->regarg == 0); assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */ /* update register live state */
jit_reglive(node); jit_reglive(node);
} }

View file

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

View file

@ -423,6 +423,10 @@ _jit_prolog(jit_state_t *_jit)
jit_alloc((jit_pointer_t *)&_jitc->function->regoff, jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t)); _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); _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
jit_link(_jitc->function->prolog); jit_link(_jitc->function->prolog);
_jitc->function->prolog->w.w = offset; _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; default: _jitc->function->self.aoff &= -8; break;
} }
_jitc->function->self.aoff -= length; _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); 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; jit_int32_t reg;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_ww(allocar, u, v);
if (!_jitc->function->allocar) { if (!_jitc->function->allocar) {
_jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t));
_jitc->function->allocar = 1; _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_addr(JIT_SP, JIT_SP, reg);
jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
jit_unget_reg(reg); jit_unget_reg(reg);
jit_dec_synth();
} }
void void
_jit_ret(jit_state_t *_jit) _jit_ret(jit_state_t *_jit)
{ {
jit_node_t *instr; jit_node_t *instr;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth(ret);
/* jump to epilog */ /* jump to epilog */
instr = jit_jmpi(); instr = jit_jmpi();
jit_patch_at(instr, _jitc->function->epilog); jit_patch_at(instr, _jitc->function->epilog);
jit_dec_synth();
} }
void void
_jit_retr(jit_state_t *_jit, jit_int32_t u) _jit_retr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr, u);
/* movr(%ret, %ret) would be optimized out */ /* movr(%ret, %ret) would be optimized out */
if (JIT_RET != u) if (JIT_RET != u)
jit_movr(JIT_RET, u); jit_movr(JIT_RET, u);
@ -491,47 +510,58 @@ _jit_retr(jit_state_t *_jit, jit_int32_t u)
else else
jit_live(JIT_RET); jit_live(JIT_RET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti(jit_state_t *_jit, jit_word_t u) _jit_reti(jit_state_t *_jit, jit_word_t u)
{ {
jit_inc_synth_w(reti, u);
jit_movi(JIT_RET, u); jit_movi(JIT_RET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u) _jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_f, u);
if (JIT_FRET != u) if (JIT_FRET != u)
jit_movr_f(JIT_FRET, u); jit_movr_f(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u) _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_movi_f(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u) _jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{ {
jit_inc_synth_w(retr_d, u);
if (JIT_FRET != u) if (JIT_FRET != u)
jit_movr_d(JIT_FRET, u); jit_movr_d(JIT_FRET, u);
else else
jit_live(JIT_FRET); jit_live(JIT_FRET);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u) _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_movi_d(JIT_FRET, u);
jit_ret(); jit_ret();
jit_dec_synth();
} }
void void
@ -555,12 +585,15 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
void void
_jit_ellipsis(jit_state_t *_jit) _jit_ellipsis(jit_state_t *_jit)
{ {
jit_inc_synth(ellipsis);
if (_jitc->prepare) { if (_jitc->prepare) {
jit_link_prepare();
/* Remember that a varargs function call is being constructed. */ /* Remember that a varargs function call is being constructed. */
assert(!(_jitc->function->call.call & jit_call_varargs)); assert(!(_jitc->function->call.call & jit_call_varargs));
_jitc->function->call.call |= jit_call_varargs; _jitc->function->call.call |= jit_call_varargs;
} }
else { else {
jit_link_prolog();
/* Remember the current function is varargs. */ /* Remember the current function is varargs. */
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
_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; _jitc->function->vafp = va_fp_max_offset;
#endif #endif
} }
jit_dec_synth();
} }
jit_node_t * jit_node_t *
_jit_arg(jit_state_t *_jit) _jit_arg(jit_state_t *_jit)
{ {
jit_int32_t offset; jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function); assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
#if __X64 #if __X64
@ -607,14 +641,17 @@ _jit_arg(jit_state_t *_jit)
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += REAL_WORDSIZE; _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_node_t *
_jit_arg_f(jit_state_t *_jit) _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);
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
#if __X64 #if __X64
@ -633,14 +670,17 @@ _jit_arg_f(jit_state_t *_jit)
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += REAL_WORDSIZE; _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_node_t *
_jit_arg_d(jit_state_t *_jit) _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);
assert(!(_jitc->function->self.call & jit_call_varargs)); assert(!(_jitc->function->self.call & jit_call_varargs));
#if __X64 #if __X64
@ -659,61 +699,73 @@ _jit_arg_d(jit_state_t *_jit)
offset = _jitc->function->self.size; offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_float64_t); _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 void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_c, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, JIT_RA0 - v->u.w); jit_extr_c(u, JIT_RA0 - v->u.w);
else else
#endif #endif
jit_ldxi_c(u, _RBP, v->u.w); jit_ldxi_c(u, _RBP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_uc, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, JIT_RA0 - v->u.w); jit_extr_uc(u, JIT_RA0 - v->u.w);
else else
#endif #endif
jit_ldxi_uc(u, _RBP, v->u.w); jit_ldxi_uc(u, _RBP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_s, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, JIT_RA0 - v->u.w); jit_extr_s(u, JIT_RA0 - v->u.w);
else else
#endif #endif
jit_ldxi_s(u, _RBP, v->u.w); jit_ldxi_s(u, _RBP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_us, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, JIT_RA0 - v->u.w); jit_extr_us(u, JIT_RA0 - v->u.w);
else else
#endif #endif
jit_ldxi_us(u, _RBP, v->u.w); jit_ldxi_us(u, _RBP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_i, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) { if (jit_arg_reg_p(v->u.w)) {
# if __X64_32 # if __X64_32
@ -725,6 +777,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
else else
#endif #endif
jit_ldxi_i(u, _RBP, v->u.w); jit_ldxi_i(u, _RBP, v->u.w);
jit_dec_synth();
} }
#if __X64 && !__X64_32 #if __X64 && !__X64_32
@ -732,20 +785,24 @@ void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, JIT_RA0 - v->u.w); jit_extr_ui(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_ui(u, _RBP, v->u.w); jit_ldxi_ui(u, _RBP, v->u.w);
jit_dec_synth();
} }
void void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(u, JIT_RA0 - v->u.w); jit_movr(u, JIT_RA0 - v->u.w);
else else
jit_ldxi_l(u, _RBP, v->u.w); jit_ldxi_l(u, _RBP, v->u.w);
jit_dec_synth();
} }
#endif #endif
@ -753,12 +810,14 @@ void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(JIT_RA0 - v->u.w, u); jit_movr(JIT_RA0 - v->u.w, u);
else else
#endif #endif
jit_stxi(v->u.w, _RBP, u); jit_stxi(v->u.w, _RBP, u);
jit_dec_synth();
} }
void void
@ -766,6 +825,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg); assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi(JIT_RA0 - v->u.w, u); 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_stxi(v->u.w, _RBP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
#if __X64 #if __X64
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(u, _XMM0 - v->u.w); jit_movr_f(u, _XMM0 - v->u.w);
else else
#endif #endif
jit_ldxi_f(u, _RBP, v->u.w); jit_ldxi_f(u, _RBP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_f(_XMM0 - v->u.w, u); jit_movr_f(_XMM0 - v->u.w, u);
else else
#endif #endif
jit_stxi_f(v->u.w, _RBP, u); jit_stxi_f(v->u.w, _RBP, u);
jit_dec_synth();
} }
void void
@ -808,6 +873,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_f); assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi_f(_XMM0 - v->u.w, u); 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_stxi_f(v->u.w, _RBP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
#if __X64 #if __X64
if (jit_arg_f_reg_p(v->u.w)) if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, _XMM0 - v->u.w); jit_movr_d(u, _XMM0 - v->u.w);
else else
#endif #endif
jit_ldxi_d(u, _RBP, v->u.w); jit_ldxi_d(u, _RBP, v->u.w);
jit_dec_synth();
} }
void void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{ {
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr_d(_XMM0 - v->u.w, u); jit_movr_d(_XMM0 - v->u.w, u);
else else
#endif #endif
jit_stxi_d(v->u.w, _RBP, u); jit_stxi_d(v->u.w, _RBP, u);
jit_dec_synth();
} }
void void
@ -850,6 +921,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(v->code == jit_code_arg_d); assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
#if __X64 #if __X64
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movi_d(_XMM0 - v->u.w, u); 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_stxi_d(v->u.w, _RBP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_link_prepare();
#if __X64 #if __X64
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(JIT_RA0 - _jitc->function->call.argi, u); 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); jit_stxi(_jitc->function->call.size, _RSP, u);
_jitc->function->call.size += REAL_WORDSIZE; _jitc->function->call.size += REAL_WORDSIZE;
} }
jit_dec_synth();
} }
void void
_jit_pushargi(jit_state_t *_jit, jit_word_t u) _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_link_prepare();
#if __X64 #if __X64
if (jit_arg_reg_p(_jitc->function->call.argi)) { if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(JIT_RA0 - _jitc->function->call.argi, u); 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; _jitc->function->call.size += REAL_WORDSIZE;
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr_f, u);
jit_link_prepare();
#if __X64 #if __X64
# if __CYGWIN__ # if __CYGWIN__
if (jit_arg_reg_p(_jitc->function->call.argi)) { 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); jit_stxi_f(_jitc->function->call.size, _RSP, u);
_jitc->function->call.size += REAL_WORDSIZE; _jitc->function->call.size += REAL_WORDSIZE;
} }
jit_dec_synth();
} }
void void
_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_f(pushargi_f, u);
jit_link_prepare();
#if __X64 #if __X64
# if __CYGWIN__ # if __CYGWIN__
if (jit_arg_reg_p(_jitc->function->call.argi)) { 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; _jitc->function->call.size += REAL_WORDSIZE;
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{ {
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(pushargr_d, u);
jit_link_prepare();
#if __X64 #if __X64
# if __CYGWIN__ # if __CYGWIN__
if (jit_arg_reg_p(_jitc->function->call.argi)) { 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); jit_stxi_d(_jitc->function->call.size, _RSP, u);
_jitc->function->call.size += sizeof(jit_float64_t); _jitc->function->call.size += sizeof(jit_float64_t);
} }
jit_dec_synth();
} }
void void
_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_d(pushargi_d, u);
jit_link_prepare();
#if __X64 #if __X64
# if __CYGWIN__ # if __CYGWIN__
if (jit_arg_reg_p(_jitc->function->call.argi)) { 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); _jitc->function->call.size += sizeof(jit_float64_t);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth();
} }
jit_bool_t jit_bool_t
@ -1075,9 +1163,9 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_int32_t reg; jit_int32_t reg;
jit_node_t *call; jit_node_t *call;
reg = r0;
assert(_jitc->function); assert(_jitc->function);
reg = r0;
jit_inc_synth_w(finishr, r0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
#if __X64 #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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
} }
jit_node_t * jit_node_t *
@ -1111,8 +1200,8 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
jit_int32_t reg; jit_int32_t reg;
#endif #endif
jit_node_t *node; jit_node_t *node;
assert(_jitc->function); assert(_jitc->function);
jit_inc_synth_w(finishi, (jit_word_t)i0);
if (_jitc->function->self.alen < _jitc->function->call.size) if (_jitc->function->self.alen < _jitc->function->call.size)
_jitc->function->self.alen = _jitc->function->call.size; _jitc->function->self.alen = _jitc->function->call.size;
#if __X64 #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.argi = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 0; _jitc->prepare = 0;
jit_dec_synth();
return (node); return (node);
} }
void void
_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) _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_extr_c(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) _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_extr_uc(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) _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_extr_s(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) _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_extr_us(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) _jit_retval_i(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_i, r0);
#if __X32 || __X64_32 #if __X32 || __X64_32
if (r0 != JIT_RET) if (r0 != JIT_RET)
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
#else #else
jit_extr_i(r0, JIT_RET); jit_extr_i(r0, JIT_RET);
#endif #endif
jit_dec_synth();
} }
#if __X64 && !__X64_32 #if __X64 && !__X64_32
void void
_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) _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_extr_ui(r0, JIT_RET);
jit_dec_synth();
} }
void void
_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) _jit_retval_l(jit_state_t *_jit, jit_int32_t r0)
{ {
jit_inc_synth_w(retval_l, r0);
if (r0 != JIT_RET) if (r0 != JIT_RET)
jit_movr(r0, JIT_RET); jit_movr(r0, JIT_RET);
jit_dec_synth();
} }
#endif #endif
void void
_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) _jit_retval_f(jit_state_t *_jit, jit_int32_t r0)
{ {
# if __X32 jit_inc_synth_w(retval_f, r0);
jit_new_node_w(jit_code_x86_retval_f, r0); #if __X64
# else
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_f(r0, JIT_FRET); jit_movr_f(r0, JIT_FRET);
# endif #endif
jit_dec_synth();
} }
void void
_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
{ {
# if __X32 jit_inc_synth_w(retval_d, r0);
jit_new_node_w(jit_code_x86_retval_d, r0); #if __X64
# else
if (r0 != JIT_FRET) if (r0 != JIT_FRET)
jit_movr_d(r0, JIT_FRET); jit_movr_d(r0, JIT_FRET);
# endif #endif
jit_dec_synth();
} }
jit_pointer_t jit_pointer_t
@ -1222,8 +1326,14 @@ _emit_code(jit_state_t *_jit)
struct { struct {
jit_node_t *node; jit_node_t *node;
jit_word_t word; jit_word_t word;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
jit_int32_t patch_offset; jit_int32_t patch_offset;
} undo; } undo;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
_jitc->function = NULL; _jitc->function = NULL;
@ -1461,12 +1571,16 @@ _emit_code(jit_state_t *_jit)
patch(word, node); \ patch(word, node); \
} \ } \
break break
#if DEVEL_DISASSEMBLER
prevw = _jit->pc.w;
#endif
for (node = _jitc->head; node; node = node->next) { for (node = _jitc->head; node; node = node->next) {
if (_jit->pc.uc >= _jitc->code.end) if (_jit->pc.uc >= _jitc->code.end)
return (NULL); return (NULL);
#if DEVEL_DISASSEMBLER #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 #endif
value = jit_classify(node->code); value = jit_classify(node->code);
jit_regarg_set(node, value); jit_regarg_set(node, value);
@ -1917,6 +2031,9 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w; _jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node; undo.node = node;
undo.word = _jit->pc.w; undo.word = _jit->pc.w;
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
undo.patch_offset = _jitc->patches.offset; undo.patch_offset = _jitc->patches.offset;
restart_function: restart_function:
_jitc->again = 0; _jitc->again = 0;
@ -1934,6 +2051,9 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch; temp->flag &= ~jit_flag_patch;
node = undo.node; node = undo.node;
_jit->pc.w = undo.word; _jit->pc.w = undo.word;
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
_jitc->patches.offset = undo.patch_offset; _jitc->patches.offset = undo.patch_offset;
goto restart_function; goto restart_function;
} }
@ -1946,24 +2066,6 @@ _emit_code(jit_state_t *_jit)
epilog(node); epilog(node);
_jitc->function = NULL; _jitc->function = NULL;
break; 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: case jit_code_va_start:
vastart(rn(node->u.w)); vastart(rn(node->u.w));
break; break;
@ -1973,16 +2075,62 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d: case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w), jit_x87_reg_p(node->u.w)); vaarg_d(rn(node->u.w), rn(node->v.w), jit_x87_reg_p(node->u.w));
break; 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:
case jit_code_arg_f: case jit_code_arg_d: case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end: 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; break;
default: default:
abort(); abort();
} }
jit_regarg_clr(node, value); jit_regarg_clr(node, value);
assert(_jitc->regarg == 0); assert(_jitc->regarg == 0 && _jitc->synth == 0);
/* update register live state */ /* update register live state */
jit_reglive(node); 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) #define del_node(u, v) _del_node(_jit, u, v)
static inline void _del_node(jit_state_t*, jit_node_t*, jit_node_t*); 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) #define del_label(u, v) _del_label(_jit, u, v)
static void _del_label(jit_state_t*, jit_node_t*, jit_node_t*); 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(); new_pool();
node = _jitc->list; node = _jitc->list;
_jitc->list = node->next; _jitc->list = node->next;
if (_jitc->synth)
node->flag |= jit_flag_synth;
node->next = NULL; node->next = NULL;
node->code = code; node->code = code;
@ -711,6 +716,14 @@ _del_node(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
_jitc->list = 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 static void
_del_label(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) _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); jit_free((jit_pointer_t *)&_jit);
} }
void
_jit_synth_inc(jit_state_t *_jit)
{
assert(_jitc->synth < 8);
++_jitc->synth;
}
jit_node_t * jit_node_t *
_jit_new_node(jit_state_t *_jit, jit_code_t code) _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); link_node(node);
} }
void
_jit_synth_dec(jit_state_t *_jit)
{
assert(_jitc->synth > 0);
--_jitc->synth;
}
jit_node_t * jit_node_t *
_jit_new_node_w(jit_state_t *_jit, jit_code_t code, _jit_new_node_w(jit_state_t *_jit, jit_code_t code,
jit_word_t u) jit_word_t u)
@ -937,6 +964,26 @@ _jit_new_node_w(jit_state_t *_jit, jit_code_t code,
return (link_node(node)); 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_node_t *
_jit_new_node_p(jit_state_t *_jit, jit_code_t code, _jit_new_node_p(jit_state_t *_jit, jit_code_t code,
jit_pointer_t u) 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)); 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_node_t *
_jit_new_node_pw(jit_state_t *_jit, jit_code_t code, _jit_new_node_pw(jit_state_t *_jit, jit_code_t code,
jit_pointer_t u, jit_word_t v) 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.argi =
_jitc->function->call.argf = _jitc->function->call.argf =
_jitc->function->call.size = 0; _jitc->function->call.size = 0;
_jitc->prepare = 1; _jitc->prepare = jit_new_node(jit_code_prepare);
} }
void void
@ -1182,28 +1251,69 @@ _jit_classify(jit_state_t *_jit, jit_code_t code)
jit_int32_t mask; jit_int32_t mask;
switch (code) { switch (code) {
case jit_code_data: case jit_code_align: case jit_code_save: case jit_code_data: case jit_code_save: case jit_code_load:
case jit_code_load: case jit_code_name: case jit_code_label: case jit_code_name: case jit_code_label: case jit_code_note:
case jit_code_note: case jit_code_prolog: case jit_code_epilog: case jit_code_prolog: case jit_code_ellipsis: case jit_code_epilog:
case jit_code_ret: case jit_code_prepare:
mask = 0; mask = 0;
break; break;
case jit_code_live: case jit_code_va_end: 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; mask = jit_cc_a0_reg;
break; 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; mask = jit_cc_a0_int;
break; 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: case jit_code_calli: case jit_code_jmpi:
mask = jit_cc_a0_jmp; mask = jit_cc_a0_jmp;
break; break;
case jit_code_callr: case jit_code_jmpr: case jit_code_callr: case jit_code_jmpr:
mask = jit_cc_a0_reg|jit_cc_a0_jmp; mask = jit_cc_a0_reg|jit_cc_a0_jmp;
break; break;
case jit_code_x86_retval_f: case jit_code_retval_c: case jit_code_retval_uc:
case jit_code_x86_retval_d: 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: case jit_code_va_start:
mask = jit_cc_a0_reg|jit_cc_a0_chg; mask = jit_cc_a0_reg|jit_cc_a0_chg;
break; 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_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_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: 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: case jit_code_bordi_d: case jit_code_bunordi_d:
mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl; mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl;
break; 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_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: case jit_code_str_l: case jit_code_str_f: case jit_code_str_d:
mask = jit_cc_a0_reg|jit_cc_a1_reg; mask = jit_cc_a0_reg|jit_cc_a1_reg;
@ -1512,7 +1624,15 @@ _jit_optimize(jit_state_t *_jit)
break; break;
default: default:
#if JIT_HASH_CONSTS #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->v.p = jit_data(&node->v.f, sizeof(jit_float32_t), 4);
node->flag |= jit_flag_node | jit_flag_data; 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_cc_a1_reg|jit_cc_a1_chg))
jit_regset_setbit(&_jitc->function->regset, jit_regset_setbit(&_jitc->function->regset,
jit_regno(node->v.w)); 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; break;
} }
@ -1632,8 +1756,14 @@ _jit_reglive(jit_state_t *_jit, jit_node_t *node)
else else
jit_regset_setbit(&_jitc->reglive, node->v.w); jit_regset_setbit(&_jitc->reglive, node->v.w);
} }
if ((value & jit_cc_a2_reg) && !(node->w.w & jit_regno_patch)) 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_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)) { if (jit_regset_set_p(&_jitc->regmask)) {
bmp_zero(); bmp_zero();
jit_update(node->next, &_jitc->reglive, &_jitc->regmask); 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) && if ((value & jit_cc_a2_reg) &&
!(node->w.w & jit_regno_patch) && !(node->w.w & jit_regno_patch) &&
jit_regset_tstbit(&regmask, node->w.w)) { jit_regset_tstbit(&regmask, node->w.w)) {
jit_regset_clrbit(&regmask, node->w.w); live = !(value & jit_cc_a2_chg);
jit_regset_setbit(&reglive, node->w.w); 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) if (value & jit_cc_a0_jmp)
jump = 1; jump = 1;
@ -2151,7 +2284,8 @@ _jit_update(jit_state_t *_jit, jit_node_t *node,
if (!(node->w.w & jit_regno_patch)) { if (!(node->w.w & jit_regno_patch)) {
if (jit_regset_tstbit(mask, node->w.w)) { if (jit_regset_tstbit(mask, node->w.w)) {
jit_regset_clrbit(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)) if (regno == jit_regno(iter->v.w))
return; 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; break;
} }
} }
@ -2959,6 +3098,11 @@ _simplify(jit_state_t *_jit)
_jitc->values[regno].kind = 0; _jitc->values[regno].kind = 0;
++_jitc->gen[regno]; ++_jitc->gen[regno];
} }
if (info & jit_cc_a2_chg) {
regno = jit_regno(node->w.w);
_jitc->values[regno].kind = 0;
++_jitc->gen[regno];
}
break; 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 && else if ((value & jit_cc_a1_reg) && node->v.w == regno &&
(value & jit_cc_a1_chg)) (value & jit_cc_a1_chg))
return (jit_reg_change); 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"); fprintf(fp, "#if defined(__ppc__)\n");
#elif defined(__powerpc__) #elif defined(__powerpc__)
fprintf(fp, "#if defined(__powerpc__)\n"); fprintf(fp, "#if defined(__powerpc__)\n");
fprintf(fp, "#if __BYTE_ORDER == %s\n",
__BYTE_ORDER == __BIG_ENDIAN ? "__BIG_ENDIAN" : "__LITTLE_ENDIAN");
#endif #endif
fprintf(fp, "#define JIT_INSTR_MAX %d\n", max); fprintf(fp, "#define JIT_INSTR_MAX %d\n", max);
for (offset = 0; offset < jit_code_last_code; offset++) for (offset = 0; offset < jit_code_last_code; offset++)
@ -93,6 +95,7 @@ main(int argc, char *argv[])
#elif defined(__ppc__) #elif defined(__ppc__)
fprintf(fp, "#endif /* __ppc__ */\n"); fprintf(fp, "#endif /* __ppc__ */\n");
#elif defined(__powerpc__) #elif defined(__powerpc__)
fprintf(fp, "#endif /* __BYTE_ORDER */\n");
fprintf(fp, "#endif /* __powerpc__ */\n"); fprintf(fp, "#endif /* __powerpc__ */\n");
#endif #endif
#if __X64 || __X32 #if __X64 || __X32
@ -100,7 +103,7 @@ main(int argc, char *argv[])
fprintf(fp, "# endif /* __X64_32 */\n"); fprintf(fp, "# endif /* __X64_32 */\n");
fprintf(fp, "#endif /* __X64 */\n"); fprintf(fp, "#endif /* __X64 */\n");
# else # else
fprintf(fp, "#if __X32\n"); fprintf(fp, "#endif /* __X32 */\n");
# endif # endif
#else #else
fprintf(fp, "#endif /* __WORDSIZE */\n"); fprintf(fp, "#endif /* __WORDSIZE */\n");