guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 393/437: Intermediate, fully functional, rework for vari


From: Andy Wingo
Subject: [Guile-commits] 393/437: Intermediate, fully functional, rework for variadic functions
Date: Mon, 2 Jul 2018 05:15:02 -0400 (EDT)

wingo pushed a commit to branch lightning
in repository guile.

commit 0b6cc01eeae66bac4573cc29f346368657ac9c73
Author: pcpa <address@hidden>
Date:   Mon May 25 15:20:24 2015 -0300

    Intermediate, fully functional, rework for variadic functions
    
        * check/cva_list.c: New file implementing a test to ensure
        the value returned by jit_va_start is a valid C va_list.
    
        * check/va_list.ok: New simple helper file, as now the
        va_list.tst test is enabled.
    
        * check/va_list.tst: Rewritten for an extensive variadic
        jit functions test.
    
        * check/Makefile.am: Update for the new tests.
    
        * lib/jit_arm-cpu.c, lib/jit_arm-swf.c, lib/jit_arm-vfp.c,
        lib/jit_arm.c: Correct broken software float in a previous
        commit. Note that the hard float abi implementation is known
        broken at this time, for special cases involving variadic
        functions, and should be corrected next.
    
        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.
---
 ChangeLog         |   22 +
 check/Makefile.am |   29 +-
 check/cva_list.c  | 1187 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 check/va_list.ok  |    1 +
 check/va_list.tst |  749 ++++++++++++++++++++++++++++++++-
 lib/jit_arm-cpu.c |   91 +---
 lib/jit_arm-swf.c |   22 +-
 lib/jit_arm-vfp.c |   22 +-
 lib/jit_arm.c     |   38 +-
 lib/jit_x86-cpu.c |   36 +-
 lib/jit_x86-sz.c  |  130 +++---
 lib/jit_x86.c     |   13 +-
 12 files changed, 2107 insertions(+), 233 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 17e8c13..9b6ffff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2015-06-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.
+
+       * check/va_list.ok: New simple helper file, as now the
+       va_list.tst test is enabled.
+
+       * check/va_list.tst: Rewritten for an extensive variadic
+       jit functions test.
+
+       * check/Makefile.am: Update for the new tests.
+
+       * lib/jit_arm-cpu.c, lib/jit_arm-swf.c, lib/jit_arm-vfp.c,
+       lib/jit_arm.c: Correct broken software float in a previous
+       commit. Note that the hard float abi implementation is known
+       broken at this time, for special cases involving variadic
+       functions, and should be corrected next.
+
+       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>
 
        * lib/Makefile.am: Bump library major. This is a preparation
diff --git a/check/Makefile.am b/check/Makefile.am
index f3c8eda..3b7d561 100644
--- a/check/Makefile.am
+++ b/check/Makefile.am
@@ -16,7 +16,7 @@
 
 AM_CFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE
 
-check_PROGRAMS = lightning ccall self setcode nodata ctramp carg
+check_PROGRAMS = lightning ccall self setcode nodata ctramp carg cva_list
 
 lightning_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
 lightning_SOURCES = lightning.c
@@ -39,6 +39,9 @@ ctramp_SOURCES = ctramp.c
 carg_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
 carg_SOURCES = carg.c
 
+cva_list_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
+cva_list_SOURCES = cva_list.c
+
 $(top_builddir)/lib/liblightning.la:
        cd $(top_builddir)/lib; $(MAKE) $(AM_MAKEFLAGS) liblightning.la
 
@@ -96,6 +99,7 @@ EXTRA_DIST =                          \
        ranger.tst      ranger.ok       \
        ret.tst         ret.ok          \
        tramp.tst       tramp.ok        \
+       va_list.tst     va_list.ok      \
        check.sh                        \
        check.x87.sh                    \
        check.arm.sh    check.swf.sh    \
@@ -123,7 +127,8 @@ base_TESTS =                                \
        clobber carry call              \
        float jmpr put                  \
        qalu_mul qalu_div               \
-       range ranger ret tramp
+       range ranger ret tramp          \
+       va_list
 
 $(base_TESTS): check.sh
        $(LN_S) $(srcdir)/check.sh $@
@@ -148,7 +153,8 @@ x87_TESTS =                                 \
        fop_abs.x87 fop_sqrt.x87                \
        varargs.x87 stack.x87                   \
        clobber.x87 carry.x87 call.x87          \
-       float.x87 jmpr.x87 put.x87
+       float.x87 jmpr.x87 put.x87              \
+       va_list.x87
 $(x87_TESTS):  check.x87.sh
        $(LN_S) $(srcdir)/check.x87.sh $@
 TESTS += $(x87_TESTS)
@@ -170,7 +176,8 @@ x87_nodata_TESTS =                                          
        \
        fop_abs.x87.nodata fop_sqrt.x87.nodata                          \
        varargs.x87.nodata stack.x87.nodata                             \
        clobber.x87.nodata carry.x87.nodata call.x87.nodata             \
-       float.x87.nodata jmpr.x87.nodata put.x87.nodata
+       float.x87.nodata jmpr.x87.nodata put.x87.nodata                 \
+       va_list.x87.nodata
 $(x87_nodata_TESTS):   check.x87.nodata.sh
        $(LN_S) $(srcdir)/check.x87.nodata.sh $@
 TESTS += $(x87_nodata_TESTS)
@@ -195,7 +202,7 @@ arm_TESTS =                                 \
        varargs.arm stack.arm                   \
        clobber.arm carry.arm call.arm          \
        float.arm jmpr.arm tramp.arm range.arm  \
-       ranger.arm put.arm
+       ranger.arm put.arm va_list.arm
 $(arm_TESTS):  check.arm.sh
        $(LN_S) $(srcdir)/check.arm.sh $@
 TESTS += $(arm_TESTS)
@@ -220,7 +227,7 @@ swf_TESTS =                                 \
        varargs.swf stack.swf                   \
        clobber.swf carry.swf call.swf          \
        float.swf jmpr.swf tramp.swf range.swf  \
-       ranger.swf put.swf
+       ranger.swf put.swf va_list.swf
 $(swf_TESTS):  check.swf.sh
        $(LN_S) $(srcdir)/check.swf.sh $@
 TESTS += $(swf_TESTS)
@@ -243,7 +250,7 @@ arm_swf_TESTS =                                             
        \
        varargs.arm.swf stack.arm.swf                           \
        clobber.arm.swf carry.arm.swf call.arm.swf              \
        float.arm.swf jmpr.arm.swf tramp.arm.swf range.arm.swf  \
-       ranger.arm.swf put.arm.swf
+       ranger.arm.swf put.arm.swf va_list.arm.swf
 $(arm_swf_TESTS):      check.arm.swf.sh
        $(LN_S) $(srcdir)/check.arm.swf.sh $@
 TESTS += $(arm_swf_TESTS)
@@ -267,7 +274,8 @@ arm4_swf_TESTS =                                            
\
        varargs.arm4.swf stack.arm4.swf                         \
        clobber.arm4.swf carry.arm4.swf call.arm4.swf           \
        float.arm4.swf jmpr.arm4.swf tramp.arm4.swf             \
-       range.arm4.swf ranger.arm4.swf put.arm4.swf
+       range.arm4.swf ranger.arm4.swf put.arm4.swf             \
+       va_list.arm4.swf
 $(arm4_swf_TESTS):     check.arm4.swf.sh
        $(LN_S) $(srcdir)/check.arm4.swf.sh $@
 TESTS += $(arm4_swf_TESTS)
@@ -293,13 +301,14 @@ nodata_TESTS =                                            
\
        varargs.nodata stack.nodata                     \
        clobber.nodata carry.nodata call.nodata         \
        float.nodata jmpr.nodata tramp.nodata           \
-       range.nodata ranger.nodata put.nodata
+       range.nodata ranger.nodata put.nodata           \
+       va_list.nodata
 $(nodata_TESTS):       check.nodata.sh
        $(LN_S) $(srcdir)/check.nodata.sh $@
 TESTS += $(nodata_TESTS)
 endif
 
-TESTS += ccall self setcode nodata ctramp carg
+TESTS += ccall self setcode nodata ctramp carg cva_list
 CLEANFILES = $(TESTS)
 
 #TESTS_ENVIRONMENT=$(srcdir)/run-test;
