guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 397/437: Implement new synthesized IR codes sequences


From: Andy Wingo
Subject: [Guile-commits] 397/437: Implement new synthesized IR codes sequences
Date: Mon, 2 Jul 2018 05:15:03 -0400 (EDT)

wingo pushed a commit to branch lightning
in repository guile.

commit d0a5bd8d3deec1574593b83dda4de361ae4bb623
Author: pcpa <address@hidden>
Date:   Thu Jun 4 18:53:07 2015 -0300

    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                | 634 +++++++++++++++++++++++++++---
 lib/jit_ppc.c                   | 347 +++++++++++-----
 lib/jit_print.c                 |  80 +++-
 lib/jit_rewind.c                | 186 +++++++++
 lib/jit_s390-fpu.c              |   4 +-
 lib/jit_s390-sz.c               | 846 ++++++++++++++++++++++------------------
 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                   | 234 +++++++++--
 lib/lightning.c                 | 173 +++++++-
 size.c                          |   5 +-
 35 files changed, 4388 insertions(+), 1143 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9b6ffff..34eeefa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,52 @@
-2015-06-25 Paulo Andrade <address@hidden>
+2015-06-04 Paulo Andrade <address@hidden>
+
+       * 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 <address@hidden>
 
        * 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 <address@hidden>
+2015-05-24 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-05-24 Paulo Andrade <address@hidden>
 
        * lib/jit_aarch64-fpu.c, lib/jit_aarch64.c: Correct base
        aarch64 varargs code.
 
-2015-06-24 Paulo Andrade <address@hidden>
+2015-05-24 Paulo Andrade <address@hidden>
 
        * check/lightning.c: Clearly run check if clang is the system
        compiler.
 
-2015-06-20 Paulo Andrade <address@hidden>
+2015-05-20 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-05-20 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-05-19 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-05-10 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-05-10 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-05-10 Paulo Andrade <address@hidden>
 
        * lib/jit_ia64.c: Implement inline assembly cache flush,
        required on multiprocessor systems.
 
-2015-06-06 Paulo Andrade <address@hidden>
+2015-05-06 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-05-05 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-05-02 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-05-01 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-04-30 Paulo Andrade <address@hidden>
 
        * 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 <address@hidden>
+2015-04-27 Paulo Andrade <address@hidden>
 
        * 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 aa32581..b4a46e2 100644
--- a/include/lightning.h
+++ b/include/lightning.h
@@ -154,11 +154,12 @@ typedef jit_int32_t               jit_fpr_t;
 #  include <lightning/jit_alpha.h>
 #endif
 
-#define jit_flag_node          0x00000001 /* patch node not absolute */
-#define jit_flag_patch         0x00000002 /* jump already patched */
-#define jit_flag_data          0x00000004 /* data in the constant pool */
-#define jit_flag_use           0x00000008 /* do not remove marker label */
-#define jit_flag_head          0x00100000 /* label reached by normal flow */
+#define jit_flag_node          0x0001  /* patch node not absolute */
+#define jit_flag_patch         0x0002  /* jump already patched */
+#define jit_flag_data          0x0004  /* data in the constant pool */
+#define jit_flag_use           0x0008  /* do not remove marker label */
+#define jit_flag_synth         0x0010  /* synthesized instruction */
+#define jit_flag_head          0x1000  /* label reached by normal flow */
 
 #define JIT_R(index)           jit_r(index)
 #define JIT_V(index)           jit_v(index)
