aboutsummaryrefslogtreecommitdiff
path: root/deps/lightening/tests
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-04-20 10:47:49 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-04-20 10:47:49 +0300
commit8a98b46ef2b5673fcdf0a9a466857a5de044dfc5 (patch)
treeae548496da015f3319760479e09cfe5a0b1eba5d /deps/lightening/tests
parent1cc7990ef7d5483d0434dda412f2d88e0b17df27 (diff)
downloadposthaste-8a98b46ef2b5673fcdf0a9a466857a5de044dfc5.tar.gz
posthaste-8a98b46ef2b5673fcdf0a9a466857a5de044dfc5.zip
add lightening jit
Diffstat (limited to 'deps/lightening/tests')
-rw-r--r--deps/lightening/tests/Makefile87
-rw-r--r--deps/lightening/tests/absr_d.c26
-rw-r--r--deps/lightening/tests/absr_f.c26
-rw-r--r--deps/lightening/tests/addi.c25
-rw-r--r--deps/lightening/tests/addr.c26
-rw-r--r--deps/lightening/tests/addr_d.c27
-rw-r--r--deps/lightening/tests/addr_f.c27
-rw-r--r--deps/lightening/tests/addx.c63
-rw-r--r--deps/lightening/tests/andi.c31
-rw-r--r--deps/lightening/tests/andr.c48
-rw-r--r--deps/lightening/tests/beqi.c32
-rw-r--r--deps/lightening/tests/beqr.c36
-rw-r--r--deps/lightening/tests/beqr_d.c35
-rw-r--r--deps/lightening/tests/beqr_f.c35
-rw-r--r--deps/lightening/tests/bgei.c32
-rw-r--r--deps/lightening/tests/bgei_u.c32
-rw-r--r--deps/lightening/tests/bger.c34
-rw-r--r--deps/lightening/tests/bger_d.c34
-rw-r--r--deps/lightening/tests/bger_f.c34
-rw-r--r--deps/lightening/tests/bger_u.c35
-rw-r--r--deps/lightening/tests/bgti.c33
-rw-r--r--deps/lightening/tests/bgti_u.c31
-rw-r--r--deps/lightening/tests/bgtr.c34
-rw-r--r--deps/lightening/tests/bgtr_d.c34
-rw-r--r--deps/lightening/tests/bgtr_f.c34
-rw-r--r--deps/lightening/tests/bgtr_u.c34
-rw-r--r--deps/lightening/tests/blei.c31
-rw-r--r--deps/lightening/tests/blei_u.c31
-rw-r--r--deps/lightening/tests/bler.c34
-rw-r--r--deps/lightening/tests/bler_d.c34
-rw-r--r--deps/lightening/tests/bler_f.c34
-rw-r--r--deps/lightening/tests/bler_u.c34
-rw-r--r--deps/lightening/tests/bltgtr_d.c36
-rw-r--r--deps/lightening/tests/bltgtr_f.c36
-rw-r--r--deps/lightening/tests/blti.c31
-rw-r--r--deps/lightening/tests/blti_u.c31
-rw-r--r--deps/lightening/tests/bltr.c34
-rw-r--r--deps/lightening/tests/bltr_d.c34
-rw-r--r--deps/lightening/tests/bltr_f.c34
-rw-r--r--deps/lightening/tests/bltr_u.c34
-rw-r--r--deps/lightening/tests/bmci.c36
-rw-r--r--deps/lightening/tests/bmcr.c38
-rw-r--r--deps/lightening/tests/bmsi.c36
-rw-r--r--deps/lightening/tests/bmsr.c38
-rw-r--r--deps/lightening/tests/bnei.c31
-rw-r--r--deps/lightening/tests/bner.c34
-rw-r--r--deps/lightening/tests/bner_d.c36
-rw-r--r--deps/lightening/tests/bner_f.c36
-rw-r--r--deps/lightening/tests/boaddi.c41
-rw-r--r--deps/lightening/tests/boaddi_u.c41
-rw-r--r--deps/lightening/tests/boaddr.c51
-rw-r--r--deps/lightening/tests/boaddr_u.c51
-rw-r--r--deps/lightening/tests/bordr_d.c36
-rw-r--r--deps/lightening/tests/bordr_f.c36
-rw-r--r--deps/lightening/tests/bosubi.c41
-rw-r--r--deps/lightening/tests/bosubi_u.c37
-rw-r--r--deps/lightening/tests/bosubr.c48
-rw-r--r--deps/lightening/tests/bosubr_u.c47
-rw-r--r--deps/lightening/tests/bswapr_ui.c28
-rw-r--r--deps/lightening/tests/bswapr_ul.c27
-rw-r--r--deps/lightening/tests/bswapr_us.c24
-rw-r--r--deps/lightening/tests/buneqr_d.c35
-rw-r--r--deps/lightening/tests/buneqr_f.c35
-rw-r--r--deps/lightening/tests/bunger_d.c34
-rw-r--r--deps/lightening/tests/bunger_f.c34
-rw-r--r--deps/lightening/tests/bungtr_d.c34
-rw-r--r--deps/lightening/tests/bungtr_f.c34
-rw-r--r--deps/lightening/tests/bunler_d.c34
-rw-r--r--deps/lightening/tests/bunler_f.c34
-rw-r--r--deps/lightening/tests/bunltr_d.c34
-rw-r--r--deps/lightening/tests/bunltr_f.c34
-rw-r--r--deps/lightening/tests/bunordr_d.c36
-rw-r--r--deps/lightening/tests/bunordr_f.c36
-rw-r--r--deps/lightening/tests/bxaddi.c39
-rw-r--r--deps/lightening/tests/bxaddi_u.c39
-rw-r--r--deps/lightening/tests/bxaddr.c49
-rw-r--r--deps/lightening/tests/bxaddr_u.c49
-rw-r--r--deps/lightening/tests/bxsubi.c39
-rw-r--r--deps/lightening/tests/bxsubi_u.c35
-rw-r--r--deps/lightening/tests/bxsubr.c46
-rw-r--r--deps/lightening/tests/bxsubr_u.c45
-rw-r--r--deps/lightening/tests/call_10.c54
-rw-r--r--deps/lightening/tests/call_double.c38
-rw-r--r--deps/lightening/tests/call_float.c38
-rw-r--r--deps/lightening/tests/callee_9.c68
-rw-r--r--deps/lightening/tests/cas_atomic.c33
-rw-r--r--deps/lightening/tests/comr.c41
-rw-r--r--deps/lightening/tests/divr.c60
-rw-r--r--deps/lightening/tests/divr_d.c27
-rw-r--r--deps/lightening/tests/divr_f.c27
-rw-r--r--deps/lightening/tests/divr_u.c55
-rw-r--r--deps/lightening/tests/extr_c.c27
-rw-r--r--deps/lightening/tests/extr_d.c25
-rw-r--r--deps/lightening/tests/extr_d_f.c26
-rw-r--r--deps/lightening/tests/extr_f.c25
-rw-r--r--deps/lightening/tests/extr_f_d.c26
-rw-r--r--deps/lightening/tests/extr_i.c30
-rw-r--r--deps/lightening/tests/extr_s.c28
-rw-r--r--deps/lightening/tests/extr_uc.c27
-rw-r--r--deps/lightening/tests/extr_ui.c29
-rw-r--r--deps/lightening/tests/extr_us.c27
-rw-r--r--deps/lightening/tests/jmp0.c24
-rw-r--r--deps/lightening/tests/jmp_table.c61
-rw-r--r--deps/lightening/tests/jmpi.c41
-rw-r--r--deps/lightening/tests/jmpi_local.c25
-rw-r--r--deps/lightening/tests/jmpr.c23
-rw-r--r--deps/lightening/tests/ldi_c.c24
-rw-r--r--deps/lightening/tests/ldi_d.c24
-rw-r--r--deps/lightening/tests/ldi_f.c24
-rw-r--r--deps/lightening/tests/ldi_i.c24
-rw-r--r--deps/lightening/tests/ldi_l.c26
-rw-r--r--deps/lightening/tests/ldi_s.c24
-rw-r--r--deps/lightening/tests/ldi_uc.c24
-rw-r--r--deps/lightening/tests/ldi_ui.c26
-rw-r--r--deps/lightening/tests/ldi_us.c24
-rw-r--r--deps/lightening/tests/ldr_atomic.c28
-rw-r--r--deps/lightening/tests/ldr_c.c27
-rw-r--r--deps/lightening/tests/ldr_d.c27
-rw-r--r--deps/lightening/tests/ldr_f.c27
-rw-r--r--deps/lightening/tests/ldr_i.c27
-rw-r--r--deps/lightening/tests/ldr_l.c29
-rw-r--r--deps/lightening/tests/ldr_s.c27
-rw-r--r--deps/lightening/tests/ldr_uc.c27
-rw-r--r--deps/lightening/tests/ldr_ui.c29
-rw-r--r--deps/lightening/tests/ldr_us.c27
-rw-r--r--deps/lightening/tests/ldxi_c.c27
-rw-r--r--deps/lightening/tests/ldxi_d.c27
-rw-r--r--deps/lightening/tests/ldxi_f.c27
-rw-r--r--deps/lightening/tests/ldxi_i.c27
-rw-r--r--deps/lightening/tests/ldxi_l.c29
-rw-r--r--deps/lightening/tests/ldxi_s.c27
-rw-r--r--deps/lightening/tests/ldxi_uc.c27
-rw-r--r--deps/lightening/tests/ldxi_ui.c29
-rw-r--r--deps/lightening/tests/ldxi_us.c27
-rw-r--r--deps/lightening/tests/ldxr_c.c28
-rw-r--r--deps/lightening/tests/ldxr_d.c28
-rw-r--r--deps/lightening/tests/ldxr_f.c28
-rw-r--r--deps/lightening/tests/ldxr_i.c28
-rw-r--r--deps/lightening/tests/ldxr_l.c30
-rw-r--r--deps/lightening/tests/ldxr_s.c28
-rw-r--r--deps/lightening/tests/ldxr_uc.c28
-rw-r--r--deps/lightening/tests/ldxr_ui.c30
-rw-r--r--deps/lightening/tests/ldxr_us.c28
-rw-r--r--deps/lightening/tests/link-register.c35
-rw-r--r--deps/lightening/tests/lshi.c27
-rw-r--r--deps/lightening/tests/lshr.c69
-rw-r--r--deps/lightening/tests/mov_addr.c25
-rw-r--r--deps/lightening/tests/movi.c22
-rw-r--r--deps/lightening/tests/movi_d.c22
-rw-r--r--deps/lightening/tests/movi_f.c22
-rw-r--r--deps/lightening/tests/mulr.c64
-rw-r--r--deps/lightening/tests/mulr_d.c27
-rw-r--r--deps/lightening/tests/mulr_f.c27
-rw-r--r--deps/lightening/tests/negr.c39
-rw-r--r--deps/lightening/tests/negr_d.c26
-rw-r--r--deps/lightening/tests/negr_f.c26
-rw-r--r--deps/lightening/tests/ori.c31
-rw-r--r--deps/lightening/tests/orr.c48
-rw-r--r--deps/lightening/tests/qdivr.c44
-rw-r--r--deps/lightening/tests/qdivr_u.c42
-rw-r--r--deps/lightening/tests/qmulr.c58
-rw-r--r--deps/lightening/tests/qmulr_u.c46
-rw-r--r--deps/lightening/tests/remr.c60
-rw-r--r--deps/lightening/tests/remr_u.c56
-rw-r--r--deps/lightening/tests/rshi.c28
-rw-r--r--deps/lightening/tests/rshi_u.c28
-rw-r--r--deps/lightening/tests/rshr.c63
-rw-r--r--deps/lightening/tests/rshr_u.c62
-rw-r--r--deps/lightening/tests/sqrtr_d.c25
-rw-r--r--deps/lightening/tests/sqrtr_f.c25
-rw-r--r--deps/lightening/tests/sti_c.c31
-rw-r--r--deps/lightening/tests/sti_d.c31
-rw-r--r--deps/lightening/tests/sti_f.c31
-rw-r--r--deps/lightening/tests/sti_i.c31
-rw-r--r--deps/lightening/tests/sti_l.c33
-rw-r--r--deps/lightening/tests/sti_s.c31
-rw-r--r--deps/lightening/tests/str_atomic.c32
-rw-r--r--deps/lightening/tests/str_c.c32
-rw-r--r--deps/lightening/tests/str_d.c32
-rw-r--r--deps/lightening/tests/str_f.c32
-rw-r--r--deps/lightening/tests/str_i.c32
-rw-r--r--deps/lightening/tests/str_l.c34
-rw-r--r--deps/lightening/tests/str_s.c32
-rw-r--r--deps/lightening/tests/stxi_c.c32
-rw-r--r--deps/lightening/tests/stxi_d.c32
-rw-r--r--deps/lightening/tests/stxi_f.c32
-rw-r--r--deps/lightening/tests/stxi_i.c32
-rw-r--r--deps/lightening/tests/stxi_l.c34
-rw-r--r--deps/lightening/tests/stxi_s.c32
-rw-r--r--deps/lightening/tests/stxr_c.c33
-rw-r--r--deps/lightening/tests/stxr_d.c33
-rw-r--r--deps/lightening/tests/stxr_f.c33
-rw-r--r--deps/lightening/tests/stxr_i.c33
-rw-r--r--deps/lightening/tests/stxr_l.c35
-rw-r--r--deps/lightening/tests/stxr_s.c33
-rw-r--r--deps/lightening/tests/subr.c26
-rw-r--r--deps/lightening/tests/subr_d.c27
-rw-r--r--deps/lightening/tests/subr_f.c27
-rw-r--r--deps/lightening/tests/subx.c63
-rw-r--r--deps/lightening/tests/swap_atomic.c32
-rw-r--r--deps/lightening/tests/test.h79
-rw-r--r--deps/lightening/tests/truncr_d_i.c30
-rw-r--r--deps/lightening/tests/truncr_d_l.c32
-rw-r--r--deps/lightening/tests/truncr_f_i.c30
-rw-r--r--deps/lightening/tests/truncr_f_l.c32
-rw-r--r--deps/lightening/tests/xori.c31
-rw-r--r--deps/lightening/tests/xorr.c48
-rw-r--r--deps/lightening/tests/z_atomic.c88
-rw-r--r--deps/lightening/tests/z_bp.c61
-rw-r--r--deps/lightening/tests/z_branch.c584
-rw-r--r--deps/lightening/tests/z_call.c307
-rw-r--r--deps/lightening/tests/z_ccall.c1000
-rw-r--r--deps/lightening/tests/z_clobber.c1145
-rw-r--r--deps/lightening/tests/z_range.c577
-rw-r--r--deps/lightening/tests/z_ranger.c580
-rw-r--r--deps/lightening/tests/z_stack.c374
216 files changed, 11852 insertions, 0 deletions
diff --git a/deps/lightening/tests/Makefile b/deps/lightening/tests/Makefile
new file mode 100644
index 0000000..793f225
--- /dev/null
+++ b/deps/lightening/tests/Makefile
@@ -0,0 +1,87 @@
+TESTS ?= $(sort $(basename $(wildcard *.c)))
+TARGETS ?= native ia32 aarch64 armv7 mips64el mipsel ppc64le
+
+# Suitable values of cross-compiler variables for Debian:
+#
+# make test CC_IA32=i668-linux-gnu-gcc CC_AARCH64=aarch64-linux-gnu-gcc
+#
+# The relevant packages that you need to run this:
+#
+# dpkg --add-architecture i386
+# dpkg --add-architecture arm64
+# apt-get update -qq
+# apt-get install -y \
+# libc6-dev:amd64 gcc make \
+# qemu binfmt-support qemu-user-static \
+# gcc-i686-linux-gnu libc6-dev-i386-cross libc6:i386 \
+# gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6:arm64
+#
+CC = gcc
+CC_IA32=guix environment --pure -s i686-linux --ad-hoc gcc-toolchain -- gcc
+CC_AARCH64=guix environment --pure -s aarch64-linux --ad-hoc gcc-toolchain -- gcc
+CC_ARMv7=guix environment --pure -s armhf-linux --ad-hoc gcc-toolchain -- gcc
+CC_MIPS64EL=guix environment --pure -s mips64el-linux --ad-hoc gcc-toolchain -- gcc
+CC_MIPSEL=guix environment --pure -s mipsel-linux --ad-hoc gcc-toolchain -- gcc
+CC_PPC64LE=guix environment --pure -s powerpc64le-linux --ad-hoc gcc-toolchain -- gcc
+CFLAGS = -Wall -O0 -g $(DEBUG)
+LDFLAGS = -lpthread
+RUNNER =
+
+all: $(foreach TARGET,$(TARGETS),$(addprefix test-$(TARGET)-,$(TESTS)))
+
+check: $(addprefix test-$(TARGET),$(TARGETS))
+
+test-vg-%: $(addprefix test-%-,$(TESTS))
+ @echo "Running unit tests..."
+ @set -e; for test in $?; do \
+ echo "Testing: $$test"; \
+ valgrind -q --error-exitcode=1 ./$$test; \
+ done
+ @echo "Success."
+
+test-%: $(addprefix test-%-,$(TESTS))
+ @echo "Running unit tests..."
+ @set -e; for test in $?; do \
+ echo "Testing: $$test"; \
+ ./$$test; \
+ done
+ @echo "Success."
+
+.PHONY: test check
+
+lightening-%.o: ../lightening.h ../lightening/*.c ../lightening/*.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) -I.. -o $@ -c ../lightening/lightening.c
+
+test-native-%: %.c lightening-native.o test.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) -I.. -o $@ lightening-native.o $< $(LDFLAGS)
+
+test-ia32-%: CC = $(CC_IA32)
+test-ia32-%: %.c lightening-ia32.o test.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) -I.. -o $@ lightening-ia32.o $< $(LDFLAGS)
+
+test-aarch64-%: CC = $(CC_AARCH64)
+test-aarch64-%: %.c lightening-aarch64.o test.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) -I.. -o $@ lightening-aarch64.o $< $(LDFLAGS)
+
+test-armv7-%: CC = $(CC_ARMv7)
+test-armv7-%: %.c lightening-armv7.o test.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) -I.. -o $@ lightening-armv7.o $< $(LDFLAGS)
+
+test-mips64el-%: CC = $(CC_MIPS64EL)
+test-mips64el-%: %.c lightening-mips64el.o test.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) -I.. -o $@ lightening-mips64el.o $< $(LDFLAGS)
+
+test-mipsel-%: CC = $(CC_MIPSEL)
+test-mipsel-%: %.c lightening-mipsel.o test.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) -I.. -o $@ lightening-mipsel.o $< $(LDFLAGS)
+
+test-ppc64le-%: CC = $(CC_PPC64LE)
+test-ppc64le-%: %.c lightening-ppc64le.o test.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) -I.. -o $@ lightening-ppc64le.o $< $(LDFLAGS)
+
+.PRECIOUS: $(foreach TARGET,$(TARGETS),$(addprefix test-$(TARGET)-,$(TESTS)))
+.PRECIOUS: $(foreach TARGET,$(TARGETS),lightening-$(TARGET).o)
+
+clean:
+ rm -f $(foreach TARGET,$(TARGETS),$(addprefix test-$(TARGET)-,$(TESTS)))
+ rm -f $(foreach TARGET,$(TARGETS),lightening-$(TARGET).o)
diff --git a/deps/lightening/tests/absr_d.c b/deps/lightening/tests/absr_d.c
new file mode 100644
index 0000000..00b8fa4
--- /dev/null
+++ b/deps/lightening/tests/absr_d.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+ jit_absr_d(j, JIT_F0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ double (*f)(double) = jit_end(j, NULL);
+
+ ASSERT(f(0.0) == 0.0);
+ ASSERT(f(-0.0) == 0.0);
+ ASSERT(f(0.5) == 0.5);
+ ASSERT(f(-0.5) == 0.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/absr_f.c b/deps/lightening/tests/absr_f.c
new file mode 100644
index 0000000..e019b5f
--- /dev/null
+++ b/deps/lightening/tests/absr_f.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+ jit_absr_f(j, JIT_F0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ float (*f)(float) = jit_end(j, NULL);
+
+ ASSERT(f(0.0) == 0.0);
+ ASSERT(f(-0.0) == 0.0);
+ ASSERT(f(0.5) == 0.5);
+ ASSERT(f(-0.5) == 0.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/addi.c b/deps/lightening/tests/addi.c
new file mode 100644
index 0000000..756d070
--- /dev/null
+++ b/deps/lightening/tests/addi.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_addi(j, JIT_R0, JIT_R0, 69);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ int (*f)(int) = ret;
+ ASSERT(f(42) == 111);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/addr.c b/deps/lightening/tests/addr.c
new file mode 100644
index 0000000..6ee76e2
--- /dev/null
+++ b/deps/lightening/tests/addr.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_addr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ int (*f)(int, int) = ret;
+ ASSERT(f(42, 69) == 111);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/addr_d.c b/deps/lightening/tests/addr_d.c
new file mode 100644
index 0000000..1121620
--- /dev/null
+++ b/deps/lightening/tests/addr_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_addr_d(j, JIT_F0, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ double (*f)(double, double) = ret;
+ ASSERT(f(42., 69.) == 111.);
+ ASSERT(f(42.5, 69.5) == 112.);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/addr_f.c b/deps/lightening/tests/addr_f.c
new file mode 100644
index 0000000..4317dfe
--- /dev/null
+++ b/deps/lightening/tests/addr_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_addr_f(j, JIT_F0, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ float (*f)(float, float) = ret;
+ ASSERT(f(42.f, 69.f) == 111.f);
+ ASSERT(f(42.5f, 69.5f) == 112.f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/addx.c b/deps/lightening/tests/addx.c
new file mode 100644
index 0000000..417cd1a
--- /dev/null
+++ b/deps/lightening/tests/addx.c
@@ -0,0 +1,63 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_movi(j, JIT_R2, 0);
+ jit_addcr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_addxi(j, JIT_R2, JIT_R2, 0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R2);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0, 0) == 0);
+
+#if __WORDSIZE == 32
+ /* carry */
+ ASSERT(f(0xffffffff, 0xffffffff) == 1);
+ /* overflow */
+ ASSERT(f(0x7fffffff, 1) == 0);
+ /* overflow */
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+ /* carry */
+ ASSERT(f(0x7fffffff, 0x80000000) == 0);
+ /* carry+overflow */
+ ASSERT(f(0x80000000, 0x80000000) == 1);
+#else
+ /* nothing */
+ ASSERT(f(0xffffffff, 0xffffffff) == 0);
+ /* nothing */
+ ASSERT(f(0x7fffffff, 1) == 0);
+ /* nothing */
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+ /* nothing */
+ ASSERT(f(0x7fffffff, 0x80000000) == 0);
+ /* nothing */
+ ASSERT(f(0x80000000, 0x80000000) == 0);
+ /* carry */
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 1);
+ /* overflow */
+ ASSERT(f(0x7fffffffffffffff, 1) == 0);
+ /* overflow */
+ ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0);
+ /* overflow */
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0);
+ /* carry+overflow */
+ ASSERT(f(0x8000000000000000, 0x8000000000000000) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/andi.c b/deps/lightening/tests/andi.c
new file mode 100644
index 0000000..c6f39d7
--- /dev/null
+++ b/deps/lightening/tests/andi.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_andi(j, JIT_R0, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff) == 1);
+ ASSERT(f(0x80000000) == 0);
+#if __WORDSIZE == 64
+ ASSERT(f(0x7fffffffffffffff) == 1);
+ ASSERT(f(0x8000000000000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/andr.c b/deps/lightening/tests/andr.c
new file mode 100644
index 0000000..1114ef9
--- /dev/null
+++ b/deps/lightening/tests/andr.c
@@ -0,0 +1,48 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_andr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff, 1) == 1);
+ ASSERT(f(1, 0x7fffffff) == 1);
+ ASSERT(f(0x80000000, 1) == 0);
+ ASSERT(f(1, 0x80000000) == 0);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0);
+ ASSERT(f(0x80000000, 0x7fffffff) == 0);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0x7fffffff);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 0x7fffffff);
+ ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffff);
+ ASSERT(f(0x7fffffff, 0) == 0);
+ ASSERT(f(0, 0x7fffffff) == 0);
+#if __WORDSIZE == 64
+ ASSERT(f(0x7fffffffffffffff, 1) == 1);
+ ASSERT(f(1, 0x7fffffffffffffff) == 1);
+ ASSERT(f(0x8000000000000000, 1) == 0);
+ ASSERT(f(1, 0x8000000000000000) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0);
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x7fffffffffffffff);
+ ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0x7fffffffffffffff);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0xffffffffffffffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/beqi.c b/deps/lightening/tests/beqi.c
new file mode 100644
index 0000000..dcb012f
--- /dev/null
+++ b/deps/lightening/tests/beqi.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_beqi(j, JIT_R0, -1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 0);
+ ASSERT(f(-1) == 1);
+
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/beqr.c b/deps/lightening/tests/beqr.c
new file mode 100644
index 0000000..0100400
--- /dev/null
+++ b/deps/lightening/tests/beqr.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_beqr(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 0);
+ ASSERT(f(1, 1) == 1);
+
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffff, -1) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/beqr_d.c b/deps/lightening/tests/beqr_d.c
new file mode 100644
index 0000000..a84b6a7
--- /dev/null
+++ b/deps/lightening/tests/beqr_d.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_beqr_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 0);
+ ASSERT(f(1, 1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/beqr_f.c b/deps/lightening/tests/beqr_f.c
new file mode 100644
index 0000000..7b5cc27
--- /dev/null
+++ b/deps/lightening/tests/beqr_f.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_beqr_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 0);
+ ASSERT(f(1, 1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bgei.c b/deps/lightening/tests/bgei.c
new file mode 100644
index 0000000..f30901e
--- /dev/null
+++ b/deps/lightening/tests/bgei.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bgei(j, JIT_R0, 0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 1);
+ ASSERT(f(1) == 1);
+ ASSERT(f(-1) == 0);
+
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffff) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bgei_u.c b/deps/lightening/tests/bgei_u.c
new file mode 100644
index 0000000..d61089f
--- /dev/null
+++ b/deps/lightening/tests/bgei_u.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bgei_u(j, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 1);
+ ASSERT(f(-1) == 1);
+
+#if __WORDSIZE == 64
+ ASSERT(f(0xff00000000) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bger.c b/deps/lightening/tests/bger.c
new file mode 100644
index 0000000..920e820
--- /dev/null
+++ b/deps/lightening/tests/bger.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bger(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffff, 1) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bger_d.c b/deps/lightening/tests/bger_d.c
new file mode 100644
index 0000000..712b118
--- /dev/null
+++ b/deps/lightening/tests/bger_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bger_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bger_f.c b/deps/lightening/tests/bger_f.c
new file mode 100644
index 0000000..b9d5478
--- /dev/null
+++ b/deps/lightening/tests/bger_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bger_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bger_u.c b/deps/lightening/tests/bger_u.c
new file mode 100644
index 0000000..1978765
--- /dev/null
+++ b/deps/lightening/tests/bger_u.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bger_u(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+
+#if __WORDSIZE == 64
+ ASSERT(f(0xff00000000, 1) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bgti.c b/deps/lightening/tests/bgti.c
new file mode 100644
index 0000000..89eecae
--- /dev/null
+++ b/deps/lightening/tests/bgti.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bgti(j, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 0);
+ ASSERT(f(2) == 1);
+ ASSERT(f(-1) == 0);
+
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffff) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bgti_u.c b/deps/lightening/tests/bgti_u.c
new file mode 100644
index 0000000..51bb754
--- /dev/null
+++ b/deps/lightening/tests/bgti_u.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bgti_u(j, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 0);
+ ASSERT(f(-1) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xff00000000) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bgtr.c b/deps/lightening/tests/bgtr.c
new file mode 100644
index 0000000..c4dcd51
--- /dev/null
+++ b/deps/lightening/tests/bgtr.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bgtr(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffff, 1) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bgtr_d.c b/deps/lightening/tests/bgtr_d.c
new file mode 100644
index 0000000..d3c2436
--- /dev/null
+++ b/deps/lightening/tests/bgtr_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bgtr_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bgtr_f.c b/deps/lightening/tests/bgtr_f.c
new file mode 100644
index 0000000..91cb8c0
--- /dev/null
+++ b/deps/lightening/tests/bgtr_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bgtr_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bgtr_u.c b/deps/lightening/tests/bgtr_u.c
new file mode 100644
index 0000000..34ad257
--- /dev/null
+++ b/deps/lightening/tests/bgtr_u.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bgtr_u(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+#if __WORDSIZE == 64
+ ASSERT(f(0xff00000000, 1) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/blei.c b/deps/lightening/tests/blei.c
new file mode 100644
index 0000000..5725032
--- /dev/null
+++ b/deps/lightening/tests/blei.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_blei(j, JIT_R0, 0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 1);
+ ASSERT(f(1) == 0);
+ ASSERT(f(-1) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/blei_u.c b/deps/lightening/tests/blei_u.c
new file mode 100644
index 0000000..f6862ad
--- /dev/null
+++ b/deps/lightening/tests/blei_u.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_blei_u(j, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 1);
+ ASSERT(f(1) == 1);
+ ASSERT(f(-1) == 0);
+#if __WORDSIZE == 64
+ ASSERT(f(0xff00000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bler.c b/deps/lightening/tests/bler.c
new file mode 100644
index 0000000..0b37785
--- /dev/null
+++ b/deps/lightening/tests/bler.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bler(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffff, 1) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bler_d.c b/deps/lightening/tests/bler_d.c
new file mode 100644
index 0000000..507dac5
--- /dev/null
+++ b/deps/lightening/tests/bler_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bler_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bler_f.c b/deps/lightening/tests/bler_f.c
new file mode 100644
index 0000000..191b649
--- /dev/null
+++ b/deps/lightening/tests/bler_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bler_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bler_u.c b/deps/lightening/tests/bler_u.c
new file mode 100644
index 0000000..0830668
--- /dev/null
+++ b/deps/lightening/tests/bler_u.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bler_u(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xff00000000, 1) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bltgtr_d.c b/deps/lightening/tests/bltgtr_d.c
new file mode 100644
index 0000000..3d8835d
--- /dev/null
+++ b/deps/lightening/tests/bltgtr_d.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bltgtr_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 1);
+ ASSERT(f(1, 1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+ ASSERT(f(0.0/0.0, 0.0/0.0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bltgtr_f.c b/deps/lightening/tests/bltgtr_f.c
new file mode 100644
index 0000000..fbdbc3b
--- /dev/null
+++ b/deps/lightening/tests/bltgtr_f.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bltgtr_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 1);
+ ASSERT(f(1, 1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+ ASSERT(f(0.0/0.0, 0.0/0.0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/blti.c b/deps/lightening/tests/blti.c
new file mode 100644
index 0000000..d073337
--- /dev/null
+++ b/deps/lightening/tests/blti.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_blti(j, JIT_R0, 0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 0);
+ ASSERT(f(-1) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/blti_u.c b/deps/lightening/tests/blti_u.c
new file mode 100644
index 0000000..04a7037
--- /dev/null
+++ b/deps/lightening/tests/blti_u.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_blti_u(j, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 1);
+ ASSERT(f(1) == 0);
+ ASSERT(f(-1) == 0);
+#if __WORDSIZE == 64
+ ASSERT(f(0xff00000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bltr.c b/deps/lightening/tests/bltr.c
new file mode 100644
index 0000000..a928fab
--- /dev/null
+++ b/deps/lightening/tests/bltr.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bltr(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffffff, 0) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bltr_d.c b/deps/lightening/tests/bltr_d.c
new file mode 100644
index 0000000..2d62609
--- /dev/null
+++ b/deps/lightening/tests/bltr_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bltr_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bltr_f.c b/deps/lightening/tests/bltr_f.c
new file mode 100644
index 0000000..eebd3da
--- /dev/null
+++ b/deps/lightening/tests/bltr_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bltr_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bltr_u.c b/deps/lightening/tests/bltr_u.c
new file mode 100644
index 0000000..c66f3d5
--- /dev/null
+++ b/deps/lightening/tests/bltr_u.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bltr_u(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xff00000000, 1) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bmci.c b/deps/lightening/tests/bmci.c
new file mode 100644
index 0000000..e6c355a
--- /dev/null
+++ b/deps/lightening/tests/bmci.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+#if __WORDSIZE == 64
+ jit_reloc_t r = jit_bmci(j, JIT_R0, 0xff00000001);
+#else
+ jit_reloc_t r = jit_bmci(j, JIT_R0, 1);
+#endif
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 1);
+ ASSERT(f(1) == 0);
+ ASSERT(f(-1) == 0);
+ ASSERT(f(2) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xfffffffff0) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bmcr.c b/deps/lightening/tests/bmcr.c
new file mode 100644
index 0000000..64c1ee6
--- /dev/null
+++ b/deps/lightening/tests/bmcr.c
@@ -0,0 +1,38 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bmcr(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 1);
+ ASSERT(f(1, 1) == 0);
+ ASSERT(f(1, -1) == 0);
+ ASSERT(f(-1, 1) == 0);
+ ASSERT(f(-1, -1) == 0);
+#if __WORDSIZE == 64
+ ASSERT(f(0xffffffffff, 0xff00000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bmsi.c b/deps/lightening/tests/bmsi.c
new file mode 100644
index 0000000..d0919f7
--- /dev/null
+++ b/deps/lightening/tests/bmsi.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+#if __WORDSIZE == 64
+ jit_reloc_t r = jit_bmsi(j, JIT_R0, 0xff00000001);
+#else
+ jit_reloc_t r = jit_bmsi(j, JIT_R0, 1);
+#endif
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 1);
+ ASSERT(f(-1) == 1);
+ ASSERT(f(2) == 0);
+#if __WORDSIZE == 64
+ ASSERT(f(0xfffffffff0) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bmsr.c b/deps/lightening/tests/bmsr.c
new file mode 100644
index 0000000..b92eb6e
--- /dev/null
+++ b/deps/lightening/tests/bmsr.c
@@ -0,0 +1,38 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bmsr(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 0);
+ ASSERT(f(1, 1) == 1);
+ ASSERT(f(1, -1) == 1);
+ ASSERT(f(-1, 1) == 1);
+ ASSERT(f(-1, -1) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xfffffffff0, 0xff00000001) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bnei.c b/deps/lightening/tests/bnei.c
new file mode 100644
index 0000000..ee077e3
--- /dev/null
+++ b/deps/lightening/tests/bnei.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bnei(j, JIT_R0, 0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 1);
+ ASSERT(f(-1) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xff00000000) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bner.c b/deps/lightening/tests/bner.c
new file mode 100644
index 0000000..7a8cd0f
--- /dev/null
+++ b/deps/lightening/tests/bner.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bner(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 1);
+#if __WORDSIZE == 64
+ ASSERT(f(0xff00000000, 0x1000000000) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bner_d.c b/deps/lightening/tests/bner_d.c
new file mode 100644
index 0000000..079fda4
--- /dev/null
+++ b/deps/lightening/tests/bner_d.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bner_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 1);
+ ASSERT(f(1, 1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+ ASSERT(f(0.0/0.0, 0.0/0.0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bner_f.c b/deps/lightening/tests/bner_f.c
new file mode 100644
index 0000000..011df67
--- /dev/null
+++ b/deps/lightening/tests/bner_f.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bner_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 1);
+ ASSERT(f(1, 1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+ ASSERT(f(0.0/0.0, 0.0/0.0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/boaddi.c b/deps/lightening/tests/boaddi.c
new file mode 100644
index 0000000..1e47297
--- /dev/null
+++ b/deps/lightening/tests/boaddi.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_boaddi(j, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+ jit_patch_here(j, r);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(-1) == 0);
+ ASSERT(f(0) == 1);
+ ASSERT(f(1) == 2);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x7fffffff) == overflowed);
+ ASSERT(f(0x80000000) == 0x80000001);
+ ASSERT(f(0xffffffff) == 0);
+#else
+ ASSERT(f(0x7fffffffffffffff) == overflowed);
+ ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+ ASSERT(f(0xffffffffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/boaddi_u.c b/deps/lightening/tests/boaddi_u.c
new file mode 100644
index 0000000..21c71df
--- /dev/null
+++ b/deps/lightening/tests/boaddi_u.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_boaddi_u(j, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+ jit_patch_here(j, r);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(-1) == overflowed);
+ ASSERT(f(0) == 1);
+ ASSERT(f(1) == 2);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x7fffffff) == 0x80000000);
+ ASSERT(f(0x80000000) == 0x80000001);
+ ASSERT(f(0xffffffff) == overflowed);
+#else
+ ASSERT(f(0x7fffffffffffffff) == 0x8000000000000000);
+ ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+ ASSERT(f(0xffffffffffffffff) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/boaddr.c b/deps/lightening/tests/boaddr.c
new file mode 100644
index 0000000..8bab91e
--- /dev/null
+++ b/deps/lightening/tests/boaddr.c
@@ -0,0 +1,51 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_boaddr(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+ jit_patch_here(j, r);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(1, 1) == 2);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0xffffffff, 0xffffffff) == -2);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+ ASSERT(f(0x7fffffff, 1) == overflowed);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == overflowed);
+ ASSERT(f(0x7fffffff, 0x80000000) == -1);
+ ASSERT(f(0x80000000, 0x80000000) == overflowed);
+#else
+ ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffffull + 0xffffffffull);
+ ASSERT(f(0x7fffffff, 1) == 0x80000000);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffull + 0x7fffffffull);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+ ASSERT(f(0x80000000, 0x80000000) == 0x100000000);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == -2);
+ ASSERT(f(0x7fffffffffffffff, 1) == overflowed);
+ ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == overflowed);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == -1);
+ ASSERT(f(0x8000000000000000, 0x8000000000000000) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/boaddr_u.c b/deps/lightening/tests/boaddr_u.c
new file mode 100644
index 0000000..f4bacde
--- /dev/null
+++ b/deps/lightening/tests/boaddr_u.c
@@ -0,0 +1,51 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_boaddr_u(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+ jit_patch_here(j, r);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(1, 1) == 2);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0xffffffff, 0xffffffff) == overflowed);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+ ASSERT(f(0x7fffffff, 1) == 0x80000000);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffu + 0x7fffffffu);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+ ASSERT(f(0x80000000, 0x80000000) == overflowed);
+#else
+ ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffffull + 0xffffffffull);
+ ASSERT(f(0x7fffffff, 1) == 0x80000000);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffull + 0x7fffffffull);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+ ASSERT(f(0x80000000, 0x80000000) == 0x100000000);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == overflowed);
+ ASSERT(f(0x7fffffffffffffff, 1) == 0x8000000000000000);
+ ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == -2);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == -1);
+ ASSERT(f(0x8000000000000000, 0x8000000000000000) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bordr_d.c b/deps/lightening/tests/bordr_d.c
new file mode 100644
index 0000000..9227f22
--- /dev/null
+++ b/deps/lightening/tests/bordr_d.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bordr_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 1);
+ ASSERT(f(1, 1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+ ASSERT(f(0.0/0.0, 0.0/0.0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bordr_f.c b/deps/lightening/tests/bordr_f.c
new file mode 100644
index 0000000..25808e5
--- /dev/null
+++ b/deps/lightening/tests/bordr_f.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bordr_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 1);
+ ASSERT(f(1, 1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 0);
+ ASSERT(f(0.0/0.0, 0) == 0);
+ ASSERT(f(0.0/0.0, 0.0/0.0) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bosubi.c b/deps/lightening/tests/bosubi.c
new file mode 100644
index 0000000..f10d90a
--- /dev/null
+++ b/deps/lightening/tests/bosubi.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bosubi(j, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+ jit_patch_here(j, r);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(-1) == -2);
+ ASSERT(f(0) == -1);
+ ASSERT(f(1) == 0);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x7fffffff) == 0x7ffffffe);
+ ASSERT(f(0x80000000) == overflowed);
+ ASSERT(f(0x80000001) == 0x80000000);
+#else
+ ASSERT(f(0x7fffffffffffffff) == 0x7ffffffffffffffe);
+ ASSERT(f(0x8000000000000000) == overflowed);
+ ASSERT(f(0x8000000000000001) == 0x8000000000000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bosubi_u.c b/deps/lightening/tests/bosubi_u.c
new file mode 100644
index 0000000..50af6ad
--- /dev/null
+++ b/deps/lightening/tests/bosubi_u.c
@@ -0,0 +1,37 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bosubi_u(j, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+ jit_patch_here(j, r);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(-1) == -2);
+ ASSERT(f(0) == overflowed);
+ ASSERT(f(1) == 0);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x80000000) == 0x7fffffff);
+#else
+ ASSERT(f(0x8000000000000000) == 0x7fffffffffffffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bosubr.c b/deps/lightening/tests/bosubr.c
new file mode 100644
index 0000000..cf68ad6
--- /dev/null
+++ b/deps/lightening/tests/bosubr.c
@@ -0,0 +1,48 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bosubr(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+ jit_patch_here(j, r);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == -1);
+ ASSERT(f(1, 1) == 0);
+ ASSERT(f(1, -1) == 2);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0xffffffff, 0xffffffff) == 0);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+ ASSERT(f(0x7fffffff, 1) == 0x7ffffffe);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+ ASSERT(f(0x80000000, 0x7fffffff) == overflowed);
+ ASSERT(f(0x7fffffff, 0x80000000) == overflowed);
+ ASSERT(f(0x80000000, 0x80000000) == 0);
+#else
+ ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == overflowed);
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == overflowed);
+ ASSERT(f(0x8000000000000000, 0x8000000000000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bosubr_u.c b/deps/lightening/tests/bosubr_u.c
new file mode 100644
index 0000000..b5e6b39
--- /dev/null
+++ b/deps/lightening/tests/bosubr_u.c
@@ -0,0 +1,47 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bosubr_u(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+ jit_patch_here(j, r);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(1, 1) == 0);
+ ASSERT(f(0, 1) == overflowed);
+ ASSERT(f(1, 0) == 1);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0xffffffff, 0xffffffff) == 0);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+ ASSERT(f(0x7fffffff, 1) == 0x7ffffffe);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+ ASSERT(f(0x7fffffff, 0x80000000) == overflowed);
+ ASSERT(f(0x80000000, 0x80000000) == 0);
+#else
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == overflowed);
+ ASSERT(f(0x8000000000000000, 0x8000000000000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bswapr_ui.c b/deps/lightening/tests/bswapr_ui.c
new file mode 100644
index 0000000..c1eb9fd
--- /dev/null
+++ b/deps/lightening/tests/bswapr_ui.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_bswapr_ui(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(0x12345678) == 0x78563412);
+#if __WORDSIZE > 32
+ ASSERT(f(0xff12345678) == 0x78563412);
+ ASSERT(f(0xff00000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bswapr_ul.c b/deps/lightening/tests/bswapr_ul.c
new file mode 100644
index 0000000..a3a11b3
--- /dev/null
+++ b/deps/lightening/tests/bswapr_ul.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_bswapr_ul(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(0x12345678) == 0x7856341200000000);
+ ASSERT(f(0xff12345678) == 0x78563412ff000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bswapr_us.c b/deps/lightening/tests/bswapr_us.c
new file mode 100644
index 0000000..0ff777e
--- /dev/null
+++ b/deps/lightening/tests/bswapr_us.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_bswapr_us(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(0x12345678) == 0x7856);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/buneqr_d.c b/deps/lightening/tests/buneqr_d.c
new file mode 100644
index 0000000..1d08e32
--- /dev/null
+++ b/deps/lightening/tests/buneqr_d.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_buneqr_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 0);
+ ASSERT(f(1, 1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/buneqr_f.c b/deps/lightening/tests/buneqr_f.c
new file mode 100644
index 0000000..49d9062
--- /dev/null
+++ b/deps/lightening/tests/buneqr_f.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_buneqr_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 0);
+ ASSERT(f(1, 1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bunger_d.c b/deps/lightening/tests/bunger_d.c
new file mode 100644
index 0000000..57888af
--- /dev/null
+++ b/deps/lightening/tests/bunger_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bunger_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bunger_f.c b/deps/lightening/tests/bunger_f.c
new file mode 100644
index 0000000..f3103dc
--- /dev/null
+++ b/deps/lightening/tests/bunger_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bunger_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bungtr_d.c b/deps/lightening/tests/bungtr_d.c
new file mode 100644
index 0000000..649d61f
--- /dev/null
+++ b/deps/lightening/tests/bungtr_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bungtr_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bungtr_f.c b/deps/lightening/tests/bungtr_f.c
new file mode 100644
index 0000000..fea66dc
--- /dev/null
+++ b/deps/lightening/tests/bungtr_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bungtr_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 1);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 1);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bunler_d.c b/deps/lightening/tests/bunler_d.c
new file mode 100644
index 0000000..e59382c
--- /dev/null
+++ b/deps/lightening/tests/bunler_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bunler_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bunler_f.c b/deps/lightening/tests/bunler_f.c
new file mode 100644
index 0000000..fddce6b
--- /dev/null
+++ b/deps/lightening/tests/bunler_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bunler_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 1);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bunltr_d.c b/deps/lightening/tests/bunltr_d.c
new file mode 100644
index 0000000..2ab0051
--- /dev/null
+++ b/deps/lightening/tests/bunltr_d.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bunltr_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bunltr_f.c b/deps/lightening/tests/bunltr_f.c
new file mode 100644
index 0000000..ade228b
--- /dev/null
+++ b/deps/lightening/tests/bunltr_f.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bunltr_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 1);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 1);
+ ASSERT(f(0, -1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bunordr_d.c b/deps/lightening/tests/bunordr_d.c
new file mode 100644
index 0000000..6b04f0e
--- /dev/null
+++ b/deps/lightening/tests/bunordr_d.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_reloc_t r = jit_bunordr_d(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(double, double) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 0);
+ ASSERT(f(1, 1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+ ASSERT(f(0.0/0.0, 0.0/0.0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bunordr_f.c b/deps/lightening/tests/bunordr_f.c
new file mode 100644
index 0000000..ce4fc7b
--- /dev/null
+++ b/deps/lightening/tests/bunordr_f.c
@@ -0,0 +1,36 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_reloc_t r = jit_bunordr_f(j, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 0);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_reti(j, 1);
+
+ jit_word_t (*f)(float, float) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == 0);
+ ASSERT(f(1, 0) == 0);
+ ASSERT(f(-1, 0) == 0);
+ ASSERT(f(0, -1) == 0);
+ ASSERT(f(1, 1) == 0);
+
+ ASSERT(f(0, 0.0/0.0) == 1);
+ ASSERT(f(0.0/0.0, 0) == 1);
+ ASSERT(f(0.0/0.0, 0.0/0.0) == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bxaddi.c b/deps/lightening/tests/bxaddi.c
new file mode 100644
index 0000000..6e872da
--- /dev/null
+++ b/deps/lightening/tests/bxaddi.c
@@ -0,0 +1,39 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bxaddi(j, JIT_R0, 1);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(-1) == 0);
+ ASSERT(f(0) == 1);
+ ASSERT(f(1) == 2);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x7fffffff) == overflowed);
+ ASSERT(f(0x80000000) == 0x80000001);
+ ASSERT(f(0xffffffff) == 0);
+#else
+ ASSERT(f(0x7fffffffffffffff) == overflowed);
+ ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+ ASSERT(f(0xffffffffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bxaddi_u.c b/deps/lightening/tests/bxaddi_u.c
new file mode 100644
index 0000000..e71aeb7
--- /dev/null
+++ b/deps/lightening/tests/bxaddi_u.c
@@ -0,0 +1,39 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bxaddi_u(j, JIT_R0, 1);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(-1) == overflowed);
+ ASSERT(f(0) == 1);
+ ASSERT(f(1) == 2);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x7fffffff) == 0x80000000);
+ ASSERT(f(0x80000000) == 0x80000001);
+ ASSERT(f(0xffffffff) == overflowed);
+#else
+ ASSERT(f(0x7fffffffffffffff) == 0x8000000000000000);
+ ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+ ASSERT(f(0xffffffffffffffff) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bxaddr.c b/deps/lightening/tests/bxaddr.c
new file mode 100644
index 0000000..c1f6f23
--- /dev/null
+++ b/deps/lightening/tests/bxaddr.c
@@ -0,0 +1,49 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bxaddr(j, JIT_R0, JIT_R1);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(1, 1) == 2);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0xffffffff, 0xffffffff) == -2);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+ ASSERT(f(0x7fffffff, 1) == overflowed);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == overflowed);
+ ASSERT(f(0x7fffffff, 0x80000000) == -1);
+ ASSERT(f(0x80000000, 0x80000000) == overflowed);
+#else
+ ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffffull + 0xffffffffull);
+ ASSERT(f(0x7fffffff, 1) == 0x80000000);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffull + 0x7fffffffull);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+ ASSERT(f(0x80000000, 0x80000000) == 0x100000000);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == -2);
+ ASSERT(f(0x7fffffffffffffff, 1) == overflowed);
+ ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == overflowed);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == -1);
+ ASSERT(f(0x8000000000000000, 0x8000000000000000) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bxaddr_u.c b/deps/lightening/tests/bxaddr_u.c
new file mode 100644
index 0000000..d674f82
--- /dev/null
+++ b/deps/lightening/tests/bxaddr_u.c
@@ -0,0 +1,49 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bxaddr_u(j, JIT_R0, JIT_R1);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(1, 1) == 2);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0xffffffff, 0xffffffff) == overflowed);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+ ASSERT(f(0x7fffffff, 1) == 0x80000000);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffu + 0x7fffffffu);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+ ASSERT(f(0x80000000, 0x80000000) == overflowed);
+#else
+ ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffffull + 0xffffffffull);
+ ASSERT(f(0x7fffffff, 1) == 0x80000000);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0x7fffffffull + 0x7fffffffull);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+ ASSERT(f(0x80000000, 0x80000000) == 0x100000000);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == overflowed);
+ ASSERT(f(0x7fffffffffffffff, 1) == 0x8000000000000000);
+ ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == -2);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == -1);
+ ASSERT(f(0x8000000000000000, 0x8000000000000000) == overflowed);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bxsubi.c b/deps/lightening/tests/bxsubi.c
new file mode 100644
index 0000000..1b642c7
--- /dev/null
+++ b/deps/lightening/tests/bxsubi.c
@@ -0,0 +1,39 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bxsubi(j, JIT_R0, 1);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(-1) == -2);
+ ASSERT(f(0) == -1);
+ ASSERT(f(1) == 0);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x7fffffff) == 0x7ffffffe);
+ ASSERT(f(0x80000000) == overflowed);
+ ASSERT(f(0x80000001) == 0x80000000);
+#else
+ ASSERT(f(0x7fffffffffffffff) == 0x7ffffffffffffffe);
+ ASSERT(f(0x8000000000000000) == overflowed);
+ ASSERT(f(0x8000000000000001) == 0x8000000000000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bxsubi_u.c b/deps/lightening/tests/bxsubi_u.c
new file mode 100644
index 0000000..1345bd2
--- /dev/null
+++ b/deps/lightening/tests/bxsubi_u.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_bxsubi_u(j, JIT_R0, 1);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(-1) == -2);
+ ASSERT(f(0) == overflowed);
+ ASSERT(f(1) == 0);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x80000000) == 0x7fffffff);
+#else
+ ASSERT(f(0x8000000000000000) == 0x7fffffffffffffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bxsubr.c b/deps/lightening/tests/bxsubr.c
new file mode 100644
index 0000000..d40d182
--- /dev/null
+++ b/deps/lightening/tests/bxsubr.c
@@ -0,0 +1,46 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bxsubr(j, JIT_R0, JIT_R1);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(0, 1) == -1);
+ ASSERT(f(1, 1) == 0);
+ ASSERT(f(1, -1) == 2);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0xffffffff, 0xffffffff) == 0);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+ ASSERT(f(0x7fffffff, 1) == 0x7ffffffe);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+ ASSERT(f(0x80000000, 0x7fffffff) == overflowed);
+ ASSERT(f(0x7fffffff, 0x80000000) == overflowed);
+ ASSERT(f(0x80000000, 0x80000000) == 0);
+#else
+ ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == overflowed);
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == overflowed);
+ ASSERT(f(0x8000000000000000, 0x8000000000000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/bxsubr_u.c b/deps/lightening/tests/bxsubr_u.c
new file mode 100644
index 0000000..54a8d28
--- /dev/null
+++ b/deps/lightening/tests/bxsubr_u.c
@@ -0,0 +1,45 @@
+#include "test.h"
+
+static const jit_word_t overflowed = 0xcabba9e5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_reloc_t r = jit_bxsubr_u(j, JIT_R0, JIT_R1);
+ jit_movi(j, JIT_R0, overflowed);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0, 0) == 0);
+ ASSERT(f(1, 1) == 0);
+ ASSERT(f(0, 1) == overflowed);
+ ASSERT(f(1, 0) == 1);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0xffffffff, 0xffffffff) == 0);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+ ASSERT(f(0x7fffffff, 1) == 0x7ffffffe);
+ ASSERT(f(0x7fffffff, 0x7fffffff) == 0);
+ ASSERT(f(0x7fffffff, 0x80000000) == overflowed);
+ ASSERT(f(0x80000000, 0x80000000) == 0);
+#else
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == overflowed);
+ ASSERT(f(0x8000000000000000, 0x8000000000000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/call_10.c b/deps/lightening/tests/call_10.c
new file mode 100644
index 0000000..d99bcb8
--- /dev/null
+++ b/deps/lightening/tests/call_10.c
@@ -0,0 +1,54 @@
+#include "test.h"
+
+static int32_t f(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e,
+ int32_t f, int32_t g, int32_t h, int32_t i, int32_t j) {
+ ASSERT(a == 0);
+ ASSERT(b == 1);
+ ASSERT(c == 2);
+ ASSERT(d == 3);
+ ASSERT(e == 4);
+ ASSERT(f == 5);
+ ASSERT(g == 6);
+ ASSERT(h == 7);
+ ASSERT(i == 8);
+ ASSERT(j == 9);
+ return 42;
+}
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+
+ jit_operand_t args[10] = {
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 0 * sizeof(int32_t)),
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 1 * sizeof(int32_t)),
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 2 * sizeof(int32_t)),
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 3 * sizeof(int32_t)),
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 4 * sizeof(int32_t)),
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 5 * sizeof(int32_t)),
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 6 * sizeof(int32_t)),
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 7 * sizeof(int32_t)),
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 8 * sizeof(int32_t)),
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 9 * sizeof(int32_t))
+ };
+ jit_calli(j, f, 10, args);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ int32_t (*f)(int32_t*) = ret;
+
+ int32_t iargs[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ ASSERT(f(iargs) == 42);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/call_double.c b/deps/lightening/tests/call_double.c
new file mode 100644
index 0000000..2aad1d0
--- /dev/null
+++ b/deps/lightening/tests/call_double.c
@@ -0,0 +1,38 @@
+#include "test.h"
+
+static double f(int32_t a, double b) {
+ return b + a;
+}
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_operand_t args[2] = {
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 0),
+ jit_operand_mem(JIT_OPERAND_ABI_DOUBLE, JIT_R1, 0)
+ };
+ jit_calli(j, f, 2, args);
+ jit_retval_d(j, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ double (*f)(int32_t*, double*) = ret;
+
+ double d = 22.0f;
+ int32_t i = 20;
+ ASSERT(f(&i, &d) == 42.0f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/call_float.c b/deps/lightening/tests/call_float.c
new file mode 100644
index 0000000..e9bbd71
--- /dev/null
+++ b/deps/lightening/tests/call_float.c
@@ -0,0 +1,38 @@
+#include "test.h"
+
+static float f(int32_t a, float b) {
+ return b + a;
+}
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_operand_t args[2] = {
+ jit_operand_mem(JIT_OPERAND_ABI_INT32, JIT_R0, 0),
+ jit_operand_mem(JIT_OPERAND_ABI_FLOAT, JIT_R1, 0)
+ };
+ jit_calli(j, f, 2, args);
+ jit_retval_f(j, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ float (*f)(int32_t*, float*) = ret;
+
+ float d = 22.0f;
+ int32_t i = 20;
+ ASSERT(f(&i, &d) == 42.0f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/callee_9.c b/deps/lightening/tests/callee_9.c
new file mode 100644
index 0000000..b7f1a46
--- /dev/null
+++ b/deps/lightening/tests/callee_9.c
@@ -0,0 +1,68 @@
+#include "test.h"
+
+struct args
+{
+ int8_t a;
+ int16_t b;
+ int32_t c;
+ jit_word_t d;
+ uint16_t e;
+ float f;
+ double g;
+ float h;
+};
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 3, 0, 0);
+
+ jit_operand_t args[9] = {
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr(JIT_OPERAND_ABI_INT8, JIT_R1),
+ jit_operand_gpr(JIT_OPERAND_ABI_INT16, JIT_R2),
+ jit_operand_gpr(JIT_OPERAND_ABI_INT32, JIT_V0),
+ jit_operand_gpr(JIT_OPERAND_ABI_WORD, JIT_V1),
+ jit_operand_gpr(JIT_OPERAND_ABI_UINT16, JIT_V2),
+ jit_operand_fpr(JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr(JIT_OPERAND_ABI_DOUBLE, JIT_F1),
+ jit_operand_fpr(JIT_OPERAND_ABI_FLOAT, JIT_F2),
+ };
+ jit_load_args(j, 9, args);
+ jit_stxi_c(j, offsetof(struct args, a), JIT_R0, JIT_R1); // a
+ jit_stxi_s(j, offsetof(struct args, b), JIT_R0, JIT_R2); // b
+ jit_stxi_i(j, offsetof(struct args, c), JIT_R0, JIT_V0); // c
+ jit_stxi(j, offsetof(struct args, d), JIT_R0, JIT_V1); // d
+ jit_stxi_s(j, offsetof(struct args, e), JIT_R0, JIT_V2); // e
+ jit_stxi_f(j, offsetof(struct args, f), JIT_R0, JIT_F0); // f
+ jit_stxi_d(j, offsetof(struct args, g), JIT_R0, JIT_F1); // g
+ jit_stxi_f(j, offsetof(struct args, h), JIT_R0, JIT_F2); // h
+
+ jit_leave_jit_abi(j, 3, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ struct args* (*f)(struct args*, int8_t, int16_t, int32_t, jit_word_t,
+ uint16_t, float, double, float) = ret;
+
+ struct args in = { 0, 1, 2, 3, 4, 5, 6, 7 };
+ struct args out;
+ ASSERT(f(&out, in.a, in.b, in.c, in.d, in.e, in.f, in.g, in.h) == &out);
+ ASSERT(in.a == out.a);
+ ASSERT(in.b == out.b);
+ ASSERT(in.c == out.c);
+ ASSERT(in.d == out.d);
+ ASSERT(in.e == out.e);
+ ASSERT(in.f == out.f);
+ ASSERT(in.g == out.g);
+ ASSERT(in.h == out.h);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/cas_atomic.c b/deps/lightening/tests/cas_atomic.c
new file mode 100644
index 0000000..11c9a22
--- /dev/null
+++ b/deps/lightening/tests/cas_atomic.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static long data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R2));
+
+ jit_cas_atomic(j, JIT_R0, JIT_R0, JIT_R1, JIT_R2);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, int32_t, int32_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34343434);
+ f(&data[1], 0, 0x0f0f0f0f);
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0x0f0f0f0f);
+ ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/comr.c b/deps/lightening/tests/comr.c
new file mode 100644
index 0000000..c2e7d18
--- /dev/null
+++ b/deps/lightening/tests/comr.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_comr(j, JIT_R0, JIT_R0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0) == 0xffffffff);
+ ASSERT(f(1) == 0xfffffffe);
+ ASSERT(f(0xffffffff) == 0);
+ ASSERT(f(0x80000000) == 0x7fffffff);
+ ASSERT(f(0x7fffffff) == 0x80000000);
+ ASSERT(f(0x80000001) == 0x7ffffffe);
+#else
+ ASSERT(f(0) == 0xffffffffffffffff);
+ ASSERT(f(1) == 0xfffffffffffffffe);
+ ASSERT(f(0xffffffff) == 0xffffffff00000000);
+ ASSERT(f(0x80000000) == 0xffffffff7fffffff);
+ ASSERT(f(0x7fffffff) == 0xffffffff80000000);
+ ASSERT(f(0x80000001) == 0xffffffff7ffffffe);
+ ASSERT(f(0xffffffffffffffff) == 0);
+ ASSERT(f(0x8000000000000000) == 0x7fffffffffffffff);
+ ASSERT(f(0x7fffffffffffffff) == 0x8000000000000000);
+ ASSERT(f(0x8000000000000001) == 0x7ffffffffffffffe);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/divr.c b/deps/lightening/tests/divr.c
new file mode 100644
index 0000000..399d70d
--- /dev/null
+++ b/deps/lightening/tests/divr.c
@@ -0,0 +1,60 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_divr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff, 1) == 0x7fffffff);
+ ASSERT(f(1, 0x7fffffff) == 0);
+ ASSERT(f(0x80000000, 1) == 0x80000000);
+ ASSERT(f(1, 0x80000000) == 0);
+ ASSERT(f(0x7fffffff, 2) == 0x3fffffff);
+ ASSERT(f(2, 0x7fffffff) == 0);
+ ASSERT(f(2, 0x80000000) == 0);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0);
+ ASSERT(f(0, 0x7fffffff) == 0);
+ ASSERT(f(0xffffffff, 0xffffffff) == 1);
+#if __WORDSIZE == 32
+ ASSERT(f(0x80000000, 2) == 0xc0000000);
+ ASSERT(f(0x80000000, 0x7fffffff) == 0xffffffff);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0x80000001);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 0);
+#else
+ ASSERT(f(0x80000000, 2) == 0x40000000);
+ ASSERT(f(0x80000000, 0x7fffffff) == 1);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 2);
+ ASSERT(f(0x7fffffffffffffff, 1) == 0x7fffffffffffffff);
+ ASSERT(f(1, 0x7fffffffffffffff) == 0);
+ ASSERT(f(0x8000000000000000, 1) == 0x8000000000000000);
+ ASSERT(f(1, 0x8000000000000000) == 0);
+ ASSERT(f(0x7fffffffffffffff, 2) == 0x3fffffffffffffff);
+ ASSERT(f(2, 0x7fffffffffffffff) == 0);
+ ASSERT(f(0x8000000000000000, 2) == 0xc000000000000000);
+ ASSERT(f(2, 0x8000000000000000) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0);
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0xffffffffffffffff);
+ ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x8000000000000001);
+ ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/divr_d.c b/deps/lightening/tests/divr_d.c
new file mode 100644
index 0000000..9d21cb5
--- /dev/null
+++ b/deps/lightening/tests/divr_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_divr_d(j, JIT_F0, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ double (*f)(double, double) = ret;
+ ASSERT(f(-0.5f, 0.5f) == -1.0f);
+ ASSERT(f(1.25f, 0.5f) == 2.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/divr_f.c b/deps/lightening/tests/divr_f.c
new file mode 100644
index 0000000..de519dc
--- /dev/null
+++ b/deps/lightening/tests/divr_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_divr_f(j, JIT_F0, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ float (*f)(float, float) = ret;
+ ASSERT(f(-0.5f, 0.5f) == -1.0f);
+ ASSERT(f(1.25f, 0.5f) == 2.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/divr_u.c b/deps/lightening/tests/divr_u.c
new file mode 100644
index 0000000..b8305f7
--- /dev/null
+++ b/deps/lightening/tests/divr_u.c
@@ -0,0 +1,55 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_divr_u(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff, 1) == 0x7fffffff);
+ ASSERT(f(1, 0x7fffffff) == 0);
+ ASSERT(f(0x80000000, 1) == 0x80000000);
+ ASSERT(f(1, 0x80000000) == 0);
+ ASSERT(f(0x7fffffff, 2) == 0x3fffffff);
+ ASSERT(f(2, 0x7fffffff) == 0);
+ ASSERT(f(0x80000000, 2) == 0x40000000);
+ ASSERT(f(2, 0x80000000) == 0);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0);
+ ASSERT(f(0x80000000, 0x7fffffff) == 1);
+ ASSERT(f(0, 0x7fffffff) == 0);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 2);
+ ASSERT(f(0xffffffff, 0xffffffff) == 1);
+#if __WORDSIZE != 32
+ ASSERT(f(0x7fffffffffffffff, 1) == 0x7fffffffffffffff);
+ ASSERT(f(1, 0x7fffffffffffffff) == 0);
+ ASSERT(f(0x8000000000000000, 1) == 0x8000000000000000);
+ ASSERT(f(1, 0x8000000000000000) == 0);
+ ASSERT(f(0x7fffffffffffffff, 2) == 0x3fffffffffffffff);
+ ASSERT(f(2, 0x7fffffffffffffff) == 0);
+ ASSERT(f(0x8000000000000000, 2) == 0x4000000000000000);
+ ASSERT(f(2, 0x8000000000000000) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0);
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 1);
+ ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0);
+ ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 2);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/extr_c.c b/deps/lightening/tests/extr_c.c
new file mode 100644
index 0000000..043068d
--- /dev/null
+++ b/deps/lightening/tests/extr_c.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_extr_c(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 1);
+ ASSERT(f(0xf) == 0xf);
+ ASSERT(f(0xff) == -1);
+ ASSERT(f(0xfff) == -1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/extr_d.c b/deps/lightening/tests/extr_d.c
new file mode 100644
index 0000000..af0fe91
--- /dev/null
+++ b/deps/lightening/tests/extr_d.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_extr_d(j, JIT_F0, JIT_R0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ double (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0.0);
+ ASSERT(f(1) == 1.0);
+ ASSERT(f(-100) == -100.0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/extr_d_f.c b/deps/lightening/tests/extr_d_f.c
new file mode 100644
index 0000000..049eb5f
--- /dev/null
+++ b/deps/lightening/tests/extr_d_f.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+ jit_extr_d_f(j, JIT_F0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ float (*f)(double) = jit_end(j, NULL);
+
+ ASSERT(f(0.0) == 0.0f);
+ ASSERT(f(0.5) == 0.5f);
+ ASSERT(f(1.0 / 0.0) == 1.0f / 0.0f);
+ ASSERT(f(1.25) == 1.25f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/extr_f.c b/deps/lightening/tests/extr_f.c
new file mode 100644
index 0000000..b57830c
--- /dev/null
+++ b/deps/lightening/tests/extr_f.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_extr_f(j, JIT_F0, JIT_R0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ float (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0.0f);
+ ASSERT(f(1) == 1.0f);
+ ASSERT(f(-100) == -100.0f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/extr_f_d.c b/deps/lightening/tests/extr_f_d.c
new file mode 100644
index 0000000..5fa5007
--- /dev/null
+++ b/deps/lightening/tests/extr_f_d.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+ jit_extr_f_d(j, JIT_F0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ double (*f)(float) = jit_end(j, NULL);
+
+ ASSERT(f(0.0f) == 0.0);
+ ASSERT(f(0.5f) == 0.5);
+ ASSERT(f(1.0f / 0.0f) == 1.0 / 0.0);
+ ASSERT(f(1.25f) == 1.25);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/extr_i.c b/deps/lightening/tests/extr_i.c
new file mode 100644
index 0000000..d26a576
--- /dev/null
+++ b/deps/lightening/tests/extr_i.c
@@ -0,0 +1,30 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_extr_i(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 1);
+ ASSERT(f(0xfffffff) == 0xfffffff);
+ ASSERT(f(0xffffffff) == -1);
+ ASSERT(f(0xfffffffff) == -1);
+ ASSERT(f(0xf00000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/extr_s.c b/deps/lightening/tests/extr_s.c
new file mode 100644
index 0000000..5b39af3
--- /dev/null
+++ b/deps/lightening/tests/extr_s.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_extr_s(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 1);
+ ASSERT(f(0xfff) == 0xfff);
+ ASSERT(f(0xffff) == -1);
+ ASSERT(f(0xfffff) == -1);
+ ASSERT(f(0xf0000) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/extr_uc.c b/deps/lightening/tests/extr_uc.c
new file mode 100644
index 0000000..a42e603
--- /dev/null
+++ b/deps/lightening/tests/extr_uc.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_extr_uc(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 1);
+ ASSERT(f(0xff) == 0xff);
+ ASSERT(f(0xfff) == 0xff);
+ ASSERT(f(0xf00) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/extr_ui.c b/deps/lightening/tests/extr_ui.c
new file mode 100644
index 0000000..37964da
--- /dev/null
+++ b/deps/lightening/tests/extr_ui.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_extr_ui(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 1);
+ ASSERT(f(0xffffffff) == 0xffffffff);
+ ASSERT(f(0xfffffffff) == 0xffffffff);
+ ASSERT(f(0xf00000000) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/extr_us.c b/deps/lightening/tests/extr_us.c
new file mode 100644
index 0000000..38a7c39
--- /dev/null
+++ b/deps/lightening/tests/extr_us.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_extr_us(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+ ASSERT(f(1) == 1);
+ ASSERT(f(0xffff) == 0xffff);
+ ASSERT(f(0xfffff) == 0xffff);
+ ASSERT(f(0xf0000) == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/jmp0.c b/deps/lightening/tests/jmp0.c
new file mode 100644
index 0000000..261a399
--- /dev/null
+++ b/deps/lightening/tests/jmp0.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_reloc_t r = jit_jmp(j);
+ jit_patch_here(j, r);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+ ASSERT(f(42) == 42);
+ ASSERT(f(-1) == -1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/jmp_table.c b/deps/lightening/tests/jmp_table.c
new file mode 100644
index 0000000..f90ab16
--- /dev/null
+++ b/deps/lightening/tests/jmp_table.c
@@ -0,0 +1,61 @@
+#include "test.h"
+
+#define NTARGETS ((size_t) 4)
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+
+ jit_reloc_t default_target = jit_bgei_u(j, JIT_R0, NTARGETS);
+
+ // FIXME: need ldxr with word stride, then can eliminate lshi.
+ jit_lshi(j, JIT_R0, JIT_R0, sizeof(intptr_t) == 4 ? 2 : 3);
+ jit_reloc_t table = jit_mov_addr(j, JIT_R1);
+ jit_ldxr(j, JIT_R1, JIT_R1, JIT_R0);
+ jit_jmpr(j, JIT_R1);
+
+ jit_begin_data (j, (NTARGETS + 1) * sizeof(intptr_t));
+ jit_align(j, sizeof(intptr_t));
+ jit_patch_here(j, table);
+ jit_reloc_t targets[NTARGETS];
+ jit_reloc_t tails[NTARGETS];
+ for (size_t i = 0; i < NTARGETS; i++) {
+ targets[i] = jit_emit_addr(j);
+ }
+ jit_end_data (j);
+
+ for (size_t i = 0; i < NTARGETS; i++) {
+ jit_patch_here(j, targets[i]);
+ jit_movi(j, JIT_R0, i * i);
+ tails[i] = jit_jmp(j);
+ }
+
+ jit_patch_here(j, default_target);
+ jit_movi(j, JIT_R0, 42);
+ for (int i = 0; i < NTARGETS; i++) {
+ jit_patch_here(j, tails[i]);
+ }
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ for (int i = -2; i < ((int) NTARGETS) + 2; i++) {
+ if (i < 0) {
+ ASSERT(f(i) == 42);
+ } else if (i < NTARGETS) {
+ ASSERT(f(i) == i * i);
+ } else {
+ ASSERT(f(i) == 42);
+ }
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/jmpi.c b/deps/lightening/tests/jmpi.c
new file mode 100644
index 0000000..e73ace0
--- /dev/null
+++ b/deps/lightening/tests/jmpi.c
@@ -0,0 +1,41 @@
+#include "test.h"
+
+void *tail;
+
+static void *target;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ jit_enter_jit_abi(j, 0, 0, 0);
+ jit_movi(j, JIT_R0, 42);
+ jit_jmpi(j, target);
+ // Unreachable.
+ jit_breakpoint(j);
+ int (*f)(void) = jit_end(j, NULL);
+ ASSERT(f() == 42);
+}
+
+// Make the tail-call target via a separate main_helper because probably the new
+// arena will be allocated farther away, forcing nonlocal jumps.
+static void
+make_target(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ // Tail call target assumes tail caller called enter_jit_abi with compatible
+ // parameters.
+ target = jit_address(j);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+ jit_end(j, NULL);
+
+ main_helper(0, NULL, run_test);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, make_target);
+}
diff --git a/deps/lightening/tests/jmpi_local.c b/deps/lightening/tests/jmpi_local.c
new file mode 100644
index 0000000..49e4507
--- /dev/null
+++ b/deps/lightening/tests/jmpi_local.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+
+ jit_reloc_t r = jit_jmp (j);
+ jit_reti (j, 0);
+ jit_pointer_t addr = jit_address (j);
+ jit_reti (j, 1);
+ jit_patch_here (j, r);
+ jit_jmpi (j, addr);
+ jit_reti (j, 2);
+
+ int (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == 1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/jmpr.c b/deps/lightening/tests/jmpr.c
new file mode 100644
index 0000000..8840897
--- /dev/null
+++ b/deps/lightening/tests/jmpr.c
@@ -0,0 +1,23 @@
+#include "test.h"
+
+static int tail(void) { return 42; }
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+ jit_leave_jit_abi(j, 0, 0, align);
+
+ jit_jmpr(j, JIT_R0);
+
+ int (*f)(void*) = jit_end(j, NULL);
+ ASSERT(f(tail) == 42);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldi_c.c b/deps/lightening/tests/ldi_c.c
new file mode 100644
index 0000000..9d5de82
--- /dev/null
+++ b/deps/lightening/tests/ldi_c.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_ldi_c(j, JIT_R0, &data[0]);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == -1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldi_d.c b/deps/lightening/tests/ldi_d.c
new file mode 100644
index 0000000..b72cdda
--- /dev/null
+++ b/deps/lightening/tests/ldi_d.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static double data = -1.5;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_ldi_d(j, JIT_F0, &data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ double (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == data);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldi_f.c b/deps/lightening/tests/ldi_f.c
new file mode 100644
index 0000000..13e5fd4
--- /dev/null
+++ b/deps/lightening/tests/ldi_f.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static float data = -1.5f;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_ldi_f(j, JIT_F0, &data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ float (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == data);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldi_i.c b/deps/lightening/tests/ldi_i.c
new file mode 100644
index 0000000..e389788
--- /dev/null
+++ b/deps/lightening/tests/ldi_i.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static uint32_t data = 0xffffffff;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_ldi_i(j, JIT_R0, &data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == -1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldi_l.c b/deps/lightening/tests/ldi_l.c
new file mode 100644
index 0000000..f3fa729
--- /dev/null
+++ b/deps/lightening/tests/ldi_l.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint64_t data = 0xffffffffffffffff;
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_ldi_l(j, JIT_R0, &data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == -1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldi_s.c b/deps/lightening/tests/ldi_s.c
new file mode 100644
index 0000000..d9d1c47
--- /dev/null
+++ b/deps/lightening/tests/ldi_s.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static uint16_t data = 0xffff;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_ldi_s(j, JIT_R0, &data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == -1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldi_uc.c b/deps/lightening/tests/ldi_uc.c
new file mode 100644
index 0000000..12f18bf
--- /dev/null
+++ b/deps/lightening/tests/ldi_uc.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_ldi_uc(j, JIT_R0, data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == 0xff);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldi_ui.c b/deps/lightening/tests/ldi_ui.c
new file mode 100644
index 0000000..d233694
--- /dev/null
+++ b/deps/lightening/tests/ldi_ui.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_ldi_ui(j, JIT_R0, data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == data[0]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldi_us.c b/deps/lightening/tests/ldi_us.c
new file mode 100644
index 0000000..70eb4a0
--- /dev/null
+++ b/deps/lightening/tests/ldi_us.c
@@ -0,0 +1,24 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_ldi_us(j, JIT_R0, data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == data[0]);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldr_atomic.c b/deps/lightening/tests/ldr_atomic.c
new file mode 100644
index 0000000..73a8c0f
--- /dev/null
+++ b/deps/lightening/tests/ldr_atomic.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static long data[] = { 0x0f0f0f0f, 0x00000000, 0x42424242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ /* atm does not test for actual atomicity, just that no segfaults etc happen */
+ jit_ldr_atomic(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+ ASSERT(f(&data[0]) == 0x0f0f0f0f);
+ ASSERT(f(&data[1]) == 0);
+ ASSERT(f(&data[2]) == 0x42424242);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldr_c.c b/deps/lightening/tests/ldr_c.c
new file mode 100644
index 0000000..07a5931
--- /dev/null
+++ b/deps/lightening/tests/ldr_c.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_ldr_c(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+ ASSERT(f(&data[0]) == -1);
+ ASSERT(f(&data[1]) == 0);
+ ASSERT(f(&data[2]) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldr_d.c b/deps/lightening/tests/ldr_d.c
new file mode 100644
index 0000000..37c75f0
--- /dev/null
+++ b/deps/lightening/tests/ldr_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_ldr_d(j, JIT_F0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ double (*f)(void*) = jit_end(j, NULL);
+
+ ASSERT(f(&data[0]) == data[0]);
+ ASSERT(f(&data[1]) == data[1]);
+ ASSERT(f(&data[2]) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldr_f.c b/deps/lightening/tests/ldr_f.c
new file mode 100644
index 0000000..bb68278
--- /dev/null
+++ b/deps/lightening/tests/ldr_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_ldr_f(j, JIT_F0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ float (*f)(void*) = jit_end(j, NULL);
+
+ ASSERT(f(&data[0]) == data[0]);
+ ASSERT(f(&data[1]) == data[1]);
+ ASSERT(f(&data[2]) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldr_i.c b/deps/lightening/tests/ldr_i.c
new file mode 100644
index 0000000..3de9e5f
--- /dev/null
+++ b/deps/lightening/tests/ldr_i.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_ldr_i(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+ ASSERT(f(&data[0]) == -1);
+ ASSERT(f(&data[1]) == 0);
+ ASSERT(f(&data[2]) == 0x42424242);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldr_l.c b/deps/lightening/tests/ldr_l.c
new file mode 100644
index 0000000..15f0080
--- /dev/null
+++ b/deps/lightening/tests/ldr_l.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint64_t data[] = { 0xffffffffffffffff, 0, 0x4242424212345678 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_ldr_l(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+ ASSERT(f(&data[0]) == -1);
+ ASSERT(f(&data[1]) == 0);
+ ASSERT(f(&data[2]) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldr_s.c b/deps/lightening/tests/ldr_s.c
new file mode 100644
index 0000000..cf668d5
--- /dev/null
+++ b/deps/lightening/tests/ldr_s.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_ldr_s(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+ ASSERT(f(&data[0]) == -1);
+ ASSERT(f(&data[1]) == 0);
+ ASSERT(f(&data[2]) == 0x4242);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldr_uc.c b/deps/lightening/tests/ldr_uc.c
new file mode 100644
index 0000000..a48f370
--- /dev/null
+++ b/deps/lightening/tests/ldr_uc.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_ldr_uc(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+ ASSERT(f(&data[0]) == 0xff);
+ ASSERT(f(&data[1]) == 0);
+ ASSERT(f(&data[2]) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldr_ui.c b/deps/lightening/tests/ldr_ui.c
new file mode 100644
index 0000000..7668778
--- /dev/null
+++ b/deps/lightening/tests/ldr_ui.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_ldr_ui(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+ ASSERT(f(&data[0]) == data[0]);
+ ASSERT(f(&data[1]) == data[1]);
+ ASSERT(f(&data[2]) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldr_us.c b/deps/lightening/tests/ldr_us.c
new file mode 100644
index 0000000..bb9928b
--- /dev/null
+++ b/deps/lightening/tests/ldr_us.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1));
+
+ jit_ldr_us(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*) = jit_end(j, NULL);
+
+ ASSERT(f(&data[0]) == data[0]);
+ ASSERT(f(&data[1]) == data[1]);
+ ASSERT(f(&data[2]) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxi_c.c b/deps/lightening/tests/ldxi_c.c
new file mode 100644
index 0000000..4271f97
--- /dev/null
+++ b/deps/lightening/tests/ldxi_c.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_ldxi_c(j, JIT_R0, JIT_R0, (uintptr_t)&data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == -1);
+ ASSERT(f(1) == 0);
+ ASSERT(f(2) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxi_d.c b/deps/lightening/tests/ldxi_d.c
new file mode 100644
index 0000000..6bcf632
--- /dev/null
+++ b/deps/lightening/tests/ldxi_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_ldxi_d(j, JIT_F0, JIT_R0, (uintptr_t)data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ double (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == data[0]);
+ ASSERT(f(8) == data[1]);
+ ASSERT(f(16) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxi_f.c b/deps/lightening/tests/ldxi_f.c
new file mode 100644
index 0000000..9e65321
--- /dev/null
+++ b/deps/lightening/tests/ldxi_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_ldxi_f(j, JIT_F0, JIT_R0, (uintptr_t)data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ float (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == data[0]);
+ ASSERT(f(4) == data[1]);
+ ASSERT(f(8) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxi_i.c b/deps/lightening/tests/ldxi_i.c
new file mode 100644
index 0000000..d1f7b56
--- /dev/null
+++ b/deps/lightening/tests/ldxi_i.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+
+ jit_ldxi_i(j, JIT_R0, JIT_R0, (uintptr_t)data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == -1);
+ ASSERT(f(4) == 0);
+ ASSERT(f(8) == 0x42424242);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxi_l.c b/deps/lightening/tests/ldxi_l.c
new file mode 100644
index 0000000..bb1a8b2
--- /dev/null
+++ b/deps/lightening/tests/ldxi_l.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint64_t data[] = { 0xffffffffffffffff, 0, 0x4242424212345678 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_ldxi_l(j, JIT_R0, JIT_R0, (uintptr_t)data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == -1);
+ ASSERT(f(8) == 0);
+ ASSERT(f(16) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxi_s.c b/deps/lightening/tests/ldxi_s.c
new file mode 100644
index 0000000..c9376d0
--- /dev/null
+++ b/deps/lightening/tests/ldxi_s.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_ldxi_s(j, JIT_R0, JIT_R0, (uintptr_t)data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == -1);
+ ASSERT(f(2) == 0);
+ ASSERT(f(4) == 0x4242);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxi_uc.c b/deps/lightening/tests/ldxi_uc.c
new file mode 100644
index 0000000..31d7b73
--- /dev/null
+++ b/deps/lightening/tests/ldxi_uc.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_ldxi_uc(j, JIT_R0, JIT_R0, (uintptr_t)data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0xff);
+ ASSERT(f(1) == 0);
+ ASSERT(f(2) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxi_ui.c b/deps/lightening/tests/ldxi_ui.c
new file mode 100644
index 0000000..4f7e304
--- /dev/null
+++ b/deps/lightening/tests/ldxi_ui.c
@@ -0,0 +1,29 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_ldxi_ui(j, JIT_R0, JIT_R0, (uintptr_t)data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == data[0]);
+ ASSERT(f(4) == data[1]);
+ ASSERT(f(8) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxi_us.c b/deps/lightening/tests/ldxi_us.c
new file mode 100644
index 0000000..81c984f
--- /dev/null
+++ b/deps/lightening/tests/ldxi_us.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_ldxi_us(j, JIT_R0, JIT_R0, (uintptr_t)data);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == data[0]);
+ ASSERT(f(2) == data[1]);
+ ASSERT(f(4) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxr_c.c b/deps/lightening/tests/ldxr_c.c
new file mode 100644
index 0000000..366f5b2
--- /dev/null
+++ b/deps/lightening/tests/ldxr_c.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_ldxr_c(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(data, 0) == -1);
+ ASSERT(f(data, 1) == 0);
+ ASSERT(f(data, 2) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxr_d.c b/deps/lightening/tests/ldxr_d.c
new file mode 100644
index 0000000..38a12fd
--- /dev/null
+++ b/deps/lightening/tests/ldxr_d.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_ldxr_d(j, JIT_F0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ double (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(data, 0) == data[0]);
+ ASSERT(f(data, 8) == data[1]);
+ ASSERT(f(data, 16) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxr_f.c b/deps/lightening/tests/ldxr_f.c
new file mode 100644
index 0000000..c48b11f
--- /dev/null
+++ b/deps/lightening/tests/ldxr_f.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_ldxr_f(j, JIT_F0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ float (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(data, 0) == data[0]);
+ ASSERT(f(data, 4) == data[1]);
+ ASSERT(f(data, 8) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxr_i.c b/deps/lightening/tests/ldxr_i.c
new file mode 100644
index 0000000..e4149aa
--- /dev/null
+++ b/deps/lightening/tests/ldxr_i.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_ldxr_i(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(data, 0) == -1);
+ ASSERT(f(data, 4) == 0);
+ ASSERT(f(data, 8) == 0x42424242);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxr_l.c b/deps/lightening/tests/ldxr_l.c
new file mode 100644
index 0000000..ee9f156
--- /dev/null
+++ b/deps/lightening/tests/ldxr_l.c
@@ -0,0 +1,30 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint64_t data[] = { 0xffffffffffffffff, 0, 0x4242424212345678 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_ldxr_l(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(data, 0) == -1);
+ ASSERT(f(data, 8) == 0);
+ ASSERT(f(data, 16) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxr_s.c b/deps/lightening/tests/ldxr_s.c
new file mode 100644
index 0000000..fbb5c09
--- /dev/null
+++ b/deps/lightening/tests/ldxr_s.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_ldxr_s(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(data, 0) == -1);
+ ASSERT(f(data, 2) == 0);
+ ASSERT(f(data, 4) == 0x4242);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxr_uc.c b/deps/lightening/tests/ldxr_uc.c
new file mode 100644
index 0000000..846c552
--- /dev/null
+++ b/deps/lightening/tests/ldxr_uc.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static uint8_t data[] = { 0xff, 0x00, 0x42 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_ldxr_uc(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(data, 0) == 0xff);
+ ASSERT(f(data, 1) == 0);
+ ASSERT(f(data, 2) == 0x42);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxr_ui.c b/deps/lightening/tests/ldxr_ui.c
new file mode 100644
index 0000000..cd774d3
--- /dev/null
+++ b/deps/lightening/tests/ldxr_ui.c
@@ -0,0 +1,30 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint32_t data[] = { 0xffffffff, 0x00000000, 0x42424242 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_ldxr_ui(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(data, 0) == data[0]);
+ ASSERT(f(data, 4) == data[1]);
+ ASSERT(f(data, 8) == data[2]);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ldxr_us.c b/deps/lightening/tests/ldxr_us.c
new file mode 100644
index 0000000..b7e408b
--- /dev/null
+++ b/deps/lightening/tests/ldxr_us.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static uint16_t data[] = { 0xffff, 0x0000, 0x4242 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_ldxr_us(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void*, jit_uword_t) = jit_end(j, NULL);
+
+ ASSERT(f(data, 0) == data[0]);
+ ASSERT(f(data, 2) == data[1]);
+ ASSERT(f(data, 4) == data[2]);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/link-register.c b/deps/lightening/tests/link-register.c
new file mode 100644
index 0000000..96ee959
--- /dev/null
+++ b/deps/lightening/tests/link-register.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+
+ jit_reloc_t call_tramp = jit_jmp (j);
+
+ void *tramp = jit_address (j);
+ jit_pop_link_register (j);
+ jit_movr (j, JIT_R0, JIT_LR);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr (j, JIT_R0);
+
+ jit_patch_here (j, call_tramp);
+ jit_jmpi_with_link (j, tramp);
+
+ void *expected_link = jit_address_to_function_pointer (jit_address (j));
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ void* (*f)(void) = ret;
+
+ ASSERT(f() == expected_link);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/lshi.c b/deps/lightening/tests/lshi.c
new file mode 100644
index 0000000..e721af5
--- /dev/null
+++ b/deps/lightening/tests/lshi.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_lshi(j, JIT_R0, JIT_R0, 31);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+#if __WORDSIZE == 32
+ ASSERT(f(-0x7f) == 0x80000000);
+#else
+ ASSERT(f(-0x7f) == 0xffffffc080000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/lshr.c b/deps/lightening/tests/lshr.c
new file mode 100644
index 0000000..f81aa69
--- /dev/null
+++ b/deps/lightening/tests/lshr.c
@@ -0,0 +1,69 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_lshr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0x7f, 1) == 0xfe);
+ ASSERT(f(0x7fff, 2) == 0x1fffc);
+ ASSERT(f(0x81, 16) == 0x810000);
+ ASSERT(f(0xff, 15) == 0x7f8000);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+#if __WORDSIZE == 32
+ ASSERT(f(0xffffffff, 8) == 0xffffff00);
+ ASSERT(f(0x7fffffff, 3) == 0xfffffff8);
+ ASSERT(f(-0x7f, 31) == 0x80000000);
+ ASSERT(f(-0x7fff, 30) == 0x40000000);
+ ASSERT(f(-0x7fffffff, 29) == 0x20000000);
+ ASSERT(f(0x80000001, 28) == 0x10000000);
+ ASSERT(f(0x8001, 17) == 0x20000);
+ ASSERT(f(0x80000001, 18) == 0x40000);
+ ASSERT(f(-0xffff, 24) == 0x1000000);
+#else
+ ASSERT(f(0xffffffff, 8) == 0xffffffff00);
+ ASSERT(f(0x7fffffff, 3) == 0x3fffffff8);
+ ASSERT(f(-0x7f, 31) == 0xffffffc080000000);
+ ASSERT(f(-0x7fff, 30) == 0xffffe00040000000);
+ ASSERT(f(-0x7fffffff, 29) == 0xf000000020000000);
+ ASSERT(f(0x80000001, 28) == 0x800000010000000);
+ ASSERT(f(0x8001, 17) == 0x100020000);
+ ASSERT(f(0x80000001, 18) == 0x2000000040000);
+ ASSERT(f(-0xffff, 24) == 0xffffff0001000000);
+ ASSERT(f(0x7f, 33) == 0xfe00000000);
+ ASSERT(f(0x7ffff, 34) == 0x1ffffc00000000);
+ ASSERT(f(0x7fffffff, 35) == 0xfffffff800000000);
+ ASSERT(f(-0x7f, 63) == 0x8000000000000000);
+ ASSERT(f(-0x7fff, 62) == 0x4000000000000000);
+ ASSERT(f(-0x7fffffff, 61) == 0x2000000000000000);
+ ASSERT(f(0x80000001, 60) == 0x1000000000000000);
+ ASSERT(f(0x81, 48) == 0x81000000000000);
+ ASSERT(f(0x8001, 49) == 0x2000000000000);
+ ASSERT(f(0x80000001, 40) == 0x10000000000);
+ ASSERT(f(0xff, 47) == 0x7f800000000000);
+ ASSERT(f(0xffff0001, 56) == 0x100000000000000);
+ ASSERT(f(0xffffffff, 40) == 0xffffff0000000000);
+ ASSERT(f(0x7fffffffff, 33) == 0xfffffffe00000000);
+ ASSERT(f(-0x7fffffffff, 63) == 0x8000000000000000);
+ ASSERT(f(0x8000000001, 48) == 0x1000000000000);
+ ASSERT(f(0xffffffffff, 47) == 0xffff800000000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/mov_addr.c b/deps/lightening/tests/mov_addr.c
new file mode 100644
index 0000000..b4a9aaa
--- /dev/null
+++ b/deps/lightening/tests/mov_addr.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static uint64_t thing = 0x123456789abcdef0;
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_patch_there(j, jit_mov_addr(j, JIT_R0), &thing);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ void* (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == &thing);
+ ASSERT(*(uint64_t*)f() == thing);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/movi.c b/deps/lightening/tests/movi.c
new file mode 100644
index 0000000..fcdd656
--- /dev/null
+++ b/deps/lightening/tests/movi.c
@@ -0,0 +1,22 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_movi(j, JIT_R0, 0xa500a500);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_uword_t (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == 0xa500a500);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/movi_d.c b/deps/lightening/tests/movi_d.c
new file mode 100644
index 0000000..cb9e63d
--- /dev/null
+++ b/deps/lightening/tests/movi_d.c
@@ -0,0 +1,22 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_movi_d(j, JIT_F0, 3.14159);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ double (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == 3.14159);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/movi_f.c b/deps/lightening/tests/movi_f.c
new file mode 100644
index 0000000..944f615
--- /dev/null
+++ b/deps/lightening/tests/movi_f.c
@@ -0,0 +1,22 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+
+ jit_movi_f(j, JIT_F0, 3.14159f);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ float (*f)(void) = jit_end(j, NULL);
+
+ ASSERT(f() == 3.14159f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/mulr.c b/deps/lightening/tests/mulr.c
new file mode 100644
index 0000000..452e35d
--- /dev/null
+++ b/deps/lightening/tests/mulr.c
@@ -0,0 +1,64 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_mulr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff, 1) == 0x7fffffff);
+ ASSERT(f(1, 0x7fffffff) == 0x7fffffff);
+ ASSERT(f(0x80000000, 1) == 0x80000000);
+ ASSERT(f(1, 0x80000000) == 0x80000000);
+ ASSERT(f(0x7fffffff, 2) == 0xfffffffe);
+ ASSERT(f(2, 0x7fffffff) == 0xfffffffe);
+ ASSERT(f(0x7fffffff, 0) == 0);
+ ASSERT(f(0, 0x7fffffff) == 0);
+#if __WORDSIZE == 32
+ ASSERT(f(0x80000000, 2) == 0);
+ ASSERT(f(2, 0x80000000) == 0);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0x80000000);
+ ASSERT(f(0x80000000, 0x7fffffff) == 0x80000000);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0x80000001);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 0x80000001);
+ ASSERT(f(0xffffffff, 0xffffffff) == 1);
+#else
+ ASSERT(f(0x80000000, 2) == 0x100000000);
+ ASSERT(f(2, 0x80000000) == 0x100000000);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0x3fffffff80000000);
+ ASSERT(f(0x80000000, 0x7fffffff) == 0x3fffffff80000000);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0x7ffffffe80000001);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 0x7ffffffe80000001);
+ ASSERT(f(0xffffffff, 0xffffffff) == 0xfffffffe00000001);
+ ASSERT(f(0x7fffffffffffffff, 1) == 0x7fffffffffffffff);
+ ASSERT(f(1, 0x7fffffffffffffff) == 0x7fffffffffffffff);
+ ASSERT(f(0x8000000000000000, 1) == 0x8000000000000000);
+ ASSERT(f(1, 0x8000000000000000) == 0x8000000000000000);
+ ASSERT(f(0x7fffffffffffffff, 2) == 0xfffffffffffffffe);
+ ASSERT(f(2, 0x7fffffffffffffff) == 0xfffffffffffffffe);
+ ASSERT(f(0x8000000000000000, 2) == 0);
+ ASSERT(f(2, 0x8000000000000000) == 0);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0x8000000000000000);
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0x8000000000000000);
+ ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x8000000000000001);
+ ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0x8000000000000001);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/mulr_d.c b/deps/lightening/tests/mulr_d.c
new file mode 100644
index 0000000..945f152
--- /dev/null
+++ b/deps/lightening/tests/mulr_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_mulr_d(j, JIT_F0, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ double (*f)(double, double) = ret;
+ ASSERT(f(-0.5, 0.5) == -0.25);
+ ASSERT(f(0.25, 0.75) == 0.1875);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/mulr_f.c b/deps/lightening/tests/mulr_f.c
new file mode 100644
index 0000000..2d0dd4f
--- /dev/null
+++ b/deps/lightening/tests/mulr_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_mulr_f(j, JIT_F0, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ float (*f)(float, float) = ret;
+ ASSERT(f(-0.5f, 0.5f) == -0.25f);
+ ASSERT(f(0.25f, 0.75f) == 0.1875f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/negr.c b/deps/lightening/tests/negr.c
new file mode 100644
index 0000000..18e27cb
--- /dev/null
+++ b/deps/lightening/tests/negr.c
@@ -0,0 +1,39 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_negr(j, JIT_R0, JIT_R0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+ ASSERT(f(0) == 0);
+#if __WORDSIZE == 32
+ ASSERT(f(1) == 0xffffffff);
+ ASSERT(f(0xffffffff) == 1);
+ ASSERT(f(0x80000000) == 0x80000000);
+ ASSERT(f(0x7fffffff) == 0x80000001);
+ ASSERT(f(0x80000001) == 0x7fffffff);
+#else
+ ASSERT(f(1) == 0xffffffffffffffff);
+ ASSERT(f(0xffffffff) == 0xffffffff00000001);
+ ASSERT(f(0x80000000) == 0xffffffff80000000);
+ ASSERT(f(0x7fffffff) == 0xffffffff80000001);
+ ASSERT(f(0x80000001) == 0xffffffff7fffffff);
+ ASSERT(f(0xffffffffffffffff) == 1);
+ ASSERT(f(0x8000000000000000) == 0x8000000000000000);
+ ASSERT(f(0x7fffffffffffffff) == 0x8000000000000001);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/negr_d.c b/deps/lightening/tests/negr_d.c
new file mode 100644
index 0000000..d0e168b
--- /dev/null
+++ b/deps/lightening/tests/negr_d.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+ jit_negr_d(j, JIT_F0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ double (*f)(double) = jit_end(j, NULL);
+
+ ASSERT(f(0.0) == -0.0);
+ ASSERT(f(0.5) == -0.5);
+ ASSERT(f(1.0 / 0.0) == -1.0 / 0.0);
+ ASSERT(f(-1.25) == 1.25);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/negr_f.c b/deps/lightening/tests/negr_f.c
new file mode 100644
index 0000000..26110d5
--- /dev/null
+++ b/deps/lightening/tests/negr_f.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+ jit_negr_f(j, JIT_F0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ float (*f)(float) = jit_end(j, NULL);
+
+ ASSERT(f(0.0f) == -0.0f);
+ ASSERT(f(0.5f) == -0.5f);
+ ASSERT(f(1.0f / 0.0f) == -1.0f / 0.0f);
+ ASSERT(f(-1.25f) == 1.25f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/ori.c b/deps/lightening/tests/ori.c
new file mode 100644
index 0000000..6310185
--- /dev/null
+++ b/deps/lightening/tests/ori.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_ori(j, JIT_R0, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff) == 0x7fffffff);
+ ASSERT(f(0x80000000) == 0x80000001);
+#if __WORDSIZE == 64
+ ASSERT(f(0x7fffffffffffffff) == 0x7fffffffffffffff);
+ ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/orr.c b/deps/lightening/tests/orr.c
new file mode 100644
index 0000000..5a9087a
--- /dev/null
+++ b/deps/lightening/tests/orr.c
@@ -0,0 +1,48 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_orr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff, 1) == 0x7fffffff);
+ ASSERT(f(1, 0x7fffffff) == 0x7fffffff);
+ ASSERT(f(0x80000000, 1) == 0x80000001);
+ ASSERT(f(1, 0x80000000) == 0x80000001);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+ ASSERT(f(0x80000000, 0x7fffffff) == 0xffffffff);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0xffffffff);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 0xffffffff);
+ ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffff);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+ ASSERT(f(0, 0x7fffffff) == 0x7fffffff);
+#if __WORDSIZE == 64
+ ASSERT(f(0x7fffffffffffffff, 1) == 0x7fffffffffffffff);
+ ASSERT(f(1, 0x7fffffffffffffff) == 0x7fffffffffffffff);
+ ASSERT(f(0x8000000000000000, 1) == 0x8000000000000001);
+ ASSERT(f(1, 0x8000000000000000) == 0x8000000000000001);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0xffffffffffffffff);
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0xffffffffffffffff);
+ ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0xffffffffffffffff);
+ ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0xffffffffffffffff);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0xffffffffffffffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/qdivr.c b/deps/lightening/tests/qdivr.c
new file mode 100644
index 0000000..665053c
--- /dev/null
+++ b/deps/lightening/tests/qdivr.c
@@ -0,0 +1,44 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 3, 0, 0);
+
+ jit_operand_t args[] =
+ { jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_V0) };
+ jit_load_args(j, 4, args);
+
+ jit_qdivr(j, JIT_V1, JIT_V2, JIT_R2, JIT_V0);
+ jit_str(j, JIT_R0, JIT_V1);
+ jit_str(j, JIT_R1, JIT_V2);
+
+ jit_leave_jit_abi(j, 3, 0, align);
+
+ jit_ret(j);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ void (*f)(jit_word_t*, jit_word_t*, jit_word_t, jit_word_t) = ret;
+
+#define QDIV(a, b, c, d) \
+ do { \
+ jit_word_t C = 0, D = 0; f(&C, &D, a, b); ASSERT(C == c); ASSERT(D == d); \
+ } while (0)
+
+ QDIV(10, 3, 3, 1);
+ QDIV(-33, 9, -3, -6);
+ QDIV(-41, -7, 5, -6);
+ QDIV(65536, 4096, 16, 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/qdivr_u.c b/deps/lightening/tests/qdivr_u.c
new file mode 100644
index 0000000..e260193
--- /dev/null
+++ b/deps/lightening/tests/qdivr_u.c
@@ -0,0 +1,42 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+
+ size_t align = jit_enter_jit_abi(j, 3, 0, 0);
+
+ jit_operand_t args[] =
+ { jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_V0) };
+ jit_load_args(j, 4, args);
+
+ jit_qdivr_u(j, JIT_V1, JIT_V2, JIT_R2, JIT_V0);
+ jit_str(j, JIT_R0, JIT_V1);
+ jit_str(j, JIT_R1, JIT_V2);
+
+ jit_leave_jit_abi(j, 3, 0, align);
+
+ jit_ret(j);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ void (*f)(jit_word_t*, jit_word_t*, jit_word_t, jit_word_t) = ret;
+#define QDIV(a, b, c, d) \
+ do { \
+ jit_word_t C = 0, D = 0; f(&C, &D, a, b); ASSERT(C == c); ASSERT(D == d); \
+ } while (0)
+
+ QDIV(-1, -2, 1, 1);
+ QDIV(-2, -5, 1, 3);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/qmulr.c b/deps/lightening/tests/qmulr.c
new file mode 100644
index 0000000..1645f5a
--- /dev/null
+++ b/deps/lightening/tests/qmulr.c
@@ -0,0 +1,58 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+
+ size_t align = jit_enter_jit_abi(j, 3, 0, 0);
+
+ jit_operand_t args[] =
+ { jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_V0) };
+ jit_load_args(j, 4, args);
+
+ jit_qmulr(j, JIT_V1, JIT_V2, JIT_R2, JIT_V0);
+ jit_str(j, JIT_R0, JIT_V1);
+ jit_str(j, JIT_R1, JIT_V2);
+
+ jit_leave_jit_abi(j, 3, 0, align);
+
+ jit_ret(j);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ void (*f)(jit_word_t*, jit_word_t*, jit_word_t, jit_word_t) = ret;
+
+#define QMUL(a, b, c, d) \
+ do { \
+ jit_word_t C = 0, D = 0; f(&C, &D, a, b); ASSERT(C == c); ASSERT(D == d); \
+ } while (0)
+
+ QMUL(-2, -1, 2, 0);
+ QMUL(0, -1, 0, 0);
+ QMUL(-1, 0, 0, 0);
+ QMUL(1, -1, -1, -1);
+#if __WORDSIZE == 32
+ QMUL(0x7ffff, 0x7ffff, 0xfff00001, 0x3f);
+ QMUL(0x80000000, -2, 0, 1);
+ QMUL(0x80000000, 2, 0, -1);
+ QMUL(0x80000001, 3, 0x80000003, -2);
+ QMUL(0x80000001, -3, 0x7ffffffd, 1);
+#else
+ QMUL(0x7ffffffff, 0x7ffffffff, 0xfffffff000000001, 0x3f);
+ QMUL(0x8000000000000000, -2, 0, 1);
+ QMUL(0x8000000000000000, 2, 0, -1);
+ QMUL(0x8000000000000001, 3, 0x8000000000000003, -2);
+ QMUL(0x8000000000000001, -3, 0x7ffffffffffffffd, 1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/qmulr_u.c b/deps/lightening/tests/qmulr_u.c
new file mode 100644
index 0000000..bb1d50d
--- /dev/null
+++ b/deps/lightening/tests/qmulr_u.c
@@ -0,0 +1,46 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+
+ size_t align = jit_enter_jit_abi(j, 3, 0, 0);
+
+ jit_operand_t args[] =
+ { jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R1),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_V0) };
+ jit_load_args(j, 4, args);
+
+ jit_qmulr_u(j, JIT_V1, JIT_V2, JIT_R2, JIT_V0);
+ jit_str(j, JIT_R0, JIT_V1);
+ jit_str(j, JIT_R1, JIT_V2);
+
+ jit_leave_jit_abi(j, 3, 0, align);
+
+ jit_ret(j);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ void (*f)(jit_word_t*, jit_word_t*, jit_word_t, jit_word_t) = ret;
+
+#define UQMUL(a, b, c, d) \
+ do { \
+ jit_word_t C = 0, D = 0; f(&C, &D, a, b); ASSERT(C == c); ASSERT(D == d); \
+ } while (0)
+
+#if __WORDSIZE == 32
+ UQMUL(0xffffff, 0xffffff, 0xfe000001, 0xffff);
+#else
+ UQMUL(0xffffffffff, 0xffffffffff, 0xfffffe0000000001, 0xffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/remr.c b/deps/lightening/tests/remr.c
new file mode 100644
index 0000000..805d6fb
--- /dev/null
+++ b/deps/lightening/tests/remr.c
@@ -0,0 +1,60 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_remr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff, 1) == 0);
+ ASSERT(f(1, 0x7fffffff) == 1);
+ ASSERT(f(0x80000000, 1) == 0);
+ ASSERT(f(1, 0x80000000) == 1);
+ ASSERT(f(0x7fffffff, 2) == 1);
+ ASSERT(f(2, 0x7fffffff) == 2);
+ ASSERT(f(0x80000000, 2) == 0);
+ ASSERT(f(2, 0x80000000) == 2);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0x7fffffff);
+ ASSERT(f(0, 0x7fffffff) == 0);
+ ASSERT(f(0xffffffff, 0xffffffff) == 0);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x80000000, 0x7fffffff) == 0xffffffff);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 0xffffffff);
+#else
+ ASSERT(f(0x80000000, 0x7fffffff) == 1);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0x7fffffff);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 1);
+ ASSERT(f(0x7fffffffffffffff, 1) == 0);
+ ASSERT(f(1, 0x7fffffffffffffff) == 1);
+ ASSERT(f(0x8000000000000000, 1) == 0);
+ ASSERT(f(1, 0x8000000000000000) == 1);
+ ASSERT(f(0x7fffffffffffffff, 2) == 1);
+ ASSERT(f(2, 0x7fffffffffffffff) == 2);
+ ASSERT(f(0x8000000000000000, 2) == 0);
+ ASSERT(f(2, 0x8000000000000000) == 2);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0x7fffffffffffffff);
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0xffffffffffffffff);
+ ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0);
+ ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0xffffffffffffffff);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/remr_u.c b/deps/lightening/tests/remr_u.c
new file mode 100644
index 0000000..a9a0178
--- /dev/null
+++ b/deps/lightening/tests/remr_u.c
@@ -0,0 +1,56 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_remr_u(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff, 1) == 0);
+ ASSERT(f(1, 0x7fffffff) == 1);
+ ASSERT(f(0x80000000, 1) == 0);
+ ASSERT(f(1, 0x80000000) == 1);
+ ASSERT(f(0x7fffffff, 2) == 1);
+ ASSERT(f(2, 0x7fffffff) == 2);
+ ASSERT(f(0x80000000, 2) == 0);
+ ASSERT(f(2, 0x80000000) == 2);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0x7fffffff);
+ ASSERT(f(0x80000000, 0x7fffffff) == 1);
+ ASSERT(f(0, 0x7fffffff) == 0);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0x7fffffff);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 1);
+ ASSERT(f(0xffffffff, 0xffffffff) == 0);
+
+#if __WORDSIZE != 32
+ ASSERT(f(0x7fffffffffffffff, 1) == 0);
+ ASSERT(f(1, 0x7fffffffffffffff) == 1);
+ ASSERT(f(0x8000000000000000, 1) == 0);
+ ASSERT(f(1, 0x8000000000000000) == 1);
+ ASSERT(f(0x7fffffffffffffff, 2) == 1);
+ ASSERT(f(2, 0x7fffffffffffffff) == 2);
+ ASSERT(f(0x8000000000000000, 2) == 0);
+ ASSERT(f(2, 0x8000000000000000) == 2);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0x7fffffffffffffff);
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 1);
+ ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x7fffffffffffffff);
+ ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 1);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/rshi.c b/deps/lightening/tests/rshi.c
new file mode 100644
index 0000000..c536055
--- /dev/null
+++ b/deps/lightening/tests/rshi.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_rshi(j, JIT_R0, JIT_R0, 31);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x80000000) == -1);
+#else
+ ASSERT(f(0x80000000) == 1);
+ ASSERT(f(0x8000000000000000) == 0xffffffff00000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/rshi_u.c b/deps/lightening/tests/rshi_u.c
new file mode 100644
index 0000000..8f6dbd4
--- /dev/null
+++ b/deps/lightening/tests/rshi_u.c
@@ -0,0 +1,28 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_rshi_u(j, JIT_R0, JIT_R0, 31);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ jit_word_t (*f)(jit_word_t) = jit_end(j, NULL);
+
+#if __WORDSIZE == 32
+ ASSERT(f(0x80000000) == 1);
+#else
+ ASSERT(f(0x80000000) == 1);
+ ASSERT(f(0x8000000000000000) == 0x100000000);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/rshr.c b/deps/lightening/tests/rshr.c
new file mode 100644
index 0000000..b4b5689
--- /dev/null
+++ b/deps/lightening/tests/rshr.c
@@ -0,0 +1,63 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_rshr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0xfe, 1) == 0x7f);
+ ASSERT(f(0x1fffc, 2) == 0x7fff);
+ ASSERT(f(0x40000000, 30) == 1);
+ ASSERT(f(0x20000000, 29) == 1);
+ ASSERT(f(0x10000000, 28) == 1);
+ ASSERT(f(0x810000, 16) == 0x81);
+ ASSERT(f(0x20000, 17) == 1);
+ ASSERT(f(0x40000, 18) == 1);
+ ASSERT(f(0x7f8000, 15) == 0xff);
+ ASSERT(f(0x1000000, 24) == 1);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+#if __WORDSIZE == 32
+ ASSERT(f(0xfffffff8, 3) == 0xffffffff);
+ ASSERT(f(0x80000000, 31) == 0xffffffff);
+ ASSERT(f(0xffffff00, 8) == 0xffffffff);
+#else
+ ASSERT(f(0x3fffffff8, 3) == 0x7fffffff);
+ ASSERT(f(0xffffffc080000000, 31) == 0xffffffffffffff81);
+ ASSERT(f(0xffffff00, 8) == 0xffffff);
+ ASSERT(f(0xfe00000000, 33) == 0x7f);
+ ASSERT(f(0x1ffffc00000000, 34) == 0x7ffff);
+ ASSERT(f(0xfffffff800000000, 29) == 0xffffffffffffffc0);
+ ASSERT(f(0x8000000000000000, 63) == 0xffffffffffffffff);
+ ASSERT(f(0x4000000000000000, 62) == 1);
+ ASSERT(f(0x2000000000000000, 61) == 1);
+ ASSERT(f(0x1000000000000000, 60) == 1);
+ ASSERT(f(0x81000000000000, 48) == 0x81);
+ ASSERT(f(0x2000000000000, 49) == 1);
+ ASSERT(f(0x10000000000, 40) == 1);
+ ASSERT(f(0x7f800000000000, 47) == 0xff);
+ ASSERT(f(0x100000000000000, 56) == 1);
+ ASSERT(f(0xffffff0000000000, 40) == 0xffffffffffffffff);
+ ASSERT(f(0xfffffffe00000000, 33) == 0xffffffffffffffff);
+ ASSERT(f(0x8000000000000001, 63) == 0xffffffffffffffff);
+ ASSERT(f(0x1000000000000, 48) == 1);
+ ASSERT(f(0xffff800000000000, 47) == 0xffffffffffffffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/rshr_u.c b/deps/lightening/tests/rshr_u.c
new file mode 100644
index 0000000..64c59fd
--- /dev/null
+++ b/deps/lightening/tests/rshr_u.c
@@ -0,0 +1,62 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_rshr_u(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0xfe, 1) == 0x7f);
+ ASSERT(f(0x1fffc, 2) == 0x7fff);
+ ASSERT(f(0x80000000, 31) == 1);
+ ASSERT(f(0x40000000, 30) == 1);
+ ASSERT(f(0x20000000, 29) == 1);
+ ASSERT(f(0x10000000, 28) == 1);
+ ASSERT(f(0x810000, 16) == 0x81);
+ ASSERT(f(0x20000, 17) == 1);
+ ASSERT(f(0x40000, 18) == 1);
+ ASSERT(f(0x7f8000, 15) == 0xff);
+ ASSERT(f(0x1000000, 24) == 1);
+ ASSERT(f(0xffffff00, 8) == 0xffffff);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+#if __WORDSIZE == 32
+ ASSERT(f(0xfffffff8, 3) == 0x1fffffff);
+#else
+ ASSERT(f(0x3fffffff8, 3) == 0x7fffffff);
+ ASSERT(f(0xffffffc080000000, 31) == 0x1ffffff81);
+ ASSERT(f(0xfe00000000, 33) == 0x7f);
+ ASSERT(f(0x1ffffc00000000, 34) == 0x7ffff);
+ ASSERT(f(0xfffffff800000000, 29) == 0x7ffffffc0);
+ ASSERT(f(0x8000000000000000, 63) == 1);
+ ASSERT(f(0x4000000000000000, 62) == 1);
+ ASSERT(f(0x2000000000000000, 61) == 1);
+ ASSERT(f(0x1000000000000000, 60) == 1);
+ ASSERT(f(0x81000000000000, 48) == 0x81);
+ ASSERT(f(0x2000000000000, 49) == 1);
+ ASSERT(f(0x10000000000, 40) == 1);
+ ASSERT(f(0x7f800000000000, 47) == 0xff);
+ ASSERT(f(0x100000000000000, 56) == 1);
+ ASSERT(f(0xffffff0000000000, 40) == 0xffffff);
+ ASSERT(f(0xfffffffe00000000, 33) == 0x7fffffff);
+ ASSERT(f(0x8000000000000001, 63) == 1);
+ ASSERT(f(0x1000000000000, 48) == 1);
+ ASSERT(f(0xffff800000000000, 47) == 0x1ffff);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/sqrtr_d.c b/deps/lightening/tests/sqrtr_d.c
new file mode 100644
index 0000000..873deb9
--- /dev/null
+++ b/deps/lightening/tests/sqrtr_d.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+ jit_sqrtr_d(j, JIT_F0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ double (*f)(double) = jit_end(j, NULL);
+
+ ASSERT(f(0.0) == 0.0);
+ ASSERT(f(4.0) == 2.0);
+ ASSERT(f(-4.0) != f(-4.0)); // nan
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/sqrtr_f.c b/deps/lightening/tests/sqrtr_f.c
new file mode 100644
index 0000000..66db831
--- /dev/null
+++ b/deps/lightening/tests/sqrtr_f.c
@@ -0,0 +1,25 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+ jit_sqrtr_f(j, JIT_F0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ float (*f)(float) = jit_end(j, NULL);
+
+ ASSERT(f(0.0) == 0.0);
+ ASSERT(f(4.0) == 2.0);
+ ASSERT(f(-4.0) != f(-4.0)); // nan
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/sti_c.c b/deps/lightening/tests/sti_c.c
new file mode 100644
index 0000000..ff6e6d5
--- /dev/null
+++ b/deps/lightening/tests/sti_c.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static uint8_t data[] = { 0x12, 0x00, 0x34 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_INT8, JIT_R1));
+
+ jit_sti_c(j, &data[1], JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(int8_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34);
+ f(-1);
+ ASSERT(data[0] == 0x12);
+ ASSERT(data[1] == 0xff);
+ ASSERT(data[2] == 0x34);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/sti_d.c b/deps/lightening/tests/sti_d.c
new file mode 100644
index 0000000..8a703e6
--- /dev/null
+++ b/deps/lightening/tests/sti_d.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+ jit_sti_d(j, &data[1], JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(double) = jit_end(j, NULL);
+
+ ASSERT(data[0] == -1.0);
+ ASSERT(data[1] == 0.0);
+ ASSERT(data[2] == 0.5);
+ f(42.5);
+ ASSERT(data[0] == -1.0);
+ ASSERT(data[1] == 42.5);
+ ASSERT(data[2] == 0.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/sti_f.c b/deps/lightening/tests/sti_f.c
new file mode 100644
index 0000000..e027192
--- /dev/null
+++ b/deps/lightening/tests/sti_f.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+ jit_sti_f(j, &data[1], JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(float) = jit_end(j, NULL);
+
+ ASSERT(data[0] == -1.0f);
+ ASSERT(data[1] == 0.0f);
+ ASSERT(data[2] == 0.5f);
+ f(42.5f);
+ ASSERT(data[0] == -1.0f);
+ ASSERT(data[1] == 42.5f);
+ ASSERT(data[2] == 0.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/sti_i.c b/deps/lightening/tests/sti_i.c
new file mode 100644
index 0000000..4a233c6
--- /dev/null
+++ b/deps/lightening/tests/sti_i.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static uint32_t data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+ jit_sti_i(j, &data[1], JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(int32_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34343434);
+ f(-1);
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0xffffffff);
+ ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/sti_l.c b/deps/lightening/tests/sti_l.c
new file mode 100644
index 0000000..fce9180
--- /dev/null
+++ b/deps/lightening/tests/sti_l.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint64_t data[] = { 0x1212121212121212, 0, 0x3434343434343434 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_INT64, JIT_R1));
+
+ jit_sti_l(j, &data[1], JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(int64_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x1212121212121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x3434343434343434);
+ f(-1);
+ ASSERT(data[0] == 0x1212121212121212);
+ ASSERT(data[1] == 0xffffffffffffffff);
+ ASSERT(data[2] == 0x3434343434343434);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/sti_s.c b/deps/lightening/tests/sti_s.c
new file mode 100644
index 0000000..daab0bd
--- /dev/null
+++ b/deps/lightening/tests/sti_s.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static uint16_t data[] = { 0x1212, 0x0000, 0x3434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_INT16, JIT_R1));
+
+ jit_sti_s(j, &data[1], JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(int16_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x1212);
+ ASSERT(data[1] == 0);
+ ASSERT(data[2] == 0x3434);
+ f(-1);
+ ASSERT(data[0] == 0x1212);
+ ASSERT(data[1] == 0xffff);
+ ASSERT(data[2] == 0x3434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/str_atomic.c b/deps/lightening/tests/str_atomic.c
new file mode 100644
index 0000000..9098c2a
--- /dev/null
+++ b/deps/lightening/tests/str_atomic.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static long data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+ jit_str_atomic(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, int32_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34343434);
+ f(&data[1], 0x0f0f0f0f);
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0x0f0f0f0f);
+ ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/str_c.c b/deps/lightening/tests/str_c.c
new file mode 100644
index 0000000..b894b82
--- /dev/null
+++ b/deps/lightening/tests/str_c.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint8_t data[] = { 0x12, 0x00, 0x34 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT8, JIT_R1));
+
+ jit_str_c(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, int8_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34);
+ f(&data[1], -1);
+ ASSERT(data[0] == 0x12);
+ ASSERT(data[1] == 0xff);
+ ASSERT(data[2] == 0x34);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/str_d.c b/deps/lightening/tests/str_d.c
new file mode 100644
index 0000000..2f992a6
--- /dev/null
+++ b/deps/lightening/tests/str_d.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+ jit_str_d(j, JIT_R0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, double) = jit_end(j, NULL);
+
+ ASSERT(data[0] == -1.0);
+ ASSERT(data[1] == 0.0);
+ ASSERT(data[2] == 0.5);
+ f(&data[1], 42.5);
+ ASSERT(data[0] == -1.0);
+ ASSERT(data[1] == 42.5);
+ ASSERT(data[2] == 0.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/str_f.c b/deps/lightening/tests/str_f.c
new file mode 100644
index 0000000..fdad3c2
--- /dev/null
+++ b/deps/lightening/tests/str_f.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+ jit_str_f(j, JIT_R0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, float) = jit_end(j, NULL);
+
+ ASSERT(data[0] == -1.0f);
+ ASSERT(data[1] == 0.0f);
+ ASSERT(data[2] == 0.5f);
+ f(&data[1], 42.5f);
+ ASSERT(data[0] == -1.0f);
+ ASSERT(data[1] == 42.5f);
+ ASSERT(data[2] == 0.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/str_i.c b/deps/lightening/tests/str_i.c
new file mode 100644
index 0000000..968f0ce
--- /dev/null
+++ b/deps/lightening/tests/str_i.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint32_t data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+ jit_str_i(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, int32_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34343434);
+ f(&data[1], -1);
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0xffffffff);
+ ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/str_l.c b/deps/lightening/tests/str_l.c
new file mode 100644
index 0000000..450885b
--- /dev/null
+++ b/deps/lightening/tests/str_l.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint64_t data[] = { 0x1212121212121212, 0, 0x3434343434343434 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT64, JIT_R1));
+
+ jit_str_l(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, int64_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x1212121212121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x3434343434343434);
+ f(&data[1], -1);
+ ASSERT(data[0] == 0x1212121212121212);
+ ASSERT(data[1] == 0xffffffffffffffff);
+ ASSERT(data[2] == 0x3434343434343434);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/str_s.c b/deps/lightening/tests/str_s.c
new file mode 100644
index 0000000..3e228ed
--- /dev/null
+++ b/deps/lightening/tests/str_s.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint16_t data[] = { 0x1212, 0x0000, 0x3434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT16, JIT_R1));
+
+ jit_str_s(j, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, int16_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x1212);
+ ASSERT(data[1] == 0);
+ ASSERT(data[2] == 0x3434);
+ f(&data[1], -1);
+ ASSERT(data[0] == 0x1212);
+ ASSERT(data[1] == 0xffff);
+ ASSERT(data[2] == 0x3434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxi_c.c b/deps/lightening/tests/stxi_c.c
new file mode 100644
index 0000000..d76d814
--- /dev/null
+++ b/deps/lightening/tests/stxi_c.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint8_t data[] = { 0x12, 0x00, 0x34 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT8, JIT_R1));
+
+ jit_stxi_c(j, (uintptr_t)data, JIT_R2, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(jit_word_t, int8_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34);
+ f(1, -1);
+ ASSERT(data[0] == 0x12);
+ ASSERT(data[1] == 0xff);
+ ASSERT(data[2] == 0x34);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxi_d.c b/deps/lightening/tests/stxi_d.c
new file mode 100644
index 0000000..3933c56
--- /dev/null
+++ b/deps/lightening/tests/stxi_d.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+ jit_stxi_d(j, (uintptr_t)data, JIT_R2, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(jit_word_t, double) = jit_end(j, NULL);
+
+ ASSERT(data[0] == -1.0);
+ ASSERT(data[1] == 0.0);
+ ASSERT(data[2] == 0.5);
+ f(8, 42.5);
+ ASSERT(data[0] == -1.0);
+ ASSERT(data[1] == 42.5);
+ ASSERT(data[2] == 0.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxi_f.c b/deps/lightening/tests/stxi_f.c
new file mode 100644
index 0000000..aea6756
--- /dev/null
+++ b/deps/lightening/tests/stxi_f.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+ jit_stxi_f(j, (uintptr_t)data, JIT_R2, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(jit_word_t, float) = jit_end(j, NULL);
+
+ ASSERT(data[0] == -1.0f);
+ ASSERT(data[1] == 0.0f);
+ ASSERT(data[2] == 0.5f);
+ f(4, 42.5f);
+ ASSERT(data[0] == -1.0f);
+ ASSERT(data[1] == 42.5f);
+ ASSERT(data[2] == 0.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxi_i.c b/deps/lightening/tests/stxi_i.c
new file mode 100644
index 0000000..79dab03
--- /dev/null
+++ b/deps/lightening/tests/stxi_i.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint32_t data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+ jit_stxi_i(j, (uintptr_t)data, JIT_R2, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(jit_word_t, int32_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34343434);
+ f(4, -1);
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0xffffffff);
+ ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxi_l.c b/deps/lightening/tests/stxi_l.c
new file mode 100644
index 0000000..8a68241
--- /dev/null
+++ b/deps/lightening/tests/stxi_l.c
@@ -0,0 +1,34 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint64_t data[] = { 0x1212121212121212, 0, 0x3434343434343434 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT64, JIT_R1));
+
+ jit_stxi_l(j, (uintptr_t)data, JIT_R2, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(jit_word_t, int64_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x1212121212121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x3434343434343434);
+ f(8, -1);
+ ASSERT(data[0] == 0x1212121212121212);
+ ASSERT(data[1] == 0xffffffffffffffff);
+ ASSERT(data[2] == 0x3434343434343434);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxi_s.c b/deps/lightening/tests/stxi_s.c
new file mode 100644
index 0000000..64bda5d
--- /dev/null
+++ b/deps/lightening/tests/stxi_s.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static uint16_t data[] = { 0x1212, 0x0000, 0x3434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT16, JIT_R1));
+
+ jit_stxi_s(j, (uintptr_t)data, JIT_R2, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(jit_word_t, int16_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x1212);
+ ASSERT(data[1] == 0);
+ ASSERT(data[2] == 0x3434);
+ f(2, -1);
+ ASSERT(data[0] == 0x1212);
+ ASSERT(data[1] == 0xffff);
+ ASSERT(data[2] == 0x3434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxr_c.c b/deps/lightening/tests/stxr_c.c
new file mode 100644
index 0000000..8876855
--- /dev/null
+++ b/deps/lightening/tests/stxr_c.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static uint8_t data[] = { 0x12, 0x00, 0x34 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT8, JIT_R1));
+
+ jit_stxr_c(j, JIT_R0, JIT_R2, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, jit_word_t, int8_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34);
+ f(data, 1, -1);
+ ASSERT(data[0] == 0x12);
+ ASSERT(data[1] == 0xff);
+ ASSERT(data[2] == 0x34);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxr_d.c b/deps/lightening/tests/stxr_d.c
new file mode 100644
index 0000000..e87688a
--- /dev/null
+++ b/deps/lightening/tests/stxr_d.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static double data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+ jit_stxr_d(j, JIT_R0, JIT_R2, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, jit_word_t, double) = jit_end(j, NULL);
+
+ ASSERT(data[0] == -1.0);
+ ASSERT(data[1] == 0.0);
+ ASSERT(data[2] == 0.5);
+ f(data, 8, 42.5);
+ ASSERT(data[0] == -1.0);
+ ASSERT(data[1] == 42.5);
+ ASSERT(data[2] == 0.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxr_f.c b/deps/lightening/tests/stxr_f.c
new file mode 100644
index 0000000..bf0c476
--- /dev/null
+++ b/deps/lightening/tests/stxr_f.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static float data[] = { -1.0, 0.0, 0.5 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+ jit_stxr_f(j, JIT_R0, JIT_R2, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, jit_word_t, float) = jit_end(j, NULL);
+
+ ASSERT(data[0] == -1.0f);
+ ASSERT(data[1] == 0.0f);
+ ASSERT(data[2] == 0.5f);
+ f(data, 4, 42.5f);
+ ASSERT(data[0] == -1.0f);
+ ASSERT(data[1] == 42.5f);
+ ASSERT(data[2] == 0.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxr_i.c b/deps/lightening/tests/stxr_i.c
new file mode 100644
index 0000000..8260462
--- /dev/null
+++ b/deps/lightening/tests/stxr_i.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static uint32_t data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+ jit_stxr_i(j, JIT_R0, JIT_R2, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, jit_word_t, int32_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34343434);
+ f(data, 4, -1);
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0xffffffff);
+ ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxr_l.c b/deps/lightening/tests/stxr_l.c
new file mode 100644
index 0000000..fa6bb1f
--- /dev/null
+++ b/deps/lightening/tests/stxr_l.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ static uint64_t data[] = { 0x1212121212121212, 0, 0x3434343434343434 };
+
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT64, JIT_R1));
+
+ jit_stxr_l(j, JIT_R0, JIT_R2, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, jit_word_t, int64_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x1212121212121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x3434343434343434);
+ f(data, 8, -1);
+ ASSERT(data[0] == 0x1212121212121212);
+ ASSERT(data[1] == 0xffffffffffffffff);
+ ASSERT(data[2] == 0x3434343434343434);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/stxr_s.c b/deps/lightening/tests/stxr_s.c
new file mode 100644
index 0000000..a93ccd9
--- /dev/null
+++ b/deps/lightening/tests/stxr_s.c
@@ -0,0 +1,33 @@
+#include "test.h"
+
+static uint16_t data[] = { 0x1212, 0x0000, 0x3434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_3(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R2),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT16, JIT_R1));
+
+ jit_stxr_s(j, JIT_R0, JIT_R2, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, jit_word_t, int16_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x1212);
+ ASSERT(data[1] == 0);
+ ASSERT(data[2] == 0x3434);
+ f(data, 2, -1);
+ ASSERT(data[0] == 0x1212);
+ ASSERT(data[1] == 0xffff);
+ ASSERT(data[2] == 0x3434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/subr.c b/deps/lightening/tests/subr.c
new file mode 100644
index 0000000..57cf950
--- /dev/null
+++ b/deps/lightening/tests/subr.c
@@ -0,0 +1,26 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_subr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ int (*f)(int, int) = ret;
+ ASSERT(f(42, 69) == -27);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/subr_d.c b/deps/lightening/tests/subr_d.c
new file mode 100644
index 0000000..bc611c5
--- /dev/null
+++ b/deps/lightening/tests/subr_d.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1));
+
+ jit_subr_d(j, JIT_F0, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_d(j, JIT_F0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ double (*f)(double, double) = ret;
+ ASSERT(f(42., 69.) == -27.);
+ ASSERT(f(42., 69.5) == -27.5);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/subr_f.c b/deps/lightening/tests/subr_f.c
new file mode 100644
index 0000000..a7befec
--- /dev/null
+++ b/deps/lightening/tests/subr_f.c
@@ -0,0 +1,27 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0),
+ jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F1));
+
+ jit_subr_f(j, JIT_F0, JIT_F0, JIT_F1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr_f(j, JIT_F0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ float (*f)(float, float) = ret;
+ ASSERT(f(42.f, 69.f) == -27.f);
+ ASSERT(f(42.0f, 69.5f) == -27.5f);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/subx.c b/deps/lightening/tests/subx.c
new file mode 100644
index 0000000..b88bcbd
--- /dev/null
+++ b/deps/lightening/tests/subx.c
@@ -0,0 +1,63 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_movi(j, JIT_R2, 0);
+ jit_subcr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_subxi(j, JIT_R2, JIT_R2, 0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R2);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0, 0) == 0);
+
+#if __WORDSIZE == 32
+ /* carry */
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0xffffffff);
+ /* overflow */
+ ASSERT(f(0x80000000, 1) == 0);
+ /* carry */
+ ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+ /* overflow */
+ ASSERT(f(0x80000000, 0x7fffffff) == 0);
+ /* carry+overflow */
+ ASSERT(f(1, 0x80000000) == 0xffffffff);
+#else
+ /* carry */
+ ASSERT(f(0x7fffffff, 0xffffffff) == -1);
+ /* nothing */
+ ASSERT(f(0x80000000, 1) == 0);
+ /* carry */
+ ASSERT(f(0x7fffffff, 0x80000000) == -1);
+ /* nothing */
+ ASSERT(f(0x80000000, 0x7fffffff) == 0);
+ /* carry */
+ ASSERT(f(1, 0x80000000) == -1);
+ /* carry */
+ ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == -1);
+ /* overflow */
+ ASSERT(f(0x8000000000000000, 1) == 0);
+ /* carry */
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == -1);
+ /* overflow */
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0);
+ /* carry+overflow */
+ ASSERT(f(1, 0x8000000000000000) == -1);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/swap_atomic.c b/deps/lightening/tests/swap_atomic.c
new file mode 100644
index 0000000..fffa05e
--- /dev/null
+++ b/deps/lightening/tests/swap_atomic.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static long data[] = { 0x12121212, 0x00000000, 0x34343434 };
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_INT32, JIT_R1));
+
+ jit_swap_atomic(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_ret(j);
+
+ void (*f)(void*, int32_t) = jit_end(j, NULL);
+
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0x00);
+ ASSERT(data[2] == 0x34343434);
+ f(&data[1], 0x0f0f0f0f);
+ ASSERT(data[0] == 0x12121212);
+ ASSERT(data[1] == 0x0f0f0f0f);
+ ASSERT(data[2] == 0x34343434);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/test.h b/deps/lightening/tests/test.h
new file mode 100644
index 0000000..c4eff2b
--- /dev/null
+++ b/deps/lightening/tests/test.h
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include <lightening.h>
+
+#define ASSERT(x) \
+ do { \
+ if (!(x)) { \
+ fprintf(stderr, "%s:%d: assertion failed: " #x "\n", \
+ __FILE__, __LINE__); \
+ abort(); \
+ } \
+ } while (0)
+
+static inline int
+main_helper (int argc, char *argv[],
+ void (*run_test)(jit_state_t*, uint8_t*, size_t))
+{
+ ASSERT(init_jit());
+ jit_state_t *j = jit_new_state (NULL, NULL);
+ ASSERT(j);
+
+ const size_t arena_size = 4096;
+ char *arena_base = mmap (NULL, arena_size,
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ if (arena_base == MAP_FAILED)
+ {
+ perror ("allocating JIT code buffer failed");
+ return 1;
+ }
+
+ run_test(j, (uint8_t*)arena_base, arena_size);
+
+ jit_destroy_state(j);
+
+ munmap(arena_base, arena_size);
+
+ return 0;
+}
+
+static inline int
+main_compiler (int argc, char *argv[],
+ size_t (*run_test)(jit_state_t*, uint8_t*, size_t))
+{
+ ASSERT(init_jit());
+ jit_state_t *j = jit_new_state (NULL, NULL);
+ ASSERT(j);
+
+ size_t arena_size = 4096, prev_arena_size = arena_size;
+ uint8_t *arena_base = NULL;
+ do {
+ if (arena_base) {
+ if (munmap(arena_base, prev_arena_size) == -1) {
+ perror("unmapping arena failed");
+ return 1;
+ }
+ }
+
+ prev_arena_size = arena_size;
+
+ arena_base = mmap (NULL, arena_size,
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ if (arena_base == MAP_FAILED) {
+ perror ("allocating JIT code buffer failed");
+ return 1;
+ }
+ } while ((arena_size = run_test(j, arena_base, arena_size)) != 0);
+
+ jit_destroy_state(j);
+
+ munmap(arena_base, arena_size);
+
+ return 0;
+}
diff --git a/deps/lightening/tests/truncr_d_i.c b/deps/lightening/tests/truncr_d_i.c
new file mode 100644
index 0000000..b21280f
--- /dev/null
+++ b/deps/lightening/tests/truncr_d_i.c
@@ -0,0 +1,30 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+ jit_truncr_d_i(j, JIT_R0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ int (*f)(double) = jit_end(j, NULL);
+
+ ASSERT(f(0.0) == 0);
+ ASSERT(f(-0.0) == 0);
+ ASSERT(f(0.5) == 0);
+ ASSERT(f(-0.5) == 0);
+ ASSERT(f(1.5) == 1);
+ ASSERT(f(-1.5) == -1);
+ ASSERT(f(2.5) == 2);
+ ASSERT(f(-2.5) == -2);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/truncr_d_l.c b/deps/lightening/tests/truncr_d_l.c
new file mode 100644
index 0000000..189617a
--- /dev/null
+++ b/deps/lightening/tests/truncr_d_l.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0));
+
+ jit_truncr_d_l(j, JIT_R0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ int64_t (*f)(double) = jit_end(j, NULL);
+
+ ASSERT(f(0.0) == 0);
+ ASSERT(f(-0.0) == 0);
+ ASSERT(f(0.5) == 0);
+ ASSERT(f(-0.5) == 0);
+ ASSERT(f(1.5) == 1);
+ ASSERT(f(-1.5) == -1);
+ ASSERT(f(2.5) == 2);
+ ASSERT(f(-2.5) == -2);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/truncr_f_i.c b/deps/lightening/tests/truncr_f_i.c
new file mode 100644
index 0000000..3dbf630
--- /dev/null
+++ b/deps/lightening/tests/truncr_f_i.c
@@ -0,0 +1,30 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+ jit_truncr_f_i(j, JIT_R0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ int (*f)(float) = jit_end(j, NULL);
+
+ ASSERT(f(0.0) == 0);
+ ASSERT(f(-0.0) == 0);
+ ASSERT(f(0.5) == 0);
+ ASSERT(f(-0.5) == 0);
+ ASSERT(f(1.5) == 1);
+ ASSERT(f(-1.5) == -1);
+ ASSERT(f(2.5) == 2);
+ ASSERT(f(-2.5) == -2);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/truncr_f_l.c b/deps/lightening/tests/truncr_f_l.c
new file mode 100644
index 0000000..7369ae3
--- /dev/null
+++ b/deps/lightening/tests/truncr_f_l.c
@@ -0,0 +1,32 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+#if __WORDSIZE > 32
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_fpr (JIT_OPERAND_ABI_FLOAT, JIT_F0));
+
+ jit_truncr_f_l(j, JIT_R0, JIT_F0);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ int64_t (*f)(float) = jit_end(j, NULL);
+
+ ASSERT(f(0.0) == 0);
+ ASSERT(f(-0.0) == 0);
+ ASSERT(f(0.5) == 0);
+ ASSERT(f(-0.5) == 0);
+ ASSERT(f(1.5) == 1);
+ ASSERT(f(-1.5) == -1);
+ ASSERT(f(2.5) == 2);
+ ASSERT(f(-2.5) == -2);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/xori.c b/deps/lightening/tests/xori.c
new file mode 100644
index 0000000..4bb2ad1
--- /dev/null
+++ b/deps/lightening/tests/xori.c
@@ -0,0 +1,31 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0));
+
+ jit_xori(j, JIT_R0, JIT_R0, 1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff) == 0x7ffffffe);
+ ASSERT(f(0x80000000) == 0x80000001);
+#if __WORDSIZE == 64
+ ASSERT(f(0x7fffffffffffffff) == 0x7ffffffffffffffe);
+ ASSERT(f(0x8000000000000000) == 0x8000000000000001);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/xorr.c b/deps/lightening/tests/xorr.c
new file mode 100644
index 0000000..dd5a390
--- /dev/null
+++ b/deps/lightening/tests/xorr.c
@@ -0,0 +1,48 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1));
+
+ jit_xorr(j, JIT_R0, JIT_R0, JIT_R1);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr(j, JIT_R0);
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ jit_word_t (*f)(jit_word_t, jit_word_t) = ret;
+
+ ASSERT(f(0x7fffffff, 1) == 0x7ffffffe);
+ ASSERT(f(1, 0x7fffffff) == 0x7ffffffe);
+ ASSERT(f(0x80000000, 1) == 0x80000001);
+ ASSERT(f(1, 0x80000000) == 0x80000001);
+ ASSERT(f(0x7fffffff, 0x80000000) == 0xffffffff);
+ ASSERT(f(0x80000000, 0x7fffffff) == 0xffffffff);
+ ASSERT(f(0x7fffffff, 0xffffffff) == 0x80000000);
+ ASSERT(f(0xffffffff, 0x7fffffff) == 0x80000000);
+ ASSERT(f(0xffffffff, 0xffffffff) == 0);
+ ASSERT(f(0x7fffffff, 0) == 0x7fffffff);
+ ASSERT(f(0, 0x7fffffff) == 0x7fffffff);
+#if __WORDSIZE == 64
+ ASSERT(f(0x7fffffffffffffff, 1) == 0x7ffffffffffffffe);
+ ASSERT(f(1, 0x7fffffffffffffff) == 0x7ffffffffffffffe);
+ ASSERT(f(0x8000000000000000, 1) == 0x8000000000000001);
+ ASSERT(f(1, 0x8000000000000000) == 0x8000000000000001);
+ ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0xffffffffffffffff);
+ ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0xffffffffffffffff);
+ ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x8000000000000000);
+ ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0x8000000000000000);
+ ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/z_atomic.c b/deps/lightening/tests/z_atomic.c
new file mode 100644
index 0000000..8612d15
--- /dev/null
+++ b/deps/lightening/tests/z_atomic.c
@@ -0,0 +1,88 @@
+#include "test.h"
+
+#include <threads.h>
+
+/* note non-atomic counter! */
+size_t num = 0;
+long lock_var = 0;
+void (*spin_lock)(void);
+void (*spin_unlock)(void);
+
+/* arbitrary number, as long as its large enough to likely allow other threads
+ * to spawn. */
+#define THREAD_INCREMENTS 1000000
+static int
+loop(void *arg)
+{
+ for (size_t i = 0; i < THREAD_INCREMENTS; ++i) {
+ (*spin_lock)();
+ num++;
+ (*spin_unlock)();
+ }
+
+ return 0;
+}
+
+#define NUM_THREADS 10
+static void
+run_loops()
+{
+ thrd_t threads[NUM_THREADS];
+ for (size_t i = 0; i < NUM_THREADS; ++i)
+ ASSERT(thrd_create(&threads[i], loop, NULL) == thrd_success);
+
+ for (size_t i = 0; i < NUM_THREADS; ++i)
+ ASSERT(thrd_join(threads[i], NULL) == thrd_success);
+
+ ASSERT(num == NUM_THREADS * THREAD_INCREMENTS);
+}
+
+static size_t
+run_test(jit_state_t *_jit, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(_jit, arena_base, arena_size);
+
+ /* based on https://rigtorp.se/spinlock/ */
+ spin_lock = jit_address(_jit);
+ {
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0);
+ void *do_exchange = jit_address(_jit);
+ void *while_load = jit_address(_jit);
+ /* do { */
+ /* while (atomic_load(lock_var)); */
+ jit_movi(_jit, JIT_R1, (jit_imm_t)&lock_var);
+ jit_ldr_atomic(_jit, JIT_R0, JIT_R1);
+ jit_patch_there(_jit, jit_bnei(_jit, JIT_R0, 0), while_load);
+ /* } while (atomic_exchange(lock_var, 1)); */
+ jit_movi(_jit, JIT_R0, 1);
+ jit_swap_atomic(_jit, JIT_R0, JIT_R1, JIT_R0);
+ jit_patch_there(_jit, jit_bnei(_jit, JIT_R0, 0), do_exchange);
+ jit_leave_jit_abi(_jit, 0, 0, frame);
+ jit_ret(_jit);
+ }
+
+ spin_unlock = jit_address(_jit);
+ {
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0);
+ jit_movi(_jit, JIT_R0, 0);
+ jit_movi(_jit, JIT_R1, (jit_imm_t)&lock_var);
+ jit_str_atomic(_jit, JIT_R1, JIT_R0);
+ jit_leave_jit_abi(_jit, 0, 0, frame);
+ jit_ret(_jit);
+ }
+
+ size_t size;
+ void *p = jit_end(_jit, &size);
+
+ if (p)
+ run_loops();
+ else
+ return size;
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return main_compiler(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/z_bp.c b/deps/lightening/tests/z_bp.c
new file mode 100644
index 0000000..57f7bfa
--- /dev/null
+++ b/deps/lightening/tests/z_bp.c
@@ -0,0 +1,61 @@
+#include "test.h"
+
+static size_t
+run_test(jit_state_t *_jit, uint8_t *arena_base, size_t arena_size)
+{
+ int32_t (*function)(int32_t);
+
+ jit_begin(_jit, arena_base, arena_size);
+
+ void *entry = jit_address(_jit);
+ size_t frame = jit_enter_jit_abi(_jit, 3, 0, 0);
+
+ jit_load_args_1(_jit, jit_operand_gpr(JIT_OPERAND_ABI_INT32, JIT_R0));
+
+ jit_reloc_t out1 = jit_beqi(_jit, JIT_R0, 0);
+ jit_movr(_jit, JIT_V0, JIT_R0);
+ jit_movi(_jit, JIT_R0, 1);
+
+ jit_reloc_t out2 = jit_blei_u(_jit, JIT_V0, 2);
+ jit_subi(_jit, JIT_V1, JIT_V0, 1);
+ jit_subi(_jit, JIT_V2, JIT_V0, 2);
+
+ jit_calli_1(_jit, entry, jit_operand_gpr(JIT_OPERAND_ABI_INT32, JIT_V1));
+ jit_retval(_jit, JIT_V1);
+
+ jit_calli_1(_jit, entry, jit_operand_gpr(JIT_OPERAND_ABI_INT32, JIT_V2));
+ jit_retval(_jit, JIT_R0);
+
+ jit_addr(_jit, JIT_R0, JIT_R0, JIT_V1);
+
+ jit_patch_here(_jit, out1);
+ jit_patch_here(_jit, out2);
+ jit_leave_jit_abi(_jit, 3, 0, frame);
+ jit_retr(_jit, JIT_R0);
+
+ size_t size = 0;
+ function = jit_end(_jit, &size);
+
+ if (function) {
+ ASSERT((*function)(1) == 1);
+ ASSERT((*function)(2) == 1);
+ ASSERT((*function)(3) == 2);
+ ASSERT((*function)(4) == 3);
+ ASSERT((*function)(5) == 5);
+ ASSERT((*function)(6) == 8);
+ ASSERT((*function)(7) == 13);
+ ASSERT((*function)(8) == 21);
+ ASSERT((*function)(9) == 34);
+
+ ASSERT((*function)(32) == 2178309);
+ } else {
+ return size;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return main_compiler(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/z_branch.c b/deps/lightening/tests/z_branch.c
new file mode 100644
index 0000000..30f0ea5
--- /dev/null
+++ b/deps/lightening/tests/z_branch.c
@@ -0,0 +1,584 @@
+#include "test.h"
+
+#if __WORDSIZE == 64
+# define I7f 0x7fffffffffffffff
+# define I80 0x8000000000000000
+# define I81 0x8000000000000001
+# define Iff 0xffffffffffffffff
+#else
+# define I7f 0x7fffffff
+# define I80 0x80000000
+# define I81 0x80000001
+# define Iff 0xffffffff
+#endif
+
+#define NaN (0.0 / 0.0)
+
+#if defined(DEBUG)
+#define dump_args(comp, r0, r1)\
+ jit_calli_1(_jit, puts,\
+ jit_operand_imm(JIT_OPERAND_ABI_POINTER,\
+ (jit_imm_t)#comp " " #r0 " " #r1));
+#else
+#define dump_args(comp, r0, r1)
+#endif
+
+#define BOP(N, Ls, Rs, Lu, Ru, R0, R1) \
+{ \
+ dump_args(N##r, Ls, Rs); \
+ jit_movi(_jit, R0, Ls); \
+ jit_movi(_jit, R1, Rs); \
+ jit_reloc_t r = jit_b##N##r(_jit, R0, R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i, Ls, Rs); \
+ jit_movi(_jit, R0, Ls); \
+ jit_reloc_t r = jit_b##N##i(_jit, R0, Rs); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##r_u, Lu, Ru); \
+ jit_movi(_jit, R0, Lu); \
+ jit_movi(_jit, R1, Ru); \
+ jit_reloc_t r = jit_b##N##r_u(_jit, R0, R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i_u, Lu, Ru); \
+ jit_movi(_jit, R0, Lu); \
+ jit_reloc_t r = jit_b##N##i_u(_jit, R0, Ru); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define EB(N, L, R, R0, R1) \
+{ \
+ dump_args(N##r, L, R); \
+ jit_movi(_jit, R0, L); \
+ jit_movi(_jit, R1, R); \
+ jit_reloc_t r = jit_b##N##r(_jit, R0, R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i, L, R); \
+ jit_movi(_jit, R0, L); \
+ jit_reloc_t r = jit_b##N##i(_jit, R0, R); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+
+#define XEB(N, L, R, R0, R1) \
+{ \
+ dump_args(N##r, L, R); \
+ jit_movi(_jit, R0, L); \
+ jit_movi(_jit, R1, R); \
+ jit_reloc_t r = jit_b##N##r(_jit, R0, R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i, L, R); \
+ jit_movi(_jit, R0, L); \
+ jit_reloc_t r = jit_b##N##i(_jit, R0, R); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define XBOP(N, Ls, Rs, Lu, Ru, R0, R1) \
+{ \
+ dump_args(N##r, Ls, Rs); \
+ jit_movi(_jit, R0, Ls); \
+ jit_movi(_jit, R1, Rs); \
+ jit_reloc_t r = jit_b##N##r(_jit, R0, R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i, Ls, Rs); \
+ jit_movi(_jit, R0, Ls); \
+ jit_reloc_t r = jit_b##N##i(_jit, R0, Rs); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##r_u, Lu, Ru); \
+ jit_movi(_jit, R0, Lu); \
+ jit_movi(_jit, R1, Ru); \
+ jit_reloc_t r = jit_b##N##r_u(_jit, R0, R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i_u, Lu, Ru); \
+ jit_movi(_jit, R0, Lu); \
+ jit_reloc_t r = jit_b##N##i_u(_jit, R0, Ru); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define BOPI(N, Ls, Rs, Lu, Ru) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V0, JIT_V1) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V0, JIT_V2) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V0, JIT_R0) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V0, JIT_R1) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V0, JIT_R2) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V1, JIT_V0) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V1, JIT_V2) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V1, JIT_R0) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V1, JIT_R1) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V1, JIT_R2) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V2, JIT_V0) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V2, JIT_V1) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V2, JIT_R0) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V2, JIT_R1) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_V2, JIT_R2) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R0, JIT_V0) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R0, JIT_V1) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R0, JIT_V2) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R0, JIT_R1) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R0, JIT_R2) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R1, JIT_V0) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R1, JIT_V1) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R1, JIT_V2) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R1, JIT_R0) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R1, JIT_R2) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R2, JIT_V0) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R2, JIT_V1) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R2, JIT_V2) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R2, JIT_R0) \
+ BOP(N, Ls, Rs, Lu, Ru, JIT_R2, JIT_R1)
+
+#define EBI(N, L, R) \
+ EB(N, L, R, JIT_V0, JIT_V1) \
+ EB(N, L, R, JIT_V0, JIT_V2) \
+ EB(N, L, R, JIT_V0, JIT_R0) \
+ EB(N, L, R, JIT_V0, JIT_R1) \
+ EB(N, L, R, JIT_V0, JIT_R2) \
+ EB(N, L, R, JIT_V1, JIT_V0) \
+ EB(N, L, R, JIT_V1, JIT_V2) \
+ EB(N, L, R, JIT_V1, JIT_R0) \
+ EB(N, L, R, JIT_V1, JIT_R1) \
+ EB(N, L, R, JIT_V1, JIT_R2) \
+ EB(N, L, R, JIT_V2, JIT_V0) \
+ EB(N, L, R, JIT_V2, JIT_V1) \
+ EB(N, L, R, JIT_V2, JIT_R0) \
+ EB(N, L, R, JIT_V2, JIT_R1) \
+ EB(N, L, R, JIT_V2, JIT_R2) \
+ EB(N, L, R, JIT_R0, JIT_V0) \
+ EB(N, L, R, JIT_R0, JIT_V1) \
+ EB(N, L, R, JIT_R0, JIT_V2) \
+ EB(N, L, R, JIT_R0, JIT_R1) \
+ EB(N, L, R, JIT_R0, JIT_R2) \
+ EB(N, L, R, JIT_R1, JIT_V0) \
+ EB(N, L, R, JIT_R1, JIT_V1) \
+ EB(N, L, R, JIT_R1, JIT_V2) \
+ EB(N, L, R, JIT_R1, JIT_R0) \
+ EB(N, L, R, JIT_R1, JIT_R2) \
+ EB(N, L, R, JIT_R2, JIT_V0) \
+ EB(N, L, R, JIT_R2, JIT_V1) \
+ EB(N, L, R, JIT_R2, JIT_V2) \
+ EB(N, L, R, JIT_R2, JIT_R0) \
+ EB(N, L, R, JIT_R2, JIT_R1)
+
+
+#define XEBI(N, L, R) \
+ XEB(N, L, R, JIT_V0, JIT_V1) \
+ XEB(N, L, R, JIT_V0, JIT_V2) \
+ XEB(N, L, R, JIT_V0, JIT_R0) \
+ XEB(N, L, R, JIT_V0, JIT_R1) \
+ XEB(N, L, R, JIT_V0, JIT_R2) \
+ XEB(N, L, R, JIT_V1, JIT_V0) \
+ XEB(N, L, R, JIT_V1, JIT_V2) \
+ XEB(N, L, R, JIT_V1, JIT_R0) \
+ XEB(N, L, R, JIT_V1, JIT_R1) \
+ XEB(N, L, R, JIT_V1, JIT_R2) \
+ XEB(N, L, R, JIT_V2, JIT_V0) \
+ XEB(N, L, R, JIT_V2, JIT_V1) \
+ XEB(N, L, R, JIT_V2, JIT_R0) \
+ XEB(N, L, R, JIT_V2, JIT_R1) \
+ XEB(N, L, R, JIT_V2, JIT_R2) \
+ XEB(N, L, R, JIT_R0, JIT_V0) \
+ XEB(N, L, R, JIT_R0, JIT_V1) \
+ XEB(N, L, R, JIT_R0, JIT_V2) \
+ XEB(N, L, R, JIT_R0, JIT_R1) \
+ XEB(N, L, R, JIT_R0, JIT_R2) \
+ XEB(N, L, R, JIT_R1, JIT_V0) \
+ XEB(N, L, R, JIT_R1, JIT_V1) \
+ XEB(N, L, R, JIT_R1, JIT_V2) \
+ XEB(N, L, R, JIT_R1, JIT_R0) \
+ XEB(N, L, R, JIT_R1, JIT_R2) \
+ XEB(N, L, R, JIT_R2, JIT_V0) \
+ XEB(N, L, R, JIT_R2, JIT_V1) \
+ XEB(N, L, R, JIT_R2, JIT_V2) \
+ XEB(N, L, R, JIT_R2, JIT_R0) \
+ XEB(N, L, R, JIT_R2, JIT_R1)
+
+#define XBOPI(N, Ls, Rs, Lu, Ru) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V0, JIT_V1) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V0, JIT_V2) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V0, JIT_R0) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V0, JIT_R1) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V0, JIT_R2) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V1, JIT_V0) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V1, JIT_V2) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V1, JIT_R0) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V1, JIT_R1) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V1, JIT_R2) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V2, JIT_V0) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V2, JIT_V1) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V2, JIT_R0) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V2, JIT_R1) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_V2, JIT_R2) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R0, JIT_V0) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R0, JIT_V1) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R0, JIT_V2) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R0, JIT_R1) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R0, JIT_R2) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R1, JIT_V0) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R1, JIT_V1) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R1, JIT_V2) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R1, JIT_R0) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R1, JIT_R2) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R2, JIT_V0) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R2, JIT_V1) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R2, JIT_V2) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R2, JIT_R0) \
+ XBOP(N, Ls, Rs, Lu, Ru, JIT_R2, JIT_R1)
+
+#define TBOPF(N, T, L, R) \
+{ \
+ dump_args(N##r##_##T, L, R); \
+ jit_movi_##T(_jit, JIT_F0, L); \
+ jit_movi_##T(_jit, JIT_F1, R); \
+ jit_reloc_t r = \
+ jit_b##N##r##_##T(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i##_##T, L, R); \
+ jit_movi_##T(_jit, JIT_F0, L); \
+ jit_movi_##T(_jit, JIT_F1, R); \
+ jit_reloc_t r = \
+ jit_b##N##r##_##T(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##r##_##T, L, NaN); \
+ jit_movi_##T(_jit, JIT_F0, L); \
+ jit_movi_##T(_jit, JIT_F1, NaN); \
+ jit_reloc_t err = \
+ jit_b##N##r##_##T(_jit, JIT_F0, JIT_F1); \
+ jit_reloc_t ok = jit_jmp(_jit); \
+ jit_patch_here(_jit, err); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, ok); \
+} \
+{ \
+ dump_args(N##i##_##T, L, NaN); \
+ jit_movi_##T(_jit, JIT_F0, L); \
+ jit_movi_##T(_jit, JIT_F1, NaN); \
+ jit_reloc_t err = \
+ jit_b##N##r##_##T(_jit, JIT_F0, JIT_F1); \
+ jit_reloc_t ok = jit_jmp(_jit); \
+ jit_patch_here(_jit, err); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, ok); \
+}
+
+#define BOPF(N, L, R) \
+ TBOPF(N, f, L, R) \
+ TBOPF(N, d, L, R)
+
+#define TUBOPF(N, T, L, R) \
+{ \
+ dump_args(N##r##_##T, L, R); \
+ jit_movi_##T(_jit, JIT_F0, L); \
+ jit_movi_##T(_jit, JIT_F1, R); \
+ jit_reloc_t r = \
+ jit_b##N##r##_##T(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i##_##T, L, R); \
+ jit_movi_##T(_jit, JIT_F0, L); \
+ jit_movi_##T(_jit, JIT_F1, R); \
+ jit_reloc_t r = \
+ jit_b##N##r##_##T(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##r##_##T, L, NaN); \
+ jit_movi_##T(_jit, JIT_F0, L); \
+ jit_movi_##T(_jit, JIT_F1, NaN); \
+ jit_reloc_t r = \
+ jit_b##N##r##_##T(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i##_##T, L, NaN); \
+ jit_movi_##T(_jit, JIT_F0, L); \
+ jit_movi_##T(_jit, JIT_F1, NaN); \
+ jit_reloc_t r = \
+ jit_b##N##r##_##T(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define UBOPF(N, L, R) \
+ TUBOPF(N, f, L, R) \
+ TUBOPF(N, d, L, R)
+
+#define ARGB(N, L, R) \
+{ \
+ dump_args(N##r, L, R); \
+ jit_movi(_jit, JIT_R0, L); \
+ jit_movi(_jit, JIT_R1, R); \
+ jit_reloc_t r = \
+ jit_b##N##r(_jit, JIT_R0, JIT_R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i, L, R); \
+ jit_movi(_jit, JIT_R0, L); \
+ jit_reloc_t r = jit_b##N##i(_jit, JIT_R0, R); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##r_u, R, L); \
+ jit_movi(_jit, JIT_R0, R); \
+ jit_movi(_jit, JIT_R1, L); \
+ jit_reloc_t r = \
+ jit_b##N##r_u(_jit, JIT_R0, JIT_R1);\
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i_u, R, L); \
+ jit_movi(_jit, JIT_R0, R); \
+ jit_reloc_t r = jit_b##N##i_u(_jit, JIT_R0, L); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define ARGBS() \
+ ARGB(lt, -1, 1) \
+ ARGB(le, -1, -1) \
+ ARGB(ge, -1, -1) \
+ ARGB(gt, 1, -1) \
+
+#define OVFGB(N, L, R, U, D) \
+{ \
+ dump_args(N##r, L, ); \
+ jit_movi(_jit, JIT_R0, L); \
+ jit_movi(_jit, JIT_R1, 1); \
+ jit_reloc_t r = \
+ jit_b##N##r(_jit, JIT_R0, JIT_R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##r_u, R, ); \
+ jit_movi(_jit, JIT_R0, R); \
+ jit_movi(_jit, JIT_R1, 1); \
+ jit_reloc_t r = \
+ jit_b##N##r_u(_jit, JIT_R0, JIT_R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i, U, ); \
+ jit_movi(_jit, JIT_R0, U); \
+ jit_reloc_t r = \
+ jit_b##N##i(_jit, JIT_R0, 1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i_u, D, ); \
+ jit_movi(_jit, JIT_R0, D); \
+ jit_reloc_t r = \
+ jit_b##N##i_u(_jit, JIT_R0, 1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define OVFGBS() \
+ OVFGB(oadd, I7f, Iff, I7f, Iff) \
+ OVFGB(xadd, I80, I7f, I80, I7f) \
+ OVFGB(osub, I80, 0x0, I80, 0x0) \
+ OVFGB(xsub, I81, I80, I81, I80)
+
+#define MGB(N, L, R) \
+{ \
+ dump_args(N##r, L, R); \
+ jit_movi(_jit, JIT_R0, L); \
+ jit_movi(_jit, JIT_R1, R); \
+ jit_reloc_t r = \
+ jit_b##N##r(_jit, JIT_R0, JIT_R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i, L, R); \
+ jit_movi(_jit, JIT_R0, L); \
+ jit_reloc_t r = jit_b##N##i(_jit, JIT_R0, R); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define MBGS() \
+ MGB(ms, 1, 3) \
+ MGB(mc, 1, 2) \
+ MGB(ne, -3, 3) \
+ MGB(eq, 3, 3)
+
+#define ARFGB(N, L, R) \
+{ \
+ dump_args(N##r_f, L, R); \
+ jit_movi_f(_jit, JIT_F0, L); \
+ jit_movi_f(_jit, JIT_F1, R); \
+ jit_reloc_t r = \
+ jit_b##N##r_f(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+} \
+{ \
+ dump_args(N##i_f, L, R); \
+ jit_movi_f(_jit, JIT_F0, L); \
+ jit_movi_f(_jit, JIT_F1, R); \
+ jit_reloc_t r = \
+ jit_b##N##r_f(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define ARFGBS() \
+ ARFGB(lt, 1, 2) \
+ ARFGB(le, -1, -1) \
+ ARFGB(ge, -3, -3) \
+ ARFGB(gt, 2, 1) \
+ ARFGB(eq, -2, -2) \
+ ARFGB(ne, 0, 2)
+
+static size_t
+run_test(jit_state_t *_jit, uint8_t *arena_base, size_t arena_size)
+{
+ void (*function)();
+ jit_begin(_jit, arena_base, arena_size);
+ size_t frame = jit_enter_jit_abi(_jit, 3, 0, 0);
+
+ ARGBS();
+ MBGS();
+ OVFGBS();
+ ARFGBS();
+
+ BOPI(lt, -1, 1, 1, -1)
+ BOPI(le, -1, -1, 1, 1)
+ EBI(eq, 32, 32)
+ BOPI(ge, -2, -2, 2, 2)
+ BOPI(gt, 2, -2, -2, 2)
+ EBI(ne, 3, -3)
+ XEBI(ms, 1, 3)
+ XEBI(mc, 1, 2)
+ XBOPI(oadd, I7f, 1, Iff, 1)
+ XBOPI(xadd, I80, 1, I7f, 1)
+ XBOPI(osub, I80, 1, 0, 1)
+ XBOPI(xsub, I81, 1, I80, 1)
+ BOPF(lt, 1, 2)
+ BOPF(le, 2, 2)
+ BOPF(eq, 3, 3)
+ BOPF(ge, 3, 3)
+ BOPF(gt, 4, 3)
+ UBOPF(ne, 4, 3)
+ UBOPF(unlt, 1, 2)
+ UBOPF(unle, 2, 2)
+ UBOPF(uneq, 3, 3)
+ UBOPF(unge, 3, 3)
+ UBOPF(ungt, 4, 3)
+ BOPF(ltgt, 4, 3)
+
+ {
+ dump_args(ordr, 5, 5);
+ jit_movi_f(_jit, JIT_F0, 5);
+ jit_movi_f(_jit, JIT_F1, 5);
+ jit_reloc_t r = jit_bordr_f(_jit, JIT_F0, JIT_F1);
+ jit_calli_0(_jit, abort);
+ jit_patch_here(_jit, r);
+ }
+ {
+ dump_args(ordr, 5, 1);
+ jit_movi_f(_jit, JIT_F0, 5);
+ jit_movi_f(_jit, JIT_F1, 1);
+ jit_reloc_t r = jit_bordr_f(_jit, JIT_F0, JIT_F1);
+ jit_calli_0(_jit, abort);
+ jit_patch_here(_jit, r);
+ }
+ {
+ dump_args(ordr, 5, NaN);
+ jit_movi_f(_jit, JIT_F0, 5);
+ jit_movi_f(_jit, JIT_F1, NaN);
+ jit_reloc_t err = jit_bordr_f(_jit, JIT_F0, JIT_F1);
+ jit_reloc_t ok = jit_jmp(_jit);
+ jit_patch_here(_jit, err);
+ jit_calli_0(_jit, abort);
+ jit_patch_here(_jit, ok);
+ }
+ {
+ dump_args(unordr, 5, 5);
+ jit_movi_f(_jit, JIT_F0, 5);
+ jit_movi_f(_jit, JIT_F1, 5);
+ jit_reloc_t err = jit_bunordr_f(_jit, JIT_F0, JIT_F1);
+ jit_reloc_t ok = jit_jmp(_jit);
+ jit_patch_here(_jit, err);
+ jit_calli_0(_jit, abort);
+ jit_patch_here(_jit, ok);
+ }
+ {
+ dump_args(unordr, 5, 1);
+ jit_movi_f(_jit, JIT_F0, 5);
+ jit_movi_f(_jit, JIT_F1, 1);
+ jit_reloc_t err = jit_bunordr_f(_jit, JIT_F0, JIT_F1);
+ jit_reloc_t ok = jit_jmp(_jit);
+ jit_patch_here(_jit, err);
+ jit_calli_0(_jit, abort);
+ jit_patch_here(_jit, ok);
+ }
+ {
+ dump_args(unordr, 5, NaN);
+ jit_movi_f(_jit, JIT_F0, 5);
+ jit_movi_f(_jit, JIT_F1, NaN);
+ jit_reloc_t r = jit_bunordr_f(_jit, JIT_F0, JIT_F1);
+ jit_calli_0(_jit, abort);
+ jit_patch_here(_jit, r);
+ }
+
+ jit_leave_jit_abi(_jit, 3, 0, frame);
+ jit_ret(_jit);
+
+ size_t size;
+ function = jit_end(_jit, &size);
+
+ if (function)
+ (*function)();
+ else
+ return size;
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return main_compiler(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/z_call.c b/deps/lightening/tests/z_call.c
new file mode 100644
index 0000000..be1c072
--- /dev/null
+++ b/deps/lightening/tests/z_call.c
@@ -0,0 +1,307 @@
+#include "test.h"
+
+#define operand_c JIT_OPERAND_ABI_INT8
+#define operand_s JIT_OPERAND_ABI_INT16
+#define operand_i JIT_OPERAND_ABI_INT32
+#define operand_uc JIT_OPERAND_ABI_UINT8
+#define operand_us JIT_OPERAND_ABI_UINT16
+#define operand_ui JIT_OPERAND_ABI_UINT32
+#define operand_l JIT_OPERAND_ABI_INT64
+#define operand_f JIT_OPERAND_ABI_FLOAT
+#define operand_d JIT_OPERAND_ABI_DOUBLE
+
+#define def_wi(i) \
+ void *_w##i = jit_address(_jit); \
+{ \
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0); \
+ jit_load_args_1(_jit, jit_operand_gpr(operand##i, JIT_R0)); \
+ jit_leave_jit_abi(_jit, 0, 0, frame); \
+ jit_retr(_jit, JIT_R0); \
+}
+
+#define def_wf(f) \
+ void *_w##f = jit_address(_jit); \
+{ \
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0); \
+ jit_load_args_1(_jit, jit_operand_fpr(operand##f, JIT_F0)); \
+ jit_truncr##f(_jit, JIT_R0, JIT_F0); \
+ jit_leave_jit_abi(_jit, 0, 0, frame); \
+ jit_retr(_jit, JIT_R0); \
+}
+
+#define def_fi(f, i) \
+ void *f##i = jit_address(_jit); \
+{ \
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0); \
+ jit_load_args_1(_jit, jit_operand_gpr(operand##i, JIT_R0)); \
+ jit_extr##f(_jit, JIT_F0, JIT_R0); \
+ jit_leave_jit_abi(_jit, 0, 0, frame); \
+ jit_retr##f(_jit, JIT_F0); \
+}
+
+#define def_f(f) \
+ void *f##f = jit_address(_jit); \
+{ \
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0); \
+ jit_load_args_1(_jit, jit_operand_fpr(operand##f, JIT_F0)); \
+ jit_leave_jit_abi(_jit, 0, 0, frame); \
+ jit_retr##f(_jit, JIT_F0); \
+}
+
+#define def_ff(f, g) \
+ void *f##g = jit_address(_jit); \
+{ \
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0); \
+ jit_load_args_1(_jit, jit_operand_fpr(operand##f, JIT_F0)); \
+ jit_extr##f##g(_jit, JIT_F0, JIT_F0); \
+ jit_leave_jit_abi(_jit, 0, 0, frame); \
+ jit_retr##g(_jit, JIT_F0); \
+}
+
+#if defined(DEBUG)
+#define dump_args(n, f, i, a, r) \
+ jit_calli_1(_jit, puts, \
+ jit_operand_imm(JIT_OPERAND_ABI_POINTER, \
+ (jit_imm_t)#n " " #f " " #i " " #a " " #r))
+#else
+#define dump_args(n, f, i, a, r)
+#endif
+
+#define _call_w(n, i, a, r) \
+{ \
+ dump_args(n, , i, a, r); \
+ jit_calli_1(_jit, _w##i, jit_operand_imm(operand##i, a)); \
+ jit_retval(_jit, JIT_R0); \
+ jit_extr##i(_jit, JIT_R0, JIT_R0); \
+ jit_reloc_t ok = jit_beqi(_jit, JIT_R0, r); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, ok); \
+}
+#define call_w(n, i, a, r) _call_w(n, i, a, r)
+
+#define _call_wf(n, f, a, r) \
+{ \
+ dump_args(n, f, , a, r); \
+ jit_movi##f(_jit, JIT_F0, (long long)a); \
+ jit_calli_1(_jit, _w##f, jit_operand_fpr(operand##f, JIT_F0)); \
+ jit_retval(_jit, JIT_R0); \
+ jit_extr##f(_jit, JIT_F0, JIT_R0); \
+ jit_movi##f(_jit, JIT_F1, r); \
+ jit_reloc_t ok = jit_beqr##f(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, ok); \
+}
+#define call_wf(n, f, a, r) _call_wf(n, f, a, r)
+
+#define _call_fi(n, f, i, a, r) \
+{ \
+ dump_args(n, f, i, a, r); \
+ jit_calli_1(_jit, f##i, jit_operand_imm(operand##i, a)); \
+ jit_retval##f(_jit, JIT_F0); \
+ jit_movi##f(_jit, JIT_F1, r); \
+ jit_reloc_t ok = jit_beqr##f(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, ok); \
+}
+#define call_fi(n, f, i, a, r) _call_fi(n, f, i, a, r)
+
+#define _call_f(n, f, a, r) \
+{ \
+ dump_args(n, f, , a, r); \
+ jit_movi##f(_jit, JIT_F0, a); \
+ jit_calli_1(_jit, f##f, jit_operand_fpr(operand##f, JIT_F0)); \
+ jit_retval##f(_jit, JIT_F0); \
+ jit_movi##f(_jit, JIT_F1, r); \
+ jit_reloc_t ok = jit_beqr##f(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, ok); \
+}
+#define call_f(n, f, a, r) _call_f(n, f, a, r)
+
+#define _call_ff(n, f, g, a, r) \
+{ \
+ dump_args(n, f, g, a, r); \
+ jit_movi##f(_jit, JIT_F0, a); \
+ jit_calli_1(_jit, f##g, jit_operand_fpr(operand##f, JIT_F0)); \
+ jit_retval##g(_jit, JIT_F0); \
+ jit_movi##g(_jit, JIT_F1, r); \
+ jit_reloc_t ok = jit_beqr##g(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, ok); \
+}
+#define call_ff(n, f, g, a, r) _call_ff(n, f, g, a, r)
+
+#define c7f (int8_t)0x7f
+#define c80 (int8_t)0x80
+#define c81 (int8_t)0x81
+#define cff (int8_t)0xff
+#define s7f (int16_t)0x7fff
+#define s80 (int16_t)0x8000
+#define s81 (int16_t)0x8001
+#define i7f (int32_t)0x7fffffff
+#define i80 (int32_t)0x80000000
+#define i81 (int32_t)0x80000001
+#define iff (int32_t)0xffffffff
+#define l7f (int64_t)0x7fffffffffffffff
+#define l80 (int64_t)0x8000000000000000
+#define l81 (int64_t)0x8000000000000001
+
+#define uc7f (uint8_t)0x7f
+#define uc80 (uint8_t)0x80
+#define uc81 (uint8_t)0x81
+#define ucff (uint8_t)0xff
+#define us7f (uint16_t)0x7fff
+#define us80 (uint16_t)0x8000
+#define us81 (uint16_t)0x8001
+#define ui7f (uint32_t)0x7fffffff
+#define ui80 (uint32_t)0x80000000
+#define ui81 (uint32_t)0x80000001
+#define uiff (uint32_t)0xffffffff
+#define ul7f (uint64_t)0x7fffffffffffffff
+#define ul80 (uint64_t)0x8000000000000000
+#define ul81 (uint64_t)0x8000000000000001
+
+#define f7f 127.0
+#define f80 -128.0
+#define f81 -127.0
+#define uf80 128.0
+#define uf81 127.0
+
+#if __WORDSIZE == 32
+# define wc80 (long)0xffffff80
+# define wc81 (long)0xffffff81
+# define ws80 (long)0xffff8000
+# define ws81 (long)0xffff8001
+#else
+# define wc80 (long)0xffffffffffffff80
+# define wc81 (long)0xffffffffffffff81
+# define ws80 (long)0xffffffffffff8000
+# define ws81 (long)0xffffffffffff8001
+# define wi80 (long)0xffffffff80000000
+# define wi81 (long)0xffffffff80000001
+#endif
+
+static size_t
+run_test(jit_state_t *_jit, uint8_t *arena_base, size_t arena_size)
+{
+ void (*function)();
+ jit_begin(_jit, arena_base, arena_size);
+ jit_reloc_t main = jit_jmp(_jit);
+
+ def_wi(_c)
+ def_wi(_uc)
+ def_wi(_s)
+ def_wi(_us)
+#if __WORDSIZE == 64
+ def_wi(_i)
+ def_wi(_ui)
+#endif
+ def_wf(_f)
+ def_wf(_d)
+ def_fi(_f, _c)
+ def_fi(_f, _uc)
+ def_fi(_f, _s)
+ def_fi(_f, _us)
+ def_fi(_f, _i)
+#if __WORDSIZE == 64
+ def_fi(_f, _ui)
+ def_fi(_f, _l)
+#endif
+ def_fi(_d, _c)
+ def_fi(_d, _uc)
+ def_fi(_d, _s)
+ def_fi(_d, _us)
+ def_fi(_d, _i)
+#if __WORDSIZE == 64
+ def_fi(_d, _ui)
+ def_fi(_d, _l)
+#endif
+ def_f(_f)
+ def_f(_d)
+ def_ff(_f, _d)
+ def_ff(_d, _f)
+
+ jit_patch_here(_jit, main);
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0);
+
+ call_w(__LINE__, _c, c7f, c7f)
+ call_w(__LINE__, _c, c80, wc80)
+ call_w(__LINE__, _c, c81, wc81)
+ call_w(__LINE__, _uc, uc7f, c7f)
+ call_w(__LINE__, _uc, uc80, uc80)
+ call_w(__LINE__, _uc, uc81, uc81)
+ call_w(__LINE__, _s, s7f, s7f)
+ call_w(__LINE__, _s, s80, ws80)
+ call_w(__LINE__, _s, s81, ws81)
+ call_w(__LINE__, _us, us7f, us7f)
+ call_w(__LINE__, _us, us80, us80)
+ call_w(__LINE__, _us, us81, us81)
+#if __WORDSIZE == 64
+ call_w(__LINE__, _i, i7f, i7f)
+ call_w(__LINE__, _i, i80, wi80)
+ call_w(__LINE__, _i, i81, wi81)
+ call_w(__LINE__, _ui, ui7f, ui7f)
+ call_w(__LINE__, _ui, ui80, ui80)
+ call_w(__LINE__, _ui, ui81, ui81)
+#endif
+ call_wf(__LINE__, _f, c7f, f7f)
+ call_wf(__LINE__, _f, wc80, f80)
+ call_wf(__LINE__, _f, wc81, f81)
+ call_wf(__LINE__, _d, c7f, f7f)
+ call_wf(__LINE__, _d, wc80, f80)
+ call_wf(__LINE__, _d, wc81, f81)
+ call_fi(__LINE__, _f, _c, c7f, f7f)
+ call_fi(__LINE__, _f, _c, c80, f80)
+ call_fi(__LINE__, _f, _uc, uc7f, f7f)
+ call_fi(__LINE__, _f, _uc, uc80, uf80)
+ call_fi(__LINE__, _f, _s, c7f, f7f)
+ call_fi(__LINE__, _f, _s, uc80, uf80)
+ call_fi(__LINE__, _f, _us, uc7f, f7f)
+ call_fi(__LINE__, _f, _us, uc80, uf80)
+ call_fi(__LINE__, _f, _i, c7f, f7f)
+ call_fi(__LINE__, _f, _i, uc80, uf80)
+#if __WORDSIZE == 64
+ call_fi(__LINE__, _f, _ui, uc7f, f7f)
+ call_fi(__LINE__, _f, _ui, uc80, uf80)
+ call_fi(__LINE__, _f, _l, c7f, f7f)
+ call_fi(__LINE__, _f, _l, uc80, uf80)
+#endif
+ call_fi(__LINE__, _d, _c, c7f, f7f)
+ call_fi(__LINE__, _d, _c, c80, f80)
+ call_fi(__LINE__, _d, _uc, uc7f, f7f)
+ call_fi(__LINE__, _d, _uc, uc80, uf80)
+ call_fi(__LINE__, _d, _s, c7f, f7f)
+ call_fi(__LINE__, _d, _s, uc80, uf80)
+ call_fi(__LINE__, _d, _us, uc7f, f7f)
+ call_fi(__LINE__, _d, _us, uc80, uf80)
+ call_fi(__LINE__, _d, _i, c7f, f7f)
+ call_fi(__LINE__, _d, _i, uc80, uf80)
+#if __WORDSIZE == 64
+ call_fi(__LINE__, _d, _ui, uc7f, f7f)
+ call_fi(__LINE__, _d, _ui, uc80, uf80)
+ call_fi(__LINE__, _d, _l, c7f, f7f)
+ call_fi(__LINE__, _d, _l, uc80, uf80)
+#endif
+ call_f(__LINE__, _f, f7f, f7f)
+ call_f(__LINE__, _d, f7f, f7f)
+ call_ff(__LINE__, _f, _d, f80, f80)
+ call_ff(__LINE__, _d, _f, f81, f81)
+
+ jit_leave_jit_abi(_jit, 0, 0, frame);
+ jit_ret(_jit);
+
+ size_t size = 0;
+ function = jit_end(_jit, &size);
+
+ if (function)
+ (*function)();
+ else
+ return size;
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return main_compiler(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/z_ccall.c b/deps/lightening/tests/z_ccall.c
new file mode 100644
index 0000000..ef2b17e
--- /dev/null
+++ b/deps/lightening/tests/z_ccall.c
@@ -0,0 +1,1000 @@
+#include "test.h"
+
+#define _QUOTE(x) #x
+#define QUOTE(x) _QUOTE(x)
+
+#if defined(DEBUG)
+#define dump_args(x) puts(x)
+#else
+#define dump_args(x)
+#endif
+
+#define _w0 0
+#define _w1 1
+#define _w2 (_w1-2)
+#define _w3 (_w2-3)
+#define _w4 (_w3-4)
+#define _w5 (_w4-5)
+#define _w6 (_w5-6)
+#define _w7 (_w6-7)
+#define _w8 (_w7-8)
+#define _w9 (_w8-9)
+#define _w10 (_w9-10)
+#define _w11 (_w10-11)
+#define _w12 (_w11-12)
+#define _w13 (_w12-13)
+#define _w14 (_w13-14)
+#define _w15 (_w14-15)
+#define _c0 _w0
+#define _c1 _w1
+#define _c2 _w2
+#define _c3 _w3
+#define _c4 _w4
+#define _c5 _w5
+#define _c6 _w6
+#define _c7 _w7
+#define _c8 _w8
+#define _c9 _w9
+#define _c10 _w10
+#define _c11 _w11
+#define _c12 _w12
+#define _c13 _w13
+#define _c14 _w14
+#define _c15 _w15
+#define _uc0 (_w0&0xff)
+#define _uc1 (_w1&0xff)
+#define _uc2 (_w2&0xff)
+#define _uc3 (_w3&0xff)
+#define _uc4 (_w4&0xff)
+#define _uc5 (_w5&0xff)
+#define _uc6 (_w6&0xff)
+#define _uc7 (_w7&0xff)
+#define _uc8 (_w8&0xff)
+#define _uc9 (_w9&0xff)
+#define _uc10 (_w10&0xff)
+#define _uc11 (_w11&0xff)
+#define _uc12 (_w12&0xff)
+#define _uc13 (_w13&0xff)
+#define _uc14 (_w14&0xff)
+#define _uc15 (_w15&0xff)
+#define _s0 _w0
+#define _s1 _w1
+#define _s2 _w2
+#define _s3 _w3
+#define _s4 _w4
+#define _s5 _w5
+#define _s6 _w6
+#define _s7 _w7
+#define _s8 _w8
+#define _s9 _w9
+#define _s10 _w10
+#define _s11 _w11
+#define _s12 _w12
+#define _s13 _w13
+#define _s14 _w14
+#define _s15 _w15
+#define _us0 (_w0&0xffff)
+#define _us1 (_w1&0xffff)
+#define _us2 (_w2&0xffff)
+#define _us3 (_w3&0xffff)
+#define _us4 (_w4&0xffff)
+#define _us5 (_w5&0xffff)
+#define _us6 (_w6&0xffff)
+#define _us7 (_w7&0xffff)
+#define _us8 (_w8&0xffff)
+#define _us9 (_w9&0xffff)
+#define _us10 (_w10&0xffff)
+#define _us11 (_w11&0xffff)
+#define _us12 (_w12&0xffff)
+#define _us13 (_w13&0xffff)
+#define _us14 (_w14&0xffff)
+#define _us15 (_w15&0xffff)
+#define _i0 _w0
+#define _i1 _w1
+#define _i2 _w2
+#define _i3 _w3
+#define _i4 _w4
+#define _i5 _w5
+#define _i6 _w6
+#define _i7 _w7
+#define _i8 _w8
+#define _i9 _w9
+#define _i10 _w10
+#define _i11 _w11
+#define _i12 _w12
+#define _i13 _w13
+#define _i14 _w14
+#define _i15 _w15
+#if __WORDSIZE == 64
+# define _ui0 (_w0&0xffffffff)
+# define _ui1 (_w1&0xffffffff)
+# define _ui2 (_w2&0xffffffff)
+# define _ui3 (_w3&0xffffffff)
+# define _ui4 (_w4&0xffffffff)
+# define _ui5 (_w5&0xffffffff)
+# define _ui6 (_w6&0xffffffff)
+# define _ui7 (_w7&0xffffffff)
+# define _ui8 (_w8&0xffffffff)
+# define _ui9 (_w9&0xffffffff)
+# define _ui10 (_w10&0xffffffff)
+# define _ui11 (_w11&0xffffffff)
+# define _ui12 (_w12&0xffffffff)
+# define _ui13 (_w13&0xffffffff)
+# define _ui14 (_w14&0xffffffff)
+# define _ui15 (_w15&0xffffffff)
+# define _l0 _w0
+# define _l1 _w1
+# define _l2 _w2
+# define _l3 _w3
+# define _l4 _w4
+# define _l5 _w5
+# define _l6 _w6
+# define _l7 _w7
+# define _l8 _w8
+# define _l9 _w9
+# define _l10 _w10
+# define _l11 _w11
+# define _l12 _w12
+# define _l13 _w13
+# define _l14 _w14
+# define _l15 _w15
+#endif
+
+/*
+ * Types
+ */
+typedef signed char _c;
+typedef unsigned char _uc;
+typedef signed short _s;
+typedef unsigned short _us;
+typedef signed int _i;
+#if __WORDSIZE == 64
+typedef unsigned int _ui;
+typedef jit_word_t _l;
+#endif
+typedef float _f;
+typedef double _d;
+
+#define prt0(T) T C##T##0(void);
+#define prt1(T) prt0(T) \
+ T C##T##1(T);
+#define prt2(T) prt1(T) \
+ T C##T##2(T,T);
+#define prt3(T) prt2(T) \
+ T C##T##3(T,T,T);
+#define prt4(T) prt3(T) \
+ T C##T##4(T,T,T,T);
+#define prt5(T) prt4(T) \
+ T C##T##5(T,T,T,T,T);
+#define prt6(T) prt5(T) \
+ T C##T##6(T,T,T,T,T,T);
+#define prt7(T) prt6(T) \
+ T C##T##7(T,T,T,T,T,T,T);
+#define prt8(T) prt7(T) \
+ T C##T##8(T,T,T,T,T,T,T,T);
+#define prt9(T) prt8(T) \
+ T C##T##9(T,T,T,T,T,T,T,T,T);
+#define prt10(T) prt9(T) \
+ T C##T##10(T,T,T,T,T,T,T,T,T,T);
+#define prt11(T) prt10(T) \
+ T C##T##11(T,T,T,T,T,T,T,T,T,T,T);
+#define prt12(T) prt11(T) \
+ T C##T##12(T,T,T,T,T,T,T,T,T,T,T,T);
+#define prt13(T) prt12(T) \
+ T C##T##13(T,T,T,T,T,T,T,T,T,T,T,T,T);
+#define prt14(T) prt13(T) \
+ T C##T##14(T,T,T,T,T,T,T,T,T,T,T,T,T,T);
+#define prt15(T) prt14(T) \
+ T C##T##15(T,T,T,T,T,T,T,T,T,T,T,T,T,T,T);
+#define prt(T) prt15(T)
+prt(_c)
+prt(_uc)
+prt(_s)
+prt(_us)
+prt(_i)
+#if __WORDSIZE == 64
+prt(_ui)
+prt(_l)
+#endif
+prt(_f)
+prt(_d)
+#undef prt
+#undef prt15
+#undef prt14
+#undef prt13
+#undef prt12
+#undef prt11
+#undef prt10
+#undef prt9
+#undef prt8
+#undef prt7
+#undef prt6
+#undef prt5
+#undef prt4
+#undef prt3
+#undef prt2
+#undef prt1
+#undef prt0
+
+#define prtn(N,T) T J##T##n(void);
+#define prt0(T) prtn(0,T)
+#define prt1(T) prt0(T) prtn(1,T)
+#define prt2(T) prt1(T) prtn(2,T)
+#define prt3(T) prt2(T) prtn(3,T)
+#define prt4(T) prt3(T) prtn(4,T)
+#define prt5(T) prt4(T) prtn(5,T)
+#define prt6(T) prt5(T) prtn(6,T)
+#define prt7(T) prt6(T) prtn(7,T)
+#define prt8(T) prt7(T) prtn(8,T)
+#define prt9(T) prt8(T) prtn(9,T)
+#define prt10(T) prt9(T) prtn(10,T)
+#define prt11(T) prt10(T) prtn(11,T)
+#define prt12(T) prt11(T) prtn(12,T)
+#define prt13(T) prt12(T) prtn(13,T)
+#define prt14(T) prt13(T) prtn(14,T)
+#define prt15(T) prt14(T) prtn(15,T)
+#define prt(T) prt15(T)
+prt(_c)
+prt(_uc)
+prt(_s)
+prt(_us)
+prt(_i)
+#if __WORDSIZE == 64
+prt(_ui)
+prt(_l)
+#endif
+prt(_f)
+prt(_d)
+#undef prt
+#undef prt15
+#undef prt14
+#undef prt13
+#undef prt12
+#undef prt11
+#undef prt10
+#undef prt9
+#undef prt8
+#undef prt7
+#undef prt6
+#undef prt5
+#undef prt4
+#undef prt3
+#undef prt2
+#undef prt1
+#undef prt0
+#undef prtn
+
+/*
+ * Initialization
+ */
+
+#define dat0(T) T (*j##T##0)(void);
+
+#define dat1(T) dat0(T) \
+ T (*j##T##1)(T);
+
+#define dat2(T) dat1(T) \
+ T (*j##T##2)(T,T);
+
+#define dat3(T) dat2(T) \
+ T (*j##T##3)(T,T,T);
+
+#define dat4(T) dat3(T) \
+ T (*j##T##4)(T,T,T,T);
+
+#define dat5(T) dat4(T) \
+ T (*j##T##5)(T,T,T,T,T);
+
+#define dat6(T) dat5(T) \
+ T (*j##T##6)(T,T,T,T,T,T);
+
+#define dat7(T) dat6(T) \
+ T (*j##T##7)(T,T,T,T,T,T,T);
+
+#define dat8(T) dat7(T) \
+ T (*j##T##8)(T,T,T,T,T,T,T,T);
+
+#define dat9(T) dat8(T) \
+ T (*j##T##9)(T,T,T,T,T,T,T,T,T);
+
+#define dat10(T) dat9(T) \
+ T (*j##T##10)(T,T,T,T,T,T,T,T,T,T);
+
+#define dat11(T) dat10(T) \
+ T (*j##T##11)(T,T,T,T,T,T,T,T,T,T,T);
+
+#define dat12(T) dat11(T) \
+ T (*j##T##12)(T,T,T,T,T,T,T,T,T,T,T,T);
+
+#define dat13(T) dat12(T) \
+ T (*j##T##13)(T,T,T,T,T,T,T,T,T,T,T,T,T);
+
+#define dat14(T) dat13(T) \
+ T (*j##T##14)(T,T,T,T,T,T,T,T,T,T,T,T,T,T);
+
+#define dat15(T) dat14(T) \
+ T (*j##T##15)(T,T,T,T,T,T,T,T,T,T,T,T,T,T,T);
+
+#define dat(T) dat15(T)
+dat(_c)
+dat(_uc)
+dat(_s)
+dat(_us)
+dat(_i)
+#if __WORDSIZE == 64
+dat(_ui)
+dat(_l)
+#endif
+dat(_f)
+dat(_d)
+#undef dat
+#undef dat15
+#undef dat14
+#undef dat13
+#undef dat12
+#undef dat11
+#undef dat10
+#undef dat9
+#undef dat8
+#undef dat7
+#undef dat6
+#undef dat5
+#undef dat4
+#undef dat3
+#undef dat2
+#undef dat1
+#undef dat0
+
+/*
+ * Implementation
+ */
+#define dcl0(T) \
+T C##T##0(void) \
+{ \
+ dump_args(QUOTE(C##T##0));\
+ return (0); \
+}
+#define dcl1(T) \
+dcl0(T) \
+T C##T##1(T A) \
+{ \
+ dump_args(QUOTE(C##T##1));\
+ return (A); \
+}
+#define dcl2(T) \
+dcl1(T) \
+T C##T##2(T A,T B) \
+{ \
+ dump_args(QUOTE(C##T##2));\
+ return (A-B); \
+}
+#define dcl3(T) \
+dcl2(T) \
+T C##T##3(T A,T B,T C) \
+{ \
+ dump_args(QUOTE(C##T##3));\
+ return (A-B-C); \
+}
+#define dcl4(T) \
+dcl3(T) \
+T C##T##4(T A,T B,T C,T D) \
+{ \
+ dump_args(QUOTE(C##T##4));\
+ return (A-B-C-D); \
+}
+#define dcl5(T) \
+dcl4(T) \
+T C##T##5(T A,T B,T C,T D,T E) \
+{ \
+ dump_args(QUOTE(C##T##5));\
+ return (A-B-C-D-E); \
+}
+#define dcl6(T) \
+dcl5(T) \
+T C##T##6(T A,T B,T C,T D,T E,T F) \
+{ \
+ dump_args(QUOTE(C##T##6));\
+ return (A-B-C-D-E-F); \
+}
+#define dcl7(T) \
+dcl6(T) \
+T C##T##7(T A,T B,T C,T D,T E,T F,T G) \
+{ \
+ dump_args(QUOTE(C##T##7));\
+ return (A-B-C-D-E-F-G); \
+}
+#define dcl8(T) \
+dcl7(T) \
+T C##T##8(T A,T B,T C,T D,T E,T F,T G,T H) \
+{ \
+ dump_args(QUOTE(C##T##8));\
+ return (A-B-C-D-E-F-G-H); \
+}
+#define dcl9(T) \
+dcl8(T) \
+T C##T##9(T A,T B,T C,T D,T E,T F,T G,T H,T I) \
+{ \
+ dump_args(QUOTE(C##T##9));\
+ return (A-B-C-D-E-F-G-H-I); \
+}
+#define dcl10(T) \
+dcl9(T) \
+T C##T##10(T A,T B,T C,T D,T E,T F,T G,T H,T I,T J) \
+{ \
+ dump_args(QUOTE(C##T##10));\
+ return (A-B-C-D-E-F-G-H-I-J); \
+}
+#define dcl11(T) \
+dcl10(T) \
+T C##T##11(T A,T B,T C,T D,T E,T F,T G,T H,T I,T J,T K) \
+{ \
+ dump_args(QUOTE(C##T##11));\
+ return (A-B-C-D-E-F-G-H-I-J-K); \
+}
+#define dcl12(T) \
+dcl11(T) \
+T C##T##12(T A,T B,T C,T D,T E,T F,T G,T H,T I,T J,T K,T L) \
+{ \
+ dump_args(QUOTE(C##T##12));\
+ return (A-B-C-D-E-F-G-H-I-J-K-L); \
+}
+#define dcl13(T) \
+dcl12(T) \
+T C##T##13(T A,T B,T C,T D,T E,T F,T G,T H,T I,T J,T K,T L,T M) \
+{ \
+ dump_args(QUOTE(C##T##13));\
+ return (A-B-C-D-E-F-G-H-I-J-K-L-M); \
+}
+#define dcl14(T) \
+dcl13(T) \
+T C##T##14(T A,T B,T C,T D,T E,T F,T G,T H,T I,T J,T K,T L,T M,T N) \
+{ \
+ dump_args(QUOTE(C##T##14));\
+ return (A-B-C-D-E-F-G-H-I-J-K-L-M-N); \
+}
+#define dcl15(T) \
+dcl14(T) \
+T C##T##15(T A,T B,T C,T D,T E,T F,T G,T H,T I,T J,T K,T L,T M,T N,T O) \
+{ \
+ dump_args(QUOTE(C##T##15));\
+ return (A-B-C-D-E-F-G-H-I-J-K-L-M-N-O); \
+}
+#define dcl(T) dcl15(T)
+dcl(_c)
+dcl(_uc)
+dcl(_s)
+dcl(_us)
+dcl(_i)
+#if __WORDSIZE == 64
+dcl(_ui)
+dcl(_l)
+#endif
+dcl(_f)
+dcl(_d)
+#undef dcl
+#undef dcl15
+#undef dcl14
+#undef dcl13
+#undef dcl12
+#undef dcl11
+#undef dcl10
+#undef dcl9
+#undef dcl8
+#undef dcl7
+#undef dcl6
+#undef dcl5
+#undef dcl4
+#undef dcl3
+#undef dcl2
+#undef dcl1
+#undef dcl0
+
+#define dcl0(T) \
+T CJ##T##0(void) \
+{ \
+ dump_args(QUOTE(CJ##T##0));\
+ return ((*j##T##0)()); \
+}
+#define dcl1(T) \
+dcl0(T) \
+T CJ##T##1(void) \
+{ \
+ dump_args(QUOTE(CJ##T##1));\
+ return ((*j##T##1)(1)); \
+}
+#define dcl2(T) \
+dcl1(T) \
+T CJ##T##2(void) \
+{ \
+ dump_args(QUOTE(CJ##T##2));\
+ return ((*j##T##2)(1,2)); \
+}
+#define dcl3(T) \
+dcl2(T) \
+T CJ##T##3(void) \
+{ \
+ dump_args(QUOTE(CJ##T##3));\
+ return ((*j##T##3)(1,2,3)); \
+}
+#define dcl4(T) \
+dcl3(T) \
+T CJ##T##4(void) \
+{ \
+ dump_args(QUOTE(CJ##T##4));\
+ return ((*j##T##4)(1,2,3,4)); \
+}
+#define dcl5(T) \
+dcl4(T) \
+T CJ##T##5(void) \
+{ \
+ dump_args(QUOTE(CJ##T##5));\
+ return ((*j##T##5)(1,2,3,4,5)); \
+}
+#define dcl6(T) \
+dcl5(T) \
+T CJ##T##6(void) \
+{ \
+ dump_args(QUOTE(CJ##T##6));\
+ return ((*j##T##6)(1,2,3,4,5,6)); \
+}
+#define dcl7(T) \
+dcl6(T) \
+T CJ##T##7(void) \
+{ \
+ dump_args(QUOTE(CJ##T##7));\
+ return ((*j##T##7)(1,2,3,4,5,6,7)); \
+}
+#define dcl8(T) \
+dcl7(T) \
+T CJ##T##8(void) \
+{ \
+ dump_args(QUOTE(CJ##T##8));\
+ return ((*j##T##8)(1,2,3,4,5,6,7,8)); \
+}
+#define dcl9(T) \
+dcl8(T) \
+T CJ##T##9(void) \
+{ \
+ dump_args(QUOTE(CJ##T##9));\
+ return ((*j##T##9)(1,2,3,4,5,6,7,8,9)); \
+}
+#define dcl10(T) \
+dcl9(T) \
+T CJ##T##10(void) \
+{ \
+ dump_args(QUOTE(CJ##T##10));\
+ return ((*j##T##10)(1,2,3,4,5,6,7,8,9,10)); \
+}
+#define dcl11(T) \
+dcl10(T) \
+T CJ##T##11(void) \
+{ \
+ dump_args(QUOTE(CJ##T##11));\
+ return ((*j##T##11)(1,2,3,4,5,6,7,8,9,10,11)); \
+}
+#define dcl12(T) \
+dcl11(T) \
+T CJ##T##12(void) \
+{ \
+ dump_args(QUOTE(CJ##T##12));\
+ return ((*j##T##12)(1,2,3,4,5,6,7,8,9,10,11,12)); \
+}
+#define dcl13(T) \
+dcl12(T) \
+T CJ##T##13(void) \
+{ \
+ dump_args(QUOTE(CJ##T##13));\
+ return ((*j##T##13)(1,2,3,4,5,6,7,8,9,10,11,12,13)); \
+}
+#define dcl14(T) \
+dcl13(T) \
+T CJ##T##14(void) \
+{ \
+ dump_args(QUOTE(CJ##T##14));\
+ return ((*j##T##14)(1,2,3,4,5,6,7,8,9,10,11,12,13,14)); \
+}
+#define dcl15(T) \
+dcl14(T) \
+T CJ##T##15(void) \
+{ \
+ dump_args(QUOTE(CJ##T##15));\
+ return ((*j##T##15)(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)); \
+}
+#define dcl(t) dcl15(t)
+dcl(_c)
+dcl(_uc)
+dcl(_s)
+dcl(_us)
+dcl(_i)
+#if __WORDSIZE == 64
+dcl(_ui)
+dcl(_l)
+#endif
+dcl(_f)
+dcl(_d)
+#undef dcl
+#undef dcl15
+#undef dcl14
+#undef dcl13
+#undef dcl12
+#undef dcl11
+#undef dcl10
+#undef dcl9
+#undef dcl8
+#undef dcl7
+#undef dcl6
+#undef dcl5
+#undef dcl4
+#undef dcl3
+#undef dcl2
+#undef dcl1
+#undef dcl0
+
+size_t
+run_test(jit_state_t *_jit, uint8_t *code_base, size_t code_size)
+{
+ jit_reloc_t jmpi_main;
+ void (*function)(void);
+ jit_reloc_t jmp;
+
+ jit_begin(_jit, code_base, code_size);
+
+ jmpi_main = jit_jmp(_jit);
+
+#define calc(B,T,R,O)\
+ jit_movr##B(_jit, R##1, R##0);\
+ jit_ldxi##T(_jit, R##0, JIT_SP, 8 * O);\
+ jit_subr##B(_jit, R##0, R##1, R##0);
+
+#define get0(B,T,R) jit_movi##B(_jit, R##0, 0);
+#define get1(B,T,R) jit_ldxi##T(_jit, R##0, JIT_SP, 8 * 0);
+#define get2(B,T,R) \
+ get1(B,T,R); \
+ calc(B,T,R,1);
+#define get3(B,T,R) \
+ get2(B,T,R); \
+ calc(B,T,R,2);
+#define get4(B,T,R) \
+ get3(B,T,R); \
+ calc(B,T,R,3);
+#define get5(B,T,R) \
+ get4(B,T,R); \
+ calc(B,T,R,4);
+#define get6(B,T,R) \
+ get5(B,T,R); \
+ calc(B,T,R,5);
+#define get7(B,T,R) \
+ get6(B,T,R); \
+ calc(B,T,R,6);
+#define get8(B,T,R) \
+ get7(B,T,R); \
+ calc(B,T,R,7);
+#define get9(B,T,R) \
+ get8(B,T,R); \
+ calc(B,T,R,8);
+#define get10(B,T,R) \
+ get9(B,T,R); \
+ calc(B,T,R,9);
+#define get11(B,T,R) \
+ get10(B,T,R); \
+ calc(B,T,R,10);
+#define get12(B,T,R) \
+ get11(B,T,R); \
+ calc(B,T,R,11);
+#define get13(B,T,R) \
+ get12(B,T,R); \
+ calc(B,T,R,12);
+#define get14(B,T,R) \
+ get13(B,T,R); \
+ calc(B,T,R,13);
+#define get15(B,T,R) \
+ get14(B,T,R); \
+ calc(B,T,R,14);
+
+#if __WORDSIZE == 32
+# define jit_extr_i(_jit, u, v) /**/
+#else
+# define jit_extr_l(_jit, u, v) /**/
+#endif
+
+#if __WORDSIZE == 64
+#define jit_stxi_ui(_jit, u, r0, r1) jit_stxi_i(_jit, u, r0, r1)
+#endif
+#define jit_stxi_us(_jit, u, r0, r1) jit_stxi_s(_jit, u, r0, r1)
+#define jit_stxi_uc(_jit, u, r0, r1) jit_stxi_c(_jit, u, r0, r1)
+
+#define abi_uc JIT_OPERAND_ABI_UINT8
+#define abi_c JIT_OPERAND_ABI_INT8
+#define abi_us JIT_OPERAND_ABI_UINT16
+#define abi_s JIT_OPERAND_ABI_INT16
+#define abi_ui JIT_OPERAND_ABI_UINT32
+#define abi_i JIT_OPERAND_ABI_INT32
+#define abi_ul JIT_OPERAND_ABI_UINT64
+#define abi_l JIT_OPERAND_ABI_INT64
+#define abi_f JIT_OPERAND_ABI_FLOAT
+#define abi_d JIT_OPERAND_ABI_DOUBLE
+
+#define store0(T) jit_operand_mem(JIT_OPERAND_ABI_UINT8, JIT_SP, 0)
+#define store1(T) jit_operand_mem(abi##T, JIT_SP, 0 * 8)
+#define store2(T) store1(T), jit_operand_mem(abi##T, JIT_SP, 1 * 8)
+#define store3(T) store2(T), jit_operand_mem(abi##T, JIT_SP, 2 * 8)
+#define store4(T) store3(T), jit_operand_mem(abi##T, JIT_SP, 3 * 8)
+#define store5(T) store4(T), jit_operand_mem(abi##T, JIT_SP, 4 * 8)
+#define store6(T) store5(T), jit_operand_mem(abi##T, JIT_SP, 5 * 8)
+#define store7(T) store6(T), jit_operand_mem(abi##T, JIT_SP, 6 * 8)
+#define store8(T) store7(T), jit_operand_mem(abi##T, JIT_SP, 7 * 8)
+#define store9(T) store8(T), jit_operand_mem(abi##T, JIT_SP, 8 * 8)
+#define store10(T) store9(T), jit_operand_mem(abi##T, JIT_SP, 9 * 8)
+#define store11(T) store10(T), jit_operand_mem(abi##T, JIT_SP, 10 * 8)
+#define store12(T) store11(T), jit_operand_mem(abi##T, JIT_SP, 11 * 8)
+#define store13(T) store12(T), jit_operand_mem(abi##T, JIT_SP, 12 * 8)
+#define store14(T) store13(T), jit_operand_mem(abi##T, JIT_SP, 13 * 8)
+#define store15(T) store14(T), jit_operand_mem(abi##T, JIT_SP, 14 * 8)
+
+// Placeholder, won't actually be used.
+#define load0(T) jit_operand_mem(JIT_OPERAND_ABI_INT8, JIT_SP, 0)
+#define load1(T) jit_operand_mem(abi##T, JIT_SP, 0 * 8)
+#define load2(T) load1(T), jit_operand_mem(abi##T, JIT_SP, 1 * 8)
+#define load3(T) load2(T), jit_operand_mem(abi##T, JIT_SP, 2 * 8)
+#define load4(T) load3(T), jit_operand_mem(abi##T, JIT_SP, 3 * 8)
+#define load5(T) load4(T), jit_operand_mem(abi##T, JIT_SP, 4 * 8)
+#define load6(T) load5(T), jit_operand_mem(abi##T, JIT_SP, 5 * 8)
+#define load7(T) load6(T), jit_operand_mem(abi##T, JIT_SP, 6 * 8)
+#define load8(T) load7(T), jit_operand_mem(abi##T, JIT_SP, 7 * 8)
+#define load9(T) load8(T), jit_operand_mem(abi##T, JIT_SP, 8 * 8)
+#define load10(T) load9(T), jit_operand_mem(abi##T, JIT_SP, 9 * 8)
+#define load11(T) load10(T), jit_operand_mem(abi##T, JIT_SP, 10 * 8)
+#define load12(T) load11(T), jit_operand_mem(abi##T, JIT_SP, 11 * 8)
+#define load13(T) load12(T), jit_operand_mem(abi##T, JIT_SP, 12 * 8)
+#define load14(T) load13(T), jit_operand_mem(abi##T, JIT_SP, 13 * 8)
+#define load15(T) load14(T), jit_operand_mem(abi##T, JIT_SP, 14 * 8)
+
+#define defi(T, N) \
+ { \
+ j##T##N = jit_address(_jit); \
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0); \
+ size_t stack = jit_align_stack(_jit, N * 8); \
+ jit_operand_t args[] = {store##N(T)}; \
+ jit_load_args(_jit, N, args); \
+ get##N(,T,JIT_R) \
+ jit_extr##T(_jit, JIT_R0, JIT_R0); \
+ jit_shrink_stack(_jit, stack); \
+ jit_leave_jit_abi(_jit, 0, 0, frame); \
+ jit_retr(_jit, JIT_R0); \
+ }
+
+#define deff(T, N) \
+ { \
+ j##T##N = jit_address(_jit); \
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0); \
+ size_t stack = jit_align_stack(_jit, N * 8); \
+ jit_operand_t args[] = {store##N(T)}; \
+ jit_load_args(_jit, N, args); \
+ get##N(T,T,JIT_F); \
+ jit_shrink_stack(_jit, stack); \
+ jit_leave_jit_abi(_jit, 0, 0, frame); \
+ jit_retr##T(_jit, JIT_F0); \
+ }
+
+#define def0(X, T) def##X(T, 0)
+#define def1(X, T) def0(X, T) def##X(T, 1)
+#define def2(X, T) def1(X, T) def##X(T, 2)
+#define def3(X, T) def2(X, T) def##X(T, 3)
+#define def4(X, T) def3(X, T) def##X(T, 4)
+#define def5(X, T) def4(X, T) def##X(T, 5)
+#define def6(X, T) def5(X, T) def##X(T, 6)
+#define def7(X, T) def6(X, T) def##X(T, 7)
+#define def8(X, T) def7(X, T) def##X(T, 8)
+#define def9(X, T) def8(X, T) def##X(T, 9)
+#define def10(X, T) def9(X, T) def##X(T, 10)
+#define def11(X, T) def10(X, T) def##X(T, 11)
+#define def12(X, T) def11(X, T) def##X(T, 12)
+#define def13(X, T) def12(X, T) def##X(T, 13)
+#define def14(X, T) def13(X, T) def##X(T, 14)
+#define def15(X, T) def14(X, T) def##X(T, 15)
+#define def(T) def15(i, T)
+ def(_c)
+ def(_uc)
+ def(_s)
+ def(_us)
+ def(_i)
+#if __WORDSIZE == 64
+ def(_ui)
+ def(_l)
+#endif
+#undef def
+#define def(T) def15(f, T)
+ def(_f)
+ def(_d)
+#undef def
+
+ jit_patch_here(_jit, jmpi_main);
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0);
+ size_t stack = jit_align_stack(_jit, 15 * 8);
+
+#define push0(B,T,R) /**/
+#define push1(B,T,R)\
+ jit_movi##B(_jit, R##0, 1);\
+ jit_stxi##T(_jit, 0 * 8, JIT_SP, R##0);
+
+#define push2(B,T,R)\
+ push1(B,T,R)\
+ jit_movi##B(_jit, R##0, 2);\
+ jit_stxi##T(_jit, 1 * 8, JIT_SP, R##0);
+
+#define push3(B,T,R)\
+ push2(B,T,R)\
+ jit_movi##B(_jit, R##0, 3);\
+ jit_stxi##T(_jit, 2 * 8, JIT_SP, R##0);
+
+#define push4(B,T,R)\
+ push3(B,T,R)\
+ jit_movi##B(_jit, R##0, 4);\
+ jit_stxi##T(_jit, 3 * 8, JIT_SP, R##0);
+
+#define push5(B,T,R)\
+ push4(B,T,R)\
+ jit_movi##B(_jit, R##0, 5);\
+ jit_stxi##T(_jit, 4 * 8, JIT_SP, R##0);
+
+#define push6(B,T,R)\
+ push5(B,T,R)\
+ jit_movi##B(_jit, R##0, 6);\
+ jit_stxi##T(_jit, 5 * 8, JIT_SP, R##0);
+
+#define push7(B,T,R)\
+ push6(B,T,R)\
+ jit_movi##B(_jit, R##0, 7);\
+ jit_stxi##T(_jit, 6 * 8, JIT_SP, R##0);
+
+#define push8(B,T,R)\
+ push7(B,T,R)\
+ jit_movi##B(_jit, R##0, 8);\
+ jit_stxi##T(_jit, 7 * 8, JIT_SP, R##0);
+
+#define push9(B,T,R)\
+ push8(B,T,R)\
+ jit_movi##B(_jit, R##0, 9);\
+ jit_stxi##T(_jit, 8 * 8, JIT_SP, R##0);
+
+#define push10(B,T,R)\
+ push9(B,T,R)\
+ jit_movi##B(_jit, R##0, 10);\
+ jit_stxi##T(_jit, 9 * 8, JIT_SP, R##0);
+
+#define push11(B,T,R)\
+ push10(B,T,R)\
+ jit_movi##B(_jit, R##0, 11);\
+ jit_stxi##T(_jit, 10 * 8, JIT_SP, R##0);
+
+#define push12(B,T,R)\
+ push11(B,T,R)\
+ jit_movi##B(_jit, R##0, 12);\
+ jit_stxi##T(_jit, 11 * 8, JIT_SP, R##0);
+
+#define push13(B,T,R)\
+ push12(B,T,R)\
+ jit_movi##B(_jit, R##0, 13);\
+ jit_stxi##T(_jit, 12 * 8, JIT_SP, R##0);
+
+#define push14(B,T,R)\
+ push13(B,T,R)\
+ jit_movi##B(_jit, R##0, 14);\
+ jit_stxi##T(_jit, 13 * 8, JIT_SP, R##0);
+
+#define push15(B,T,R)\
+ push14(B,T,R)\
+ jit_movi##B(_jit, R##0, 15);\
+ jit_stxi##T(_jit, 14 * 8, JIT_SP, R##0);
+
+#define calin(T,N) \
+ { \
+ push##N(, T, JIT_R) \
+ jit_operand_t args[] = {load##N(T)}; \
+ jit_calli(_jit, C##T##N, N, args); \
+ jit_retval##T(_jit, JIT_R0); \
+ jit_movi(_jit, JIT_R1, T##N); \
+ jmp = jit_beqr(_jit, JIT_R0, JIT_R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, jmp); \
+ }
+
+#define calfn(T,N) \
+ { \
+ push##N(T, T, JIT_F) \
+ jit_operand_t args[] = {load##N(T)}; \
+ jit_calli(_jit, C##T##N, N, args); \
+ jit_retval##T(_jit, JIT_F0); \
+ jit_movi##T(_jit, JIT_F1, _w##N); \
+ jmp = jit_beqr##T(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, jmp); \
+ }
+#define calx0(X,T) cal##X##n(T,0)
+#define calx1(X,T) calx0(X,T) cal##X##n(T,1)
+#define calx2(X,T) calx1(X,T) cal##X##n(T,2)
+#define calx3(X,T) calx2(X,T) cal##X##n(T,3)
+#define calx4(X,T) calx3(X,T) cal##X##n(T,4)
+#define calx5(X,T) calx4(X,T) cal##X##n(T,5)
+#define calx6(X,T) calx5(X,T) cal##X##n(T,6)
+#define calx7(X,T) calx6(X,T) cal##X##n(T,7)
+#define calx8(X,T) calx7(X,T) cal##X##n(T,8)
+#define calx9(X,T) calx8(X,T) cal##X##n(T,9)
+#define calx10(X,T) calx9(X,T) cal##X##n(T,10)
+#define calx11(X,T) calx10(X,T) cal##X##n(T,11)
+#define calx12(X,T) calx11(X,T) cal##X##n(T,12)
+#define calx13(X,T) calx12(X,T) cal##X##n(T,13)
+#define calx14(X,T) calx13(X,T) cal##X##n(T,14)
+#define calx15(X,T) calx14(X,T) cal##X##n(T,15)
+#define cali(T) calx15(i,T)
+#define calf(T) calx15(f,T)
+
+ cali(_c)
+ cali(_uc)
+ cali(_s)
+ cali(_us)
+ cali(_i)
+#if __WORDSIZE == 64
+ cali(_ui)
+ cali(_l)
+#endif
+ calf(_f)
+ calf(_d)
+
+#undef calin
+#undef calfn
+#define calin(T,N) \
+ { \
+ push##N(, T, JIT_R) \
+ jit_operand_t args[] = {load##N(T)}; \
+ jit_calli(_jit, CJ##T##N, N, args); \
+ jit_retval##T(_jit, JIT_R0); \
+ jit_movi(_jit, JIT_R1, T##N); \
+ jmp = jit_beqr(_jit, JIT_R0, JIT_R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, jmp); \
+ }
+
+#define calfn(T,N) \
+ { \
+ push##N(T, T, JIT_F) \
+ jit_operand_t args[] = {load##N(T)}; \
+ jit_calli(_jit, CJ##T##N, N, args); \
+ jit_retval##T(_jit, JIT_F0); \
+ jit_movi##T(_jit, JIT_F1, _w##N); \
+ jmp = jit_beqr##T(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, jmp); \
+ }
+
+ cali(_c)
+ cali(_uc)
+ cali(_s)
+ cali(_us)
+ cali(_i)
+#if __WORDSIZE == 64
+ cali(_ui)
+ cali(_l)
+#endif
+ calf(_f)
+ calf(_d)
+
+ jit_shrink_stack(_jit, stack);
+ jit_leave_jit_abi(_jit, 0, 0, frame);
+ jit_ret(_jit);
+
+ size_t size = 0;
+ function = jit_end(_jit, &size);
+
+ if (function)
+ (*function)();
+ else
+ return size;
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return main_compiler(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/z_clobber.c b/deps/lightening/tests/z_clobber.c
new file mode 100644
index 0000000..7503de7
--- /dev/null
+++ b/deps/lightening/tests/z_clobber.c
@@ -0,0 +1,1145 @@
+#include "test.h"
+
+/* do not bother about result of operations, only ensure valid arguments
+ * and that registers not modified by the operation are not clobbered */
+
+#define IV0 0x10000
+#define IV1 0x10001
+#define IV2 0x10002
+#define IV3 0x10003
+#define IV4 0x10004
+#define IV5 0x10005
+#define FV0 100.0
+#define FV1 101.0
+#define FV2 102.0
+#define FV3 103.0
+#define FV4 104.0
+#define FV5 105.0
+#define IR0 JIT_R0
+#define IR1 JIT_R1
+#define IR2 JIT_R2
+#define IR3 JIT_V0
+#define IR4 JIT_V1
+#define IR5 JIT_V2
+#define FR0 JIT_F0
+#define FR1 JIT_F1
+#define FR2 JIT_F2
+#define FR3 JIT_F3
+#define FR4 JIT_F4
+#define FR5 JIT_F5
+
+#define setup() \
+ jit_movi(_jit, JIT_R0, IV0); \
+ jit_movi(_jit, JIT_R1, IV1); \
+ jit_movi(_jit, JIT_R2, IV2); \
+ jit_movi(_jit, JIT_V0, IV3); \
+ jit_movi(_jit, JIT_V1, IV4); \
+ jit_movi(_jit, JIT_V2, IV5);
+
+#define setup_f() \
+ jit_movi_f(_jit, JIT_F0, FV0); \
+ jit_movi_f(_jit, JIT_F1, FV1); \
+ jit_movi_f(_jit, JIT_F2, FV2); \
+ jit_movi_f(_jit, JIT_F3, FV3); \
+ jit_movi_f(_jit, JIT_F4, FV4); \
+ jit_movi_f(_jit, JIT_F5, FV5);
+
+#define setup_d() \
+ jit_movi_d(_jit, JIT_F0, FV0); \
+ jit_movi_d(_jit, JIT_F1, FV1); \
+ jit_movi_d(_jit, JIT_F2, FV2); \
+ jit_movi_d(_jit, JIT_F3, FV3); \
+ jit_movi_d(_jit, JIT_F4, FV4); \
+ jit_movi_d(_jit, JIT_F5, FV5);
+
+#define check(label, rn) \
+{ \
+ jit_reloc_t r = jit_beqi(_jit, IR##rn, IV##rn); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define check1(k, l, i0) \
+ check(k##l##i0##_0, i0)
+
+#define check2(k, l, i0, i1) \
+ check(k##l##i0##i1##_0, i0) \
+ check(k##l##i0##i1##_1, i1)
+
+#define check3(k, l, i0, i1, i2) \
+ check(k##l##i0##i1##i2##_0, i0) \
+ check(k##l##i0##i1##i2##_1, i1) \
+ check(k##l##i0##i1##i2##_2, i2)
+
+#define check4(k, l, i0, i1, i2, i3) \
+ check(k##l##i0##i1##i2##i3##_0, i0) \
+ check(k##l##i0##i1##i2##i3##_1, i1) \
+ check(k##l##i0##i1##i2##i3##_2, i2) \
+ check(k##l##i0##i1##i2##i3##_3, i3)
+
+#define check5(k, l, i0, i1, i2, i3, i4) \
+ check(k##l##i0##i1##i2##i3##i4##_0, i0) \
+ check(k##l##i0##i1##i2##i3##i4##_1, i1) \
+ check(k##l##i0##i1##i2##i3##i3##_2, i2) \
+ check(k##l##i0##i1##i2##i3##i4##_3, i3) \
+ check(k##l##i0##i1##i2##i3##i4##_4, i4)
+
+#define check6(k, l, i0, i1, i2, i3, i4, i5) \
+ check(k##l##i0##i1##i2##i3##i4##i5##_0, i0) \
+ check(k##l##i0##i1##i2##i3##i4##i5##_1, i1) \
+ check(k##l##i0##i1##i2##i3##i3##i5##_2, i2) \
+ check(k##l##i0##i1##i2##i3##i4##i5##_3, i3) \
+ check(k##l##i0##i1##i2##i3##i4##i5##_4, i4) \
+ check(k##l##i0##i1##i2##i3##i4##i5##_5, i5)
+
+/* slightly hacky, lightning only uses JIT_F0-F5, and since all lightening
+ * platforms (at least at the moment) support JIT_F6, we can use it as a
+ * temporary register to get the value to compare agains in to the beqrf.
+ */
+#define checkf(f, label, rn) \
+{ \
+ jit_movi##f(_jit, JIT_F6, FV##rn); \
+ jit_reloc_t r = jit_beqr##f(_jit, FR##rn, JIT_F6); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define checkf1(f, k, l, i0) \
+ checkf(f, f##k##l##i0##_0, i0)
+
+#define checkf2(f, k, l, i0, i1) \
+ checkf(f, f##k##l##i0##i1##_0, i0) \
+ checkf(f, f##k##l##i0##i1##_1, i1)
+
+#define checkf3(f, k, l, i0, i1, i2) \
+ checkf(f, f##k##l##i0##i1##i2##_0, i0) \
+ checkf(f, f##k##l##i0##i1##i2##_1, i1) \
+ checkf(f, f##k##l##i0##i1##i2##_2, i2)
+
+#define checkf4(f, k, l, i0, i1, i2, i3) \
+ checkf(f, f##k##l##i0##i1##i2##i3##_0, i0) \
+ checkf(f, f##k##l##i0##i1##i2##i3##_1, i1) \
+ checkf(f, f##k##l##i0##i1##i2##i3##_2, i2) \
+ checkf(f, f##k##l##i0##i1##i2##i3##_3, i3)
+
+#define checkf5(f, k, l, i0, i1, i2, i3, i4) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i4##_0, i0) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i4##_1, i1) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i3##_2, i2) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i4##_3, i3) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i4##_4, i4)
+
+#define checkf6(f, k, l, i0, i1, i2, i3, i4, i5) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i4##i5##_0, i0) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i4##i5##_1, i1) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i3##i5##_2, i2) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i4##i5##_3, i3) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i4##i5##_4, i4) \
+ checkf(f, f##k##l##i0##i1##i2##i3##i4##i5##_5, i5)
+
+#define alui(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_##op##i(_jit, IR##i1, IR##i0, 1); \
+ check4(i, l, i2, i3, i4, i5)
+
+#define aluic(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_##op##i(_jit, IR##i0, IR##i0, 1); \
+ check5(ic, l, i1, i2, i3, i4, i5)
+
+#define alur(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_movi(_jit, IR##i1, 1); \
+ jit_##op##r(_jit, IR##i2, IR##i0, IR##i1); \
+ check3(r, l, i3, i4, i5)
+
+#define alurc0(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_movi(_jit, IR##i1, 1); \
+ jit_##op##r(_jit, IR##i0, IR##i0, IR##i1); \
+ check4(r0, l, i2, i3, i4, i5)
+
+#define alurc1(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_movi(_jit, IR##i1, 1); \
+ jit_##op##r(_jit, IR##i1, IR##i0, IR##i1); \
+ check4(r1, l, i2, i3, i4, i5)
+
+#define alurc2(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_##op##r(_jit, IR##i0, IR##i0, IR##i0); \
+ check5(r2, l, i1, i2, i3, i4, i5)
+
+#define xalu(l, op, i0, i1, i2, i3, i4, i5) \
+ alui(l, op, i0, i1, i2, i3, i4, i5) \
+ aluic(l, op, i0, i1, i2, i3, i4, i5) \
+ alur(l, op, i0, i1, i2, i3, i4, i5) \
+ alurc0(l, op, i0, i1, i2, i3, i4, i5) \
+ alurc1(l, op, i0, i1, i2, i3, i4, i5) \
+ alurc2(l, op, i0, i1, i2, i3, i4, i5)
+
+#if __ia64__
+# define alu(l, op) \
+ xalu(l, op, 0, 1, 2, 3, 4, 5)
+#else
+# define alu(l, op) \
+ xalu(l, op, 0, 1, 2, 3, 4, 5) \
+ xalu(l, op, 1, 2, 3, 4, 5, 0) \
+ xalu(l, op, 2, 3, 4, 5, 0, 1) \
+ xalu(l, op, 3, 4, 5, 0, 1, 2) \
+ xalu(l, op, 4, 5, 0, 1, 2, 3) \
+ xalu(l, op, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define fopi(f, l, op, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1.0); \
+ jit_movi##f(_jit, JIT_F6, 1.0); \
+ jit_##op##r##f(_jit, FR##f1, FR##f0, JIT_F6); \
+ checkf4(f, i, l, f2, f3, f4, f5)
+
+#define fopic(f, l, op, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1.0); \
+ jit_movi##f(_jit, JIT_F6, 1.0); \
+ jit_##op##r##f(_jit, FR##f0, FR##f0, JIT_F6); \
+ checkf5(f, ic, l, f1, f2, f3, f4, f5)
+
+#define fopr(f, l, op, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1.0); \
+ jit_movi##f(_jit, FR##f1, 1.0); \
+ jit_##op##r##f(_jit, FR##f2, FR##f0, FR##f1); \
+ checkf3(f, r, l, f3, f4, f5)
+
+#define foprc0(f, l, op, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1.0); \
+ jit_movi##f(_jit, FR##f1, 1.0); \
+ jit_##op##r##f(_jit, FR##f0, FR##f0, FR##f1); \
+ checkf4(f, r0, l, f2, f3, f4, f5)
+
+#define foprc1(f, l, op, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1.0); \
+ jit_movi##f(_jit, FR##f1, 1.0); \
+ jit_##op##r##f(_jit, FR##f1, FR##f0, FR##f1); \
+ checkf4(f, r1, l, f2, f3, f4, f5)
+
+#define foprc2(f, l, op, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1.0); \
+ jit_##op##r##f(_jit, FR##f0, FR##f0, FR##f0); \
+ checkf5(f, r2, l, f1, f2, f3, f4, f5)
+
+#define xfop(f, l, op, f0, f1, f2, f3, f4, f5) \
+ fopi(f, l, op, f0, f1, f2, f3, f4, f5) \
+ fopic(f, l, op, f0, f1, f2, f3, f4, f5) \
+ fopr(f, l, op, f0, f1, f2, f3, f4, f5) \
+ foprc0(f, l, op, f0, f1, f2, f3, f4, f5) \
+ foprc1(f, l, op, f0, f1, f2, f3, f4, f5) \
+ foprc2(f, l, op, f0, f1, f2, f3, f4, f5)
+#if __ia64__
+# define xxfop(l, op, f, f0, f1, f2, f3, f4, f5) \
+ xfop(_f, l, op, f0, f1, f2, f3, f4, f5)
+#else
+# define xxfop(l, op, f, f0, f1, f2, f3, f4, f5) \
+ xfop(_f, l, op, f0, f1, f2, f3, f4, f5) \
+ xfop(_d, l, op, f0, f1, f2, f3, f4, f5)
+#endif
+#if __ia64__
+# define fop(l, op) \
+ xxfop(l, op, f, 0, 1, 2, 3, 4, 5)
+#else
+# define fop(l, op) \
+ xxfop(l, op, f, 0, 1, 2, 3, 4, 5) \
+ xxfop(l, op, f, 1, 2, 3, 4, 5, 0) \
+ xxfop(l, op, f, 2, 3, 4, 5, 0, 1) \
+ xxfop(l, op, f, 3, 4, 5, 0, 1, 2) \
+ xxfop(l, op, f, 4, 5, 0, 1, 2, 3) \
+ xxfop(l, op, f, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define aluxii(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_##op##ci(_jit, IR##i1, IR##i0, 1); \
+ jit_##op##xi(_jit, IR##i2, IR##i0, 1); \
+ check3(ii, l, i3, i4, i5)
+
+#define aluxir(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_##op##ci(_jit, IR##i1, IR##i0, 1); \
+ jit_##op##xr(_jit, IR##i2, IR##i0, IR##i1); \
+ check3(ir, l, i3, i4, i5)
+
+#define aluxri(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_movi(_jit, IR##i1, 1); \
+ jit_##op##cr(_jit, IR##i2, IR##i0, IR##i1); \
+ jit_##op##xi(_jit, IR##i0, IR##i1, 1); \
+ check3(ri, l, i3, i4, i5)
+
+#define aluxrr(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_movi(_jit, IR##i1, 1); \
+ jit_##op##cr(_jit, IR##i2, IR##i0, IR##i1); \
+ jit_##op##xr(_jit, IR##i2, IR##i0, IR##i1); \
+ check3(rr, l, i3, i4, i5)
+
+#define xalux(l, op, i0, i1, i2, i3, i4, i5) \
+ aluxii(l, op, i0, i1, i2, i3, i4, i5) \
+ aluxir(l, op, i0, i1, i2, i3, i4, i5) \
+ aluxri(l, op, i0, i1, i2, i3, i4, i5) \
+ aluxrr(l, op, i0, i1, i2, i3, i4, i5)
+#if __ia64__
+# define alux(l, op) \
+ xalux(l, op, 0, 1, 2, 3, 4, 5)
+#else
+# define alux(l, op) \
+ xalux(l, op, 0, 1, 2, 3, 4, 5) \
+ xalux(l, op, 1, 2, 3, 4, 5, 0) \
+ xalux(l, op, 2, 3, 4, 5, 0, 1) \
+ xalux(l, op, 3, 4, 5, 0, 1, 2) \
+ xalux(l, op, 4, 5, 0, 1, 2, 3) \
+ xalux(l, op, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define alui_u(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_##op##i_u(_jit, IR##i1, IR##i0, 1); \
+ check4(i_u, l, i2, i3, i4, i5)
+
+#define aluic_u(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_##op##i_u(_jit, IR##i0, IR##i0, 1); \
+ check5(ic_u, l, i1, i2, i3, i4, i5)
+
+#define alur_u(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_movi(_jit, IR##i1, 1); \
+ jit_##op##r_u(_jit, IR##i2, IR##i0, IR##i1); \
+ check3(r_u, l, i3, i4, i5)
+
+#define alurc0_u(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_movi(_jit, IR##i1, 1); \
+ jit_##op##r_u(_jit, IR##i0, IR##i0, IR##i1); \
+ check4(r0_u, l, i2, i3, i4, i5)
+
+#define alurc1_u(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_movi(_jit, IR##i1, 1); \
+ jit_##op##r_u(_jit, IR##i1, IR##i0, IR##i1); \
+ check4(r1_u, l, i2, i3, i4, i5)
+
+#define alurc2_u(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_##op##r_u(_jit, IR##i0, IR##i0, IR##i0); \
+ check5(r2_u, l, i1, i2, i3, i4, i5)
+
+#define xalu_u(l, op, i0, i1, i2, i3, i4, i5) \
+ alui_u(l, op, i0, i1, i2, i3, i4, i5) \
+ aluic_u(l, op, i0, i1, i2, i3, i4, i5) \
+ alur_u(l, op, i0, i1, i2, i3, i4, i5) \
+ alurc0_u(l, op, i0, i1, i2, i3, i4, i5) \
+ alurc1_u(l, op, i0, i1, i2, i3, i4, i5) \
+ alurc2_u(l, op, i0, i1, i2, i3, i4, i5)
+#if __ia64__
+# define alu_u(l, op) \
+ xalu_u(l, op, 0, 1, 2, 3, 4, 5)
+#else
+# define alu_u(l, op) \
+ xalu_u(l, op, 0, 1, 2, 3, 4, 5) \
+ xalu_u(l, op, 1, 2, 3, 4, 5, 0) \
+ xalu_u(l, op, 2, 3, 4, 5, 0, 1) \
+ xalu_u(l, op, 3, 4, 5, 0, 1, 2) \
+ xalu_u(l, op, 4, 5, 0, 1, 2, 3) \
+ xalu_u(l, op, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define unir(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_##op(_jit, IR##i1, IR##i0); \
+ check4(rr, l, i2, i3, i4, i5)
+
+#define unirc(l, op, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ jit_##op(_jit, IR##i0, IR##i0); \
+ check5(rc, l, i1, i2, i3, i4, i5)
+
+#define xuni(l, op, i0, i1, i2, i3, i4, i5) \
+ unir(l, op, i0, i1, i2, i3, i4, i5) \
+ unirc(l, op, i0, i1, i2, i3, i4, i5)
+#if __ia64__
+# define uni(l, op) \
+ xuni(l, op, 0, 1, 2, 3, 4, 5)
+#else
+# define uni(l, op) \
+ xuni(l, op, 0, 1, 2, 3, 4, 5) \
+ xuni(l, op, 1, 2, 3, 4, 5, 0) \
+ xuni(l, op, 2, 3, 4, 5, 0, 1) \
+ xuni(l, op, 3, 4, 5, 0, 1, 2) \
+ xuni(l, op, 4, 5, 0, 1, 2, 3) \
+ xuni(l, op, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define unfr(f, l, op, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1); \
+ jit_##op##f(_jit, FR##f1, FR##f0); \
+ checkf4(f, rr, l, f2, f3, f4, f5)
+
+#define unfrc(f, l, op, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1); \
+ jit_##op##f(_jit, FR##f0, FR##f0); \
+ checkf5(f, rc, l, f1, f2, f3, f4, f5)
+
+#define xunf(f, l, op, f0, f1, f2, f3, f4, f5) \
+ unfr(f, l, op, f0, f1, f2, f3, f4, f5) \
+ unfrc(f, l, op, f0, f1, f2, f3, f4, f5)
+#define xxunf(l, op, f0, f1, f2, f3, f4, f5) \
+ xunf(_f, l, op, f0, f1, f2, f3, f4, f5) \
+ xunf(_d, l, op, f0, f1, f2, f3, f4, f5)
+#if __ia64__
+# define unf(l, op) \
+ xxunf(l, op, 0, 1, 2, 3, 4, 5)
+#else
+# define unf(l, op) \
+ xxunf(l, op, 0, 1, 2, 3, 4, 5) \
+ xxunf(l, op, 1, 2, 3, 4, 5, 0) \
+ xxunf(l, op, 2, 3, 4, 5, 0, 1) \
+ xxunf(l, op, 3, 4, 5, 0, 1, 2) \
+ xxunf(l, op, 4, 5, 0, 1, 2, 3) \
+ xxunf(l, op, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define fcpi(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1.0); \
+ jit_movi##f(_jit, JIT_F6, 1.0); \
+ jit_##op##r##f(_jit, IR##r0, FR##f0, JIT_F6); \
+ check5(i##f##f0, l, r1, r2, r3, r4, r5) \
+ checkf5(f, i##r0, l, f1, f2, f3, f4, f5)
+
+#define fcpr(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1.0); \
+ jit_movi##f(_jit, FR##f1, 1.0); \
+ jit_##op##r##f(_jit, IR##r0, FR##f0, FR##f1); \
+ check5(r##f##f0, l, r1, r2, r3, r4, r5) \
+ checkf4(f, r##r0, l, f2, f3, f4, f5)
+
+#define fcprc(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1.0); \
+ jit_##op##r##f(_jit, IR##r0, FR##f0, FR##f0); \
+ check5(rc##f##f0, l, r1, r2, r3, r4, r5) \
+ checkf5(f, rc##r0, l, f1, f2, f3, f4, f5)
+
+#if __ia64__
+# define ifcp(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fcpi(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+#else
+# define ifcp(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fcpi(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fcpr(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fcprc(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fcpi(f, l, op, r1,r2,r3,r4,r5,r0, f0,f1,f2,f3,f4,f5) \
+ fcpr(f, l, op, r1,r2,r3,r4,r5,r0, f0,f1,f2,f3,f4,f5) \
+ fcprc(f, l, op, r1,r2,r3,r4,r5,r0, f0,f1,f2,f3,f4,f5) \
+ fcpi(f, l, op, r2,r3,r4,r5,r0,r1, f0,f1,f2,f3,f4,f5) \
+ fcpr(f, l, op, r2,r3,r4,r5,r0,r1, f0,f1,f2,f3,f4,f5) \
+ fcprc(f, l, op, r2,r3,r4,r5,r0,r1, f0,f1,f2,f3,f4,f5) \
+ fcpi(f, l, op, r3,r4,r5,r0,r1,r2, f0,f1,f2,f3,f4,f5) \
+ fcpr(f, l, op, r3,r4,r5,r0,r1,r2, f0,f1,f2,f3,f4,f5) \
+ fcprc(f, l, op, r3,r4,r5,r0,r1,r2, f0,f1,f2,f3,f4,f5) \
+ fcpi(f, l, op, r4,r5,r0,r1,r2,r3, f0,f1,f2,f3,f4,f5) \
+ fcpr(f, l, op, r4,r5,r0,r1,r2,r3, f0,f1,f2,f3,f4,f5) \
+ fcprc(f, l, op, r4,r5,r0,r1,r2,r3, f0,f1,f2,f3,f4,f5) \
+ fcpi(f, l, op, r5,r0,r1,r2,r3,r4, f0,f1,f2,f3,f4,f5) \
+ fcpr(f, l, op, r5,r0,r1,r2,r3,r4, f0,f1,f2,f3,f4,f5) \
+ fcprc(f, l, op, r5,r0,r1,r2,r3,r4, f0,f1,f2,f3,f4,f5)
+#endif
+#if __ia64__
+# define xfcp(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ ifcp(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+#else
+# define xfcp(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ ifcp(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ ifcp(f, l, op, r0,r1,r2,r3,r4,r5, f1,f2,f3,f4,f5,f0) \
+ ifcp(f, l, op, r0,r1,r2,r3,r4,r5, f2,f3,f4,f5,f0,f1) \
+ ifcp(f, l, op, r0,r1,r2,r3,r4,r5, f3,f4,f5,f0,f1,f2) \
+ ifcp(f, l, op, r0,r1,r2,r3,r4,r5, f4,f5,f0,f1,f2,f3) \
+ ifcp(f, l, op, r0,r1,r2,r3,r4,r5, f5,f0,f1,f2,f3,f4)
+#endif
+#if __ia64__
+# define fcmp(l, op) \
+ xfcp(_f, l, op, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5)
+#else
+# define fcmp(l, op) \
+ xfcp(_f, l, op, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5) \
+ xfcp(_d, l, op, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5)
+#endif
+
+#define imvi(l, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i0, 1); \
+ check5(i, l, i1, i2, i3, i4, i5)
+
+#define imvr(l, i0, i1, i2, i3, i4, i5) \
+ setup() \
+ jit_movi(_jit, IR##i1, 1); \
+ jit_movr(_jit, IR##i0, IR##i1); \
+ check4(r, l, i2, i3, i4, i5)
+
+#define xmvi(l, i0, i1, i2, i3, i4, i5) \
+ imvi(l, i0, i1, i2, i3, i4, i5) \
+ imvr(l, i0, i1, i2, i3, i4, i5)
+#if __ia64__
+# define mvi(l) \
+ xmvi(l, 0, 1, 2, 3, 4, 5)
+#else
+# define mvi(l) \
+ xmvi(l, 0, 1, 2, 3, 4, 5) \
+ xmvi(l, 1, 2, 3, 4, 5, 0) \
+ xmvi(l, 2, 3, 4, 5, 0, 1) \
+ xmvi(l, 3, 4, 5, 0, 1, 2) \
+ xmvi(l, 4, 5, 0, 1, 2, 3) \
+ xmvi(l, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define fmvi(f, l, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1); \
+ checkf5(f, i, l, f1, f2, f3, f4, f5)
+
+#define fmvr(f, l, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f1, 1); \
+ jit_movr##f(_jit, FR##f0, FR##f1); \
+ checkf4(f, r, l, f2, f3, f4, f5)
+
+#define xmvf(f, l, f0, f1, f2, f3, f4, f5) \
+ fmvi(f, l, f0, f1, f2, f3, f4, f5) \
+ fmvr(f, l, f0, f1, f2, f3, f4, f5)
+#if __ia64__
+# define xxmvf(f, l) \
+ xmvf(f, l, 0, 1, 2, 3, 4, 5)
+#else
+# define xxmvf(f, l) \
+ xmvf(f, l, 0, 1, 2, 3, 4, 5) \
+ xmvf(f, l, 1, 2, 3, 4, 5, 0) \
+ xmvf(f, l, 2, 3, 4, 5, 0, 1) \
+ xmvf(f, l, 3, 4, 5, 0, 1, 2) \
+ xmvf(f, l, 4, 5, 0, 1, 2, 3) \
+ xmvf(f, l, 5, 0, 1, 2, 3, 4)
+#endif
+#define mvf(l) \
+ xxmvf(_f, l) \
+ xxmvf(_d, l)
+
+#define f2fr(f, l, op, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1); \
+ jit_##op(_jit, FR##f1, FR##f0); \
+ checkf4(f, rr, l, f2, f3, f4, f5)
+
+#define f2frc(f, l, op, f0, f1, f2, f3, f4, f5) \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1); \
+ jit_##op(_jit, FR##f0, FR##f0); \
+ checkf5(f, rc, l, f1, f2, f3, f4, f5)
+
+#define xf2f(f, l, op, f0, f1, f2, f3, f4, f5) \
+ f2fr(f, l, op, f0, f1, f2, f3, f4, f5) \
+ f2frc(f, l, op, f0, f1, f2, f3, f4, f5)
+#if __ia64__
+# define f2f(l, f, op) \
+ xf2f(f, l, op, 0, 1, 2, 3, 4, 5)
+#else
+# define f2f(l, f, op) \
+ xf2f(f, l, op, 0, 1, 2, 3, 4, 5) \
+ xf2f(f, l, op, 1, 2, 3, 4, 5, 0) \
+ xf2f(f, l, op, 2, 3, 4, 5, 0, 1) \
+ xf2f(f, l, op, 3, 4, 5, 0, 1, 2) \
+ xf2f(f, l, op, 4, 5, 0, 1, 2, 3) \
+ xf2f(f, l, op, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define f2ir(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, 1); \
+ jit_##op##f(_jit, IR##r0, FR##f0); \
+ check5(r##f##f0, l, r1, r2, r3, r4, r5) \
+ checkf5(f, i##r0, l, f1, f2, f3, f4, f5)
+
+#if __ia64__
+# define if2i(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ f2ir(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+# define xf2i(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ if2i(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+#else
+# define if2i(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ f2ir(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ f2ir(f, l, op, r1,r2,r3,r4,r5,r0, f0,f1,f2,f3,f4,f5) \
+ f2ir(f, l, op, r2,r3,r4,r5,r0,r1, f0,f1,f2,f3,f4,f5) \
+ f2ir(f, l, op, r3,r4,r5,r0,r1,r2, f0,f1,f2,f3,f4,f5) \
+ f2ir(f, l, op, r4,r5,r0,r1,r2,r3, f0,f1,f2,f3,f4,f5) \
+ f2ir(f, l, op, r5,r0,r1,r2,r3,r4, f0,f1,f2,f3,f4,f5)
+# define xf2i(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ if2i(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ if2i(f, l, op, r0,r1,r2,r3,r4,r5, f1,f2,f3,f4,f5,f0) \
+ if2i(f, l, op, r0,r1,r2,r3,r4,r5, f2,f3,f4,f5,f0,f1) \
+ if2i(f, l, op, r0,r1,r2,r3,r4,r5, f3,f4,f5,f0,f1,f2) \
+ if2i(f, l, op, r0,r1,r2,r3,r4,r5, f4,f5,f0,f1,f2,f3) \
+ if2i(f, l, op, r0,r1,r2,r3,r4,r5, f5,f0,f1,f2,f3,f4)
+#endif
+#define f2i(l, op) \
+ xf2i(_f, l, op, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5) \
+ xf2i(_d, l, op, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5)
+
+#define i2fr(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi(_jit, IR##r0, 1); \
+ jit_##op##f(_jit, FR##f0, IR##r0); \
+ check5(r##f##f0, l, r1, r2, r3, r4, r5) \
+ checkf5(f, i##r0, l, f1, f2, f3, f4, f5)
+#if __ia64__
+# define ii2f(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ i2fr(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+# define xi2f(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ ii2f(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+#else
+# define ii2f(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ i2fr(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ i2fr(f, l, op, r1,r2,r3,r4,r5,r0, f0,f1,f2,f3,f4,f5) \
+ i2fr(f, l, op, r2,r3,r4,r5,r0,r1, f0,f1,f2,f3,f4,f5) \
+ i2fr(f, l, op, r3,r4,r5,r0,r1,r2, f0,f1,f2,f3,f4,f5) \
+ i2fr(f, l, op, r4,r5,r0,r1,r2,r3, f0,f1,f2,f3,f4,f5) \
+ i2fr(f, l, op, r5,r0,r1,r2,r3,r4, f0,f1,f2,f3,f4,f5)
+# define xi2f(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ ii2f(f, l, op, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ ii2f(f, l, op, r0,r1,r2,r3,r4,r5, f1,f2,f3,f4,f5,f0) \
+ ii2f(f, l, op, r0,r1,r2,r3,r4,r5, f2,f3,f4,f5,f0,f1) \
+ ii2f(f, l, op, r0,r1,r2,r3,r4,r5, f3,f4,f5,f0,f1,f2) \
+ ii2f(f, l, op, r0,r1,r2,r3,r4,r5, f4,f5,f0,f1,f2,f3) \
+ ii2f(f, l, op, r0,r1,r2,r3,r4,r5, f5,f0,f1,f2,f3,f4)
+#endif
+#define i2f(l, op) \
+ xi2f(_f, l, op, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5) \
+ xi2f(_d, l, op, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5)
+
+#define off_c 1
+#define off_uc off_c
+#define off_s 2
+#define off_us off_s
+#define off_i 4
+#define off_ui off_i
+#define off_l 8
+#define off_f 4
+#define off_d 8
+
+#define ildi(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_##ldi##i(_jit, IR##r0, buff); \
+ check5(ldi##i, l, r1, r2, r3, r4, r5)
+
+#define ildr(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r1, (jit_imm_t)buff); \
+ jit_##ldr##i(_jit, IR##r0, IR##r1); \
+ check4(ldr##i, l, r2, r3, r4, r5)
+
+#define ildr0(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r0, (jit_imm_t)buff); \
+ jit_##ldr##i(_jit, IR##r0, IR##r0); \
+ check5(ldr##i, l, r1, r2, r3, r4, r5)
+
+#define ildxi(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r1, (jit_imm_t)buff); \
+ jit_ldxi##i(_jit, IR##r0, IR##r1, off##i); \
+ check4(ldxi##i, l, r2, r3, r4, r5)
+
+#define ildxr(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r1, (jit_imm_t)buff); \
+ jit_movi(_jit, IR##r2, off##i); \
+ jit_ldxr##i(_jit, IR##r0, IR##r1, IR##r2); \
+ check3(ldxr##i, l, r3, r4, r5)
+
+#define ildxr0(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r1, (jit_imm_t)buff); \
+ jit_movi(_jit, IR##r0, off##i); \
+ jit_ldxr##i(_jit, IR##r0, IR##r1, IR##r0); \
+ check4(ldxr0##i, l, r2, r3, r4, r5)
+
+#define ildxr1(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r0, (jit_imm_t)buff); \
+ jit_movi(_jit, IR##r1, off##i); \
+ jit_ldxr##i(_jit, IR##r0, IR##r0, IR##r1); \
+ check4(ldxr1##i, l, r2, r3, r4, r5)
+
+#define xxldi(i, l, r0, r1, r2, r3, r4, r5) \
+ ildi(i, l, r0, r1, r2, r3, r4, r5) \
+ ildr(i, l, r0, r1, r2, r3, r4, r5) \
+ ildr0(i, l, r0, r1, r2, r3, r4, r5) \
+ ildxi(i, l, r0, r1, r2, r3, r4, r5) \
+ ildxr(i, l, r0, r1, r2, r3, r4, r5) \
+ ildxr0(i, l, r0, r1, r2, r3, r4, r5) \
+ ildxr1(i, l, r0, r1, r2, r3, r4, r5)
+#if __WORDSIZE == 32
+#define xxxldi(l, r0, r1, r2, r3, r4, r5)
+#else
+#define xxxldi(l, r0, r1, r2, r3, r4, r5) \
+ xxldi(_ui, l, r0, r1, r2, r3, r4, r5) \
+ xxldi( _l, l, r0, r1, r2, r3, r4, r5)
+#endif
+#define xldi(l, r0, r1, r2, r3, r4, r5) \
+ xxldi( _c, l, r0, r1, r2, r3, r4, r5) \
+ xxldi(_uc, l, r0, r1, r2, r3, r4, r5) \
+ xxldi( _s, l, r0, r1, r2, r3, r4, r5) \
+ xxldi(_us, l, r0, r1, r2, r3, r4, r5) \
+ xxldi( _i, l, r0, r1, r2, r3, r4, r5) \
+ xxxldi(l, r0, r1, r2, r3, r4, r5)
+#if __ia64__
+# define ldi(l) \
+ xldi(l, 0, 1, 2, 3, 4, 5)
+#else
+# define ldi(l) \
+ xldi(l, 0, 1, 2, 3, 4, 5) \
+ xldi(l, 1, 2, 3, 4, 5, 0) \
+ xldi(l, 2, 3, 4, 5, 0, 1) \
+ xldi(l, 3, 4, 5, 0, 1, 2) \
+ xldi(l, 4, 5, 0, 1, 2, 3) \
+ xldi(l, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define fldi(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_ldi##f(_jit, FR##f0, buff); \
+ check6(ldi##f##r0##f0, l, r0, r1, r2, r3, r4, r5) \
+ checkf5(f, ldi##r0##f0, l, f1, f2, f3, f4, f5)
+
+#define fldr(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi(_jit, IR##r0, (jit_imm_t)buff); \
+ jit_ldr##f(_jit, FR##f0, IR##r0); \
+ check5(ldr##f##r0##f0, l, r1, r2, r3, r4, r5) \
+ checkf5(f, ldr##r0##f0, l, f1, f2, f3, f4, f5)
+
+#define fldxi(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi(_jit, IR##r0, (jit_imm_t)buff); \
+ jit_ldxi##f(_jit, FR##f0, IR##r0, off##f); \
+ check5(ldxi##f##r0##f0, l, r1, r2, r3, r4, r5) \
+ checkf5(f, ldxi##r0##f0, l, f1, f2, f3, f4, f5)
+
+#define fldxr(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi(_jit, IR##r0, (jit_imm_t)buff); \
+ jit_movi(_jit, IR##r1, off##f); \
+ jit_ldxr##f(_jit, FR##f0, IR##r0, IR##r1); \
+ check4(ldxr##f##r0##f0, l, r2, r3, r4, r5) \
+ checkf5(f, ldxr##r0##f0, l, f1, f2, f3, f4, f5)
+
+#define xldf(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fldi(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fldr(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fldxi(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fldxr(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+
+#define xxldf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ xldf(_f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ xldf(_d, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+#if __ia64__
+# define ixldf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ xxldf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+#else
+# define fxldf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ xxldf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ xxldf(l, r0,r1,r2,r3,r4,r5, f1,f2,f3,f4,f5,f0) \
+ xxldf(l, r0,r1,r2,r3,r4,r5, f2,f3,f4,f5,f0,f1) \
+ xxldf(l, r0,r1,r2,r3,r4,r5, f3,f4,f5,f0,f1,f2) \
+ xxldf(l, r0,r1,r2,r3,r4,r5, f4,f5,f0,f1,f2,f3) \
+ xxldf(l, r0,r1,r2,r3,r4,r5, f5,f0,f1,f2,f3,f4)
+# define ixldf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fxldf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fxldf(l, r1,r2,r3,r4,r5,r0, f0,f1,f2,f3,f4,f5) \
+ fxldf(l, r2,r3,r4,r5,r0,r1, f0,f1,f2,f3,f4,f5) \
+ fxldf(l, r3,r4,r5,r0,r1,r2, f0,f1,f2,f3,f4,f5) \
+ fxldf(l, r4,r5,r0,r1,r2,r3, f0,f1,f2,f3,f4,f5) \
+ fxldf(l, r5,r0,r1,r2,r3,r4, f0,f1,f2,f3,f4,f5)
+#endif
+#define ldf(l) \
+ ixldf(l, 0,1,2,3,4,5, 0,1,2,3,4,5)
+
+#define isti(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_sti##i(_jit, buff, IR##r0); \
+ check5(sti##i, l, r1, r2, r3, r4, r5)
+
+#define istr(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r1, (jit_imm_t)buff); \
+ jit_str##i(_jit, IR##r1, IR##r0); \
+ check4(str##i, l, r2, r3, r4, r5)
+
+#define istr0(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r1, (jit_imm_t)buff); \
+ jit_str##i(_jit, IR##r1, IR##r0); \
+ check4(str0##i, l, r2, r3, r4, r5)
+
+#define istxi(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r1, (jit_imm_t)buff); \
+ jit_stxi##i(_jit, off##i, IR##r1, IR##r0); \
+ check4(stxi##i, l, r2, r3, r4, r5)
+
+#define istxr(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r1, (jit_imm_t)buff); \
+ jit_movi(_jit, IR##r2, off##i); \
+ jit_stxr##i(_jit, IR##r2, IR##r1, IR##r0); \
+ check3(stxr##i, l, r3, r4, r5)
+
+#define istxr0(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r1, (jit_imm_t)buff); \
+ jit_movi(_jit, IR##r0, off##i); \
+ jit_stxr##i(_jit, IR##r0, IR##r1, IR##r0); \
+ check4(stxr0##i, l, r2, r3, r4, r5)
+
+#define istxr1(i, l, r0, r1, r2, r3, r4, r5) \
+ setup() \
+ jit_movi(_jit, IR##r0, (jit_imm_t)buff); \
+ jit_movi(_jit, IR##r1, off##i); \
+ jit_stxr##i(_jit, IR##r1, IR##r0, IR##r0); \
+ check4(stxr1##i, l, r2, r3, r4, r5)
+
+#define xxsti(i, l, r0, r1, r2, r3, r4, r5) \
+ isti(i, l, r0, r1, r2, r3, r4, r5) \
+ istr(i, l, r0, r1, r2, r3, r4, r5) \
+ istr0(i, l, r0, r1, r2, r3, r4, r5) \
+ istxi(i, l, r0, r1, r2, r3, r4, r5) \
+ istxr(i, l, r0, r1, r2, r3, r4, r5) \
+ istxr0(i, l, r0, r1, r2, r3, r4, r5) \
+ istxr1(i, l, r0, r1, r2, r3, r4, r5)
+#if __WORDSIZE == 32
+#define xxxsti(l, r0, r1, r2, r3, r4, r5)
+#else
+#define xxxsti(l, r0, r1, r2, r3, r4, r5) \
+ xxsti( _l, l, r0, r1, r2, r3, r4, r5)
+#endif
+#define xsti(l, r0, r1, r2, r3, r4, r5) \
+ xxsti( _c, l, r0, r1, r2, r3, r4, r5) \
+ xxsti( _s, l, r0, r1, r2, r3, r4, r5) \
+ xxsti( _i, l, r0, r1, r2, r3, r4, r5) \
+ xxxsti(l, r0, r1, r2, r3, r4, r5)
+#if __ia64__
+# define sti(l) \
+ xsti(l, 0, 1, 2, 3, 4, 5)
+#else
+# define sti(l) \
+ xsti(l, 0, 1, 2, 3, 4, 5) \
+ xsti(l, 1, 2, 3, 4, 5, 0) \
+ xsti(l, 2, 3, 4, 5, 0, 1) \
+ xsti(l, 3, 4, 5, 0, 1, 2) \
+ xsti(l, 4, 5, 0, 1, 2, 3) \
+ xsti(l, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define fsti(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_sti##f(_jit, buff, FR##f0); \
+ check6(sti##f##r0##f0, l, r0, r1, r2, r3, r4, r5) \
+ checkf5(f, sti##r0##f0, l, f1, f2, f3, f4, f5)
+
+#define fstr(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi(_jit, IR##r0, (jit_imm_t)buff); \
+ jit_str##f(_jit, IR##r0, FR##f0); \
+ check5(str##f##r0##f0, l, r1, r2, r3, r4, r5) \
+ checkf5(f, str##r0##f0, l, f1, f2, f3, f4, f5)
+
+#define fstxi(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi(_jit, IR##r0, (jit_imm_t)buff); \
+ jit_stxi##f(_jit, off##f, IR##r0, FR##f0); \
+ check5(stxi##f##r0##f0, l, r1, r2, r3, r4, r5) \
+ checkf5(f, stxi##r0##f0, l, f1, f2, f3, f4, f5)
+
+#define fstxr(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ setup() \
+ setup##f() \
+ jit_movi(_jit, IR##r0, (jit_imm_t)buff); \
+ jit_movi(_jit, IR##r1, off##f); \
+ jit_stxr##f(_jit, IR##r1, IR##r0, FR##f0); \
+ check4(stxr##f##r0##f0, l, r2, r3, r4, r5) \
+ checkf5(f, stxr##r0##f0, l, f1, f2, f3, f4, f5)
+
+#define xstf(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fsti(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fstr(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fstxi(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fstxr(f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+#define xxstf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ xstf(_f, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ xstf(_d, l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+#if __ia64__
+# define ixstf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ xxstf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5)
+#else
+# define fxstf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ xxstf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ xxstf(l, r0,r1,r2,r3,r4,r5, f1,f2,f3,f4,f5,f0) \
+ xxstf(l, r0,r1,r2,r3,r4,r5, f2,f3,f4,f5,f0,f1) \
+ xxstf(l, r0,r1,r2,r3,r4,r5, f3,f4,f5,f0,f1,f2) \
+ xxstf(l, r0,r1,r2,r3,r4,r5, f4,f5,f0,f1,f2,f3) \
+ xxstf(l, r0,r1,r2,r3,r4,r5, f5,f0,f1,f2,f3,f4)
+# define ixstf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fxstf(l, r0,r1,r2,r3,r4,r5, f0,f1,f2,f3,f4,f5) \
+ fxstf(l, r1,r2,r3,r4,r5,r0, f0,f1,f2,f3,f4,f5) \
+ fxstf(l, r2,r3,r4,r5,r0,r1, f0,f1,f2,f3,f4,f5) \
+ fxstf(l, r3,r4,r5,r0,r1,r2, f0,f1,f2,f3,f4,f5) \
+ fxstf(l, r4,r5,r0,r1,r2,r3, f0,f1,f2,f3,f4,f5) \
+ fxstf(l, r5,r0,r1,r2,r3,r4, f0,f1,f2,f3,f4,f5)
+#endif
+#define stf(l) \
+ ixstf(l, 0,1,2,3,4,5, 0,1,2,3,4,5)
+
+#define bri(l, op, u, il, ir, r0, r1, r2, r3, r4, r5) \
+{ \
+ setup() \
+ jit_movi(_jit, IR##r0, il); \
+ jit_reloc_t r = jit_b##op##i##u(_jit, IR##r0, ir); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+ check5(i, l, r1, r2, r3, r4, r5) \
+}
+
+#define brr(l, op, u, il, ir, r0, r1, r2, r3, r4, r5) \
+{ \
+ setup() \
+ jit_movi(_jit, IR##r0, il); \
+ jit_movi(_jit, IR##r1, ir); \
+ jit_reloc_t r = jit_b##op##r##u(_jit, IR##r0, IR##r1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+ check4(r, l, r2, r3, r4, r5) \
+}
+
+#define xjmpi(l, op, u, il, ir, r0, r1, r2, r3, r4, r5) \
+ bri(l, op, u, il, ir, r0, r1, r2, r3, r4, r5) \
+ brr(l, op, u, il, ir, r0, r1, r2, r3, r4, r5)
+#if __ia64__
+# define jmpi(l, op, u, il, ir) \
+ xjmpi(l, op, u, il, ir, 0, 1, 2, 3, 4, 5)
+#else
+# define jmpi(l, op, u, il, ir) \
+ xjmpi(l, op, u, il, ir, 0, 1, 2, 3, 4, 5) \
+ xjmpi(l, op, u, il, ir, 1, 2, 3, 4, 5, 0) \
+ xjmpi(l, op, u, il, ir, 2, 3, 4, 5, 0, 1) \
+ xjmpi(l, op, u, il, ir, 3, 4, 5, 0, 1, 2) \
+ xjmpi(l, op, u, il, ir, 4, 5, 0, 1, 2, 3) \
+ xjmpi(l, op, u, il, ir, 5, 0, 1, 2, 3, 4)
+#endif
+
+#define bfi(f, l, op, il, ir, f0, f1, f2, f3, f4, f5) \
+{ \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, il); \
+ jit_movi##f(_jit, JIT_F6, ir); \
+ jit_reloc_t r = jit_b##op##r##f(_jit, FR##f0, JIT_F6); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+ checkf5(f, i, l, f1, f2, f3, f4, f5) \
+}
+
+#define bff(f, l, op, il, ir, f0, f1, f2, f3, f4, f5) \
+{ \
+ setup##f() \
+ jit_movi##f(_jit, FR##f0, il); \
+ jit_movi##f(_jit, FR##f1, ir); \
+ jit_reloc_t r = jit_b##op##r##f(_jit, FR##f0, FR##f1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+ checkf4(f, r, l, f2, f3, f4, f5) \
+}
+
+#define xjmpf(f, l, op, il, ir, f0, f1, f2, f3, f4, f5) \
+ bfi(f, l, op, il, ir, f0, f1, f2, f3, f4, f5) \
+ bff(f, l, op, il, ir, f0, f1, f2, f3, f4, f5)
+#define xxjmpf(l, op, il, ir, f0, f1, f2, f3, f4, f5) \
+ xjmpf(_f, l, op, il, ir, f0, f1, f2, f3, f4, f5) \
+ xjmpf(_d, l, op, il, ir, f0, f1, f2, f3, f4, f5)
+#if __ia64__
+# define jmpf(l, op, il, ir) \
+ xxjmpf(l, op, il, ir, 0, 1, 2, 3, 4, 5)
+#else
+# define jmpf(l, op, il, ir) \
+ xxjmpf(l, op, il, ir, 0, 1, 2, 3, 4, 5) \
+ xxjmpf(l, op, il, ir, 1, 2, 3, 4, 5, 0) \
+ xxjmpf(l, op, il, ir, 2, 3, 4, 5, 0, 1) \
+ xxjmpf(l, op, il, ir, 3, 4, 5, 0, 1, 2) \
+ xxjmpf(l, op, il, ir, 4, 5, 0, 1, 2, 3) \
+ xxjmpf(l, op, il, ir, 5, 0, 1, 2, 3, 4)
+#endif
+
+static size_t
+run_test(jit_state_t *_jit, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(_jit, arena_base, arena_size);
+ size_t frame = jit_enter_jit_abi(_jit, 3, 0, 0);
+
+ void (*function)(void);
+
+ char *buff = malloc(16);
+ ASSERT(buff);
+
+ alu(__LINE__, add)
+ alux(__LINE__, add)
+ fop(__LINE__, add)
+ alu(__LINE__, sub)
+ alux(__LINE__, sub)
+ fop(__LINE__, sub)
+ alu(__LINE__, mul)
+ fop(__LINE__, mul)
+ alu(__LINE__, div)
+ alu_u(__LINE__, div)
+ fop(__LINE__, div)
+ alu(__LINE__, rem)
+ alu_u(__LINE__, rem)
+ alu(__LINE__, and)
+ alu(__LINE__, or)
+ alu(__LINE__, xor)
+ alu(__LINE__, lsh)
+ alu(__LINE__, rsh)
+ alu_u(__LINE__, rsh)
+ uni(__LINE__, negr)
+ unf(__LINE__, negr)
+ uni(__LINE__, comr)
+ unf(__LINE__, absr)
+ unf(__LINE__, sqrtr)
+ mvi(__LINE__)
+ mvf(__LINE__)
+ uni(__LINE__, extr_c)
+ uni(__LINE__, extr_uc)
+ uni(__LINE__, extr_s)
+ uni(__LINE__, extr_us)
+#if __WORDSIZE == 64
+ uni(__LINE__, extr_ui)
+#endif
+ uni(__LINE__, bswapr_us)
+ uni(__LINE__, bswapr_ui)
+#if __WORDSIZE == 64
+ uni(__LINE__, bswapr_ul)
+#endif
+ f2f(__LINE__, _f, extr_d_f)
+ f2f(__LINE__, _d, extr_f_d)
+ f2i(__LINE__, truncr)
+ i2f(__LINE__, extr)
+ ldi(__LINE__)
+ ldf(__LINE__)
+ sti(__LINE__)
+ stf(__LINE__)
+ jmpi(__LINE__, lt, , 0, 1)
+ jmpi(__LINE__, lt, _u, 0, 1)
+ jmpf(__LINE__, lt, 0, 1)
+ jmpi(__LINE__, le, , 1, 1)
+ jmpi(__LINE__, le, _u, 1, 1)
+ jmpf(__LINE__, le, 1, 1)
+ jmpi(__LINE__, eq, , -1, -1)
+ jmpf(__LINE__, eq, -1, -1)
+ jmpi(__LINE__, ge, , 2, 2)
+ jmpi(__LINE__, ge, _u, 2, 2)
+ jmpf(__LINE__, ge, 2, 2)
+ jmpi(__LINE__, gt, , 2, 1)
+ jmpi(__LINE__, gt, _u, 2, 1)
+ jmpf(__LINE__, gt, 2, 1)
+ jmpi(__LINE__, ne, , 3, 2)
+ jmpf(__LINE__, ne, 3, 2)
+ jmpi(__LINE__, ms, , 1, 1)
+ jmpi(__LINE__, mc, , 1, 2)
+#if __WORDSIZE == 32
+# define ix7f 0x7fffffff
+# define ix80 0x80000000
+# define ixff 0xffffffff
+#else
+# define ix7f 0x7fffffffffffffff
+# define ix80 0x8000000000000000
+# define ixff 0xffffffffffffffff
+#endif
+ jmpi(__LINE__, oadd, , ix7f, 1)
+ jmpi(__LINE__, oadd, _u, ixff, 1)
+ jmpi(__LINE__, xadd, , ix80, 1)
+ jmpi(__LINE__, xadd, _u, ix7f, 1)
+ jmpi(__LINE__, osub, , ix80, 1)
+ jmpi(__LINE__, osub, _u, 0, 1)
+ jmpi(__LINE__, xsub, , ix7f, 1)
+ jmpi(__LINE__, xsub, _u, ix80, 1)
+ jmpf(__LINE__, unlt, 0, 1)
+ jmpf(__LINE__, unle, 1, 1)
+ jmpf(__LINE__, uneq, 2, 2)
+ jmpf(__LINE__, unge, 3, 3)
+ jmpf(__LINE__, ungt, 4, 3)
+ jmpf(__LINE__, ltgt, 5, 4)
+ jmpf(__LINE__, ord, 0, 0)
+ jmpf(__LINE__, unord, 0, (0.0 / 0.0))
+
+ jit_leave_jit_abi(_jit, 3, 0, frame);
+ jit_ret(_jit);
+
+ size_t size = 0;
+ function = jit_end(_jit, &size);
+
+ if (function)
+ (*function)();
+ else {
+ free(buff);
+ return size;
+ }
+
+ free(buff);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return main_compiler(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/z_range.c b/deps/lightening/tests/z_range.c
new file mode 100644
index 0000000..a8b82f4
--- /dev/null
+++ b/deps/lightening/tests/z_range.c
@@ -0,0 +1,577 @@
+#include "test.h"
+
+#define M64 67108864
+
+#define aB1 (1<<1)
+#define aB2 (1<<2)
+#define aB3 (1<<3)
+#define aB4 (1<<4)
+#define aB5 (1<<5)
+#define aB6 (1<<6)
+#define aB7 (1<<7)
+#define aB8 (1<<8)
+#define aB9 (1<<9)
+#define aB10 (1<<10)
+#define aB11 (1<<11)
+#define aB12 (1<<12)
+#define aB13 (1<<13)
+#define aB14 (1<<14)
+#define aB15 (1<<15)
+#define aB16 (1<<16)
+#define aB17 (1<<17)
+#define aB18 (1<<18)
+#define aB19 (1<<19)
+#define aB20 (1<<20)
+#define aB21 (1<<21)
+#define aB22 (1<<22)
+#define aB23 (1<<23)
+#define aB24 (1<<24)
+#define aB25 (1<<25)
+#define aB26 (1<<26)
+#define bB1 (-aB1)
+#define bB2 (-aB2)
+#define bB3 (-aB3)
+#define bB4 (-aB4)
+#define bB5 (-aB5)
+#define bB6 (-aB6)
+#define bB7 (-aB7)
+#define bB8 (-aB8)
+#define bB9 (-aB9)
+#define bB10 (-aB10)
+#define bB11 (-aB11)
+#define bB12 (-aB12)
+#define bB13 (-aB13)
+#define bB14 (-aB14)
+#define bB15 (-aB15)
+#define bB16 (-aB16)
+#define bB17 (-aB17)
+#define bB18 (-aB18)
+#define bB19 (-aB19)
+#define bB20 (-aB20)
+#define bB21 (-aB21)
+#define bB22 (-aB22)
+#define bB23 (-aB23)
+#define bB24 (-aB24)
+#define bB25 (-aB25)
+#define bB26 (-aB26)
+#define cB1 (aB1-1)
+#define cB2 (aB2-1)
+#define cB3 (aB3-1)
+#define cB4 (aB4-1)
+#define cB5 (aB5-1)
+#define cB6 (aB6-1)
+#define cB7 (aB7-1)
+#define cB8 (aB8-1)
+#define cB9 (aB9-1)
+#define cB10 (aB10-1)
+#define cB11 (aB11-1)
+#define cB12 (aB12-1)
+#define cB13 (aB13-1)
+#define cB14 (aB14-1)
+#define cB15 (aB15-1)
+#define cB16 (aB16-1)
+#define cB17 (aB17-1)
+#define cB18 (aB18-1)
+#define cB19 (aB19-1)
+#define cB20 (aB20-1)
+#define cB21 (aB21-1)
+#define cB22 (aB22-1)
+#define cB23 (aB23-1)
+#define cB24 (aB24-1)
+#define cB25 (aB25-1)
+#define cB26 (aB26-1)
+#define dB1 (-aB1+1)
+#define dB2 (-aB2+1)
+#define dB3 (-aB3+1)
+#define dB4 (-aB4+1)
+#define dB5 (-aB5+1)
+#define dB6 (-aB6+1)
+#define dB7 (-aB7+1)
+#define dB8 (-aB8+1)
+#define dB9 (-aB9+1)
+#define dB10 (-aB10+1)
+#define dB11 (-aB11+1)
+#define dB12 (-aB12+1)
+#define dB13 (-aB13+1)
+#define dB14 (-aB14+1)
+#define dB15 (-aB15+1)
+#define dB16 (-aB16+1)
+#define dB17 (-aB17+1)
+#define dB18 (-aB18+1)
+#define dB19 (-aB19+1)
+#define dB20 (-aB20+1)
+#define dB21 (-aB21+1)
+#define dB22 (-aB22+1)
+#define dB23 (-aB23+1)
+#define dB24 (-aB24+1)
+#define dB25 (-aB25+1)
+#define dB26 (-aB26+1)
+
+#define add(a, b) (a + b)
+#define sub(a, b) (a - b)
+#define mul(a, b) (a * b)
+#define div(a, b) (a / b)
+#define rem(a, b) (a % b)
+#define and(a, b) (a & b)
+#define or(a, b) (a | b)
+#define xor(a, b) (a ^ b)
+
+#if defined(DEBUG)
+#define dump_args(N, X, L, R, V)\
+ jit_calli_1(_jit, puts,\
+ jit_operand_imm(JIT_OPERAND_ABI_POINTER,\
+ (jit_imm_t)#N " " #X " " #L " " #R " " #V))
+#else
+#define dump_args(N, X, L, R, V)
+#endif
+
+/* alu2 doesn't really work for jit_rshi_u, so define a shim */
+#define jit_rsh_ui jit_rshi_u
+
+#define alu2(N, X, L, R, V) \
+{ \
+ dump_args(N, X, L, R, V); \
+ jit_movi(_jit, JIT_R1, L); \
+ jit_##N##i(_jit, JIT_R0, JIT_R1, R); \
+ jit_reloc_t r = jit_beqi(_jit, JIT_R0, V); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define alu1(N, M) \
+ alu2(N, N##M##1, 3, (M##1), N(3, M##1)) \
+ alu2(N, N##M##2, 3, (M##2), N(3, M##2)) \
+ alu2(N, N##M##3, 3, (M##3), N(3, M##3)) \
+ alu2(N, N##M##4, 3, (M##4), N(3, M##4)) \
+ alu2(N, N##M##5, 3, (M##5), N(3, M##5)) \
+ alu2(N, N##M##6, 3, (M##6), N(3, M##6)) \
+ alu2(N, N##M##7, 3, (M##7), N(3, M##7)) \
+ alu2(N, N##M##8, 3, (M##8), N(3, M##8)) \
+ alu2(N, N##M##9, 3, (M##9), N(3, M##9)) \
+ alu2(N, N##M##10, 3, (M##10), N(3, M##10)) \
+ alu2(N, N##M##11, 3, (M##11), N(3, M##11)) \
+ alu2(N, N##M##12, 3, (M##12), N(3, M##12)) \
+ alu2(N, N##M##13, 3, (M##13), N(3, M##13)) \
+ alu2(N, N##M##14, 3, (M##14), N(3, M##14)) \
+ alu2(N, N##M##15, 3, (M##15), N(3, M##15)) \
+ alu2(N, N##M##16, 3, (M##16), N(3, M##16)) \
+ alu2(N, N##M##17, 3, (M##17), N(3, M##17)) \
+ alu2(N, N##M##18, 3, (M##18), N(3, M##18)) \
+ alu2(N, N##M##19, 3, (M##19), N(3, M##19)) \
+ alu2(N, N##M##20, 3, (M##20), N(3, M##20)) \
+ alu2(N, N##M##21, 3, (M##21), N(3, M##21)) \
+ alu2(N, N##M##22, 3, (M##22), N(3, M##22)) \
+ alu2(N, N##M##23, 3, (M##23), N(3, M##23)) \
+ alu2(N, N##M##24, 3, (M##24), N(3, M##24)) \
+ alu2(N, N##M##25, 3, (M##25), N(3, M##25)) \
+ alu2(N, N##M##26, 3, (M##26), N(3, M##26))
+
+#define alu(N) \
+ alu1(N, aB) \
+ alu1(N, bB) \
+ alu1(N, cB) \
+ alu1(N, dB)
+
+#define _lsh(N) \
+ alu2(lsh, L##N, 1, N, (1L<<N))
+
+#if __WORDSIZE == 64
+#define _rsh(N) \
+ alu2(rsh, R##N, (1L<<63), N, ((1L<<63)>>N))
+
+#define _rush(N) \
+ alu2(rsh_u, R##N, (1UL<<63), N, ((1UL<<63)>>N))
+#else
+#define _rsh(N) \
+ alu2(rsh, R##N, (1L<<31), N, ((1L<<31)>>N))
+
+#define _rush(N) \
+ alu2(rsh_u, R##N, (1UL<<31), N, ((1UL<<31)>>N))
+#endif
+
+#if __WORDSIZE == 32
+# define xsh64(X) /**/
+#else
+# define xsh64(X) \
+ _##X##sh(32) \
+ _##X##sh(33) \
+ _##X##sh(34) \
+ _##X##sh(35) \
+ _##X##sh(36) \
+ _##X##sh(37) \
+ _##X##sh(38) \
+ _##X##sh(39) \
+ _##X##sh(40) \
+ _##X##sh(41) \
+ _##X##sh(42) \
+ _##X##sh(43) \
+ _##X##sh(44) \
+ _##X##sh(45) \
+ _##X##sh(46) \
+ _##X##sh(47) \
+ _##X##sh(48) \
+ _##X##sh(49) \
+ _##X##sh(50) \
+ _##X##sh(51) \
+ _##X##sh(52) \
+ _##X##sh(53) \
+ _##X##sh(54) \
+ _##X##sh(55) \
+ _##X##sh(56) \
+ _##X##sh(57) \
+ _##X##sh(58) \
+ _##X##sh(59) \
+ _##X##sh(60) \
+ _##X##sh(61) \
+ _##X##sh(62) \
+ _##X##sh(63)
+#endif
+
+#define xsh(X) \
+ _##X##sh(0) \
+ _##X##sh(1) \
+ _##X##sh(2) \
+ _##X##sh(3) \
+ _##X##sh(4) \
+ _##X##sh(5) \
+ _##X##sh(6) \
+ _##X##sh(7) \
+ _##X##sh(8) \
+ _##X##sh(9) \
+ _##X##sh(10) \
+ _##X##sh(11) \
+ _##X##sh(12) \
+ _##X##sh(13) \
+ _##X##sh(14) \
+ _##X##sh(15) \
+ _##X##sh(16) \
+ _##X##sh(17) \
+ _##X##sh(18) \
+ _##X##sh(19) \
+ _##X##sh(20) \
+ _##X##sh(21) \
+ _##X##sh(22) \
+ _##X##sh(23) \
+ _##X##sh(24) \
+ _##X##sh(25) \
+ _##X##sh(26) \
+ _##X##sh(27) \
+ _##X##sh(28) \
+ _##X##sh(29) \
+ _##X##sh(30) \
+ _##X##sh(31) \
+ xsh64(X)
+
+#define lsh() \
+ xsh(l)
+
+#define rsh() \
+ xsh(r)
+
+#define rsh_u() \
+ xsh(ru)
+
+#define reset(V) \
+ jit_calli_3(_jit, memset, \
+ jit_operand_imm(JIT_OPERAND_ABI_POINTER, (jit_imm_t)buf),\
+ jit_operand_imm(JIT_OPERAND_ABI_INT32, V), \
+ jit_operand_imm(JIT_OPERAND_ABI_UINT32, M64 + 8));
+
+#define stx(T, N, O, V) \
+ jit_movi(_jit, JIT_R0, V); \
+ jit_stxi##T(_jit, O, JIT_V0, JIT_R0);
+
+#define stx8(T, M, V) \
+ stx(T, 3, (M##B3), V) \
+ stx(T, 4, (M##B4), V) \
+ stx(T, 5, (M##B5), V) \
+ stx(T, 6, (M##B6), V) \
+ stx(T, 7, (M##B7), V) \
+ stx(T, 8, (M##B8), V) \
+ stx(T, 9, (M##B9), V) \
+ stx(T, 10, (M##B10), V) \
+ stx(T, 11, (M##B11), V) \
+ stx(T, 12, (M##B12), V) \
+ stx(T, 13, (M##B13), V) \
+ stx(T, 14, (M##B14), V) \
+ stx(T, 15, (M##B15), V) \
+ stx(T, 16, (M##B16), V) \
+ stx(T, 17, (M##B17), V) \
+ stx(T, 18, (M##B18), V) \
+ stx(T, 19, (M##B19), V) \
+ stx(T, 20, (M##B20), V) \
+ stx(T, 21, (M##B21), V) \
+ stx(T, 22, (M##B22), V) \
+ stx(T, 23, (M##B23), V) \
+ stx(T, 24, (M##B24), V) \
+ stx(T, 25, (M##B25), V) \
+ stx(T, 26, (M##B26), V)
+
+#define stx4(T, M, V) \
+ stx(T, 2, (M##B2), V) \
+ stx8(T, M, V)
+
+#define stx2(T, M, V) \
+ stx(T, 1, (M##B1), V) \
+ stx4(T, M, V)
+
+#define ldx(T, N, M, O, V) \
+{ \
+ dump_args(T, N, M, O, V); \
+ jit_movi(_jit, JIT_R0, 0); \
+ jit_ldxi##T(_jit, JIT_R0, JIT_V0, O); \
+ jit_reloc_t r = jit_beqi(_jit, JIT_R0, V); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define ldx8(T, M, V) \
+ ldx(T, 3, M, (M##B3), V) \
+ ldx(T, 4, M, (M##B4), V) \
+ ldx(T, 5, M, (M##B5), V) \
+ ldx(T, 6, M, (M##B6), V) \
+ ldx(T, 7, M, (M##B7), V) \
+ ldx(T, 8, M, (M##B8), V) \
+ ldx(T, 9, M, (M##B9), V) \
+ ldx(T, 10, M, (M##B10), V) \
+ ldx(T, 11, M, (M##B11), V) \
+ ldx(T, 12, M, (M##B12), V) \
+ ldx(T, 13, M, (M##B13), V) \
+ ldx(T, 14, M, (M##B14), V) \
+ ldx(T, 15, M, (M##B15), V) \
+ ldx(T, 16, M, (M##B16), V) \
+ ldx(T, 17, M, (M##B17), V) \
+ ldx(T, 18, M, (M##B18), V) \
+ ldx(T, 19, M, (M##B19), V) \
+ ldx(T, 20, M, (M##B20), V) \
+ ldx(T, 21, M, (M##B21), V) \
+ ldx(T, 22, M, (M##B22), V) \
+ ldx(T, 23, M, (M##B23), V) \
+ ldx(T, 24, M, (M##B24), V) \
+ ldx(T, 25, M, (M##B25), V) \
+ ldx(T, 26, M, (M##B26), V)
+#define ldx4(T, M, V) \
+ ldx(T, 2, M, (M##B2), V) \
+ ldx8(T, M, V)
+#define ldx2(T, M, V) \
+ ldx(T, 1, M, (M##B1), V) \
+ ldx4(T, M, V)
+
+#define stf(T, N, O, V) \
+ jit_movi##T(_jit, JIT_F0, V); \
+ jit_stxi##T(_jit, O, JIT_V0, JIT_F0);
+
+#define stf8(T, M, V) \
+ stf(T, 3, (M##B3), V) \
+ stf(T, 4, (M##B4), V) \
+ stf(T, 5, (M##B5), V) \
+ stf(T, 6, (M##B6), V) \
+ stf(T, 7, (M##B7), V) \
+ stf(T, 8, (M##B8), V) \
+ stf(T, 9, (M##B9), V) \
+ stf(T, 10, (M##B10), V) \
+ stf(T, 11, (M##B11), V) \
+ stf(T, 12, (M##B12), V) \
+ stf(T, 13, (M##B13), V) \
+ stf(T, 14, (M##B14), V) \
+ stf(T, 15, (M##B15), V) \
+ stf(T, 16, (M##B16), V) \
+ stf(T, 17, (M##B17), V) \
+ stf(T, 18, (M##B18), V) \
+ stf(T, 19, (M##B19), V) \
+ stf(T, 20, (M##B20), V) \
+ stf(T, 21, (M##B21), V) \
+ stf(T, 22, (M##B22), V) \
+ stf(T, 23, (M##B23), V) \
+ stf(T, 24, (M##B24), V) \
+ stf(T, 25, (M##B25), V) \
+ stf(T, 26, (M##B26), V)
+
+#define stf4(T, M, V) \
+ stf(T, 2, (M##B2), V) \
+ stf8(T, M, V)
+
+#define ldf(T, N, M, O, V) \
+{ \
+ dump_args(T, N, M, O, V); \
+ jit_movi##T(_jit, JIT_F0, 0); \
+ jit_ldxi##T(_jit, JIT_F0, JIT_V0, O); \
+ jit_movi##T(_jit, JIT_F1, V); \
+ jit_reloc_t r = jit_beqr##T(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define ldf8(T, M, V) \
+ ldf(T, 3, M, (M##B3), V) \
+ ldf(T, 4, M, (M##B4), V) \
+ ldf(T, 5, M, (M##B5), V) \
+ ldf(T, 6, M, (M##B6), V) \
+ ldf(T, 7, M, (M##B7), V) \
+ ldf(T, 8, M, (M##B8), V) \
+ ldf(T, 9, M, (M##B9), V) \
+ ldf(T, 10, M, (M##B10), V) \
+ ldf(T, 11, M, (M##B11), V) \
+ ldf(T, 12, M, (M##B12), V) \
+ ldf(T, 13, M, (M##B13), V) \
+ ldf(T, 14, M, (M##B14), V) \
+ ldf(T, 15, M, (M##B15), V) \
+ ldf(T, 16, M, (M##B16), V) \
+ ldf(T, 17, M, (M##B17), V) \
+ ldf(T, 18, M, (M##B18), V) \
+ ldf(T, 19, M, (M##B19), V) \
+ ldf(T, 20, M, (M##B20), V) \
+ ldf(T, 21, M, (M##B21), V) \
+ ldf(T, 22, M, (M##B22), V) \
+ ldf(T, 23, M, (M##B23), V) \
+ ldf(T, 24, M, (M##B24), V) \
+ ldf(T, 25, M, (M##B25), V) \
+ ldf(T, 26, M, (M##B26), V)
+#define ldf4(T, M, V) \
+ ldf(T, 2, M, (M##B2), V) \
+ ldf8(T, M, V)
+
+#define ldst_c() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx2(_c, a, 0x5a) \
+ ldx2(_c, a, 0x5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx2(_c, b, 0x5a) \
+ ldx2(_c, b, 0x5a)
+
+#define ldst_uc() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx2(_c, a, 0x5a) \
+ ldx2(_uc, a, 0x5a) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx2(_c, b, 0x5a) \
+ ldx2(_uc, b, 0x5a)
+
+#define ldst_s() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx2(_s, a, 0x5a5a) \
+ ldx2(_s, a, 0x5a5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx2(_s, b, 0x5a5a) \
+ ldx2(_s, b, 0x5a5a)
+
+#define ldst_us() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx2(_s, a, 0x5a5a) \
+ ldx2(_us, a, 0x5a5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx2(_s, b, 0x5a5a) \
+ ldx2(_us, b, 0x5a5a)
+
+#define ldst_i() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx4(_i, a, 0x5a5a5a5a) \
+ ldx4(_i, a, 0x5a5a5a5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx4(_i, b, 0x5a5a5a5a) \
+ ldx4(_i, b, 0x5a5a5a5a)
+
+#define ldst_ui() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx4(_i, a, 0x5a5a5a5a) \
+ ldx4(_ui, a, 0x5a5a5a5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx4(_i, b, 0x5a5a5a5a) \
+ ldx4(_ui, b, 0x5a5a5a5a)
+
+#define ldst_l() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx8(_l, a, 0x5a5a5a5a5a5a5a5a) \
+ ldx8(_l, a, 0x5a5a5a5a5a5a5a5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx8(_l, b, 0x5a5a5a5a5a5a5a5a) \
+ ldx8(_l, b, 0x5a5a5a5a5a5a5a5a)
+
+#define ldst_f() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stf4(_f, a, 0.5) \
+ ldf4(_f, a, 0.5) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stf4(_f, b, 0.5) \
+ ldf4(_f, b, 0.5)
+
+#define ldst_d() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stf8(_d, a, 0.5) \
+ ldf8(_d, a, 0.5) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stf8(_d, b, 0.5) \
+ ldf8(_d, b, 0.5)
+
+static size_t
+run_test(jit_state_t *_jit, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(_jit, arena_base, arena_size);
+ size_t frame = jit_enter_jit_abi(_jit, 3, 0, 0);
+
+ void (*function)(void);
+
+ char *buf = malloc(M64 + 8);
+ ASSERT(buf);
+
+ alu(add)
+ alu(sub)
+ alu(mul)
+ alu(div)
+ alu(rem)
+ lsh()
+ rsh()
+ rsh_u()
+ alu(and)
+ alu(or)
+ alu(xor)
+ ldst_c()
+ ldst_uc()
+ ldst_s()
+ ldst_us()
+ ldst_i()
+#if __WORDSIZE == 64
+ ldst_ui()
+ ldst_l()
+#endif
+ ldst_f()
+ ldst_d()
+
+ jit_leave_jit_abi(_jit, 3, 0, frame);
+ jit_ret(_jit);
+
+ size_t size = 0;
+ function = jit_end(_jit, &size);
+
+ if (function)
+ (*function)();
+ else {
+ free(buf);
+ return size;
+ }
+
+ free(buf);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return main_compiler(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/z_ranger.c b/deps/lightening/tests/z_ranger.c
new file mode 100644
index 0000000..aa9eadd
--- /dev/null
+++ b/deps/lightening/tests/z_ranger.c
@@ -0,0 +1,580 @@
+#include "test.h"
+
+#define M64 67108864
+
+#define aB1 (1<<1)
+#define aB2 (1<<2)
+#define aB3 (1<<3)
+#define aB4 (1<<4)
+#define aB5 (1<<5)
+#define aB6 (1<<6)
+#define aB7 (1<<7)
+#define aB8 (1<<8)
+#define aB9 (1<<9)
+#define aB10 (1<<10)
+#define aB11 (1<<11)
+#define aB12 (1<<12)
+#define aB13 (1<<13)
+#define aB14 (1<<14)
+#define aB15 (1<<15)
+#define aB16 (1<<16)
+#define aB17 (1<<17)
+#define aB18 (1<<18)
+#define aB19 (1<<19)
+#define aB20 (1<<20)
+#define aB21 (1<<21)
+#define aB22 (1<<22)
+#define aB23 (1<<23)
+#define aB24 (1<<24)
+#define aB25 (1<<25)
+#define aB26 (1<<26)
+#define bB1 (-aB1)
+#define bB2 (-aB2)
+#define bB3 (-aB3)
+#define bB4 (-aB4)
+#define bB5 (-aB5)
+#define bB6 (-aB6)
+#define bB7 (-aB7)
+#define bB8 (-aB8)
+#define bB9 (-aB9)
+#define bB10 (-aB10)
+#define bB11 (-aB11)
+#define bB12 (-aB12)
+#define bB13 (-aB13)
+#define bB14 (-aB14)
+#define bB15 (-aB15)
+#define bB16 (-aB16)
+#define bB17 (-aB17)
+#define bB18 (-aB18)
+#define bB19 (-aB19)
+#define bB20 (-aB20)
+#define bB21 (-aB21)
+#define bB22 (-aB22)
+#define bB23 (-aB23)
+#define bB24 (-aB24)
+#define bB25 (-aB25)
+#define bB26 (-aB26)
+#define cB1 (aB1-1)
+#define cB2 (aB2-1)
+#define cB3 (aB3-1)
+#define cB4 (aB4-1)
+#define cB5 (aB5-1)
+#define cB6 (aB6-1)
+#define cB7 (aB7-1)
+#define cB8 (aB8-1)
+#define cB9 (aB9-1)
+#define cB10 (aB10-1)
+#define cB11 (aB11-1)
+#define cB12 (aB12-1)
+#define cB13 (aB13-1)
+#define cB14 (aB14-1)
+#define cB15 (aB15-1)
+#define cB16 (aB16-1)
+#define cB17 (aB17-1)
+#define cB18 (aB18-1)
+#define cB19 (aB19-1)
+#define cB20 (aB20-1)
+#define cB21 (aB21-1)
+#define cB22 (aB22-1)
+#define cB23 (aB23-1)
+#define cB24 (aB24-1)
+#define cB25 (aB25-1)
+#define cB26 (aB26-1)
+#define dB1 (-aB1+1)
+#define dB2 (-aB2+1)
+#define dB3 (-aB3+1)
+#define dB4 (-aB4+1)
+#define dB5 (-aB5+1)
+#define dB6 (-aB6+1)
+#define dB7 (-aB7+1)
+#define dB8 (-aB8+1)
+#define dB9 (-aB9+1)
+#define dB10 (-aB10+1)
+#define dB11 (-aB11+1)
+#define dB12 (-aB12+1)
+#define dB13 (-aB13+1)
+#define dB14 (-aB14+1)
+#define dB15 (-aB15+1)
+#define dB16 (-aB16+1)
+#define dB17 (-aB17+1)
+#define dB18 (-aB18+1)
+#define dB19 (-aB19+1)
+#define dB20 (-aB20+1)
+#define dB21 (-aB21+1)
+#define dB22 (-aB22+1)
+#define dB23 (-aB23+1)
+#define dB24 (-aB24+1)
+#define dB25 (-aB25+1)
+#define dB26 (-aB26+1)
+
+#define add(a, b) (a + b)
+#define sub(a, b) (a - b)
+#define mul(a, b) (a * b)
+#define div(a, b) (a / b)
+#define rem(a, b) (a % b)
+#define and(a, b) (a & b)
+#define or(a, b) (a | b)
+#define xor(a, b) (a ^ b)
+
+#if defined(DEBUG)
+#define dump_args(N, X, L, R, V)\
+ jit_calli_1(_jit, puts,\
+ jit_operand_imm(JIT_OPERAND_ABI_POINTER,\
+ (jit_imm_t)#N " " #X " " #L " " #R " " #V))
+#else
+#define dump_args(N, X, L, R, V)
+#endif
+
+#define jit_rshi_ui jit_rshi_u
+
+#define alu2(N, X, L, R, V) \
+{ \
+ dump_args(N, X, L, R, V); \
+ jit_movi(_jit, JIT_R1, L); \
+ jit_movi(_jit, JIT_R2, R); \
+ jit_##N##r(_jit, JIT_R0, JIT_R1, JIT_R2); \
+ jit_reloc_t r = jit_beqi(_jit, JIT_R0, V); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define alu1(N, M) \
+ alu2(N, N##M##1, 3, (M##1), N(3, M##1)) \
+ alu2(N, N##M##2, 3, (M##2), N(3, M##2)) \
+ alu2(N, N##M##3, 3, (M##3), N(3, M##3)) \
+ alu2(N, N##M##4, 3, (M##4), N(3, M##4)) \
+ alu2(N, N##M##5, 3, (M##5), N(3, M##5)) \
+ alu2(N, N##M##6, 3, (M##6), N(3, M##6)) \
+ alu2(N, N##M##7, 3, (M##7), N(3, M##7)) \
+ alu2(N, N##M##8, 3, (M##8), N(3, M##8)) \
+ alu2(N, N##M##9, 3, (M##9), N(3, M##9)) \
+ alu2(N, N##M##10, 3, (M##10), N(3, M##10)) \
+ alu2(N, N##M##11, 3, (M##11), N(3, M##11)) \
+ alu2(N, N##M##12, 3, (M##12), N(3, M##12)) \
+ alu2(N, N##M##13, 3, (M##13), N(3, M##13)) \
+ alu2(N, N##M##14, 3, (M##14), N(3, M##14)) \
+ alu2(N, N##M##15, 3, (M##15), N(3, M##15)) \
+ alu2(N, N##M##16, 3, (M##16), N(3, M##16)) \
+ alu2(N, N##M##17, 3, (M##17), N(3, M##17)) \
+ alu2(N, N##M##18, 3, (M##18), N(3, M##18)) \
+ alu2(N, N##M##19, 3, (M##19), N(3, M##19)) \
+ alu2(N, N##M##20, 3, (M##20), N(3, M##20)) \
+ alu2(N, N##M##21, 3, (M##21), N(3, M##21)) \
+ alu2(N, N##M##22, 3, (M##22), N(3, M##22)) \
+ alu2(N, N##M##23, 3, (M##23), N(3, M##23)) \
+ alu2(N, N##M##24, 3, (M##24), N(3, M##24)) \
+ alu2(N, N##M##25, 3, (M##25), N(3, M##25)) \
+ alu2(N, N##M##26, 3, (M##26), N(3, M##26))
+
+#define alu(N) \
+ alu1(N, aB) \
+ alu1(N, bB) \
+ alu1(N, cB) \
+ alu1(N, dB)
+
+#define _lsh(N) \
+ alu2(lsh, L##N, 1, N, (1L<<N))
+
+#if __WORDSIZE == 64
+#define _rsh(N) \
+ alu2(rsh, R##N, (1L<<63), N, ((1L<<63)>>N))
+
+#define _rush(N) \
+ alu2(rsh_u, R##N, (1UL<<63), N, ((1UL<<63)>>N))
+#else
+#define _rsh(N) \
+ alu2(rsh, R##N, (1L<<31), N, ((1L<<31)>>N))
+
+#define _rush(N) \
+ alu2(rsh_u, R##N, (1UL<<31), N, ((1UL<<31)>>N))
+#endif
+
+#if __WORDSIZE == 32
+# define xsh64(X) /**/
+#else
+# define xsh64(X) \
+ _##X##sh(32) \
+ _##X##sh(33) \
+ _##X##sh(34) \
+ _##X##sh(35) \
+ _##X##sh(36) \
+ _##X##sh(37) \
+ _##X##sh(38) \
+ _##X##sh(39) \
+ _##X##sh(40) \
+ _##X##sh(41) \
+ _##X##sh(42) \
+ _##X##sh(43) \
+ _##X##sh(44) \
+ _##X##sh(45) \
+ _##X##sh(46) \
+ _##X##sh(47) \
+ _##X##sh(48) \
+ _##X##sh(49) \
+ _##X##sh(50) \
+ _##X##sh(51) \
+ _##X##sh(52) \
+ _##X##sh(53) \
+ _##X##sh(54) \
+ _##X##sh(55) \
+ _##X##sh(56) \
+ _##X##sh(57) \
+ _##X##sh(58) \
+ _##X##sh(59) \
+ _##X##sh(60) \
+ _##X##sh(61) \
+ _##X##sh(62) \
+ _##X##sh(63)
+#endif
+
+#define xsh(X) \
+ _##X##sh(0) \
+ _##X##sh(1) \
+ _##X##sh(2) \
+ _##X##sh(3) \
+ _##X##sh(4) \
+ _##X##sh(5) \
+ _##X##sh(6) \
+ _##X##sh(7) \
+ _##X##sh(8) \
+ _##X##sh(9) \
+ _##X##sh(10) \
+ _##X##sh(11) \
+ _##X##sh(12) \
+ _##X##sh(13) \
+ _##X##sh(14) \
+ _##X##sh(15) \
+ _##X##sh(16) \
+ _##X##sh(17) \
+ _##X##sh(18) \
+ _##X##sh(19) \
+ _##X##sh(20) \
+ _##X##sh(21) \
+ _##X##sh(22) \
+ _##X##sh(23) \
+ _##X##sh(24) \
+ _##X##sh(25) \
+ _##X##sh(26) \
+ _##X##sh(27) \
+ _##X##sh(28) \
+ _##X##sh(29) \
+ _##X##sh(30) \
+ _##X##sh(31) \
+ xsh64(X)
+
+#define lsh() \
+ xsh(l)
+
+#define rsh() \
+ xsh(r)
+
+#define rsh_u() \
+ xsh(ru)
+
+#define reset(V) \
+ jit_calli_3(_jit, memset, \
+ jit_operand_imm(JIT_OPERAND_ABI_POINTER, (jit_imm_t)buf),\
+ jit_operand_imm(JIT_OPERAND_ABI_INT32, V), \
+ jit_operand_imm(JIT_OPERAND_ABI_UINT32, M64 + 8));
+
+#define stx(T, N, O, V) \
+ jit_movi(_jit, JIT_R0, V); \
+ jit_movi(_jit, JIT_R1, O); \
+ jit_stxr##T(_jit, JIT_R1, JIT_V0, JIT_R0);
+
+#define stx8(T, M, V) \
+ stx(T, 3, (M##B3), V) \
+ stx(T, 4, (M##B4), V) \
+ stx(T, 5, (M##B5), V) \
+ stx(T, 6, (M##B6), V) \
+ stx(T, 7, (M##B7), V) \
+ stx(T, 8, (M##B8), V) \
+ stx(T, 9, (M##B9), V) \
+ stx(T, 10, (M##B10), V) \
+ stx(T, 11, (M##B11), V) \
+ stx(T, 12, (M##B12), V) \
+ stx(T, 13, (M##B13), V) \
+ stx(T, 14, (M##B14), V) \
+ stx(T, 15, (M##B15), V) \
+ stx(T, 16, (M##B16), V) \
+ stx(T, 17, (M##B17), V) \
+ stx(T, 18, (M##B18), V) \
+ stx(T, 19, (M##B19), V) \
+ stx(T, 20, (M##B20), V) \
+ stx(T, 21, (M##B21), V) \
+ stx(T, 22, (M##B22), V) \
+ stx(T, 23, (M##B23), V) \
+ stx(T, 24, (M##B24), V) \
+ stx(T, 25, (M##B25), V) \
+ stx(T, 26, (M##B26), V)
+
+#define stx4(T, M, V) \
+ stx(T, 2, (M##B2), V) \
+ stx8(T, M, V)
+
+#define stx2(T, M, V) \
+ stx(T, 1, (M##B1), V) \
+ stx4(T, M, V)
+
+#define ldx(T, N, M, O, V) \
+{ \
+ dump_args(T, N, M, O, V); \
+ jit_movi(_jit, JIT_R0, 0); \
+ jit_ldxi##T(_jit, JIT_R0, JIT_V0, O); \
+ jit_reloc_t r = jit_beqi(_jit, JIT_R0, V); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define ldx8(T, M, V) \
+ ldx(T, 3, M, (M##B3), V) \
+ ldx(T, 4, M, (M##B4), V) \
+ ldx(T, 5, M, (M##B5), V) \
+ ldx(T, 6, M, (M##B6), V) \
+ ldx(T, 7, M, (M##B7), V) \
+ ldx(T, 8, M, (M##B8), V) \
+ ldx(T, 9, M, (M##B9), V) \
+ ldx(T, 10, M, (M##B10), V) \
+ ldx(T, 11, M, (M##B11), V) \
+ ldx(T, 12, M, (M##B12), V) \
+ ldx(T, 13, M, (M##B13), V) \
+ ldx(T, 14, M, (M##B14), V) \
+ ldx(T, 15, M, (M##B15), V) \
+ ldx(T, 16, M, (M##B16), V) \
+ ldx(T, 17, M, (M##B17), V) \
+ ldx(T, 18, M, (M##B18), V) \
+ ldx(T, 19, M, (M##B19), V) \
+ ldx(T, 20, M, (M##B20), V) \
+ ldx(T, 21, M, (M##B21), V) \
+ ldx(T, 22, M, (M##B22), V) \
+ ldx(T, 23, M, (M##B23), V) \
+ ldx(T, 24, M, (M##B24), V) \
+ ldx(T, 25, M, (M##B25), V) \
+ ldx(T, 26, M, (M##B26), V)
+
+#define ldx4(T, M, V) \
+ ldx(T, 2, M, (M##B2), V) \
+ ldx8(T, M, V)
+
+#define ldx2(T, M, V) \
+ ldx(T, 1, M, (M##B1), V) \
+ ldx4(T, M, V)
+
+#define stf(T, N, O, V) \
+ jit_movi##T(_jit, JIT_F0, V); \
+ jit_movi(_jit, JIT_R0, O); \
+ jit_stxr##T(_jit, JIT_R0, JIT_V0, JIT_F0);
+
+#define stf8(T, M, V) \
+ stf(T, 3, (M##B3), V) \
+ stf(T, 4, (M##B4), V) \
+ stf(T, 5, (M##B5), V) \
+ stf(T, 6, (M##B6), V) \
+ stf(T, 7, (M##B7), V) \
+ stf(T, 8, (M##B8), V) \
+ stf(T, 9, (M##B9), V) \
+ stf(T, 10, (M##B10), V) \
+ stf(T, 11, (M##B11), V) \
+ stf(T, 12, (M##B12), V) \
+ stf(T, 13, (M##B13), V) \
+ stf(T, 14, (M##B14), V) \
+ stf(T, 15, (M##B15), V) \
+ stf(T, 16, (M##B16), V) \
+ stf(T, 17, (M##B17), V) \
+ stf(T, 18, (M##B18), V) \
+ stf(T, 19, (M##B19), V) \
+ stf(T, 20, (M##B20), V) \
+ stf(T, 21, (M##B21), V) \
+ stf(T, 22, (M##B22), V) \
+ stf(T, 23, (M##B23), V) \
+ stf(T, 24, (M##B24), V) \
+ stf(T, 25, (M##B25), V) \
+ stf(T, 26, (M##B26), V)
+
+#define stf4(T, M, V) \
+ stf(T, 2, (M##B2), V) \
+ stf8(T, M, V)
+
+#define ldf(T, N, M, O, V) \
+{ \
+ dump_args(T, N, M, O, V); \
+ jit_movi##T(_jit, JIT_F0, 0); \
+ jit_ldxi##T(_jit, JIT_F0, JIT_V0, O); \
+ jit_movi##T(_jit, JIT_F1, V); \
+ jit_reloc_t r = jit_beqr##T(_jit, JIT_F0, JIT_F1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define ldf8(T, M, V) \
+ ldf(T, 3, M, (M##B3), V) \
+ ldf(T, 4, M, (M##B4), V) \
+ ldf(T, 5, M, (M##B5), V) \
+ ldf(T, 6, M, (M##B6), V) \
+ ldf(T, 7, M, (M##B7), V) \
+ ldf(T, 8, M, (M##B8), V) \
+ ldf(T, 9, M, (M##B9), V) \
+ ldf(T, 10, M, (M##B10), V) \
+ ldf(T, 11, M, (M##B11), V) \
+ ldf(T, 12, M, (M##B12), V) \
+ ldf(T, 13, M, (M##B13), V) \
+ ldf(T, 14, M, (M##B14), V) \
+ ldf(T, 15, M, (M##B15), V) \
+ ldf(T, 16, M, (M##B16), V) \
+ ldf(T, 17, M, (M##B17), V) \
+ ldf(T, 18, M, (M##B18), V) \
+ ldf(T, 19, M, (M##B19), V) \
+ ldf(T, 20, M, (M##B20), V) \
+ ldf(T, 21, M, (M##B21), V) \
+ ldf(T, 22, M, (M##B22), V) \
+ ldf(T, 23, M, (M##B23), V) \
+ ldf(T, 24, M, (M##B24), V) \
+ ldf(T, 25, M, (M##B25), V) \
+ ldf(T, 26, M, (M##B26), V)
+#define ldf4(T, M, V) \
+ ldf(T, 2, M, (M##B2), V) \
+ ldf8(T, M, V)
+
+#define ldst_c() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx2(_c, a, 0x5a) \
+ ldx2(_c, a, 0x5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx2(_c, b, 0x5a) \
+ ldx2(_c, b, 0x5a)
+
+#define ldst_uc() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx2(_c, a, 0x5a) \
+ ldx2(_uc, a, 0x5a) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx2(_c, b, 0x5a) \
+ ldx2(_uc, b, 0x5a)
+
+#define ldst_s() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx2(_s, a, 0x5a5a) \
+ ldx2(_s, a, 0x5a5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx2(_s, b, 0x5a5a) \
+ ldx2(_s, b, 0x5a5a)
+
+#define ldst_us() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx2(_s, a, 0x5a5a) \
+ ldx2(_us, a, 0x5a5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx2(_s, b, 0x5a5a) \
+ ldx2(_us, b, 0x5a5a)
+
+#define ldst_i() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx4(_i, a, 0x5a5a5a5a) \
+ ldx4(_i, a, 0x5a5a5a5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx4(_i, b, 0x5a5a5a5a) \
+ ldx4(_i, b, 0x5a5a5a5a)
+
+#define ldst_ui() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx4(_i, a, 0x5a5a5a5a) \
+ ldx4(_ui, a, 0x5a5a5a5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx4(_i, b, 0x5a5a5a5a) \
+ ldx4(_ui, b, 0x5a5a5a5a)
+
+#define ldst_l() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stx8(_l, a, 0x5a5a5a5a5a5a5a5a) \
+ ldx8(_l, a, 0x5a5a5a5a5a5a5a5a) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stx8(_l, b, 0x5a5a5a5a5a5a5a5a) \
+ ldx8(_l, b, 0x5a5a5a5a5a5a5a5a)
+
+#define ldst_f() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stf4(_f, a, 0.5) \
+ ldf4(_f, a, 0.5) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stf4(_f, b, 0.5) \
+ ldf4(_f, b, 0.5)
+
+#define ldst_d() \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)buf); \
+ stf8(_d, a, 0.5) \
+ ldf8(_d, a, 0.5) \
+ reset(0xa5) \
+ jit_movi(_jit, JIT_V0, (jit_imm_t)(buf + M64)); \
+ stf8(_d, b, 0.5) \
+ ldf8(_d, b, 0.5)
+
+static size_t
+run_test(jit_state_t *_jit, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(_jit, arena_base, arena_size);
+ size_t frame = jit_enter_jit_abi(_jit, 3, 0, 0);
+
+ void (*function)(void);
+
+ char *buf = malloc(M64 + 8);
+ ASSERT(buf);
+
+ alu(add)
+ alu(sub)
+ alu(mul)
+ alu(div)
+ alu(rem)
+ lsh()
+ rsh()
+ alu(and)
+ alu(or)
+ alu(xor)
+ ldst_c()
+ ldst_uc()
+ ldst_s()
+ ldst_us()
+ ldst_i()
+#if __WORDSIZE == 64
+ ldst_ui()
+ ldst_l()
+#endif
+ ldst_f()
+ ldst_d()
+
+ jit_leave_jit_abi(_jit, 3, 0, frame);
+ jit_ret(_jit);
+
+ size_t size = 0;
+ function = jit_end(_jit, &size);
+
+ if (function)
+ (*function)();
+ else {
+ free(buf);
+ return size;
+ }
+
+ free(buf);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return main_compiler(argc, argv, run_test);
+}
diff --git a/deps/lightening/tests/z_stack.c b/deps/lightening/tests/z_stack.c
new file mode 100644
index 0000000..0ee9590
--- /dev/null
+++ b/deps/lightening/tests/z_stack.c
@@ -0,0 +1,374 @@
+#include "test.h"
+
+#if defined(DEBUG)
+#define dump_args(N, M, T) \
+ jit_calli_1(_jit, puts, \
+ jit_operand_imm(JIT_OPERAND_ABI_POINTER, \
+ (jit_imm_t)#N " " #M " " #T));
+#else
+#define dump_args(N, M, T)
+#endif
+
+#define szof_c 1
+#define szof_uc szof_c
+#define szof_s 2
+#define szof_us szof_s
+#define szof_i 4
+#if __WORDSIZE == 64
+# define szof_ui szof_i
+# define szof_l 8
+#endif
+#define szof_max 8
+
+#define operand_c JIT_OPERAND_ABI_INT8
+#define operand_uc JIT_OPERAND_ABI_UINT8
+#define operand_s JIT_OPERAND_ABI_INT16
+#define operand_us JIT_OPERAND_ABI_UINT16
+#define operand_i JIT_OPERAND_ABI_INT32
+#define operand_ui JIT_OPERAND_ABI_UINT32
+#define operand_l JIT_OPERAND_ABI_INT64
+#define operand_ul JIT_OPERAND_ABI_UINT64
+#define operand_f JIT_OPERAND_ABI_FLOAT
+#define operand_d JIT_OPERAND_ABI_DOUBLE
+
+#define FILL(T) \
+ void *fill##T = jit_address(_jit); \
+{ \
+ size_t frame = jit_enter_jit_abi(_jit, 2, 0, 0); \
+ jit_load_args_2(_jit, \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V0), \
+ jit_operand_gpr(JIT_OPERAND_ABI_UINT32, JIT_R0)); \
+ \
+ jit_muli(_jit, JIT_R0, JIT_R0, szof##T); \
+ jit_addr(_jit, JIT_V1, JIT_V0, JIT_R0); \
+ jit_movi(_jit, JIT_R0, 0); \
+ \
+ void *loop = jit_address(_jit); \
+ jit_reloc_t done = jit_bger(_jit, JIT_V0, JIT_V1); \
+ jit_str##T(_jit, JIT_V0, JIT_R0); \
+ jit_addi(_jit, JIT_R0, JIT_R0, 1); \
+ jit_addi(_jit, JIT_V0, JIT_V0, szof##T); \
+ jit_jmpi(_jit, loop); \
+ \
+ jit_patch_here(_jit, done); \
+ jit_leave_jit_abi(_jit, 2, 0, frame); \
+ jit_ret(_jit); \
+}
+
+#define fill_uc fill_c
+#define fill_us fill_s
+#define fill_ui fill_i
+
+#define ARG( T, N) jit_operand_mem(operand##T, JIT_SP, - ((N + 1) * szof##T))
+
+#define ARG1( K, T) ARG##K(T, 0)
+#define ARG2( K, T) ARG1( K, T), ARG##K(T, 1)
+#define ARG3( K, T) ARG2( K, T), ARG##K(T, 2)
+#define ARG4( K, T) ARG3( K, T), ARG##K(T, 3)
+#define ARG5( K, T) ARG4( K, T), ARG##K(T, 4)
+#define ARG6( K, T) ARG5( K, T), ARG##K(T, 5)
+#define ARG7( K, T) ARG6( K, T), ARG##K(T, 6)
+#define ARG8( K, T) ARG7( K, T), ARG##K(T, 7)
+#define ARG9( K, T) ARG8( K, T), ARG##K(T, 8)
+#define ARG10(K, T) ARG9( K, T), ARG##K(T, 9)
+#define ARG11(K, T) ARG10(K, T), ARG##K(T, 10)
+#define ARG12(K, T) ARG11(K, T), ARG##K(T, 11)
+#define ARG13(K, T) ARG12(K, T), ARG##K(T, 12)
+#define ARG14(K, T) ARG13(K, T), ARG##K(T, 13)
+#define ARG15(K, T) ARG14(K, T), ARG##K(T, 14)
+#define ARG16(K, T) ARG15(K, T), ARG##K(T, 15)
+#define ARG_c(N) ARG##N( , _c)
+#define ARG_uc(N) ARG##N( , _uc)
+#define ARG_s(N) ARG##N( , _s)
+#define ARG_us(N) ARG##N( , _us)
+#define ARG_i(N) ARG##N( , _i)
+#define ARG_ui(N) ARG##N( , _ui)
+#define ARG_l(N) ARG##N( , _l)
+#define ARG_f(N) ARG##N(F, _f)
+#define ARG_d(N) ARG##N(F, _d)
+
+#define CHK(N, T, V) \
+{ \
+ jit_ldxi##T(_jit, JIT_R0, JIT_SP, arg_space - ((V + 1) * szof##T)); \
+ jit_ldxi##T(_jit, JIT_R1, JIT_V0, (V * szof##T)); \
+ jit_reloc_t r = jit_beqr(_jit, JIT_R0, JIT_R1); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+}
+
+#define GET1( K, N, T, V) CHK##K(N, T, 0)
+#define GET2( K, N, T, V) GET1( K, N, T, V) CHK##K(N, T, 1)
+#define GET3( K, N, T, V) GET2( K, N, T, V) CHK##K(N, T, 2)
+#define GET4( K, N, T, V) GET3( K, N, T, V) CHK##K(N, T, 3)
+#define GET5( K, N, T, V) GET4( K, N, T, V) CHK##K(N, T, 4)
+#define GET6( K, N, T, V) GET5( K, N, T, V) CHK##K(N, T, 5)
+#define GET7( K, N, T, V) GET6( K, N, T, V) CHK##K(N, T, 6)
+#define GET8( K, N, T, V) GET7( K, N, T, V) CHK##K(N, T, 7)
+#define GET9( K, N, T, V) GET8( K, N, T, V) CHK##K(N, T, 8)
+#define GET10(K, N, T, V) GET9( K, N, T, V) CHK##K(N, T, 9)
+#define GET11(K, N, T, V) GET10(K, N, T, V) CHK##K(N, T, 10)
+#define GET12(K, N, T, V) GET11(K, N, T, V) CHK##K(N, T, 11)
+#define GET13(K, N, T, V) GET12(K, N, T, V) CHK##K(N, T, 12)
+#define GET14(K, N, T, V) GET13(K, N, T, V) CHK##K(N, T, 13)
+#define GET15(K, N, T, V) GET14(K, N, T, V) CHK##K(N, T, 14)
+#define GET16(K, N, T, V) GET15(K, N, T, V) CHK##K(N, T, 15)
+
+#define GET_c(N, M) GET##N( , c##N, _c, M)
+#define GET_uc(N, M) GET##N( , uc##N, _uc, M)
+#define GET_s(N, M) GET##N( , s##N, _s, M)
+#define GET_us(N, M) GET##N( , us##N, _us, M)
+#define GET_i(N, M) GET##N( , i##N, _i, M)
+#define GET_ui(N, M) GET##N( , ui##N, _ui, M)
+#define GET_l(N, M) GET##N( , l##N, _l, M)
+#define GET_f(N, M) GET##N(F, f##N, _f, M)
+#define GET_d(N, M) GET##N(F, d##N, _d, M)
+
+#define PUSH( T, V) jit_operand_imm(operand##T, V)
+#define PUSH0( K, T) /**/
+#define PUSH1( K, T) PUSH##K(T, 0)
+#define PUSH2( K, T) PUSH1( K, T), PUSH##K(T, 1)
+#define PUSH3( K, T) PUSH2( K, T), PUSH##K(T, 2)
+#define PUSH4( K, T) PUSH3( K, T), PUSH##K(T, 3)
+#define PUSH5( K, T) PUSH4( K, T), PUSH##K(T, 4)
+#define PUSH6( K, T) PUSH5( K, T), PUSH##K(T, 5)
+#define PUSH7( K, T) PUSH6( K, T), PUSH##K(T, 6)
+#define PUSH8( K, T) PUSH7( K, T), PUSH##K(T, 7)
+#define PUSH9( K, T) PUSH8( K, T), PUSH##K(T, 8)
+#define PUSH10(K, T) PUSH9( K, T), PUSH##K(T, 9)
+#define PUSH11(K, T) PUSH10(K, T), PUSH##K(T, 10)
+#define PUSH12(K, T) PUSH11(K, T), PUSH##K(T, 11)
+#define PUSH13(K, T) PUSH12(K, T), PUSH##K(T, 12)
+#define PUSH14(K, T) PUSH13(K, T), PUSH##K(T, 13)
+#define PUSH15(K, T) PUSH14(K, T), PUSH##K(T, 14)
+#define PUSH16(K, T) PUSH15(K, T), PUSH##K(T, 15)
+
+#define PUSH_c( N) PUSH##N( , _c)
+#define PUSH_uc(N) PUSH##N( , _uc)
+#define PUSH_s( N) PUSH##N( , _s)
+#define PUSH_us(N) PUSH##N( , _us)
+#define PUSH_i( N) PUSH##N( , _i)
+#define PUSH_ui(N) PUSH##N( , _ui)
+#define PUSH_l( N) PUSH##N( , _l)
+#define PUSH_f( N) PUSH##N(F, _f)
+#define PUSH_d( N) PUSH##N(F, _d)
+
+/* bottom function */
+#define DEF0(T) \
+ void *test##T##_0 = jit_address(_jit); \
+{ \
+ size_t frame = jit_enter_jit_abi(_jit, 0, 0, 0); \
+ dump_args(0, 0, T); \
+ jit_leave_jit_abi(_jit, 0, 0, frame); \
+ jit_ret(_jit); \
+}
+
+/*
+ * stack frame:
+ * | lightening reserved stuff - frame |
+ * |-----------------------------------| <- JIT_SP at entry
+ * | argument save area - arg_space |
+ * |-----------------------------------| <- JIT_SP during argument validation
+ * | stack buffer - stack |
+ * |-----------------------------------| <- JIT_SP during next call
+ *
+ * at entry, first push arguments in ascending order (0, 1, 2, ...)
+ * to stack, and afterwards move JIT_SP forward to not mess with the internal
+ * load_args stuff.
+ */
+#define DEFN(N, M, T) \
+ void *test##T##_##N = jit_address(_jit); \
+{ \
+ size_t frame = jit_enter_jit_abi(_jit, 3, 0, 0); \
+ jit_operand_t args[] = \
+ {jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V0), \
+ ARG##T(N)}; \
+ jit_load_args(_jit, N + 1, args); \
+ \
+ size_t arg_space = jit_align_stack(_jit, N * szof##T); \
+ \
+ dump_args(N, M, T); \
+ \
+ /* validate arguments */ \
+ GET##T(N, M) \
+ \
+ /* heap buffer in %v1 */ \
+ jit_calli_1(_jit, malloc, \
+ jit_operand_imm(JIT_OPERAND_ABI_UINT32, N * szof##T)); \
+ jit_retval(_jit, JIT_V1); \
+ \
+ /* copy stack buffer to heap buffer */ \
+ jit_calli_3(_jit, memcpy, \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V1), \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V0), \
+ jit_operand_imm(JIT_OPERAND_ABI_UINT32, N * szof##T)); \
+ \
+ /* stack buffer for next function in %v2 */ \
+ size_t stack = jit_align_stack(_jit, M * szof##T); \
+ jit_movr(_jit, JIT_V2, JIT_SP); \
+ \
+ /* fill stack buffer for next function */ \
+ jit_calli_2(_jit, fill##T, \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V2), \
+ jit_operand_imm(JIT_OPERAND_ABI_UINT32, M)); \
+ \
+ /* call next function */ \
+ jit_operand_t call_args[] = \
+ {jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V2), \
+ PUSH##T(M)}; \
+ jit_calli(_jit, test##T##_##M, M + 1, call_args); \
+ \
+ /* validate stack buffer */ \
+ jit_calli_3(_jit, memcmp, \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V1), \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V0), \
+ jit_operand_imm(JIT_OPERAND_ABI_UINT32, N * szof##T)); \
+ jit_retval(_jit, JIT_R0); \
+ jit_reloc_t r = jit_beqi(_jit, JIT_R0, 0); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+ \
+ /* release heap bufer */ \
+ jit_calli_1(_jit, free, \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V1)); \
+ jit_shrink_stack(_jit, arg_space); \
+ jit_shrink_stack(_jit, stack); \
+ jit_leave_jit_abi(_jit, 3, 0, frame); \
+ jit_ret(_jit); \
+}
+
+/* top function */
+#define DEFX(T) \
+ void *test##T##_17 = jit_address(_jit); \
+{ \
+ size_t frame = jit_enter_jit_abi(_jit, 3, 0, 0); \
+ size_t arg_space = jit_align_stack(_jit, 16 * szof##T); \
+ \
+ dump_args(17, top, T) \
+ \
+ /* heap buffer in %v1 */ \
+ jit_calli_1(_jit, malloc, \
+ jit_operand_imm(JIT_OPERAND_ABI_UINT32, 16 * szof##T)); \
+ jit_retval(_jit, JIT_V1); \
+ \
+ /* stack buffer for next function in %v2 */ \
+ size_t stack = jit_align_stack(_jit, 16 * szof##T); \
+ jit_movr(_jit, JIT_V2, JIT_SP); \
+ \
+ /* fill stack buffer for next function */ \
+ jit_calli_2(_jit, fill##T, \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V2), \
+ jit_operand_imm(JIT_OPERAND_ABI_UINT32, 16)); \
+ \
+ /* copy stack buffer to heap buffer */ \
+ jit_calli_3(_jit, memcpy, \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V1), \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V2), \
+ jit_operand_imm(JIT_OPERAND_ABI_UINT32, 16 * szof##T)); \
+ \
+ /* call next function */ \
+ jit_operand_t args[] = \
+ {jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V2), \
+ PUSH##T(16)}; \
+ jit_calli(_jit, test##T##_16, 17, args); \
+ \
+ /* validate stack buffer */ \
+ jit_calli_3(_jit, memcmp, \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V1), \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V2), \
+ jit_operand_imm(JIT_OPERAND_ABI_UINT32, 16 * szof##T)); \
+ jit_retval(_jit, JIT_R0); \
+ jit_reloc_t r = jit_beqi(_jit, JIT_R0, 0); \
+ jit_calli_0(_jit, abort); \
+ jit_patch_here(_jit, r); \
+ \
+ /* release heap bufer */ \
+ jit_calli_1(_jit, free, \
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_V1)); \
+ /* technically speaking not necessary */ \
+ /* jit_leave_jit_abi will shrink stack for us */ \
+ jit_shrink_stack(_jit, arg_space); \
+ jit_shrink_stack(_jit, stack); \
+ jit_leave_jit_abi(_jit, 3, 0, frame); \
+ jit_ret(_jit); \
+}
+
+#define DEF( T) \
+ DEF0( T) \
+ DEFN( 1, 0, T) \
+ DEFN( 2, 1, T) \
+ DEFN( 3, 2, T) \
+ DEFN( 4, 3, T) \
+ DEFN( 5, 4, T) \
+ DEFN( 6, 5, T) \
+ DEFN( 7, 6, T) \
+ DEFN( 8, 7, T) \
+ DEFN( 9, 8, T) \
+ DEFN(10, 9, T) \
+ DEFN(11, 10, T) \
+ DEFN(12, 11, T) \
+ DEFN(13, 12, T) \
+ DEFN(14, 13, T) \
+ DEFN(15, 14, T) \
+ DEFN(16, 15, T) \
+ DEFX(T)
+
+#define CALL(T) jit_calli_0(_jit, test##T##_17);
+
+static size_t
+run_test(jit_state_t *_jit, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(_jit, arena_base, arena_size);
+ int32_t (*function)();
+
+ jit_reloc_t main = jit_jmp(_jit);
+
+ FILL(_c)
+ FILL(_s)
+ FILL(_i)
+#if __WORDSIZE == 64
+ FILL(_l)
+#endif
+
+ DEF(_c)
+ DEF(_uc)
+ DEF(_s)
+ DEF(_us)
+ DEF(_i)
+#if __WORDSIZE == 64
+ DEF(_ui)
+ DEF(_l)
+#endif
+
+ jit_patch_here(_jit, main);
+ /* not sure about the actual number of registers, but too many can't
+ * hurt. */
+ size_t frame = jit_enter_jit_abi(_jit, 3, 0, 0);
+
+ CALL(_c)
+ CALL(_uc)
+ CALL(_s)
+ CALL(_us)
+ CALL(_i)
+#if __WORDSIZE == 64
+ CALL(_ui)
+ CALL(_l)
+#endif
+
+ jit_leave_jit_abi(_jit, 3, 0, frame);
+ jit_ret(_jit);
+
+ size_t size;
+ function = jit_end(_jit, &size);
+
+ if (function)
+ (*function)();
+ else
+ return size;
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return main_compiler(argc, argv, run_test);
+}