diff --git a/check/cva_list.c b/check/cva_list.c
new file mode 100644
index 0000000..350d796
--- /dev/null
+++ b/check/cva_list.c
@@ -0,0 +1,1187 @@
+#include <lightning.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#define W              jit_word_t
+#define D              jit_float64_t
+#define VASTART(A)                                                     \
+    va_list            ap;                                             \
+    va_start(ap, A)
+#define VARG2()                a2 = va_arg(ap, jit_word_t);    VARG3()
+#define VARG3()                a3 = va_arg(ap, jit_word_t);    VARG4()
+#define VARG4()                a4 = va_arg(ap, jit_word_t);    VARG5()
+#define VARG5()                a5 = va_arg(ap, jit_word_t);    VARG6()
+#define VARG6()                a6 = va_arg(ap, jit_word_t);    VARG7()
+#define VARG7()                a7 = va_arg(ap, jit_word_t);    VARG8()
+#define VARG8()                a8 = va_arg(ap, jit_word_t);    VARG9()
+#define VARG9()                a9 = va_arg(ap, jit_word_t);    VARG10()
+#define VARG10()       a10 = va_arg(ap, jit_word_t);   va_end(ap)
+
+#define VARGD2()       a2 = va_arg(ap, jit_float64_t); VARGD3()
+#define VARGD3()       a3 = va_arg(ap, jit_float64_t); VARGD4()
+#define VARGD4()       a4 = va_arg(ap, jit_float64_t); VARGD5()
+#define VARGD5()       a5 = va_arg(ap, jit_float64_t); VARGD6()
+#define VARGD6()       a6 = va_arg(ap, jit_float64_t); VARGD7()
+#define VARGD7()       a7 = va_arg(ap, jit_float64_t); VARGD8()
+#define VARGD8()       a8 = va_arg(ap, jit_float64_t); VARGD9()
+#define VARGD9()       a9 = va_arg(ap, jit_float64_t); VARGD10()
+#define VARGD10()      a10 = va_arg(ap, jit_float64_t);va_end(ap)
+
+#define IDVARG2()      a2 = va_arg(ap, jit_float64_t); IDVARG3()
+#define IDVARG3()      a3 = va_arg(ap, jit_word_t);    IDVARG4()
+#define IDVARG4()      a4 = va_arg(ap, jit_float64_t); IDVARG5()
+#define IDVARG5()      a5 = va_arg(ap, jit_word_t);    IDVARG6()
+#define IDVARG6()      a6 = va_arg(ap, jit_float64_t); IDVARG7()
+#define IDVARG7()      a7 = va_arg(ap, jit_word_t);    IDVARG8()
+#define IDVARG8()      a8 = va_arg(ap, jit_float64_t); IDVARG9()
+#define IDVARG9()      a9 = va_arg(ap, jit_word_t);    IDVARG10()
+#define IDVARG10()     a10 = va_arg(ap, jit_float64_t);va_end(ap)
+
+#define DIVARG2()      a2 = va_arg(ap, jit_word_t);    DIVARG3()
+#define DIVARG3()      a3 = va_arg(ap, jit_float64_t); DIVARG4()
+#define DIVARG4()      a4 = va_arg(ap, jit_word_t);    DIVARG5()
+#define DIVARG5()      a5 = va_arg(ap, jit_float64_t); DIVARG6()
+#define DIVARG6()      a6 = va_arg(ap, jit_word_t);    DIVARG7()
+#define DIVARG7()      a7 = va_arg(ap, jit_float64_t); DIVARG8()
+#define DIVARG8()      a8 = va_arg(ap, jit_word_t);    DIVARG9()
+#define DIVARG9()      a9 = va_arg(ap, jit_float64_t); DIVARG10()
+#define DIVARG10()     a10 = va_arg(ap, jit_word_t);   va_end(ap)
+
+#define CHECK()                                                                
\
+    do {                                                               \
+       if (a1 != 1 || a2 != 2 || a3 != 3 || a4 != 4 || a5 != 5 ||      \
+           a6 != 6 || a7 != 7 || a8 != 8 || a9 != 9 || a10 != 10)      \
+           abort();                                                    \
+    } while (0)
+
+
+void i_iiiiiiiii(W a1, ...)
+{
+    W          a2, a3, a4, a5, a6, a7, a8, a9, a10;
+    VASTART(a1);
+    VARG2();
+    CHECK();
+}
+
+void ii_iiiiiiii(W a1, W a2, ...)
+{
+    W          a3, a4, a5, a6, a7, a8, a9, a10;
+    VASTART(a2);
+    VARG3();
+    CHECK();
+}
+
+void iii_iiiiiii(W a1, W a2, W a3, ...)
+{
+    W          a4, a5, a6, a7, a8, a9, a10;
+    VASTART(a3);
+    VARG4();
+    CHECK();
+}
+
+void iiii_iiiiii(W a1, W a2, W a3, W a4, ...)
+{
+    W          a5, a6, a7, a8, a9, a10;
+    VASTART(a4);
+    VARG5();
+    CHECK();
+}
+
+void iiiii_iiiii(W a1, W a2, W a3, W a4, W a5, ...)
+{
+    W          a6, a7, a8, a9, a10;
+    VASTART(a5);
+    VARG6();
+    CHECK();
+}
+
+void iiiiii_iiii(W a1, W a2, W a3, W a4, W a5, W a6, ...)
+{
+    W          a7, a8, a9, a10;
+    VASTART(a6);
+    VARG7();
+    CHECK();
+}
+
+void iiiiiii_iii(W a1, W a2, W a3, W a4, W a5, W a6, W a7, ...)
+{
+    W          a8, a9, a10;
+    VASTART(a7);
+    VARG8();
+    CHECK();
+}
+
+void iiiiiiii_ii(W a1, W a2, W a3, W a4, W a5, W a6, W a7, W a8, ...)
+{
+    W          a9, a10;
+    VASTART(a8);
+    VARG9();
+    CHECK();
+}
+
+void iiiiiiiii_i(W a1, W a2, W a3, W a4, W a5, W a6, W a7, W a8, W a9, ...)
+{
+    W          a10;
+    VASTART(a9);
+    VARG10();
+    CHECK();
+}
+
+void d_ddddddddd(D a1, ...)
+{
+    D          a2, a3, a4, a5, a6, a7, a8, a9, a10;
+    VASTART(a1);
+    VARGD2();
+    CHECK();
+}
+
+void dd_dddddddd(D a1, D a2, ...)
+{
+    D          a3, a4, a5, a6, a7, a8, a9, a10;
+    VASTART(a2);
+    VARGD3();
+    CHECK();
+}
+
+void ddd_ddddddd(D a1, D a2, D a3, ...)
+{
+    D          a4, a5, a6, a7, a8, a9, a10;
+    VASTART(a3);
+    VARGD4();
+    CHECK();
+}
+
+void dddd_dddddd(D a1, D a2, D a3, D a4, ...)
+{
+    D          a5, a6, a7, a8, a9, a10;
+    VASTART(a4);
+    VARGD5();
+    CHECK();
+}
+
+void ddddd_ddddd(D a1, D a2, D a3, D a4, D a5, ...)
+{
+    D          a6, a7, a8, a9, a10;
+    VASTART(a5);
+    VARGD6();
+    CHECK();
+}
+
+void dddddd_dddd(D a1, D a2, D a3, D a4, D a5, D a6, ...)
+{
+    D          a7, a8, a9, a10;
+    VASTART(a6);
+    VARGD7();
+    CHECK();
+}
+
+void ddddddd_ddd(D a1, D a2, D a3, D a4, D a5, D a6, D a7, ...)
+{
+    D          a8, a9, a10;
+    VASTART(a7);
+    VARGD8();
+    CHECK();
+}
+
+void dddddddd_dd(D a1, D a2, D a3, D a4, D a5, D a6, D a7, D a8, ...)
+{
+    D          a9, a10;
+    VASTART(a8);
+    VARGD9();
+    CHECK();
+}
+
+void ddddddddd_d(D a1, D a2, D a3, D a4, D a5, D a6, D a7, D a8, D a9, ...)
+{
+    D          a10;
+    VASTART(a9);
+    VARGD10();
+    CHECK();
+}
+
+void i_didididid(W a1, ...)
+{
+    W          a3, a5, a7, a9;
+    D          a2, a4, a6, a8, a10;
+    VASTART(a1);
+    IDVARG2();
+    CHECK();
+}
+
+void id_idididid(W a1, D a2, ...)
+{
+    W          a3, a5, a7, a9;
+    D          a4, a6, a8, a10;
+    VASTART(a2);
+    IDVARG3();
+    CHECK();
+}
+
+void idi_dididid(W a1, D a2, W a3, ...)
+{
+    W          a5, a7, a9;
+    D          a4, a6, a8, a10;
+    VASTART(a3);
+    IDVARG4();
+    CHECK();
+}
+
+void idid_ididid(W a1, D a2, W a3, D a4, ...)
+{
+    W          a5, a7, a9;
+    D          a6, a8, a10;
+    VASTART(a4);
+    IDVARG5();
+    CHECK();
+}
+
+void ididi_didid(W a1, D a2, W a3, D a4, W a5, ...)
+{
+    W          a7, a9;
+    D          a6, a8, a10;
+    VASTART(a5);
+    IDVARG6();
+    CHECK();
+}
+
+void ididid_idid(W a1, D a2, W a3, D a4, W a5, D a6, ...)
+{
+    W          a7, a9;
+    D          a8, a10;
+    VASTART(a6);
+    IDVARG7();
+    CHECK();
+}
+
+void idididi_did(W a1, D a2, W a3, D a4, W a5, D a6, W a7, ...)
+{
+    W          a9;
+    D          a8, a10;
+    VASTART(a7);
+    IDVARG8();
+    CHECK();
+}
+
+void idididid_id(W a1, D a2, W a3, D a4, W a5, D a6, W a7, D a8, ...)
+{
+    W          a9;
+    D          a10;
+    VASTART(a8);
+    IDVARG9();
+    CHECK();
+}
+
+void ididididi_d(W a1, D a2, W a3, D a4, W a5, D a6, W a7, D a8, W a9, ...)
+{
+    D          a10;
+    VASTART(a9);
+    IDVARG10();
+    CHECK();
+}
+
+void d_ididididi(D a1, ...)
+{
+    W          a2, a4, a6, a8, a10;
+    D          a3, a5, a7, a9;
+    VASTART(a1);
+    DIVARG2();
+    CHECK();
+}
+
+void di_didididi(D a1, W a2, ...)
+{
+    W          a4, a6, a8, a10;
+    D          a3, a5, a7, a9;
+    VASTART(a2);
+    DIVARG3();
+    CHECK();
+}
+
+void did_idididi(D a1, W a2, D a3, ...)
+{
+    W          a4, a6, a8, a10;
+    D          a5, a7, a9;
+    VASTART(a3);
+    DIVARG4();
+    CHECK();
+}
+
+void didi_dididi(D a1, W a2, D a3, W a4, ...)
+{
+    W          a6, a8, a10;
+    D          a5, a7, a9;
+    VASTART(a4);
+    DIVARG5();
+    CHECK();
+}
+
+void didid_ididi(D a1, W a2, D a3, W a4, D a5, ...)
+{
+    W          a6, a8, a10;
+    D          a7, a9;
+    VASTART(a5);
+    DIVARG6();
+    CHECK();
+}
+
+void dididi_didi(D a1, W a2, D a3, W a4, D a5, W a6, ...)
+{
+    W          a8, a10;
+    D          a7, a9;
+    VASTART(a6);
+    DIVARG7();
+    CHECK();
+}
+
+void dididid_idi(D a1, W a2, D a3, W a4, D a5, W a6, D a7, ...)
+{
+    W          a8, a10;
+    D          a9;
+    VASTART(a7);
+    DIVARG8();
+    CHECK();
+}
+
+void didididi_di(D a1, W a2, D a3, W a4, D a5, W a6, D a7, W a8, ...)
+{
+    W          a10;
+    D          a9;
+    VASTART(a8);
+    DIVARG9();
+    CHECK();
+}
+
+void didididid_i(D a1, W a2, D a3, W a4, D a5, W a6, D a7, W a8, D a9, ...)
+{
+    W          a10;
+    VASTART(a9);
+    DIVARG10();
+    CHECK();
+}
+
+void va_i_iiiiiiiii(W a1, va_list ap)
+{
+    W          a2, a3, a4, a5, a6, a7, a8, a9, a10;
+    VARG2();
+    CHECK();
+}
+
+void va_ii_iiiiiiii(W a1, W a2, va_list ap)
+{
+    W          a3, a4, a5, a6, a7, a8, a9, a10;
+    VARG3();
+    CHECK();
+}
+
+void va_iii_iiiiiii(W a1, W a2, W a3, va_list ap)
+{
+    W          a4, a5, a6, a7, a8, a9, a10;
+    VARG4();
+    CHECK();
+}
+
+void va_iiii_iiiiii(W a1, W a2, W a3, W a4, va_list ap)
+{
+    W          a5, a6, a7, a8, a9, a10;
+    VARG5();
+    CHECK();
+}
+
+
+void va_d_ddddddddd(D a1, va_list ap)
+{
+    D          a2, a3, a4, a5, a6, a7, a8, a9, a10;
+    VARGD2();
+    CHECK();
+}
+
+void va_dd_dddddddd(D a1, D a2, va_list ap)
+{
+    D          a3, a4, a5, a6, a7, a8, a9, a10;
+    VARGD3();
+    CHECK();
+}
+
+void va_ddd_ddddddd(D a1, D a2, D a3, va_list ap)
+{
+    D          a4, a5, a6, a7, a8, a9, a10;
+    VARGD4();
+    CHECK();
+}
+
+void va_dddd_dddddd(D a1, D a2, D a3, D a4, va_list ap)
+{
+    D          a5, a6, a7, a8, a9, a10;
+    VARGD5();
+    CHECK();
+}
+
+void va_i_didididid(W a1, va_list ap)
+{
+    W          a3, a5, a7, a9;
+    D          a2, a4, a6, a8, a10;
+    IDVARG2();
+    CHECK();
+}
+
+void va_id_idididid(W a1, D a2, va_list ap)
+{
+    W          a3, a5, a7, a9;
+    D          a4, a6, a8, a10;
+    IDVARG3();
+    CHECK();
+}
+
+void va_idi_dididid(W a1, D a2, W a3, va_list ap)
+{
+    W          a5, a7, a9;
+    D          a4, a6, a8, a10;
+    IDVARG4();
+    CHECK();
+}
+
+void va_idid_ididid(W a1, D a2, W a3, D a4, va_list ap)
+{
+    W          a5, a7, a9;
+    D          a6, a8, a10;
+    IDVARG5();
+    CHECK();
+}
+
+void va_d_ididididi(D a1, va_list ap)
+{
+    W          a2, a4, a6, a8, a10;
+    D          a3, a5, a7, a9;
+    DIVARG2();
+    CHECK();
+}
+
+void va_di_didididi(D a1, W a2, va_list ap)
+{
+    W          a4, a6, a8, a10;
+    D          a3, a5, a7, a9;
+    DIVARG3();
+    CHECK();
+}
+
+void va_did_idididi(D a1, W a2, D a3, va_list ap)
+{
+    W          a4, a6, a8, a10;
+    D          a5, a7, a9;
+    DIVARG4();
+    CHECK();
+}
+
+void va_didi_dididi(D a1, W a2, D a3, W a4, va_list ap)
+{
+    W          a6, a8, a10;
+    D          a5, a7, a9;
+    DIVARG5();
+    CHECK();
+}
+
+#define PUSH1()                                        jit_pushargi(1)
+#define PUSH2()                PUSH1();                jit_pushargi(2)
+#define PUSH3()                PUSH2();                jit_pushargi(3)
+#define PUSH4()                PUSH3();                jit_pushargi(4)
+#define PUSH5()                PUSH4();                jit_pushargi(5)
+#define PUSH6()                PUSH5();                jit_pushargi(6)
+#define PUSH7()                PUSH6();                jit_pushargi(7)
+#define PUSH8()                PUSH7();                jit_pushargi(8)
+#define PUSH9()                PUSH8();                jit_pushargi(9)
+#define VPUSH2()       jit_pushargi(2);        VPUSH3()
+#define VPUSH3()       jit_pushargi(3);        VPUSH4()
+#define VPUSH4()       jit_pushargi(4);        VPUSH5()
+#define VPUSH5()       jit_pushargi(5);        VPUSH6()
+#define VPUSH6()       jit_pushargi(6);        VPUSH7()
+#define VPUSH7()       jit_pushargi(7);        VPUSH8()
+#define VPUSH8()       jit_pushargi(8);        VPUSH9()
+#define VPUSH9()       jit_pushargi(9);        VPUSH10()
+#define VPUSH10()      jit_pushargi(10);
+#define PUSHD1()                               jit_pushargi_d(1)
+#define PUSHD2()       PUSHD1();               jit_pushargi_d(2)
+#define PUSHD3()       PUSHD2();               jit_pushargi_d(3)
+#define PUSHD4()       PUSHD3();               jit_pushargi_d(4)
+#define PUSHD5()       PUSHD4();               jit_pushargi_d(5)
+#define PUSHD6()       PUSHD5();               jit_pushargi_d(6)
+#define PUSHD7()       PUSHD6();               jit_pushargi_d(7)
+#define PUSHD8()       PUSHD7();               jit_pushargi_d(8)
+#define PUSHD9()       PUSHD8();               jit_pushargi_d(9)
+#define VPUSHD2()      jit_pushargi_d(2);      VPUSHD3()
+#define VPUSHD3()      jit_pushargi_d(3);      VPUSHD4()
+#define VPUSHD4()      jit_pushargi_d(4);      VPUSHD5()
+#define VPUSHD5()      jit_pushargi_d(5);      VPUSHD6()
+#define VPUSHD6()      jit_pushargi_d(6);      VPUSHD7()
+#define VPUSHD7()      jit_pushargi_d(7);      VPUSHD8()
+#define VPUSHD8()      jit_pushargi_d(8);      VPUSHD9()
+#define VPUSHD9()      jit_pushargi_d(9);      VPUSHD10()
+#define VPUSHD10()     jit_pushargi_d(10);
+#define IDPUSH1()                              jit_pushargi(1)
+#define IDPUSH2()      IDPUSH1();              jit_pushargi_d(2)
+#define IDPUSH3()      IDPUSH2();              jit_pushargi(3)
+#define IDPUSH4()      IDPUSH3();              jit_pushargi_d(4)
+#define IDPUSH5()      IDPUSH4();              jit_pushargi(5)
+#define IDPUSH6()      IDPUSH5();              jit_pushargi_d(6)
+#define IDPUSH7()      IDPUSH6();              jit_pushargi(7)
+#define IDPUSH8()      IDPUSH7();              jit_pushargi_d(8)
+#define IDPUSH9()      IDPUSH8();              jit_pushargi(9)
+#define IDVPUSH2()     jit_pushargi_d(2);      IDVPUSH3()
+#define IDVPUSH3()     jit_pushargi(3);        IDVPUSH4()
+#define IDVPUSH4()     jit_pushargi_d(4);      IDVPUSH5()
+#define IDVPUSH5()     jit_pushargi(5);        IDVPUSH6()
+#define IDVPUSH6()     jit_pushargi_d(6);      IDVPUSH7()
+#define IDVPUSH7()     jit_pushargi(7);        IDVPUSH8()
+#define IDVPUSH8()     jit_pushargi_d(8);      IDVPUSH9()
+#define IDVPUSH9()     jit_pushargi(9);        IDVPUSH10()
+#define IDVPUSH10()    jit_pushargi_d(10);
+#define DIPUSH1()                              jit_pushargi_d(1)
+#define DIPUSH2()      DIPUSH1();              jit_pushargi(2)
+#define DIPUSH3()      DIPUSH2();              jit_pushargi_d(3)
+#define DIPUSH4()      DIPUSH3();              jit_pushargi(4)
+#define DIPUSH5()      DIPUSH4();              jit_pushargi_d(5)
+#define DIPUSH6()      DIPUSH5();              jit_pushargi(6)
+#define DIPUSH7()      DIPUSH6();              jit_pushargi_d(7)
+#define DIPUSH8()      DIPUSH7();              jit_pushargi(8)
+#define DIPUSH9()      DIPUSH8();              jit_pushargi_d(9)
+#define DIVPUSH2()     jit_pushargi(2);        DIVPUSH3()
+#define DIVPUSH3()     jit_pushargi_d(3);      DIVPUSH4()
+#define DIVPUSH4()     jit_pushargi(4);        DIVPUSH5()
+#define DIVPUSH5()     jit_pushargi_d(5);      DIVPUSH6()
+#define DIVPUSH6()     jit_pushargi(6);        DIVPUSH7()
+#define DIVPUSH7()     jit_pushargi_d(7);      DIVPUSH8()
+#define DIVPUSH8()     jit_pushargi(8);        DIVPUSH9()
+#define DIVPUSH9()     jit_pushargi_d(9);      DIVPUSH10()
+#define DIVPUSH10()    jit_pushargi(10);
+
+jit_state_t     *_jit;
+
+int main(int argc, char *argv[])
+{
+    void               (*function)(void);
+    jit_node_t         *jmpi_main;
+    jit_node_t         *a1, *a2, *node;
+    jit_node_t         *jva_i_iiiiiiiii, *jva_ii_iiiiiiii;
+    jit_node_t         *jva_d_ddddddddd, *jva_dd_dddddddd;
+    jit_node_t         *jva_i_didididid, *jva_id_idididid;
+    jit_node_t         *jva_d_ididididi, *jva_di_didididi;
+    jit_node_t         *jva_iii_iiiiiii, *jva_iiii_iiiiii;
+    jit_node_t         *jva_ddd_ddddddd, *jva_dddd_dddddd;
+    jit_node_t         *jva_idi_dididid, *jva_idid_ididid;
+    jit_node_t         *jva_did_idididi, *jva_didi_dididi;
+
+    init_jit(argv[0]);
+    _jit = jit_new_state();
+
+    jmpi_main = jit_jmpi();
+
+    /* Define simple functions to validate a jit_va_list_t
+     * is a valid va_list; these do not fetch arguments from
+     * the va_list. */
+    jva_i_iiiiiiiii = jit_label();
+    jit_name("va_i_iiiiiiiii");
+    jit_prolog();
+    a1 = jit_arg();
+    jit_getarg(JIT_V1, a1);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_prepare();
+    jit_pushargr(JIT_V1);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_i_iiiiiiiii);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_ii_iiiiiiii = jit_label();
+    jit_name("va_ii_iiiiiiii");
+    jit_prolog();
+    a1 = jit_arg();
+    a2 = jit_arg();
+    jit_getarg(JIT_V1, a1);
+    jit_getarg(JIT_V2, a2);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_prepare();
+    jit_pushargr(JIT_V1);
+    jit_pushargr(JIT_V2);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_ii_iiiiiiii);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_d_ddddddddd = jit_label();
+    jit_name("va_d_ddddddddd");
+    jit_prolog();
+    a1 = jit_arg_d();
+    jit_getarg_d(JIT_F3, a1);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_prepare();
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_d_ddddddddd);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_dd_dddddddd = jit_label();
+    jit_name("va_dd_dddddddd");
+    jit_prolog();
+    a1 = jit_arg_d();
+    a2 = jit_arg_d();
+    jit_getarg_d(JIT_F3, a1);
+    jit_getarg_d(JIT_F4, a2);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_prepare();
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr_d(JIT_F4);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_dd_dddddddd);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_i_didididid = jit_label();
+    jit_name("va_i_didididid");
+    jit_prolog();
+    a1 = jit_arg();
+    jit_getarg(JIT_V1, a1);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_prepare();
+    jit_pushargr(JIT_V1);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_i_didididid);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_id_idididid = jit_label();
+    jit_name("va_id_idididid");
+    jit_prolog();
+    a1 = jit_arg();
+    a2 = jit_arg_d();
+    jit_getarg(JIT_V1, a1);
+    jit_getarg_d(JIT_F3, a2);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_prepare();
+    jit_pushargr(JIT_V1);
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_id_idididid);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_d_ididididi = jit_label();
+    jit_name("va_d_ididididi");
+    jit_prolog();
+    a1 = jit_arg_d();
+    jit_getarg_d(JIT_F3, a1);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_prepare();
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_d_ididididi);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_di_didididi = jit_label();
+    jit_name("va_di_didididi");
+    jit_prolog();
+    a1 = jit_arg_d();
+    a2 = jit_arg();
+    jit_getarg_d(JIT_F3, a1);
+    jit_getarg(JIT_V1, a2);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_prepare();
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr(JIT_V1);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_di_didididi);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+
+    /* Define complex functions to validate a jit_va_list_t
+     * is a valid va_list; these do fetch arguments from
+     * the va_list, to ensure it does the correct operations
+     * fetching arguments, and pass a valid va_list to the
+     * C function. */
+    jva_iii_iiiiiii = jit_label();
+    jit_name("va_iii_iiiiiii");
+    jit_prolog();
+    a1 = jit_arg();
+    jit_getarg(JIT_V1, a1);
+    node = jit_beqi(JIT_V1, 1);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_va_arg(JIT_V1, JIT_V0);
+    jit_va_arg(JIT_V2, JIT_V0);
+    jit_prepare();
+    jit_pushargi(1);
+    jit_pushargr(JIT_V1);
+    jit_pushargr(JIT_V2);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_iii_iiiiiii);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_iiii_iiiiii = jit_label();
+    jit_name("va_iiii_iiiiii");
+    jit_prolog();
+    a1 = jit_arg();
+    a2 = jit_arg();
+    jit_getarg(JIT_V1, a1);
+    node = jit_beqi(JIT_V1, 1);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_getarg(JIT_V1, a2);
+    node = jit_beqi(JIT_V1, 2);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_va_arg(JIT_V1, JIT_V0);
+    jit_va_arg(JIT_V2, JIT_V0);
+    jit_prepare();
+    jit_pushargi(1);
+    jit_pushargi(2);
+    jit_pushargr(JIT_V1);
+    jit_pushargr(JIT_V2);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_iiii_iiiiii);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_ddd_ddddddd = jit_label();
+    jit_name("va_ddd_ddddddd");
+    jit_prolog();
+    a1 = jit_arg_d();
+    jit_getarg_d(JIT_F3, a1);
+    node = jit_beqi_d(JIT_F3, 1);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_va_arg_d(JIT_F3, JIT_V0);
+    jit_va_arg_d(JIT_F4, JIT_V0);
+    jit_prepare();
+    jit_pushargi_d(1);
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr_d(JIT_F4);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_ddd_ddddddd);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_dddd_dddddd = jit_label();
+    jit_name("va_dddd_dddddd");
+    jit_prolog();
+    a1 = jit_arg_d();
+    a2 = jit_arg_d();
+    jit_getarg_d(JIT_F3, a1);
+    node = jit_beqi_d(JIT_F3, 1);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_getarg_d(JIT_F3, a2);
+    node = jit_beqi_d(JIT_F3, 2);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_va_arg_d(JIT_F3, JIT_V0);
+    jit_va_arg_d(JIT_F4, JIT_V0);
+    jit_prepare();
+    jit_pushargi_d(1);
+    jit_pushargi_d(2);
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr_d(JIT_F4);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_dddd_dddddd);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_idi_dididid = jit_label();
+    jit_name("va_idi_dididid");
+    jit_prolog();
+    a1 = jit_arg();
+    jit_getarg(JIT_V1, a1);
+    node = jit_beqi(JIT_V1, 1);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_va_arg_d(JIT_F3, JIT_V0);
+    jit_va_arg(JIT_V1, JIT_V0);
+    jit_prepare();
+    jit_pushargi(1);
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr(JIT_V1);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_idi_dididid);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_idid_ididid = jit_label();
+    jit_name("va_idid_ididid");
+    jit_prolog();
+    a1 = jit_arg();
+    a2 = jit_arg_d();
+    jit_getarg(JIT_V1, a1);
+    node = jit_beqi(JIT_V1, 1);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_getarg_d(JIT_F3, a2);
+    node = jit_beqi_d(JIT_F3, 2);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_va_arg(JIT_V1, JIT_V0);
+    jit_va_arg_d(JIT_F3, JIT_V0);
+    jit_prepare();
+    jit_pushargi(1);
+    jit_pushargi_d(2);
+    jit_pushargr(JIT_V1);
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_idid_ididid);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_did_idididi = jit_label();
+    jit_name("va_did_idididi");
+    jit_prolog();
+    a1 = jit_arg_d();
+    jit_getarg_d(JIT_F3, a1);
+    node = jit_beqi_d(JIT_F3, 1);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_va_arg(JIT_V1, JIT_V0);
+    jit_va_arg_d(JIT_F3, JIT_V0);
+    jit_prepare();
+    jit_pushargi_d(1);
+    jit_pushargr(JIT_V1);
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_did_idididi);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+    jva_didi_dididi = jit_label();
+    jit_name("va_didi_dididi");
+    jit_prolog();
+    a1 = jit_arg_d();
+    a2 = jit_arg();
+    jit_getarg_d(JIT_F3, a1);
+    node = jit_beqi_d(JIT_F3, 1);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_getarg(JIT_V1, a2);
+    node = jit_beqi(JIT_V1, 2);
+    jit_calli(abort);
+    jit_patch(node);
+    jit_ellipsis();
+    jit_va_start(JIT_V0);
+    jit_va_arg_d(JIT_F3, JIT_V0);
+    jit_va_arg(JIT_V1, JIT_V0);
+    jit_prepare();
+    jit_pushargi_d(1);
+    jit_pushargi(2);
+    jit_pushargr_d(JIT_F3);
+    jit_pushargr(JIT_V1);
+    jit_pushargr(JIT_V0);
+    jit_finishi(va_didi_dididi);
+    jit_va_end(JIT_V0);
+    jit_ret();
+    jit_epilog();
+
+    jit_patch(jmpi_main);
+    jit_name("main");
+    jit_prolog();
+
+    /* Check that lightning properly calls vararg functions */
+    jit_prepare();
+    PUSH1();
+    jit_ellipsis();
+    VPUSH2();
+    jit_finishi(i_iiiiiiiii);
+    jit_prepare();
+    PUSH2();
+    jit_ellipsis();
+    VPUSH3();
+    jit_finishi(ii_iiiiiiii);
+    jit_prepare();
+    PUSH3();
+    jit_ellipsis();
+    VPUSH4();
+    jit_finishi(iii_iiiiiii);
+    jit_prepare();
+    PUSH4();
+    jit_ellipsis();
+    VPUSH5();
+    jit_finishi(iiii_iiiiii);
+    jit_prepare();
+    PUSH5();
+    jit_ellipsis();
+    VPUSH6();
+    jit_finishi(iiiii_iiiii);
+    jit_prepare();
+    PUSH6();
+    jit_ellipsis();
+    VPUSH7();
+    jit_finishi(iiiiii_iiii);
+    jit_prepare();
+    PUSH7();
+    jit_ellipsis();
+    VPUSH8();
+    jit_finishi(iiiiiii_iii);
+    jit_prepare();
+    PUSH8();
+    jit_ellipsis();
+    VPUSH9();
+    jit_finishi(iiiiiiii_ii);
+    jit_prepare();
+    PUSH9();
+    jit_ellipsis();
+    VPUSH10();
+    jit_finishi(iiiiiiiii_i);
+    jit_prepare();
+    PUSHD1();
+    jit_ellipsis();
+    VPUSHD2();
+    jit_finishi(d_ddddddddd);
+    jit_prepare();
+    PUSHD2();
+    jit_ellipsis();
+    VPUSHD3();
+    jit_finishi(dd_dddddddd);
+    jit_prepare();
+    PUSHD3();
+    jit_ellipsis();
+    VPUSHD4();
+    jit_finishi(ddd_ddddddd);
+    jit_prepare();
+    PUSHD4();
+    jit_ellipsis();
+    VPUSHD5();
+    jit_finishi(dddd_dddddd);
+    jit_prepare();
+    PUSHD5();
+    jit_ellipsis();
+    VPUSHD6();
+    jit_finishi(ddddd_ddddd);
+    jit_prepare();
+    PUSHD6();
+    jit_ellipsis();
+    VPUSHD7();
+    jit_finishi(dddddd_dddd);
+    jit_prepare();
+    PUSHD7();
+    jit_ellipsis();
+    VPUSHD8();
+    jit_finishi(ddddddd_ddd);
+    jit_prepare();
+    PUSHD8();
+    jit_ellipsis();
+    VPUSHD9();
+    jit_finishi(dddddddd_dd);
+    jit_prepare();
+    PUSHD9();
+    jit_ellipsis();
+    VPUSHD10();
+    jit_finishi(ddddddddd_d);
+    jit_prepare();
+    IDPUSH1();
+    jit_ellipsis();
+    IDVPUSH2();
+    jit_finishi(i_didididid);
+    jit_prepare();
+    IDPUSH2();
+    jit_ellipsis();
+    IDVPUSH3();
+    jit_finishi(id_idididid);
+    jit_prepare();
+    IDPUSH3();
+    jit_ellipsis();
+    IDVPUSH4();
+    jit_finishi(idi_dididid);
+    jit_prepare();
+    IDPUSH4();
+    jit_ellipsis();
+    IDVPUSH5();
+    jit_finishi(idid_ididid);
+    jit_prepare();
+    IDPUSH5();
+    jit_ellipsis();
+    IDVPUSH6();
+    jit_finishi(ididi_didid);
+    jit_prepare();
+    IDPUSH6();
+    jit_ellipsis();
+    IDVPUSH7();
+    jit_finishi(ididid_idid);
+    jit_prepare();
+    IDPUSH7();
+    jit_ellipsis();
+    IDVPUSH8();
+    jit_finishi(idididi_did);
+    jit_prepare();
+    IDPUSH8();
+    jit_ellipsis();
+    IDVPUSH9();
+    jit_finishi(idididid_id);
+    jit_prepare();
+    IDPUSH9();
+    jit_ellipsis();
+    IDVPUSH10();
+    jit_finishi(ididididi_d);
+    jit_prepare();
+    DIPUSH1();
+    jit_ellipsis();
+    DIVPUSH2();
+    jit_finishi(d_ididididi);
+    jit_prepare();
+    DIPUSH2();
+    jit_ellipsis();
+    DIVPUSH3();
+    jit_finishi(di_didididi);
+    jit_prepare();
+    DIPUSH3();
+    jit_ellipsis();
+    DIVPUSH4();
+    jit_finishi(did_idididi);
+    jit_prepare();
+    DIPUSH4();
+    jit_ellipsis();
+    DIVPUSH5();
+    jit_finishi(didi_dididi);
+    jit_prepare();
+    DIPUSH5();
+    jit_ellipsis();
+    DIVPUSH6();
+    jit_finishi(didid_ididi);
+    jit_prepare();
+    DIPUSH6();
+    jit_ellipsis();
+    DIVPUSH7();
+    jit_finishi(dididi_didi);
+    jit_prepare();
+    DIPUSH7();
+    jit_ellipsis();
+    DIVPUSH8();
+    jit_finishi(dididid_idi);
+    jit_prepare();
+    DIPUSH8();
+    jit_ellipsis();
+    DIVPUSH9();
+    jit_finishi(didididi_di);
+    jit_prepare();
+    DIPUSH9();
+    jit_ellipsis();
+    DIVPUSH10();
+    jit_finishi(didididid_i);
+
+    /* Check that unmodified jit_va_list_t is a valid va_list */
+    jit_prepare();
+    PUSH1();
+    jit_ellipsis();
+    VPUSH2();
+    jit_patch_at(jit_finishi(NULL), jva_i_iiiiiiiii);
+    jit_prepare();
+    PUSH2();
+    jit_ellipsis();
+    VPUSH3();
+    jit_patch_at(jit_finishi(NULL), jva_ii_iiiiiiii);
+    jit_prepare();
+    PUSHD1();
+    jit_ellipsis();
+    VPUSHD2();
+    jit_patch_at(jit_finishi(NULL), jva_d_ddddddddd);
+    jit_prepare();
+    PUSHD2();
+    jit_ellipsis();
+    VPUSHD3();
+    jit_patch_at(jit_finishi(NULL), jva_dd_dddddddd);
+    jit_prepare();
+    IDPUSH1();
+    jit_ellipsis();
+    IDVPUSH2();
+    jit_patch_at(jit_finishi(NULL), jva_i_didididid);
+    jit_prepare();
+    IDPUSH2();
+    jit_ellipsis();
+    IDVPUSH3();
+    jit_patch_at(jit_finishi(NULL), jva_id_idididid);
+    jit_prepare();
+    DIPUSH1();
+    jit_ellipsis();
+    DIVPUSH2();
+    jit_patch_at(jit_finishi(NULL), jva_d_ididididi);
+    jit_prepare();
+    DIPUSH2();
+    jit_ellipsis();
+    DIVPUSH3();
+    jit_patch_at(jit_finishi(NULL), jva_di_didididi);
+
+    /* Check that modified jit_va_list_t is a valid va_list */
+    jit_prepare();
+    PUSH1();
+    jit_ellipsis();
+    VPUSH2();
+    jit_patch_at(jit_finishi(NULL), jva_iii_iiiiiii);
+    jit_prepare();
+    PUSH2();
+    jit_ellipsis();
+    VPUSH3();
+    jit_patch_at(jit_finishi(NULL), jva_iiii_iiiiii);
+    jit_prepare();
+    PUSHD1();
+    jit_ellipsis();
+    VPUSHD2();
+    jit_patch_at(jit_finishi(NULL), jva_ddd_ddddddd);
+    jit_prepare();
+    PUSHD2();
+    jit_ellipsis();
+    VPUSHD3();
+    jit_patch_at(jit_finishi(NULL), jva_dddd_dddddd);
+    jit_prepare();
+    IDPUSH1();
+    jit_ellipsis();
+    IDVPUSH2();
+    jit_patch_at(jit_finishi(NULL), jva_idi_dididid);
+    jit_prepare();
+    IDPUSH2();
+    jit_ellipsis();
+    IDVPUSH3();
+    jit_patch_at(jit_finishi(NULL), jva_idid_ididid);
+    jit_prepare();
+    DIPUSH1();
+    jit_ellipsis();
+    DIVPUSH2();
+    jit_patch_at(jit_finishi(NULL), jva_did_idididi);
+    jit_prepare();
+    DIPUSH2();
+    jit_ellipsis();
+    DIVPUSH3();
+    jit_patch_at(jit_finishi(NULL), jva_didi_dididi);
+
+    jit_ret();
+    jit_epilog();
+
+
+    function = jit_emit();
+    jit_clear_state();
+    //jit_disassemble();
+    (*function)();
+    jit_destroy_state();
+
+    finish_jit();
+
+    printf("ok\n");
+    return 0;
+}
diff --git a/check/va_list.ok b/check/va_list.ok
new file mode 100644
index 0000000..9766475
--- /dev/null
+++ b/check/va_list.ok
@@ -0,0 +1 @@
+ok
diff --git a/check/va_list.tst b/check/va_list.tst
index 76a23de..ad704c9 100644
--- a/check/va_list.tst
+++ b/check/va_list.tst
@@ -1,30 +1,743 @@
-.data  16
-fmt:
-.c     "%d %f\n"
+.data  8
+ok:
+.c     "ok\n"
 .code
        jmpi main