@@ -200,14 +201,19 @@ typedef enum {
     jit_code_prolog,
 
 #define jit_ellipsis()         _jit_ellipsis(_jit)
+    jit_code_ellipsis,
 #define jit_allocai(u)         _jit_allocai(_jit,u)
 #define jit_allocar(u, v)      _jit_allocar(_jit,u,v)
+    jit_code_allocai,          jit_code_allocar,
 
 #define jit_arg()              _jit_arg(_jit)
+    jit_code_arg,
 #define jit_getarg_c(u,v)      _jit_getarg_c(_jit,u,v)
 #define jit_getarg_uc(u,v)     _jit_getarg_uc(_jit,u,v)
+    jit_code_getarg_c,         jit_code_getarg_uc,
 #define jit_getarg_s(u,v)      _jit_getarg_s(_jit,u,v)
 #define jit_getarg_us(u,v)     _jit_getarg_us(_jit,u,v)
+    jit_code_getarg_s,         jit_code_getarg_us,
 #define jit_getarg_i(u,v)      _jit_getarg_i(_jit,u,v)
 #if __WORDSIZE == 32
 #  define jit_getarg(u,v)      jit_getarg_i(u,v)
@@ -216,9 +222,11 @@ typedef enum {
 #  define jit_getarg_ui(u,v)   _jit_getarg_ui(_jit,u,v)
 #  define jit_getarg_l(u,v)    _jit_getarg_l(_jit,u,v)
 #endif
+    jit_code_getarg_i,         jit_code_getarg_ui,
+    jit_code_getarg_l,
 #  define jit_putargr(u,v)     _jit_putargr(_jit,u,v)
 #  define jit_putargi(u,v)     _jit_putargi(_jit,u,v)
-    jit_code_arg,
+    jit_code_putargr,          jit_code_putargi,
 
 #define jit_va_start(u)                jit_new_node_w(jit_code_va_start, u)
     jit_code_va_start,
@@ -532,17 +540,24 @@ typedef enum {
     jit_code_callr,            jit_code_calli,
 
 #define jit_prepare()          _jit_prepare(_jit)
+    jit_code_prepare,
 #define jit_pushargr(u)                _jit_pushargr(_jit,u)
 #define jit_pushargi(u)                _jit_pushargi(_jit,u)
+    jit_code_pushargr,         jit_code_pushargi,
 #define jit_finishr(u)         _jit_finishr(_jit,u)
 #define jit_finishi(u)         _jit_finishi(_jit,u)
+    jit_code_finishr,          jit_code_finishi,
 #define jit_ret()              _jit_ret(_jit)
+    jit_code_ret,
 #define jit_retr(u)            _jit_retr(_jit,u)
 #define jit_reti(u)            _jit_reti(_jit,u)
+    jit_code_retr,             jit_code_reti,
 #define jit_retval_c(u)                _jit_retval_c(_jit,u)
 #define jit_retval_uc(u)       _jit_retval_uc(_jit,u)
+    jit_code_retval_c,         jit_code_retval_uc,
 #define jit_retval_s(u)                _jit_retval_s(_jit,u)
 #define jit_retval_us(u)       _jit_retval_us(_jit,u)
+    jit_code_retval_s,         jit_code_retval_us,
 #define jit_retval_i(u)                _jit_retval_i(_jit,u)
 #if __WORDSIZE == 32
 #  define jit_retval(u)                jit_retval_i(u)
@@ -551,16 +566,19 @@ typedef enum {
 #  define jit_retval_ui(u)     _jit_retval_ui(_jit,u)
 #  define jit_retval_l(u)      _jit_retval_l(_jit,u)
 #endif
-    /* Usually should not need to call directly, but useful if need
-     * to get a label just before a jit_prolog() call */
+    jit_code_retval_i,         jit_code_retval_ui,
+    jit_code_retval_l,
+
 #define jit_epilog()           _jit_epilog(_jit)
     jit_code_epilog,
 
 #define jit_arg_f()            _jit_arg_f(_jit)
+    jit_code_arg_f,
 #define jit_getarg_f(u,v)      _jit_getarg_f(_jit,u,v)
+    jit_code_getarg_f,
 #define jit_putargr_f(u,v)     _jit_putargr_f(_jit,u,v)
 #define jit_putargi_f(u,v)     _jit_putargi_f(_jit,u,v)
-    jit_code_arg_f,
+    jit_code_putargr_f,                jit_code_putargi_f,
 
 #define jit_addr_f(u,v,w)      jit_new_node_www(jit_code_addr_f,u,v,w)
 #define jit_addi_f(u,v,w)      jit_new_node_wwf(jit_code_addi_f,u,v,w)
@@ -699,15 +717,20 @@ typedef enum {
 
 #define jit_pushargr_f(u)      _jit_pushargr_f(_jit,u)
 #define jit_pushargi_f(u)      _jit_pushargi_f(_jit,u)
+    jit_code_pushargr_f,       jit_code_pushargi_f,
 #define jit_retr_f(u)          _jit_retr_f(_jit,u)
 #define jit_reti_f(u)          _jit_reti_f(_jit,u)
+    jit_code_retr_f,           jit_code_reti_f,
 #define jit_retval_f(u)                _jit_retval_f(_jit,u)
+    jit_code_retval_f,
 
 #define jit_arg_d()            _jit_arg_d(_jit)
+    jit_code_arg_d,
 #define jit_getarg_d(u,v)      _jit_getarg_d(_jit,u,v)
+    jit_code_getarg_d,
 #define jit_putargr_d(u,v)     _jit_putargr_d(_jit,u,v)
 #define jit_putargi_d(u,v)     _jit_putargi_d(_jit,u,v)
-    jit_code_arg_d,
+    jit_code_putargr_d,                jit_code_putargi_d,
 
 #define jit_addr_d(u,v,w)      jit_new_node_www(jit_code_addr_d,u,v,w)
 #define jit_addi_d(u,v,w)      jit_new_node_wwd(jit_code_addi_d,u,v,w)
@@ -847,9 +870,12 @@ typedef enum {
 
 #define jit_pushargr_d(u)      _jit_pushargr_d(_jit,u)
 #define jit_pushargi_d(u)      _jit_pushargi_d(_jit,u)
+    jit_code_pushargr_d,       jit_code_pushargi_d,
 #define jit_retr_d(u)          _jit_retr_d(_jit,u)
 #define jit_reti_d(u)          _jit_reti_d(_jit,u)
+    jit_code_retr_d,           jit_code_reti_d,
 #define jit_retval_d(u)                _jit_retval_d(_jit,u)
+    jit_code_retval_d,
 
     /* Special internal backend specific codes */
     jit_code_movr_w_f,         jit_code_movr_ww_d,     /* w* -> f|d */
@@ -869,7 +895,6 @@ typedef enum {
 #define jit_movr_d_w(u, v)     jit_new_node_ww(jit_code_movr_d_w, u, v)
 #define jit_movi_d_w(u, v)     jit_new_node_wd(jit_code_movi_d_w, u, v)
 
-    jit_code_x86_retval_f,     jit_code_x86_retval_d,
     jit_code_last_code
 } jit_code_t;
 
@@ -994,6 +1019,12 @@ extern jit_node_t *_jit_new_node(jit_state_t*, 
jit_code_t);
 #define jit_new_node_w(c,u)    _jit_new_node_w(_jit,c,u)
 extern jit_node_t *_jit_new_node_w(jit_state_t*, jit_code_t,
                                   jit_word_t);
+#define jit_new_node_f(c,u)    _jit_new_node_f(_jit,c,u)
+extern jit_node_t *_jit_new_node_f(jit_state_t*, jit_code_t,
+                                  jit_float32_t);
+#define jit_new_node_d(c,u)    _jit_new_node_d(_jit,c,u)
+extern jit_node_t *_jit_new_node_d(jit_state_t*, jit_code_t,
+                                  jit_float64_t);
 #define jit_new_node_p(c,u)    _jit_new_node_p(_jit,c,u)
 extern jit_node_t *_jit_new_node_p(jit_state_t*, jit_code_t,
                                   jit_pointer_t);
@@ -1003,6 +1034,12 @@ extern jit_node_t 
*_jit_new_node_ww(jit_state_t*,jit_code_t,
 #define jit_new_node_wp(c,u,v) _jit_new_node_wp(_jit,c,u,v)
 extern jit_node_t *_jit_new_node_wp(jit_state_t*,jit_code_t,
                                    jit_word_t, jit_pointer_t);
+#define jit_new_node_fp(c,u,v) _jit_new_node_fp(_jit,c,u,v)
+extern jit_node_t *_jit_new_node_fp(jit_state_t*,jit_code_t,
+                                   jit_float32_t, jit_pointer_t);
+#define jit_new_node_dp(c,u,v) _jit_new_node_dp(_jit,c,u,v)
+extern jit_node_t *_jit_new_node_dp(jit_state_t*,jit_code_t,
+                                   jit_float64_t, jit_pointer_t);
 #define jit_new_node_pw(c,u,v) _jit_new_node_pw(_jit,c,u,v)
 extern jit_node_t *_jit_new_node_pw(jit_state_t*,jit_code_t,
                                    jit_pointer_t, jit_word_t);
diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h
index 953e361..0730439 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 009e6de..57de4fd 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 1918bbe..75a5e78 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 9273b45..0f42590 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 d6df970..c605d5b 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 ea0abb1..42744cd 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 204235d..aa991f3 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 4da9c25..e33d5fe 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 52d08c7..e3773a7 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 cadd312..0903a69 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 94e9595..e35d46e 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 9e953ac..d954c30 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 b0b8954..f5345c0 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 f43a3fa..f9a2568 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));
-
-    /* Update vararg stack pointer. */
-    addi(rn(reg), rn(reg), sizeof(jit_word_t));
-    stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
+    ldr(r0, r1);
 
-    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 0294bde..e995985 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 8e30a68..208ef32 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 ffbeac6..eac92a0 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)
-{
-    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)
+static jit_node_t *
+_jit_make_arg(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++;
@@ -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 02cb8db..028ea54 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 e3f9114..c0196ed 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 7781954..7a0535a 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));
-
-    /* Update vararg stack pointer. */
-    addi(rn(reg), rn(reg), sizeof(jit_float64_t));
-    stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
+    ldr_d(r0, r1);
 
-    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 8974c7f..c206b0f 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,414 @@
     4, /* extr_us */
     4, /* extr_i */
     4, /* extr_ui */
-#  if __BYTE_ORDER == __BIG_ENDIAN
     4, /* htonr_us */
     4, /* htonr_ui */
     4, /* htonr_ul */
-#else
+    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 */
+    28,        /* callr */
+    56,        /* 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 /* __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 */
-#endif
     8, /* ldr_c */
     28,        /* ldi_c */
     4, /* ldr_uc */
@@ -837,19 +1333,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 +1355,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 +1402,30 @@
     16,        /* bxsubi */
     12,        /* bxsubr_u */
     16,        /* bxsubi_u */
-    0, /* jmpr */
+    8, /* jmpr */
     4, /* jmpi */
-    28,        /* callr */
-    56,        /* calli */
-    72,        /* epilog */
+    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 */
@@ -961,11 +1475,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 +1508,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 +1566,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 +1599,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 +1613,6 @@
     0, /* movi_d_ww */
     0, /* movr_d_w */
     0, /* movi_d_w */
-    0, /* x86_retval_f */
-    0, /* x86_retval_d */
+#endif /* __BYTE_ORDER */
 #endif /* __powerpc__ */
 #endif /* __WORDSIZE */
diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c
index 940dc06..a087ecb 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++;
+       _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++;
+    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 a95499c..1820e38 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 0000000..f796d0f
--- /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 <lightning.h>
+#include <lightning/jit_private.h>
+
+#if PROTO
+#  define free_synth_list(node)                _free_synth_list(_jit,node)
+static jit_node_t *_free_synth_list(jit_state_t*,jit_node_t*);
+#define rewind_prolog()                        _rewind_prolog(_jit)
+static void _rewind_prolog(jit_state_t*);
+#define rewind_prepare()               _rewind_prepare(_jit)
+static void _rewind_prepare(jit_state_t*);
+#endif
+
+#if CODE
+/*
+ * Implementation
+ */
+static jit_node_t *
+_free_synth_list(jit_state_t *_jit, jit_node_t *node)
+{
+    jit_node_t         *next;
+    next = node->next;
+    free_node(node);
+    for (node = next; node && (node->flag & jit_flag_synth); node = next) {
+       next = node->next;
+       free_node(node);
+    }
+    return (next);
+}
+
+static void
+_rewind_prolog(jit_state_t *_jit)
+{
+    jit_node_t         *node;
+    jit_node_t         *next;
+    _jitc->function->self.size = stack_framesize;
+#if __arm__
+    assert(jit_cpu.abi);
+    _jitc->function->self.size += 64;
+#endif
+    _jitc->function->self.argi =
+       _jitc->function->self.argf = _jitc->function->self.argn = 0;
+    _jitc->tail = _jitc->function->prolog;
+    node = _jitc->tail->next;
+    _jitc->tail->next = (jit_node_t *)0;
+    _jitc->tail->link = (jit_node_t *)0;
+    for (; node; node = next) {
+       next = node->next;
+       switch (node->code) {
+           case jit_code_arg:
+               node->next = (jit_node_t *)0;
+               jit_make_arg(node);
+               break;
+           case jit_code_arg_f:
+               node->next = (jit_node_t *)0;
+               jit_make_arg_f(node);
+               break;
+           case jit_code_arg_d:
+               node->next = (jit_node_t *)0;
+               jit_make_arg_d(node);
+               break;
+           case jit_code_getarg_c:
+               jit_getarg_c(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_getarg_uc:
+               jit_getarg_uc(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_getarg_s:
+               jit_getarg_s(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_getarg_us:
+               jit_getarg_us(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_getarg_i:
+               jit_getarg_i(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_getarg_f:
+               jit_getarg_f(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_getarg_d:
+               jit_getarg_d(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_putargr:
+               jit_putargr(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_putargi:
+               jit_putargi(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_putargr_f:
+               jit_putargr_f(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_putargi_f:
+               jit_putargi_f(node->u.f, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_putargr_d:
+               jit_putargr_d(node->u.w, node->v.n);
+               next = free_synth_list(node);
+               break;
+           case jit_code_putargi_d:
+               jit_putargi_d(node->u.d, node->v.n);
+               next = free_synth_list(node);
+               break;
+           default:
+               node->next = (jit_node_t *)0;
+               link_node(node);
+               break;
+       }
+    }
+}
+
+static void
+_rewind_prepare(jit_state_t *_jit)
+{
+    jit_node_t         *node;
+    jit_node_t         *next;
+    _jitc->function->call.argi =
+       _jitc->function->call.argf =
+       _jitc->function->call.size = 0;
+    _jitc->tail = _jitc->prepare;
+    node = _jitc->tail->next;
+    _jitc->tail->next = (jit_node_t *)0;
+    _jitc->tail->link = (jit_node_t *)0;
+    for (; node; node = next) {
+       next = node->next;
+       switch (node->code) {
+           case jit_code_pushargr:
+               jit_pushargr(node->u.w);
+               next = free_synth_list(node);
+               break;
+           case jit_code_pushargi:
+               jit_pushargi(node->u.w);
+               next = free_synth_list(node);
+               break;
+           case jit_code_pushargr_f:
+               jit_pushargr_f(node->u.w);
+               next = free_synth_list(node);
+               break;
+           case jit_code_pushargi_f:
+               jit_pushargi_f(node->u.f);
+               next = free_synth_list(node);
+               break;
+           case jit_code_pushargr_d:
+               jit_pushargr_d(node->u.w);
+               next = free_synth_list(node);
+               break;
+           case jit_code_pushargi_d:
+               jit_pushargi_d(node->u.d);
+               next = free_synth_list(node);
+               break;
+           default:
+               node->next = (jit_node_t *)0;
+               link_node(node);
+               break;
+       }
+    }
+}
+#endif
diff --git a/lib/jit_s390-fpu.c b/lib/jit_s390-fpu.c
index b84aa4c..b887fa2 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 6ca5e64..d1d8861 100644
--- a/lib/jit_s390-sz.c
+++ b/lib/jit_s390-sz.c
@@ -1,366 +1,407 @@
 
 #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 */
+#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 */
-    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 */
+    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 */
+    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 68
+#define JIT_INSTR_MAX 104
     0, /* data */
     0, /* live */
     6, /* align */
@@ -369,11 +410,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 +519,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 +541,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 +588,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 +661,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 +694,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 +752,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 +785,11 @@
     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 1f59745..c853aac 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 f062ae0..473c0ca 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 c3c8297..097110a 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 d634db4..feb4c48 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 cbdf5a0..2e3ba80 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,43 +2066,71 @@ _emit_code(jit_state_t *_jit)
                epilog(node);
                _jitc->function = NULL;
                break;
+           case jit_code_va_start:
+               vastart(rn(node->u.w));
+               break;
+           case jit_code_va_arg:
+               vaarg(rn(node->u.w), rn(node->v.w));
+               break;
+           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_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
-           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);
+#endif
                break;
-           case jit_code_x86_retval_d:
+           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);
-               break;
 #endif
-           case jit_code_va_start:
-               vastart(rn(node->u.w));
-               break;
-           case jit_code_va_arg:
-               vaarg(rn(node->u.w), rn(node->v.w));
-               break;
-           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_arg:
-           case jit_code_arg_f:                case jit_code_arg_d:
-           case jit_code_va_end:
                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 a7eb271..9436422 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)
@@ -938,6 +965,26 @@ _jit_new_node_w(jit_state_t *_jit, jit_code_t code,
 }
 
 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)
 {
@@ -966,6 +1013,28 @@ _jit_new_node_wp(jit_state_t *_jit, jit_code_t code,
 }
 
 jit_node_t *
+_jit_new_node_fp(jit_state_t *_jit, jit_code_t code,
+                jit_float32_t u, jit_pointer_t v)
+{
+    jit_node_t         *node = new_node(code);
+    assert(!_jitc->realize);
+    node->u.f = u;
+    node->v.w = (jit_word_t)v;
+    return (link_node(node));
+}
+
+jit_node_t *
+_jit_new_node_dp(jit_state_t *_jit, jit_code_t code,
+                jit_float64_t u, jit_pointer_t v)
+{
+    jit_node_t         *node = new_node(code);
+    assert(!_jitc->realize);
+    node->u.d = u;
+    node->v.w = (jit_word_t)v;
+    return (link_node(node));
+}
+
+jit_node_t *
 _jit_new_node_pw(jit_state_t *_jit, jit_code_t code,
                 jit_pointer_t u, jit_word_t v)
 {
@@ -1163,7 +1232,7 @@ _jit_prepare(jit_state_t *_jit)
     _jitc->function->call.argi =
        _jitc->function->call.argf =
        _jitc->function->call.size = 0;
-    _jitc->prepare = 1;
+    _jitc->prepare = jit_new_node(jit_code_prepare);
 }
 
 void
@@ -1182,28 +1251,69 @@ _jit_classify(jit_state_t *_jit, jit_code_t code)
     jit_int32_t                mask;
 
     switch (code) {
-       case jit_code_data:     case jit_code_align:    case jit_code_save:
-       case jit_code_load:     case jit_code_name:     case jit_code_label:
-       case jit_code_note:     case jit_code_prolog:   case jit_code_epilog:
+       case jit_code_data:     case jit_code_save:     case jit_code_load:
+       case jit_code_name:     case jit_code_label:    case jit_code_note:
+       case jit_code_prolog:   case jit_code_ellipsis: case jit_code_epilog:
+       case jit_code_ret:      case jit_code_prepare:
            mask = 0;
            break;
        case jit_code_live:     case jit_code_va_end:
+       case jit_code_retr:     case jit_code_retr_f:   case jit_code_retr_d:
+       case jit_code_pushargr: case jit_code_pushargr_f:
+       case jit_code_pushargr_d:
+       case jit_code_finishr:  /* synthesized will set jit_cc_a0_jmp */
            mask = jit_cc_a0_reg;
            break;
-       case jit_code_arg:      case jit_code_arg_f:    case jit_code_arg_d:
+       case jit_code_align:    case jit_code_reti:     case jit_code_pushargi:
+       case jit_code_finishi:  /* synthesized will set jit_cc_a0_jmp */
            mask = jit_cc_a0_int;
            break;
+       case jit_code_reti_f:   case jit_code_pushargi_f:
+           mask = jit_cc_a0_flt;
+           break;
+       case jit_code_reti_d:   case jit_code_pushargi_d:
+           mask = jit_cc_a0_dbl;
+           break;
+       case jit_code_allocai:
+           mask = jit_cc_a0_int|jit_cc_a1_int;
+           break;
+       case jit_code_arg:      case jit_code_arg_f:    case jit_code_arg_d:
+           mask = jit_cc_a0_int|jit_cc_a0_arg;
+           break;
        case jit_code_calli:    case jit_code_jmpi:
            mask = jit_cc_a0_jmp;
            break;
        case jit_code_callr:    case jit_code_jmpr:
            mask = jit_cc_a0_reg|jit_cc_a0_jmp;
            break;
-       case jit_code_x86_retval_f:
-       case jit_code_x86_retval_d:
+       case jit_code_retval_c: case jit_code_retval_uc:
+       case jit_code_retval_s: case jit_code_retval_us:
+       case jit_code_retval_i: case jit_code_retval_ui:
+       case jit_code_retval_l:
+       case jit_code_retval_f: case jit_code_retval_d:
        case jit_code_va_start:
            mask = jit_cc_a0_reg|jit_cc_a0_chg;
            break;
+       case jit_code_getarg_c: case jit_code_getarg_uc:
+       case jit_code_getarg_s: case jit_code_getarg_us:
+       case jit_code_getarg_i: case jit_code_getarg_ui:
+       case jit_code_getarg_l:
+       case jit_code_getarg_f: case jit_code_getarg_d:
+           mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_arg;
+           break;
+       case jit_code_putargr:  case jit_code_putargr_f:
+       case jit_code_putargr_d:
+           mask = jit_cc_a0_reg|jit_cc_a1_arg;
+           break;
+       case jit_code_putargi:
+           mask = jit_cc_a0_int|jit_cc_a1_arg;
+           break;
+       case jit_code_putargi_f:
+           mask = jit_cc_a0_flt|jit_cc_a1_arg;
+           break;
+       case jit_code_putargi_d:
+           mask = jit_cc_a0_dbl|jit_cc_a1_arg;
+           break;
        case jit_code_movi:     case jit_code_ldi_c:    case jit_code_ldi_uc:
        case jit_code_ldi_s:    case jit_code_ldi_us:   case jit_code_ldi_i:
        case jit_code_ldi_ui:   case jit_code_ldi_l:    case jit_code_ldi_f:
@@ -1337,6 +1447,8 @@ _jit_classify(jit_state_t *_jit, jit_code_t code)
        case jit_code_bordi_d:  case jit_code_bunordi_d:
            mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl;
            break;
+       case jit_code_allocar:  /* synthesized instructions make it
+                                * equivalent to jit_cc_a0_chg */
        case jit_code_str_c:    case jit_code_str_s:    case jit_code_str_i:
        case jit_code_str_l:    case jit_code_str_f:    case jit_code_str_d:
            mask = jit_cc_a0_reg|jit_cc_a1_reg;
@@ -1512,7 +1624,15 @@ _jit_optimize(jit_state_t *_jit)
                break;
            default:
 #if JIT_HASH_CONSTS
-               if (mask & jit_cc_a1_flt) {
+               if (mask & jit_cc_a0_flt) {
+                   node->u.p = jit_data(&node->u.f, sizeof(jit_float32_t), 4);
+                   node->flag |= jit_flag_node | jit_flag_data;
+               }
+               else if (mask & jit_cc_a0_dbl) {
+                   node->u.p = jit_data(&node->u.d, sizeof(jit_float64_t), 8);
+                   node->flag |= jit_flag_node | jit_flag_data;
+               }
+               else if (mask & jit_cc_a1_flt) {
                    node->v.p = jit_data(&node->v.f, sizeof(jit_float32_t), 4);
                    node->flag |= jit_flag_node | jit_flag_data;
                }
@@ -1546,6 +1666,10 @@ _jit_optimize(jit_state_t *_jit)
                        (jit_cc_a1_reg|jit_cc_a1_chg))
                        jit_regset_setbit(&_jitc->function->regset,
                                          jit_regno(node->v.w));
+                   if ((mask & (jit_cc_a2_reg|jit_cc_a2_chg)) ==
+                       (jit_cc_a2_reg|jit_cc_a2_chg))
+                       jit_regset_setbit(&_jitc->function->regset,
+                                         jit_regno(node->w.w));
                }
                break;
        }
@@ -1632,8 +1756,14 @@ _jit_reglive(jit_state_t *_jit, jit_node_t *node)
                else
                    jit_regset_setbit(&_jitc->reglive, node->v.w);
            }
-           if ((value & jit_cc_a2_reg) && !(node->w.w & jit_regno_patch))
-               jit_regset_setbit(&_jitc->reglive, node->w.w);
+           if ((value & jit_cc_a2_reg) && !(node->w.w & jit_regno_patch)) {
+               if (value & jit_cc_a2_chg) {
+                   jit_regset_clrbit(&_jitc->reglive, node->w.w);
+                   jit_regset_setbit(&_jitc->regmask, node->w.w);
+               }
+               else
+                   jit_regset_setbit(&_jitc->reglive, node->w.w);
+           }
            if (jit_regset_set_p(&_jitc->regmask)) {
                bmp_zero();
                jit_update(node->next, &_jitc->reglive, &_jitc->regmask);
@@ -2039,8 +2169,11 @@ _jit_setup(jit_state_t *_jit, jit_block_t *block)
                if ((value & jit_cc_a2_reg) &&
                    !(node->w.w & jit_regno_patch) &&
                    jit_regset_tstbit(&regmask, node->w.w)) {
-                   jit_regset_clrbit(&regmask, node->w.w);
-                   jit_regset_setbit(&reglive, node->w.w);
+                   live = !(value & jit_cc_a2_chg);
+                   if (live || !jump)
+                       jit_regset_clrbit(&regmask, node->w.w);
+                   if (live)
+                       jit_regset_setbit(&reglive, node->w.w);
                }
                if (value & jit_cc_a0_jmp)
                    jump = 1;
@@ -2151,7 +2284,8 @@ _jit_update(jit_state_t *_jit, jit_node_t *node,
                    if (!(node->w.w & jit_regno_patch)) {
                        if (jit_regset_tstbit(mask, node->w.w)) {
                            jit_regset_clrbit(mask, node->w.w);
-                           jit_regset_setbit(live, node->w.w);
+                           if (!(value & jit_cc_a2_chg))
+                               jit_regset_setbit(live, node->w.w);
                        }
                    }
                }
@@ -2654,6 +2788,11 @@ _redundant_store(jit_state_t *_jit, jit_node_t *node, 
jit_bool_t jump)
                    if (regno == jit_regno(iter->v.w))
                        return;
                }
+               if ((spec & (jit_cc_a2_reg|jit_cc_a2_chg)) ==
+                   (jit_cc_a2_reg|jit_cc_a2_chg)) {
+                   if (regno == jit_regno(iter->w.w))
+                       return;
+               }
                break;
        }
     }
@@ -2959,6 +3098,11 @@ _simplify(jit_state_t *_jit)
                    _jitc->values[regno].kind = 0;
                    ++_jitc->gen[regno];
                }
+               if (info & jit_cc_a2_chg) {
+                   regno = jit_regno(node->w.w);
+                   _jitc->values[regno].kind = 0;
+                   ++_jitc->gen[regno];
+               }
                break;
        }
     }
@@ -2994,6 +3138,9 @@ _register_change_p(jit_state_t *_jit, jit_node_t *node, 
jit_node_t *link,
                else if ((value & jit_cc_a1_reg) && node->v.w == regno &&
                         (value & jit_cc_a1_chg))
                    return (jit_reg_change);
+               else if ((value & jit_cc_a2_reg) && node->w.w == regno &&
+                        (value & jit_cc_a2_chg))
+                   return (jit_reg_change);
        }
     }
 
diff --git a/size.c b/size.c
index 59a7322..b19bcf6 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");



reply via email to

[Prev in Thread] Current Thread [Next in Thread]