From d0a5bd8d3deec1574593b83dda4de361ae4bb623 Mon Sep 17 00:00:00 2001 From: pcpa Date: Thu, 4 Jun 2015 18:53:07 -0300 Subject: [PATCH] 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. --- ChangeLog | 80 ++- include/lightning.h | 59 ++- include/lightning/jit_private.h | 82 ++- lib/Makefile.am | 1 + lib/jit_aarch64-sz.c | 107 ++-- lib/jit_aarch64.c | 169 ++++++- lib/jit_alpha-sz.c | 45 +- lib/jit_alpha.c | 173 ++++++- lib/jit_arm-sz.c | 374 ++++++++------ lib/jit_arm.c | 281 +++++++++-- lib/jit_disasm.c | 9 +- lib/jit_hppa-sz.c | 45 +- lib/jit_hppa.c | 159 +++++- lib/jit_ia64-sz.c | 45 +- lib/jit_ia64.c | 174 ++++++- lib/jit_mips-cpu.c | 34 +- lib/jit_mips-fpu.c | 25 +- lib/jit_mips-sz.c | 175 ++++++- lib/jit_mips.c | 313 +++++++++--- lib/jit_names.c | 29 +- lib/jit_ppc-cpu.c | 31 +- lib/jit_ppc-fpu.c | 19 +- lib/jit_ppc-sz.c | 636 ++++++++++++++++++++++-- lib/jit_ppc.c | 349 +++++++++---- lib/jit_print.c | 80 ++- lib/jit_rewind.c | 186 +++++++ lib/jit_s390-fpu.c | 4 +- lib/jit_s390-sz.c | 854 +++++++++++++++++--------------- lib/jit_s390.c | 173 ++++++- lib/jit_sparc-sz.c | 45 +- lib/jit_sparc.c | 165 +++++- lib/jit_x86-sz.c | 210 +++++++- lib/jit_x86.c | 240 +++++++-- lib/lightning.c | 173 ++++++- size.c | 5 +- 35 files changed, 4397 insertions(+), 1152 deletions(-) create mode 100644 lib/jit_rewind.c diff --git a/ChangeLog b/ChangeLog index 9b6ffff06..34eeefa7f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,52 @@ -2015-06-25 Paulo Andrade +2015-06-04 Paulo Andrade + + * 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 * check/cva_list.c: New file implementing a test to ensure the value returned by jit_va_start is a valid C va_list. @@ -20,7 +68,7 @@ lib/jit_x86-cpu.c, lib/jit_x86-sz.c, lib/jit_x86.c: Correct the jit_va_list_t semantics to match C va_list. -2015-06-24 Paulo Andrade +2015-05-24 Paulo Andrade * lib/Makefile.am: Bump library major. This is a preparation for a rework that was due for quite some time, but that is @@ -40,78 +88,78 @@ make that call after jit_ellipsis, but documentation should be updated for it. -2015-06-24 Paulo Andrade +2015-05-24 Paulo Andrade * lib/jit_aarch64-fpu.c, lib/jit_aarch64.c: Correct base aarch64 varargs code. -2015-06-24 Paulo Andrade +2015-05-24 Paulo Andrade * check/lightning.c: Clearly run check if clang is the system compiler. -2015-06-20 Paulo Andrade +2015-05-20 Paulo Andrade * lib/jit_sparc-cpu.c, lib/jit_sparc-fpu.c, lib/jit_sparc.c: Add base support to jit vararg functions to the sparc backend. -2015-06-20 Paulo Andrade +2015-05-20 Paulo Andrade * lib/jit_alpha-cpu.c, lib/jit_alpha-fpu.c, lib/jit_alpha.c: Add base support to jit vararg functions to the alpha backend. -2015-06-19 Paulo Andrade +2015-05-19 Paulo Andrade * lib/jit_hppa-cpu.c, lib/jit_hppa-fpu.c, lib/jit_hppa.c: Add base support to jit vararg functions to the hppa backend. -2015-06-10 Paulo Andrade +2015-05-10 Paulo Andrade * lib/jit_ia64-cpu.c, lib/jit_ia64-fpu.c, lib/jit_ia64.c: Add base support to jit vararg functions to the ia64 backend. -2015-06-10 Paulo Andrade +2015-05-10 Paulo Andrade * lib/jit_ia64-fpu.c, lib/jit_ia64.c: Correct movi_d_w and movi_f_w implementation to work when not using a data buffer. This causes the check varargs.tst to work when passing "-d" to the lightning test tool. -2015-06-10 Paulo Andrade +2015-05-10 Paulo Andrade * lib/jit_ia64.c: Implement inline assembly cache flush, required on multiprocessor systems. -2015-06-06 Paulo Andrade +2015-05-06 Paulo Andrade * lib/jit_mips-cpu.c, lib/jit_mips-fpu.c, lib/jit_mips.c: Add base support to jit vararg functions to the mips backend. Currently only supported on the o32 abi, until access to a n32 system is arranged. -2015-06-05 Paulo Andrade +2015-05-05 Paulo Andrade * lib/jit_ppc-cpu.c, lib/jit_ppc-fpu.c, lib/jit_ppc.c: Add base support to jit vararg functions to the PowerPC backend. -2015-06-02 Paulo Andrade +2015-05-02 Paulo Andrade * lib/jit_s390-cpu.c, lib/jit_s390-fpu.c, lib/jit_s390.c: Add base support to jit vararg functions to the s390 backend. -2015-06-01 Paulo Andrade +2015-05-01 Paulo Andrade * lib/jit_arm-cpu.c, lib/jit_arm-swf.c, lib/jit_arm-vfp.c, lib/jit_arm.c: Add base support to jit vararg functions to the arm backend. -2015-05-30 Paulo Andrade +2015-04-30 Paulo Andrade * lib/jit_aarch64-cpu.c, lib/jit_aarch64-fpu.c, lib/jit_aarch64.c: Add base support to jit vararg functions to the aarch64 backend. -2015-05-27 Paulo Andrade +2015-04-27 Paulo Andrade * include/lightning.h, include/lightning/jit_private.h, lib/jit_names.c, lib/lightning.c: Add initial support diff --git a/include/lightning.h b/include/lightning.h index aa32581a4..b4a46e239 100644 --- a/include/lightning.h +++ b/include/lightning.h @@ -154,11 +154,12 @@ typedef jit_int32_t jit_fpr_t; # include #endif -#define jit_flag_node 0x00000001 /* patch node not absolute */ -#define jit_flag_patch 0x00000002 /* jump already patched */ -#define jit_flag_data 0x00000004 /* data in the constant pool */ -#define jit_flag_use 0x00000008 /* do not remove marker label */ -#define jit_flag_head 0x00100000 /* label reached by normal flow */ +#define jit_flag_node 0x0001 /* patch node not absolute */ +#define jit_flag_patch 0x0002 /* jump already patched */ +#define jit_flag_data 0x0004 /* data in the constant pool */ +#define jit_flag_use 0x0008 /* do not remove marker label */ +#define jit_flag_synth 0x0010 /* synthesized instruction */ +#define jit_flag_head 0x1000 /* label reached by normal flow */ #define JIT_R(index) jit_r(index) #define JIT_V(index) jit_v(index) @@ -200,14 +201,19 @@ typedef enum { jit_code_prolog, #define jit_ellipsis() _jit_ellipsis(_jit) + jit_code_ellipsis, #define jit_allocai(u) _jit_allocai(_jit,u) #define jit_allocar(u, v) _jit_allocar(_jit,u,v) + jit_code_allocai, jit_code_allocar, #define jit_arg() _jit_arg(_jit) + jit_code_arg, #define jit_getarg_c(u,v) _jit_getarg_c(_jit,u,v) #define jit_getarg_uc(u,v) _jit_getarg_uc(_jit,u,v) + jit_code_getarg_c, jit_code_getarg_uc, #define jit_getarg_s(u,v) _jit_getarg_s(_jit,u,v) #define jit_getarg_us(u,v) _jit_getarg_us(_jit,u,v) + jit_code_getarg_s, jit_code_getarg_us, #define jit_getarg_i(u,v) _jit_getarg_i(_jit,u,v) #if __WORDSIZE == 32 # define jit_getarg(u,v) jit_getarg_i(u,v) @@ -216,9 +222,11 @@ typedef enum { # define jit_getarg_ui(u,v) _jit_getarg_ui(_jit,u,v) # define jit_getarg_l(u,v) _jit_getarg_l(_jit,u,v) #endif + jit_code_getarg_i, jit_code_getarg_ui, + jit_code_getarg_l, # define jit_putargr(u,v) _jit_putargr(_jit,u,v) # define jit_putargi(u,v) _jit_putargi(_jit,u,v) - jit_code_arg, + jit_code_putargr, jit_code_putargi, #define jit_va_start(u) jit_new_node_w(jit_code_va_start, u) jit_code_va_start, @@ -532,17 +540,24 @@ typedef enum { jit_code_callr, jit_code_calli, #define jit_prepare() _jit_prepare(_jit) + jit_code_prepare, #define jit_pushargr(u) _jit_pushargr(_jit,u) #define jit_pushargi(u) _jit_pushargi(_jit,u) + jit_code_pushargr, jit_code_pushargi, #define jit_finishr(u) _jit_finishr(_jit,u) #define jit_finishi(u) _jit_finishi(_jit,u) + jit_code_finishr, jit_code_finishi, #define jit_ret() _jit_ret(_jit) + jit_code_ret, #define jit_retr(u) _jit_retr(_jit,u) #define jit_reti(u) _jit_reti(_jit,u) + jit_code_retr, jit_code_reti, #define jit_retval_c(u) _jit_retval_c(_jit,u) #define jit_retval_uc(u) _jit_retval_uc(_jit,u) + jit_code_retval_c, jit_code_retval_uc, #define jit_retval_s(u) _jit_retval_s(_jit,u) #define jit_retval_us(u) _jit_retval_us(_jit,u) + jit_code_retval_s, jit_code_retval_us, #define jit_retval_i(u) _jit_retval_i(_jit,u) #if __WORDSIZE == 32 # define jit_retval(u) jit_retval_i(u) @@ -551,16 +566,19 @@ typedef enum { # define jit_retval_ui(u) _jit_retval_ui(_jit,u) # define jit_retval_l(u) _jit_retval_l(_jit,u) #endif - /* Usually should not need to call directly, but useful if need - * to get a label just before a jit_prolog() call */ + jit_code_retval_i, jit_code_retval_ui, + jit_code_retval_l, + #define jit_epilog() _jit_epilog(_jit) jit_code_epilog, #define jit_arg_f() _jit_arg_f(_jit) + jit_code_arg_f, #define jit_getarg_f(u,v) _jit_getarg_f(_jit,u,v) + jit_code_getarg_f, #define jit_putargr_f(u,v) _jit_putargr_f(_jit,u,v) #define jit_putargi_f(u,v) _jit_putargi_f(_jit,u,v) - jit_code_arg_f, + jit_code_putargr_f, jit_code_putargi_f, #define jit_addr_f(u,v,w) jit_new_node_www(jit_code_addr_f,u,v,w) #define jit_addi_f(u,v,w) jit_new_node_wwf(jit_code_addi_f,u,v,w) @@ -699,15 +717,20 @@ typedef enum { #define jit_pushargr_f(u) _jit_pushargr_f(_jit,u) #define jit_pushargi_f(u) _jit_pushargi_f(_jit,u) + jit_code_pushargr_f, jit_code_pushargi_f, #define jit_retr_f(u) _jit_retr_f(_jit,u) #define jit_reti_f(u) _jit_reti_f(_jit,u) + jit_code_retr_f, jit_code_reti_f, #define jit_retval_f(u) _jit_retval_f(_jit,u) + jit_code_retval_f, #define jit_arg_d() _jit_arg_d(_jit) + jit_code_arg_d, #define jit_getarg_d(u,v) _jit_getarg_d(_jit,u,v) + jit_code_getarg_d, #define jit_putargr_d(u,v) _jit_putargr_d(_jit,u,v) #define jit_putargi_d(u,v) _jit_putargi_d(_jit,u,v) - jit_code_arg_d, + jit_code_putargr_d, jit_code_putargi_d, #define jit_addr_d(u,v,w) jit_new_node_www(jit_code_addr_d,u,v,w) #define jit_addi_d(u,v,w) jit_new_node_wwd(jit_code_addi_d,u,v,w) @@ -847,9 +870,12 @@ typedef enum { #define jit_pushargr_d(u) _jit_pushargr_d(_jit,u) #define jit_pushargi_d(u) _jit_pushargi_d(_jit,u) + jit_code_pushargr_d, jit_code_pushargi_d, #define jit_retr_d(u) _jit_retr_d(_jit,u) #define jit_reti_d(u) _jit_reti_d(_jit,u) + jit_code_retr_d, jit_code_reti_d, #define jit_retval_d(u) _jit_retval_d(_jit,u) + jit_code_retval_d, /* Special internal backend specific codes */ jit_code_movr_w_f, jit_code_movr_ww_d, /* w* -> f|d */ @@ -869,7 +895,6 @@ typedef enum { #define jit_movr_d_w(u, v) jit_new_node_ww(jit_code_movr_d_w, u, v) #define jit_movi_d_w(u, v) jit_new_node_wd(jit_code_movi_d_w, u, v) - jit_code_x86_retval_f, jit_code_x86_retval_d, jit_code_last_code } jit_code_t; @@ -994,6 +1019,12 @@ extern jit_node_t *_jit_new_node(jit_state_t*, jit_code_t); #define jit_new_node_w(c,u) _jit_new_node_w(_jit,c,u) extern jit_node_t *_jit_new_node_w(jit_state_t*, jit_code_t, jit_word_t); +#define jit_new_node_f(c,u) _jit_new_node_f(_jit,c,u) +extern jit_node_t *_jit_new_node_f(jit_state_t*, jit_code_t, + jit_float32_t); +#define jit_new_node_d(c,u) _jit_new_node_d(_jit,c,u) +extern jit_node_t *_jit_new_node_d(jit_state_t*, jit_code_t, + jit_float64_t); #define jit_new_node_p(c,u) _jit_new_node_p(_jit,c,u) extern jit_node_t *_jit_new_node_p(jit_state_t*, jit_code_t, jit_pointer_t); @@ -1003,6 +1034,12 @@ extern jit_node_t *_jit_new_node_ww(jit_state_t*,jit_code_t, #define jit_new_node_wp(c,u,v) _jit_new_node_wp(_jit,c,u,v) extern jit_node_t *_jit_new_node_wp(jit_state_t*,jit_code_t, jit_word_t, jit_pointer_t); +#define jit_new_node_fp(c,u,v) _jit_new_node_fp(_jit,c,u,v) +extern jit_node_t *_jit_new_node_fp(jit_state_t*,jit_code_t, + jit_float32_t, jit_pointer_t); +#define jit_new_node_dp(c,u,v) _jit_new_node_dp(_jit,c,u,v) +extern jit_node_t *_jit_new_node_dp(jit_state_t*,jit_code_t, + jit_float64_t, jit_pointer_t); #define jit_new_node_pw(c,u,v) _jit_new_node_pw(_jit,c,u,v) extern jit_node_t *_jit_new_node_pw(jit_state_t*,jit_code_t, jit_pointer_t, jit_word_t); diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h index 953e361b0..0730439cd 100644 --- a/include/lightning/jit_private.h +++ b/include/lightning/jit_private.h @@ -145,6 +145,70 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*, (!jit_regset_tstbit(&_jitc->regarg, regno) && \ !jit_regset_tstbit(&_jitc->regsav, regno)) +#define jit_inc_synth(code) \ + do { \ + (void)jit_new_node(jit_code_##code); \ + jit_synth_inc(); \ + } while (0) +#define jit_inc_synth_w(code, u) \ + do { \ + (void)jit_new_node_w(jit_code_##code, u); \ + jit_synth_inc(); \ + } while (0) +#define jit_inc_synth_f(code, u) \ + do { \ + (void)jit_new_node_f(jit_code_##code, u); \ + jit_synth_inc(); \ + } while (0) +#define jit_inc_synth_d(code, u) \ + do { \ + (void)jit_new_node_d(jit_code_##code, u); \ + jit_synth_inc(); \ + } while (0) +#define jit_inc_synth_ww(code, u, v) \ + do { \ + (void)jit_new_node_ww(jit_code_##code, u, v); \ + jit_synth_inc(); \ + } while (0) +#define jit_inc_synth_wp(code, u, v) \ + do { \ + (void)jit_new_node_wp(jit_code_##code, u, v); \ + jit_synth_inc(); \ + } while (0) +#define jit_inc_synth_fp(code, u, v) \ + do { \ + (void)jit_new_node_fp(jit_code_##code, u, v); \ + jit_synth_inc(); \ + } while (0) +#define jit_inc_synth_dp(code, u, v) \ + do { \ + (void)jit_new_node_dp(jit_code_##code, u, v); \ + jit_synth_inc(); \ + } while (0) +#define jit_dec_synth() jit_synth_dec() + +#define jit_link_prolog() \ + do { \ + _jitc->tail->link = _jitc->function->prolog->link; \ + _jitc->function->prolog->link = _jitc->tail; \ + } while (0) +#define jit_link_prepare() \ + do { \ + _jitc->tail->link = _jitc->prepare->link; \ + _jitc->prepare->link = _jitc->tail; \ + } while (0) +#define jit_link_reverse(where) \ + do { \ + jit_node_t *tmp, *tail = 0; \ + while (where) { \ + tmp = (where)->link; \ + (where)->link = tail; \ + tail = where; \ + where = tmp; \ + } \ + where = tail; \ + } while (0); + /* * Private jit_class bitmasks */ @@ -173,11 +237,13 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*, #define jit_cc_a0_int 0x00000010 /* arg0 is immediate word */ #define jit_cc_a0_flt 0x00000020 /* arg0 is immediate float */ #define jit_cc_a0_dbl 0x00000040 /* arg0 is immediate double */ +#define jit_cc_a0_arg 0x00000080 /* arg1 is an argument int id */ #define jit_cc_a1_reg 0x00000100 /* arg1 is a register */ #define jit_cc_a1_chg 0x00000200 /* arg1 is modified */ #define jit_cc_a1_int 0x00001000 /* arg1 is immediate word */ #define jit_cc_a1_flt 0x00002000 /* arg1 is immediate float */ #define jit_cc_a1_dbl 0x00004000 /* arg1 is immediate double */ +#define jit_cc_a1_arg 0x00008000 /* arg1 is an argument node */ #define jit_cc_a2_reg 0x00010000 /* arg2 is a register */ #define jit_cc_a2_chg 0x00020000 /* arg2 is modified */ #define jit_cc_a2_int 0x00100000 /* arg2 is immediate word */ @@ -301,14 +367,12 @@ struct jit_line { struct jit_node { jit_node_t *next; jit_code_t code; - jit_int32_t flag; + jit_uint16_t flag; + jit_uint16_t offset; /* Used if DEVEL_DISASSEMBLER */ jit_data_t u; jit_data_t v; jit_data_t w; jit_node_t *link; -#if DEVEL_DISASSEMBLER - jit_uword_t offset; -#endif }; struct jit_block { @@ -347,6 +411,7 @@ struct jit_function { jit_int32_t aoff; jit_int32_t alen; jit_int32_t call; + jit_int32_t argn; /* for debug output */ } self; struct { jit_int32_t argi; @@ -397,12 +462,13 @@ struct jit_compiler { #endif jit_node_t *head; jit_node_t *tail; + jit_node_t *prepare; /* inside prepare/finish* block */ jit_uint32_t realize : 1; /* jit_realize() called? */ jit_uint32_t dataset : 1; /* jit_dataset() called? */ jit_uint32_t done : 1; /* emit state finished */ jit_uint32_t emit : 1; /* emit state entered */ jit_uint32_t again : 1; /* start over emiting function */ - jit_uint32_t prepare : 1; /* inside prepare/finish* block */ + jit_uint32_t synth : 8; /* emiting synthesized instructions */ #if DEBUG jit_uint32_t getreg : 1; #endif @@ -548,6 +614,9 @@ extern void jit_get_cpu(void); #define jit_init() _jit_init(_jit) extern void _jit_init(jit_state_t*); +#define jit_synth_inc() _jit_synth_inc(_jit) +extern void _jit_synth_inc(jit_state_t*); + #define jit_new_node_no_link(u) _jit_new_node_no_link(_jit, u) extern jit_node_t *_jit_new_node_no_link(jit_state_t*, jit_code_t); @@ -558,6 +627,9 @@ extern void _jit_link_node(jit_state_t*, jit_node_t*); extern void _jit_link_label(jit_state_t*,jit_node_t*); +#define jit_synth_dec() _jit_synth_dec(_jit) +extern void _jit_synth_dec(jit_state_t*); + #define jit_reglive(node) _jit_reglive(_jit, node) extern void _jit_reglive(jit_state_t*, jit_node_t*); diff --git a/lib/Makefile.am b/lib/Makefile.am index 009e6de27..57de4fd0d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -34,6 +34,7 @@ liblightning_la_SOURCES = \ lightning.c EXTRA_DIST = \ + jit_rewind.c \ jit_aarch64.c \ jit_aarch64-cpu.c \ jit_aarch64-fpu.c \ diff --git a/lib/jit_aarch64-sz.c b/lib/jit_aarch64-sz.c index 1918bbecd..75a5e78ac 100644 --- a/lib/jit_aarch64-sz.c +++ b/lib/jit_aarch64-sz.c @@ -1,6 +1,6 @@ #if __WORDSIZE == 64 -#define JIT_INSTR_MAX 64 +#define JIT_INSTR_MAX 120 0, /* data */ 0, /* live */ 4, /* align */ @@ -9,33 +9,45 @@ 0, /* #name */ 0, /* #note */ 0, /* label */ - 64, /* prolog */ + 120, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ - 0, /* va_start */ - 0, /* va_arg */ - 0, /* va_arg_d */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 44, /* va_start */ + 64, /* va_arg */ + 72, /* va_arg_d */ 0, /* va_end */ 4, /* addr */ - 12, /* addi */ + 20, /* addi */ 4, /* addcr */ 12, /* addci */ 4, /* addxr */ 8, /* addxi */ 4, /* subr */ - 16, /* subi */ + 20, /* subi */ 4, /* subcr */ 12, /* subci */ 4, /* subxr */ 8, /* subxi */ - 20, /* rsbi */ + 24, /* rsbi */ 4, /* mulr */ - 12, /* muli */ + 20, /* muli */ 12, /* qmulr */ 20, /* qmuli */ 12, /* qmulr_u */ 20, /* qmuli_u */ 4, /* divr */ - 12, /* divi */ + 20, /* divi */ 4, /* divr_u */ 12, /* divi_u */ 20, /* qdivr */ @@ -43,15 +55,15 @@ 20, /* qdivr_u */ 16, /* qdivi_u */ 12, /* remr */ - 20, /* remi */ + 28, /* remi */ 12, /* remr_u */ 20, /* remi_u */ 4, /* andr */ - 12, /* andi */ + 20, /* andi */ 4, /* orr */ - 12, /* ori */ + 20, /* ori */ 4, /* xorr */ - 12, /* xori */ + 20, /* xori */ 4, /* lshr */ 4, /* lshi */ 4, /* rshr */ @@ -106,19 +118,19 @@ 4, /* ldr_l */ 12, /* ldi_l */ 8, /* ldxr_c */ - 8, /* ldxi_c */ + 20, /* ldxi_c */ 4, /* ldxr_uc */ - 4, /* ldxi_uc */ + 20, /* ldxi_uc */ 4, /* ldxr_s */ - 4, /* ldxi_s */ + 16, /* ldxi_s */ 4, /* ldxr_us */ - 4, /* ldxi_us */ + 16, /* ldxi_us */ 4, /* ldxr_i */ - 4, /* ldxi_i */ + 20, /* ldxi_i */ 4, /* ldxr_ui */ - 4, /* ldxi_ui */ + 16, /* ldxi_ui */ 4, /* ldxr_l */ - 4, /* ldxi_l */ + 20, /* ldxi_l */ 4, /* str_c */ 12, /* sti_c */ 4, /* str_s */ @@ -128,13 +140,13 @@ 4, /* str_l */ 12, /* sti_l */ 4, /* stxr_c */ - 4, /* stxi_c */ + 20, /* stxi_c */ 4, /* stxr_s */ - 4, /* stxi_s */ + 20, /* stxi_s */ 4, /* stxr_i */ - 4, /* stxi_i */ + 20, /* stxi_i */ 4, /* stxr_l */ - 4, /* stxi_l */ + 20, /* stxi_l */ 8, /* bltr */ 8, /* blti */ 8, /* bltr_u */ @@ -175,12 +187,30 @@ 8, /* bxsubi */ 8, /* bxsubr_u */ 8, /* bxsubi_u */ - 0, /* jmpr */ + 4, /* jmpr */ 20, /* jmpi */ 4, /* callr */ 20, /* calli */ - 64, /* epilog */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 96, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 4, /* addr_f */ 12, /* addi_f */ 4, /* subr_f */ @@ -230,11 +260,11 @@ 8, /* ldr_f */ 16, /* ldi_f */ 8, /* ldxr_f */ - 8, /* ldxi_f */ + 24, /* ldxi_f */ 8, /* str_f */ 16, /* sti_f */ 8, /* stxr_f */ - 8, /* stxi_f */ + 24, /* stxi_f */ 8, /* bltr_f */ 16, /* blti_f */ 8, /* bler_f */ @@ -263,7 +293,15 @@ 16, /* bordi_f */ 8, /* bunordr_f */ 16, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 4, /* addr_d */ 12, /* addi_d */ 4, /* subr_d */ @@ -313,11 +351,11 @@ 8, /* ldr_d */ 16, /* ldi_d */ 8, /* ldxr_d */ - 8, /* ldxi_d */ + 24, /* ldxi_d */ 8, /* str_d */ 16, /* sti_d */ 8, /* stxr_d */ - 8, /* stxi_d */ + 24, /* stxi_d */ 8, /* bltr_d */ 16, /* blti_d */ 8, /* bler_d */ @@ -346,6 +384,11 @@ 16, /* bordi_d */ 8, /* bunordr_d */ 16, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -355,6 +398,4 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __WORDSIZE */ diff --git a/lib/jit_aarch64.c b/lib/jit_aarch64.c index 9273b455d..0f4259061 100644 --- a/lib/jit_aarch64.c +++ b/lib/jit_aarch64.c @@ -177,6 +177,10 @@ _jit_prolog(jit_state_t *_jit) jit_alloc((jit_pointer_t *)&_jitc->function->regoff, _jitc->reglen * sizeof(jit_int32_t)); + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); jit_link(_jitc->function->prolog); _jitc->function->prolog->w.w = offset; @@ -201,6 +205,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length) default: _jitc->function->self.aoff &= -8; break; } _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } return (_jitc->function->self.aoff); } @@ -209,6 +217,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) { jit_int32_t r0, r1; assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); if (!_jitc->function->allocar) { _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->allocar = 1; @@ -233,69 +242,82 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) #endif jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_unget_reg(r0); + jit_dec_synth(); } void _jit_ret(jit_state_t *_jit) { jit_node_t *instr; - assert(_jitc->function); - + jit_inc_synth(ret); /* jump to epilog */ instr = jit_jmpi(); jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); } void _jit_retr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr, u); if (JIT_RET != u) jit_movr(JIT_RET, u); else jit_live(JIT_RET); jit_ret(); + jit_dec_synth(); } void _jit_reti(jit_state_t *_jit, jit_word_t u) { + jit_inc_synth_w(reti, u); jit_movi(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_f, u); if (u != JIT_FRET) jit_movr_f(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_f(jit_state_t *_jit, jit_float32_t u) { + jit_inc_synth_f(reti_f, u); jit_movi_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_d, u); if (u != JIT_FRET) jit_movr_d(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { + jit_inc_synth_d(reti_d, u); jit_movi_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void @@ -319,11 +341,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) void _jit_ellipsis(jit_state_t *_jit) { + jit_inc_synth(ellipsis); if (_jitc->prepare) { + jit_link_prepare(); assert(!(_jitc->function->call.call & jit_call_varargs)); _jitc->function->call.call |= jit_call_varargs; } else { + jit_link_prolog(); assert(!(_jitc->function->self.call & jit_call_varargs)); _jitc->function->self.call |= jit_call_varargs; @@ -344,12 +369,14 @@ _jit_ellipsis(jit_state_t *_jit) else _jitc->function->vafp = 0; } + jit_dec_synth(); } jit_node_t * _jit_arg(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); assert(!(_jitc->function->self.call & jit_call_varargs)); if (jit_arg_reg_p(_jitc->function->self.argi)) @@ -358,13 +385,17 @@ _jit_arg(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } - return (jit_new_node_w(jit_code_arg, offset)); + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_f(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); assert(!(_jitc->function->self.call & jit_call_varargs)); if (jit_arg_f_reg_p(_jitc->function->self.argf)) @@ -373,13 +404,17 @@ _jit_arg_f(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } - return (jit_new_node_w(jit_code_arg_f, offset)); + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_d(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); assert(!(_jitc->function->self.call & jit_call_varargs)); if (jit_arg_f_reg_p(_jitc->function->self.argf)) @@ -388,87 +423,106 @@ _jit_arg_d(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } - return (jit_new_node_w(jit_code_arg_d, offset)); + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_c(u, JIT_RA0 - v->u.w); else jit_ldxi_c(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_uc(u, JIT_RA0 - v->u.w); else jit_ldxi_uc(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_s(u, JIT_RA0 - v->u.w); else jit_ldxi_s(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_us(u, JIT_RA0 - v->u.w); else jit_ldxi_us(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_i(u, JIT_RA0 - v->u.w); else jit_ldxi_i(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_ui(u, JIT_RA0 - v->u.w); else jit_ldxi_ui(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(u, JIT_RA0 - v->u.w); else jit_ldxi_l(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(JIT_RA0 - v->u.w, u); else jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -476,6 +530,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); if (jit_arg_reg_p(v->u.w)) jit_movi(JIT_RA0 - v->u.w, u); else { @@ -484,26 +539,31 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) jit_stxi(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr_f(u, JIT_FA0 - v->u.w); else jit_ldxi_f(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_f(JIT_FA0 - v->u.w, u); else jit_stxi_f(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -511,6 +571,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movi_f(JIT_FA0 - v->u.w, u); else { @@ -519,26 +580,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) jit_stxi_f(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(u, JIT_FA0 - v->u.w); else jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr_d(JIT_FA0 - v->u.w, u); else jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -546,6 +612,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); if (jit_arg_reg_p(v->u.w)) jit_movi_d(JIT_FA0 - v->u.w, u); else { @@ -554,12 +621,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_stxi_d(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr(JIT_RA0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -568,6 +638,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) jit_stxi(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void @@ -575,6 +646,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(JIT_RA0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -586,12 +659,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argf)) { jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; @@ -600,6 +676,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) jit_stxi_f(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void @@ -607,6 +684,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argf)) { jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; @@ -618,12 +697,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argf)) { jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; @@ -632,6 +714,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) jit_stxi_d(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void @@ -639,6 +722,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argf)) { jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; @@ -650,6 +735,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } jit_bool_t @@ -676,6 +762,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_node_t *node; assert(_jitc->function); + jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; node = jit_callr(r0); @@ -684,6 +771,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); } jit_node_t * @@ -691,6 +779,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) { jit_node_t *node; assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; node = jit_calli(i0); @@ -699,64 +788,83 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); return (node); } void _jit_retval_c(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_c, r0); jit_extr_c(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_uc, r0); jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_s(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_s, r0); jit_extr_s(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_us(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_us, r0); jit_extr_us(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_i(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_i, r0); jit_extr_i(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_ui, r0); jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_l(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_l, r0); if (r0 != JIT_RET) jit_movr(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_f(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_f, r0); if (r0 != JIT_FRET) jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); } void _jit_retval_d(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_d, r0); if (r0 != JIT_FRET) jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); } jit_pointer_t @@ -771,9 +879,15 @@ _emit_code(jit_state_t *_jit) jit_node_t *node; jit_uint8_t *data; jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif jit_int32_t const_offset; jit_int32_t patch_offset; } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif _jitc->function = NULL; @@ -882,12 +996,16 @@ _emit_code(jit_state_t *_jit) patch(word, node); \ } \ break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif for (node = _jitc->head; node; node = node->next) { if (_jit->pc.uc >= _jitc->code.end) return (NULL); #if DEVEL_DISASSEMBLER - node->offset = _jit->pc.w; + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; #endif value = jit_classify(node->code); jit_regarg_set(node, value); @@ -1293,6 +1411,9 @@ _emit_code(jit_state_t *_jit) _jitc->function = _jitc->functions.ptr + node->w.w; undo.node = node; undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif undo.patch_offset = _jitc->patches.offset; restart_function: _jitc->again = 0; @@ -1310,6 +1431,9 @@ _emit_code(jit_state_t *_jit) temp->flag &= ~jit_flag_patch; node = undo.node; _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif _jitc->patches.offset = undo.patch_offset; goto restart_function; } @@ -1328,16 +1452,39 @@ _emit_code(jit_state_t *_jit) case jit_code_va_arg_d: vaarg_d(rn(node->u.w), rn(node->v.w)); break; - case jit_code_live: + case jit_code_live: case jit_code_ellipsis: + case jit_code_allocai: case jit_code_allocar: case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: case jit_code_getarg_ui: + case jit_code_getarg_l: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_ui: case jit_code_retval_l: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: break; default: abort(); } jit_regarg_clr(node, value); - assert(_jitc->regarg == 0); + assert(_jitc->regarg == 0 && _jitc->synth == 0); /* update register live state */ jit_reglive(node); } diff --git a/lib/jit_alpha-sz.c b/lib/jit_alpha-sz.c index d6df970bb..c605d5b9b 100644 --- a/lib/jit_alpha-sz.c +++ b/lib/jit_alpha-sz.c @@ -10,7 +10,19 @@ 0, /* #note */ 0, /* label */ 76, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ 0, /* va_start */ 0, /* va_arg */ 0, /* va_arg_d */ @@ -179,8 +191,26 @@ 36, /* jmpi */ 8, /* callr */ 36, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ 68, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 8, /* addr_f */ 32, /* addi_f */ 8, /* subr_f */ @@ -263,7 +293,15 @@ 36, /* bordi_f */ 12, /* bunordr_f */ 36, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 8, /* addr_d */ 28, /* addi_d */ 8, /* subr_d */ @@ -346,6 +384,11 @@ 32, /* bordi_d */ 12, /* bunordr_d */ 32, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -355,6 +398,4 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __WORDSIZE */ diff --git a/lib/jit_alpha.c b/lib/jit_alpha.c index ea0abb160..42744cddb 100644 --- a/lib/jit_alpha.c +++ b/lib/jit_alpha.c @@ -177,6 +177,10 @@ _jit_prolog(jit_state_t *_jit) jit_alloc((jit_pointer_t *)&_jitc->function->regoff, _jitc->reglen * sizeof(jit_int32_t)); + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); jit_link(_jitc->function->prolog); _jitc->function->prolog->w.w = offset; @@ -201,6 +205,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length) default: _jitc->function->self.aoff &= -8; break; } _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } return (_jitc->function->self.aoff); } @@ -209,84 +217,95 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) { jit_int32_t reg; assert(_jitc->function != NULL); + jit_inc_synth_ww(allocar, u, v); if (!_jitc->function->allocar) { _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->allocar = 1; } - reg = jit_get_reg(jit_class_gpr); jit_negr(reg, v); jit_andi(reg, reg, -8); - jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); jit_addr(u, u, reg); jit_addr(JIT_SP, JIT_SP, reg); - jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_unget_reg(reg); + jit_dec_synth(); } void _jit_ret(jit_state_t *_jit) { jit_node_t *instr; - assert(_jitc->function != NULL); - + jit_inc_synth(ret); /* jump to epilog */ instr = jit_jmpi(); jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); } void _jit_retr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr, u); if (JIT_RET != u) jit_movr(JIT_RET, u); else jit_live(JIT_RET); jit_ret(); + jit_dec_synth(); } void _jit_reti(jit_state_t *_jit, jit_word_t u) { + jit_inc_synth_w(reti, u); jit_movi(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_f, u); if (u != JIT_FRET) jit_movr_f(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_f(jit_state_t *_jit, jit_float32_t u) { + jit_inc_synth_f(reti_f, u); jit_movi_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_d, u); if (u != JIT_FRET) jit_movr_d(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { + jit_inc_synth_d(reti_d, u); jit_movi_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void @@ -310,11 +329,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) void _jit_ellipsis(jit_state_t *_jit) { + jit_inc_synth(jit_code_ellipsis); if (_jitc->prepare) { + jit_link_prepare(); assert(!(_jitc->function->call.call & jit_call_varargs)); _jitc->function->call.call |= jit_call_varargs; } else { + jit_link_prolog(); assert(!(_jitc->function->self.call & jit_call_varargs)); _jitc->function->self.call |= jit_call_varargs; @@ -322,12 +344,14 @@ _jit_ellipsis(jit_state_t *_jit) _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t)); _jitc->function->vagp = _jitc->function->self.argi; } + jit_dec_synth(); } jit_node_t * _jit_arg(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function != NULL); if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -335,13 +359,17 @@ _jit_arg(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += 8; } - return (jit_new_node_w(jit_code_arg, offset)); + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_f(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function != NULL); if (jit_arg_f_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -349,13 +377,17 @@ _jit_arg_f(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += 8; } - return (jit_new_node_w(jit_code_arg_f, offset)); + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_d(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function != NULL); if (jit_arg_f_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -363,87 +395,106 @@ _jit_arg_d(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += 8; } - return (jit_new_node_w(jit_code_arg_d, offset)); + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_c(u, _A0 - v->u.w); else jit_ldxi_c(u, _FP, v->u.w + C_DISP); + jit_dec_synth(); } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_uc(u, _A0 - v->u.w); else jit_ldxi_uc(u, _FP, v->u.w + C_DISP); + jit_dec_synth(); } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_s(u, _A0 - v->u.w); else jit_ldxi_s(u, _FP, v->u.w + S_DISP); + jit_dec_synth(); } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_us(u, _A0 - v->u.w); else jit_ldxi_us(u, _FP, v->u.w + S_DISP); + jit_dec_synth(); } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_i(u, _A0 - v->u.w); else jit_ldxi_i(u, _FP, v->u.w + I_DISP); + jit_dec_synth(); } void _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_ui(u, _A0 - v->u.w); else jit_ldxi_ui(u, _FP, v->u.w + I_DISP); + jit_dec_synth(); } void _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(u, _A0 - v->u.w); else jit_ldxi_l(u, _FP, v->u.w); + jit_dec_synth(); } void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(_A0 - v->u.w, u); else jit_stxi(v->u.w, _FP, u); + jit_dec_synth(); } void @@ -451,6 +502,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); if (jit_arg_reg_p(v->u.w)) jit_movi(_A0 - v->u.w, u); else { @@ -459,26 +511,31 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) jit_stxi(v->u.w, _FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_f(u, _F16 - v->u.w); else jit_ldxi_f(u, _FP, v->u.w + F_DISP); + jit_dec_synth(); } void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_f(_F16 - v->u.w, u); else jit_stxi_f(v->u.w, _FP, u + F_DISP); + jit_dec_synth(); } void @@ -486,6 +543,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movi_f(_F16 - v->u.w, u); else { @@ -494,26 +552,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) jit_stxi_f(v->u.w, _FP, regno + F_DISP); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(u, _F16 - v->u.w); else jit_ldxi_d(u, _FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(_F16 - v->u.w, u); else jit_stxi_d(v->u.w, _FP, u); + jit_dec_synth(); } void @@ -521,6 +584,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movi_d(_F16 - v->u.w, u); else { @@ -529,12 +593,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_stxi_d(v->u.w, _FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function != NULL); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr(_A0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -543,6 +610,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) jit_stxi(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += 8; } + jit_dec_synth(); } void @@ -550,6 +618,8 @@ _jit_pushargi(jit_state_t *_jit, jit_int64_t u) { jit_int32_t regno; assert(_jitc->function != NULL); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(_A0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -561,12 +631,15 @@ _jit_pushargi(jit_state_t *_jit, jit_int64_t u) _jitc->function->call.size += 8; jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function != NULL); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argi)) { jit_movr_f(_F16 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -575,6 +648,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) jit_stxi_f(_jitc->function->call.size + F_DISP, JIT_SP, u); _jitc->function->call.size += 8; } + jit_dec_synth(); } void @@ -582,6 +656,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; assert(_jitc->function != NULL); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argi)) { jit_movi_f(_F16 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -593,12 +669,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) _jitc->function->call.size += 8; jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function != NULL); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argi)) { jit_movr_d(_F16 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -607,6 +686,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) jit_stxi_d(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += 8; } + jit_dec_synth(); } void @@ -614,6 +694,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; assert(_jitc->function != NULL); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argi)) { jit_movi_d(_F16 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -625,6 +707,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) _jitc->function->call.size += 8; jit_unget_reg(regno); } + jit_dec_synth(); } jit_bool_t @@ -653,86 +736,106 @@ void _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_node_t *call; - assert(_jitc->function != NULL); + jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; call = jit_callr(r0); call->v.w = call->w.w = _jitc->function->self.argi; _jitc->function->call.argi = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); } jit_node_t * _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) { jit_node_t *call; - assert(_jitc->function != NULL); + jit_inc_synth_w(finishi, (jit_word_t)i0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; call = jit_calli(i0); call->v.w = call->w.w = _jitc->function->self.argf; _jitc->function->call.argi = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); return (call); } void _jit_retval_c(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_c, r0); jit_extr_c(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_uc, r0); jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_s(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_s, r0); jit_extr_s(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_us(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_us, r0); jit_extr_us(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_i(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_i, r0); jit_extr_i(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_ui, r0); jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_l(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_l, r0); if (r0 != JIT_RET) jit_movr(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_f(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_f, r0); if (r0 != JIT_FRET) jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); } void _jit_retval_d(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_d, r0); if (r0 != JIT_FRET) jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); } jit_pointer_t @@ -747,9 +850,15 @@ _emit_code(jit_state_t *_jit) jit_node_t *node; jit_uint8_t *data; jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif jit_int32_t const_offset; jit_int32_t patch_offset; } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif _jitc->function = NULL; @@ -841,12 +950,16 @@ _emit_code(jit_state_t *_jit) patch(word, node); \ } \ break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif for (node = _jitc->head; node; node = node->next) { if (_jit->pc.uc >= _jitc->code.end) return (NULL); #if DEVEL_DISASSEMBLER - node->offset = _jit->pc.w; + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; #endif value = jit_classify(node->code); jit_regarg_set(node, value); @@ -1252,6 +1365,9 @@ _emit_code(jit_state_t *_jit) _jitc->function = _jitc->functions.ptr + node->w.w; undo.node = node; undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif undo.patch_offset = _jitc->patches.offset; restart_function: _jitc->again = 0; @@ -1269,6 +1385,9 @@ _emit_code(jit_state_t *_jit) temp->flag &= ~jit_flag_patch; node = undo.node; _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif _jitc->patches.offset = undo.patch_offset; goto restart_function; } @@ -1287,10 +1406,33 @@ _emit_code(jit_state_t *_jit) case jit_code_va_arg_d: vaarg_d(rn(node->u.w), rn(node->v.w)); break; - case jit_code_live: + case jit_code_live: case jit_code_ellipsis: + case jit_code_allocai: case jit_code_allocar: case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: case jit_code_getarg_ui: + case jit_code_getarg_l: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_ui: case jit_code_retval_l: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: break; default: abort(); @@ -1311,6 +1453,7 @@ _emit_code(jit_state_t *_jit) } jit_regarg_clr(node, value); assert(_jitc->regarg == (jit_carry == _NOREG) ? 0 : (1 << jit_carry)); + assert(_jitc->synth == 0); /* update register live state */ jit_reglive(node); } diff --git a/lib/jit_arm-sz.c b/lib/jit_arm-sz.c index 204235d81..aa991f3f8 100644 --- a/lib/jit_arm-sz.c +++ b/lib/jit_arm-sz.c @@ -10,11 +10,23 @@ 2, /* #name */ 0, /* #note */ 0, /* label */ - 26, /* prolog */ + 34, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ - 0, /* va_start */ - 0, /* va_arg */ - 0, /* va_arg_d */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 16, /* va_arg_d */ 0, /* va_end */ 4, /* addr */ 12, /* addi */ @@ -176,12 +188,30 @@ 8, /* bxsubi */ 8, /* bxsubr_u */ 8, /* bxsubi_u */ - 8, /* jmpr */ + 4, /* jmpr */ 8, /* jmpi */ 4, /* callr */ - 12, /* calli */ - 20, /* epilog */ + 20, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 24, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 4, /* addr_f */ 8, /* addi_f */ 4, /* subr_f */ @@ -264,7 +294,15 @@ 24, /* bordi_f */ 12, /* bunordr_f */ 24, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 4, /* addr_d */ 20, /* addi_d */ 4, /* subr_d */ @@ -347,58 +385,73 @@ 28, /* bordi_d */ 12, /* bunordr_d */ 28, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ - 0, /* movr_ww_d */ + 4, /* movr_ww_d */ 0, /* movr_w_d */ 0, /* movr_f_w */ 0, /* movi_f_w */ 4, /* movr_d_ww */ - 10, /* movi_d_ww */ + 12, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __ARM_PCS_VFP */ #endif /* __WORDSIZE */ #if __WORDSIZE == 32 #if !defined(__ARM_PCS_VFP) -#define JIT_INSTR_MAX 90 +#define JIT_INSTR_MAX 160 0, /* data */ 0, /* live */ 2, /* align */ 0, /* save */ 0, /* load */ - 0, /* #name */ + 2, /* #name */ 0, /* #note */ 0, /* label */ - 18, /* prolog */ + 30, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ - 0, /* va_start */ - 0, /* va_arg */ - 0, /* va_arg_d */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 28, /* va_arg_d */ 0, /* va_end */ 4, /* addr */ - 8, /* addi */ + 12, /* addi */ 4, /* addcr */ 8, /* addci */ 4, /* addxr */ 4, /* addxi */ 4, /* subr */ - 8, /* subi */ + 12, /* subi */ 4, /* subcr */ 8, /* subci */ 4, /* subxr */ 4, /* subxi */ - 12, /* rsbi */ - 4, /* mulr */ - 8, /* muli */ + 16, /* rsbi */ + 8, /* mulr */ + 12, /* muli */ 4, /* qmulr */ 12, /* qmuli */ 4, /* qmulr_u */ 8, /* qmuli_u */ 40, /* divr */ - 44, /* divi */ + 48, /* divi */ 40, /* divr_u */ 44, /* divi_u */ 34, /* qdivr */ @@ -406,15 +459,15 @@ 34, /* qdivr_u */ 38, /* qdivi_u */ 40, /* remr */ - 44, /* remi */ + 48, /* remi */ 40, /* remr_u */ 44, /* remi_u */ 4, /* andr */ - 4, /* andi */ + 12, /* andi */ 4, /* orr */ - 8, /* ori */ + 12, /* ori */ 4, /* xorr */ - 8, /* xori */ + 12, /* xori */ 4, /* lshr */ 4, /* lshi */ 4, /* rshr */ @@ -445,10 +498,10 @@ 14, /* nei */ 4, /* movr */ 8, /* movi */ - 4, /* extr_c */ + 8, /* extr_c */ 4, /* extr_uc */ - 4, /* extr_s */ - 4, /* extr_us */ + 8, /* extr_s */ + 8, /* extr_us */ 0, /* extr_i */ 0, /* extr_ui */ 20, /* htonr_us */ @@ -469,15 +522,15 @@ 0, /* ldr_l */ 0, /* ldi_l */ 4, /* ldxr_c */ - 4, /* ldxi_c */ + 12, /* ldxi_c */ 4, /* ldxr_uc */ - 4, /* ldxi_uc */ + 12, /* ldxi_uc */ 4, /* ldxr_s */ - 4, /* ldxi_s */ + 12, /* ldxi_s */ 4, /* ldxr_us */ - 4, /* ldxi_us */ + 12, /* ldxi_us */ 4, /* ldxr_i */ - 4, /* ldxi_i */ + 12, /* ldxi_i */ 0, /* ldxr_ui */ 0, /* ldxi_ui */ 0, /* ldxr_l */ @@ -491,11 +544,11 @@ 0, /* str_l */ 0, /* sti_l */ 4, /* stxr_c */ - 4, /* stxi_c */ + 12, /* stxi_c */ 4, /* stxr_s */ - 4, /* stxi_s */ + 12, /* stxi_s */ 4, /* stxr_i */ - 4, /* stxi_i */ + 12, /* stxi_i */ 0, /* stxr_l */ 0, /* stxi_l */ 8, /* bltr */ @@ -538,95 +591,121 @@ 8, /* bxsubi */ 8, /* bxsubr_u */ 8, /* bxsubi_u */ - 0, /* jmpr */ - 4, /* jmpi */ + 12, /* jmpr */ + 72, /* jmpi */ 4, /* callr */ - 12, /* calli */ - 12, /* epilog */ + 20, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 160, /* epilog */ 0, /* arg_f */ - 38, /* addr_f */ - 38, /* addi_f */ - 38, /* subr_f */ - 38, /* subi_f */ - 38, /* rsbi_f */ - 38, /* mulr_f */ - 38, /* muli_f */ - 38, /* divr_f */ - 38, /* divi_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 40, /* addr_f */ + 40, /* addi_f */ + 40, /* subr_f */ + 40, /* subi_f */ + 40, /* rsbi_f */ + 40, /* mulr_f */ + 40, /* muli_f */ + 40, /* divr_f */ + 40, /* divi_f */ 12, /* negr_f */ 12, /* absr_f */ - 34, /* sqrtr_f */ - 36, /* ltr_f */ - 40, /* lti_f */ - 36, /* ler_f */ - 40, /* lei_f */ - 36, /* eqr_f */ - 40, /* eqi_f */ - 36, /* ger_f */ - 40, /* gei_f */ - 36, /* gtr_f */ - 40, /* gti_f */ - 40, /* ner_f */ - 44, /* nei_f */ - 66, /* unltr_f */ - 74, /* unlti_f */ - 66, /* unler_f */ - 74, /* unlei_f */ - 66, /* uneqr_f */ - 74, /* uneqi_f */ - 66, /* unger_f */ - 74, /* ungei_f */ - 66, /* ungtr_f */ - 74, /* ungti_f */ - 70, /* ltgtr_f */ - 78, /* ltgti_f */ - 40, /* ordr_f */ - 44, /* ordi_f */ - 66, /* unordr_f */ - 74, /* unordi_f */ - 32, /* truncr_f_i */ + 36, /* sqrtr_f */ + 40, /* ltr_f */ + 44, /* lti_f */ + 40, /* ler_f */ + 44, /* lei_f */ + 40, /* eqr_f */ + 44, /* eqi_f */ + 40, /* ger_f */ + 44, /* gei_f */ + 40, /* gtr_f */ + 44, /* gti_f */ + 44, /* ner_f */ + 48, /* nei_f */ + 72, /* unltr_f */ + 80, /* unlti_f */ + 72, /* unler_f */ + 80, /* unlei_f */ + 72, /* uneqr_f */ + 80, /* uneqi_f */ + 72, /* unger_f */ + 80, /* ungei_f */ + 72, /* ungtr_f */ + 80, /* ungti_f */ + 76, /* ltgtr_f */ + 84, /* ltgti_f */ + 44, /* ordr_f */ + 48, /* ordi_f */ + 72, /* unordr_f */ + 80, /* unordi_f */ + 36, /* truncr_f_i */ 0, /* truncr_f_l */ - 32, /* extr_f */ + 36, /* extr_f */ 38, /* extr_d_f */ 8, /* movr_f */ 12, /* movi_f */ 8, /* ldr_f */ 16, /* ldi_f */ 8, /* ldxr_f */ - 8, /* ldxi_f */ + 16, /* ldxi_f */ 8, /* str_f */ 16, /* sti_f */ 8, /* stxr_f */ - 8, /* stxi_f */ - 40, /* bltr_f */ - 40, /* blti_f */ - 40, /* bler_f */ - 44, /* blei_f */ - 40, /* beqr_f */ - 44, /* beqi_f */ - 40, /* bger_f */ - 44, /* bgei_f */ - 40, /* bgtr_f */ - 44, /* bgti_f */ - 40, /* bner_f */ - 44, /* bnei_f */ - 40, /* bunltr_f */ - 44, /* bunlti_f */ - 40, /* bunler_f */ - 44, /* bunlei_f */ - 68, /* buneqr_f */ - 76, /* buneqi_f */ - 40, /* bunger_f */ - 44, /* bungei_f */ - 40, /* bungtr_f */ - 44, /* bungti_f */ - 68, /* bltgtr_f */ - 76, /* bltgti_f */ - 40, /* bordr_f */ - 44, /* bordi_f */ - 40, /* bunordr_f */ - 44, /* bunordi_f */ + 16, /* stxi_f */ + 44, /* bltr_f */ + 48, /* blti_f */ + 44, /* bler_f */ + 48, /* blei_f */ + 44, /* beqr_f */ + 52, /* beqi_f */ + 44, /* bger_f */ + 48, /* bgei_f */ + 44, /* bgtr_f */ + 48, /* bgti_f */ + 44, /* bner_f */ + 48, /* bnei_f */ + 44, /* bunltr_f */ + 48, /* bunlti_f */ + 44, /* bunler_f */ + 48, /* bunlei_f */ + 76, /* buneqr_f */ + 84, /* buneqi_f */ + 44, /* bunger_f */ + 48, /* bungei_f */ + 44, /* bungtr_f */ + 48, /* bungti_f */ + 76, /* bltgtr_f */ + 84, /* bltgti_f */ + 44, /* bordr_f */ + 48, /* bordi_f */ + 44, /* bunordr_f */ + 48, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 50, /* addr_d */ 52, /* addi_d */ 50, /* subr_d */ @@ -640,33 +719,33 @@ 20, /* absr_d */ 42, /* sqrtr_d */ 44, /* ltr_d */ - 46, /* lti_d */ + 48, /* lti_d */ 44, /* ler_d */ - 46, /* lei_d */ + 48, /* lei_d */ 44, /* eqr_d */ - 46, /* eqi_d */ + 48, /* eqi_d */ 44, /* ger_d */ - 46, /* gei_d */ + 48, /* gei_d */ 44, /* gtr_d */ - 46, /* gti_d */ + 48, /* gti_d */ 48, /* ner_d */ - 50, /* nei_d */ + 52, /* nei_d */ 82, /* unltr_d */ - 86, /* unlti_d */ + 88, /* unlti_d */ 82, /* unler_d */ - 86, /* unlei_d */ + 88, /* unlei_d */ 82, /* uneqr_d */ - 86, /* uneqi_d */ + 88, /* uneqi_d */ 82, /* unger_d */ - 86, /* ungei_d */ + 88, /* ungei_d */ 82, /* ungtr_d */ - 86, /* ungti_d */ + 88, /* ungti_d */ 86, /* ltgtr_d */ - 90, /* ltgti_d */ + 92, /* ltgti_d */ 48, /* ordr_d */ - 50, /* ordi_d */ + 52, /* ordi_d */ 82, /* unordr_d */ - 86, /* unordi_d */ + 88, /* unordi_d */ 36, /* truncr_d_i */ 0, /* truncr_d_l */ 36, /* extr_d */ @@ -676,49 +755,52 @@ 16, /* ldr_d */ 24, /* ldi_d */ 20, /* ldxr_d */ - 16, /* ldxi_d */ + 28, /* ldxi_d */ 16, /* str_d */ 24, /* sti_d */ 20, /* stxr_d */ - 16, /* stxi_d */ + 28, /* stxi_d */ 48, /* bltr_d */ - 50, /* blti_d */ + 52, /* blti_d */ 48, /* bler_d */ - 50, /* blei_d */ + 52, /* blei_d */ 48, /* beqr_d */ - 50, /* beqi_d */ + 60, /* beqi_d */ 48, /* bger_d */ - 50, /* bgei_d */ + 52, /* bgei_d */ 48, /* bgtr_d */ - 50, /* bgti_d */ + 52, /* bgti_d */ 48, /* bner_d */ - 50, /* bnei_d */ + 52, /* bnei_d */ 48, /* bunltr_d */ - 50, /* bunlti_d */ + 52, /* bunlti_d */ 48, /* bunler_d */ - 50, /* bunlei_d */ + 52, /* bunlei_d */ 84, /* buneqr_d */ - 88, /* buneqi_d */ + 92, /* buneqi_d */ 48, /* bunger_d */ - 50, /* bungei_d */ + 52, /* bungei_d */ 48, /* bungtr_d */ - 50, /* bungti_d */ + 52, /* bungti_d */ 84, /* bltgtr_d */ - 88, /* bltgti_d */ + 92, /* bltgti_d */ 48, /* bordr_d */ - 50, /* bordi_d */ + 52, /* bordi_d */ 48, /* bunordr_d */ - 50, /* bunordi_d */ + 52, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 4, /* movr_w_f */ 8, /* movr_ww_d */ 0, /* movr_w_d */ - 6, /* movr_f_w */ + 8, /* movr_f_w */ 8, /* movi_f_w */ - 12, /* movr_d_ww */ + 16, /* movr_d_ww */ 12, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __ARM_PCS_VFP */ #endif /* __WORDSIZE */ diff --git a/lib/jit_arm.c b/lib/jit_arm.c index 4da9c2504..e33d5fe8a 100644 --- a/lib/jit_arm.c +++ b/lib/jit_arm.c @@ -59,6 +59,12 @@ typedef jit_pointer_t jit_va_list; /* * Prototypes */ +#define jit_make_arg(node) _jit_make_arg(_jit,node) +static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*); +#define jit_make_arg_f(node) _jit_make_arg_f(_jit,node) +static jit_node_t *_jit_make_arg_f(jit_state_t*,jit_node_t*); +#define jit_make_arg_d(node) _jit_make_arg_d(_jit,node) +static jit_node_t *_jit_make_arg_d(jit_state_t*,jit_node_t*); #define jit_get_reg_pair() _jit_get_reg_pair(_jit) static jit_int32_t _jit_get_reg_pair(jit_state_t*); #define jit_unget_reg_pair(rn) _jit_unget_reg_pair(_jit,rn) @@ -80,6 +86,7 @@ extern void __clear_cache(void *, void *); #endif #define PROTO 1 +# include "jit_rewind.c" # include "jit_arm-cpu.c" # include "jit_arm-swf.c" # include "jit_arm-vfp.c" @@ -250,6 +257,10 @@ _jit_prolog(jit_state_t *_jit) jit_alloc((jit_pointer_t *)&_jitc->function->regoff, _jitc->reglen * sizeof(jit_int32_t)); + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); jit_link(_jitc->function->prolog); _jitc->function->prolog->w.w = offset; @@ -274,6 +285,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length) default: _jitc->function->self.aoff &= -8; break; } _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } return (_jitc->function->self.aoff); } @@ -282,55 +297,59 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) { jit_int32_t reg; assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); if (!_jitc->function->allocar) { _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->allocar = 1; } - reg = jit_get_reg(jit_class_gpr); jit_negr(reg, v); jit_andi(reg, reg, -8); - jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); jit_addr(u, u, reg); jit_addr(JIT_SP, JIT_SP, reg); - jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_unget_reg(reg); + jit_dec_synth(); } void _jit_ret(jit_state_t *_jit) { jit_node_t *instr; - assert(_jitc->function); - + jit_inc_synth(ret); /* jump to epilog */ instr = jit_jmpi(); jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); } void _jit_retr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr, u); if (JIT_RET != u) jit_movr(JIT_RET, u); else jit_live(JIT_RET); jit_ret(); + jit_dec_synth(); } void _jit_reti(jit_state_t *_jit, jit_word_t u) { + jit_inc_synth_w(reti, u); jit_movi(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_f, u); if (jit_cpu.abi) { if (u != JIT_FRET) jit_movr_f(JIT_FRET, u); @@ -344,21 +363,25 @@ _jit_retr_f(jit_state_t *_jit, jit_int32_t u) jit_live(JIT_RET); } jit_ret(); + jit_dec_synth(); } void _jit_reti_f(jit_state_t *_jit, jit_float32_t u) { + jit_inc_synth_f(reti_f, u); if (jit_cpu.abi) jit_movi_f(JIT_FRET, u); else jit_movi_f_w(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_d, u); if (jit_cpu.abi) { if (u != JIT_FRET) jit_movr_d(JIT_FRET, u); @@ -372,16 +395,19 @@ _jit_retr_d(jit_state_t *_jit, jit_int32_t u) jit_live(JIT_RET); } jit_ret(); + jit_dec_synth(); } void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { + jit_inc_synth_d(reti_d, u); if (jit_cpu.abi) jit_movi_d(JIT_FRET, u); else jit_movi_d_ww(JIT_RET, _R1, u); jit_ret(); + jit_dec_synth(); } void @@ -410,44 +436,30 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) return (jit_arg_reg_p(u->u.w)); } -void -_jit_ellipsis(jit_state_t *_jit) +static jit_node_t * +_jit_make_arg(jit_state_t *_jit, jit_node_t *node) { - if (_jitc->prepare) { - assert(!(_jitc->function->call.call & jit_call_varargs)); - _jitc->function->call.call |= jit_call_varargs; - } - else { - assert(!(_jitc->function->self.call & jit_call_varargs)); - _jitc->function->self.call |= jit_call_varargs; - - /* First 4 stack addresses are always spilled r0-r3 */ - if (jit_arg_reg_p(_jitc->function->self.argi)) - _jitc->function->vagp = _jitc->function->self.argi * 4; - else - _jitc->function->vagp = 16; - } -} - -jit_node_t * -_jit_arg(jit_state_t *_jit) -{ - jit_int32_t offset; - assert(_jitc->function); + jit_int32_t offset; if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; else { offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } - return (jit_new_node_w(jit_code_arg, offset)); + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); } jit_node_t * -_jit_arg_f(jit_state_t *_jit) +_jit_make_arg_f(jit_state_t *_jit, jit_node_t *node) { - jit_int32_t offset; - assert(_jitc->function); + jit_int32_t offset; if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) { if (jit_arg_f_reg_p(_jitc->function->self.argf)) { offset = _jitc->function->self.argf++; @@ -463,14 +475,20 @@ _jit_arg_f(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_float32_t); done: - return (jit_new_node_w(jit_code_arg_f, offset)); + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg_f); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); } jit_node_t * -_jit_arg_d(jit_state_t *_jit) +_jit_make_arg_d(jit_state_t *_jit, jit_node_t *node) { - jit_int32_t offset; - assert(_jitc->function); + jit_int32_t offset; if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) { if (jit_arg_d_reg_p(_jitc->function->self.argf)) { if (_jitc->function->self.argf & 1) @@ -494,79 +512,147 @@ _jit_arg_d(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_float64_t); done: - return (jit_new_node_w(jit_code_arg_d, offset)); + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg_d); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + if (_jitc->prepare) { + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + if (jit_cpu.abi && _jitc->function->call.argf) + rewind_prepare(); + } + else { + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + if (jit_cpu.abi && _jitc->function->self.argf) + rewind_prolog(); + /* First 4 stack addresses are always spilled r0-r3 */ + if (jit_arg_reg_p(_jitc->function->self.argi)) + _jitc->function->vagp = _jitc->function->self.argi * 4; + else + _jitc->function->vagp = 16; + } + jit_inc_synth(ellipsis); + if (_jitc->prepare) + jit_link_prepare(); + else + jit_link_prolog(); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg((jit_node_t*)0)); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg_f((jit_node_t*)0)); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg_d((jit_node_t*)0)); } void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); if (jit_swf_p()) jit_ldxi_c(u, JIT_FP, arg_offset(v->u.w)); else if (jit_arg_reg_p(v->u.w)) jit_extr_c(u, JIT_RA0 - v->u.w); else jit_ldxi_c(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); if (jit_swf_p()) jit_ldxi_uc(u, JIT_FP, arg_offset(v->u.w)); else if (jit_arg_reg_p(v->u.w)) jit_extr_uc(u, JIT_RA0 - v->u.w); else jit_ldxi_uc(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); if (jit_swf_p()) jit_ldxi_s(u, JIT_FP, arg_offset(v->u.w)); else if (jit_arg_reg_p(v->u.w)) jit_extr_s(u, JIT_RA0 - v->u.w); else jit_ldxi_s(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); if (jit_swf_p()) jit_ldxi_us(u, JIT_FP, arg_offset(v->u.w)); else if (jit_arg_reg_p(v->u.w)) jit_extr_us(u, JIT_RA0 - v->u.w); else jit_ldxi_us(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); if (jit_swf_p()) jit_ldxi_i(u, JIT_FP, arg_offset(v->u.w)); else if (jit_arg_reg_p(v->u.w)) jit_movr(u, JIT_RA0 - v->u.w); else jit_ldxi_i(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); if (jit_swf_p()) jit_stxi(arg_offset(v->u.w), JIT_FP, u); else if (jit_arg_reg_p(v->u.w)) jit_movr(JIT_RA0 - v->u.w, u); else jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -574,6 +660,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); if (jit_swf_p()) { regno = jit_get_reg(jit_class_gpr); jit_movi(regno, u); @@ -588,13 +675,15 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) jit_stxi(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); - if (jit_cpu.abi) { + jit_inc_synth_wp(getarg_f, u, v); + if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) { if (jit_arg_f_reg_p(v->u.w)) jit_movr_f(u, JIT_FA0 - v->u.w); else @@ -608,12 +697,14 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) else jit_ldxi_f(u, JIT_FP, v->u.w); } + jit_dec_synth(); } void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); if (jit_cpu.abi) { if (jit_arg_f_reg_p(v->u.w)) jit_movr_f(JIT_FA0 - v->u.w, u); @@ -628,6 +719,7 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) else jit_stxi_f(v->u.w, JIT_FP, u); } + jit_dec_synth(); } void @@ -635,6 +727,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); if (jit_cpu.abi) { if (jit_arg_f_reg_p(v->u.w)) jit_movi_f(JIT_FA0 - v->u.w, u); @@ -660,13 +753,15 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) jit_stxi_f(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); - if (jit_cpu.abi) { + jit_inc_synth_wp(getarg_d, u, v); + if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) { if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(u, JIT_FA0 - v->u.w); else @@ -680,12 +775,14 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) else jit_ldxi_d(u, JIT_FP, v->u.w); } + jit_dec_synth(); } void _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); if (jit_cpu.abi) { if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(JIT_FA0 - v->u.w, u); @@ -700,6 +797,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) else jit_stxi_d(v->u.w, JIT_FP, u); } + jit_dec_synth(); } void @@ -707,6 +805,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); if (jit_cpu.abi) { if (jit_arg_f_reg_p(v->u.w)) jit_movi_d(JIT_FA0 - v->u.w, u); @@ -732,12 +831,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_stxi_d(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr(JIT_RA0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -746,6 +848,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) jit_stxi(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void @@ -753,6 +856,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(JIT_RA0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -764,28 +869,33 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) { jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; - return; + goto done; } } else { if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr_f_w(JIT_RA0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; - return; + goto done; } } jit_stxi_f(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); +done: + jit_dec_synth(); } void @@ -793,6 +903,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) { if (jit_arg_f_reg_p(_jitc->function->call.argf)) { /* cannot jit_movi_f in the argument register because @@ -804,14 +916,14 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) jit_movr_f(JIT_FA0 - _jitc->function->call.argf, regno); jit_unget_reg(regno); ++_jitc->function->call.argf; - return; + goto done; } } else { if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi_f_w(JIT_RA0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; - return; + goto done; } } regno = jit_get_reg(jit_class_fpr); @@ -819,19 +931,23 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_word_t); +done: + jit_dec_synth(); } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) { if (jit_arg_d_reg_p(_jitc->function->call.argf)) { if (_jitc->function->call.argf & 1) ++_jitc->function->call.argf; jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); _jitc->function->call.argf += 2; - return; + goto done; } } else { @@ -842,13 +958,15 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) JIT_RA0 - (_jitc->function->call.argi + 1), u); _jitc->function->call.argi += 2; - return; + goto done; } } if (_jitc->function->call.size & 7) _jitc->function->call.size += 4; jit_stxi_d(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += sizeof(jit_float64_t); +done: + jit_dec_synth(); } void @@ -856,13 +974,15 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) { if (jit_arg_d_reg_p(_jitc->function->call.argf)) { if (_jitc->function->call.argf & 1) ++_jitc->function->call.argf; jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); _jitc->function->call.argf += 2; - return; + goto done; } } else { @@ -873,7 +993,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) JIT_RA0 - (_jitc->function->call.argi + 1), u); _jitc->function->call.argi += 2; - return; + goto done; } } if (_jitc->function->call.size & 7) @@ -883,6 +1003,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_float64_t); +done: + jit_dec_synth(); } jit_bool_t @@ -909,6 +1031,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_node_t *node; assert(_jitc->function); + jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; node = jit_callr(r0); @@ -917,6 +1040,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); } jit_node_t * @@ -924,6 +1048,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) { jit_node_t *node; assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; node = jit_calli(i0); @@ -932,60 +1057,75 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); return (node); } void _jit_retval_c(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_c, r0); jit_extr_c(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_uc, r0); jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_s(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_s, r0); jit_extr_s(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_us(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_us, r0); jit_extr_us(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_i(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_i, r0); if (r0 != JIT_RET) jit_movr(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_f(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_f, r0); if (jit_cpu.abi) { if (r0 != JIT_FRET) jit_movr_f(r0, JIT_FRET); } else if (r0 != JIT_RET) jit_movr_w_f(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_d(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_d, r0); if (jit_cpu.abi) { if (r0 != JIT_FRET) jit_movr_d(r0, JIT_FRET); } else if (r0 != JIT_RET) jit_movr_ww_d(r0, JIT_RET, _R1); + jit_dec_synth(); } jit_pointer_t @@ -1000,6 +1140,9 @@ _emit_code(jit_state_t *_jit) jit_node_t *node; jit_uint8_t *data; jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif jit_uword_t thumb; #if DISASSEMBLER jit_int32_t info_offset; @@ -1007,12 +1150,18 @@ _emit_code(jit_state_t *_jit) jit_int32_t const_offset; jit_int32_t patch_offset; } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif _jitc->function = NULL; _jitc->thumb = 0; jit_reglive_setup(); + _jitc->consts.data = NULL; + _jitc->consts.offset = _jitc->consts.length = 0; + undo.word = 0; undo.node = NULL; undo.data = NULL; @@ -1228,12 +1377,16 @@ _emit_code(jit_state_t *_jit) patch(word, node); \ } \ break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif for (node = _jitc->head; node; node = node->next) { if (_jit->pc.uc >= _jitc->code.end) return (NULL); #if DEVEL_DISASSEMBLER - node->offset = _jit->pc.w; + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; #endif value = jit_classify(node->code); jit_regarg_set(node, value); @@ -1634,6 +1787,9 @@ _emit_code(jit_state_t *_jit) _jitc->function = _jitc->functions.ptr + node->w.w; undo.node = node; undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif undo.data = _jitc->consts.data; undo.thumb = _jitc->thumb; undo.const_offset = _jitc->consts.offset; @@ -1658,6 +1814,9 @@ _emit_code(jit_state_t *_jit) temp->flag &= ~jit_flag_patch; node = undo.node; _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif invalidate_consts(); _jitc->consts.data = undo.data; _jitc->thumb = undo.thumb; @@ -1726,16 +1885,37 @@ _emit_code(jit_state_t *_jit) else vfp_vaarg_d(rn(node->u.w), rn(node->v.w)); break; - case jit_code_live: + case jit_code_live: case jit_code_ellipsis: + case jit_code_allocai: case jit_code_allocar: case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: break; default: abort(); } jit_regarg_clr(node, value); - assert(_jitc->regarg == 0); + assert(_jitc->regarg == 0 && _jitc->synth == 0); /* update register live state */ jit_reglive(node); @@ -1807,6 +1987,7 @@ _emit_code(jit_state_t *_jit) } #define CODE 1 +# include "jit_rewind.c" # include "jit_arm-cpu.c" # include "jit_arm-swf.c" # include "jit_arm-vfp.c" diff --git a/lib/jit_disasm.c b/lib/jit_disasm.c index 52d08c7e1..e3773a74a 100644 --- a/lib/jit_disasm.c +++ b/lib/jit_disasm.c @@ -329,6 +329,7 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) char buffer[address_buffer_length]; #if DEVEL_DISASSEMBLER jit_node_t *node; + jit_uword_t prevw; #endif #if __arm__ @@ -343,14 +344,18 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) disasm_jit = _jit; #if DEVEL_DISASSEMBLER node = _jitc->head; + prevw = pc; #endif while (pc < end) { #if DEVEL_DISASSEMBLER - while (node && node->offset < (jit_uword_t)pc) + while (node && (jit_uword_t)(prevw + node->offset) < (jit_uword_t)pc) { + prevw += node->offset; node = node->next; - while (node && node->offset == (jit_uword_t)pc) { + } + while (node && (jit_uword_t)(prevw + node->offset) == (jit_uword_t)pc) { jit_print_node(node); fputc('\n', stdout); + prevw += node->offset; node = node->next; } #endif diff --git a/lib/jit_hppa-sz.c b/lib/jit_hppa-sz.c index cadd31252..0903a69d0 100644 --- a/lib/jit_hppa-sz.c +++ b/lib/jit_hppa-sz.c @@ -10,7 +10,19 @@ 0, /* #note */ 0, /* label */ 64, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ 0, /* va_start */ 0, /* va_arg */ 0, /* va_arg_d */ @@ -179,8 +191,26 @@ 12, /* jmpi */ 40, /* callr */ 44, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ 64, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 4, /* addr_f */ 16, /* addi_f */ 4, /* subr_f */ @@ -263,7 +293,15 @@ 28, /* bordi_f */ 16, /* bunordr_f */ 28, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 4, /* addr_d */ 24, /* addi_d */ 4, /* subr_d */ @@ -346,6 +384,11 @@ 36, /* bordi_d */ 16, /* bunordr_d */ 36, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -355,6 +398,4 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __WORDSIZE */ diff --git a/lib/jit_hppa.c b/lib/jit_hppa.c index 94e959597..e35d46ea1 100644 --- a/lib/jit_hppa.c +++ b/lib/jit_hppa.c @@ -163,6 +163,10 @@ _jit_prolog(jit_state_t *_jit) jit_alloc((jit_pointer_t *)&_jitc->function->regoff, _jitc->reglen * sizeof(jit_int32_t)); + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); jit_link(_jitc->function->prolog); _jitc->function->prolog->w.w = offset; @@ -194,6 +198,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length) _jitc->function->self.aoff = (_jitc->function->self.aoff + 7) & -8; break; } + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } offset = _jitc->function->self.aoff; _jitc->function->self.aoff += length; return (offset); @@ -204,6 +212,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) { jit_int32_t reg; assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); if (!_jitc->function->allocar) { _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->allocar = 1; @@ -215,60 +224,73 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) jit_addr(JIT_SP, JIT_SP, reg); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_unget_reg(reg); + jit_dec_synth(); } void _jit_ret(jit_state_t *_jit) { jit_node_t *instr; - assert(_jitc->function); - + jit_inc_synth(ret); /* jump to epilog */ instr = jit_jmpi(); jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); } void _jit_retr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr, u); jit_movr(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_reti(jit_state_t *_jit, jit_word_t u) { + jit_inc_synth_w(reti, u); jit_movi(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_f, u); jit_movr_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_reti_f(jit_state_t *_jit, jit_float32_t u) { + jit_inc_synth_f(reti_f, u); jit_movi_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_d, u); jit_movr_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { + jit_inc_synth_d(reti_d, u); jit_movi_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void @@ -291,48 +313,61 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) void _jit_ellipsis(jit_state_t *_jit) { + jit_inc_synth(ellipsis); if (_jitc->prepare) { + jit_link_prepare(); assert(!(_jitc->function->call.call & jit_call_varargs)); _jitc->function->call.call |= jit_call_varargs; } else { + jit_link_prolog(); assert(!(_jitc->function->self.call & jit_call_varargs)); _jitc->function->self.call |= jit_call_varargs; _jitc->function->vagp = _jitc->function->self.argi; } + jit_dec_synth(); } jit_node_t * _jit_arg(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); _jitc->function->self.size -= sizeof(jit_word_t); if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; else offset = _jitc->function->self.size; - return (jit_new_node_w(jit_code_arg, offset)); + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_f(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); _jitc->function->self.size -= sizeof(jit_word_t); if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; else offset = _jitc->function->self.size; - return (jit_new_node_w(jit_code_arg_f, offset)); + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_d(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (_jitc->function->self.argi & 1) { ++_jitc->function->self.argi; @@ -349,67 +384,82 @@ _jit_arg_d(jit_state_t *_jit) _jitc->function->self.size -= sizeof(jit_word_t); offset = _jitc->function->self.size; } - return (jit_new_node_w(jit_code_arg_d, offset)); + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); if (v->u.w >= 0) jit_extr_c(u, _R26 - v->u.w); else jit_ldxi_c(u, JIT_FP, v->u.w + 3); + jit_dec_synth(); } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); if (v->u.w >= 0) jit_extr_uc(u, _R26 - v->u.w); else jit_ldxi_uc(u, JIT_FP, v->u.w + 3); + jit_dec_synth(); } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); if (v->u.w >= 0) jit_extr_s(u, _R26 - v->u.w); else jit_ldxi_s(u, JIT_FP, v->u.w + 2); + jit_dec_synth(); } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); if (v->u.w >= 0) jit_extr_us(u, _R26 - v->u.w); else jit_ldxi_us(u, JIT_FP, v->u.w + 2); + jit_dec_synth(); } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); if (v->u.w >= 0) jit_movr(u, _R26 - v->u.w); else jit_ldxi_i(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); if (v->u.w >= 0) jit_movr(_R26 - v->u.w, u); else jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -417,6 +467,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); if (v->u.w >= 0) jit_movi(_R26 - v->u.w, u); else { @@ -425,26 +476,31 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) jit_stxi(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); if (v->u.w >= 0) jit_movr_f(u, _F4 - v->u.w); else jit_ldxi_f(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); if (v->u.w >= 0) jit_movr_f(_F4 - v->u.w, u); else jit_stxi_f(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -452,6 +508,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); if (v->u.w >= 0) jit_movi_f(_R26 - v->u.w, u); else { @@ -460,26 +517,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) jit_stxi_f(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); if (v->u.w >= 0) jit_movr_d(u, _F4 - v->u.w); else jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); if (v->u.w >= 0) jit_movr_d(_F4 - v->u.w, u); else jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -487,6 +549,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); if (v->u.w >= 0) jit_movi_d(_R26 - v->u.w, u); else { @@ -495,12 +558,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_stxi_d(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); _jitc->function->call.size -= sizeof(jit_word_t); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr(_R26 - _jitc->function->call.argi, u); @@ -508,6 +574,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) } else jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u); + jit_dec_synth(); } void @@ -515,6 +582,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); _jitc->function->call.size -= sizeof(jit_word_t); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(_R26 - _jitc->function->call.argi, u); @@ -526,12 +595,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); _jitc->function->call.size -= sizeof(jit_word_t); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr_f(_F4 - _jitc->function->call.argi, u); @@ -548,6 +620,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) } else jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, u); + jit_dec_synth(); } void @@ -555,6 +628,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); _jitc->function->call.size -= sizeof(jit_word_t); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi_f(_F4 - _jitc->function->call.argi, u); @@ -576,12 +651,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); _jitc->function->call.size -= sizeof(jit_float64_t); if (_jitc->function->call.argi & 1) { ++_jitc->function->call.argi; @@ -608,6 +686,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jitc->function->call.size -= sizeof(jit_word_t); jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u); } + jit_dec_synth(); } void @@ -615,6 +694,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); _jitc->function->call.size -= sizeof(jit_float64_t); if (_jitc->function->call.argi & 1) { ++_jitc->function->call.argi; @@ -644,6 +725,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } jit_bool_t @@ -671,12 +753,14 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_node_t *call; assert(_jitc->function); + jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen > _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; call = jit_callr(r0); call->v.w = call->w.w = _jitc->function->call.argi; _jitc->function->call.argi = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); } jit_node_t * @@ -684,55 +768,71 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) { jit_node_t *node; assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); if (_jitc->function->self.alen > _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; node = jit_calli(i0); node->v.w = node->w.w = _jitc->function->call.argi; _jitc->function->call.argi = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); return (node); } void _jit_retval_c(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_c, r0); jit_extr_c(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_uc, r0); jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_s(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_s, r0); jit_extr_s(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_us(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_us, r0); jit_extr_us(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_i(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_i, r0); jit_movr(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_f(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_f, r0); jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); } void _jit_retval_d(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_d, r0); jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); } jit_pointer_t @@ -746,8 +846,14 @@ _emit_code(jit_state_t *_jit) struct { jit_node_t *node; jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif jit_int32_t patch_offset; } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif _jitc->function = NULL; @@ -840,12 +946,16 @@ _emit_code(jit_state_t *_jit) patch(word, node); \ } \ break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif for (node = _jitc->head; node; node = node->next) { if (_jit->pc.uc >= _jitc->code.end) return (NULL); #if DEVEL_DISASSEMBLER - node->offset = _jit->pc.w; + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; #endif value = jit_classify(node->code); jit_regarg_set(node, value); @@ -1234,6 +1344,9 @@ _emit_code(jit_state_t *_jit) _jitc->function = _jitc->functions.ptr + node->w.w; undo.node = node; undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif undo.patch_offset = _jitc->patches.offset; restart_function: _jitc->again = 0; @@ -1251,6 +1364,9 @@ _emit_code(jit_state_t *_jit) temp->flag &= ~jit_flag_patch; node = undo.node; _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif _jitc->patches.offset = undo.patch_offset; goto restart_function; } @@ -1270,15 +1386,36 @@ _emit_code(jit_state_t *_jit) vaarg_d(rn(node->u.w), rn(node->v.w)); break; case jit_code_live: - case jit_code_arg: + case jit_code_arg: case jit_code_ellipsis: + case jit_code_allocai: case jit_code_allocar: case jit_code_arg_f: case jit_code_arg_d: case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: break; default: abort(); } jit_regarg_clr(node, value); - assert(_jitc->regarg == 0); + assert(_jitc->regarg == 0 && _jitc->synth == 0); /* update register live state */ jit_reglive(node); } diff --git a/lib/jit_ia64-sz.c b/lib/jit_ia64-sz.c index 9e953ac84..d954c3031 100644 --- a/lib/jit_ia64-sz.c +++ b/lib/jit_ia64-sz.c @@ -10,7 +10,19 @@ 16, /* #note */ 48, /* label */ 128, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ 0, /* va_start */ 0, /* va_arg */ 0, /* va_arg_d */ @@ -179,8 +191,26 @@ 48, /* jmpi */ 32, /* callr */ 64, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ 144, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 0, /* addr_f */ 32, /* addi_f */ 16, /* subr_f */ @@ -263,7 +293,15 @@ 64, /* bordi_f */ 32, /* bunordr_f */ 64, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 0, /* addr_d */ 32, /* addi_d */ 16, /* subr_d */ @@ -346,6 +384,11 @@ 64, /* bordi_d */ 32, /* bunordr_d */ 64, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -355,6 +398,4 @@ 0, /* movi_d_ww */ 16, /* movr_d_w */ 32, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __WORDSIZE */ diff --git a/lib/jit_ia64.c b/lib/jit_ia64.c index b0b895407..f5345c081 100644 --- a/lib/jit_ia64.c +++ b/lib/jit_ia64.c @@ -277,6 +277,10 @@ _jit_prolog(jit_state_t *_jit) jit_alloc((jit_pointer_t *)&_jitc->function->regoff, _jitc->reglen * sizeof(jit_int32_t)); + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); jit_link(_jitc->function->prolog); _jitc->function->prolog->w.w = offset; @@ -301,6 +305,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length) default: _jitc->function->self.aoff &= -8; break; } _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } return (_jitc->function->self.aoff); } @@ -309,75 +317,86 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) { jit_int32_t reg; assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); if (!_jitc->function->allocar) { _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->allocar = 1; } - reg = jit_get_reg(jit_class_gpr); jit_negr(reg, v); jit_andi(reg, reg, -16); - jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); jit_addr(u, u, reg); jit_addr(JIT_SP, JIT_SP, reg); - jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_unget_reg(reg); + jit_dec_synth(); } void _jit_ret(jit_state_t *_jit) { jit_node_t *instr; - assert(_jitc->function); - + jit_inc_synth(ret); /* jump to epilog */ instr = jit_jmpi(); jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); } void _jit_retr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr, u); jit_movr(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_reti(jit_state_t *_jit, jit_word_t u) { + jit_inc_synth_w(reti, u); jit_movi(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_f, u); jit_movr_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_reti_f(jit_state_t *_jit, jit_float32_t u) { + jit_inc_synth_f(reti_f, u); jit_movi_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_d, u); jit_movr_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { + jit_inc_synth_d(reti_d, u); jit_movi_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void @@ -400,11 +419,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) void _jit_ellipsis(jit_state_t *_jit) { + jit_inc_synth(ellipsis); if (_jitc->prepare) { + jit_link_prepare(); assert(!(_jitc->function->call.call & jit_call_varargs)); _jitc->function->call.call |= jit_call_varargs; } else { + jit_link_prolog(); assert(!(_jitc->function->self.call & jit_call_varargs)); _jitc->function->self.call |= jit_call_varargs; @@ -413,13 +435,14 @@ _jit_ellipsis(jit_state_t *_jit) _jitc->function->vagp = _jitc->function->self.argi; } + jit_dec_synth(); } jit_node_t * _jit_arg(jit_state_t *_jit) { - jit_int32_t offset; - + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -427,14 +450,17 @@ _jit_arg(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } - return (jit_new_node_w(jit_code_arg, offset)); + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_f(jit_state_t *_jit) { - jit_int32_t offset; - + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -442,14 +468,17 @@ _jit_arg_f(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } - return (jit_new_node_w(jit_code_arg_f, offset)); + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_d(jit_state_t *_jit) { - jit_int32_t offset; - + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -457,87 +486,106 @@ _jit_arg_d(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } - return (jit_new_node_w(jit_code_arg_d, offset)); + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_c(u, _R32 + v->u.w); else jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP); + jit_dec_synth(); } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_uc(u, _R32 + v->u.w); else jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP); + jit_dec_synth(); } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_s(u, _R32 + v->u.w); else jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP); + jit_dec_synth(); } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_us(u, _R32 + v->u.w); else jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP); + jit_dec_synth(); } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_i(u, _R32 + v->u.w); else jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP); + jit_dec_synth(); } void _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_ui(u, _R32 + v->u.w); else jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP); + jit_dec_synth(); } void _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(u, _R32 + v->u.w); else jit_ldxi(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(_R32 + v->u.w, u); else jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -545,6 +593,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); if (jit_arg_reg_p(v->u.w)) jit_movi(_R32 + v->u.w, u); else { @@ -553,26 +602,31 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) jit_stxi(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr_f(u, _F8 + v->u.w); else jit_ldxi_f(u, JIT_FP, v->u.w + F_DISP); + jit_dec_synth(); } void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr_f(_F8 + v->u.w, u); else jit_stxi_f(v->u.w, JIT_FP, u + F_DISP); + jit_dec_synth(); } void @@ -580,6 +634,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); if (jit_arg_reg_p(v->u.w)) jit_movi_f(_F8 + v->u.w, u); else { @@ -588,26 +643,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) jit_stxi_f(v->u.w, JIT_FP, regno + F_DISP); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr_d(u, _F8 + v->u.w); else jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr_d(_F8 + v->u.w, u); else jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -615,6 +675,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); if (jit_arg_reg_p(v->u.w)) jit_movi_d(_F8 + v->u.w, u); else { @@ -623,12 +684,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_stxi_d(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr(_OUT0 + _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -637,6 +701,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void @@ -644,6 +709,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(_OUT0 + _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -655,12 +722,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) _jitc->function->call.size += sizeof(jit_word_t); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { if (!(_jitc->function->call.call & jit_call_varargs)) jit_movr_f(_F8 + _jitc->function->call.argi, u); @@ -673,6 +743,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void @@ -680,6 +751,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { if (!(_jitc->function->call.call & jit_call_varargs)) jit_movi_f(_F8 + _jitc->function->call.argi, u); @@ -695,12 +768,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) _jitc->function->call.size += sizeof(jit_word_t); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { if (!(_jitc->function->call.call & jit_call_varargs)) jit_movr_d(_F8 + _jitc->function->call.argi, u); @@ -712,6 +788,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void @@ -719,6 +796,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { if (!(_jitc->function->call.call & jit_call_varargs)) jit_movi_d(_F8 + _jitc->function->call.argi, u); @@ -733,6 +812,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) _jitc->function->call.size += sizeof(jit_word_t); jit_unget_reg(regno); } + jit_dec_synth(); } jit_bool_t @@ -747,6 +827,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_node_t *call; assert(_jitc->function); + jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; call = jit_callr(r0); @@ -755,6 +836,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); } jit_node_t * @@ -762,6 +844,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) { jit_node_t *node; assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; node = jit_calli(i0); @@ -770,61 +853,80 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); return (node); } void _jit_retval_c(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_c, r0); jit_extr_c(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_uc, r0); jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_s(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_s, r0); jit_extr_s(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_us(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_us, r0); jit_extr_us(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_i(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_i, r0); jit_extr_i(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_ui, r0); jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_l(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_l, r0); jit_movr(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_f(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_l, r0); jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); } void _jit_retval_d(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_d, r0); jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); } jit_pointer_t @@ -838,9 +940,15 @@ _emit_code(jit_state_t *_jit) struct { jit_node_t *node; jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif jit_int32_t patch_offset; jit_word_t prolog_offset; } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif _jitc->function = NULL; @@ -855,6 +963,9 @@ _emit_code(jit_state_t *_jit) undo.node = NULL; undo.patch_offset = 0; +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif undo.prolog_offset = 0; for (node = _jitc->head; node; node = node->next) if (node->code != jit_code_label && @@ -961,7 +1072,8 @@ _emit_code(jit_state_t *_jit) #endif #if DEVEL_DISASSEMBLER sync(); - node->offset = _jit->pc.w; + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; #endif jit_regarg_set(node, value); switch (node->code) { @@ -1368,6 +1480,9 @@ _emit_code(jit_state_t *_jit) _jitc->function = _jitc->functions.ptr + node->w.w; undo.node = node; undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif undo.patch_offset = _jitc->patches.offset; undo.prolog_offset = _jitc->prolog.offset; restart_function: @@ -1403,6 +1518,9 @@ _emit_code(jit_state_t *_jit) temp->flag &= ~jit_flag_patch; node = undo.node; _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif _jitc->patches.offset = undo.patch_offset; _jitc->prolog.offset = undo.prolog_offset; _jitc->ioff = 0; @@ -1429,9 +1547,32 @@ _emit_code(jit_state_t *_jit) vaarg_d(rn(node->u.w), rn(node->v.w)); break; case jit_code_live: - case jit_code_arg: + case jit_code_arg: case jit_code_ellipsis: + case jit_code_allocai: case jit_code_allocar: case jit_code_arg_f: case jit_code_arg_d: case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: case jit_code_getarg_ui: + case jit_code_getarg_l: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_ui: case jit_code_retval_l: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: break; case jit_code_movr_f_w: movr_f_w(rn(node->u.w), rn(node->v.w)); @@ -1472,6 +1613,7 @@ _emit_code(jit_state_t *_jit) assert(jit_regset_scan1(&_jitc->regarg, 0) == jit_carry); assert(jit_regset_scan1(&_jitc->regarg, jit_carry + 1) == ULONG_MAX); } + assert(_jitc->synth == 0); /* update register live state */ jit_reglive(node); } diff --git a/lib/jit_mips-cpu.c b/lib/jit_mips-cpu.c index f43a3fa5f..f9a256862 100644 --- a/lib/jit_mips-cpu.c +++ b/lib/jit_mips-cpu.c @@ -2956,7 +2956,7 @@ _prolog(jit_state_t *_jit, jit_node_t *node) } if (_jitc->function->self.call & jit_call_varargs) { - index = _jitc->function->vagp; + index = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; offset = stack_framesize + index * sizeof(jit_word_t); for (; jit_arg_reg_p(index); ++index, offset += sizeof(jit_word_t)) stxi(offset, _BP_REGNO, rn(_A0 - index)); @@ -2993,41 +2993,19 @@ _epilog(jit_state_t *_jit, jit_node_t *node) static void _vastart(jit_state_t *_jit, jit_int32_t r0) { - jit_int32_t reg; - assert(_jitc->function->self.call & jit_call_varargs); - - /* Return jit_va_list_t in the register argument */ - addi(r0, _BP_REGNO, _jitc->function->vaoff); - reg = jit_get_reg(jit_class_gpr); - - /* Initialize stack pointer to the first stack argument. */ - addi(rn(reg), _BP_REGNO, stack_framesize + - _jitc->function->vagp * sizeof(jit_word_t)); - stxi(offsetof(jit_va_list_t, stack), r0, rn(reg)); - - jit_unget_reg(reg); + /* Initialize va_list to the first stack argument. */ + addi(r0, _BP_REGNO, _jitc->function->self.size); } static void _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { - jit_int32_t reg; - - assert(_jitc->function->self.call & jit_call_varargs); - reg = jit_get_reg(jit_class_gpr); - - /* Load varargs stack pointer. */ - ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack)); - /* Load argument. */ - ldr(r0, rn(reg)); + ldr(r0, r1); - /* Update vararg stack pointer. */ - addi(rn(reg), rn(reg), sizeof(jit_word_t)); - stxi(offsetof(jit_va_list_t, stack), r1, rn(reg)); - - jit_unget_reg(reg); + /* Update va_list. */ + addi(r1, r1, sizeof(jit_word_t)); } static void diff --git a/lib/jit_mips-fpu.c b/lib/jit_mips-fpu.c index 0294bdeeb..e995985a3 100644 --- a/lib/jit_mips-fpu.c +++ b/lib/jit_mips-fpu.c @@ -1780,28 +1780,19 @@ dbopi(unord) static void _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { - jit_int32_t reg, aln; - + jit_int32_t reg; assert(_jitc->function->self.call & jit_call_varargs); - reg = jit_get_reg(jit_class_gpr); - - /* Load varargs stack pointer. */ - ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack)); - /* Align, if required. */ - aln = jit_get_reg(jit_class_gpr); - andi(rn(aln), rn(reg), 7); - addr(rn(reg), rn(reg), rn(aln)); - jit_unget_reg(aln); + reg = jit_get_reg(jit_class_gpr); + andi(rn(reg), r1, 7); + addr(r1, r1, rn(reg)); + jit_unget_reg(reg); /* Load argument. */ - ldr_d(r0, rn(reg)); + ldr_d(r0, r1); - /* Update vararg stack pointer. */ - addi(rn(reg), rn(reg), sizeof(jit_float64_t)); - stxi(offsetof(jit_va_list_t, stack), r1, rn(reg)); - - jit_unget_reg(reg); + /* Update va_list. */ + addi(r1, r1, sizeof(jit_float64_t)); } # undef fopi diff --git a/lib/jit_mips-sz.c b/lib/jit_mips-sz.c index 8e30a680c..208ef32ea 100644 --- a/lib/jit_mips-sz.c +++ b/lib/jit_mips-sz.c @@ -11,7 +11,19 @@ 0, /* #note */ 0, /* label */ 44, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ 0, /* va_start */ 0, /* va_arg */ 0, /* va_arg_d */ @@ -180,8 +192,26 @@ 8, /* jmpi */ 12, /* callr */ 16, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ 44, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 4, /* addr_f */ 16, /* addi_f */ 4, /* subr_f */ @@ -264,7 +294,15 @@ 24, /* bordi_f */ 12, /* bunordr_f */ 24, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 4, /* addr_d */ 16, /* addi_d */ 4, /* subr_d */ @@ -347,6 +385,11 @@ 24, /* bordi_d */ 12, /* bunordr_d */ 24, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -356,14 +399,12 @@ 0, /* movi_d_ww */ 4, /* movr_d_w */ 12, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* NEW_ABI */ #endif /* __WORDSIZE */ #if __WORDSIZE == 32 #if !NEW_ABI -#define JIT_INSTR_MAX 96 +#define JIT_INSTR_MAX 116 0, /* data */ 0, /* live */ 0, /* align */ @@ -372,11 +413,23 @@ 0, /* #name */ 0, /* #note */ 0, /* label */ - 96, /* prolog */ + 116, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ - 0, /* va_start */ - 0, /* va_arg */ - 0, /* va_arg_d */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 20, /* va_arg_d */ 0, /* va_end */ 4, /* addr */ 12, /* addi */ @@ -469,15 +522,15 @@ 0, /* ldr_l */ 0, /* ldi_l */ 8, /* ldxr_c */ - 4, /* ldxi_c */ + 16, /* ldxi_c */ 8, /* ldxr_uc */ - 4, /* ldxi_uc */ + 16, /* ldxi_uc */ 8, /* ldxr_s */ - 4, /* ldxi_s */ + 16, /* ldxi_s */ 8, /* ldxr_us */ - 4, /* ldxi_us */ + 16, /* ldxi_us */ 8, /* ldxr_i */ - 4, /* ldxi_i */ + 16, /* ldxi_i */ 0, /* ldxr_ui */ 0, /* ldxi_ui */ 0, /* ldxr_l */ @@ -491,11 +544,11 @@ 0, /* str_l */ 0, /* sti_l */ 8, /* stxr_c */ - 4, /* stxi_c */ + 16, /* stxi_c */ 8, /* stxr_s */ - 4, /* stxi_s */ + 16, /* stxi_s */ 8, /* stxr_i */ - 4, /* stxi_i */ + 16, /* stxi_i */ 0, /* stxr_l */ 0, /* stxi_l */ 12, /* bltr */ @@ -538,12 +591,30 @@ 28, /* bxsubi */ 16, /* bxsubr_u */ 20, /* bxsubi_u */ - 0, /* jmpr */ + 8, /* jmpr */ 8, /* jmpi */ 12, /* callr */ 16, /* calli */ - 96, /* epilog */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 116, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 4, /* addr_f */ 16, /* addi_f */ 4, /* subr_f */ @@ -593,11 +664,11 @@ 4, /* ldr_f */ 12, /* ldi_f */ 8, /* ldxr_f */ - 4, /* ldxi_f */ + 16, /* ldxi_f */ 4, /* str_f */ 12, /* sti_f */ 8, /* stxr_f */ - 4, /* stxi_f */ + 16, /* stxi_f */ 12, /* bltr_f */ 24, /* blti_f */ 12, /* bler_f */ @@ -626,7 +697,15 @@ 24, /* bordi_f */ 12, /* bunordr_f */ 24, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 4, /* addr_d */ 20, /* addi_d */ 4, /* subr_d */ @@ -676,11 +755,11 @@ 8, /* ldr_d */ 16, /* ldi_d */ 12, /* ldxr_d */ - 8, /* ldxi_d */ + 20, /* ldxi_d */ 8, /* str_d */ 16, /* sti_d */ 12, /* stxr_d */ - 8, /* stxi_d */ + 20, /* stxi_d */ 12, /* bltr_d */ 28, /* blti_d */ 12, /* bler_d */ @@ -709,17 +788,20 @@ 28, /* bordi_d */ 12, /* bunordr_d */ 36, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 4, /* movr_w_f */ 8, /* movr_ww_d */ 0, /* movr_w_d */ - 0, /* movr_f_w */ + 4, /* movr_f_w */ 4, /* movi_f_w */ 8, /* movr_d_ww */ 8, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* NEW_ABI */ #endif /* __WORDSIZE */ @@ -734,7 +816,19 @@ 0, /* #note */ 0, /* label */ 44, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ 0, /* va_start */ 0, /* va_arg */ 0, /* va_arg_d */ @@ -903,8 +997,26 @@ 8, /* jmpi */ 12, /* callr */ 32, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ 44, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 4, /* addr_f */ 16, /* addi_f */ 4, /* subr_f */ @@ -987,7 +1099,15 @@ 24, /* bordi_f */ 12, /* bunordr_f */ 24, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 4, /* addr_d */ 16, /* addi_d */ 4, /* subr_d */ @@ -1070,6 +1190,11 @@ 24, /* bordi_d */ 12, /* bunordr_d */ 24, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -1079,6 +1204,4 @@ 0, /* movi_d_ww */ 4, /* movr_d_w */ 12, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __WORDSIZE */ diff --git a/lib/jit_mips.c b/lib/jit_mips.c index ffbeac67e..eac92a014 100644 --- a/lib/jit_mips.c +++ b/lib/jit_mips.c @@ -53,17 +53,22 @@ /* * Types */ -typedef struct jit_va_list { - jit_pointer_t stack; -} jit_va_list_t; +typedef struct jit_pointer_t jit_va_list_t; /* * Prototypes */ -# define patch(instr, node) _patch(_jit, instr, node) +#define jit_make_arg(node) _jit_make_arg(_jit,node) +static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*); +#define jit_make_arg_f(node) _jit_make_arg_f(_jit,node) +static jit_node_t *_jit_make_arg_f(jit_state_t*,jit_node_t*); +#define jit_make_arg_d(node) _jit_make_arg_d(_jit,node) +static jit_node_t *_jit_make_arg_d(jit_state_t*,jit_node_t*); +#define patch(instr, node) _patch(_jit, instr, node) static void _patch(jit_state_t*,jit_word_t,jit_node_t*); #define PROTO 1 +# include "jit_rewind.c" # include "jit_mips-cpu.c" # include "jit_mips-fpu.c" #undef PROTO @@ -189,6 +194,10 @@ _jit_prolog(jit_state_t *_jit) jit_alloc((jit_pointer_t *)&_jitc->function->regoff, _jitc->reglen * sizeof(jit_int32_t)); + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); jit_link(_jitc->function->prolog); _jitc->function->prolog->w.w = offset; @@ -213,6 +222,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length) default: _jitc->function->self.aoff &= -8; break; } _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } return (_jitc->function->self.aoff); } @@ -221,6 +234,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) { jit_int32_t reg; assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); if (!_jitc->function->allocar) { _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->allocar = 1; @@ -233,69 +247,82 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) jit_addr(JIT_SP, JIT_SP, reg); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_unget_reg(reg); + jit_dec_synth(); } void _jit_ret(jit_state_t *_jit) { jit_node_t *instr; - assert(_jitc->function); - + jit_inc_synth(ret); /* jump to epilog */ instr = jit_jmpi(); jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); } void _jit_retr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr, u); if (JIT_RET != u) jit_movr(JIT_RET, u); else jit_live(JIT_RET); jit_ret(); + jit_dec_synth(); } void _jit_reti(jit_state_t *_jit, jit_word_t u) { + jit_inc_synth_w(reti, u); jit_movi(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_f, u); if (JIT_FRET != u) jit_movr_f(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_f(jit_state_t *_jit, jit_float32_t u) { + jit_inc_synth_f(reti_f, u); jit_movi_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_d, u); if (JIT_FRET != u) jit_movr_d(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { + jit_inc_synth_d(reti_d, u); jit_movi_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void @@ -320,29 +347,10 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) #endif } -void -_jit_ellipsis(jit_state_t *_jit) +static jit_node_t * +_jit_make_arg(jit_state_t *_jit, jit_node_t *node) { - if (_jitc->prepare) { - assert(!(_jitc->function->call.call & jit_call_varargs)); - _jitc->function->call.call |= jit_call_varargs; - } - else { - assert(!(_jitc->function->self.call & jit_call_varargs)); - _jitc->function->self.call |= jit_call_varargs; - - /* Allocate va_list like object in the stack. */ - _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t)); - - _jitc->function->vagp = _jitc->function->self.argi; - } -} - -jit_node_t * -_jit_arg(jit_state_t *_jit) -{ - jit_int32_t offset; - assert(_jitc->function); + jit_int32_t offset; #if NEW_ABI if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -357,14 +365,20 @@ _jit_arg(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += STACK_SLOT; #endif - return (jit_new_node_w(jit_code_arg, offset)); + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); } -jit_node_t * -_jit_arg_f(jit_state_t *_jit) +static jit_node_t * +_jit_make_arg_f(jit_state_t *_jit, jit_node_t *node) { - jit_int32_t offset; - assert(_jitc->function); + jit_int32_t offset; #if NEW_ABI if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -375,27 +389,36 @@ _jit_arg_f(jit_state_t *_jit) #else offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; if (offset < NUM_WORD_ARGS) { - if (!_jitc->function->self.argi) { + if (!_jitc->function->self.argi && + !(_jitc->function->self.call & jit_call_varargs)) { if (offset == 0) offset = 4; else { offset = 6; _jitc->function->self.argi = 1; } + /* Use as flag to rewind in case of varargs function */ + ++_jitc->function->self.argf; } } else offset = _jitc->function->self.size; _jitc->function->self.size += STACK_SLOT; #endif - return (jit_new_node_w(jit_code_arg_f, offset)); + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg_f); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); } -jit_node_t * -_jit_arg_d(jit_state_t *_jit) +static jit_node_t * +_jit_make_arg_d(jit_state_t *_jit, jit_node_t *node) { - jit_int32_t offset; - assert(_jitc->function); + jit_int32_t offset; #if NEW_ABI if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -410,60 +433,124 @@ _jit_arg_d(jit_state_t *_jit) } offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; if (offset < NUM_WORD_ARGS) { - if (!_jitc->function->self.argi) + if (!_jitc->function->self.argi && + !(_jitc->function->self.call & jit_call_varargs)) { offset += 4; + /* Use as flag to rewind in case of varargs function */ + ++_jitc->function->self.argf; + } } else offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_float64_t); #endif - return (jit_new_node_w(jit_code_arg_d, offset)); + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg_d); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + if (_jitc->prepare) { + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + if (_jitc->function->call.argf) + rewind_prepare(); + } + else { + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + if (_jitc->function->self.argf) + rewind_prolog(); + } + jit_inc_synth(ellipsis); + if (_jitc->prepare) + jit_link_prepare(); + else + jit_link_prolog(); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg((jit_node_t*)0)); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg_f((jit_node_t*)0)); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg_d((jit_node_t*)0)); } void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_c(u, _A0 - v->u.w); else jit_ldxi_c(u, _FP, v->u.w + C_DISP); + jit_dec_synth(); } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_uc(u, _A0 - v->u.w); else jit_ldxi_uc(u, _FP, v->u.w + C_DISP); + jit_dec_synth(); } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_s(u, _A0 - v->u.w); else jit_ldxi_s(u, _FP, v->u.w + S_DISP); + jit_dec_synth(); } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_us(u, _A0 - v->u.w); else jit_ldxi_us(u, _FP, v->u.w + S_DISP); + jit_dec_synth(); } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); if (jit_arg_reg_p(v->u.w)) { #if __WORDSIZE == 64 jit_extr_i(u, _A0 - v->u.w); @@ -473,6 +560,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) } else jit_ldxi_i(u, _FP, v->u.w + I_DISP); + jit_dec_synth(); } #if __WORDSIZE == 64 @@ -480,31 +568,37 @@ void _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_ui(u, _A0 - v->u.w); else jit_ldxi_ui(u, _FP, v->u.w + I_DISP); + jit_dec_synth(); } void _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(u, _A0 - v->u.w); else jit_ldxi_l(u, _FP, v->u.w); + jit_dec_synth(); } #endif void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { + jit_inc_synth_wp(putargr, u, v); assert(v->code == jit_code_arg); if (jit_arg_reg_p(v->u.w)) jit_movr(_A0 - v->u.w, u); else jit_stxi(v->u.w, _FP, u); + jit_dec_synth(); } void @@ -512,6 +606,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); if (jit_arg_reg_p(v->u.w)) jit_movi(_A0 - v->u.w, u); else { @@ -520,12 +615,14 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) jit_stxi(v->u.w, _FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movr_f(u, _F12 - v->u.w); @@ -537,12 +634,14 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) #endif else jit_ldxi_f(u, _FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movr_f(_F12 - v->u.w, u); @@ -554,6 +653,7 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) #endif else jit_stxi_f(v->u.w, _FP, u); + jit_dec_synth(); } void @@ -561,6 +661,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movi_f(_F12 - v->u.w, u); @@ -580,12 +681,14 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) jit_stxi_f(v->u.w, _FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movr_d(u, _F12 - v->u.w); @@ -597,12 +700,14 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) #endif else jit_ldxi_d(u, _FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movr_d(_F12 - v->u.w, u); @@ -614,6 +719,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) #endif else jit_stxi_d(v->u.w, _FP, u); + jit_dec_synth(); } void @@ -621,6 +727,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movi_d(_F12 - v->u.w, u); @@ -640,11 +747,14 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_stxi_d(v->u.w, _FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); #if NEW_ABI assert(_jitc->function); if (jit_arg_reg_p(_jitc->function->call.argi)) { @@ -666,14 +776,20 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) jit_stxi(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += STACK_SLOT; #endif + jit_dec_synth(); } void _jit_pushargi(jit_state_t *_jit, jit_word_t u) { -#if NEW_ABI jit_int32_t regno; +#if !NEW_ABI + jit_word_t offset; +#endif assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); +#if NEW_ABI if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(_A0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -686,9 +802,6 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) jit_unget_reg(regno); } #else - jit_int32_t regno; - jit_word_t offset; - assert(_jitc->function); offset = _jitc->function->call.size >> STACK_SHIFT; ++_jitc->function->call.argi; if (jit_arg_reg_p(offset)) @@ -701,13 +814,19 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) } _jitc->function->call.size += STACK_SLOT; #endif + jit_dec_synth(); } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { -#if NEW_ABI +#if !NEW_ABI + jit_word_t offset; +#endif assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); +#if NEW_ABI if (jit_arg_reg_p(_jitc->function->call.argi)) { if (!(_jitc->function->call.call & jit_call_varargs)) jit_movr_f(_F12 - _jitc->function->call.argi, u); @@ -720,10 +839,9 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jitc->function->call.size += STACK_SLOT; } #else - jit_word_t offset; - assert(_jitc->function); offset = _jitc->function->call.size >> STACK_SHIFT; - if (offset < 2 && !_jitc->function->call.argi) { + if (offset < 2 && !_jitc->function->call.argi && + !(_jitc->function->call.call & jit_call_varargs)) { ++_jitc->function->call.argf; jit_movr_f(_F12 - offset, u); } @@ -735,14 +853,20 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) jit_stxi_f(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += STACK_SLOT; #endif + jit_dec_synth(); } void _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; -#if NEW_ABI +#if !NEW_ABI + jit_word_t offset; +#endif assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); +#if NEW_ABI if (jit_arg_reg_p(_jitc->function->call.argi)) { if (!(_jitc->function->call.call & jit_call_varargs)) jit_movi_f(_F12 - _jitc->function->call.argi, u); @@ -758,10 +882,9 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) jit_unget_reg(regno); } #else - jit_word_t offset; - assert(_jitc->function); offset = _jitc->function->call.size >> STACK_SHIFT; - if (offset < 2 && !_jitc->function->call.argi) { + if (offset < 2 && !_jitc->function->call.argi && + !(_jitc->function->call.call & jit_call_varargs)) { ++_jitc->function->call.argf; jit_movi_f(_F12 - offset, u); } @@ -777,13 +900,20 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) } _jitc->function->call.size += STACK_SLOT; #endif + jit_dec_synth(); } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { -#if NEW_ABI +#if !NEW_ABI + jit_bool_t adjust; + jit_word_t offset; +#endif assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); +#if NEW_ABI if (jit_arg_reg_p(_jitc->function->call.argi)) { if (!(_jitc->function->call.call & jit_call_varargs)) jit_movr_d(_F12 - _jitc->function->call.argi, u); @@ -796,9 +926,6 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jitc->function->call.size += STACK_SLOT; } #else - jit_bool_t adjust; - jit_word_t offset; - assert(_jitc->function); adjust = !!_jitc->function->call.argi; if (_jitc->function->call.size & 7) { _jitc->function->call.size += 4; @@ -806,7 +933,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) } offset = _jitc->function->call.size >> STACK_SHIFT; if (offset < 3) { - if (adjust) { + if (adjust || (_jitc->function->call.call & jit_call_varargs)) { jit_movr_d_ww(_A0 - offset, _A0 - (offset + 1), u); _jitc->function->call.argi += 2; } @@ -819,14 +946,21 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) jit_stxi_d(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += sizeof(jit_float64_t); #endif + jit_dec_synth(); } void _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; -#if NEW_ABI +#if !NEW_ABI + jit_bool_t adjust; + jit_word_t offset; +#endif assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); +#if NEW_ABI if (jit_arg_reg_p(_jitc->function->call.argi)) { if (!(_jitc->function->call.call & jit_call_varargs)) jit_movi_d(_F12 - _jitc->function->call.argi, u); @@ -842,9 +976,6 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) jit_unget_reg(regno); } #else - jit_bool_t adjust; - jit_word_t offset; - assert(_jitc->function); adjust = !!_jitc->function->call.argi; if (_jitc->function->call.size & 7) { _jitc->function->call.size += 4; @@ -852,7 +983,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) } offset = _jitc->function->call.size >> STACK_SHIFT; if (offset < 3) { - if (adjust) { + if (adjust || (_jitc->function->call.call & jit_call_varargs)) { jit_movi_d_ww(_A0 - offset, _A0 - (offset + 1), u); _jitc->function->call.argi += 2; } @@ -869,6 +1000,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) } _jitc->function->call.size += sizeof(jit_float64_t); #endif + jit_dec_synth(); } jit_bool_t @@ -897,8 +1029,8 @@ void _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_node_t *call; - assert(_jitc->function); + jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; jit_movr(_T9, r0); @@ -912,6 +1044,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); } jit_node_t * @@ -919,8 +1052,8 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) { jit_node_t *call; jit_node_t *node; - assert(_jitc->function); + jit_inc_synth_w(finishr, (jit_word_t)i0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; node = jit_movi(_T9, (jit_word_t)i0); @@ -934,6 +1067,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); return (node); } @@ -1012,8 +1146,14 @@ _emit_code(jit_state_t *_jit) struct { jit_node_t *node; jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif jit_int32_t patch_offset; } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif _jitc->function = NULL; @@ -1105,12 +1245,16 @@ _emit_code(jit_state_t *_jit) patch(word, node); \ } \ break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif for (node = _jitc->head; node; node = node->next) { if (_jit->pc.uc >= _jitc->code.end) return (NULL); #if DEVEL_DISASSEMBLER - node->offset = _jit->pc.w; + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; #endif value = jit_classify(node->code); jit_regarg_set(node, value); @@ -1527,6 +1671,9 @@ _emit_code(jit_state_t *_jit) _jitc->function = _jitc->functions.ptr + node->w.w; undo.node = node; undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif undo.patch_offset = _jitc->patches.offset; restart_function: _jitc->again = 0; @@ -1544,6 +1691,9 @@ _emit_code(jit_state_t *_jit) temp->flag &= ~jit_flag_patch; node = undo.node; _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif _jitc->patches.offset = undo.patch_offset; goto restart_function; } @@ -1596,9 +1746,36 @@ _emit_code(jit_state_t *_jit) vaarg_d(rn(node->u.w), rn(node->v.w)); break; case jit_code_live: - case jit_code_arg: + case jit_code_arg: case jit_code_ellipsis: + case jit_code_allocai: case jit_code_allocar: case jit_code_arg_f: case jit_code_arg_d: case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: +#if __WORDSIZE == 64 + case jit_code_getarg_ui: case jit_code_getarg_l: +#endif + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: +#if __WORDSIZE == 64 + case jit_code_retval_ui: case jit_code_retval_l: +#endif + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: break; default: abort(); @@ -1619,6 +1796,7 @@ _emit_code(jit_state_t *_jit) } jit_regarg_clr(node, value); assert(_jitc->regarg == jit_carry == _NOREG ? 0 : (1 << jit_carry)); + assert(_jitc->synth == 0); /* update register live state */ jit_reglive(node); } @@ -1645,6 +1823,7 @@ _emit_code(jit_state_t *_jit) } #define CODE 1 +# include "jit_rewind.c" # include "jit_mips-cpu.c" # include "jit_mips-fpu.c" #undef CODE diff --git a/lib/jit_names.c b/lib/jit_names.c index 02cb8db8d..028ea5492 100644 --- a/lib/jit_names.c +++ b/lib/jit_names.c @@ -24,7 +24,14 @@ static char *code_name[] = { "#name", "#note", "label", "prolog", + "ellipsis", + "allocai", "allocar", "arg", + "getarg_c", "getarg_uc", + "getarg_s", "getarg_us", + "getarg_i", "getarg_ui", + "getarg_l", + "putargr", "putargi", "va_start", "va_arg", "va_arg_d", "va_end", @@ -111,8 +118,18 @@ static char *code_name[] = { "bxsubr_u", "bxsubi_u", "jmpr", "jmpi", "callr", "calli", + "prepare", + "pushargr", "pushargi", + "finishr", "finishi", + "ret", + "retr", "reti", + "retval_c", "retval_uc", + "retval_s", "retval_us", + "retval_i", "retval_ui", + "retval_l", "epilog", - "arg_f", + "arg_f", "getarg_f", + "putargr_f", "putargi_f", "addr_f", "addi_f", "subr_f", "subi_f", "rsbi_f", @@ -155,7 +172,11 @@ static char *code_name[] = { "bltgtr_f", "bltgti_f", "bordr_f", "bordi_f", "bunordr_f", "bunordi_f", - "arg_d", + "pushargr_f", "pushargi_f", + "retr_f", "reti_f", + "retval_f", + "arg_d", "getarg_d", + "putargr_d", "putargi_d", "addr_d", "addi_d", "subr_d", "subi_d", "rsbi_d", @@ -198,10 +219,12 @@ static char *code_name[] = { "bltgtr_d", "bltgti_d", "bordr_d", "bordi_d", "bunordr_d", "bunordi_d", + "pushargr_d", "pushargi_d", + "retr_d", "reti_d", + "retval_d", "movr_w_f", "movr_ww_d", "movr_w_d", "movr_f_w", "movi_f_w", "movr_d_ww", "movi_d_ww", "movr_d_w", "movi_d_w", - "x86_retval_f", "x86_retval_d", }; diff --git a/lib/jit_ppc-cpu.c b/lib/jit_ppc-cpu.c index e3f9114ff..c0196edd5 100644 --- a/lib/jit_ppc-cpu.c +++ b/lib/jit_ppc-cpu.c @@ -3287,7 +3287,7 @@ _prolog(jit_state_t *_jit, jit_node_t *node) if (_jitc->function->self.call & jit_call_varargs) { for (regno = _jitc->function->vagp; jit_arg_reg_p(regno); ++regno) - stxi(gpr_save_area - (8 - regno) * sizeof(jit_word_t), + stxi(params_offset + regno * sizeof(jit_word_t), _FP_REGNO, rn(JIT_RA0 - regno)); } } @@ -3342,43 +3342,22 @@ _epilog(jit_state_t *_jit, jit_node_t *node) static void _vastart(jit_state_t *_jit, jit_int32_t r0) { - jit_int32_t reg; - assert(_jitc->function->self.call & jit_call_varargs); - /* Return jit_va_list_t in the register argument */ - addi(r0, _FP_REGNO, _jitc->function->vaoff); - reg = jit_get_reg(jit_class_gpr); - /* Initialize stack pointer to the first stack argument. */ - addi(rn(reg), _FP_REGNO, gpr_save_area - - 8 * sizeof(jit_word_t) + _jitc->function->vagp * sizeof(jit_word_t)); - stxi(offsetof(jit_va_list_t, stack), r0, rn(reg)); - - jit_unget_reg(reg); + addi(r0, _FP_REGNO, _jitc->function->self.size); } static void _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { - jit_int32_t inv, reg; - assert(_jitc->function->self.call & jit_call_varargs); - reg = jit_get_reg(jit_class_gpr); - if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); - - /* Load varargs stack pointer. */ - ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack)); /* Load argument. */ - ldr(r0, rn(reg)); + ldr(r0, r1); - /* Update vararg stack pointer. */ - addi(rn(reg), rn(reg), sizeof(jit_word_t)); - stxi(offsetof(jit_va_list_t, stack), r1, rn(reg)); - - jit_unget_reg(reg); - if (inv) jit_unget_reg(_R0); + /* Update va_list. */ + addi(r1, r1, sizeof(jit_word_t)); } static void diff --git a/lib/jit_ppc-fpu.c b/lib/jit_ppc-fpu.c index 778195459..7a0535a66 100644 --- a/lib/jit_ppc-fpu.c +++ b/lib/jit_ppc-fpu.c @@ -1185,23 +1185,10 @@ _stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) static void _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { - jit_int32_t inv, reg; - - assert(_jitc->function->self.call & jit_call_varargs); - reg = jit_get_reg(jit_class_gpr); - if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); - - /* Load varargs stack pointer. */ - ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack)); - /* Load argument. */ - ldr_d(r0, rn(reg)); + ldr_d(r0, r1); - /* Update vararg stack pointer. */ - addi(rn(reg), rn(reg), sizeof(jit_float64_t)); - stxi(offsetof(jit_va_list_t, stack), r1, rn(reg)); - - jit_unget_reg(reg); - if (inv) jit_unget_reg(_R0); + /* Update va_list. */ + addi(r1, r1, sizeof(jit_float64_t)); } #endif diff --git a/lib/jit_ppc-sz.c b/lib/jit_ppc-sz.c index 8974c7fca..c206b0f66 100644 --- a/lib/jit_ppc-sz.c +++ b/lib/jit_ppc-sz.c @@ -11,7 +11,19 @@ 0, /* #note */ 0, /* label */ 44, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ 0, /* va_start */ 0, /* va_arg */ 0, /* va_arg_d */ @@ -180,8 +192,26 @@ 4, /* jmpi */ 8, /* callr */ 16, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ 44, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 4, /* addr_f */ 12, /* addi_f */ 4, /* subr_f */ @@ -264,7 +294,15 @@ 16, /* bordi_f */ 8, /* bunordr_f */ 16, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 4, /* addr_d */ 12, /* addi_d */ 4, /* subr_d */ @@ -347,6 +385,11 @@ 16, /* bordi_d */ 8, /* bunordr_d */ 16, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -356,14 +399,13 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __ppc__ */ #endif /* __WORDSIZE */ #if __WORDSIZE == 32 #if defined(__powerpc__) -#define JIT_INSTR_MAX 72 +#if __BYTE_ORDER == __BIG_ENDIAN +#define JIT_INSTR_MAX 136 0, /* data */ 0, /* live */ 0, /* align */ @@ -372,11 +414,23 @@ 0, /* #name */ 0, /* #note */ 0, /* label */ - 72, /* prolog */ + 136, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ - 0, /* va_start */ - 0, /* va_arg */ - 0, /* va_arg_d */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 8, /* va_arg_d */ 0, /* va_end */ 4, /* addr */ 12, /* addi */ @@ -469,15 +523,15 @@ 0, /* ldr_l */ 0, /* ldi_l */ 8, /* ldxr_c */ - 8, /* ldxi_c */ + 16, /* ldxi_c */ 4, /* ldxr_uc */ - 4, /* ldxi_uc */ + 12, /* ldxi_uc */ 4, /* ldxr_s */ - 4, /* ldxi_s */ + 12, /* ldxi_s */ 4, /* ldxr_us */ - 4, /* ldxi_us */ + 12, /* ldxi_us */ 4, /* ldxr_i */ - 4, /* ldxi_i */ + 12, /* ldxi_i */ 0, /* ldxr_ui */ 0, /* ldxi_ui */ 0, /* ldxr_l */ @@ -491,11 +545,11 @@ 0, /* str_l */ 0, /* sti_l */ 4, /* stxr_c */ - 4, /* stxi_c */ + 12, /* stxi_c */ 4, /* stxr_s */ - 4, /* stxi_s */ + 12, /* stxi_s */ 4, /* stxr_i */ - 4, /* stxi_i */ + 12, /* stxi_i */ 0, /* stxr_l */ 0, /* stxi_l */ 8, /* bltr */ @@ -538,12 +592,30 @@ 16, /* bxsubi */ 12, /* bxsubr_u */ 16, /* bxsubi_u */ - 0, /* jmpr */ + 8, /* jmpr */ 4, /* jmpi */ 28, /* callr */ 40, /* calli */ - 72, /* epilog */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 124, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 4, /* addr_f */ 16, /* addi_f */ 4, /* subr_f */ @@ -593,11 +665,11 @@ 4, /* ldr_f */ 8, /* ldi_f */ 4, /* ldxr_f */ - 4, /* ldxi_f */ + 12, /* ldxi_f */ 4, /* str_f */ 8, /* sti_f */ 4, /* stxr_f */ - 4, /* stxi_f */ + 12, /* stxi_f */ 8, /* bltr_f */ 20, /* blti_f */ 12, /* bler_f */ @@ -626,7 +698,15 @@ 20, /* bordi_f */ 8, /* bunordr_f */ 20, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 4, /* addr_d */ 24, /* addi_d */ 4, /* subr_d */ @@ -676,11 +756,11 @@ 4, /* ldr_d */ 8, /* ldi_d */ 4, /* ldxr_d */ - 4, /* ldxi_d */ + 12, /* ldxi_d */ 4, /* str_d */ 8, /* sti_d */ 4, /* stxr_d */ - 4, /* stxi_d */ + 12, /* stxi_d */ 8, /* bltr_d */ 28, /* blti_d */ 12, /* bler_d */ @@ -709,6 +789,11 @@ 28, /* bordi_d */ 8, /* bunordr_d */ 28, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -718,14 +803,14 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ +#endif /* __BYTEORDER */ #endif /* __powerpc__ */ #endif /* __WORDSIZE */ #if __WORDSIZE == 64 #if defined(__powerpc__) -#define JIT_INSTR_MAX 72 +#if __BYTE_ORDER == __BIG_ENDIAN +#define JIT_INSTR_MAX 148 0, /* data */ 0, /* live */ 4, /* align */ @@ -734,11 +819,23 @@ 0, /* #name */ 0, /* #note */ 0, /* label */ - 72, /* prolog */ + 148, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ - 0, /* va_start */ - 0, /* va_arg */ - 0, /* va_arg_d */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 8, /* va_arg_d */ 0, /* va_end */ 4, /* addr */ 28, /* addi */ @@ -752,7 +849,7 @@ 28, /* subci */ 4, /* subxr */ 8, /* subxi */ - 32, /* rsbi */ + 44, /* rsbi */ 4, /* mulr */ 28, /* muli */ 12, /* qmulr */ @@ -813,15 +910,9 @@ 4, /* extr_us */ 4, /* extr_i */ 4, /* extr_ui */ -# if __BYTE_ORDER == __BIG_ENDIAN 4, /* htonr_us */ 4, /* htonr_ui */ 4, /* htonr_ul */ -#else - 20, /* htonr_us */ - 16, /* htonr_ui */ - 44, /* htonr_ul */ -#endif 8, /* ldr_c */ 28, /* ldi_c */ 4, /* ldr_uc */ @@ -837,19 +928,19 @@ 4, /* ldr_l */ 24, /* ldi_l */ 8, /* ldxr_c */ - 8, /* ldxi_c */ + 16, /* ldxi_c */ 4, /* ldxr_uc */ - 4, /* ldxi_uc */ + 12, /* ldxi_uc */ 4, /* ldxr_s */ - 4, /* ldxi_s */ + 12, /* ldxi_s */ 4, /* ldxr_us */ - 4, /* ldxi_us */ + 12, /* ldxi_us */ 4, /* ldxr_i */ - 4, /* ldxi_i */ + 12, /* ldxi_i */ 4, /* ldxr_ui */ - 4, /* ldxi_ui */ + 12, /* ldxi_ui */ 4, /* ldxr_l */ - 4, /* ldxi_l */ + 12, /* ldxi_l */ 4, /* str_c */ 24, /* sti_c */ 4, /* str_s */ @@ -859,13 +950,13 @@ 4, /* str_l */ 24, /* sti_l */ 4, /* stxr_c */ - 4, /* stxi_c */ + 12, /* stxi_c */ 4, /* stxr_s */ - 4, /* stxi_s */ + 12, /* stxi_s */ 4, /* stxr_i */ - 4, /* stxi_i */ + 12, /* stxi_i */ 4, /* stxr_l */ - 4, /* stxi_l */ + 12, /* stxi_l */ 8, /* bltr */ 8, /* blti */ 8, /* bltr_u */ @@ -906,12 +997,30 @@ 16, /* bxsubi */ 12, /* bxsubr_u */ 16, /* bxsubi_u */ - 0, /* jmpr */ + 8, /* jmpr */ 4, /* jmpi */ 28, /* callr */ 56, /* calli */ - 72, /* epilog */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 124, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 4, /* addr_f */ 28, /* addi_f */ 4, /* subr_f */ @@ -961,11 +1070,11 @@ 4, /* ldr_f */ 24, /* ldi_f */ 4, /* ldxr_f */ - 4, /* ldxi_f */ + 12, /* ldxi_f */ 4, /* str_f */ 24, /* sti_f */ 4, /* stxr_f */ - 4, /* stxi_f */ + 12, /* stxi_f */ 8, /* bltr_f */ 32, /* blti_f */ 12, /* bler_f */ @@ -994,12 +1103,20 @@ 32, /* bordi_f */ 8, /* bunordr_f */ 32, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 4, /* addr_d */ 28, /* addi_d */ 4, /* subr_d */ 28, /* subi_d */ - 28, /* rsbi_d */ + 32, /* rsbi_d */ 4, /* mulr_d */ 28, /* muli_d */ 4, /* divr_d */ @@ -1044,11 +1161,11 @@ 4, /* ldr_d */ 24, /* ldi_d */ 4, /* ldxr_d */ - 4, /* ldxi_d */ + 12, /* ldxi_d */ 4, /* str_d */ 24, /* sti_d */ 4, /* stxr_d */ - 4, /* stxi_d */ + 12, /* stxi_d */ 8, /* bltr_d */ 32, /* blti_d */ 12, /* bler_d */ @@ -1077,6 +1194,11 @@ 36, /* bordi_d */ 8, /* bunordr_d */ 32, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -1086,7 +1208,411 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ +#endif /* __BYTEORDER */ +#endif /* __powerpc__ */ +#endif /* __WORDSIZE */ + +#if __WORDSIZE == 64 +#if defined(__powerpc__) +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define JIT_INSTR_MAX 124 + 0, /* data */ + 0, /* live */ + 4, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 124, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 8, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 28, /* addi */ + 4, /* addcr */ + 28, /* addci */ + 4, /* addxr */ + 8, /* addxi */ + 4, /* subr */ + 28, /* subi */ + 4, /* subcr */ + 28, /* subci */ + 4, /* subxr */ + 8, /* subxi */ + 44, /* rsbi */ + 4, /* mulr */ + 28, /* muli */ + 12, /* qmulr */ + 28, /* qmuli */ + 12, /* qmulr_u */ + 28, /* qmuli_u */ + 4, /* divr */ + 28, /* divi */ + 4, /* divr_u */ + 28, /* divi_u */ + 20, /* qdivr */ + 16, /* qdivi */ + 20, /* qdivr_u */ + 16, /* qdivi_u */ + 12, /* remr */ + 36, /* remi */ + 12, /* remr_u */ + 36, /* remi_u */ + 4, /* andr */ + 28, /* andi */ + 4, /* orr */ + 28, /* ori */ + 4, /* xorr */ + 28, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 12, /* ltr */ + 12, /* lti */ + 12, /* ltr_u */ + 16, /* lti_u */ + 16, /* ler */ + 16, /* lei */ + 16, /* ler_u */ + 16, /* lei_u */ + 12, /* eqr */ + 12, /* eqi */ + 16, /* ger */ + 16, /* gei */ + 16, /* ger_u */ + 16, /* gei_u */ + 12, /* gtr */ + 12, /* gti */ + 12, /* gtr_u */ + 12, /* gti_u */ + 16, /* ner */ + 16, /* nei */ + 4, /* movr */ + 36, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 4, /* extr_i */ + 4, /* extr_ui */ + 20, /* htonr_us */ + 16, /* htonr_ui */ + 44, /* htonr_ul */ + 8, /* ldr_c */ + 28, /* ldi_c */ + 4, /* ldr_uc */ + 24, /* ldi_uc */ + 4, /* ldr_s */ + 24, /* ldi_s */ + 4, /* ldr_us */ + 24, /* ldi_us */ + 4, /* ldr_i */ + 24, /* ldi_i */ + 4, /* ldr_ui */ + 24, /* ldi_ui */ + 4, /* ldr_l */ + 24, /* ldi_l */ + 8, /* ldxr_c */ + 16, /* ldxi_c */ + 4, /* ldxr_uc */ + 12, /* ldxi_uc */ + 4, /* ldxr_s */ + 12, /* ldxi_s */ + 4, /* ldxr_us */ + 12, /* ldxi_us */ + 4, /* ldxr_i */ + 12, /* ldxi_i */ + 4, /* ldxr_ui */ + 12, /* ldxi_ui */ + 4, /* ldxr_l */ + 12, /* ldxi_l */ + 4, /* str_c */ + 24, /* sti_c */ + 4, /* str_s */ + 24, /* sti_s */ + 4, /* str_i */ + 24, /* sti_i */ + 4, /* str_l */ + 24, /* sti_l */ + 4, /* stxr_c */ + 12, /* stxi_c */ + 4, /* stxr_s */ + 12, /* stxi_s */ + 4, /* stxr_i */ + 12, /* stxi_i */ + 4, /* stxr_l */ + 12, /* stxi_l */ + 8, /* bltr */ + 8, /* blti */ + 8, /* bltr_u */ + 12, /* blti_u */ + 8, /* bler */ + 8, /* blei */ + 8, /* bler_u */ + 12, /* blei_u */ + 8, /* beqr */ + 44, /* beqi */ + 8, /* bger */ + 8, /* bgei */ + 8, /* bger_u */ + 8, /* bgei_u */ + 8, /* bgtr */ + 8, /* bgti */ + 8, /* bgtr_u */ + 8, /* bgti_u */ + 8, /* bner */ + 36, /* bnei */ + 12, /* bmsr */ + 12, /* bmsi */ + 12, /* bmcr */ + 12, /* bmci */ + 12, /* boaddr */ + 16, /* boaddi */ + 12, /* boaddr_u */ + 12, /* boaddi_u */ + 12, /* bxaddr */ + 16, /* bxaddi */ + 12, /* bxaddr_u */ + 12, /* bxaddi_u */ + 12, /* bosubr */ + 16, /* bosubi */ + 12, /* bosubr_u */ + 16, /* bosubi_u */ + 12, /* bxsubr */ + 16, /* bxsubi */ + 12, /* bxsubr_u */ + 16, /* bxsubi_u */ + 8, /* jmpr */ + 4, /* jmpi */ + 12, /* callr */ + 36, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 124, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 28, /* addi_f */ + 4, /* subr_f */ + 28, /* subi_f */ + 28, /* rsbi_f */ + 4, /* mulr_f */ + 28, /* muli_f */ + 4, /* divr_f */ + 28, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 12, /* ltr_f */ + 36, /* lti_f */ + 16, /* ler_f */ + 40, /* lei_f */ + 12, /* eqr_f */ + 36, /* eqi_f */ + 16, /* ger_f */ + 40, /* gei_f */ + 12, /* gtr_f */ + 36, /* gti_f */ + 16, /* ner_f */ + 40, /* nei_f */ + 16, /* unltr_f */ + 40, /* unlti_f */ + 16, /* unler_f */ + 40, /* unlei_f */ + 16, /* uneqr_f */ + 40, /* uneqi_f */ + 16, /* unger_f */ + 40, /* ungei_f */ + 16, /* ungtr_f */ + 40, /* ungti_f */ + 16, /* ltgtr_f */ + 40, /* ltgti_f */ + 16, /* ordr_f */ + 40, /* ordi_f */ + 12, /* unordr_f */ + 36, /* unordi_f */ + 12, /* truncr_f_i */ + 12, /* truncr_f_l */ + 12, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 24, /* movi_f */ + 4, /* ldr_f */ + 24, /* ldi_f */ + 4, /* ldxr_f */ + 12, /* ldxi_f */ + 4, /* str_f */ + 24, /* sti_f */ + 4, /* stxr_f */ + 12, /* stxi_f */ + 8, /* bltr_f */ + 32, /* blti_f */ + 12, /* bler_f */ + 36, /* blei_f */ + 8, /* beqr_f */ + 32, /* beqi_f */ + 12, /* bger_f */ + 36, /* bgei_f */ + 8, /* bgtr_f */ + 32, /* bgti_f */ + 8, /* bner_f */ + 32, /* bnei_f */ + 12, /* bunltr_f */ + 36, /* bunlti_f */ + 8, /* bunler_f */ + 32, /* bunlei_f */ + 12, /* buneqr_f */ + 36, /* buneqi_f */ + 8, /* bunger_f */ + 32, /* bungei_f */ + 12, /* bungtr_f */ + 36, /* bungti_f */ + 12, /* bltgtr_f */ + 36, /* bltgti_f */ + 8, /* bordr_f */ + 32, /* bordi_f */ + 8, /* bunordr_f */ + 32, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 28, /* addi_d */ + 4, /* subr_d */ + 28, /* subi_d */ + 32, /* rsbi_d */ + 4, /* mulr_d */ + 28, /* muli_d */ + 4, /* divr_d */ + 28, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 12, /* ltr_d */ + 40, /* lti_d */ + 16, /* ler_d */ + 44, /* lei_d */ + 12, /* eqr_d */ + 40, /* eqi_d */ + 16, /* ger_d */ + 44, /* gei_d */ + 12, /* gtr_d */ + 40, /* gti_d */ + 16, /* ner_d */ + 44, /* nei_d */ + 16, /* unltr_d */ + 44, /* unlti_d */ + 16, /* unler_d */ + 44, /* unlei_d */ + 16, /* uneqr_d */ + 44, /* uneqi_d */ + 16, /* unger_d */ + 44, /* ungei_d */ + 16, /* ungtr_d */ + 44, /* ungti_d */ + 16, /* ltgtr_d */ + 44, /* ltgti_d */ + 16, /* ordr_d */ + 44, /* ordi_d */ + 12, /* unordr_d */ + 40, /* unordi_d */ + 12, /* truncr_d_i */ + 12, /* truncr_d_l */ + 12, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 32, /* movi_d */ + 4, /* ldr_d */ + 24, /* ldi_d */ + 4, /* ldxr_d */ + 12, /* ldxi_d */ + 4, /* str_d */ + 24, /* sti_d */ + 4, /* stxr_d */ + 12, /* stxi_d */ + 8, /* bltr_d */ + 32, /* blti_d */ + 12, /* bler_d */ + 36, /* blei_d */ + 8, /* beqr_d */ + 40, /* beqi_d */ + 12, /* bger_d */ + 40, /* bgei_d */ + 8, /* bgtr_d */ + 36, /* bgti_d */ + 8, /* bner_d */ + 36, /* bnei_d */ + 12, /* bunltr_d */ + 36, /* bunlti_d */ + 8, /* bunler_d */ + 32, /* bunlei_d */ + 12, /* buneqr_d */ + 36, /* buneqi_d */ + 8, /* bunger_d */ + 36, /* bungei_d */ + 12, /* bungtr_d */ + 40, /* bungti_d */ + 12, /* bltgtr_d */ + 40, /* bltgti_d */ + 8, /* bordr_d */ + 36, /* bordi_d */ + 8, /* bunordr_d */ + 32, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __BYTE_ORDER */ #endif /* __powerpc__ */ #endif /* __WORDSIZE */ diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c index 940dc06d4..a087ecb75 100644 --- a/lib/jit_ppc.c +++ b/lib/jit_ppc.c @@ -34,9 +34,7 @@ /* * Types */ -typedef struct jit_va_list { - jit_pointer_t stack; -} jit_va_list_t; +typedef jit_pointer_t jit_va_list_t; /* * Prototypes @@ -170,6 +168,10 @@ _jit_prolog(jit_state_t *_jit) jit_alloc((jit_pointer_t *)&_jitc->function->regoff, _jitc->reglen * sizeof(jit_int32_t)); + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); jit_link(_jitc->function->prolog); _jitc->function->prolog->w.w = offset; @@ -194,6 +196,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length) default: _jitc->function->self.aoff &= -8; break; } _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } return (_jitc->function->self.aoff); } @@ -202,6 +208,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) { jit_int32_t r0, r1; assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); if (!_jitc->function->allocar) { _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->allocar = 1; @@ -218,69 +225,82 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) jit_str(JIT_SP, r0); jit_unget_reg(r1); jit_unget_reg(r0); + jit_dec_synth(); } void _jit_ret(jit_state_t *_jit) { jit_node_t *instr; - assert(_jitc->function); - + jit_inc_synth(ret); /* jump to epilog */ instr = jit_jmpi(); jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); } void _jit_retr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr, u); if (JIT_RET != u) jit_movr(JIT_RET, u); else jit_live(JIT_RET); jit_ret(); + jit_dec_synth(); } void _jit_reti(jit_state_t *_jit, jit_word_t u) { + jit_inc_synth_w(reti, u); jit_movi(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_f, u); if (JIT_RET != u) jit_movr_f(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_f(jit_state_t *_jit, jit_float32_t u) { + jit_inc_synth_f(reti_f, u); jit_movi_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_d, u); if (JIT_FRET != u) jit_movr_d(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { + jit_inc_synth_d(reti_d, u); jit_movi_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void @@ -304,39 +324,45 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) void _jit_ellipsis(jit_state_t *_jit) { + jit_inc_synth(ellipsis); if (_jitc->prepare) { + jit_link_prepare(); assert(!(_jitc->function->call.call & jit_call_varargs)); _jitc->function->call.call |= jit_call_varargs; } else { + jit_link_prolog(); assert(!(_jitc->function->self.call & jit_call_varargs)); _jitc->function->self.call |= jit_call_varargs; - /* Allocate va_list like object in the stack. */ - _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t)); - _jitc->function->vagp = _jitc->function->self.argi; _jitc->function->vafp = _jitc->function->self.argf; } + jit_dec_synth(); } jit_node_t * _jit_arg(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; else offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); - return (jit_new_node_w(jit_code_arg, offset)); + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_f(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_f_reg_p(_jitc->function->self.argf)) offset = _jitc->function->self.argf++; @@ -350,13 +376,17 @@ _jit_arg_f(jit_state_t *_jit) #endif } _jitc->function->self.size += sizeof(jit_word_t); - return (jit_new_node_w(jit_code_arg_f, offset)); + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_d(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_f_reg_p(_jitc->function->self.argf)) offset = _jitc->function->self.argf++; @@ -370,53 +400,65 @@ _jit_arg_d(jit_state_t *_jit) #endif } _jitc->function->self.size += sizeof(jit_float64_t); - return (jit_new_node_w(jit_code_arg_d, offset)); + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_c(u, JIT_RA0 - v->u.w); else jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP); + jit_dec_synth(); } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_uc(u, JIT_RA0 - v->u.w); else jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP); + jit_dec_synth(); } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_s(u, JIT_RA0 - v->u.w); else jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP); + jit_dec_synth(); } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_us(u, JIT_RA0 - v->u.w); else jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP); + jit_dec_synth(); } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); if (jit_arg_reg_p(v->u.w)) { #if __WORDSIZE == 32 jit_movr(u, JIT_RA0 - v->u.w); @@ -426,6 +468,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) } else jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP); + jit_dec_synth(); } #if __WORDSIZE == 64 @@ -433,20 +476,24 @@ void _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_ui(u, JIT_RA0 - v->u.w); else jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP); + jit_dec_synth(); } void _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(u, JIT_RA0 - v->u.w); else jit_ldxi_l(u, JIT_FP, v->u.w); + jit_dec_synth(); } #endif @@ -454,16 +501,19 @@ void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(JIT_RA0 - v->u.w, u); else jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); } void _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; + jit_inc_synth_wp(putargi, u, v); assert(v->code == jit_code_arg); if (jit_arg_reg_p(v->u.w)) jit_movi(JIT_RA0 - v->u.w, u); @@ -473,26 +523,31 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) jit_stxi(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(u, JIT_FA0 - v->u.w); else jit_ldxi_f(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(JIT_FA0 - v->u.w, u); else jit_stxi_f(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -500,6 +555,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movi_d(JIT_FA0 - v->u.w, u); else { @@ -508,26 +564,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) jit_stxi_f(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(u, JIT_FA0 - v->u.w); else jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(JIT_FA0 - v->u.w, u); else jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -535,6 +596,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movi_d(JIT_FA0 - v->u.w, u); else { @@ -543,12 +605,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_stxi_d(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr(JIT_RA0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -556,6 +621,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) else jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); + jit_dec_synth(); } void @@ -563,6 +629,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(JIT_RA0 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -574,29 +642,35 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) jit_unget_reg(regno); } _jitc->function->call.size += sizeof(jit_word_t); + jit_dec_synth(); } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); - if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; - if (!(_jitc->function->call.call & jit_call_varargs)) { - /* in case of excess arguments */ - if (jit_arg_reg_p(_jitc->function->call.argi)) { + /* in case of excess arguments */ + if (jit_arg_reg_p(_jitc->function->call.argi)) { #if __WORDSIZE == 32 - _jitc->function->call.argi += 2; + _jitc->function->call.argi += 2; + if (!jit_arg_reg_p(_jitc->function->call.argi - 1)) + --_jitc->function->call.argi; #else - _jitc->function->call.argi++; + _jitc->function->call.argi++; #endif - } - _jitc->function->call.size += sizeof(jit_word_t); - return; } } - if (jit_arg_reg_p(_jitc->function->call.argi)) { + else if (jit_arg_reg_p(_jitc->function->call.argi +#if __WORDSIZE == 32 + + 1 +#endif + )) { /* use reserved 8 bytes area */ jit_stxi_d(alloca_offset - 8, JIT_FP, u); jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, @@ -612,72 +686,81 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); + jit_dec_synth(); } void _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; - assert(_jitc->function); - if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; - if (!(_jitc->function->call.call & jit_call_varargs)) { /* in case of excess arguments */ - if (jit_arg_reg_p(_jitc->function->call.argi)) { #if __WORDSIZE == 32 - _jitc->function->call.argi += 2; + _jitc->function->call.argi += 2; + if (!jit_arg_reg_p(_jitc->function->call.argi - 1)) + --_jitc->function->call.argi; #else - _jitc->function->call.argi++; -#endif - } - _jitc->function->call.size += sizeof(jit_word_t); - return; - } - } - regno = jit_get_reg(jit_class_fpr); - jit_movi_f(regno, u); - if (jit_arg_reg_p(_jitc->function->call.argi)) { - /* use reserved 8 bytes area */ - jit_stxi_d(alloca_offset - 8, JIT_FP, regno); - jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, - alloca_offset - 8); _jitc->function->call.argi++; +#endif + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + if (jit_arg_reg_p(_jitc->function->call.argi #if __WORDSIZE == 32 - jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, - alloca_offset - 4); - _jitc->function->call.argi++; + + 1 #endif + )) { + /* use reserved 8 bytes area */ + jit_stxi_d(alloca_offset - 8, JIT_FP, regno); + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 8); + _jitc->function->call.argi++; +#if __WORDSIZE == 32 + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 4); + _jitc->function->call.argi++; +#endif + } + else + jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP, + JIT_SP, regno); + jit_unget_reg(regno); } - else - jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP, - JIT_SP, regno); _jitc->function->call.size += sizeof(jit_word_t); - jit_unget_reg(regno); + jit_dec_synth(); } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); - if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; - if (!(_jitc->function->call.call & jit_call_varargs)) { /* in case of excess arguments */ - if (jit_arg_reg_p(_jitc->function->call.argi)) { #if __WORDSIZE == 32 - _jitc->function->call.argi += 2; + _jitc->function->call.argi += 2; + if (!jit_arg_reg_p(_jitc->function->call.argi - 1)) + --_jitc->function->call.argi; #else - _jitc->function->call.argi++; + _jitc->function->call.argi++; #endif - } - _jitc->function->call.size += sizeof(jit_float64_t); - return; - } } - if (jit_arg_reg_p(_jitc->function->call.argi)) { + else if (jit_arg_reg_p(_jitc->function->call.argi +#if __WORDSIZE == 32 + + 1 +#endif + )) { /* use reserved 8 bytes area */ jit_stxi_d(alloca_offset - 8, JIT_FP, u); jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, @@ -689,51 +772,76 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jitc->function->call.argi++; #endif } - else + else { jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u); +#if __WORDSIZE == 32 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_SP, + _jitc->function->call.size + params_offset); + _jitc->function->call.argi++; + } +#endif + } _jitc->function->call.size += sizeof(jit_float64_t); + jit_dec_synth(); } void _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; - assert(_jitc->function); - if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; - if (!(_jitc->function->call.call & jit_call_varargs)) { - /* in case of excess arguments */ - if (jit_arg_reg_p(_jitc->function->call.argi)) { + /* in case of excess arguments */ + if (jit_arg_reg_p(_jitc->function->call.argi)) { #if __WORDSIZE == 32 - _jitc->function->call.argi += 2; + _jitc->function->call.argi += 2; + if (!jit_arg_reg_p(_jitc->function->call.argi - 1)) + --_jitc->function->call.argi; #else - _jitc->function->call.argi++; + _jitc->function->call.argi++; #endif - } - _jitc->function->call.size += sizeof(jit_float64_t); - return; } } - regno = jit_get_reg(jit_class_fpr); - jit_movi_d(regno, u); - if (jit_arg_reg_p(_jitc->function->call.argi)) { - /* use reserved 8 bytes area */ - jit_stxi_d(alloca_offset - 8, JIT_FP, regno); - jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, - alloca_offset - 8); - _jitc->function->call.argi++; + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + if (jit_arg_reg_p(_jitc->function->call.argi #if __WORDSIZE == 32 - jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, - alloca_offset - 4); - _jitc->function->call.argi++; + + 1 #endif + )) { + /* use reserved 8 bytes area */ + jit_stxi_d(alloca_offset - 8, JIT_FP, regno); + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 8); + _jitc->function->call.argi++; +#if __WORDSIZE == 32 + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 4); + _jitc->function->call.argi++; +#endif + } + else { + jit_stxi_d(_jitc->function->call.size + params_offset, + JIT_SP, regno); +#if __WORDSIZE == 32 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_SP, + _jitc->function->call.size + params_offset); + _jitc->function->call.argi++; + } +#endif + } + jit_unget_reg(regno); } - else - jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno); _jitc->function->call.size += sizeof(jit_float64_t); - jit_unget_reg(regno); + jit_dec_synth(); } jit_bool_t @@ -761,6 +869,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_node_t *call; assert(_jitc->function); + jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; call = jit_callr(r0); @@ -768,6 +877,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) call->w.w = _jitc->function->call.argf; _jitc->function->call.argi = _jitc->function->call.argf = 0; _jitc->prepare = 0; + jit_dec_synth(); } jit_node_t * @@ -775,6 +885,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) { jit_node_t *node; assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; node = jit_calli(i0); @@ -782,70 +893,89 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) node->w.w = _jitc->function->call.argf; _jitc->function->call.argi = _jitc->function->call.argf = 0; _jitc->prepare = 0; + jit_dec_synth(); return (node); } void _jit_retval_c(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth(retval_c); jit_extr_c(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth(retval_uc); jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_s(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth(retval_s); jit_extr_s(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_us(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth(retval_us); jit_extr_us(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_i(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth(retval_i); #if __WORDSIZE == 32 if (r0 != JIT_RET) jit_movr(r0, JIT_RET); #else jit_extr_i(r0, JIT_RET); #endif + jit_dec_synth(); } #if __WORDSIZE == 64 void _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth(retval_ui); jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_l(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth(retval_l); if (r0 != JIT_RET) jit_movr(r0, JIT_RET); + jit_dec_synth(); } #endif void _jit_retval_f(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth(retval_f); jit_retval_d(r0); + jit_dec_synth(); } void _jit_retval_d(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth(retval_d); if (r0 != JIT_FRET) jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); } jit_pointer_t @@ -859,11 +989,17 @@ _emit_code(jit_state_t *_jit) struct { jit_node_t *node; jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif jit_word_t patch_offset; #if __powerpc__ jit_word_t prolog_offset; #endif } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif _jitc->function = NULL; @@ -873,6 +1009,9 @@ _emit_code(jit_state_t *_jit) undo.node = NULL; undo.patch_offset = 0; +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif #if __powerpc__ && !ABI_ELFv2 undo.prolog_offset = 0; for (node = _jitc->head; node; node = node->next) @@ -978,7 +1117,8 @@ _emit_code(jit_state_t *_jit) return (NULL); #if DEVEL_DISASSEMBLER - node->offset = _jit->pc.w; + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; #endif value = jit_classify(node->code); jit_regarg_set(node, value); @@ -1395,6 +1535,9 @@ _emit_code(jit_state_t *_jit) _jitc->function = _jitc->functions.ptr + node->w.w; undo.node = node; undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif undo.patch_offset = _jitc->patches.offset; #if __powerpc__ && !ABI_ELFv2 undo.prolog_offset = _jitc->prolog.offset; @@ -1435,6 +1578,9 @@ _emit_code(jit_state_t *_jit) temp->flag &= ~jit_flag_patch; node = undo.node; _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif _jitc->patches.offset = undo.patch_offset; #if __powerpc__ && !ABI_ELFv2 _jitc->prolog.offset = undo.prolog_offset; @@ -1457,15 +1603,42 @@ _emit_code(jit_state_t *_jit) vaarg_d(rn(node->u.w), rn(node->v.w)); break; case jit_code_live: - case jit_code_arg: + case jit_code_arg: case jit_code_ellipsis: + case jit_code_allocai: case jit_code_allocar: case jit_code_arg_f: case jit_code_arg_d: case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: +#if __WORDSIZE == 64 + case jit_code_getarg_ui: case jit_code_getarg_l: +#endif + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: +#if __WORDSIZE == 64 + case jit_code_retval_ui: case jit_code_retval_l: +#endif + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: break; default: abort(); } jit_regarg_clr(node, value); - assert(_jitc->regarg == 0); + assert(_jitc->regarg == 0 && _jitc->synth == 0); /* update register live state */ jit_reglive(node); } diff --git a/lib/jit_print.c b/lib/jit_print.c index a95499c49..1820e38ce 100644 --- a/lib/jit_print.c +++ b/lib/jit_print.c @@ -32,6 +32,14 @@ print_chr('?'); \ print_str(_rvs[jit_regno(value)].name); \ } while (0) +#define print_arg(value) \ + do { \ + print_chr('#'); \ + if (value) \ + print_dec((value)->v.w); \ + else \ + print_chr('?'); \ + } while (0) /* * Initialization @@ -84,19 +92,38 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node) return; } value = jit_classify(node->code) & - (jit_cc_a0_int|jit_cc_a0_jmp|jit_cc_a0_reg|jit_cc_a0_rlh| - jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl| + (jit_cc_a0_int|jit_cc_a0_flt|jit_cc_a0_dbl|jit_cc_a0_jmp| + jit_cc_a0_reg|jit_cc_a0_rlh|jit_cc_a0_arg| + jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl|jit_cc_a1_arg| jit_cc_a2_reg|jit_cc_a2_int|jit_cc_a2_flt|jit_cc_a2_dbl); - if (value & jit_cc_a0_jmp) + if (!(node->flag & jit_flag_synth) && ((value & jit_cc_a0_jmp) || + node->code == jit_code_finishr || + node->code == jit_code_finishi)) print_str(" "); else print_chr('\t'); + if (node->flag & jit_flag_synth) + print_str(" \\__ "); print_str(code_name[node->code]); switch (node->code) { r: print_chr(' '); print_reg(node->u.w); return; w: print_chr(' '); print_hex(node->u.w); return; + f: + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float32_t *)node->u.n->u.w); + else + print_flt(node->u.f); + return; + d: + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float64_t *)node->u.n->u.w); + else + print_flt(node->u.d); + return; n: print_chr(' '); if (!(node->flag & jit_flag_node)) @@ -106,6 +133,8 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node) print_dec(node->u.n->v.w); } return; + a: + print_chr(' '); print_arg(node); return; r_r: print_chr(' '); print_reg(node->u.w); print_chr(' '); print_reg(node->v.w); return; @@ -128,9 +157,36 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node) else print_flt(node->v.d); return; + r_a: + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_arg(node->v.n); + return; w_r: print_chr(' '); print_hex(node->u.w); print_chr(' '); print_reg(node->v.w); return; + w_w: + print_chr(' '); print_hex(node->u.w); + print_chr(' '); print_hex(node->v.w); return; + w_a: + print_chr(' '); print_hex(node->u.w); + print_chr(' '); print_arg(node->v.n); + return; + f_a: + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float32_t *)node->u.n->u.w); + else + print_flt(node->u.f); + print_chr(' '); print_arg(node->v.n); + return; + d_a: + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float64_t *)node->u.n->u.w); + else + print_flt(node->u.d); + print_chr(' '); print_arg(node->v.n); + return; r_r_r: print_chr(' '); print_reg(node->u.w); print_chr(' '); print_reg(node->v.w); @@ -237,7 +293,9 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node) break; case jit_code_data: case jit_code_label: + case jit_code_ellipsis: case jit_code_prolog: case jit_code_epilog: + case jit_code_ret: case jit_code_prepare: break; case jit_code_save: case jit_code_load: goto r; @@ -249,8 +307,14 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node) goto r; case jit_cc_a0_int: goto w; + case jit_cc_a0_flt: + goto f; + case jit_cc_a0_dbl: + goto d; case jit_cc_a0_jmp: goto n; + case jit_cc_a0_int|jit_cc_a0_arg: + goto a; case jit_cc_a0_reg|jit_cc_a1_reg: goto r_r; case jit_cc_a0_reg|jit_cc_a1_int: @@ -259,8 +323,18 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node) goto r_f; case jit_cc_a0_reg|jit_cc_a1_dbl: goto r_d; + case jit_cc_a0_reg|jit_cc_a1_arg: + goto r_a; case jit_cc_a0_int|jit_cc_a1_reg: goto w_r; + case jit_cc_a0_int|jit_cc_a1_int: + goto w_w; + case jit_cc_a0_int|jit_cc_a1_arg: + goto w_a; + case jit_cc_a0_flt|jit_cc_a1_arg: + goto f_a; + case jit_cc_a0_dbl|jit_cc_a1_arg: + goto d_a; case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_reg: goto r_r_r; case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_int: diff --git a/lib/jit_rewind.c b/lib/jit_rewind.c new file mode 100644 index 000000000..f796d0fad --- /dev/null +++ b/lib/jit_rewind.c @@ -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 +#include + +#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 diff --git a/lib/jit_s390-fpu.c b/lib/jit_s390-fpu.c index b84aa4cbd..b887fa22d 100644 --- a/lib/jit_s390-fpu.c +++ b/lib/jit_s390-fpu.c @@ -1287,7 +1287,7 @@ _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) /* Update the fp offset. */ addi(rn(rg0), rn(rg0), 1); - stxi(offsetof(jit_va_list_t, gpoff), r1, rn(rg0)); + stxi(offsetof(jit_va_list_t, fpoff), r1, rn(rg0)); /* Will only need one temporary register below. */ jit_unget_reg_but_zero(rg1); @@ -1305,7 +1305,7 @@ _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) ldr_d(r0, rn(rg0)); /* Update overflow pointer. */ - addi(rn(rg0), rn(rg0), sizeof(jit_word_t)); + addi(rn(rg0), rn(rg0), sizeof(jit_float64_t)); stxi(offsetof(jit_va_list_t, over), r1, rn(rg0)); /* Where to land if argument is in save area. */ diff --git a/lib/jit_s390-sz.c b/lib/jit_s390-sz.c index 6ca5e64c8..d1d8861c7 100644 --- a/lib/jit_s390-sz.c +++ b/lib/jit_s390-sz.c @@ -1,366 +1,6 @@ #if __WORDSIZE == 32 -#define JIT_INSTR_MAX 50 - 0, /* data */ - 0, /* live */ - 2, /* align */ - 0, /* save */ - 0, /* load */ - 0, /* #name */ - 0, /* #note */ - 2, /* label */ - 38, /* prolog */ - 0, /* arg */ - 0, /* va_start */ - 0, /* va_arg */ - 0, /* va_arg_d */ - 0, /* va_end */ - 4, /* addr */ - 12, /* addi */ - 4, /* addcr */ - 10, /* addci */ - 6, /* addxr */ - 10, /* addxi */ - 6, /* subr */ - 12, /* subi */ - 6, /* subcr */ - 10, /* subci */ - 8, /* subxr */ - 10, /* subxi */ - 14, /* rsbi */ - 6, /* mulr */ - 14, /* muli */ - 46, /* qmulr */ - 50, /* qmuli */ - 10, /* qmulr_u */ - 18, /* qmuli_u */ - 10, /* divr */ - 18, /* divi */ - 16, /* divr_u */ - 24, /* divi_u */ - 12, /* qdivr */ - 16, /* qdivi */ - 18, /* qdivr_u */ - 22, /* qdivi_u */ - 10, /* remr */ - 18, /* remi */ - 16, /* remr_u */ - 24, /* remi_u */ - 4, /* andr */ - 10, /* andi */ - 4, /* orr */ - 10, /* ori */ - 4, /* xorr */ - 12, /* xori */ - 8, /* lshr */ - 10, /* lshi */ - 8, /* rshr */ - 10, /* rshi */ - 8, /* rshr_u */ - 10, /* rshi_u */ - 2, /* negr */ - 8, /* comr */ - 16, /* ltr */ - 20, /* lti */ - 16, /* ltr_u */ - 20, /* lti_u */ - 16, /* ler */ - 20, /* lei */ - 16, /* ler_u */ - 20, /* lei_u */ - 16, /* eqr */ - 20, /* eqi */ - 16, /* ger */ - 20, /* gei */ - 16, /* ger_u */ - 20, /* gei_u */ - 16, /* gtr */ - 20, /* gti */ - 16, /* gtr_u */ - 20, /* gti_u */ - 16, /* ner */ - 20, /* nei */ - 2, /* movr */ - 8, /* movi */ - 4, /* extr_c */ - 4, /* extr_uc */ - 4, /* extr_s */ - 4, /* extr_us */ - 0, /* extr_i */ - 0, /* extr_ui */ - 4, /* htonr_us */ - 2, /* htonr_ui */ - 0, /* htonr_ul */ - 6, /* ldr_c */ - 12, /* ldi_c */ - 6, /* ldr_uc */ - 14, /* ldi_uc */ - 6, /* ldr_s */ - 12, /* ldi_s */ - 6, /* ldr_us */ - 12, /* ldi_us */ - 6, /* ldr_i */ - 12, /* ldi_i */ - 0, /* ldr_ui */ - 0, /* ldi_ui */ - 0, /* ldr_l */ - 0, /* ldi_l */ - 10, /* ldxr_c */ - 16, /* ldxi_c */ - 10, /* ldxr_uc */ - 16, /* ldxi_uc */ - 10, /* ldxr_s */ - 16, /* ldxi_s */ - 10, /* ldxr_us */ - 16, /* ldxi_us */ - 10, /* ldxr_i */ - 16, /* ldxi_i */ - 0, /* ldxr_ui */ - 0, /* ldxi_ui */ - 0, /* ldxr_l */ - 0, /* ldxi_l */ - 4, /* str_c */ - 12, /* sti_c */ - 4, /* str_s */ - 10, /* sti_s */ - 4, /* str_i */ - 10, /* sti_i */ - 0, /* str_l */ - 0, /* sti_l */ - 8, /* stxr_c */ - 16, /* stxi_c */ - 8, /* stxr_s */ - 16, /* stxi_s */ - 8, /* stxr_i */ - 16, /* stxi_i */ - 0, /* stxr_l */ - 0, /* stxi_l */ - 8, /* bltr */ - 12, /* blti */ - 8, /* bltr_u */ - 12, /* blti_u */ - 8, /* bler */ - 12, /* blei */ - 8, /* bler_u */ - 12, /* blei_u */ - 8, /* beqr */ - 16, /* beqi */ - 8, /* bger */ - 12, /* bgei */ - 8, /* bger_u */ - 12, /* bgei_u */ - 8, /* bgtr */ - 12, /* bgti */ - 8, /* bgtr_u */ - 12, /* bgti_u */ - 8, /* bner */ - 16, /* bnei */ - 12, /* bmsr */ - 14, /* bmsi */ - 12, /* bmcr */ - 14, /* bmci */ - 8, /* boaddr */ - 12, /* boaddi */ - 8, /* boaddr_u */ - 12, /* boaddi_u */ - 8, /* bxaddr */ - 12, /* bxaddi */ - 8, /* bxaddr_u */ - 12, /* bxaddi_u */ - 8, /* bosubr */ - 12, /* bosubi */ - 8, /* bosubr_u */ - 12, /* bosubi_u */ - 8, /* bxsubr */ - 12, /* bxsubi */ - 8, /* bxsubr_u */ - 12, /* bxsubi_u */ - 2, /* jmpr */ - 10, /* jmpi */ - 2, /* callr */ - 10, /* calli */ - 36, /* epilog */ - 0, /* arg_f */ - 6, /* addr_f */ - 24, /* addi_f */ - 8, /* subr_f */ - 24, /* subi_f */ - 28, /* rsbi_f */ - 6, /* mulr_f */ - 24, /* muli_f */ - 8, /* divr_f */ - 24, /* divi_f */ - 4, /* negr_f */ - 4, /* absr_f */ - 4, /* sqrtr_f */ - 16, /* ltr_f */ - 36, /* lti_f */ - 16, /* ler_f */ - 36, /* lei_f */ - 16, /* eqr_f */ - 36, /* eqi_f */ - 16, /* ger_f */ - 36, /* gei_f */ - 16, /* gtr_f */ - 36, /* gti_f */ - 16, /* ner_f */ - 36, /* nei_f */ - 16, /* unltr_f */ - 36, /* unlti_f */ - 16, /* unler_f */ - 36, /* unlei_f */ - 20, /* uneqr_f */ - 40, /* uneqi_f */ - 16, /* unger_f */ - 36, /* ungei_f */ - 16, /* ungtr_f */ - 36, /* ungti_f */ - 20, /* ltgtr_f */ - 40, /* ltgti_f */ - 16, /* ordr_f */ - 36, /* ordi_f */ - 16, /* unordr_f */ - 36, /* unordi_f */ - 4, /* truncr_f_i */ - 0, /* truncr_f_l */ - 4, /* extr_f */ - 4, /* extr_d_f */ - 2, /* movr_f */ - 20, /* movi_f */ - 4, /* ldr_f */ - 10, /* ldi_f */ - 8, /* ldxr_f */ - 14, /* ldxi_f */ - 4, /* str_f */ - 10, /* sti_f */ - 8, /* stxr_f */ - 14, /* stxi_f */ - 10, /* bltr_f */ - 28, /* blti_f */ - 10, /* bler_f */ - 30, /* blei_f */ - 10, /* beqr_f */ - 30, /* beqi_f */ - 10, /* bger_f */ - 30, /* bgei_f */ - 10, /* bgtr_f */ - 30, /* bgti_f */ - 10, /* bner_f */ - 30, /* bnei_f */ - 10, /* bunltr_f */ - 28, /* bunlti_f */ - 10, /* bunler_f */ - 28, /* bunlei_f */ - 18, /* buneqr_f */ - 36, /* buneqi_f */ - 10, /* bunger_f */ - 30, /* bungei_f */ - 10, /* bungtr_f */ - 30, /* bungti_f */ - 18, /* bltgtr_f */ - 38, /* bltgti_f */ - 10, /* bordr_f */ - 30, /* bordi_f */ - 10, /* bunordr_f */ - 28, /* bunordi_f */ - 0, /* arg_d */ - 6, /* addr_d */ - 34, /* addi_d */ - 8, /* subr_d */ - 34, /* subi_d */ - 38, /* rsbi_d */ - 6, /* mulr_d */ - 34, /* muli_d */ - 8, /* divr_d */ - 34, /* divi_d */ - 4, /* negr_d */ - 4, /* absr_d */ - 4, /* sqrtr_d */ - 16, /* ltr_d */ - 46, /* lti_d */ - 16, /* ler_d */ - 46, /* lei_d */ - 16, /* eqr_d */ - 46, /* eqi_d */ - 16, /* ger_d */ - 46, /* gei_d */ - 16, /* gtr_d */ - 46, /* gti_d */ - 16, /* ner_d */ - 46, /* nei_d */ - 16, /* unltr_d */ - 46, /* unlti_d */ - 16, /* unler_d */ - 46, /* unlei_d */ - 20, /* uneqr_d */ - 50, /* uneqi_d */ - 16, /* unger_d */ - 46, /* ungei_d */ - 16, /* ungtr_d */ - 46, /* ungti_d */ - 20, /* ltgtr_d */ - 50, /* ltgti_d */ - 16, /* ordr_d */ - 46, /* ordi_d */ - 16, /* unordr_d */ - 46, /* unordi_d */ - 4, /* truncr_d_i */ - 0, /* truncr_d_l */ - 4, /* extr_d */ - 4, /* extr_f_d */ - 2, /* movr_d */ - 30, /* movi_d */ - 4, /* ldr_d */ - 10, /* ldi_d */ - 8, /* ldxr_d */ - 14, /* ldxi_d */ - 4, /* str_d */ - 10, /* sti_d */ - 8, /* stxr_d */ - 14, /* stxi_d */ - 10, /* bltr_d */ - 38, /* blti_d */ - 10, /* bler_d */ - 38, /* blei_d */ - 10, /* beqr_d */ - 40, /* beqi_d */ - 10, /* bger_d */ - 40, /* bgei_d */ - 10, /* bgtr_d */ - 40, /* bgti_d */ - 10, /* bner_d */ - 40, /* bnei_d */ - 10, /* bunltr_d */ - 38, /* bunlti_d */ - 10, /* bunler_d */ - 38, /* bunlei_d */ - 18, /* buneqr_d */ - 46, /* buneqi_d */ - 10, /* bunger_d */ - 40, /* bungei_d */ - 10, /* bungtr_d */ - 40, /* bungti_d */ - 18, /* bltgtr_d */ - 48, /* bltgti_d */ - 10, /* bordr_d */ - 40, /* bordi_d */ - 10, /* bunordr_d */ - 38, /* bunordi_d */ - 0, /* movr_w_f */ - 0, /* movr_ww_d */ - 0, /* movr_w_d */ - 0, /* movr_f_w */ - 0, /* movi_f_w */ - 0, /* movr_d_ww */ - 0, /* movi_d_ww */ - 0, /* movr_d_w */ - 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ -#endif /* __WORDSIZE */ - -#if __WORDSIZE == 64 -#define JIT_INSTR_MAX 68 +#define JIT_INSTR_MAX 104 0, /* data */ 0, /* live */ 6, /* align */ @@ -369,11 +9,23 @@ 0, /* #name */ 0, /* #note */ 2, /* label */ - 38, /* prolog */ + 42, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ - 0, /* va_start */ - 0, /* va_arg */ - 0, /* va_arg_d */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 44, /* va_start */ + 104, /* va_arg */ + 100, /* va_arg_d */ 0, /* va_end */ 8, /* addr */ 24, /* addi */ @@ -466,19 +118,19 @@ 6, /* ldr_l */ 18, /* ldi_l */ 14, /* ldxr_c */ - 6, /* ldxi_c */ + 26, /* ldxi_c */ 14, /* ldxr_uc */ - 6, /* ldxi_uc */ + 26, /* ldxi_uc */ 14, /* ldxr_s */ - 6, /* ldxi_s */ + 26, /* ldxi_s */ 14, /* ldxr_us */ - 6, /* ldxi_us */ + 26, /* ldxi_us */ 14, /* ldxr_i */ - 6, /* ldxi_i */ + 26, /* ldxi_i */ 14, /* ldxr_ui */ - 6, /* ldxi_ui */ + 26, /* ldxi_ui */ 14, /* ldxr_l */ - 6, /* ldxi_l */ + 26, /* ldxi_l */ 4, /* str_c */ 16, /* sti_c */ 4, /* str_s */ @@ -488,13 +140,13 @@ 6, /* str_l */ 18, /* sti_l */ 12, /* stxr_c */ - 4, /* stxi_c */ + 28, /* stxi_c */ 12, /* stxr_s */ - 4, /* stxi_s */ + 28, /* stxi_s */ 12, /* stxr_i */ - 6, /* stxi_i */ + 28, /* stxi_i */ 14, /* stxr_l */ - 6, /* stxi_l */ + 30, /* stxi_l */ 10, /* bltr */ 14, /* blti */ 10, /* bltr_u */ @@ -535,17 +187,35 @@ 14, /* bxsubi */ 10, /* bxsubr_u */ 14, /* bxsubi_u */ - 0, /* jmpr */ + 2, /* jmpr */ 18, /* jmpi */ 2, /* callr */ 18, /* calli */ - 36, /* epilog */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 40, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 6, /* addr_f */ 26, /* addi_f */ 8, /* subr_f */ 26, /* subi_f */ - 26, /* rsbi_f */ + 28, /* rsbi_f */ 6, /* mulr_f */ 26, /* muli_f */ 8, /* divr_f */ @@ -590,11 +260,11 @@ 4, /* ldr_f */ 16, /* ldi_f */ 12, /* ldxr_f */ - 4, /* ldxi_f */ + 24, /* ldxi_f */ 4, /* str_f */ 16, /* sti_f */ 12, /* stxr_f */ - 4, /* stxi_f */ + 24, /* stxi_f */ 10, /* bltr_f */ 30, /* blti_f */ 10, /* bler_f */ @@ -623,12 +293,20 @@ 30, /* bordi_f */ 10, /* bunordr_f */ 30, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 6, /* addr_d */ 26, /* addi_d */ 8, /* subr_d */ 26, /* subi_d */ - 26, /* rsbi_d */ + 28, /* rsbi_d */ 6, /* mulr_d */ 26, /* muli_d */ 8, /* divr_d */ @@ -673,11 +351,11 @@ 4, /* ldr_d */ 16, /* ldi_d */ 12, /* ldxr_d */ - 4, /* ldxi_d */ + 24, /* ldxi_d */ 4, /* str_d */ 16, /* sti_d */ 12, /* stxr_d */ - 4, /* stxi_d */ + 24, /* stxi_d */ 10, /* bltr_d */ 30, /* blti_d */ 10, /* bler_d */ @@ -706,6 +384,412 @@ 30, /* bordi_d */ 10, /* bunordr_d */ 30, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __WORDSIZE */ + +#if __WORDSIZE == 64 +#define JIT_INSTR_MAX 104 + 0, /* data */ + 0, /* live */ + 6, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 2, /* label */ + 42, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 44, /* va_start */ + 104, /* va_arg */ + 100, /* va_arg_d */ + 0, /* va_end */ + 8, /* addr */ + 24, /* addi */ + 8, /* addcr */ + 20, /* addci */ + 8, /* addxr */ + 12, /* addxi */ + 12, /* subr */ + 24, /* subi */ + 12, /* subcr */ + 20, /* subci */ + 12, /* subxr */ + 12, /* subxi */ + 28, /* rsbi */ + 8, /* mulr */ + 24, /* muli */ + 60, /* qmulr */ + 68, /* qmuli */ + 16, /* qmulr_u */ + 32, /* qmuli_u */ + 12, /* divr */ + 28, /* divi */ + 16, /* divr_u */ + 32, /* divi_u */ + 16, /* qdivr */ + 20, /* qdivi */ + 20, /* qdivr_u */ + 24, /* qdivi_u */ + 12, /* remr */ + 28, /* remi */ + 16, /* remr_u */ + 32, /* remi_u */ + 8, /* andr */ + 20, /* andi */ + 8, /* orr */ + 20, /* ori */ + 8, /* xorr */ + 24, /* xori */ + 6, /* lshr */ + 10, /* lshi */ + 6, /* rshr */ + 10, /* rshi */ + 6, /* rshr_u */ + 10, /* rshi_u */ + 4, /* negr */ + 12, /* comr */ + 20, /* ltr */ + 24, /* lti */ + 20, /* ltr_u */ + 24, /* lti_u */ + 20, /* ler */ + 24, /* lei */ + 20, /* ler_u */ + 24, /* lei_u */ + 20, /* eqr */ + 24, /* eqi */ + 20, /* ger */ + 24, /* gei */ + 20, /* ger_u */ + 24, /* gei_u */ + 20, /* gtr */ + 24, /* gti */ + 20, /* gtr_u */ + 24, /* gti_u */ + 20, /* ner */ + 24, /* nei */ + 4, /* movr */ + 16, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 4, /* extr_i */ + 4, /* extr_ui */ + 4, /* htonr_us */ + 4, /* htonr_ui */ + 4, /* htonr_ul */ + 6, /* ldr_c */ + 18, /* ldi_c */ + 6, /* ldr_uc */ + 18, /* ldi_uc */ + 6, /* ldr_s */ + 18, /* ldi_s */ + 6, /* ldr_us */ + 18, /* ldi_us */ + 6, /* ldr_i */ + 18, /* ldi_i */ + 6, /* ldr_ui */ + 18, /* ldi_ui */ + 6, /* ldr_l */ + 18, /* ldi_l */ + 14, /* ldxr_c */ + 26, /* ldxi_c */ + 14, /* ldxr_uc */ + 26, /* ldxi_uc */ + 14, /* ldxr_s */ + 26, /* ldxi_s */ + 14, /* ldxr_us */ + 26, /* ldxi_us */ + 14, /* ldxr_i */ + 26, /* ldxi_i */ + 14, /* ldxr_ui */ + 26, /* ldxi_ui */ + 14, /* ldxr_l */ + 26, /* ldxi_l */ + 4, /* str_c */ + 16, /* sti_c */ + 4, /* str_s */ + 16, /* sti_s */ + 4, /* str_i */ + 16, /* sti_i */ + 6, /* str_l */ + 18, /* sti_l */ + 12, /* stxr_c */ + 28, /* stxi_c */ + 12, /* stxr_s */ + 28, /* stxi_s */ + 12, /* stxr_i */ + 28, /* stxi_i */ + 14, /* stxr_l */ + 30, /* stxi_l */ + 10, /* bltr */ + 14, /* blti */ + 10, /* bltr_u */ + 14, /* blti_u */ + 10, /* bler */ + 14, /* blei */ + 10, /* bler_u */ + 14, /* blei_u */ + 10, /* beqr */ + 26, /* beqi */ + 10, /* bger */ + 14, /* bgei */ + 10, /* bger_u */ + 14, /* bgei_u */ + 10, /* bgtr */ + 14, /* bgti */ + 10, /* bgtr_u */ + 14, /* bgti_u */ + 10, /* bner */ + 26, /* bnei */ + 18, /* bmsr */ + 18, /* bmsi */ + 18, /* bmcr */ + 18, /* bmci */ + 10, /* boaddr */ + 14, /* boaddi */ + 10, /* boaddr_u */ + 14, /* boaddi_u */ + 10, /* bxaddr */ + 14, /* bxaddi */ + 10, /* bxaddr_u */ + 14, /* bxaddi_u */ + 10, /* bosubr */ + 14, /* bosubi */ + 10, /* bosubr_u */ + 14, /* bosubi_u */ + 10, /* bxsubr */ + 14, /* bxsubi */ + 10, /* bxsubr_u */ + 14, /* bxsubi_u */ + 2, /* jmpr */ + 18, /* jmpi */ + 2, /* callr */ + 18, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 40, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 6, /* addr_f */ + 26, /* addi_f */ + 8, /* subr_f */ + 26, /* subi_f */ + 28, /* rsbi_f */ + 6, /* mulr_f */ + 26, /* muli_f */ + 8, /* divr_f */ + 26, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 16, /* ltr_f */ + 36, /* lti_f */ + 16, /* ler_f */ + 36, /* lei_f */ + 16, /* eqr_f */ + 36, /* eqi_f */ + 16, /* ger_f */ + 36, /* gei_f */ + 16, /* gtr_f */ + 36, /* gti_f */ + 16, /* ner_f */ + 36, /* nei_f */ + 16, /* unltr_f */ + 36, /* unlti_f */ + 16, /* unler_f */ + 36, /* unlei_f */ + 20, /* uneqr_f */ + 40, /* uneqi_f */ + 16, /* unger_f */ + 36, /* ungei_f */ + 16, /* ungtr_f */ + 36, /* ungti_f */ + 20, /* ltgtr_f */ + 40, /* ltgti_f */ + 16, /* ordr_f */ + 36, /* ordi_f */ + 16, /* unordr_f */ + 36, /* unordi_f */ + 4, /* truncr_f_i */ + 4, /* truncr_f_l */ + 4, /* extr_f */ + 4, /* extr_d_f */ + 2, /* movr_f */ + 20, /* movi_f */ + 4, /* ldr_f */ + 16, /* ldi_f */ + 12, /* ldxr_f */ + 24, /* ldxi_f */ + 4, /* str_f */ + 16, /* sti_f */ + 12, /* stxr_f */ + 24, /* stxi_f */ + 10, /* bltr_f */ + 30, /* blti_f */ + 10, /* bler_f */ + 30, /* blei_f */ + 10, /* beqr_f */ + 30, /* beqi_f */ + 10, /* bger_f */ + 30, /* bgei_f */ + 10, /* bgtr_f */ + 30, /* bgti_f */ + 10, /* bner_f */ + 30, /* bnei_f */ + 10, /* bunltr_f */ + 30, /* bunlti_f */ + 10, /* bunler_f */ + 30, /* bunlei_f */ + 18, /* buneqr_f */ + 38, /* buneqi_f */ + 10, /* bunger_f */ + 30, /* bungei_f */ + 10, /* bungtr_f */ + 30, /* bungti_f */ + 18, /* bltgtr_f */ + 38, /* bltgti_f */ + 10, /* bordr_f */ + 30, /* bordi_f */ + 10, /* bunordr_f */ + 30, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 6, /* addr_d */ + 26, /* addi_d */ + 8, /* subr_d */ + 26, /* subi_d */ + 28, /* rsbi_d */ + 6, /* mulr_d */ + 26, /* muli_d */ + 8, /* divr_d */ + 26, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 16, /* ltr_d */ + 36, /* lti_d */ + 16, /* ler_d */ + 36, /* lei_d */ + 16, /* eqr_d */ + 36, /* eqi_d */ + 16, /* ger_d */ + 36, /* gei_d */ + 16, /* gtr_d */ + 36, /* gti_d */ + 16, /* ner_d */ + 36, /* nei_d */ + 16, /* unltr_d */ + 36, /* unlti_d */ + 16, /* unler_d */ + 36, /* unlei_d */ + 20, /* uneqr_d */ + 40, /* uneqi_d */ + 16, /* unger_d */ + 36, /* ungei_d */ + 16, /* ungtr_d */ + 36, /* ungti_d */ + 20, /* ltgtr_d */ + 40, /* ltgti_d */ + 16, /* ordr_d */ + 36, /* ordi_d */ + 16, /* unordr_d */ + 36, /* unordi_d */ + 4, /* truncr_d_i */ + 4, /* truncr_d_l */ + 4, /* extr_d */ + 4, /* extr_f_d */ + 2, /* movr_d */ + 24, /* movi_d */ + 4, /* ldr_d */ + 16, /* ldi_d */ + 12, /* ldxr_d */ + 24, /* ldxi_d */ + 4, /* str_d */ + 16, /* sti_d */ + 12, /* stxr_d */ + 24, /* stxi_d */ + 10, /* bltr_d */ + 30, /* blti_d */ + 10, /* bler_d */ + 30, /* blei_d */ + 10, /* beqr_d */ + 34, /* beqi_d */ + 10, /* bger_d */ + 30, /* bgei_d */ + 10, /* bgtr_d */ + 30, /* bgti_d */ + 10, /* bner_d */ + 30, /* bnei_d */ + 10, /* bunltr_d */ + 30, /* bunlti_d */ + 10, /* bunler_d */ + 30, /* bunlei_d */ + 18, /* buneqr_d */ + 38, /* buneqi_d */ + 10, /* bunger_d */ + 30, /* bungei_d */ + 10, /* bungtr_d */ + 30, /* bungti_d */ + 18, /* bltgtr_d */ + 38, /* bltgti_d */ + 10, /* bordr_d */ + 30, /* bordi_d */ + 10, /* bunordr_d */ + 30, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -715,6 +799,4 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __WORDSIZE */ diff --git a/lib/jit_s390.c b/lib/jit_s390.c index 1f59745ce..c853aac9f 100644 --- a/lib/jit_s390.c +++ b/lib/jit_s390.c @@ -171,6 +171,10 @@ _jit_prolog(jit_state_t *_jit) jit_alloc((jit_pointer_t *)&_jitc->function->regoff, _jitc->reglen * sizeof(jit_int32_t)); + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); jit_link(_jitc->function->prolog); _jitc->function->prolog->w.w = offset; @@ -195,6 +199,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length) default: _jitc->function->self.aoff &= -8; break; } _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } return (_jitc->function->self.aoff); } @@ -203,6 +211,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) { jit_int32_t reg; assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); if (!_jitc->function->allocar) { _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->allocar = 1; @@ -215,60 +224,73 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) jit_addr(JIT_SP, JIT_SP, reg); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_unget_reg(reg); + jit_dec_synth(); } void _jit_ret(jit_state_t *_jit) { jit_node_t *instr; - assert(_jitc->function); - + jit_inc_synth(ret); /* jump to epilog */ instr = jit_jmpi(); jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); } void _jit_retr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr, u); jit_movr(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_reti(jit_state_t *_jit, jit_word_t u) { + jit_inc_synth_w(reti, u); jit_movi(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_f, u); jit_movr_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_reti_f(jit_state_t *_jit, jit_float32_t u) { + jit_inc_synth_f(reti_f, u); jit_movi_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_d, u); jit_movr_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { + jit_inc_synth_d(reti_d, u); jit_movi_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void @@ -292,11 +314,14 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) void _jit_ellipsis(jit_state_t *_jit) { + jit_inc_synth(ellipsis); if (_jitc->prepare) { + jit_link_prepare(); assert(!(_jitc->function->call.call & jit_call_varargs)); _jitc->function->call.call |= jit_call_varargs; } else { + jit_link_prolog(); assert(!(_jitc->function->self.call & jit_call_varargs)); _jitc->function->self.call |= jit_call_varargs; @@ -315,12 +340,14 @@ _jit_ellipsis(jit_state_t *_jit) else _jitc->function->vafp = NUM_FLOAT_REG_ARGS; } + jit_dec_synth(); } jit_node_t * _jit_arg(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -328,13 +355,17 @@ _jit_arg(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } - return (jit_new_node_w(jit_code_arg, offset)); + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_f(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_f_reg_p(_jitc->function->self.argf)) offset = _jitc->function->self.argf++; @@ -342,13 +373,17 @@ _jit_arg_f(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } - return (jit_new_node_w(jit_code_arg_f, offset)); + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_d(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_f_reg_p(_jitc->function->self.argf)) offset = _jitc->function->self.argf++; @@ -356,57 +391,69 @@ _jit_arg_d(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_float64_t); } - return (jit_new_node_w(jit_code_arg_d, offset)); + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_c(u, _R2 - v->u.w); else jit_ldxi_c(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t)); + jit_dec_synth(); } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_uc(u, _R2 - v->u.w); else jit_ldxi_uc(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t)); + jit_dec_synth(); } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_s(u, _R2 - v->u.w); else jit_ldxi_s(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t)); + jit_dec_synth(); } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_us(u, _R2 - v->u.w); else jit_ldxi_us(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t)); + jit_dec_synth(); } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); if (jit_arg_reg_p(v->u.w)) { #if __WORDSIZE == 32 jit_movr(u, _R2 - v->u.w); @@ -417,6 +464,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) else jit_ldxi_i(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t)); + jit_dec_synth(); } #if __WORDSIZE == 64 @@ -424,21 +472,25 @@ void _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_ui(u, _R2 - v->u.w); else jit_ldxi_ui(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint32_t)); + jit_dec_synth(); } void _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(u, _R2 - v->u.w); else jit_ldxi_l(u, JIT_FP, v->u.w); + jit_dec_synth(); } #endif @@ -446,10 +498,12 @@ void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(_R2 - v->u.w, u); else jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -457,6 +511,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); if (jit_arg_reg_p(v->u.w)) jit_movi(_R2 - v->u.w, u); else { @@ -465,12 +520,14 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) jit_stxi(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_f(u, _F0 - v->u.w); else @@ -480,12 +537,14 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) + (__WORDSIZE >> 3) - sizeof(jit_float32_t) #endif ); + jit_dec_synth(); } void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_f(_F0 - v->u.w, u); else @@ -494,6 +553,7 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) + (__WORDSIZE >> 3) - sizeof(jit_float32_t) #endif , JIT_FP, u); + jit_dec_synth(); } void @@ -501,6 +561,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movi_f(_F0 - v->u.w, u); else { @@ -513,26 +574,31 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) , JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(u, _F0 - v->u.w); else jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(_F0 - v->u.w, u); else jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -540,6 +606,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); if (jit_arg_f_reg_p(v->u.w)) jit_movi_d(_F0 - v->u.w, u); else { @@ -548,12 +615,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_stxi_d(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr(_R2 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -562,6 +632,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void @@ -569,6 +640,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(_R2 - _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -580,12 +653,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argf)) { jit_movr_f(_F0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; @@ -598,6 +674,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) , JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void @@ -605,6 +682,8 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argf)) { jit_movi_f(_F0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; @@ -620,12 +699,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argf)) { jit_movr_d(_F0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; @@ -634,6 +716,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, u); _jitc->function->call.size += sizeof(jit_float64_t); } + jit_dec_synth(); } void @@ -641,6 +724,8 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); if (jit_arg_f_reg_p(_jitc->function->call.argf)) { jit_movi_d(_F0 - _jitc->function->call.argf, u); ++_jitc->function->call.argf; @@ -652,6 +737,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_float64_t); } + jit_dec_synth(); } jit_bool_t @@ -677,6 +763,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_node_t *call; assert(_jitc->function); + jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; call = jit_callr(r0); @@ -685,6 +772,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); } jit_node_t * @@ -692,6 +780,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) { jit_node_t *node; assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; node = jit_calli(i0); @@ -700,67 +789,86 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); return (node); } void _jit_retval_c(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_c, r0); jit_extr_c(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_uc, r0); jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_s(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_s, r0); jit_extr_s(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_us(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_us, r0); jit_extr_us(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_i(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_i, r0); #if __WORDSIZE == 64 jit_extr_i(r0, JIT_RET); #else jit_movr(r0, JIT_RET); #endif + jit_dec_synth(); } #if __WORDSIZE == 64 void _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_ui, r0); jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_l(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_l, r0); jit_movr(r0, JIT_RET); + jit_dec_synth(); } #endif void _jit_retval_f(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_f, r0); jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); } void _jit_retval_d(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_d, r0); jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); } jit_pointer_t @@ -774,8 +882,14 @@ _emit_code(jit_state_t *_jit) struct { jit_node_t *node; jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif jit_int32_t patch_offset; } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif _jitc->function = NULL; @@ -890,12 +1004,16 @@ _emit_code(jit_state_t *_jit) patch(word, node); \ } \ break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif for (node = _jitc->head; node; node = node->next) { if (_jit->pc.uc >= _jitc->code.end) return (NULL); #if DEVEL_DISASSEMBLER - node->offset = _jit->pc.w; + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; #endif value = jit_classify(node->code); jit_regarg_set(node, value); @@ -1318,6 +1436,9 @@ _emit_code(jit_state_t *_jit) _jitc->function = _jitc->functions.ptr + node->w.w; undo.node = node; undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif undo.patch_offset = _jitc->patches.offset; restart_function: _jitc->again = 0; @@ -1335,6 +1456,9 @@ _emit_code(jit_state_t *_jit) temp->flag &= ~jit_flag_patch; node = undo.node; _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif _jitc->patches.offset = undo.patch_offset; goto restart_function; } @@ -1355,16 +1479,43 @@ _emit_code(jit_state_t *_jit) case jit_code_va_arg_d: vaarg_d(rn(node->u.w), rn(node->v.w)); break; - case jit_code_live: + case jit_code_live: case jit_code_ellipsis: + case jit_code_allocai: case jit_code_allocar: case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: +#if __WORDSIZE == 64 + case jit_code_getarg_ui: case jit_code_getarg_l: +#endif + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: +#if __WORDSIZE == 64 + case jit_code_retval_ui: case jit_code_retval_l: +#endif + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: break; default: abort(); } jit_regarg_clr(node, value); - assert(_jitc->regarg == 0); + assert(_jitc->regarg == 0 && _jitc->synth == 0); /* update register live state */ jit_reglive(node); } diff --git a/lib/jit_sparc-sz.c b/lib/jit_sparc-sz.c index f062ae098..473c0cad7 100644 --- a/lib/jit_sparc-sz.c +++ b/lib/jit_sparc-sz.c @@ -10,7 +10,19 @@ 0, /* #note */ 0, /* label */ 16, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ 0, /* va_start */ 0, /* va_arg */ 0, /* va_arg_d */ @@ -179,8 +191,26 @@ 16, /* jmpi */ 8, /* callr */ 16, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ 24, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 4, /* addr_f */ 16, /* addi_f */ 4, /* subr_f */ @@ -263,7 +293,15 @@ 24, /* bordi_f */ 12, /* bunordr_f */ 28, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 4, /* addr_d */ 24, /* addi_d */ 4, /* subr_d */ @@ -346,6 +384,11 @@ 32, /* bordi_d */ 12, /* bunordr_d */ 36, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -355,6 +398,4 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __WORDSIZE */ diff --git a/lib/jit_sparc.c b/lib/jit_sparc.c index c3c829701..097110aba 100644 --- a/lib/jit_sparc.c +++ b/lib/jit_sparc.c @@ -131,6 +131,10 @@ _jit_prolog(jit_state_t *_jit) jit_alloc((jit_pointer_t *)&_jitc->function->regoff, _jitc->reglen * sizeof(jit_int32_t)); + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); jit_link(_jitc->function->prolog); _jitc->function->prolog->w.w = offset; @@ -155,6 +159,10 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length) default: _jitc->function->self.aoff &= -8; break; } _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } return (_jitc->function->self.aoff); } @@ -163,84 +171,95 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) { jit_int32_t reg; assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); if (!_jitc->function->allocar) { _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->allocar = 1; } - reg = jit_get_reg(jit_class_gpr); jit_negr(reg, v); jit_andi(reg, reg, -16); - jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); jit_addr(u, u, reg); jit_addr(_SP, _SP, reg); - jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_unget_reg(reg); + jit_dec_synth(); } void _jit_ret(jit_state_t *_jit) { jit_node_t *instr; - assert(_jitc->function); - + jit_inc_synth(ret); /* jump to epilog */ instr = jit_jmpi(); jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); } void _jit_retr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr, u); if (JIT_RET != u) jit_movr(JIT_RET, u); else jit_live(JIT_RET); jit_ret(); + jit_dec_synth(); } void _jit_reti(jit_state_t *_jit, jit_word_t u) { + jit_inc_synth_w(reti, u); jit_movi(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_f, u); if (JIT_FRET != u) jit_movr_f(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_f(jit_state_t *_jit, jit_float32_t u) { + jit_inc_synth_f(reti_f, u); jit_movi_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_d, u); if (JIT_FRET != u) jit_movr_d(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { + jit_inc_synth_d(reti_d, u); jit_movi_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void @@ -264,22 +283,27 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) void _jit_ellipsis(jit_state_t *_jit) { + jit_inc_synth(ellipsis); if (_jitc->prepare) { + jit_link_prepare(); assert(!(_jitc->function->call.call & jit_call_varargs)); _jitc->function->call.call |= jit_call_varargs; } else { + jit_link_prolog(); assert(!(_jitc->function->self.call & jit_call_varargs)); _jitc->function->self.call |= jit_call_varargs; _jitc->function->vagp = _jitc->function->self.argi; } + jit_dec_synth(); } jit_node_t * _jit_arg(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -287,13 +311,17 @@ _jit_arg(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_word_t); } - return (jit_new_node_w(jit_code_arg, offset)); + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prepare(); + return (node); } jit_node_t * _jit_arg_f(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_reg_p(_jitc->function->self.argi)) offset = _jitc->function->self.argi++; @@ -301,13 +329,17 @@ _jit_arg_f(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_float32_t); } - return (jit_new_node_w(jit_code_arg_f, offset)); + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prepare(); + return (node); } jit_node_t * _jit_arg_d(jit_state_t *_jit) { - jit_int32_t offset; + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); if (jit_arg_d_reg_p(_jitc->function->self.argi)) { offset = _jitc->function->self.argi; @@ -321,71 +353,86 @@ _jit_arg_d(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_float64_t); } - return (jit_new_node_w(jit_code_arg_d, offset)); + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prepare(); + return (node); } void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_c(u, _I0 + v->u.w); else jit_ldxi_c(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t)); + jit_dec_synth(); } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_uc(u, _I0 + v->u.w); else jit_ldxi_uc(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t)); + jit_dec_synth(); } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_s(u, _I0 + v->u.w); else jit_ldxi_s(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t)); + jit_dec_synth(); } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_us(u, _I0 + v->u.w); else jit_ldxi_us(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t)); + jit_dec_synth(); } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(u, _I0 + v->u.w); else jit_ldxi_i(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(_I0 + v->u.w, u); else jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -393,6 +440,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); if (jit_arg_reg_p(v->u.w)) jit_movi(_I0 + v->u.w, u); else { @@ -401,6 +449,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) jit_stxi(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void @@ -408,24 +457,28 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); assert(_jitc->function); + jit_inc_synth_wp(getarg_f, u, v); if (jit_arg_reg_p(v->u.w)) { jit_stxi(-4, JIT_FP, _I0 + v->u.w); jit_ldxi_f(u, JIT_FP, -4); } else jit_ldxi_f(u, JIT_FP, v->u.w); + jit_dec_synth(); } void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); if (jit_arg_reg_p(v->u.w)) { jit_stxi_f(-4, JIT_FP, u); jit_ldxi(_I0 + v->u.w, JIT_FP, -4); } else jit_stxi_f(v->u.w, JIT_FP, u); + jit_dec_synth(); } void @@ -433,6 +486,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); regno = jit_get_reg(jit_class_fpr); jit_movi_f(regno, u); if (jit_arg_reg_p(v->u.w)) { @@ -442,6 +496,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) else jit_stxi_f(v->u.w, JIT_FP, regno); jit_unget_reg(regno); + jit_dec_synth(); } void @@ -449,6 +504,7 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); assert(_jitc->function); + jit_inc_synth_wp(getarg_d, u, v); if (jit_arg_d_reg_p(v->u.w)) { jit_stxi(-8, JIT_FP, _I0 + v->u.w); jit_stxi(-4, JIT_FP, _I0 + v->u.w + 1); @@ -463,6 +519,7 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) jit_ldxi_f(u, JIT_FP, v->u.w); jit_ldxi_f(u + 1, JIT_FP, v->u.w + 4); } + jit_dec_synth(); } void @@ -470,6 +527,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); if (jit_arg_d_reg_p(v->u.w)) { jit_stxi_d(-8, JIT_FP, u); jit_ldxi(_I0 + v->u.w, JIT_FP, -8); @@ -494,6 +552,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) jit_stxi(v->u.w + 4, JIT_FP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void @@ -501,6 +560,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno, gpr; assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); if (jit_arg_d_reg_p(v->u.w)) { @@ -528,12 +588,14 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_unget_reg(gpr); } jit_unget_reg(regno); + jit_dec_synth(); } - void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr(_O0 + _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -542,12 +604,15 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void _jit_pushargi(jit_state_t *_jit, jit_word_t u) { jit_int32_t regno; + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(_O0 + _jitc->function->call.argi, u); ++_jitc->function->call.argi; @@ -559,11 +624,14 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_word_t); } + jit_dec_synth(); } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_stxi_f(-4, JIT_FP, u); jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -4); @@ -573,12 +641,15 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) jit_stxi_f(_jitc->function->call.size + stack_framesize, JIT_SP, u); _jitc->function->call.size += sizeof(jit_float32_t); } + jit_dec_synth(); } void _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); regno = jit_get_reg(jit_class_fpr); jit_movi_f(regno, u); if (jit_arg_reg_p(_jitc->function->call.argi)) { @@ -591,11 +662,14 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) _jitc->function->call.size += sizeof(jit_float32_t); } jit_unget_reg(regno); + jit_dec_synth(); } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); if (jit_arg_d_reg_p(_jitc->function->call.argi)) { jit_stxi_d(-8, JIT_FP, u); jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8); @@ -616,12 +690,15 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) JIT_SP, u + 1); _jitc->function->call.size += sizeof(jit_float64_t); } + jit_dec_synth(); } void _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); if (jit_arg_d_reg_p(_jitc->function->call.argi)) { @@ -645,6 +722,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) _jitc->function->call.size += sizeof(jit_float64_t); } jit_unget_reg(regno); + jit_dec_synth(); } jit_bool_t @@ -667,8 +745,8 @@ void _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_node_t *call; - assert(_jitc->function); + jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; call = jit_callr(r0); @@ -677,14 +755,15 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); } jit_node_t * _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) { jit_node_t *node; - assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; node = jit_calli(i0); @@ -693,52 +772,67 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); return (node); } void _jit_retval_c(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_c, r0); jit_extr_c(r0, _O0); + jit_dec_synth(); } void _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_uc, r0); jit_extr_uc(r0, _O0); + jit_dec_synth(); } void _jit_retval_s(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_s, r0); jit_extr_s(r0, _O0); + jit_dec_synth(); } void _jit_retval_us(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_us, r0); jit_extr_us(r0, _O0); + jit_dec_synth(); } void _jit_retval_i(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_i, r0); if (r0 != _O0) jit_movr(r0, _O0); + jit_dec_synth(); } void _jit_retval_f(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_f, r0); if (r0 != JIT_FRET) jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); } void _jit_retval_d(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_d, r0); if (r0 != JIT_FRET) jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); } jit_pointer_t @@ -752,8 +846,14 @@ _emit_code(jit_state_t *_jit) struct { jit_node_t *node; jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif jit_int32_t patch_offset; } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif _jitc->function = NULL; @@ -859,12 +959,16 @@ _emit_code(jit_state_t *_jit) patch(word, node); \ } \ break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif for (node = _jitc->head; node; node = node->next) { if (_jit->pc.uc >= _jitc->code.end) return (NULL); #if DEVEL_DISASSEMBLER - node->offset = _jit->pc.w; + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; #endif value = jit_classify(node->code); jit_regarg_set(node, value); @@ -1253,6 +1357,9 @@ _emit_code(jit_state_t *_jit) _jitc->function = _jitc->functions.ptr + node->w.w; undo.node = node; undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif undo.patch_offset = _jitc->patches.offset; restart_function: _jitc->again = 0; @@ -1270,6 +1377,9 @@ _emit_code(jit_state_t *_jit) temp->flag &= ~jit_flag_patch; node = undo.node; _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif _jitc->patches.offset = undo.patch_offset; goto restart_function; } @@ -1288,16 +1398,37 @@ _emit_code(jit_state_t *_jit) case jit_code_va_arg_d: vaarg_d(rn(node->u.w), rn(node->v.w)); break; - case jit_code_live: + case jit_code_live: case jit_code_ellipsis: + case jit_code_allocai: case jit_code_allocar: case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: break; default: abort(); } jit_regarg_clr(node, value); - assert(_jitc->regarg == 0); + assert(_jitc->regarg == 0 && _jitc->synth == 0); /* update register live state */ jit_reglive(node); } diff --git a/lib/jit_x86-sz.c b/lib/jit_x86-sz.c index d634db45a..feb4c488a 100644 --- a/lib/jit_x86-sz.c +++ b/lib/jit_x86-sz.c @@ -10,7 +10,19 @@ 0, /* #note */ 3, /* label */ 34, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ 3, /* va_start */ 5, /* va_arg */ 7, /* va_arg_d */ @@ -179,8 +191,26 @@ 5, /* jmpi */ 2, /* callr */ 5, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ 24, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 8, /* addr_f */ 19, /* addi_f */ 12, /* subr_f */ @@ -263,7 +293,15 @@ 23, /* bordi_f */ 10, /* bunordr_f */ 23, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 10, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 8, /* addr_d */ 26, /* addi_d */ 12, /* subr_d */ @@ -346,6 +384,11 @@ 28, /* bordi_d */ 10, /* bunordr_d */ 28, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 10, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -355,26 +398,36 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 10, /* x86_retval_f */ - 10, /* x86_retval_d */ -#endif /* __X32 */ +#endif #if __X64 #if __CYGWIN__ -#define JIT_INSTR_MAX 71 +#define JIT_INSTR_MAX 130 0, /* data */ 0, /* live */ - 7, /* align */ + 6, /* align */ 0, /* save */ 0, /* load */ 0, /* #name */ 0, /* #note */ 7, /* label */ - 71, /* prolog */ + 130, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ - 0, /* va_start */ - 0, /* va_arg */ - 0, /* va_arg_d */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 7, /* va_start */ + 7, /* va_arg */ + 9, /* va_arg_d */ 0, /* va_end */ 4, /* addr */ 13, /* addi */ @@ -388,7 +441,7 @@ 13, /* subci */ 9, /* subxr */ 7, /* subxi */ - 19, /* rsbi */ + 16, /* rsbi */ 7, /* mulr */ 14, /* muli */ 20, /* qmulr */ @@ -491,7 +544,7 @@ 7, /* stxr_c */ 7, /* stxi_c */ 5, /* stxr_s */ - 5, /* stxi_s */ + 7, /* stxi_s */ 4, /* stxr_i */ 6, /* stxi_i */ 4, /* stxr_l */ @@ -540,13 +593,31 @@ 5, /* jmpi */ 3, /* callr */ 13, /* calli */ - 68, /* epilog */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 124, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 10, /* addr_f */ 21, /* addi_f */ 15, /* subr_f */ 21, /* subi_f */ - 21, /* rsbi_f */ + 27, /* rsbi_f */ 10, /* mulr_f */ 21, /* muli_f */ 15, /* divr_f */ @@ -624,12 +695,20 @@ 25, /* bordi_f */ 10, /* bunordr_f */ 25, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 10, /* addr_d */ 25, /* addi_d */ 15, /* subr_d */ 25, /* subi_d */ - 25, /* rsbi_d */ + 27, /* rsbi_d */ 10, /* mulr_d */ 25, /* muli_d */ 15, /* divr_d */ @@ -707,6 +786,11 @@ 26, /* bordi_d */ 11, /* bunordr_d */ 26, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -716,8 +800,6 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #else # if __X64_32 @@ -731,7 +813,19 @@ 0, /* #note */ 3, /* label */ 108, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ 41, /* va_start */ 45, /* va_arg */ 54, /* va_arg_d */ @@ -900,8 +994,26 @@ 5, /* jmpi */ 3, /* callr */ 9, /* calli */ - 35, /* epilog */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 34, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 10, /* addr_f */ 21, /* addi_f */ 15, /* subr_f */ @@ -984,7 +1096,15 @@ 21, /* bordi_f */ 10, /* bunordr_f */ 21, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 10, /* addr_d */ 33, /* addi_d */ 15, /* subr_d */ @@ -1067,6 +1187,11 @@ 34, /* bordi_d */ 11, /* bunordr_d */ 34, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -1076,10 +1201,8 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ -# else +# else #define JIT_INSTR_MAX 115 0, /* data */ 0, /* live */ @@ -1090,7 +1213,19 @@ 0, /* #note */ 7, /* label */ 115, /* prolog */ + 0, /* ellipsis */ + 0, /* allocai */ + 0, /* allocar */ 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ 42, /* va_start */ 41, /* va_arg */ 50, /* va_arg_d */ @@ -1259,8 +1394,26 @@ 5, /* jmpi */ 3, /* callr */ 13, /* calli */ - 38, /* epilog */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 37, /* epilog */ 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ 10, /* addr_f */ 21, /* addi_f */ 15, /* subr_f */ @@ -1343,7 +1496,15 @@ 25, /* bordi_f */ 10, /* bunordr_f */ 25, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ 10, /* addr_d */ 25, /* addi_d */ 15, /* subr_d */ @@ -1426,6 +1587,11 @@ 26, /* bordi_d */ 11, /* bunordr_d */ 26, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ 0, /* movr_w_f */ 0, /* movr_ww_d */ 0, /* movr_w_d */ @@ -1435,8 +1601,6 @@ 0, /* movi_d_ww */ 0, /* movr_d_w */ 0, /* movi_d_w */ - 0, /* x86_retval_f */ - 0, /* x86_retval_d */ #endif /* __CYGWIN__ */ # endif /* __X64_32 */ #endif /* __X64 */ diff --git a/lib/jit_x86.c b/lib/jit_x86.c index cbdf5a04a..2e3ba80a5 100644 --- a/lib/jit_x86.c +++ b/lib/jit_x86.c @@ -423,6 +423,10 @@ _jit_prolog(jit_state_t *_jit) jit_alloc((jit_pointer_t *)&_jitc->function->regoff, _jitc->reglen * sizeof(jit_int32_t)); + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); jit_link(_jitc->function->prolog); _jitc->function->prolog->w.w = offset; @@ -447,6 +451,18 @@ _jit_allocai(jit_state_t *_jit, jit_int32_t length) default: _jitc->function->self.aoff &= -8; break; } _jitc->function->self.aoff -= length; + + /* jit_allocai() may be called from jit_x86-cpu.c, and force a function + * generation restart on some conditions: div/rem and qmul/qdiv, due + * to registers constraints. + * The check is to prevent an assertion of a jit_xyz() being called + * during code generation, and attempting to add a node to the tail + * of the current IR generation. */ + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (_jitc->function->self.aoff); } @@ -455,6 +471,7 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) { jit_int32_t reg; assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); if (!_jitc->function->allocar) { _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); _jitc->function->allocar = 1; @@ -467,23 +484,25 @@ _jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) jit_addr(JIT_SP, JIT_SP, reg); jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); jit_unget_reg(reg); + jit_dec_synth(); } void _jit_ret(jit_state_t *_jit) { jit_node_t *instr; - assert(_jitc->function); - + jit_inc_synth(ret); /* jump to epilog */ instr = jit_jmpi(); jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); } void _jit_retr(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr, u); /* movr(%ret, %ret) would be optimized out */ if (JIT_RET != u) jit_movr(JIT_RET, u); @@ -491,47 +510,58 @@ _jit_retr(jit_state_t *_jit, jit_int32_t u) else jit_live(JIT_RET); jit_ret(); + jit_dec_synth(); } void _jit_reti(jit_state_t *_jit, jit_word_t u) { + jit_inc_synth_w(reti, u); jit_movi(JIT_RET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_f(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_f, u); if (JIT_FRET != u) jit_movr_f(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_f(jit_state_t *_jit, jit_float32_t u) { + jit_inc_synth_f(reti_f, u); jit_movi_f(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void _jit_retr_d(jit_state_t *_jit, jit_int32_t u) { + jit_inc_synth_w(retr_d, u); if (JIT_FRET != u) jit_movr_d(JIT_FRET, u); else jit_live(JIT_FRET); jit_ret(); + jit_dec_synth(); } void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { + jit_inc_synth_d(reti_d, u); jit_movi_d(JIT_FRET, u); jit_ret(); + jit_dec_synth(); } void @@ -555,12 +585,15 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) void _jit_ellipsis(jit_state_t *_jit) { + jit_inc_synth(ellipsis); if (_jitc->prepare) { + jit_link_prepare(); /* Remember that a varargs function call is being constructed. */ assert(!(_jitc->function->call.call & jit_call_varargs)); _jitc->function->call.call |= jit_call_varargs; } else { + jit_link_prolog(); /* Remember the current function is varargs. */ assert(!(_jitc->function->self.call & jit_call_varargs)); _jitc->function->self.call |= jit_call_varargs; @@ -585,13 +618,14 @@ _jit_ellipsis(jit_state_t *_jit) _jitc->function->vafp = va_fp_max_offset; #endif } + jit_dec_synth(); } jit_node_t * _jit_arg(jit_state_t *_jit) { - jit_int32_t offset; - + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); assert(!(_jitc->function->self.call & jit_call_varargs)); #if __X64 @@ -607,14 +641,17 @@ _jit_arg(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += REAL_WORDSIZE; } - return (jit_new_node_w(jit_code_arg, offset)); + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_f(jit_state_t *_jit) { - jit_int32_t offset; - + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); assert(!(_jitc->function->self.call & jit_call_varargs)); #if __X64 @@ -633,14 +670,17 @@ _jit_arg_f(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += REAL_WORDSIZE; } - return (jit_new_node_w(jit_code_arg_f, offset)); + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } jit_node_t * _jit_arg_d(jit_state_t *_jit) { - jit_int32_t offset; - + jit_node_t *node; + jit_int32_t offset; assert(_jitc->function); assert(!(_jitc->function->self.call & jit_call_varargs)); #if __X64 @@ -659,61 +699,73 @@ _jit_arg_d(jit_state_t *_jit) offset = _jitc->function->self.size; _jitc->function->self.size += sizeof(jit_float64_t); } - return (jit_new_node_w(jit_code_arg_d, offset)); + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); } void _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) jit_extr_c(u, JIT_RA0 - v->u.w); else #endif jit_ldxi_c(u, _RBP, v->u.w); + jit_dec_synth(); } void _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) jit_extr_uc(u, JIT_RA0 - v->u.w); else #endif jit_ldxi_uc(u, _RBP, v->u.w); + jit_dec_synth(); } void _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) jit_extr_s(u, JIT_RA0 - v->u.w); else #endif jit_ldxi_s(u, _RBP, v->u.w); + jit_dec_synth(); } void _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) jit_extr_us(u, JIT_RA0 - v->u.w); else #endif jit_ldxi_us(u, _RBP, v->u.w); + jit_dec_synth(); } void _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) { # if __X64_32 @@ -725,6 +777,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) else #endif jit_ldxi_i(u, _RBP, v->u.w); + jit_dec_synth(); } #if __X64 && !__X64_32 @@ -732,20 +785,24 @@ void _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_ui(u, JIT_RA0 - v->u.w); else jit_ldxi_ui(u, _RBP, v->u.w); + jit_dec_synth(); } void _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(u, JIT_RA0 - v->u.w); else jit_ldxi_l(u, _RBP, v->u.w); + jit_dec_synth(); } #endif @@ -753,12 +810,14 @@ void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) jit_movr(JIT_RA0 - v->u.w, u); else #endif jit_stxi(v->u.w, _RBP, u); + jit_dec_synth(); } void @@ -766,6 +825,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) jit_movi(JIT_RA0 - v->u.w, u); @@ -777,30 +837,35 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) jit_stxi(v->u.w, _RBP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); #if __X64 if (jit_arg_f_reg_p(v->u.w)) jit_movr_f(u, _XMM0 - v->u.w); else #endif jit_ldxi_f(u, _RBP, v->u.w); + jit_dec_synth(); } void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) jit_movr_f(_XMM0 - v->u.w, u); else #endif jit_stxi_f(v->u.w, _RBP, u); + jit_dec_synth(); } void @@ -808,6 +873,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) jit_movi_f(_XMM0 - v->u.w, u); @@ -819,30 +885,35 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) jit_stxi_f(v->u.w, _RBP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); #if __X64 if (jit_arg_f_reg_p(v->u.w)) jit_movr_d(u, _XMM0 - v->u.w); else #endif jit_ldxi_d(u, _RBP, v->u.w); + jit_dec_synth(); } void _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) jit_movr_d(_XMM0 - v->u.w, u); else #endif jit_stxi_d(v->u.w, _RBP, u); + jit_dec_synth(); } void @@ -850,6 +921,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); #if __X64 if (jit_arg_reg_p(v->u.w)) jit_movi_d(_XMM0 - v->u.w, u); @@ -861,12 +933,15 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_stxi_d(v->u.w, _RBP, regno); jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); #if __X64 if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr(JIT_RA0 - _jitc->function->call.argi, u); @@ -883,14 +958,16 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) jit_stxi(_jitc->function->call.size, _RSP, u); _jitc->function->call.size += REAL_WORDSIZE; } + jit_dec_synth(); } void _jit_pushargi(jit_state_t *_jit, jit_word_t u) { jit_int32_t regno; - assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); #if __X64 if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(JIT_RA0 - _jitc->function->call.argi, u); @@ -911,12 +988,15 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) _jitc->function->call.size += REAL_WORDSIZE; jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); #if __X64 # if __CYGWIN__ if (jit_arg_reg_p(_jitc->function->call.argi)) { @@ -942,14 +1022,16 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) jit_stxi_f(_jitc->function->call.size, _RSP, u); _jitc->function->call.size += REAL_WORDSIZE; } + jit_dec_synth(); } void _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) { jit_int32_t regno; - assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); #if __X64 # if __CYGWIN__ if (jit_arg_reg_p(_jitc->function->call.argi)) { @@ -978,12 +1060,15 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) _jitc->function->call.size += REAL_WORDSIZE; jit_unget_reg(regno); } + jit_dec_synth(); } void _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) { assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); #if __X64 # if __CYGWIN__ if (jit_arg_reg_p(_jitc->function->call.argi)) { @@ -1009,14 +1094,16 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) jit_stxi_d(_jitc->function->call.size, _RSP, u); _jitc->function->call.size += sizeof(jit_float64_t); } + jit_dec_synth(); } void _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; - assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); #if __X64 # if __CYGWIN__ if (jit_arg_reg_p(_jitc->function->call.argi)) { @@ -1045,6 +1132,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) _jitc->function->call.size += sizeof(jit_float64_t); jit_unget_reg(regno); } + jit_dec_synth(); } jit_bool_t @@ -1075,9 +1163,9 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_int32_t reg; jit_node_t *call; - - reg = r0; assert(_jitc->function); + reg = r0; + jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; #if __X64 @@ -1102,6 +1190,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); } jit_node_t * @@ -1111,8 +1200,8 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) jit_int32_t reg; #endif jit_node_t *node; - assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; #if __X64 @@ -1136,79 +1225,94 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; _jitc->prepare = 0; + jit_dec_synth(); return (node); } void _jit_retval_c(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_c, r0); jit_extr_c(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_uc, r0); jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_s(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_s, r0); jit_extr_s(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_us(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_us, r0); jit_extr_us(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_i(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_i, r0); #if __X32 || __X64_32 if (r0 != JIT_RET) jit_movr(r0, JIT_RET); #else jit_extr_i(r0, JIT_RET); #endif + jit_dec_synth(); } #if __X64 && !__X64_32 void _jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_ui, r0); jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); } void _jit_retval_l(jit_state_t *_jit, jit_int32_t r0) { + jit_inc_synth_w(retval_l, r0); if (r0 != JIT_RET) jit_movr(r0, JIT_RET); + jit_dec_synth(); } #endif void _jit_retval_f(jit_state_t *_jit, jit_int32_t r0) { -# if __X32 - jit_new_node_w(jit_code_x86_retval_f, r0); -# else + jit_inc_synth_w(retval_f, r0); +#if __X64 if (r0 != JIT_FRET) jit_movr_f(r0, JIT_FRET); -# endif +#endif + jit_dec_synth(); } void _jit_retval_d(jit_state_t *_jit, jit_int32_t r0) { -# if __X32 - jit_new_node_w(jit_code_x86_retval_d, r0); -# else + jit_inc_synth_w(retval_d, r0); +#if __X64 if (r0 != JIT_FRET) jit_movr_d(r0, JIT_FRET); -# endif +#endif + jit_dec_synth(); } jit_pointer_t @@ -1222,8 +1326,14 @@ _emit_code(jit_state_t *_jit) struct { jit_node_t *node; jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif jit_int32_t patch_offset; } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif _jitc->function = NULL; @@ -1461,12 +1571,16 @@ _emit_code(jit_state_t *_jit) patch(word, node); \ } \ break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif for (node = _jitc->head; node; node = node->next) { if (_jit->pc.uc >= _jitc->code.end) return (NULL); #if DEVEL_DISASSEMBLER - node->offset = _jit->pc.w; + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; #endif value = jit_classify(node->code); jit_regarg_set(node, value); @@ -1917,6 +2031,9 @@ _emit_code(jit_state_t *_jit) _jitc->function = _jitc->functions.ptr + node->w.w; undo.node = node; undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif undo.patch_offset = _jitc->patches.offset; restart_function: _jitc->again = 0; @@ -1934,6 +2051,9 @@ _emit_code(jit_state_t *_jit) temp->flag &= ~jit_flag_patch; node = undo.node; _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif _jitc->patches.offset = undo.patch_offset; goto restart_function; } @@ -1946,24 +2066,6 @@ _emit_code(jit_state_t *_jit) epilog(node); _jitc->function = NULL; break; -#if __X32 - case jit_code_x86_retval_f: - if (jit_sse_reg_p(node->u.w)) { - fstpr(_ST1_REGNO); - sse_from_x87_f(rn(node->u.w), _ST0_REGNO); - } - else - fstpr(rn(node->u.w) + 1); - break; - case jit_code_x86_retval_d: - if (jit_sse_reg_p(node->u.w)) { - fstpr(_ST1_REGNO); - sse_from_x87_d(rn(node->u.w), _ST0_REGNO); - } - else - fstpr(rn(node->u.w) + 1); - break; -#endif case jit_code_va_start: vastart(rn(node->u.w)); break; @@ -1973,16 +2075,62 @@ _emit_code(jit_state_t *_jit) case jit_code_va_arg_d: vaarg_d(rn(node->u.w), rn(node->v.w), jit_x87_reg_p(node->u.w)); break; - case jit_code_live: + case jit_code_live: case jit_code_ellipsis: + case jit_code_allocai: case jit_code_allocar: case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: +#if __X64 && !__X64_32 + case jit_code_getarg_ui: case jit_code_getarg_l: +#endif + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: +#if __X64 && !__X32 + case jit_code_retval_ui: case jit_code_retval_l: +#endif + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + case jit_code_retval_f: +#if __X32 + if (jit_sse_reg_p(node->u.w)) { + fstpr(_ST1_REGNO); + sse_from_x87_f(rn(node->u.w), _ST0_REGNO); + } + else + fstpr(rn(node->u.w) + 1); +#endif + break; + case jit_code_retval_d: +#if __X32 + if (jit_sse_reg_p(node->u.w)) { + fstpr(_ST1_REGNO); + sse_from_x87_d(rn(node->u.w), _ST0_REGNO); + } + else + fstpr(rn(node->u.w) + 1); +#endif break; default: abort(); } jit_regarg_clr(node, value); - assert(_jitc->regarg == 0); + assert(_jitc->regarg == 0 && _jitc->synth == 0); /* update register live state */ jit_reglive(node); } diff --git a/lib/lightning.c b/lib/lightning.c index a7eb27150..943642266 100644 --- a/lib/lightning.c +++ b/lib/lightning.c @@ -58,6 +58,9 @@ static inline jit_node_t *_link_node(jit_state_t*, jit_node_t*); #define del_node(u, v) _del_node(_jit, u, v) static inline void _del_node(jit_state_t*, jit_node_t*, jit_node_t*); +#define free_node(u) _free_node(_jit, u) +static inline void _free_node(jit_state_t*, jit_node_t*); + #define del_label(u, v) _del_label(_jit, u, v) static void _del_label(jit_state_t*, jit_node_t*, jit_node_t*); @@ -681,6 +684,8 @@ _new_node(jit_state_t *_jit, jit_code_t code) new_pool(); node = _jitc->list; _jitc->list = node->next; + if (_jitc->synth) + node->flag |= jit_flag_synth; node->next = NULL; node->code = code; @@ -711,6 +716,14 @@ _del_node(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) _jitc->list = node; } +static inline void +_free_node(jit_state_t *_jit, jit_node_t *node) +{ + memset(node, 0, sizeof(jit_node_t)); + node->next = _jitc->list; + _jitc->list = node; +} + static void _del_label(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) { @@ -906,6 +919,13 @@ _jit_destroy_state(jit_state_t *_jit) jit_free((jit_pointer_t *)&_jit); } +void +_jit_synth_inc(jit_state_t *_jit) +{ + assert(_jitc->synth < 8); + ++_jitc->synth; +} + jit_node_t * _jit_new_node(jit_state_t *_jit, jit_code_t code) { @@ -927,6 +947,13 @@ _jit_link_node(jit_state_t *_jit, jit_node_t *node) link_node(node); } +void +_jit_synth_dec(jit_state_t *_jit) +{ + assert(_jitc->synth > 0); + --_jitc->synth; +} + jit_node_t * _jit_new_node_w(jit_state_t *_jit, jit_code_t code, jit_word_t u) @@ -937,6 +964,26 @@ _jit_new_node_w(jit_state_t *_jit, jit_code_t code, return (link_node(node)); } +jit_node_t * +_jit_new_node_f(jit_state_t *_jit, jit_code_t code, + jit_float32_t u) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.f = u; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_d(jit_state_t *_jit, jit_code_t code, + jit_float64_t u) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.d = u; + return (link_node(node)); +} + jit_node_t * _jit_new_node_p(jit_state_t *_jit, jit_code_t code, jit_pointer_t u) @@ -965,6 +1012,28 @@ _jit_new_node_wp(jit_state_t *_jit, jit_code_t code, return (jit_new_node_ww(code, u, (jit_word_t)v)); } +jit_node_t * +_jit_new_node_fp(jit_state_t *_jit, jit_code_t code, + jit_float32_t u, jit_pointer_t v) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.f = u; + node->v.w = (jit_word_t)v; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_dp(jit_state_t *_jit, jit_code_t code, + jit_float64_t u, jit_pointer_t v) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.d = u; + node->v.w = (jit_word_t)v; + return (link_node(node)); +} + jit_node_t * _jit_new_node_pw(jit_state_t *_jit, jit_code_t code, jit_pointer_t u, jit_word_t v) @@ -1163,7 +1232,7 @@ _jit_prepare(jit_state_t *_jit) _jitc->function->call.argi = _jitc->function->call.argf = _jitc->function->call.size = 0; - _jitc->prepare = 1; + _jitc->prepare = jit_new_node(jit_code_prepare); } void @@ -1182,28 +1251,69 @@ _jit_classify(jit_state_t *_jit, jit_code_t code) jit_int32_t mask; switch (code) { - case jit_code_data: case jit_code_align: case jit_code_save: - case jit_code_load: case jit_code_name: case jit_code_label: - case jit_code_note: case jit_code_prolog: case jit_code_epilog: + case jit_code_data: case jit_code_save: case jit_code_load: + case jit_code_name: case jit_code_label: case jit_code_note: + case jit_code_prolog: case jit_code_ellipsis: case jit_code_epilog: + case jit_code_ret: case jit_code_prepare: mask = 0; break; case jit_code_live: case jit_code_va_end: + case jit_code_retr: case jit_code_retr_f: case jit_code_retr_d: + case jit_code_pushargr: case jit_code_pushargr_f: + case jit_code_pushargr_d: + case jit_code_finishr: /* synthesized will set jit_cc_a0_jmp */ mask = jit_cc_a0_reg; break; - case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: + case jit_code_align: case jit_code_reti: case jit_code_pushargi: + case jit_code_finishi: /* synthesized will set jit_cc_a0_jmp */ mask = jit_cc_a0_int; break; + case jit_code_reti_f: case jit_code_pushargi_f: + mask = jit_cc_a0_flt; + break; + case jit_code_reti_d: case jit_code_pushargi_d: + mask = jit_cc_a0_dbl; + break; + case jit_code_allocai: + mask = jit_cc_a0_int|jit_cc_a1_int; + break; + case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: + mask = jit_cc_a0_int|jit_cc_a0_arg; + break; case jit_code_calli: case jit_code_jmpi: mask = jit_cc_a0_jmp; break; case jit_code_callr: case jit_code_jmpr: mask = jit_cc_a0_reg|jit_cc_a0_jmp; break; - case jit_code_x86_retval_f: - case jit_code_x86_retval_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: case jit_code_retval_ui: + case jit_code_retval_l: + case jit_code_retval_f: case jit_code_retval_d: case jit_code_va_start: mask = jit_cc_a0_reg|jit_cc_a0_chg; break; + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: case jit_code_getarg_ui: + case jit_code_getarg_l: + case jit_code_getarg_f: case jit_code_getarg_d: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_arg; + break; + case jit_code_putargr: case jit_code_putargr_f: + case jit_code_putargr_d: + mask = jit_cc_a0_reg|jit_cc_a1_arg; + break; + case jit_code_putargi: + mask = jit_cc_a0_int|jit_cc_a1_arg; + break; + case jit_code_putargi_f: + mask = jit_cc_a0_flt|jit_cc_a1_arg; + break; + case jit_code_putargi_d: + mask = jit_cc_a0_dbl|jit_cc_a1_arg; + break; case jit_code_movi: case jit_code_ldi_c: case jit_code_ldi_uc: case jit_code_ldi_s: case jit_code_ldi_us: case jit_code_ldi_i: case jit_code_ldi_ui: case jit_code_ldi_l: case jit_code_ldi_f: @@ -1337,6 +1447,8 @@ _jit_classify(jit_state_t *_jit, jit_code_t code) case jit_code_bordi_d: case jit_code_bunordi_d: mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl; break; + case jit_code_allocar: /* synthesized instructions make it + * equivalent to jit_cc_a0_chg */ case jit_code_str_c: case jit_code_str_s: case jit_code_str_i: case jit_code_str_l: case jit_code_str_f: case jit_code_str_d: mask = jit_cc_a0_reg|jit_cc_a1_reg; @@ -1512,7 +1624,15 @@ _jit_optimize(jit_state_t *_jit) break; default: #if JIT_HASH_CONSTS - if (mask & jit_cc_a1_flt) { + if (mask & jit_cc_a0_flt) { + node->u.p = jit_data(&node->u.f, sizeof(jit_float32_t), 4); + node->flag |= jit_flag_node | jit_flag_data; + } + else if (mask & jit_cc_a0_dbl) { + node->u.p = jit_data(&node->u.d, sizeof(jit_float64_t), 8); + node->flag |= jit_flag_node | jit_flag_data; + } + else if (mask & jit_cc_a1_flt) { node->v.p = jit_data(&node->v.f, sizeof(jit_float32_t), 4); node->flag |= jit_flag_node | jit_flag_data; } @@ -1546,6 +1666,10 @@ _jit_optimize(jit_state_t *_jit) (jit_cc_a1_reg|jit_cc_a1_chg)) jit_regset_setbit(&_jitc->function->regset, jit_regno(node->v.w)); + if ((mask & (jit_cc_a2_reg|jit_cc_a2_chg)) == + (jit_cc_a2_reg|jit_cc_a2_chg)) + jit_regset_setbit(&_jitc->function->regset, + jit_regno(node->w.w)); } break; } @@ -1632,8 +1756,14 @@ _jit_reglive(jit_state_t *_jit, jit_node_t *node) else jit_regset_setbit(&_jitc->reglive, node->v.w); } - if ((value & jit_cc_a2_reg) && !(node->w.w & jit_regno_patch)) - jit_regset_setbit(&_jitc->reglive, node->w.w); + if ((value & jit_cc_a2_reg) && !(node->w.w & jit_regno_patch)) { + if (value & jit_cc_a2_chg) { + jit_regset_clrbit(&_jitc->reglive, node->w.w); + jit_regset_setbit(&_jitc->regmask, node->w.w); + } + else + jit_regset_setbit(&_jitc->reglive, node->w.w); + } if (jit_regset_set_p(&_jitc->regmask)) { bmp_zero(); jit_update(node->next, &_jitc->reglive, &_jitc->regmask); @@ -2039,8 +2169,11 @@ _jit_setup(jit_state_t *_jit, jit_block_t *block) if ((value & jit_cc_a2_reg) && !(node->w.w & jit_regno_patch) && jit_regset_tstbit(®mask, node->w.w)) { - jit_regset_clrbit(®mask, node->w.w); - jit_regset_setbit(®live, node->w.w); + live = !(value & jit_cc_a2_chg); + if (live || !jump) + jit_regset_clrbit(®mask, node->w.w); + if (live) + jit_regset_setbit(®live, node->w.w); } if (value & jit_cc_a0_jmp) jump = 1; @@ -2151,7 +2284,8 @@ _jit_update(jit_state_t *_jit, jit_node_t *node, if (!(node->w.w & jit_regno_patch)) { if (jit_regset_tstbit(mask, node->w.w)) { jit_regset_clrbit(mask, node->w.w); - jit_regset_setbit(live, node->w.w); + if (!(value & jit_cc_a2_chg)) + jit_regset_setbit(live, node->w.w); } } } @@ -2654,6 +2788,11 @@ _redundant_store(jit_state_t *_jit, jit_node_t *node, jit_bool_t jump) if (regno == jit_regno(iter->v.w)) return; } + if ((spec & (jit_cc_a2_reg|jit_cc_a2_chg)) == + (jit_cc_a2_reg|jit_cc_a2_chg)) { + if (regno == jit_regno(iter->w.w)) + return; + } break; } } @@ -2959,6 +3098,11 @@ _simplify(jit_state_t *_jit) _jitc->values[regno].kind = 0; ++_jitc->gen[regno]; } + if (info & jit_cc_a2_chg) { + regno = jit_regno(node->w.w); + _jitc->values[regno].kind = 0; + ++_jitc->gen[regno]; + } break; } } @@ -2994,6 +3138,9 @@ _register_change_p(jit_state_t *_jit, jit_node_t *node, jit_node_t *link, else if ((value & jit_cc_a1_reg) && node->v.w == regno && (value & jit_cc_a1_chg)) return (jit_reg_change); + else if ((value & jit_cc_a2_reg) && node->w.w == regno && + (value & jit_cc_a2_chg)) + return (jit_reg_change); } } diff --git a/size.c b/size.c index 59a7322c8..b19bcf615 100644 --- a/size.c +++ b/size.c @@ -80,6 +80,8 @@ main(int argc, char *argv[]) fprintf(fp, "#if defined(__ppc__)\n"); #elif defined(__powerpc__) fprintf(fp, "#if defined(__powerpc__)\n"); + fprintf(fp, "#if __BYTE_ORDER == %s\n", + __BYTE_ORDER == __BIG_ENDIAN ? "__BIG_ENDIAN" : "__LITTLE_ENDIAN"); #endif fprintf(fp, "#define JIT_INSTR_MAX %d\n", max); for (offset = 0; offset < jit_code_last_code; offset++) @@ -93,6 +95,7 @@ main(int argc, char *argv[]) #elif defined(__ppc__) fprintf(fp, "#endif /* __ppc__ */\n"); #elif defined(__powerpc__) + fprintf(fp, "#endif /* __BYTE_ORDER */\n"); fprintf(fp, "#endif /* __powerpc__ */\n"); #endif #if __X64 || __X32 @@ -100,7 +103,7 @@ main(int argc, char *argv[]) fprintf(fp, "# endif /* __X64_32 */\n"); fprintf(fp, "#endif /* __X64 */\n"); # else - fprintf(fp, "#if __X32\n"); + fprintf(fp, "#endif /* __X32 */\n"); # endif #else fprintf(fp, "#endif /* __WORDSIZE */\n");