-varargs:
+
+#define BEGIN(L)                                               \
+L:                                                             \
        prolog
-       ellipsis
+#define VA_START()                                             \
+       ellipsis                                                \
        va_start %v0
-       va_arg %r0 %v0
-       va_arg_d %f0 %v0
-       va_end %v0
-       prepare
-               pushargi fmt
-               ellipsis
-               pushargr %r0
-               pushargr_d %f0
-       finishi @printf
-       ret
+#define VARG(L,N)                                              \
+       va_arg %r0 %v0                                          \
+       beqi L##N %r0 N                                         \
+       calli @abort                                            \
+L##N:
+#define VARGD(L,N)                                             \
+       va_arg_d %f0 %v0                                        \
+       beqi_d L##N %f0 N                                       \
+       calli @abort                                            \
+L##N:
+#define VA_END()                                               \
+       va_end %v0                                              \
+       ret                                                     \
        epilog
+#define ARG(N)                 arg $arg##N
+#define ARGD(N)                        arg_d $arg##N
+#define GET(L,N)                                               \
+       getarg %r0 $arg##N                                      \
+       beqi L##N %r0 N                                         \
+       calli @abort                                            \
+L##N:
+#define GETD(L,N)                                              \
+       getarg_d %f0 $arg##N                                    \
+       beqi_d L##N %f0 N                                       \
+       calli @abort                                            \
+L##N:
+
+#define ARG1()                         ARG(1)
+#define ARG2()         ARG1()          ARG(2)
+#define ARG3()         ARG2()          ARG(3)
+#define ARG4()         ARG3()          ARG(4)
+#define ARG5()         ARG4()          ARG(5)
+#define ARG6()         ARG5()          ARG(6)
+#define ARG7()         ARG6()          ARG(7)
+#define ARG8()         ARG7()          ARG(8)
+#define ARG9()         ARG8()          ARG(9)
+#define GET1(L)                                GET(L,1)
+#define GET2(L)                GET1(L)         GET(L,2)
+#define GET3(L)                GET2(L)         GET(L,3)
+#define GET4(L)                GET3(L)         GET(L,4)
+#define GET5(L)                GET4(L)         GET(L,5)
+#define GET6(L)                GET5(L)         GET(L,6)
+#define GET7(L)                GET6(L)         GET(L,7)
+#define GET8(L)                GET7(L)         GET(L,8)
+#define GET9(L)                GET8(L)         GET(L,9)
+#define ARGD1()                                ARGD(1)
+#define ARGD2()                ARGD1()         ARGD(2)
+#define ARGD3()                ARGD2()         ARGD(3)
+#define ARGD4()                ARGD3()         ARGD(4)
+#define ARGD5()                ARGD4()         ARGD(5)
+#define ARGD6()                ARGD5()         ARGD(6)
+#define ARGD7()                ARGD6()         ARGD(7)
+#define ARGD8()                ARGD7()         ARGD(8)
+#define ARGD9()                ARGD8()         ARGD(9)
+#define GETD1(L)                       GETD(L,1)
+#define GETD2(L)       GETD1(L)        GETD(L,2)
+#define GETD3(L)       GETD2(L)        GETD(L,3)
+#define GETD4(L)       GETD3(L)        GETD(L,4)
+#define GETD5(L)       GETD4(L)        GETD(L,5)
+#define GETD6(L)       GETD5(L)        GETD(L,6)
+#define GETD7(L)       GETD6(L)        GETD(L,7)
+#define GETD8(L)       GETD7(L)        GETD(L,8)
+#define GETD9(L)       GETD8(L)        GETD(L,9)
+#define IDARG1()                       ARG(1)
+#define IDARG2()       IDARG1()        ARGD(2)
+#define IDARG3()       IDARG2()        ARG(3)
+#define IDARG4()       IDARG3()        ARGD(4)
+#define IDARG5()       IDARG4()        ARG(5)
+#define IDARG6()       IDARG5()        ARGD(6)
+#define IDARG7()       IDARG6()        ARG(7)
+#define IDARG8()       IDARG7()        ARGD(8)
+#define IDARG9()       IDARG8()        ARG(9)
+#define IDGET1(L)                      GET(L,1)
+#define IDGET2(L)      IDGET1(L)       GETD(L,2)
+#define IDGET3(L)      IDGET2(L)       GET(L,3)
+#define IDGET4(L)      IDGET3(L)       GETD(L,4)
+#define IDGET5(L)      IDGET4(L)       GET(L,5)
+#define IDGET6(L)      IDGET5(L)       GETD(L,6)
+#define IDGET7(L)      IDGET6(L)       GET(L,7)
+#define IDGET8(L)      IDGET7(L)       GETD(L,8)
+#define IDGET9(L)      IDGET8(L)       GET(L,9)
+#define DIARG1()                       ARGD(1)
+#define DIARG2()       DIARG1()        ARG(2)
+#define DIARG3()       DIARG2()        ARGD(3)
+#define DIARG4()       DIARG3()        ARG(4)
+#define DIARG5()       DIARG4()        ARGD(5)
+#define DIARG6()       DIARG5()        ARG(6)
+#define DIARG7()       DIARG6()        ARGD(7)
+#define DIARG8()       DIARG7()        ARG(8)
+#define DIARG9()       DIARG8()        ARGD(9)
+#define DIGET1(L)                      GETD(L,1)
+#define DIGET2(L)      DIGET1(L)       GET(L,2)
+#define DIGET3(L)      DIGET2(L)       GETD(L,3)
+#define DIGET4(L)      DIGET3(L)       GET(L,4)
+#define DIGET5(L)      DIGET4(L)       GETD(L,5)
+#define DIGET6(L)      DIGET5(L)       GET(L,6)
+#define DIGET7(L)      DIGET6(L)       GETD(L,7)
+#define DIGET8(L)      DIGET7(L)       GET(L,8)
+#define DIGET9(L)      DIGET8(L)       GETD(L,9)
+
+#define VARG1(L)                                               \
+       VARG(L, 10)
+#define VARG2(L)                                               \
+       VARG(L, 9)                                              \
+       VARG1(L)
+#define VARG3(L)                                               \
+       VARG(L, 8)                                              \
+       VARG2(L)
+#define VARG4(L)                                               \
+       VARG(L, 7)                                              \
+       VARG3(L)
+#define VARG5(L)                                               \
+       VARG(L, 6)                                              \
+       VARG4(L)
+#define VARG6(L)                                               \
+       VARG(L, 5)                                              \
+       VARG5(L)
+#define VARG7(L)                                               \
+       VARG(L, 4)                                              \
+       VARG6(L)
+#define VARG8(L)                                               \
+       VARG(L, 3)                                              \
+       VARG7(L)
+#define VARG9(L)                                               \
+       VARG(L, 2)                                              \
+       VARG8(L)
+#define VARG10(L)                                              \
+       VARG(L, 1)                                              \
+       VARG9(L)
+#define VARGD1(L)                                              \
+       VARGD(L, 10)
+#define VARGD2(L)                                              \
+       VARGD(L, 9)                                             \
+       VARGD1(L)
+#define VARGD3(L)                                              \
+       VARGD(L, 8)                                             \
+       VARGD2(L)
+#define VARGD4(L)                                              \
+       VARGD(L, 7)                                             \
+       VARGD3(L)
+#define VARGD5(L)                                              \
+       VARGD(L, 6)                                             \
+       VARGD4(L)
+#define VARGD6(L)                                              \
+       VARGD(L, 5)                                             \
+       VARGD5(L)
+#define VARGD7(L)                                              \
+       VARGD(L, 4)                                             \
+       VARGD6(L)
+#define VARGD8(L)                                              \
+       VARGD(L, 3)                                             \
+       VARGD7(L)
+#define VARGD9(L)                                              \
+       VARGD(L, 2)                                             \
+       VARGD8(L)
+#define VARGD10(L)                                             \
+       VARGD(L, 1)                                             \
+       VARGD9(L)
+#define IDVARG1(L)                                             \
+       VARGD(L, 10)
+#define IDVARG2(L)                                             \
+       VARG(L, 9)                                              \
+       IDVARG1(L)
+#define IDVARG3(L)                                             \
+       VARGD(L, 8)                                             \
+       IDVARG2(L)
+#define IDVARG4(L)                                             \
+       VARG(L, 7)                                              \
+       IDVARG3(L)
+#define IDVARG5(L)                                             \
+       VARGD(L, 6)                                             \
+       IDVARG4(L)
+#define IDVARG6(L)                                             \
+       VARG(L, 5)                                              \
+       IDVARG5(L)
+#define IDVARG7(L)                                             \
+       VARGD(L, 4)                                             \
+       IDVARG6(L)
+#define IDVARG8(L)                                             \
+       VARG(L, 3)                                              \
+       IDVARG7(L)
+#define IDVARG9(L)                                             \
+       VARGD(L, 2)                                             \
+       IDVARG8(L)
+#define IDVARG10(L)                                            \
+       VARG(L, 1)                                              \
+       IDVARG9(L)
+#define DIVARG1(L)                                             \
+       VARG(L, 10)
+#define DIVARG2(L)                                             \
+       VARGD(L, 9)                                             \
+       DIVARG1(L)
+#define DIVARG3(L)                                             \
+       VARG(L, 8)                                              \
+       DIVARG2(L)
+#define DIVARG4(L)                                             \
+       VARGD(L, 7)                                             \
+       DIVARG3(L)
+#define DIVARG5(L)                                             \
+       VARG(L, 6)                                              \
+       DIVARG4(L)
+#define DIVARG6(L)                                             \
+       VARGD(L, 5)                                             \
+       DIVARG5(L)
+#define DIVARG7(L)                                             \
+       VARG(L, 4)                                              \
+       DIVARG6(L)
+#define DIVARG8(L)                                             \
+       VARGD(L, 3)                                             \
+       DIVARG7(L)
+#define DIVARG9(L)                                             \
+       VARG(L, 2)                                              \
+       DIVARG8(L)
+#define DIVARG10(L)                                            \
+       VARGD(L, 1)                                             \
+       DIVARG9(L)
+
+BEGIN(_iiiiiiiiii)
+       VA_START()
+       VARG10(_iiiiiiiiii)
+       VA_END()
+BEGIN(i_iiiiiiiii)
+       ARG1()
+       GET1(i_iiiiiiiii)
+       VA_START()
+       VARG9(i_iiiiiiiii)
+       VA_END()
+BEGIN(ii_iiiiiiii)
+       ARG2()
+       GET2(ii_iiiiiiii)
+       VA_START()
+       VARG8(ii_iiiiiiii)
+       VA_END()
+BEGIN(iii_iiiiiii)
+       ARG3()
+       GET3(iii_iiiiiii)
+       VA_START()
+       VARG7(iii_iiiiiii)
+       VA_END()
+BEGIN(iiii_iiiiii)
+       ARG4()
+       GET4(iiii_iiiiii)
+       VA_START()
+       VARG6(iiii_iiiiii)
+       VA_END()
+BEGIN(iiiii_iiiii)
+       ARG5()
+       GET5(iiiii_iiiii)
+       VA_START()
+       VARG5(iiiii_iiiii)
+       VA_END()
+BEGIN(iiiiii_iiii)
+       ARG6()
+       GET6(iiiiii_iiii)
+       VA_START()
+       VARG4(iiiiii_iiii)
+       VA_END()
+BEGIN(iiiiiii_iii)
+       ARG7()
+       GET7(iiiiiii_iii)
+       VA_START()
+       VARG3(iiiiiii_iii)
+       VA_END()
+BEGIN(iiiiiiii_ii)
+       ARG8()
+       GET8(iiiiiiii_ii)
+       VA_START()
+       VARG2(iiiiiiii_ii)
+       VA_END()
+BEGIN(iiiiiiiii_i)
+       ARG9()
+       GET9(iiiiiiiii_i)
+       VA_START()
+       VARG1(iiiiiiiii_i)
+       VA_END()
+BEGIN(_dddddddddd)
+       VA_START()
+       VARGD10(_dddddddddd)
+       VA_END()
+BEGIN(d_ddddddddd)
+       ARGD1()
+       GETD1(d_ddddddddd)
+       VA_START()
+       VARGD9(d_ddddddddd)
+       VA_END()
+BEGIN(dd_dddddddd)
+       ARGD2()
+       GETD2(dd_dddddddd)
+       VA_START()
+       VARGD8(dd_dddddddd)
+       VA_END()
+BEGIN(ddd_ddddddd)
+       ARGD3()
+       GETD3(ddd_ddddddd)
+       VA_START()
+       VARGD7(ddd_ddddddd)
+       VA_END()
+BEGIN(dddd_dddddd)
+       ARGD4()
+       GETD4(dddd_dddddd)
+       VA_START()
+       VARGD6(dddd_dddddd)
+       VA_END()
+BEGIN(ddddd_ddddd)
+       ARGD5()
+       GETD5(ddddd_ddddd)
+       VA_START()
+       VARGD5(ddddd_ddddd)
+       VA_END()
+BEGIN(dddddd_dddd)
+       ARGD6()
+       GETD6(dddddd_dddd)
+       VA_START()
+       VARGD4(dddddd_dddd)
+       VA_END()
+BEGIN(ddddddd_ddd)
+       ARGD7()
+       GETD7(ddddddd_ddd)
+       VA_START()
+       VARGD3(ddddddd_ddd)
+       VA_END()
+BEGIN(dddddddd_dd)
+       ARGD8()
+       GETD8(dddddddd_dd)
+       VA_START()
+       VARGD2(dddddddd_dd)
+       VA_END()
+BEGIN(ddddddddd_d)
+       ARGD9()
+       GETD9(ddddddddd_d)
+       VA_START()
+       VARGD1(ddddddddd_d)
+       VA_END()
+BEGIN(_ididididid)
+       VA_START()
+       IDVARG10(_ididididid)
+       VA_END()
+BEGIN(i_didididid)
+       IDARG1()
+       IDGET1(i_didididid)
+       VA_START()
+       IDVARG9(i_didididid)
+       VA_END()
+BEGIN(id_idididid)
+       IDARG2()
+       IDGET2(id_idididid)
+       VA_START()
+       IDVARG8(id_idididid)
+       VA_END()
+BEGIN(idi_dididid)
+       IDARG3()
+       IDGET3(idi_dididid)
+       VA_START()
+       IDVARG7(idi_dididid)
+       VA_END()
+BEGIN(idid_ididid)
+       IDARG4()
+       IDGET4(idid_ididid)
+       VA_START()
+       IDVARG6(idid_ididid)
+       VA_END()
+BEGIN(ididi_didid)
+       IDARG5()
+       IDGET5(ididi_didid)
+       VA_START()
+       IDVARG5(ididi_didid)
+       VA_END()
+BEGIN(ididid_idid)
+       IDARG6()
+       IDGET6(ididid_idid)
+       VA_START()
+       IDVARG4(ididid_idid)
+       VA_END()
+BEGIN(idididi_did)
+       IDARG7()
+       IDGET7(idididi_did)
+       VA_START()
+       IDVARG3(idididi_did)
+       VA_END()
+BEGIN(idididid_id)
+       IDARG8()
+       IDGET8(idididid_id)
+       VA_START()
+       IDVARG2(idididid_id)
+       VA_END()
+BEGIN(ididididi_d)
+       IDARG9()
+       IDGET9(ididididi_d)
+       VA_START()
+       IDVARG1(ididididi_d)
+       VA_END()
+BEGIN(_dididididi)
+       VA_START()
+       DIVARG10(_dididididi)
+       VA_END()
+BEGIN(d_ididididi)
+       DIARG1()
+       DIGET1(d_ididididi)
+       VA_START()
+       DIVARG9(d_ididididi)
+       VA_END()
+BEGIN(di_didididi)
+       DIARG2()
+       DIGET2(di_didididi)
+       VA_START()
+       DIVARG8(di_didididi)
+       VA_END()
+BEGIN(did_idididi)
+       DIARG3()
+       DIGET3(did_idididi)
+       VA_START()
+       DIVARG7(did_idididi)
+       VA_END()
+BEGIN(didi_dididi)
+       DIARG4()
+       DIGET4(didi_dididi)
+       VA_START()
+       DIVARG6(didi_dididi)
+       VA_END()
+BEGIN(didid_ididi)
+       DIARG5()
+       DIGET5(didid_ididi)
+       VA_START()
+       DIVARG5(didid_ididi)
+       VA_END()
+BEGIN(dididi_didi)
+       DIARG6()
+       DIGET6(dididi_didi)
+       VA_START()
+       DIVARG4(dididi_didi)
+       VA_END()
+BEGIN(dididid_idi)
+       DIARG7()
+       DIGET7(dididid_idi)
+       VA_START()
+       DIVARG3(dididid_idi)
+       VA_END()
+BEGIN(didididi_di)
+       DIARG8()
+       DIGET8(didididi_di)
+       VA_START()
+       DIVARG2(didididi_di)
+       VA_END()
+BEGIN(didididid_i)
+       DIARG9()
+       DIGET9(didididid_i)
+       VA_START()
+       DIVARG1(didididid_i)
+       VA_END()
+
+#define PUSH1()                pushargi 1
+#define PUSH2()                PUSH1()         pushargi 2
+#define PUSH3()                PUSH2()         pushargi 3
+#define PUSH4()                PUSH3()         pushargi 4
+#define PUSH5()                PUSH4()         pushargi 5
+#define PUSH6()                PUSH5()         pushargi 6
+#define PUSH7()                PUSH6()         pushargi 7
+#define PUSH8()                PUSH7()         pushargi 8
+#define PUSH9()                PUSH8()         pushargi 9
+#define VPUSH1()       pushargi 1      VPUSH2()
+#define VPUSH2()       pushargi 2      VPUSH3()
+#define VPUSH3()       pushargi 3      VPUSH4()
+#define VPUSH4()       pushargi 4      VPUSH5()
+#define VPUSH5()       pushargi 5      VPUSH6()
+#define VPUSH6()       pushargi 6      VPUSH7()
+#define VPUSH7()       pushargi 7      VPUSH8()
+#define VPUSH8()       pushargi 8      VPUSH9()
+#define VPUSH9()       pushargi 9      VPUSH10()
+#define VPUSH10()      pushargi 10
+#define PUSHD1()       pushargi_d 1
+#define PUSHD2()       PUSHD1()        pushargi_d 2
+#define PUSHD3()       PUSHD2()        pushargi_d 3
+#define PUSHD4()       PUSHD3()        pushargi_d 4
+#define PUSHD5()       PUSHD4()        pushargi_d 5
+#define PUSHD6()       PUSHD5()        pushargi_d 6
+#define PUSHD7()       PUSHD6()        pushargi_d 7
+#define PUSHD8()       PUSHD7()        pushargi_d 8
+#define PUSHD9()       PUSHD8()        pushargi_d 9
+#define VPUSHD1()      pushargi_d 1    VPUSHD2()
+#define VPUSHD2()      pushargi_d 2    VPUSHD3()
+#define VPUSHD3()      pushargi_d 3    VPUSHD4()
+#define VPUSHD4()      pushargi_d 4    VPUSHD5()
+#define VPUSHD5()      pushargi_d 5    VPUSHD6()
+#define VPUSHD6()      pushargi_d 6    VPUSHD7()
+#define VPUSHD7()      pushargi_d 7    VPUSHD8()
+#define VPUSHD8()      pushargi_d 8    VPUSHD9()
+#define VPUSHD9()      pushargi_d 9    VPUSHD10()
+#define VPUSHD10()     pushargi_d 10
+#define IDPUSH1()      pushargi 1
+#define IDPUSH2()      IDPUSH1()       pushargi_d 2
+#define IDPUSH3()      IDPUSH2()       pushargi 3
+#define IDPUSH4()      IDPUSH3()       pushargi_d 4
+#define IDPUSH5()      IDPUSH4()       pushargi 5
+#define IDPUSH6()      IDPUSH5()       pushargi_d 6
+#define IDPUSH7()      IDPUSH6()       pushargi 7
+#define IDPUSH8()      IDPUSH7()       pushargi_d 8
+#define IDPUSH9()      IDPUSH8()       pushargi 9
+#define IDVPUSH1()     pushargi 1      IDVPUSH2()
+#define IDVPUSH2()     pushargi_d 2    IDVPUSH3()
+#define IDVPUSH3()     pushargi 3      IDVPUSH4()
+#define IDVPUSH4()     pushargi_d 4    IDVPUSH5()
+#define IDVPUSH5()     pushargi 5      IDVPUSH6()
+#define IDVPUSH6()     pushargi_d 6    IDVPUSH7()
+#define IDVPUSH7()     pushargi 7      IDVPUSH8()
+#define IDVPUSH8()     pushargi_d 8    IDVPUSH9()
+#define IDVPUSH9()     pushargi 9      IDVPUSH10()
+#define IDVPUSH10()    pushargi_d 10
+#define DIPUSH1()      pushargi_d 1
+#define DIPUSH2()      DIPUSH1()       pushargi 2
+#define DIPUSH3()      DIPUSH2()       pushargi_d 3
+#define DIPUSH4()      DIPUSH3()       pushargi 4
+#define DIPUSH5()      DIPUSH4()       pushargi_d 5
+#define DIPUSH6()      DIPUSH5()       pushargi 6
+#define DIPUSH7()      DIPUSH6()       pushargi_d 7
+#define DIPUSH8()      DIPUSH7()       pushargi 8
+#define DIPUSH9()      DIPUSH8()       pushargi_d 9
+#define DIVPUSH1()     pushargi_d 1    DIVPUSH2()
+#define DIVPUSH2()     pushargi 2      DIVPUSH3()
+#define DIVPUSH3()     pushargi_d 3    DIVPUSH4()
+#define DIVPUSH4()     pushargi 4      DIVPUSH5()
+#define DIVPUSH5()     pushargi_d 5    DIVPUSH6()
+#define DIVPUSH6()     pushargi 6      DIVPUSH7()
+#define DIVPUSH7()     pushargi_d 7    DIVPUSH8()
+#define DIVPUSH8()     pushargi 8      DIVPUSH9()
+#define DIVPUSH9()     pushargi_d 9    DIVPUSH10()
+#define DIVPUSH10()    pushargi 10
 
 main:
        prolog
        prepare
                ellipsis
-               pushargi 1
-               pushargi_d 2
-       finishi varargs
+               VPUSH1()
+       finishi _iiiiiiiiii
+       prepare
+               PUSH1()
+               ellipsis
+               VPUSH2()
+       finishi i_iiiiiiiii
+       prepare
+               PUSH2()
+               ellipsis
+               VPUSH3()
+       finishi ii_iiiiiiii
+       prepare
+               PUSH3()
+               ellipsis
+               VPUSH4()
+       finishi iii_iiiiiii
+       prepare
+               PUSH4()
+               ellipsis
+               VPUSH5()
+       finishi iiii_iiiiii
+       prepare
+               PUSH5()
+               ellipsis
+               VPUSH6()
+       finishi iiiii_iiiii
+       prepare
+               PUSH6()
+               ellipsis
+               VPUSH7()
+       finishi iiiiii_iiii
+       prepare
+               PUSH7()
+               ellipsis
+               VPUSH8()
+       finishi iiiiiii_iii
+       prepare
+               PUSH8()
+               ellipsis
+               VPUSH9()
+       finishi iiiiiiii_ii
+       prepare
+               PUSH9()
+               ellipsis
+               VPUSH10()
+       finishi iiiiiiiii_i
+       prepare
+               ellipsis
+               VPUSHD1()
+       finishi _dddddddddd
+       prepare
+               PUSHD1()
+               ellipsis
+               VPUSHD2()
+       finishi d_ddddddddd
+       prepare
+               PUSHD2()
+               ellipsis
+               VPUSHD3()
+       finishi dd_dddddddd
+       prepare
+               PUSHD3()
+               ellipsis
+               VPUSHD4()
+       finishi ddd_ddddddd
+       prepare
+               PUSHD4()
+               ellipsis
+               VPUSHD5()
+       finishi dddd_dddddd
+       prepare
+               PUSHD5()
+               ellipsis
+               VPUSHD6()
+       finishi ddddd_ddddd
+       prepare
+               PUSHD6()
+               ellipsis
+               VPUSHD7()
+       finishi dddddd_dddd
+       prepare
+               PUSHD7()
+               ellipsis
+               VPUSHD8()
+       finishi ddddddd_ddd
+       prepare
+               PUSHD8()
+               ellipsis
+               VPUSHD9()
+       finishi dddddddd_dd
+       prepare
+               PUSHD9()
+               ellipsis
+               VPUSHD10()
+       finishi ddddddddd_d
+       prepare
+               ellipsis
+               IDVPUSH1()
+       finishi _ididididid
+       prepare
+               IDPUSH1()
+               ellipsis
+               IDVPUSH2()
+       finishi i_didididid
+       prepare
+               IDPUSH2()
+               ellipsis
+               IDVPUSH3()
+       finishi id_idididid
+       prepare
+               IDPUSH3()
+               ellipsis
+               IDVPUSH4()
+       finishi idi_dididid
+       prepare
+               IDPUSH4()
+               ellipsis
+               IDVPUSH5()
+       finishi idid_ididid
+       prepare
+               IDPUSH5()
+               ellipsis
+               IDVPUSH6()
+       finishi ididi_didid
+       prepare
+               IDPUSH6()
+               ellipsis
+               IDVPUSH7()
+       finishi ididid_idid
+       prepare
+               IDPUSH7()
+               ellipsis
+               IDVPUSH8()
+       finishi idididi_did
+       prepare
+               IDPUSH8()
+               ellipsis
+               IDVPUSH9()
+       finishi idididid_id
+       prepare
+               IDPUSH9()
+               ellipsis
+               IDVPUSH10()
+       finishi ididididi_d
+       prepare
+               ellipsis
+               DIVPUSH1()
+       finishi _dididididi
+       prepare
+               DIPUSH1()
+               ellipsis
+               DIVPUSH2()
+       finishi d_ididididi
+       prepare
+               DIPUSH2()
+               ellipsis
+               DIVPUSH3()
+       finishi di_didididi
+       prepare
+               DIPUSH3()
+               ellipsis
+               DIVPUSH4()
+       finishi did_idididi
+       prepare
+               DIPUSH4()
+               ellipsis
+               DIVPUSH5()
+       finishi didi_dididi
+       prepare
+               DIPUSH5()
+               ellipsis
+               DIVPUSH6()
+       finishi didid_ididi
+       prepare
+               DIPUSH6()
+               ellipsis
+               DIVPUSH7()
+       finishi dididi_didi
+       prepare
+               DIPUSH7()
+               ellipsis
+               DIVPUSH8()
+       finishi dididid_idi
+       prepare
+               DIPUSH8()
+               ellipsis
+               DIVPUSH9()
+       finishi didididi_di
+       prepare
+               DIPUSH9()
+               ellipsis
+               DIVPUSH10()
+       finishi didididid_i
+       prepare
+               pushargi ok
+               ellipsis
+       finishi @printf
        ret
        epilog
diff --git a/lib/jit_arm-cpu.c b/lib/jit_arm-cpu.c
index 07b4630..ae0b284 100644
--- a/lib/jit_arm-cpu.c
+++ b/lib/jit_arm-cpu.c
@@ -3778,42 +3778,25 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
        BX(_R12_REGNO);
        if (!_jitc->thumb)
            _jitc->thumb = _jit->pc.w;
-
-       /* If the jit function is varargs, do a slightly more
-        * costly prolog to save first the 4 argument registers. */
        if (jit_cpu.abi) {
-           if (_jitc->function->self.call & jit_call_varargs)
-               T2_PUSH(0xf);
+           T2_PUSH(0xf);
            T2_PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
            VPUSH_F64(_D8_REGNO, 8);
-           if (!(_jitc->function->self.call & jit_call_varargs))
-               T2_PUSH(0xf);
        }
        else {
-           if (_jitc->function->self.call & jit_call_varargs) {
-               T2_PUSH(0xf);
-               T2_PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
-           }
-           else
-               T2_PUSH(0x3ff|(1<<_FP_REGNO)|(1<<_LR_REGNO));
+           T2_PUSH(0xf);
+           T2_PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
        }
     }
     else {
        if (jit_cpu.abi) {
-           if (_jitc->function->self.call & jit_call_varargs)
-               PUSH(0xf);
+           PUSH(0xf);
            PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
            VPUSH_F64(_D8_REGNO, 8);
-           if (!(_jitc->function->self.call & jit_call_varargs))
-               PUSH(0xf);
        }
        else {
-           if (_jitc->function->self.call & jit_call_varargs) {
-               PUSH(0xf);
-               PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
-           }
-           else
-               PUSH(0x3ff|(1<<_FP_REGNO)|(1<<_LR_REGNO));
+           PUSH(0xf);
+           PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
        }
     }
     movr(_FP_REGNO, _SP_REGNO);
@@ -3833,35 +3816,18 @@ _epilog(jit_state_t *_jit, jit_node_t *node)
     if (_jitc->function->assume_frame)
        return;
 
-    /* If the jit function is varargs, need a different
-     * epilog, that also does not directly restore the
-     * pc, but instead branch to the lr, after correcting
-     * the stack. */
-    if (_jitc->function->self.call & jit_call_varargs)
-       movr(_SP_REGNO, _FP_REGNO);
-    else
-       addi(_SP_REGNO, _FP_REGNO, 16);
+    movr(_SP_REGNO, _FP_REGNO);
     if (jit_cpu.abi)
        VPOP_F64(_D8_REGNO, 8);
-    if (jit_thumb_p()) {
-       if (!(_jitc->function->self.call & jit_call_varargs))
-           T2_POP(0x3f0|(1<<_FP_REGNO)|(1<<_PC_REGNO));
-       else
-           T2_POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
-    }
-    else {
-       if (!(_jitc->function->self.call & jit_call_varargs))
-           POP(0x3f0|(1<<_FP_REGNO)|(1<<_PC_REGNO));
-       else
-           POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
-    }
-    if (_jitc->function->self.call & jit_call_varargs) {
-       addi(_SP_REGNO, _SP_REGNO, 16);
-       if (jit_thumb_p())
-           T1_BX(_LR_REGNO);
-       else
-           BX(_LR_REGNO);
-    }
+    if (jit_thumb_p())
+       T2_POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
+    else
+       POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
+    addi(_SP_REGNO, _SP_REGNO, 16);
+    if (jit_thumb_p())
+       T1_BX(_LR_REGNO);
+    else
+       BX(_LR_REGNO);
     if (jit_thumb_p() && (_jit->pc.w & 2))
        T1_NOP();
 }
@@ -3869,45 +3835,26 @@ _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.
      * The -16 is to account for the 4 argument registers
      * always saved, and _jitc->function->vagp is to account
      * for declared arguments. */
-    addi(rn(reg), _FP_REGNO, _jitc->function->self.size -
+    addi(r0, _FP_REGNO, _jitc->function->self.size -
         16 + _jitc->function->vagp);
-    stxi(offsetof(jit_va_list_t, stack), r0, rn(reg));
-
-    jit_unget_reg(reg);
 }
 
 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 stack pointer. */
-    ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack));
-
     /* Load argument. */
-    ldr(r0, rn(reg));
+    ldr(r0, r1);
 
     /* Update 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);
+    addi(r1, r1, sizeof(jit_word_t));
 }
 
 static void
diff --git a/lib/jit_arm-swf.c b/lib/jit_arm-swf.c
index 6e041fc..c1e3ac4 100644
--- a/lib/jit_arm-swf.c
+++ b/lib/jit_arm-swf.c
@@ -2620,27 +2620,21 @@ _swf_stxi_d(jit_state_t *_jit, jit_word_t i0, 
jit_int32_t r0, jit_int32_t r1)
 static void
 _swf_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
 {
-    jit_int32_t                rg0, rg1;
+    jit_int32_t                reg;
 
     assert(_jitc->function->self.call & jit_call_varargs);
 
-    rg0 = jit_get_reg(jit_class_gpr);
-
-    /* Load stack pointer. */
-    ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack));
-    rg1 = jit_get_reg(jit_class_gpr);
-    andi(rn(rg1), rn(rg0), 7);
-    addr(rn(rg0), rn(rg0), rn(rg1));
-    jit_unget_reg(rg1);
+    /* Adjust pointer. */
+    reg = jit_get_reg(jit_class_gpr);
+    andi(rn(reg), r1, 7);
+    addr(r1, r1, rn(reg));
+    jit_unget_reg(reg);
 
     /* Load argument. */
-    swf_ldr_d(r0, rn(rg0));
+    swf_ldr_d(r0, r1);
 
     /* Update stack pointer. */
-    addi(rn(rg0), rn(rg0), sizeof(jit_float64_t));
-    stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0));
-
-    jit_unget_reg(rg0);
+    addi(r1, r1, sizeof(jit_float64_t));
 }
 
 #endif
diff --git a/lib/jit_arm-vfp.c b/lib/jit_arm-vfp.c
index 6966942..beea825 100644
--- a/lib/jit_arm-vfp.c
+++ b/lib/jit_arm-vfp.c
@@ -2307,27 +2307,21 @@ _vfp_stxi_d(jit_state_t *_jit, jit_word_t i0, 
jit_int32_t r0, jit_int32_t r1)
 static void
 _vfp_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
 {
-    jit_int32_t                rg0, rg1;
+    jit_int32_t                reg;
 
     assert(_jitc->function->self.call & jit_call_varargs);
 
-    rg0 = jit_get_reg(jit_class_gpr);
-
-    /* Load stack pointer. */
-    ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack));
-    rg1 = jit_get_reg(jit_class_gpr);
-    andi(rn(rg1), rn(rg0), 7);
-    addr(rn(rg0), rn(rg0), rn(rg1));
-    jit_unget_reg(rg1);
+    /* Adjust pointer. */
+    reg = jit_get_reg(jit_class_gpr);
+    andi(rn(reg), r1, 7);
+    addr(r1, r1, rn(reg));
+    jit_unget_reg(reg);
 
     /* Load argument. */
-    vfp_ldr_d(r0, rn(rg0));
+    vfp_ldr_d(r0, r1);
 
     /* Update stack pointer. */
-    addi(rn(rg0), rn(rg0), sizeof(jit_float64_t));
-    stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0));
-
-    jit_unget_reg(rg0);
+    addi(r1, r1, sizeof(jit_float64_t));
 }
 #  undef dbopi
 #  undef fbopi
diff --git a/lib/jit_arm.c b/lib/jit_arm.c
index 66ce126..60a8ff1 100644
--- a/lib/jit_arm.c
+++ b/lib/jit_arm.c
@@ -34,6 +34,11 @@
 
 #define jit_fpr_p(rn)                  ((rn) > 15)
 
+#define arg_base()                                                     \
+    (stack_framesize - 16 + (jit_cpu.abi ? 64 : 0))
+#define arg_offset(n)                                                  \
+    ((n) < 4 ? arg_base() + ((n) << 2) : (n))
+
 /* Assume functions called never match jit instruction set, that is
  * libc, gmp, mpfr, etc functions are in thumb mode and jit is in
  * arm mode, what may cause a crash upon return of that function
@@ -51,9 +56,7 @@ typedef union _jit_thumb_t {
     jit_int16_t                s[2];
 } jit_thumb_t;
 
-typedef struct jit_va_list {
-    jit_pointer_t      stack;
-} jit_va_list_t;
+typedef jit_pointer_t  jit_va_list;
 
 /*
  * Prototypes
@@ -420,9 +423,6 @@ _jit_ellipsis(jit_state_t *_jit)
        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));
-
        /* 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;
@@ -504,7 +504,7 @@ _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t 
*v)
 {
     assert(v->code == jit_code_arg);
     if (jit_swf_p())
-       jit_ldxi_c(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
+       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
@@ -516,7 +516,7 @@ _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t 
*v)
 {
     assert(v->code == jit_code_arg);
     if (jit_swf_p())
-       jit_ldxi_uc(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
+       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
@@ -528,7 +528,7 @@ _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t 
*v)
 {
     assert(v->code == jit_code_arg);
     if (jit_swf_p())
-       jit_ldxi_s(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
+       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
@@ -540,7 +540,7 @@ _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t 
*v)
 {
     assert(v->code == jit_code_arg);
     if (jit_swf_p())
-       jit_ldxi_us(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
+       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
@@ -552,7 +552,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t 
*v)
 {
     assert(v->code == jit_code_arg);
     if (jit_swf_p())
-       jit_ldxi_i(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
+       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
@@ -564,7 +564,7 @@ _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t 
*v)
 {
     assert(v->code == jit_code_arg);
     if (jit_swf_p())
-       jit_stxi(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, u);
+       jit_stxi(arg_offset(v->u.w), JIT_FP, u);
     else if (jit_arg_reg_p(v->u.w))
        jit_movr(JIT_RA0 - v->u.w, u);
     else
@@ -579,7 +579,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
     if (jit_swf_p()) {
        regno = jit_get_reg(jit_class_gpr);
        jit_movi(regno, u);
-       jit_stxi(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, regno);
+       jit_stxi(arg_offset(v->u.w), JIT_FP, regno);
        jit_unget_reg(regno);
     }
     else if (jit_arg_reg_p(v->u.w))
@@ -603,7 +603,7 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t 
*v)
            jit_ldxi_f(u, JIT_FP, v->u.w);
     }
     else if (jit_swf_p())
-       jit_ldxi_f(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
+       jit_ldxi_f(u, JIT_FP, arg_offset(v->u.w));
     else {
        if (jit_arg_reg_p(v->u.w))
            jit_movr_w_f(u, JIT_RA0 - v->u.w);
@@ -623,7 +623,7 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t 
*v)
            jit_stxi_f(v->u.w, JIT_FP, u);
     }
     else if (jit_swf_p())
-       jit_stxi_f(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, u);
+       jit_stxi_f(arg_offset(v->u.w), JIT_FP, u);
     else {
        if (jit_arg_reg_p(v->u.w))
            jit_movr_f_w(JIT_RA0 - v->u.w, u);
@@ -650,7 +650,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, 
jit_node_t *v)
     else if (jit_swf_p()) {
        regno = jit_get_reg(jit_class_fpr);
        jit_movi_f(regno, u);
-       jit_stxi_f(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, regno);
+       jit_stxi_f(arg_offset(v->u.w), JIT_FP, regno);
        jit_unget_reg(regno);
     }
     else {
@@ -675,7 +675,7 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t 
*v)
            jit_ldxi_d(u, JIT_FP, v->u.w);
     }
     else if (jit_swf_p())
-       jit_ldxi_d(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
+       jit_ldxi_d(u, JIT_FP, arg_offset(v->u.w));
     else {
        if (jit_arg_reg_p(v->u.w))
            jit_movr_ww_d(u, JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1));
@@ -695,7 +695,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t 
*v)
            jit_stxi_d(v->u.w, JIT_FP, u);
     }
     else if (jit_swf_p())
-       jit_stxi_d(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, u);
+       jit_stxi_d(arg_offset(v->u.w), JIT_FP, u);
     else {
        if (jit_arg_reg_p(v->u.w))
            jit_movr_d_ww(JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1), u);
@@ -722,7 +722,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, 
jit_node_t *v)
     else if (jit_swf_p()) {
        regno = jit_get_reg(jit_class_fpr);
        jit_movi_d(regno, u);
-       jit_stxi_d(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, regno);
+       jit_stxi_d(arg_offset(v->u.w), JIT_FP, regno);
        jit_unget_reg(regno);
     }
     else {
diff --git a/lib/jit_x86-cpu.c b/lib/jit_x86-cpu.c
index a77eb55..448edcd 100644
--- a/lib/jit_x86-cpu.c
+++ b/lib/jit_x86-cpu.c
@@ -3654,6 +3654,10 @@ _epilog(jit_state_t *_jit, jit_node_t *node)
 static void
 _vastart(jit_state_t *_jit, jit_int32_t r0)
 {
+#if __X32 || __CYGWIN__
+    assert(_jitc->function->self.call & jit_call_varargs);
+    addi(r0, _RBP_REGNO, _jitc->function->self.size);
+#else
     jit_int32_t                reg;
 
     assert(_jitc->function->self.call & jit_call_varargs);
@@ -3662,7 +3666,6 @@ _vastart(jit_state_t *_jit, jit_int32_t r0)
     addi(r0, _RBP_REGNO, _jitc->function->vaoff);
     reg = jit_get_reg(jit_class_gpr);
 
-#if __X64 && !__CYGWIN__
     /* Initialize gp offset in the save area. */
     movi(rn(reg), _jitc->function->vagp);
     stxi_i(offsetof(jit_va_list_t, gpoff), r0, rn(reg));
@@ -3670,35 +3673,35 @@ _vastart(jit_state_t *_jit, jit_int32_t r0)
     /* Initialize fp offset in the save area. */
     movi(rn(reg), _jitc->function->vafp);
     stxi_i(offsetof(jit_va_list_t, fpoff), r0, rn(reg));
-#endif
 
     /* Initialize overflow pointer to the first stack argument. */
     addi(rn(reg), _RBP_REGNO, _jitc->function->self.size);
     stxi(offsetof(jit_va_list_t, over), r0, rn(reg));
 
-#if __X64 && !__CYGWIN__
     /* Initialize register save area pointer. */
     addi(rn(reg), r0, first_gp_offset);
     stxi(offsetof(jit_va_list_t, save), r0, rn(reg));
-#endif
 
     jit_unget_reg(reg);
+#endif
 }
 
 static void
 _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
 {
+#if __X32 || __CYGWIN__
+    assert(_jitc->function->self.call & jit_call_varargs);
+    ldr(r0, r1);
+    addi(r1, r1, va_gp_increment);
+#else
     jit_int32_t                rg0;
-#if __X64 && !__CYGWIN__
     jit_int32_t                rg1;
     jit_word_t         ge_code;
     jit_word_t         lt_code;
-#endif
 
     assert(_jitc->function->self.call & jit_call_varargs);
 
     rg0 = jit_get_reg(jit_class_gpr);
-#if __X64 && !__CYGWIN__
     rg1 = jit_get_reg(jit_class_gpr);
 
     /* Load the gp offset in save area in the first temporary. */
@@ -3728,7 +3731,6 @@ _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
 
     /* Where to land if argument is in overflow area. */
     patch_rel_char(ge_code, _jit->pc.w);
-#endif
 
     /* Load overflow pointer. */
     ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over));
@@ -3740,12 +3742,11 @@ _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t 
r1)
     addi(rn(rg0), rn(rg0), va_gp_increment);
     stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));
 
-#if __X64 && !__CYGWIN__
     /* Where to land if argument is in save area. */
     patch_rel_char(lt_code, _jit->pc.w);
-#endif
 
     jit_unget_reg(rg0);
+#endif
 }
 
 /* The x87 boolean argument tells if will put the result in a x87
@@ -3753,17 +3754,22 @@ _vaarg(jit_state_t *_jit, 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_bool_t x87)
 {
+#if __X32 || __CYGWIN__
+    assert(_jitc->function->self.call & jit_call_varargs);
+    if (x87)
+       x87_ldr_d(r0, r1);
+    else
+       sse_ldr_d(r0, r1);
+    addi(r1, r1, 8);
+#else
     jit_int32_t                rg0;
-#if __X64 && !__CYGWIN__
     jit_int32_t                rg1;
     jit_word_t         ge_code;
     jit_word_t         lt_code;
-#endif
 
     assert(_jitc->function->self.call & jit_call_varargs);
 
     rg0 = jit_get_reg(jit_class_gpr);
-#if __X64 && !__CYGWIN__
     rg1 = jit_get_reg(jit_class_gpr);
 
     /* Load the fp offset in save area in the first temporary. */
@@ -3796,7 +3802,6 @@ _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t 
r1, jit_bool_t x87)
 
     /* Where to land if argument is in overflow area. */
     patch_rel_char(ge_code, _jit->pc.w);
-#endif
 
     /* Load overflow pointer. */
     ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over));
@@ -3811,12 +3816,11 @@ _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t 
r1, jit_bool_t x87)
     addi(rn(rg0), rn(rg0), 8);
     stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));
 
-#if __X64 && !__CYGWIN__
     /* Where to land if argument is in save area. */
     patch_rel_char(lt_code, _jit->pc.w);
-#endif
 
     jit_unget_reg(rg0);
+#endif
 }
 
 static void
diff --git a/lib/jit_x86-sz.c b/lib/jit_x86-sz.c
index ba79079..c6e4ebd 100644
--- a/lib/jit_x86-sz.c
+++ b/lib/jit_x86-sz.c
@@ -9,7 +9,7 @@
     0, /* #name */
     0, /* #note */
     3, /* label */
-    26,        /* prolog */
+    34,        /* prolog */
     0, /* arg */
     3, /* addr */
     6, /* addi */
@@ -23,7 +23,7 @@
     6, /* subci */
     6, /* subxr */
     5, /* subxi */
-    10,        /* rsbi */
+    8, /* rsbi */
     5, /* mulr */
     7, /* muli */
     20,        /* qmulr */
@@ -84,7 +84,7 @@
     3, /* extr_us */
     0, /* extr_i */
     0, /* extr_ui */
-    4, /* htonr_us */
+    7, /* htonr_us */
     4, /* htonr_ui */
     0, /* htonr_ul */
     3, /* ldr_c */
@@ -102,13 +102,13 @@
     0, /* ldr_l */
     0, /* ldi_l */
     4, /* ldxr_c */
-    4, /* ldxi_c */
+    7, /* ldxi_c */
     4, /* ldxr_uc */
-    4, /* ldxi_uc */
+    7, /* ldxi_uc */
     4, /* ldxr_s */
-    4, /* ldxi_s */
+    7, /* ldxi_s */
     4, /* ldxr_us */
-    4, /* ldxi_us */
+    7, /* ldxi_us */
     3, /* ldxr_i */
     6, /* ldxi_i */
     0, /* ldxr_ui */
@@ -126,7 +126,7 @@
     11,        /* stxr_c */
     11,        /* stxi_c */
     4, /* stxr_s */
-    4, /* stxi_s */
+    7, /* stxi_s */
     3, /* stxr_i */
     6, /* stxi_i */
     0, /* stxr_l */
@@ -173,15 +173,15 @@
     9, /* bxsubi_u */
     2, /* jmpr */
     5, /* jmpi */
-    4, /* callr */
-    7, /* calli */
+    2, /* callr */
+    5, /* calli */
     24,        /* epilog */
     0, /* arg_f */
     8, /* addr_f */
     19,        /* addi_f */
     12,        /* subr_f */
     19,        /* subi_f */
-    19,        /* rsbi_f */
+    21,        /* rsbi_f */
     8, /* mulr_f */
     19,        /* muli_f */
     12,        /* divr_f */
@@ -226,11 +226,11 @@
     4, /* ldr_f */
     8, /* ldi_f */
     5, /* ldxr_f */
-    5, /* ldxi_f */
+    8, /* ldxi_f */
     6, /* str_f */
     10,        /* sti_f */
     7, /* stxr_f */
-    7, /* stxi_f */
+    8, /* stxi_f */
     10,        /* bltr_f */
     23,        /* blti_f */
     10,        /* bler_f */
@@ -264,7 +264,7 @@
     26,        /* addi_d */
     12,        /* subr_d */
     26,        /* subi_d */
-    26,        /* rsbi_d */
+    30,        /* rsbi_d */
     8, /* mulr_d */
     26,        /* muli_d */
     12,        /* divr_d */
@@ -313,7 +313,7 @@
     6, /* str_d */
     10,        /* sti_d */
     7, /* stxr_d */
-    7, /* stxi_d */
+    8, /* stxi_d */
     10,        /* bltr_d */
     28,        /* blti_d */
     10,        /* bler_d */
@@ -353,9 +353,9 @@
     0, /* movi_d_w */
     10,        /* x86_retval_f */
     10,        /* x86_retval_d */
-    0, /* va_start */
-    0, /* va_arg */
-    0, /* va_arg_d */
+    3, /* va_start */
+    5, /* va_arg */
+    7, /* va_arg_d */
     0, /* va_end */
 #endif /* __X32 */
 
@@ -721,7 +721,7 @@
 #else
 
 #  if __X64_32
-#define JIT_INSTR_MAX 44
+#define JIT_INSTR_MAX 108
     0, /* data */
     0, /* live */
     3, /* align */
@@ -730,7 +730,7 @@
     0, /* #name */
     0, /* #note */
     3, /* label */
-    39,        /* prolog */
+    108,       /* prolog */
     0, /* arg */
     5, /* addr */
     7, /* addi */
@@ -822,15 +822,15 @@
     0, /* ldi_ui */
     0, /* ldr_l */
     0, /* ldi_l */
-    6, /* ldxr_c */
+    9, /* ldxr_c */
     7, /* ldxi_c */
-    6, /* ldxr_uc */
+    9, /* ldxr_uc */
     7, /* ldxi_uc */
-    6, /* ldxr_s */
+    9, /* ldxr_s */
     7, /* ldxi_s */
-    6, /* ldxr_us */
+    9, /* ldxr_us */
     7, /* ldxi_us */
-    5, /* ldxr_i */
+    8, /* ldxr_i */
     7, /* ldxi_i */
     0, /* ldxr_ui */
     0, /* ldxi_ui */
@@ -844,11 +844,11 @@
     8, /* sti_i */
     0, /* str_l */
     0, /* sti_l */
-    8, /* stxr_c */
+    12,        /* stxr_c */
     7, /* stxi_c */
-    6, /* stxr_s */
+    10,        /* stxr_s */
     7, /* stxi_s */
-    5, /* stxr_i */
+    9, /* stxr_i */
     6, /* stxi_i */
     0, /* stxr_l */
     0, /* stxi_l */
@@ -896,7 +896,7 @@
     5, /* jmpi */
     3, /* callr */
     9, /* calli */
-    34,        /* epilog */
+    35,        /* epilog */
     0, /* arg_f */
     10,        /* addr_f */
     21,        /* addi_f */
@@ -946,11 +946,11 @@
     11,        /* movi_f */
     6, /* ldr_f */
     10,        /* ldi_f */
-    7, /* ldxr_f */
+    11,        /* ldxr_f */
     9, /* ldxi_f */
     6, /* str_f */
     10,        /* sti_f */
-    7, /* stxr_f */
+    11,        /* stxr_f */
     9, /* stxi_f */
     10,        /* bltr_f */
     21,        /* blti_f */
@@ -1029,11 +1029,11 @@
     23,        /* movi_d */
     6, /* ldr_d */
     10,        /* ldi_d */
-    7, /* ldxr_d */
+    11,        /* ldxr_d */
     9, /* ldxi_d */
     6, /* str_d */
     10,        /* sti_d */
-    7, /* stxr_d */
+    11,        /* stxr_d */
     9, /* stxi_d */
     11,        /* bltr_d */
     34,        /* blti_d */
@@ -1074,22 +1074,22 @@
     0, /* movi_d_w */
     0, /* x86_retval_f */
     0, /* x86_retval_d */
-    0, /* va_start */
-    0, /* va_arg */
-    0, /* va_arg_d */
+    41,        /* va_start */
+    45,        /* va_arg */
+    54,        /* va_arg_d */
     0, /* va_end */
 #  else
 
-#define JIT_INSTR_MAX 43
+#define JIT_INSTR_MAX 115
     0, /* data */
     0, /* live */
-    7, /* align */
+    6, /* align */
     0, /* save */
     0, /* load */
     0, /* #name */
     0, /* #note */
     7, /* label */
-    43,        /* prolog */
+    115,       /* prolog */
     0, /* arg */
     5, /* addr */
     13,        /* addi */
@@ -1103,7 +1103,7 @@
     13,        /* subci */
     9, /* subxr */
     7, /* subxi */
-    19,        /* rsbi */
+    16,        /* rsbi */
     7, /* mulr */
     14,        /* muli */
     20,        /* qmulr */
@@ -1182,17 +1182,17 @@
     4, /* ldr_l */
     8, /* ldi_l */
     6, /* ldxr_c */
-    5, /* ldxi_c */
+    8, /* ldxi_c */
     6, /* ldxr_uc */
-    5, /* ldxi_uc */
+    8, /* ldxi_uc */
     6, /* ldxr_s */
-    5, /* ldxi_s */
+    8, /* ldxi_s */
     6, /* ldxr_us */
-    5, /* ldxi_us */
+    8, /* ldxi_us */
     5, /* ldxr_i */
     7, /* ldxi_i */
     5, /* ldxr_ui */
-    4, /* ldxi_ui */
+    6, /* ldxi_ui */
     5, /* ldxr_l */
     7, /* ldxi_l */
     4, /* str_c */
@@ -1204,9 +1204,9 @@
     4, /* str_l */
     8, /* sti_l */
     5, /* stxr_c */
-    4, /* stxi_c */
+    6, /* stxi_c */
     6, /* stxr_s */
-    5, /* stxi_s */
+    7, /* stxi_s */
     5, /* stxr_i */
     6, /* stxi_i */
     5, /* stxr_l */
@@ -1251,22 +1251,22 @@
     10,        /* bxsubi */
     9, /* bxsubr_u */
     10,        /* bxsubi_u */
-    0, /* jmpr */
+    3, /* jmpr */
     5, /* jmpi */
     3, /* callr */
     13,        /* calli */
-    37,        /* epilog */
+    38,        /* epilog */
     0, /* arg_f */
     10,        /* addr_f */
-    20,        /* addi_f */
+    21,        /* addi_f */
     15,        /* subr_f */
-    20,        /* subi_f */
-    20,        /* rsbi_f */
+    21,        /* subi_f */
+    30,        /* rsbi_f */
     10,        /* mulr_f */
-    20,        /* muli_f */
+    21,        /* muli_f */
     15,        /* divr_f */
-    20,        /* divi_f */
-    14,        /* negr_f */
+    21,        /* divi_f */
+    15,        /* negr_f */
     15,        /* absr_f */
     5, /* sqrtr_f */
     11,        /* ltr_f */
@@ -1306,13 +1306,13 @@
     6, /* ldr_f */
     10,        /* ldi_f */
     7, /* ldxr_f */
-    6, /* ldxi_f */
+    9, /* ldxi_f */
     6, /* str_f */
     10,        /* sti_f */
     7, /* stxr_f */
-    7, /* stxi_f */
+    9, /* stxi_f */
     10,        /* bltr_f */
-    20,        /* blti_f */
+    21,        /* blti_f */
     10,        /* bler_f */
     25,        /* blei_f */
     12,        /* beqr_f */
@@ -1344,12 +1344,12 @@
     25,        /* addi_d */
     15,        /* subr_d */
     25,        /* subi_d */
-    25,        /* rsbi_d */
+    30,        /* rsbi_d */
     10,        /* mulr_d */
     25,        /* muli_d */
     15,        /* divr_d */
     25,        /* divi_d */
-    21,        /* negr_d */
+    22,        /* negr_d */
     16,        /* absr_d */
     5, /* sqrtr_d */
     12,        /* ltr_d */
@@ -1389,11 +1389,11 @@
     6, /* ldr_d */
     10,        /* ldi_d */
     7, /* ldxr_d */
-    6, /* ldxi_d */
+    9, /* ldxi_d */
     6, /* str_d */
     10,        /* sti_d */
     7, /* stxr_d */
-    7, /* stxi_d */
+    9, /* stxi_d */
     11,        /* bltr_d */
     26,        /* blti_d */
     11,        /* bler_d */
@@ -1433,9 +1433,9 @@
     0, /* movi_d_w */
     0, /* x86_retval_f */
     0, /* x86_retval_d */
-    0, /* va_start */
-    0, /* va_arg */
-    0, /* va_arg_d */
+    42,        /* va_start */
+    41,        /* va_arg */
+    50,        /* va_arg_d */
     0, /* va_end */
 #endif /* __CYGWIN__ */
 #  endif /* __X64_32 */
diff --git a/lib/jit_x86.c b/lib/jit_x86.c
index 1806a27..fadd9c5 100644
--- a/lib/jit_x86.c
+++ b/lib/jit_x86.c
@@ -61,13 +61,16 @@
 #  define REAL_WORDSIZE                        8
 #endif
 
+/*
+ * Types
+ */
+#if __X32 || __CYGWIN__
+typedef jit_pointer_t jit_va_list_t;
+#else
 typedef struct jit_va_list {
-#if __X64 && !__CYGWIN__
     jit_int32_t                gpoff;
     jit_int32_t                fpoff;
-#endif
     jit_pointer_t      over;
-#if __X64 && !__CYGWIN__
     jit_pointer_t      save;
     /* Declared explicitly as int64 for the x32 abi */
     jit_int64_t                rdi;
@@ -92,8 +95,8 @@ typedef struct jit_va_list {
     jit_float64_t      _up6;
     jit_float64_t      xmm7;
     jit_float64_t      _up7;
-#endif
 } jit_va_list_t;
+#endif
 
 /*
  * Prototypes
@@ -564,12 +567,12 @@ _jit_ellipsis(jit_state_t *_jit)
        assert(!(_jitc->function->self.call & jit_call_varargs));
        _jitc->function->self.call |= jit_call_varargs;
 
+#if __X64 && !__CYGWIN__
        /* Allocate va_list like object in the stack.
         * If applicable, with enough space to save all argument
         * registers, and use fixed offsets for them. */
        _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
 
-#if __X64 && !__CYGWIN__
        /* Initialize gp offset in save area. */
        if (jit_arg_reg_p(_jitc->function->self.argi))
            _jitc->function->vagp = _jitc->function->self.argi * 8;



reply via email to

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