diff options
Diffstat (limited to 'deps/lightning/check')
124 files changed, 18276 insertions, 0 deletions
diff --git a/deps/lightning/check/3to2.ok b/deps/lightning/check/3to2.ok new file mode 100644 index 0000000..de2c040 --- /dev/null +++ b/deps/lightning/check/3to2.ok @@ -0,0 +1,22 @@ +0 +1 +1 +1 +0 +1 +1 +1 +0 +1 +1 +0 +1 +1 +1 +0 +1 +1 +1 +0 +1 +1 diff --git a/deps/lightning/check/3to2.tst b/deps/lightning/check/3to2.tst new file mode 100644 index 0000000..563cf85 --- /dev/null +++ b/deps/lightning/check/3to2.tst @@ -0,0 +1,118 @@ +.data 32 +dfmt: +.c "%1.0f\n" +ifmt: +.c "%d\n" + +.code + jmpi main + +#define def_test_double(a, b, c) \ + name test_double_##a##_##b##_##c \ +test_double_##a##_##b##_##c: \ + prolog \ + arg_d $d0 \ + arg_d $d1 \ + getarg_d %b $d0 \ + getarg_d %c $d1 \ + subr_d %a %b %c \ + retr_d %a \ + epilog +#define test_double(a, b, c, x, y) \ + prepare \ + pushargi_d x \ + pushargi_d y \ + finishi test_double_##a##_##b##_##c \ + retval_d %f0 \ + prepare \ + pushargi dfmt \ + ellipsis \ + pushargr_d %f0 \ + finishi @printf + +#define def_test_int(a, b, c) \ + name test_int_##a##_##b##_##c \ +test_int_##a##_##b##_##c: \ + prolog \ + arg $i0 \ + arg $i1 \ + getarg %b $i0 \ + getarg %c $i1 \ + subr %a %b %c \ + retr %a \ + epilog +#define test_int(a, b, c, x, y) \ + prepare \ + pushargi x \ + pushargi y \ + finishi test_int_##a##_##b##_##c \ + retval %r0 \ + prepare \ + pushargi ifmt \ + ellipsis \ + pushargr %r0 \ + finishi @printf + +def_test_double(f0, f0, f0) +def_test_double(f0, f0, f1) +def_test_double(f0, f1, f0) +def_test_double(f0, f1, f2) + +def_test_double(f3, f3, f3) +def_test_double(f3, f3, f1) +def_test_double(f3, f1, f3) +def_test_double(f3, f1, f2) + +def_test_double(f3, f0, f0) +def_test_double(f3, f0, f3) +def_test_double(f3, f3, f0) + +def_test_int(r0, r0, r0) +def_test_int(r0, r0, r1) +def_test_int(r0, r1, r0) +def_test_int(r0, r1, r2) + +def_test_int(v0, v0, v0) +def_test_int(v0, v0, r1) +def_test_int(v0, r1, v0) +def_test_int(v0, r1, r2) + +def_test_int(v0, r0, r0) +def_test_int(v0, r0, v0) +def_test_int(v0, v0, r0) + + + name main +main: + prolog + + test_double(f0, f0, f0, 3.0, 2.0) + test_double(f0, f0, f1, 3.0, 2.0) + test_double(f0, f1, f0, 3.0, 2.0) + test_double(f0, f1, f2, 3.0, 2.0) + + test_double(f3, f3, f3, 3.0, 2.0) + test_double(f3, f3, f1, 3.0, 2.0) + test_double(f3, f1, f3, 3.0, 2.0) + test_double(f3, f1, f2, 3.0, 2.0) + + test_double(f3, f0, f0, 3.0, 2.0) + test_double(f3, f0, f3, 3.0, 2.0) + test_double(f3, f3, f0, 3.0, 2.0) + + test_int(r0, r0, r0, 3, 2) + test_int(r0, r0, r1, 3, 2) + test_int(r0, r1, r0, 3, 2) + test_int(r0, r1, r2, 3, 2) + + test_int(v0, v0, v0, 3, 2) + test_int(v0, v0, r1, 3, 2) + test_int(v0, r1, v0, 3, 2) + test_int(v0, r1, r2, 3, 2) + + test_int(v0, r0, r0, 3, 2) + test_int(v0, r0, v0, 3, 2) + test_int(v0, v0, r0, 3, 2) + + ret + epilog diff --git a/deps/lightning/check/Makefile.am b/deps/lightning/check/Makefile.am new file mode 100644 index 0000000..e04f7ac --- /dev/null +++ b/deps/lightning/check/Makefile.am @@ -0,0 +1,318 @@ +# +# Copyright 2012-2019 Free Software Foundation, Inc. +# +# This file is part of GNU lightning. +# +# GNU lightning is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU lightning is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. +# + +AM_CFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE + +check_PROGRAMS = lightning ccall self setcode nodata ctramp carg cva_list + +lightning_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) +lightning_SOURCES = lightning.c + +ccall_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) +ccall_SOURCES = ccall.c + +self_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) +self_SOURCES = self.c + +setcode_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) +setcode_SOURCES = setcode.c + +nodata_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) +nodata_SOURCES = nodata.c + +ctramp_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) +ctramp_SOURCES = ctramp.c + +carg_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) +carg_SOURCES = carg.c + +cva_list_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) +cva_list_SOURCES = cva_list.c + +$(top_builddir)/lib/liblightning.la: + cd $(top_builddir)/lib; $(MAKE) $(AM_MAKEFLAGS) liblightning.la + +EXTRA_DIST = \ + 3to2.tst 3to2.ok \ + add.tst add.ok \ + align.tst align.ok \ + allocai.tst allocai.ok \ + allocar.tst allocar.ok \ + bp.tst bp.ok \ + divi.tst divi.ok \ + fib.tst fib.ok \ + rpn.tst rpn.ok \ + ldst.inc \ + ldstr.tst ldstr.ok \ + ldsti.tst ldsti.ok \ + ldstxr.tst ldstxr.ok \ + ldstxi.tst ldstxi.ok \ + ldstr-c.tst ldstr-c.ok \ + ldstxr-c.tst ldstxr-c.ok \ + ldstxi-c.tst ldstxi-c.ok \ + cvt.tst cvt.ok \ + hton.tst hton.ok \ + branch.tst branch.ok \ + alu.inc \ + alu_add.tst alu_add.ok \ + alux_add.tst alux_add.ok \ + alu_sub.tst alu_sub.ok \ + alux_sub.tst alux_sub.ok \ + alu_rsb.tst alu_rsb.ok \ + alu_mul.tst alu_mul.ok \ + alu_div.tst alu_div.ok \ + alu_rem.tst alu_rem.ok \ + alu_and.tst alu_and.ok \ + alu_or.tst alu_or.ok \ + alu_xor.tst alu_xor.ok \ + alu_lsh.tst alu_lsh.ok \ + alu_rsh.tst alu_rsh.ok \ + alu_com.tst alu_com.ok \ + alu_neg.tst alu_neg.ok \ + fop_abs.tst fop_abs.ok \ + fop_sqrt.tst fop_sqrt.ok \ + varargs.tst varargs.ok \ + stack.tst stack.ok \ + clobber.tst clobber.ok \ + carry.tst carry.ok \ + call.tst call.ok \ + float.tst float.ok \ + jmpr.tst jmpr.ok \ + put.tst put.ok \ + qalu.inc \ + qalu_mul.tst qalu_mul.ok \ + qalu_div.tst qalu_div.ok \ + range.tst range.ok \ + ranger.tst ranger.ok \ + ret.tst ret.ok \ + tramp.tst tramp.ok \ + va_list.tst va_list.ok \ + check.sh \ + check.x87.sh \ + check.arm.sh check.swf.sh \ + check.arm.swf.sh \ + check.arm4.swf.sh \ + check.nodata.sh \ + check.x87.nodata.sh \ + run-test all.tst + +base_TESTS = \ + 3to2 add align allocai \ + allocar bp divi fib rpn \ + ldstr ldsti \ + ldstxr ldstxi \ + ldstr-c ldstxr-c ldstxi-c \ + cvt hton branch \ + alu_add alux_add \ + alu_sub alux_sub alu_rsb \ + alu_mul alu_div alu_rem \ + alu_and alu_or alu_xor \ + alu_lsh alu_rsh \ + alu_com alu_neg \ + fop_abs fop_sqrt \ + varargs stack \ + clobber carry call \ + float jmpr put \ + qalu_mul qalu_div \ + range ranger ret tramp \ + va_list + +$(base_TESTS): check.sh + $(LN_S) $(srcdir)/check.sh $@ + +TESTS = $(base_TESTS) + +if test_x86_x87 +#x87_TESTS = $(addsuffix .x87, $(base_TESTS)) +x87_TESTS = \ + 3to2.x87 add.x87 allocai.x87 \ + allocar.x87 bp.x87 divi.x87 fib.x87 \ + rpn.x87 ldstr.x87 ldsti.x87 \ + ldstxr.x87 ldstxi.x87 \ + ldstr-c.x87 ldstxr-c.x87 ldstxi-c.x87 \ + cvt.x87 branch.x87 \ + alu_add.x87 alux_add.x87 \ + alu_sub.x87 alux_sub.x87 alu_rsb.x87 \ + alu_mul.x87 alu_div.x87 alu_rem.x87 \ + alu_and.x87 alu_or.x87 alu_xor.x87 \ + alu_lsh.x87 alu_rsh.x87 \ + alu_com.x87 alu_neg.x87 \ + fop_abs.x87 fop_sqrt.x87 \ + varargs.x87 stack.x87 \ + clobber.x87 carry.x87 call.x87 \ + float.x87 jmpr.x87 put.x87 \ + va_list.x87 +$(x87_TESTS): check.x87.sh + $(LN_S) $(srcdir)/check.x87.sh $@ +TESTS += $(x87_TESTS) + +#x87_nodata_TESTS = $(addsuffix .x87.nodata, $(base_TESTS)) +x87_nodata_TESTS = \ + 3to2.x87.nodata add.x87.nodata allocai.x87.nodata \ + allocar.x87.nodata bp.x87.nodata divi.x87.nodata fib.x87.nodata \ + rpn.x87.nodata ldstr.x87.nodata ldsti.x87.nodata \ + ldstxr.x87.nodata ldstxi.x87.nodata \ + ldstr-c.x87.nodata ldstxr-c.x87.nodata ldstxi-c.x87.nodata \ + cvt.x87.nodata branch.x87.nodata \ + alu_add.x87.nodata alux_add.x87.nodata \ + alu_sub.x87.nodata alux_sub.x87.nodata alu_rsb.x87.nodata \ + alu_mul.x87.nodata alu_div.x87.nodata alu_rem.x87.nodata \ + alu_and.x87.nodata alu_or.x87.nodata alu_xor.x87.nodata \ + alu_lsh.x87.nodata alu_rsh.x87.nodata \ + alu_com.x87.nodata alu_neg.x87.nodata \ + fop_abs.x87.nodata fop_sqrt.x87.nodata \ + varargs.x87.nodata stack.x87.nodata \ + clobber.x87.nodata carry.x87.nodata call.x87.nodata \ + float.x87.nodata jmpr.x87.nodata put.x87.nodata \ + va_list.x87.nodata +$(x87_nodata_TESTS): check.x87.nodata.sh + $(LN_S) $(srcdir)/check.x87.nodata.sh $@ +TESTS += $(x87_nodata_TESTS) +endif + +if test_arm_arm +#arm_TESTS = $(addsuffix .arm, $(base_TESTS)) +arm_TESTS = \ + 3to2.arm add.arm align.arm allocai.arm \ + allocar.arm bp.arm divi.arm fib.arm \ + rpn.arm ldstr.arm ldsti.arm \ + ldstxr.arm ldstxi.arm \ + ldstr-c.arm ldstxr-c.arm ldstxi-c.arm \ + cvt.arm hton.arm branch.arm \ + alu_add.arm alux_add.arm \ + alu_sub.arm alux_sub.arm alu_rsb.arm \ + alu_mul.arm alu_div.arm alu_rem.arm \ + alu_and.arm alu_or.arm alu_xor.arm \ + alu_lsh.arm alu_rsh.arm \ + alu_com.arm alu_neg.arm \ + fop_abs.arm fop_sqrt.arm \ + varargs.arm stack.arm \ + clobber.arm carry.arm call.arm \ + float.arm jmpr.arm tramp.arm range.arm \ + ranger.arm put.arm va_list.arm +$(arm_TESTS): check.arm.sh + $(LN_S) $(srcdir)/check.arm.sh $@ +TESTS += $(arm_TESTS) +endif + +if test_arm_swf +#swf_TESTS = $(addsuffix .swf, $(base_TESTS)) +swf_TESTS = \ + 3to2.swf add.swf allocai.swf \ + allocar.swf bp.swf divi.swf fib.swf \ + rpn.swf ldstr.swf ldsti.swf \ + ldstxr.swf ldstxi.swf \ + ldstr-c.swf ldstxr-c.swf ldstxi-c.swf \ + cvt.swf hton.swf branch.swf \ + alu_add.swf alux_add.swf \ + alu_sub.swf alux_sub.swf alu_rsb.swf \ + alu_mul.swf alu_div.swf alu_rem.swf \ + alu_and.swf alu_or.swf alu_xor.swf \ + alu_lsh.swf alu_rsh.swf \ + alu_com.swf alu_neg.swf \ + fop_abs.swf fop_sqrt.swf \ + varargs.swf stack.swf \ + clobber.swf carry.swf call.swf \ + float.swf jmpr.swf tramp.swf range.swf \ + ranger.swf put.swf va_list.swf +$(swf_TESTS): check.swf.sh + $(LN_S) $(srcdir)/check.swf.sh $@ +TESTS += $(swf_TESTS) +if test_arm_arm +#arm_swf_TESTS = $(addsuffix .arm.swf, $(base_TESTS)) +arm_swf_TESTS = \ + 3to2.arm.swf add.arm.swf allocai.arm.swf \ + allocar.arm.swf bp.arm.swf divi.arm.swf fib.arm.swf \ + rpn.arm.swf ldstr.arm.swf ldsti.arm.swf \ + ldstxr.arm.swf ldstxi.arm.swf \ + ldstr-c.arm.swf ldstxr-c.arm.swf ldstxi-c.arm.swf \ + cvt.arm.swf hton.arm.swf branch.arm.swf \ + alu_add.arm.swf alux_add.arm.swf \ + alu_sub.arm.swf alux_sub.arm.swf alu_rsb.arm.swf \ + alu_mul.arm.swf alu_div.arm.swf alu_rem.arm.swf \ + alu_and.arm.swf alu_or.arm.swf alu_xor.arm.swf \ + alu_lsh.arm.swf alu_rsh.arm.swf \ + alu_com.arm.swf alu_neg.arm.swf \ + fop_abs.arm.swf fop_sqrt.arm.swf \ + varargs.arm.swf stack.arm.swf \ + clobber.arm.swf carry.arm.swf call.arm.swf \ + float.arm.swf jmpr.arm.swf tramp.arm.swf range.arm.swf \ + ranger.arm.swf put.arm.swf va_list.arm.swf +$(arm_swf_TESTS): check.arm.swf.sh + $(LN_S) $(srcdir)/check.arm.swf.sh $@ +TESTS += $(arm_swf_TESTS) +endif +if test_arm_arm +#arm4_swf_TESTS = $(addsuffix .arm4.swf, $(base_TESTS)) +arm4_swf_TESTS = \ + 3to2.arm4.swf add.arm4.swf allocai.arm4.swf \ + allocar.arm4.swf bp.arm4.swf divi.arm4.swf fib.arm4.swf \ + rpn.arm4.swf ldstr.arm4.swf ldsti.arm4.swf \ + ldstxr.arm4.swf ldstxi.arm4.swf \ + ldstr-c.arm4.swf ldstxr-c.arm4.swf ldstxi-c.arm4.swf \ + cvt.arm4.swf hton.arm4.swf branch.arm4.swf \ + alu_add.arm4.swf alux_add.arm4.swf \ + alu_sub.arm4.swf alux_sub.arm4.swf alu_rsb.arm4.swf \ + alu_mul.arm4.swf alu_div.arm4.swf alu_rem.arm4.swf \ + alu_and.arm4.swf alu_or.arm4.swf alu_xor.arm4.swf \ + alu_lsh.arm4.swf alu_rsh.arm4.swf \ + alu_com.arm4.swf alu_neg.arm4.swf \ + fop_abs.arm4.swf fop_sqrt.arm4.swf \ + varargs.arm4.swf stack.arm4.swf \ + clobber.arm4.swf carry.arm4.swf call.arm4.swf \ + float.arm4.swf jmpr.arm4.swf tramp.arm4.swf \ + range.arm4.swf ranger.arm4.swf put.arm4.swf \ + va_list.arm4.swf +$(arm4_swf_TESTS): check.arm4.swf.sh + $(LN_S) $(srcdir)/check.arm4.swf.sh $@ +TESTS += $(arm4_swf_TESTS) +endif +endif + +if test_nodata +#nodata_TESTS = $(addsuffix .nodata, $(base_TESTS)) +nodata_TESTS = \ + 3to2.nodata add.nodata allocai.nodata \ + allocar.nodata bp.nodata divi.nodata fib.nodata \ + rpn.nodata ldstr.nodata ldsti.nodata \ + ldstxr.nodata ldstxi.nodata \ + ldstr-c.nodata ldstxr-c.nodata ldstxi-c.nodata \ + cvt.nodata branch.nodata \ + alu_add.nodata alux_add.nodata \ + alu_sub.nodata alux_sub.nodata alu_rsb.nodata \ + alu_mul.nodata alu_div.nodata alu_rem.nodata \ + alu_and.nodata alu_or.nodata alu_xor.nodata \ + alu_lsh.nodata alu_rsh.nodata \ + alu_com.nodata alu_neg.nodata \ + fop_abs.nodata fop_sqrt.nodata \ + varargs.nodata stack.nodata \ + clobber.nodata carry.nodata call.nodata \ + float.nodata jmpr.nodata tramp.nodata \ + range.nodata ranger.nodata put.nodata \ + va_list.nodata +$(nodata_TESTS): check.nodata.sh + $(LN_S) $(srcdir)/check.nodata.sh $@ +TESTS += $(nodata_TESTS) +endif + +TESTS += ccall self setcode nodata ctramp carg cva_list +CLEANFILES = $(TESTS) + +#TESTS_ENVIRONMENT=$(srcdir)/run-test; + +debug: lightning + $(LIBTOOL) --mode=execute gdb lightning + diff --git a/deps/lightning/check/add.ok b/deps/lightning/check/add.ok new file mode 100644 index 0000000..f5f322c --- /dev/null +++ b/deps/lightning/check/add.ok @@ -0,0 +1 @@ +5 + 4 = 9 diff --git a/deps/lightning/check/add.tst b/deps/lightning/check/add.tst new file mode 100644 index 0000000..9fc054d --- /dev/null +++ b/deps/lightning/check/add.tst @@ -0,0 +1,35 @@ +.data 32 +fmt: +.c "%d + %d = %d\n" + +.code + jmpi main + + name test +test: + prolog + arg $i0 + arg $i1 + getarg %r0 $i0 + getarg %r1 $i1 + addr %r0 %r0 %r1 + retr %r0 + epilog + + name main +main: + prolog + prepare + pushargi 5 + pushargi 4 + finishi test + retval %r0 + prepare + pushargi fmt + ellipsis + pushargi 5 + pushargi 4 + pushargr %r0 + finishi @printf + ret + epilog diff --git a/deps/lightning/check/align.ok b/deps/lightning/check/align.ok new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/deps/lightning/check/align.ok @@ -0,0 +1 @@ +10 diff --git a/deps/lightning/check/align.tst b/deps/lightning/check/align.tst new file mode 100644 index 0000000..5d5348c --- /dev/null +++ b/deps/lightning/check/align.tst @@ -0,0 +1,28 @@ +.data 32 +fmt: +.c "%d\n" +.code + prolog + movi %r0 1 + jmpi L1 /* should not generate this */ + align $(__WORDSIZE / 8) /* possible nops */ +L1: + bgei L4 %r0 10 + addi %r0 %r0 1 + jmpi L2 + movr %r1 %r0 /* to force jump generation */ + align $(__WORDSIZE / 8) /* possible nops */ +L2: + bgti L4 %r0 10 /* never executed */ + align $(__WORDSIZE / 8) /* possible nops */ +L3: + jmpi L1 + align $(__WORDSIZE / 8) /* possible nops */ +L4: + prepare + pushargi fmt + ellipsis + pushargr %r0 + finishi @printf + ret + epilog diff --git a/deps/lightning/check/all.tst b/deps/lightning/check/all.tst new file mode 100644 index 0000000..ac4fc97 --- /dev/null +++ b/deps/lightning/check/all.tst @@ -0,0 +1,415 @@ +.disasm // only disassemble +.code + prolog + allocai 32 $buf + arg $c + arg $uc + arg $s + arg $us + arg $i +#if __WORDSIZE == 64 + arg $ui + arg $l +#endif + getarg_c %r0 $c + getarg_uc %r0 $uc + getarg_s %r0 $s + getarg_us %r0 $us + getarg_i %r0 $i +#if __WORDSIZE == 64 + getarg_ui %r0 $ui + getarg_l %r0 $l +#endif + addr %r0 %r1 %r2 + addi %r0 %r1 2 + addcr %r0 %r1 %r2 + addci %r0 %r1 2 + addxr %r0 %r1 %r2 + addxi %r0 %r1 2 + subr %r0 %r1 %r2 + subi %r0 %r1 2 + subcr %r0 %r1 %r2 + subci %r0 %r1 2 + subxr %r0 %r1 %r2 + subxi %r0 %r1 2 + mulr %r0 %r1 %r2 + muli %r0 %r1 2 + qmulr %r0 %r1 %r2 %v0 + qmuli %r0 %r1 %r2 3 + qmulr_u %r0 %r1 %r2 %v0 + qmuli_u %r0 %r1 %r2 3 + divr %r0 %r1 %r2 + divi %r0 %r1 2 + divr_u %r0 %r1 %r2 + divi_u %r0 %r1 2 + qdivr %r0 %r1 %r2 %v0 + qdivi %r0 %r1 %r2 3 + qdivr_u %r0 %r1 %r2 %v0 + qdivi_u %r0 %r1 %r2 3 + remr %r0 %r1 %r2 + remi %r0 %r1 2 + remr_u %r0 %r1 %r2 + remi_u %r0 %r1 2 + andr %r0 %r1 %r2 + andi %r0 %r1 2 + orr %r0 %r1 %r2 + ori %r0 %r1 2 + xorr %r0 %r1 %r2 + xori %r0 %r1 2 + lshr %r0 %r1 %r2 + lshi %r0 %r1 2 + rshr %r0 %r1 %r2 + rshi %r0 %r1 2 + rshr_u %r0 %r1 %r2 + rshi_u %r0 %r1 2 + negr %r0 %r1 + comr %r0 %r1 + ltr %r0 %r1 %r2 + lti %r0 %r1 2 + ltr_u %r0 %r1 %r2 + lti_u %r0 %r1 2 + ler %r0 %r1 %r2 + lei %r0 %r1 2 + ler_u %r0 %r1 %r2 + lei_u %r0 %r1 2 + eqr %r0 %r1 %r2 + eqi %r0 %r1 2 + ger %r0 %r1 %r2 + gei %r0 %r1 2 + ger_u %r0 %r1 %r2 + gei_u %r0 %r1 2 + gtr %r0 %r1 %r2 + gti %r0 %r1 2 + gtr_u %r0 %r1 %r2 + gti_u %r0 %r1 2 + ner %r0 %r1 %r2 + nei %r0 %r1 2 + movr %r0 %r1 + movi %r0 1 + extr_c %r0 %r1 + extr_uc %r0 %r1 + extr_s %r0 %r1 + extr_us %r0 %r1 +#if __WORDSIZE == 64 + extr_i %r0 %r1 + extr_ui %r0 %r1 +#endif + htonr %r0 %r1 + ntohr %r0 %r1 + ldr_c %r0 %r1 + ldi_c %r0 0x80000000 + ldr_uc %r0 %r1 + ldi_uc %r0 0x80000000 + ldr_s %r0 %r1 + ldi_s %r0 0x80000000 + ldr_us %r0 %r1 + ldi_us %r0 0x80000000 + ldr_i %r0 %r1 + ldi_i %r0 0x80000000 +#if __WORDSIZE == 64 + ldr_ui %r0 %r1 + ldi_ui %r0 0x80000000 + ldr_l %r0 %r1 + ldi_l %r0 0x80000000 +#endif + ldxr_c %r0 %r1 %r2 + ldxi_c %r0 %r1 1 + ldxr_uc %r0 %r1 %r2 + ldxi_uc %r0 %r1 1 + ldxr_s %r0 %r1 %r2 + ldxi_s %r0 %r1 2 + ldxr_us %r0 %r1 %r2 + ldxi_us %r0 %r1 2 + ldxr_i %r0 %r1 %r2 + ldxi_i %r0 %r1 4 +#if __WORDSIZE == 64 + ldxr_ui %r0 %r1 %r2 + ldxi_ui %r0 %r1 4 + ldxr_l %r0 %r1 %r2 + ldxi_l %r0 %r1 8 +#endif + str_c %r1 %r0 + sti_c 0x80000000 %r1 + str_s %r1 %r0 + sti_s 0x80000000 %r1 + str_i %r1 %r0 + sti_i 0x80000000 %r1 +#if __WORDSIZE == 64 + str_l %r1 %r0 + sti_l 0x80000000 %r1 +#endif + stxr_c %r2 %r1 %r0 + stxi_c 1 %r1 %r0 + stxr_s %r2 %r1 %r0 + stxi_s 2 %r1 %r0 + stxr_i %r2 %r1 %r0 + stxi_i 4 %r1 %r0 +#if __WORDSIZE == 64 + stxr_l %r2 %r1 %r0 + stxi_l 8 %r1 %r0 +#endif +cond: + bltr cond %r0 %r1 +condi: + blti condi %r0 1 +condu: + bltr_u condu %r0 %r1 +condiu: + blti_u condiu %r0 1 + bler cond %r0 %r1 + blei condi %r0 1 + bler_u condu %r0 %r1 + blei_u condiu %r0 1 +bool: + beqr bool %r0 %r1 +booli: + beqi booli %r0 1 + bger cond %r0 %r1 + bgei condi %r0 1 + bger_u condu %r0 %r1 + bgei_u condiu %r0 1 + bgtr cond %r0 %r1 + bgti condi %r0 1 + bgtr_u condu %r0 %r1 + bgti_u condiu %r0 1 + bner bool %r0 %r1 + bnei booli %r0 1 +mask: + bmsr mask %r0 %r1 +maski: + bmsi maski %r0 1 + bmcr mask %r0 %r1 + bmci maski %r0 1 +as: + boaddr as %r0 %r1 +asi: + boaddi asi %r0 1 +asu: + boaddr_u as %r0 %r1 + boaddi_u asi %r0 1 + bxaddr as %r0 %r1 + bxaddi asi %r0 1 + bxaddr_u as %r0 %r1 + bxaddi_u asi %r0 1 + bosubr as %r0 %r1 + bosubi asi %r0 1 + bosubr_u as %r0 %r1 + bosubi_u asi %r0 1 + bxsubr as %r0 %r1 + bxsubi asi %r0 1 + bxsubr_u as %r0 %r1 + bxsubi_u asi %r0 1 +label: + jmpr %r0 + jmpi label + callr %r0 + calli label + prepare + pushargr %r0 + finishr %r0 + prepare + pushargi 1 + ellipsis + finishi 0x80000000 + ret + retr %r1 + reti 2 + retval_c %r1 + retval_uc %r1 + retval_s %r1 + retval_us %r1 + retval_i %r1 +#if __WORDSIZE == 64 + retval_ui %r1 + retval_l %r1 +#endif + arg_f $f + getarg_f %f1 $f + addr_f %f0 %f1 %f2 + addi_f %f0 %f1 0.5 + subr_f %f0 %f1 %f2 + subi_f %f0 %f1 0.5 + mulr_f %f0 %f1 %f2 + muli_f %f0 %f1 0.5 + divr_f %f0 %f1 %f2 + divi_f %f0 %f1 0.5 + negr_f %f0 %f1 + absr_f %f0 %f1 + sqrtr_f %f0 %f1 + ltr_f %r0 %f0 %f1 + lti_f %r0 %f0 0.5 + ler_f %r0 %f0 %f1 + lei_f %r0 %f0 0.5 + eqr_f %r0 %f0 %f1 + eqi_f %r0 %f0 0.5 + ger_f %r0 %f0 %f1 + gei_f %r0 %f0 0.5 + gtr_f %r0 %f0 %f1 + gti_f %r0 %f0 0.5 + ner_f %r0 %f0 %f1 + nei_f %r0 %f0 0.5 + unltr_f %r0 %f0 %f1 + unlti_f %r0 %f0 0.5 + unler_f %r0 %f0 %f1 + unlei_f %r0 %f0 0.5 + uneqr_f %r0 %f0 %f1 + uneqi_f %r0 %f0 0.5 + unger_f %r0 %f0 %f1 + ungei_f %r0 %f0 0.5 + ungtr_f %r0 %f0 %f1 + ungti_f %r0 %f0 0.5 + ltgtr_f %r0 %f0 %f1 + ltgti_f %r0 %f0 0.5 + ordr_f %r0 %f0 %f1 + ordi_f %r0 %f0 0.5 + unordr_f %r0 %f0 %f1 + unordi_f %r0 %f0 0.5 + truncr_f_i %r0 %f0 +#if __WORDSIZE == 64 + truncr_f_l %r0 %f0 +#endif + extr_f %f0 %r0 + extr_d_f %f0 %f1 + movr_f %f0 %f1 + movi_f %f0 1.5 + ldr_f %f0 %r0 + ldi_f %f0 0x80000000 + ldxr_f %f0 %r0 %r1 + ldxi_f %f0 %r0 4 + str_f %r0 %f0 + sti_f 0x80000000 %f0 + stxr_f %r1 %r0 %f0 + stxi_f 4 %r0 %f0 +/* FIXME the bordr_d at the end will cause an assertion on riscv due to + * too distant jump (does not fit in a 12 bit signed int) */ +ord: + bltr_f ord %f0 %f1 +ordi: + blti_f ordi %f0 0.5 + bler_f ord %f0 %f1 + blei_f ordi %f0 0.5 + beqr_f ord %f0 %f1 + beqi_f ordi %f0 0.5 + bger_f ord %f0 %f1 + bgei_f ordi %f0 0.5 + bgtr_f ord %f0 %f1 + bgti_f ordi %f0 0.5 + bner_f ord %f0 %f1 + bnei_f ordi %f0 0.5 +unord: + bunltr_f unord %f0 %f1 +unordi: + bunlti_f unordi %f0 0.5 + bunler_f unord %f0 %f1 + bunlei_f unordi %f0 0.5 + buneqr_f unord %f0 %f1 + buneqi_f unordi %f0 0.5 + bunger_f unord %f0 %f1 + bungei_f unordi %f0 0.5 + bungtr_f unord %f0 %f1 + bungti_f unordi %f0 0.5 + bltgtr_f unord %f0 %f1 + bltgti_f unordi %f0 0.5 + bordr_f unord %f0 %f1 + bordi_f unordi %f0 0.5 + bunordr_f unord %f0 %f1 + bunordi_f unordi %f0 0.5 + prepare + pushargr_f %f1 + pushargi_f 0.5 + finishi 0x80000000 + retr_f %f1 + reti_f 0.5 + retval_f %f1 + arg_d $f + getarg_d %f1 $f + addr_d %f0 %f1 %f2 + addi_d %f0 %f1 0.5 + subr_d %f0 %f1 %f2 + subi_d %f0 %f1 0.5 + mulr_d %f0 %f1 %f2 + muli_d %f0 %f1 0.5 + divr_d %f0 %f1 %f2 + divi_d %f0 %f1 0.5 + negr_d %f0 %f1 + absr_d %f0 %f1 + sqrtr_d %f0 %f1 + ltr_d %r0 %f0 %f1 + lti_d %r0 %f0 0.5 + ler_d %r0 %f0 %f1 + lei_d %r0 %f0 0.5 + eqr_d %r0 %f0 %f1 + eqi_d %r0 %f0 0.5 + ger_d %r0 %f0 %f1 + gei_d %r0 %f0 0.5 + gtr_d %r0 %f0 %f1 + gti_d %r0 %f0 0.5 + ner_d %r0 %f0 %f1 + nei_d %r0 %f0 0.5 + unltr_d %r0 %f0 %f1 + unlti_d %r0 %f0 0.5 + unler_d %r0 %f0 %f1 + unlei_d %r0 %f0 0.5 + uneqr_d %r0 %f0 %f1 + uneqi_d %r0 %f0 0.5 + unger_d %r0 %f0 %f1 + ungei_d %r0 %f0 0.5 + ungtr_d %r0 %f0 %f1 + ungti_d %r0 %f0 0.5 + ltgtr_d %r0 %f0 %f1 + ltgti_d %r0 %f0 0.5 + ordr_d %r0 %f0 %f1 + ordi_d %r0 %f0 0.5 + unordr_d %r0 %f0 %f1 + unordi_d %r0 %f0 0.5 + truncr_d_i %r0 %f0 +#if __WORDSIZE == 64 + truncr_d_l %r0 %f0 +#endif + extr_d %f0 %r0 + extr_f_d %f0 %f1 + movr_d %f0 %f1 + movi_d %f0 1.5 + ldr_d %f0 %r0 + ldi_d %f0 0x80000000 + ldxr_d %f0 %r0 %r1 + ldxi_d %f0 %r0 8 + str_d %r0 %f0 + sti_d 0x80000000 %f0 + stxr_d %r1 %r0 %f0 + stxi_d 8 %r0 %f0 + bltr_d ord %f0 %f1 + blti_d ordi %f0 0.5 + bler_d ord %f0 %f1 + blei_d ordi %f0 0.5 + beqr_d ord %f0 %f1 + beqi_d ordi %f0 0.5 + bger_d ord %f0 %f1 + bgei_d ordi %f0 0.5 + bgtr_d ord %f0 %f1 + bgti_d ordi %f0 0.5 + bner_d ord %f0 %f1 + bnei_d ordi %f0 0.5 + bunltr_d unord %f0 %f1 + bunlti_d unordi %f0 0.5 + bunler_d unord %f0 %f1 + bunlei_d unordi %f0 0.5 + buneqr_d unord %f0 %f1 + buneqi_d unordi %f0 0.5 + bunger_d unord %f0 %f1 + bungei_d unordi %f0 0.5 + bungtr_d unord %f0 %f1 + bungti_d unordi %f0 0.5 + bltgtr_d unord %f0 %f1 + bltgti_d unordi %f0 0.5 + bordr_d unord %f0 %f1 + bordi_d unordi %f0 0.5 + bunordr_d unord %f0 %f1 + bunordi_d unordi %f0 0.5 + prepare + pushargr_d %f1 + pushargi_d 0.5 + finishi 0x80000000 + retr_d %f1 + reti_d 0.5 + retval_d %f1 diff --git a/deps/lightning/check/allocai.ok b/deps/lightning/check/allocai.ok new file mode 100644 index 0000000..2962f7a --- /dev/null +++ b/deps/lightning/check/allocai.ok @@ -0,0 +1,2 @@ +received 7777 +succeeded diff --git a/deps/lightning/check/allocai.tst b/deps/lightning/check/allocai.tst new file mode 100644 index 0000000..c20cad0 --- /dev/null +++ b/deps/lightning/check/allocai.tst @@ -0,0 +1,100 @@ +.data 128 +idfmt: +.c "received %d\n" +failure_message: +.c "numbers don't add up to zero\n" +report_message: +.c "failed: got %i instead of %i\n" +succeeded_message: +.c "succeeded\n" + +.code + jmpi main + +/* +static int +identity (int arg) +{ + printf ("received %i\n", arg); + return arg; +} + */ + name identify +identify: + prolog + arg $i + getarg %v0 $i + prepare + pushargi idfmt + ellipsis + pushargr %v0 + finishi @printf + retr %v0 + epilog + + name identity_func +identity_func: + prolog + arg $i + getarg %r1 $i + + /* Store the argument on the stack. */ + allocai $(__WORDSIZE >> 3) $off + stxi $off %fp %r1 + + /* Store the negative of the argument on the stack. */ + allocai $(__WORDSIZE >> 3) $neg + negr %r2 %r1 + stxi $neg %fp %r2 + + /* Invoke FUNC. */ + prepare + pushargr %r1 + finishi identify + + /* Ignore the result. */ + + /* Restore the negative and the argument from the stack. */ + ldxi %r2 %fp $neg + ldxi %v1 %fp $off + + /* Make sure they still add to zero. */ + addr %r0 %v1 %r2 + bnei branch %r0 0 + + /* Return it. */ + retr %v1 + + /* Display a failure message. */ +branch: + prepare + pushargi failure_message + ellipsis + finishi @printf + + /* Leave. */ + retr %v1 + epilog + + name main +main: + prolog + prepare + pushargi 7777 + finishi identity_func + retval %r0 + beqi succeeded %r0 7777 + prepare + pushargi report_message + ellipsis + pushargr %r0 + pushargi 7777 + finishi @printf + reti 1 +succeeded: + prepare + pushargi succeeded_message + ellipsis + finishi @printf + reti 0 + epilog diff --git a/deps/lightning/check/allocar.ok b/deps/lightning/check/allocar.ok new file mode 100644 index 0000000..516b1e7 --- /dev/null +++ b/deps/lightning/check/allocar.ok @@ -0,0 +1,4 @@ +1 2 3 +3 4 5 +5 6 7 +7 8 9 diff --git a/deps/lightning/check/allocar.tst b/deps/lightning/check/allocar.tst new file mode 100644 index 0000000..e3ee010 --- /dev/null +++ b/deps/lightning/check/allocar.tst @@ -0,0 +1,403 @@ +#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_f 4 +#define szof_d 8 + +#define FILL(T) \ + name fill##T \ +fill##T: \ + prolog \ + arg $argp \ + getarg %v0 $argp \ + arg $argi \ + getarg %r0 $argi \ + muli %r0 %r0 szof##T \ + addr %v1 %v0 %r0 \ + movi %r0 0 \ +fill##T##loop: \ + bger fill##T##done %v0 %v1 \ + str##T %v0 %r0 \ + addi %r0 %r0 1 \ + addi %v0 %v0 szof##T \ + jmpi fill##T##loop \ +fill##T##done: \ + ret \ + epilog +#define FILLF(T) \ + name fill##T \ +fill##T: \ + prolog \ + arg $argp \ + getarg %v0 $argp \ + arg $argi \ + getarg %r0 $argi \ + muli %r0 %r0 szof##T \ + addr %v1 %v0 %r0 \ + movi##T %f0 0.0 \ +fill##T##loop: \ + bger fill##T##done %v0 %v1 \ + str##T %v0 %f0 \ + addi##T %f0 %f0 1.0 \ + addi %v0 %v0 szof##T \ + jmpi fill##T##loop \ +fill##T##done: \ + ret \ + epilog + +#define fill_uc fill_c +#define fill_us fill_s +#define fill_ui fill_i + +#define ARG( T, N) arg $arg##T##N +#define ARGF( T, N) arg##T $arg##T##N +#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) \ + getarg %r0 $arg##T##V \ + ldxi##T %r1 %v0 $(V * szof##T) \ + beqr N##T##V %r0 %r1 \ + calli @abort \ +N##T##V: +#define CHKF(N, T, V) \ + getarg##T %f0 $arg##T##V \ + ldxi##T %f1 %v0 $(V * szof##T) \ + beqr##T N##T##V %f0 %f1 \ + calli @abort \ +N##T##V: + +#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) pushargi V +#define PUSHF( T, V) pushargi##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) \ + name test##T##_0 \ +test##T##_0: \ + prolog \ + ret \ + epilog + +#define DEFN(N, M, T) \ + name test##T##_##N \ +test##T##_##N: \ + prolog \ + arg $argp \ + /* stack buffer in %v0 */ \ + getarg %v0 $argp \ + ARG##T(N) \ + /* validate arguments */ \ + GET##T(N, M) \ + /* heap buffer in %v1 */ \ + prepare \ + pushargi $(N * szof##T) \ + finishi @malloc \ + retval %v1 \ + /* copy stack bufer to heap buffer */ \ + prepare \ + pushargr %v1 \ + pushargr %v0 \ + pushargi $(N * szof##T) \ + finishi MEMCPY \ + /* stack buffer for next function in %v2 */ \ + movi %r0 $(M * szof##T) \ + allocar %v2 %r0 \ + addr %v2 %v2 %fp \ + /* fill stack buffer for next function */ \ + prepare \ + pushargr %v2 \ + pushargi M \ + finishi fill##T \ + /* call next function */ \ + prepare \ + pushargr %v2 \ + PUSH##T(M) \ + finishi test##T##_##M \ + /* validate stack buffer */ \ + prepare \ + pushargr %v1 \ + pushargr %v0 \ + pushargi $(N * szof##T) \ + finishi @memcmp \ + retval %r0 \ + beqi test##T##_##N##_done %r0 0 \ + calli @abort \ +test##T##_##N##_done: \ + /* release heap bufer */ \ + prepare \ + pushargr %v1 \ + finishi @free \ + ret \ + epilog + +/* top function */ +#define DEFX(T) \ + name test##T##_17 \ +test##T##_17: \ + prolog \ + /* heap buffer in %v1 */ \ + prepare \ + pushargi $(16 * szof##T) \ + finishi @malloc \ + retval %v1 \ + /* stack buffer for next function in %v2 */ \ + movi %r0 $(16 * szof##T) \ + allocar %v2 %r0 \ + addr %v2 %v2 %fp \ + /* fill stack buffer for next function */ \ + prepare \ + pushargr %v2 \ + pushargi 16 \ + finishi fill##T \ + /* copy stack buffer to heap buffer */ \ + prepare \ + pushargr %v1 \ + pushargr %v2 \ + pushargi $(16 * szof##T) \ + finishi MEMCPY \ + /* call next function */ \ + prepare \ + pushargr %v2 \ + PUSH##T(16) \ + finishi test##T##_16 \ + /* validate stack buffer */ \ + prepare \ + pushargr %v1 \ + pushargr %v2 \ + pushargi $(16 * szof##T) \ + finishi @memcmp \ + retval %r0 \ + beqi test##T##_17_done %r0 0 \ + calli @abort \ +test##T##_17_done: \ + /* release heap bufer */ \ + prepare \ + pushargr %v1 \ + finishi @free \ + ret \ + epilog + +#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) calli test##T##_17 + +.data 16 +fmt: +.c "%d %d %d\n" +.code + jmpi main + +#if _AIX +# define MEMCPY memcpy +/* error: Function not implemented (memcpy) */ + name memcpy +memcpy: + prolog + arg $dst + arg $src + arg $len + getarg %r0 $dst + getarg %r1 $src + getarg %r2 $len + movr %v1 %r0 + blti memcpy_done %r2 1 +memcpy_loop: + subi %r2 %r2 1 + ldxr_c %v0 %r1 %r2 + stxr_c %r2 %r0 %v0 + bgti memcpy_loop %r2 0 +memcpy_done: + retr %v1 + epilog +#else +# define MEMCPY @memcpy +#endif + + FILL(_c) + FILL(_s) + FILL(_i) +#if __WORDSIZE == 64 + FILL(_l) +#endif + FILLF(_f) + FILLF(_d) + + DEF(_c) + DEF(_uc) + DEF(_s) + DEF(_us) + DEF(_i) +#if __WORDSIZE == 64 + DEF(_ui) + DEF(_l) +#endif + DEF(_f) + DEF(_d) + + name main +main: + prolog + + CALL(_c) + CALL(_uc) + CALL(_s) + CALL(_us) + CALL(_i) +#if __WORDSIZE == 64 + CALL(_ui) + CALL(_l) +#endif + CALL(_f) + CALL(_d) + + // loop control + movi %v2 1 + + // loop a few times calling allocar +loop: + // allocate 12 bytes + movi %r0 12 + allocar %v0 %r0 + + // offset + movr %v1 %v0 + + // 1 + stxr_i %v1 %fp %v2 + + // 2 + addi %v2 %v2 1 + addi %v1 %v1 4 + stxr_i %v1 %fp %v2 + + // 3 + addi %v2 %v2 1 + addi %v1 %v1 4 + stxr_i %v1 %fp %v2 + + // reload + movr %v1 %v0 + + // 1 + ldxr_i %r0 %fp %v1 + + // 2 + addi %v1 %v1 4 + ldxr_i %r1 %fp %v1 + + // 3 + addi %v1 %v1 4 + ldxr_i %r2 %fp %v1 + + prepare + pushargi fmt + ellipsis + pushargr %r0 + pushargr %r1 + pushargr %r2 + finishi @printf + blti loop %v2 9 + + ret + epilog diff --git a/deps/lightning/check/alu.inc b/deps/lightning/check/alu.inc new file mode 100644 index 0000000..0c259ea --- /dev/null +++ b/deps/lightning/check/alu.inc @@ -0,0 +1,360 @@ +.data 8 +ok: +.c "ok\n" + +/* ia64 code generation is not optimized for size, and also some + * codes generate quite long sequences due to need for stops causing + * no code template match and needing to add nops, and other cases + * are division/remainder that needs function calls, or float division + * that requires a quite long sequence. + * (the brute force tests of all register combinations can easily + * generate several GB of jit). + */ + +/* 3 operand */ + +/* reg0 = reg1 op reg2 */ +#define ALUR(N, T, OP, I0, I1, V, R0, R1, R2) \ + movi %R1 I0 \ + movi %R2 I1 \ + OP##r##T %R0 %R1 %R2 \ + beqi OP##T##N##r_##R0##R1##R2 %R0 V \ + calli @abort \ +OP##T##N##r_##R0##R1##R2: + +/* reg0 = reg1 op im */ +#define ALUI(N, T, OP, I0, I1, V, R0, R1, R2) \ + movi %R1 I0 \ + movi %R2 V \ + OP##i##T %R0 %R1 I1 \ + beqr OP##T##N##i_##R0##R1##R2 %R0 %R2 \ + calli @abort \ +OP##T##N##i_##R0##R1##R2: + +/* reg0 = reg0 op reg1 */ +#define ALUR0(N, T, OP, I0, I1, V, R0, R1, R2) \ + movi %R0 I0 \ + movi %R1 I1 \ + movi %R2 V \ + OP##r##T %R0 %R0 %R1 \ + beqr OP##T##N##r_0##R0##R1##R2 %R0 %R2 \ + calli @abort \ +OP##T##N##r_0##R0##R1##R2: + +/* reg0 = reg1 op reg0 */ +#define ALUR1(N, T, OP, I0, I1, V, R0, R1, R2) \ + movi %R0 I1 \ + movi %R1 I0 \ + movi %R2 V \ + OP##r##T %R0 %R1 %R0 \ + beqr OP##T##N##r_1##R0##R1##R2 %R0 %R2 \ + calli @abort \ +OP##T##N##r_1##R0##R1##R2: + +/* reg0 = reg0 op im */ +#define ALUI0(N, T, OP, I0, I1, V, R0, R1, R2) \ + movi %R0 I0 \ + movi %R1 V \ + OP##i##T %R0 %R0 I1 \ + beqr OP##T##N##i_0##R0##R1##R2 %R0 %R1 \ + calli @abort \ +OP##T##N##i_0##R0##R1##R2: + +#define ALU3(N, T, OP, I0, I1, V, R0, R1, R2) \ + ALUR(N, T, OP, I0, I1, V, R0, R1, R2) \ + ALUI(N, T, OP, I0, I1, V, R0, R1, R2) \ + ALUR0(N, T, OP, I0, I1, V, R0, R1, R2) \ + ALUR1(N, T, OP, I0, I1, V, R0, R1, R2) \ + ALUI0(N, T, OP, I0, I1, V, R0, R1, R2) + +#define ALU2(N, T, OP, I0, I1, V, R0, R1, R2) \ + ALU3(N, T, OP, I0, I1, V, R0, R1, R2) \ + ALU3(N, T, OP, I0, I1, V, R0, R2, R1) + +#define ALU1(N, T, OP, I0, I1, V, R0, R1, R2) \ + ALU2(N, T, OP, I0, I1, V, R0, R1, R2) \ + ALU2(N, T, OP, I0, I1, V, R1, R0, R2) \ + ALU2(N, T, OP, I0, I1, V, R2, R1, R0) + +#if __ia64__ +# define ALU(N, T, OP, I0, I1, V) \ + ALU3(N, T, OP, I0, I1, V, r0, r1, r2) \ + ALU3(N, T, OP, I0, I1, V, v0, v1, v2) +#else +# define ALU(N, T, OP, I0, I1, V) \ + ALU1(N, T, OP, I0, I1, V, v0, v1, v2) \ + ALU1(N, T, OP, I0, I1, V, v0, v1, r0) \ + ALU1(N, T, OP, I0, I1, V, v0, v1, r1) \ + ALU1(N, T, OP, I0, I1, V, v0, v1, r2) \ + ALU1(N, T, OP, I0, I1, V, v1, v2, r1) \ + ALU1(N, T, OP, I0, I1, V, v1, v2, r2) \ + ALU1(N, T, OP, I0, I1, V, v2, r0, r1) \ + ALU1(N, T, OP, I0, I1, V, v2, r0, r2) \ + ALU1(N, T, OP, I0, I1, V, r0, r1, r2) +#endif + +/* 3 carry set/propagate */ + +/* + * r0 = i0 + * r1 = i1 + * r2 = 0 + * r0 = r0 opc r1 <only want carry> + * r2 = r2 opx r2 <r2 must match v> + */ +#define ALUXII(N, OP, I0, I1, V, R0, R1, R2) \ + movi %R0 I0 \ + movi %R2 0 \ + OP##ci %R0 %R0 I1 \ + OP##xi %R2 %R2 0 \ + beqi OP##N##ii##R0##R1##R2 %R2 V \ + calli @abort \ +OP##N##ii##R0##R1##R2: + +#define ALUXIR(N, OP, I0, I1, V, R0, R1, R2) \ + movi %R0 I0 \ + movi %R2 0 \ + OP##ci %R0 %R0 I1 \ + OP##xr %R2 %R2 %R2 \ + beqi OP##N##ir##R0##R1##R2 %R2 V \ + calli @abort \ +OP##N##ir##R0##R1##R2: + +#define ALUXRI(N, OP, I0, I1, V, R0, R1, R2) \ + movi %R0 I0 \ + movi %R1 I1 \ + movi %R2 0 \ + OP##cr %R0 %R0 %R1 \ + OP##xi %R2 %R2 0 \ + beqi OP##N##ri##R0##R1##R2 %R2 V \ + calli @abort \ +OP##N##ri##R0##R1##R2: + +#define ALUXRR(N, OP, I0, I1, V, R0, R1, R2) \ + movi %R0 I0 \ + movi %R1 I1 \ + movi %R2 0 \ + OP##cr %R0 %R0 %R1 \ + OP##xr %R2 %R2 %R2 \ + beqi OP##N##rr##R0##R1##R2 %R2 V \ + calli @abort \ +OP##N##rr##R0##R1##R2: + +#define ALUX2(N, OP, I0, I1, V, R0, R1, R2) \ + ALUXII(N, OP, I0, I1, V, R0, R1, R2) \ + ALUXIR(N, OP, I0, I1, V, R0, R1, R2) \ + ALUXRI(N, OP, I0, I1, V, R0, R1, R2) \ + ALUXRR(N, OP, I0, I1, V, R0, R1, R2) + +#define ALUX1(N, OP, I0, I1, V, R0, R1, R2) \ + ALUX2(N, OP, I0, I1, V, R0, R1, R2) \ + ALUX2(N, OP, I0, I1, V, R0, R2, R1) + +#define ALUX0(N, OP, I0, I1, V, R0, R1, R2) \ + ALUX1(N, OP, I0, I1, V, R0, R1, R2) \ + ALUX1(N, OP, I0, I1, V, R1, R0, R2) \ + ALUX1(N, OP, I0, I1, V, R2, R1, R0) + +#if __ia64__ +# define ALUX(N, OP, I0, I1, V) \ + ALUX2(N, OP, I0, I1, V, r0, r1, r2) \ + ALUX2(N, OP, I0, I1, V, v0, v1, v2) +#else +# define ALUX(N, OP, I0, I1, V) \ + ALUX0(N, OP, I0, I1, V, v0, v1, v2) \ + ALUX0(N, OP, I0, I1, V, v0, v1, r0) \ + ALUX0(N, OP, I0, I1, V, v0, v1, r1) \ + ALUX0(N, OP, I0, I1, V, v0, v1, r2) \ + ALUX0(N, OP, I0, I1, V, v1, v2, r0) \ + ALUX0(N, OP, I0, I1, V, v1, v2, r1) \ + ALUX0(N, OP, I0, I1, V, v1, v2, r2) \ + ALUX0(N, OP, I0, I1, V, v2, r0, r1) \ + ALUX0(N, OP, I0, I1, V, v2, r0, r2) \ + ALUX0(N, OP, I0, I1, V, r0, r1, r2) +#endif + +/* unary int */ + +#define UNR(N, OP, I, V, R0, R1) \ + movi %R1 I \ + OP##r %R0 %R1 \ + beqi OP##N##R0##R1 %R0 V \ + calli @abort \ +OP##N##R0##R1: + +#define UNRC(N, OP, I, V, R0, R1) \ + movi %R0 I \ + OP##r %R0 %R0 \ + beqi OP##N##c##R0##R1 %R0 V \ + calli @abort \ +OP##N##c##R0##R1: + +#define UN2(N, OP, I, V, R0, R1) \ + UNR(N, OP, I, V, R0, R1) \ + UNRC(N, OP, I, V, R0, R1) + +#define UN1(N, OP, I, V, R0, R1) \ + UN2(N, OP, I, V, R0, R1) \ + UN2(N, OP, I, V, R1, R0) + +#if __ia64__ +# define UN(N, OP, I, V) \ + UN2(N, OP, I, V, r0, r1) \ + UN2(N, OP, I, V, v0, v1) +#else +# define UN(N, OP, I, V) \ + UN1(N, OP, I, V, v0, v1) \ + UN1(N, OP, I, V, v0, v2) \ + UN1(N, OP, I, V, v0, r0) \ + UN1(N, OP, I, V, v0, r1) \ + UN1(N, OP, I, V, v0, r2) \ + UN1(N, OP, I, V, v1, v2) \ + UN1(N, OP, I, V, v1, r0) \ + UN1(N, OP, I, V, v1, r1) \ + UN1(N, OP, I, V, v1, r2) \ + UN1(N, OP, I, V, v2, r0) \ + UN1(N, OP, I, V, v2, r1) \ + UN1(N, OP, I, V, v2, r2) \ + UN1(N, OP, I, V, r0, r1) \ + UN1(N, OP, I, V, r0, r2) \ + UN1(N, OP, I, V, r1, r2) +#endif + +/* reg0 = reg1 op reg2 */ +#define FOPR(N, T, OP, I0, I1, V, F0, F1, F2) \ + movi##T %F1 I0 \ + movi##T %F2 I1 \ + OP##r##T %F0 %F1 %F2 \ + beqi##T OP##T##N##F0##F1##F2 %F0 V \ + calli @abort \ +OP##T##N##F0##F1##F2: + +/* reg0 = reg0 op reg1 */ +#define FOPR0(N, T, OP, I0, I1, V, F0, F1, F2) \ + movi##T %F0 I0 \ + movi##T %F1 I1 \ + OP##r##T %F0 %F0 %F1 \ + beqi##T OP##T##N##0##F0##F1##F2 %F0 V \ + calli @abort \ +OP##T##N##0##F0##F1##F2: + +/* reg1 = reg0 op reg1 */ +#define FOPR1(N, T, OP, I0, I1, V, F0, F1, F2) \ + movi##T %F0 I0 \ + movi##T %F1 I1 \ + OP##r##T %F1 %F0 %F1 \ + beqi##T OP##T##N##1##F0##F1##F2 %F1 V \ + calli @abort \ +OP##T##N##1##F0##F1##F2: + +/* reg0 = reg1 op im */ +#define FOPI(N, T, OP, I0, I1, V, F0, F1, F2) \ + movi##T %F1 I0 \ + movi##T %F2 V \ + OP##i##T %F0 %F1 I1 \ + beqr##T OP##T##N##i##F0##F1##F2 %F0 %F2 \ + calli @abort \ +OP##T##N##i##F0##F1##F2: + +/* reg0 = reg0 op im */ +#define FOPI0(N, T, OP, I0, I1, V, F0, F1, F2) \ + movi##T %F0 I0 \ + movi##T %F2 V \ + OP##i##T %F0 %F0 I1 \ + beqr##T OP##T##N##i0##F0##F1##F2 %F0 %F2 \ + calli @abort \ +OP##T##N##i0##F0##F1##F2: + +#define FOP1(N, T, OP, I0, I1, V, F0, F1, F2) \ + FOPR(N, T, OP, I0, I1, V, F0, F1, F2) \ + FOPR0(N, T, OP, I0, I1, V, F0, F1, F2) \ + FOPR1(N, T, OP, I0, I1, V, F0, F1, F2) \ + FOPI(N, T, OP, I0, I1, V, F0, F1, F2) \ + FOPI0(N, T, OP, I0, I1, V, F0, F1, F2) + +#if __ia64__ +# define FOP(N, T, OP, I0, I1, V) \ + FOP1(N, T, OP, I0, I1, V, f0, f1, f2) +#else +# define FOP(N, T, OP, I0, I1, V) \ + FOP1(N, T, OP, I0, I1, V, f0, f1, f2) \ + FOP1(N, T, OP, I0, I1, V, f0, f2, f3) \ + FOP1(N, T, OP, I0, I1, V, f0, f3, f4) \ + FOP1(N, T, OP, I0, I1, V, f0, f5, f1) +#endif + +/* unary float */ + +#define FUNR(N, T, OP, I, V, R0, R1) \ + movi##T %R1 I \ + OP##r##T %R0 %R1 \ + beqi##T OP##N##T##R0##R1 %R0 V \ + calli @abort \ +OP##N##T##R0##R1: + +#define FUNRC(N, T, OP, I, V, R0, R1) \ + movi##T %R0 I \ + OP##r##T %R0 %R0 \ + beqi##T OP##N##T##c##R0##R1 %R0 V \ + calli @abort \ +OP##N##T##c##R0##R1: + +#define FUN2(N, T, OP, I, V, R0, R1) \ + FUNR(N, T, OP, I, V, R0, R1) \ + FUNRC(N, T, OP, I, V, R0, R1) + +#define FUN1(N, T, OP, I, V, R0, R1) \ + FUN2(N, T, OP, I, V, R0, R1) \ + FUN2(N, T, OP, I, V, R1, R0) + +#if __ia64__ +# define FUN(N, T, OP, I, V) \ + FUN2(N, T, OP, I, V, f0, f1) +#else +# define FUN(N, T, OP, I, V) \ + FUN1(N, T, OP, I, V, f0, f1) \ + FUN1(N, T, OP, I, V, f0, f2) \ + FUN1(N, T, OP, I, V, f0, f3) \ + FUN1(N, T, OP, I, V, f0, f4) \ + FUN1(N, T, OP, I, V, f0, f5) +#endif + +/* unordered comparison unary float */ + +#define UFUNR(N, T, OP, I, V, R0, R1) \ + movi##T %R1 I \ + OP##r##T %R0 %R1 \ + buneqi##T OP##N##T##u##R0##R1 %R0 V \ + calli @abort \ +OP##N##T##u##R0##R1: + +#define UFUNRC(N, T, OP, I, V, R0, R1) \ + movi##T %R0 I \ + OP##r##T %R0 %R0 \ + buneqi##T OP##N##T##uc##R0##R1 %R0 V \ + calli @abort \ +OP##N##T##uc##R0##R1: + +#define UFUN2(N, T, OP, I, V, R0, R1) \ + UFUNR(N, T, OP, I, V, R0, R1) \ + UFUNRC(N, T, OP, I, V, R0, R1) + +#define UFUN1(N, T, OP, I, V, R0, R1) \ + UFUN2(N, T, OP, I, V, R0, R1) \ + UFUN2(N, T, OP, I, V, R1, R0) + +#if __ia64__ +# define UFUN(N, T, OP, I, V) \ + UFUN2(N, T, OP, I, V, f0, f1) +#else +# define UFUN(N, T, OP, I, V) \ + UFUN1(N, T, OP, I, V, f0, f1) \ + UFUN1(N, T, OP, I, V, f0, f2) \ + UFUN1(N, T, OP, I, V, f0, f3) \ + UFUN1(N, T, OP, I, V, f0, f4) \ + UFUN1(N, T, OP, I, V, f0, f5) +#endif + +. $( $NaN = 0.0/0.0) +. $( $Inf = 1.0/0.0) +. $($nInf = -1.0/0.0) diff --git a/deps/lightning/check/alu_add.ok b/deps/lightning/check/alu_add.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_add.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_add.tst b/deps/lightning/check/alu_add.tst new file mode 100644 index 0000000..16cdf38 --- /dev/null +++ b/deps/lightning/check/alu_add.tst @@ -0,0 +1,47 @@ +#include "alu.inc" + +.code + prolog + +#define ADD(N, I0, I1, V) ALU(N, , add, I0, I1, V) + + ADD(0, 0x7fffffff, 1, 0x80000000) + ADD(1, 1, 0x7fffffff, 0x80000000) + ADD(2, 0x80000000, 1, 0x80000001) + ADD(3, 1, 0x80000000, 0x80000001) + ADD(4, 0x7fffffff, 0x80000000, 0xffffffff) + ADD(5, 0x80000000, 0x7fffffff, 0xffffffff) + ADD(6, 0x7fffffff, 0, 0x7fffffff) + ADD(7, 0, 0x7fffffff, 0x7fffffff) +#if __WORDSIZE == 32 + ADD(8, 0x7fffffff, 0xffffffff, 0x7ffffffe) + ADD(9, 0xffffffff, 0x7fffffff, 0x7ffffffe) + ADD(10, 0xffffffff, 0xffffffff, 0xfffffffe) +#else + ADD(8, 0x7fffffff, 0xffffffff, 0x17ffffffe) + ADD(9, 0xffffffff, 0x7fffffff, 0x17ffffffe) + ADD(10, 0xffffffff, 0xffffffff, 0x1fffffffe) + ADD(11, 0x7fffffffffffffff, 1, 0x8000000000000000) + ADD(12, 1, 0x7fffffffffffffff, 0x8000000000000000) + ADD(13, 0x8000000000000000, 1, 0x8000000000000001) + ADD(14, 1, 0x8000000000000000, 0x8000000000000001) + ADD(15, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff) + ADD(16, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) + ADD(17, 0x7fffffffffffffff, 0xffffffffffffffff, 0x7ffffffffffffffe) + ADD(18, 0x7fffffffffffffff, 0x7fffffffffffffff, 0xfffffffffffffffe) + ADD(19, 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffffe) +#endif + +#undef ADD +#define ADD(N, T, I0, I1, V) FOP(N, T, add, I0, I1, V) + ADD(0, _f, -0.5, 0.5, 0.0) + ADD(1, _f, 0.25, 0.75, 1.0) + ADD(0, _d, -0.5, 0.5, 0.0) + ADD(1, _d, 0.25, 0.75, 1.0) + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_and.ok b/deps/lightning/check/alu_and.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_and.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_and.tst b/deps/lightning/check/alu_and.tst new file mode 100644 index 0000000..7474271 --- /dev/null +++ b/deps/lightning/check/alu_and.tst @@ -0,0 +1,36 @@ +#include "alu.inc" + +.code + prolog + +#define AND(N, I0, I1, V) ALU(N, , and, I0, I1, V) + + AND(0, 0x7fffffff, 1, 1) + AND(1, 1, 0x7fffffff, 1) + AND(2, 0x80000000, 1, 0) + AND(3, 1, 0x80000000, 0) + AND(4, 0x7fffffff, 0x80000000, 0) + AND(5, 0x80000000, 0x7fffffff, 0) + AND(6, 0x7fffffff, 0xffffffff, 0x7fffffff) + AND(7, 0xffffffff, 0x7fffffff, 0x7fffffff) + AND(8, 0xffffffff, 0xffffffff, 0xffffffff) + AND(9, 0x7fffffff, 0, 0) + AND(10, 0, 0x7fffffff, 0) +#if __WORDSIZE == 64 + AND(11, 0x7fffffffffffffff, 1, 1) + AND(12, 1, 0x7fffffffffffffff, 1) + AND(13, 0x8000000000000000, 1, 0) + AND(14, 1, 0x8000000000000000, 0) + AND(15, 0x7fffffffffffffff, 0x8000000000000000, 0) + AND(16, 0x8000000000000000, 0x7fffffffffffffff, 0) + AND(17, 0x7fffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff) + AND(18, 0xffffffffffffffff, 0x7fffffffffffffff, 0x7fffffffffffffff) + AND(19, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff) +#endif + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_com.ok b/deps/lightning/check/alu_com.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_com.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_com.tst b/deps/lightning/check/alu_com.tst new file mode 100644 index 0000000..581c940 --- /dev/null +++ b/deps/lightning/check/alu_com.tst @@ -0,0 +1,33 @@ +#include "alu.inc" + +.code + prolog + +#define COM(N, I0, V) UN(N, com, I0, V) + +#if __WORDSIZE == 32 + COM(0, 0, 0xffffffff) + COM(1, 1, 0xfffffffe) + COM(2, 0xffffffff, 0) + COM(3, 0x80000000, 0x7fffffff) + COM(4, 0x7fffffff, 0x80000000) + COM(5, 0x80000001, 0x7ffffffe) +#else + COM(0, 0, 0xffffffffffffffff) + COM(1, 1, 0xfffffffffffffffe) + COM(2, 0xffffffff, 0xffffffff00000000) + COM(3, 0x80000000, 0xffffffff7fffffff) + COM(4, 0x7fffffff, 0xffffffff80000000) + COM(5, 0x80000001, 0xffffffff7ffffffe) + COM(6, 0xffffffffffffffff, 0) + COM(7, 0x8000000000000000, 0x7fffffffffffffff) + COM(8, 0x7fffffffffffffff, 0x8000000000000000) + COM(9, 0x8000000000000001, 0x7ffffffffffffffe) +#endif + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_div.ok b/deps/lightning/check/alu_div.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_div.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_div.tst b/deps/lightning/check/alu_div.tst new file mode 100644 index 0000000..97e024d --- /dev/null +++ b/deps/lightning/check/alu_div.tst @@ -0,0 +1,83 @@ +#include "alu.inc" + +.code + prolog + +#define DIV(N, I0, I1, V) ALU(N, , div, I0, I1, V) +#define UDIV(N, I0, I1, V) ALU(N, _u, div, I0, I1, V) + + DIV(0, 0x7fffffff, 1, 0x7fffffff) + DIV(1, 1, 0x7fffffff, 0) + DIV(2, 0x80000000, 1, 0x80000000) + DIV(3, 1, 0x80000000, 0) + DIV(4, 0x7fffffff, 2, 0x3fffffff) + DIV(5, 2, 0x7fffffff, 0) + DIV(6, 2, 0x80000000, 0) + DIV(7, 0x7fffffff, 0x80000000, 0) + DIV(8, 0, 0x7fffffff, 0) + DIV(9, 0xffffffff, 0xffffffff, 1) + UDIV(0, 0x7fffffff, 1, 0x7fffffff) + UDIV(1, 1, 0x7fffffff, 0) + UDIV(2, 0x80000000, 1, 0x80000000) + UDIV(3, 1, 0x80000000, 0) + UDIV(4, 0x7fffffff, 2, 0x3fffffff) + UDIV(5, 2, 0x7fffffff, 0) + UDIV(6, 0x80000000, 2, 0x40000000) + UDIV(7, 2, 0x80000000, 0) + UDIV(8, 0x7fffffff, 0x80000000, 0) + UDIV(9, 0x80000000, 0x7fffffff, 1) + UDIV(10,0, 0x7fffffff, 0) + UDIV(11,0x7fffffff, 0xffffffff, 0) + UDIV(12,0xffffffff, 0x7fffffff, 2) + UDIV(13,0xffffffff, 0xffffffff, 1) +#if __WORDSIZE == 32 + DIV(10, 0x80000000, 2, 0xc0000000) + DIV(11, 0x80000000, 0x7fffffff, 0xffffffff) + DIV(12, 0x7fffffff, 0xffffffff, 0x80000001) + DIV(13, 0xffffffff, 0x7fffffff, 0) +#else + DIV(10, 0x80000000, 2, 0x40000000) + DIV(11, 0x80000000, 0x7fffffff, 1) + DIV(12, 0x7fffffff, 0xffffffff, 0) + DIV(13, 0xffffffff, 0x7fffffff, 2) + DIV(14, 0x7fffffffffffffff, 1, 0x7fffffffffffffff) + DIV(15, 1, 0x7fffffffffffffff, 0) + DIV(16, 0x8000000000000000, 1, 0x8000000000000000) + DIV(17, 1, 0x8000000000000000, 0) + DIV(18, 0x7fffffffffffffff, 2, 0x3fffffffffffffff) + DIV(19, 2, 0x7fffffffffffffff, 0) + DIV(20, 0x8000000000000000, 2, 0xc000000000000000) + DIV(21, 2, 0x8000000000000000, 0) + DIV(22, 0x7fffffffffffffff, 0x8000000000000000, 0) + DIV(23, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) + DIV(24, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000001) + DIV(25, 0xffffffffffffffff, 0x7fffffffffffffff, 0) + DIV(26, 0xffffffffffffffff, 0xffffffffffffffff, 1) + UDIV(14,0x7fffffffffffffff, 1, 0x7fffffffffffffff) + UDIV(15,1, 0x7fffffffffffffff, 0) + UDIV(16,0x8000000000000000, 1, 0x8000000000000000) + UDIV(17,1, 0x8000000000000000, 0) + UDIV(18,0x7fffffffffffffff, 2, 0x3fffffffffffffff) + UDIV(19,2, 0x7fffffffffffffff, 0) + UDIV(20,0x8000000000000000, 2, 0x4000000000000000) + UDIV(21,2, 0x8000000000000000, 0) + UDIV(22,0x7fffffffffffffff, 0x8000000000000000, 0) + UDIV(23,0x8000000000000000, 0x7fffffffffffffff, 1) + UDIV(24,0x7fffffffffffffff, 0xffffffffffffffff, 0) + UDIV(25,0xffffffffffffffff, 0x7fffffffffffffff, 2) + UDIV(26,0xffffffffffffffff, 0xffffffffffffffff, 1) +#endif + +#undef DIV +#define DIV(N, T, I0, I1, V) FOP(N, T, div, I0, I1, V) + DIV(0, _f, -0.5, 0.5, -1.0) + DIV(1, _f, 1.25, 0.5, 2.5) + DIV(0, _d, -0.5, 0.5, -1.0) + DIV(1, _d, 1.25, 0.5, 2.5) + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_lsh.ok b/deps/lightning/check/alu_lsh.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_lsh.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_lsh.tst b/deps/lightning/check/alu_lsh.tst new file mode 100644 index 0000000..c05fda0 --- /dev/null +++ b/deps/lightning/check/alu_lsh.tst @@ -0,0 +1,57 @@ +#include "alu.inc" + +.code + prolog + +#define LSH(N, I0, I1, V) ALU(N, , lsh, I0, I1, V) + + LSH(0, 0x7f, 1, 0xfe) + LSH(1, 0x7fff, 2, 0x1fffc) + LSH(2, 0x81, 16, 0x810000) + LSH(3, 0xff, 15, 0x7f8000) + LSH(4, 0x7fffffff, 0, 0x7fffffff) +#if __WORDSIZE == 32 + LSH(5, 0xffffffff, 8, 0xffffff00) + LSH(6, 0x7fffffff, 3, 0xfffffff8) + LSH(7, -0x7f, 31, 0x80000000) + LSH(8, -0x7fff, 30, 0x40000000) + LSH(9, -0x7fffffff, 29, 0x20000000) + LSH(10, 0x80000001, 28, 0x10000000) + LSH(11, 0x8001, 17, 0x20000) + LSH(12, 0x80000001, 18, 0x40000) + LSH(13, -0xffff, 24, 0x1000000) +#else + LSH(5, 0xffffffff, 8, 0xffffffff00) + LSH(6, 0x7fffffff, 3, 0x3fffffff8) + LSH(7, -0x7f, 31, 0xffffffc080000000) + LSH(8, -0x7fff, 30, 0xffffe00040000000) + LSH(9, -0x7fffffff, 29, 0xf000000020000000) + LSH(10, 0x80000001, 28, 0x800000010000000) + LSH(11, 0x8001, 17, 0x100020000) + LSH(12, 0x80000001, 18, 0x2000000040000) + LSH(13, -0xffff, 24, 0xffffff0001000000) + LSH(14, 0x7f, 33, 0xfe00000000) + LSH(15, 0x7ffff, 34, 0x1ffffc00000000) + LSH(16, 0x7fffffff, 35, 0xfffffff800000000) + LSH(17, -0x7f, 63, 0x8000000000000000) + LSH(18, -0x7fff, 62, 0x4000000000000000) + LSH(19, -0x7fffffff, 61, 0x2000000000000000) + LSH(20, 0x80000001, 60, 0x1000000000000000) + LSH(21, 0x81, 48, 0x81000000000000) + LSH(22, 0x8001, 49, 0x2000000000000) + LSH(23, 0x80000001, 40, 0x10000000000) + LSH(24, 0xff, 47, 0x7f800000000000) + LSH(25, 0xffff0001, 56, 0x100000000000000) + LSH(26, 0xffffffff, 40, 0xffffff0000000000) + LSH(27, 0x7fffffffff, 33, 0xfffffffe00000000) + LSH(28, -0x7fffffffff, 63, 0x8000000000000000) + LSH(29, 0x8000000001, 48, 0x1000000000000) + LSH(30, 0xffffffffff, 47, 0xffff800000000000) +#endif + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_mul.ok b/deps/lightning/check/alu_mul.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_mul.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_mul.tst b/deps/lightning/check/alu_mul.tst new file mode 100644 index 0000000..748417c --- /dev/null +++ b/deps/lightning/check/alu_mul.tst @@ -0,0 +1,59 @@ +#include "alu.inc" + +.code + prolog + +#define MUL(N, I0, I1, V) ALU(N, , mul, I0, I1, V) + + MUL(0, 0x7fffffff, 1, 0x7fffffff) + MUL(1, 1, 0x7fffffff, 0x7fffffff) + MUL(2, 0x80000000, 1, 0x80000000) + MUL(3, 1, 0x80000000, 0x80000000) + MUL(4, 0x7fffffff, 2, 0xfffffffe) + MUL(5, 2, 0x7fffffff, 0xfffffffe) + MUL(6, 0x7fffffff, 0, 0) + MUL(7, 0, 0x7fffffff, 0) +#if __WORDSIZE == 32 + MUL(8, 0x80000000, 2, 0) + MUL(9, 2, 0x80000000, 0) + MUL(10, 0x7fffffff, 0x80000000, 0x80000000) + MUL(11, 0x80000000, 0x7fffffff, 0x80000000) + MUL(12, 0x7fffffff, 0xffffffff, 0x80000001) + MUL(13, 0xffffffff, 0x7fffffff, 0x80000001) + MUL(14, 0xffffffff, 0xffffffff, 1) +#else + MUL(8, 0x80000000, 2, 0x100000000) + MUL(9, 2, 0x80000000, 0x100000000) + MUL(10, 0x7fffffff, 0x80000000, 0x3fffffff80000000) + MUL(11, 0x80000000, 0x7fffffff, 0x3fffffff80000000) + MUL(12, 0x7fffffff, 0xffffffff, 0x7ffffffe80000001) + MUL(13, 0xffffffff, 0x7fffffff, 0x7ffffffe80000001) + MUL(14, 0xffffffff, 0xffffffff, 0xfffffffe00000001) + MUL(15, 0x7fffffffffffffff, 1, 0x7fffffffffffffff) + MUL(16, 1, 0x7fffffffffffffff, 0x7fffffffffffffff) + MUL(17, 0x8000000000000000, 1, 0x8000000000000000) + MUL(18, 1, 0x8000000000000000, 0x8000000000000000) + MUL(19, 0x7fffffffffffffff, 2, 0xfffffffffffffffe) + MUL(20, 2, 0x7fffffffffffffff, 0xfffffffffffffffe) + MUL(21, 0x8000000000000000, 2, 0) + MUL(22, 2, 0x8000000000000000, 0) + MUL(23, 0x7fffffffffffffff, 0x8000000000000000, 0x8000000000000000) + MUL(24, 0x8000000000000000, 0x7fffffffffffffff, 0x8000000000000000) + MUL(25, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000001) + MUL(26, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000001) + MUL(27, 0xffffffffffffffff, 0xffffffffffffffff, 1) +#endif + +#undef MUL +#define MUL(N, T, I0, I1, V) FOP(N, T, mul, I0, I1, V) + MUL(0, _f, -0.5, 0.5, -0.25) + MUL(1, _f, 0.25, 0.75, 0.1875) + MUL(0, _d, -0.5, 0.5, -0.25) + MUL(1, _d, 0.25, 0.75, 0.1875) + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_neg.ok b/deps/lightning/check/alu_neg.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_neg.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_neg.tst b/deps/lightning/check/alu_neg.tst new file mode 100644 index 0000000..3264d13 --- /dev/null +++ b/deps/lightning/check/alu_neg.tst @@ -0,0 +1,42 @@ +#include "alu.inc" + +.code + prolog + +#define NEG(N, I, V) UN(N, neg, I, V) + + NEG(0, 0, 0) +#if __WORDSIZE == 32 + NEG(1, 1, 0xffffffff) + NEG(2, 0xffffffff, 1) + NEG(3, 0x80000000, 0x80000000) + NEG(4, 0x7fffffff, 0x80000001) + NEG(5, 0x80000001, 0x7fffffff) +#else + NEG(1, 1, 0xffffffffffffffff) + NEG(2, 0xffffffff, 0xffffffff00000001) + NEG(3, 0x80000000, 0xffffffff80000000) + NEG(4, 0x7fffffff, 0xffffffff80000001) + NEG(5, 0x80000001, 0xffffffff7fffffff) + NEG(6, 0xffffffffffffffff, 1) + NEG(7, 0x8000000000000000, 0x8000000000000000) + NEG(8, 0x7fffffffffffffff, 0x8000000000000001) +#endif + +#undef NEG +#define NEG(N, T, I, V) FUN(N, T, neg, I, V) + NEG(0, _f, 0.0, -0.0) + NEG(1, _f, 0.5, -0.5) + NEG(2, _f, $(1 / 0.0), $(-1.0 / 0)) + NEG(3, _f, -1.25, 1.25) + NEG(0, _d, 0.0, -0.0) + NEG(1, _d, 0.5, -0.5) + NEG(2, _d, $(1.0 / 0), $(-1 / 0.0)) + NEG(3, _d, -1.25, 1.25) + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_or.ok b/deps/lightning/check/alu_or.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_or.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_or.tst b/deps/lightning/check/alu_or.tst new file mode 100644 index 0000000..1e55a86 --- /dev/null +++ b/deps/lightning/check/alu_or.tst @@ -0,0 +1,36 @@ +#include "alu.inc" + +.code + prolog + +#define OR(N, I0, I1, V) ALU(N, , or, I0, I1, V) + + OR(0, 0x7fffffff, 1, 0x7fffffff) + OR(1, 1, 0x7fffffff, 0x7fffffff) + OR(2, 0x80000000, 1, 0x80000001) + OR(3, 1, 0x80000000, 0x80000001) + OR(4, 0x7fffffff, 0x80000000, 0xffffffff) + OR(5, 0x80000000, 0x7fffffff, 0xffffffff) + OR(6, 0x7fffffff, 0xffffffff, 0xffffffff) + OR(7, 0xffffffff, 0x7fffffff, 0xffffffff) + OR(8, 0xffffffff, 0xffffffff, 0xffffffff) + OR(9, 0x7fffffff, 0, 0x7fffffff) + OR(10, 0, 0x7fffffff, 0x7fffffff) +#if __WORDSIZE == 64 + OR(11, 0x7fffffffffffffff, 1, 0x7fffffffffffffff) + OR(12, 1, 0x7fffffffffffffff, 0x7fffffffffffffff) + OR(13, 0x8000000000000000, 1, 0x8000000000000001) + OR(14, 1, 0x8000000000000000, 0x8000000000000001) + OR(15, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff) + OR(16, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) + OR(17, 0x7fffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff) + OR(18, 0xffffffffffffffff, 0x7fffffffffffffff, 0xffffffffffffffff) + OR(19, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff) +#endif + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_rem.ok b/deps/lightning/check/alu_rem.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_rem.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_rem.tst b/deps/lightning/check/alu_rem.tst new file mode 100644 index 0000000..5aea7cf --- /dev/null +++ b/deps/lightning/check/alu_rem.tst @@ -0,0 +1,76 @@ +#include "alu.inc" + +.code + prolog + +#define REM(N, I0, I1, V) ALU(N, , rem, I0, I1, V) +#define UREM(N, I0, I1, V) ALU(N, _u, rem, I0, I1, V) + + REM(0, 0x7fffffff, 1, 0) + REM(1, 1, 0x7fffffff, 1) + REM(2, 0x80000000, 1, 0) + REM(3, 1, 0x80000000, 1) + REM(4, 0x7fffffff, 2, 1) + REM(5, 2, 0x7fffffff, 2) + REM(6, 0x80000000, 2, 0) + REM(7, 2, 0x80000000, 2) + REM(8, 0x7fffffff, 0x80000000, 0x7fffffff) + REM(9, 0, 0x7fffffff, 0) + REM(10, 0xffffffff, 0xffffffff, 0) + UREM(0, 0x7fffffff, 1, 0) + UREM(1, 1, 0x7fffffff, 1) + UREM(2, 0x80000000, 1, 0) + UREM(3, 1, 0x80000000, 1) + UREM(4, 0x7fffffff, 2, 1) + UREM(5, 2, 0x7fffffff, 2) + UREM(6, 0x80000000, 2, 0) + UREM(7, 2, 0x80000000, 2) + UREM(8, 0x7fffffff, 0x80000000, 0x7fffffff) + UREM(9, 0x80000000, 0x7fffffff, 1) + UREM(10,0, 0x7fffffff, 0) + UREM(11,0x7fffffff, 0xffffffff, 0x7fffffff) + UREM(12,0xffffffff, 0x7fffffff, 1) + UREM(13,0xffffffff, 0xffffffff, 0) + +#if __WORDSIZE == 32 + REM(11, 0x80000000, 0x7fffffff, 0xffffffff) + REM(12, 0x7fffffff, 0xffffffff, 0) + REM(13, 0xffffffff, 0x7fffffff, 0xffffffff) +#else + REM(11, 0x80000000, 0x7fffffff, 1) + REM(12, 0x7fffffff, 0xffffffff, 0x7fffffff) + REM(13, 0xffffffff, 0x7fffffff, 1) + REM(14, 0x7fffffffffffffff, 1, 0) + REM(15, 1, 0x7fffffffffffffff, 1) + REM(16, 0x8000000000000000, 1, 0) + REM(17, 1, 0x8000000000000000, 1) + REM(18, 0x7fffffffffffffff, 2, 1) + REM(19, 2, 0x7fffffffffffffff, 2) + REM(20, 0x8000000000000000, 2, 0) + REM(21, 2, 0x8000000000000000, 2) + REM(22, 0x7fffffffffffffff, 0x8000000000000000, 0x7fffffffffffffff) + REM(23, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) + REM(24, 0x7fffffffffffffff, 0xffffffffffffffff, 0) + REM(25, 0xffffffffffffffff, 0x7fffffffffffffff, 0xffffffffffffffff) + REM(26, 0xffffffffffffffff, 0xffffffffffffffff, 0) + UREM(14,0x7fffffffffffffff, 1, 0) + UREM(15,1, 0x7fffffffffffffff, 1) + UREM(16,0x8000000000000000, 1, 0) + UREM(17,1, 0x8000000000000000, 1) + UREM(18,0x7fffffffffffffff, 2, 1) + UREM(19,2, 0x7fffffffffffffff, 2) + UREM(20,0x8000000000000000, 2, 0) + UREM(21,2, 0x8000000000000000, 2) + UREM(22,0x7fffffffffffffff, 0x8000000000000000, 0x7fffffffffffffff) + UREM(23,0x8000000000000000, 0x7fffffffffffffff, 1) + UREM(24,0x7fffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff) + UREM(25,0xffffffffffffffff, 0x7fffffffffffffff, 1) + UREM(26,0xffffffffffffffff, 0xffffffffffffffff, 0) +#endif + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_rsb.ok b/deps/lightning/check/alu_rsb.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_rsb.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_rsb.tst b/deps/lightning/check/alu_rsb.tst new file mode 100644 index 0000000..00e08c2 --- /dev/null +++ b/deps/lightning/check/alu_rsb.tst @@ -0,0 +1,49 @@ +#include "alu.inc" + +.code + prolog + +#define RSB(N, I0, I1, V) ALU(N, , rsb, I0, I1, V) + + RSB(0, 1, 0x7fffffff, 0x7ffffffe) + RSB(2, 1, 0x80000000, 0x7fffffff) + RSB(3, 0x7fffffff, 0x80000000, 1) + RSB(4, 0xffffffff, 0xffffffff, 0) + RSB(5, 0x7fffffff, 0xffffffff, 0x80000000) + RSB(6, 0, 0x7fffffff, 0x7fffffff) +#if __WORDSIZE == 32 + RSB(7, 0x7fffffff, 1, 0x80000002) + RSB(8, 0x80000000, 1, 0x80000001) + RSB(9, 0x80000000, 0x7fffffff, 0xffffffff) + RSB(10, 0xffffffff, 0x7fffffff, 0x80000000) + RSB(11, 0x7fffffff, 0, 0x80000001) +#else + RSB(7, 0x7fffffff, 1, 0xffffffff80000002) + RSB(8, 0xffffffff80000000, 1, 0x80000001) + RSB(9, 0xffffffff80000000, 0x7fffffff, 0xffffffff) + RSB(10, 0xffffffffffffffff, 0xffffffff7fffffff, 0xffffffff80000000) + RSB(11, 0x7fffffff, 0, 0xffffffff80000001) + RSB(12, 1, 0x7fffffffffffffff, 0x7ffffffffffffffe) + RSB(13, 0x7fffffffffffffff, 1, 0x8000000000000002) + RSB(14, 1, 0x8000000000000000, 0x7fffffffffffffff) + RSB(15, 0x8000000000000000, 1, 0x8000000000000001) + RSB(16, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) + RSB(17, 0x7fffffffffffffff, 0x8000000000000000, 1) + RSB(18, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000000) + RSB(19, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000000) + RSB(20, 0xffffffffffffffff, 0xffffffffffffffff, 0) +#endif + +#undef RSB +#define RSB(N, T, I0, I1, V) FOP(N, T, rsb, I0, I1, V) + RSB(0, _f, 0.5, -0.5, -1.0) + RSB(1, _f, 0.75, 0.25, -0.5) + RSB(0, _d, 0.5, -0.5, -1.0) + RSB(1, _d, 0.75, 0.25, -0.5) + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_rsh.ok b/deps/lightning/check/alu_rsh.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_rsh.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_rsh.tst b/deps/lightning/check/alu_rsh.tst new file mode 100644 index 0000000..93f8c7b --- /dev/null +++ b/deps/lightning/check/alu_rsh.tst @@ -0,0 +1,85 @@ +#include "alu.inc" + +.code + prolog + +#define RSH(N, I0, I1, V) ALU(N, , rsh, I0, I1, V) +#define URSH(N, I0, I1, V) ALU(N, _u, rsh, I0, I1, V) + + RSH(0, 0xfe, 1, 0x7f) + RSH(1, 0x1fffc, 2, 0x7fff) + RSH(2, 0x40000000, 30, 1) + RSH(3, 0x20000000, 29, 1) + RSH(4, 0x10000000, 28, 1) + RSH(5, 0x810000, 16, 0x81) + RSH(6, 0x20000, 17, 1) + RSH(7, 0x40000, 18, 1) + RSH(8, 0x7f8000, 15, 0xff) + RSH(9, 0x1000000, 24, 1) + RSH(10, 0x7fffffff, 0, 0x7fffffff) + URSH(0, 0xfe, 1, 0x7f) + URSH(1, 0x1fffc, 2, 0x7fff) + URSH(2, 0x80000000, 31, 1) + URSH(3, 0x40000000, 30, 1) + URSH(4, 0x20000000, 29, 1) + URSH(5, 0x10000000, 28, 1) + URSH(6, 0x810000, 16, 0x81) + URSH(7, 0x20000, 17, 1) + URSH(8, 0x40000, 18, 1) + URSH(9,0x7f8000, 15, 0xff) + URSH(10,0x1000000, 24, 1) + URSH(11,0xffffff00, 8, 0xffffff) + URSH(12,0x7fffffff, 0, 0x7fffffff) +#if __WORDSIZE == 32 + RSH(11, 0xfffffff8, 3, 0xffffffff) + RSH(12, 0x80000000, 31, 0xffffffff) + RSH(13, 0xffffff00, 8, 0xffffffff) + URSH(13,0xfffffff8, 3, 0x1fffffff) +#else + RSH(11, 0x3fffffff8, 3, 0x7fffffff) + RSH(12, 0xffffffc080000000, 31, 0xffffffffffffff81) + RSH(13, 0xffffff00, 8, 0xffffff) + RSH(14, 0xfe00000000, 33, 0x7f) + RSH(15, 0x1ffffc00000000, 34, 0x7ffff) + RSH(16, 0xfffffff800000000, 29, 0xffffffffffffffc0) + RSH(17, 0x8000000000000000, 63, 0xffffffffffffffff) + RSH(18, 0x4000000000000000, 62, 1) + RSH(19, 0x2000000000000000, 61, 1) + RSH(20, 0x1000000000000000, 60, 1) + RSH(21, 0x81000000000000, 48, 0x81) + RSH(22, 0x2000000000000, 49, 1) + RSH(23, 0x10000000000, 40, 1) + RSH(24, 0x7f800000000000, 47, 0xff) + RSH(25, 0x100000000000000, 56, 1) + RSH(26, 0xffffff0000000000, 40, 0xffffffffffffffff) + RSH(27, 0xfffffffe00000000, 33, 0xffffffffffffffff) + RSH(28, 0x8000000000000001, 63, 0xffffffffffffffff) + RSH(29, 0x1000000000000, 48, 1) + RSH(30, 0xffff800000000000, 47, 0xffffffffffffffff) + URSH(13,0x3fffffff8, 3, 0x7fffffff) + URSH(14,0xffffffc080000000, 31, 0x1ffffff81) + URSH(15,0xfe00000000, 33, 0x7f) + URSH(16,0x1ffffc00000000, 34, 0x7ffff) + URSH(17,0xfffffff800000000, 29, 0x7ffffffc0) + URSH(18,0x8000000000000000, 63, 1) + URSH(19,0x4000000000000000, 62, 1) + URSH(20,0x2000000000000000, 61, 1) + URSH(21,0x1000000000000000, 60, 1) + URSH(22,0x81000000000000, 48, 0x81) + URSH(23,0x2000000000000, 49, 1) + URSH(24,0x10000000000, 40, 1) + URSH(25,0x7f800000000000, 47, 0xff) + URSH(26,0x100000000000000, 56, 1) + URSH(27,0xffffff0000000000, 40, 0xffffff) + URSH(28,0xfffffffe00000000, 33, 0x7fffffff) + URSH(29,0x8000000000000001, 63, 1) + URSH(30,0x1000000000000, 48, 1) + URSH(31,0xffff800000000000, 47, 0x1ffff) +#endif + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_sub.ok b/deps/lightning/check/alu_sub.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_sub.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_sub.tst b/deps/lightning/check/alu_sub.tst new file mode 100644 index 0000000..8f07b62 --- /dev/null +++ b/deps/lightning/check/alu_sub.tst @@ -0,0 +1,49 @@ +#include "alu.inc" + +.code + prolog + +#define SUB(N, I0, I1, V) ALU(N, , sub, I0, I1, V) + + SUB(0, 0x7fffffff, 1, 0x7ffffffe) + SUB(2, 0x80000000, 1, 0x7fffffff) + SUB(3, 0x80000000, 0x7fffffff, 1) + SUB(4, 0xffffffff, 0xffffffff, 0) + SUB(5, 0xffffffff, 0x7fffffff, 0x80000000) + SUB(6, 0x7fffffff, 0, 0x7fffffff) +#if __WORDSIZE == 32 + SUB(7, 1, 0x7fffffff, 0x80000002) + SUB(8, 1, 0x80000000, 0x80000001) + SUB(9, 0x7fffffff, 0x80000000, 0xffffffff) + SUB(10, 0x7fffffff, 0xffffffff, 0x80000000) + SUB(11, 0, 0x7fffffff, 0x80000001) +#else + SUB(7, 1, 0x7fffffff, 0xffffffff80000002) + SUB(8, 1, 0xffffffff80000000, 0x80000001) + SUB(9, 0x7fffffff, 0xffffffff80000000, 0xffffffff) + SUB(10, 0xffffffff7fffffff, 0xffffffffffffffff, 0xffffffff80000000) + SUB(11, 0, 0x7fffffff, 0xffffffff80000001) + SUB(12, 0x7fffffffffffffff, 1, 0x7ffffffffffffffe) + SUB(13, 1, 0x7fffffffffffffff, 0x8000000000000002) + SUB(14, 0x8000000000000000, 1, 0x7fffffffffffffff) + SUB(15, 1, 0x8000000000000000, 0x8000000000000001) + SUB(16, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff) + SUB(17, 0x8000000000000000, 0x7fffffffffffffff, 1) + SUB(18, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000000) + SUB(19, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000000) + SUB(20, 0xffffffffffffffff, 0xffffffffffffffff, 0) +#endif + +#undef SUB +#define SUB(N, T, I0, I1, V) FOP(N, T, sub, I0, I1, V) + SUB(0, _f, -0.5, 0.5, -1.0) + SUB(1, _f, 0.25, 0.75, -0.5) + SUB(0, _d, -0.5, 0.5, -1.0) + SUB(1, _d, 0.25, 0.75, -0.5) + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alu_xor.ok b/deps/lightning/check/alu_xor.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alu_xor.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alu_xor.tst b/deps/lightning/check/alu_xor.tst new file mode 100644 index 0000000..d1976ab --- /dev/null +++ b/deps/lightning/check/alu_xor.tst @@ -0,0 +1,36 @@ +#include "alu.inc" + +.code + prolog + +#define XOR(N, I0, I1, V) ALU(N, , xor, I0, I1, V) + + XOR(0, 0x7fffffff, 1, 0x7ffffffe) + XOR(1, 1, 0x7fffffff, 0x7ffffffe) + XOR(2, 0x80000000, 1, 0x80000001) + XOR(3, 1, 0x80000000, 0x80000001) + XOR(4, 0x7fffffff, 0x80000000, 0xffffffff) + XOR(5, 0x80000000, 0x7fffffff, 0xffffffff) + XOR(6, 0x7fffffff, 0xffffffff, 0x80000000) + XOR(7, 0xffffffff, 0x7fffffff, 0x80000000) + XOR(9, 0xffffffff, 0xffffffff, 0) + XOR(10, 0x7fffffff, 0, 0x7fffffff) + XOR(11, 0, 0x7fffffff, 0x7fffffff) +#if __WORDSIZE == 64 + XOR(12, 0x7fffffffffffffff, 1, 0x7ffffffffffffffe) + XOR(13, 1, 0x7fffffffffffffff, 0x7ffffffffffffffe) + XOR(14, 0x8000000000000000, 1, 0x8000000000000001) + XOR(15, 1, 0x8000000000000000, 0x8000000000000001) + XOR(16, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff) + XOR(17, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) + XOR(18, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000000) + XOR(19, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000000) + XOR(20, 0xffffffffffffffff, 0xffffffffffffffff, 0) +#endif + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alux_add.ok b/deps/lightning/check/alux_add.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alux_add.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alux_add.tst b/deps/lightning/check/alux_add.tst new file mode 100644 index 0000000..ddc4e57 --- /dev/null +++ b/deps/lightning/check/alux_add.tst @@ -0,0 +1,49 @@ +#include "alu.inc" + +.code + prolog + +#define ADDX(N, I0, I1, V) ALUX(N, add, I0, I1, V) + + /* nothing */ + ADDX(0, 0, 0, 0) +#if __WORDSIZE == 32 + /* carry */ + ADDX(1, 0xffffffff, 0xffffffff, 1) + /* overflow */ + ADDX(2, 0x7fffffff, 1, 0) + /* overflow */ + ADDX(3, 0x7fffffff, 0x7fffffff, 0) + /* carry */ + ADDX(4, 0x7fffffff, 0x80000000, 0) + /* carry+overflow */ + ADDX(5, 0x80000000, 0x80000000, 1) +#else + /* nothing */ + ADDX(1, 0xffffffff, 0xffffffff, 0) + /* nothing */ + ADDX(2, 0x7fffffff, 1, 0) + /* nothing */ + ADDX(3, 0x7fffffff, 0x7fffffff, 0) + /* nothing */ + ADDX(4, 0x7fffffff, 0x80000000, 0) + /* nothing */ + ADDX(5, 0x80000000, 0x80000000, 0) + /* carry */ + ADDX(6, 0xffffffffffffffff, 0xffffffffffffffff, 1) + /* overflow */ + ADDX(7, 0x7fffffffffffffff, 1, 0) + /* overflow */ + ADDX(8, 0x7fffffffffffffff, 0x7fffffffffffffff, 0) + /* overflow */ + ADDX(9, 0x7fffffffffffffff, 0x8000000000000000, 0) + /* carry+overflow */ + ADDX(10,0x8000000000000000, 0x8000000000000000, 1) +#endif + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/alux_sub.ok b/deps/lightning/check/alux_sub.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/alux_sub.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/alux_sub.tst b/deps/lightning/check/alux_sub.tst new file mode 100644 index 0000000..8a2838d --- /dev/null +++ b/deps/lightning/check/alux_sub.tst @@ -0,0 +1,49 @@ +#include "alu.inc" + +.code + prolog + +#define SUBX(N, I0, I1, V) ALUX(N, sub, I0, I1, V) + + /* nothing */ + SUBX(0, 0, 0, 0) +#if __WORDSIZE == 32 + /* carry */ + SUBX(1, 0x7fffffff, 0xffffffff, 0xffffffff) + /* overflow */ + SUBX(2, 0x80000000, 1, 0) + /* carry */ + SUBX(3, 0x7fffffff, 0x80000000, 0xffffffff) + /* overflow */ + SUBX(4, 0x80000000, 0x7fffffff, 0) + /* carry+overflow */ + SUBX(5, 1, 0x80000000, 0xffffffff) +#else + /* carry */ + SUBX(1, 0x7fffffff, 0xffffffff, -1) + /* nothing */ + SUBX(2, 0x80000000, 1, 0) + /* carry */ + SUBX(3, 0x7fffffff, 0x80000000, -1) + /* nothing */ + SUBX(4, 0x80000000, 0x7fffffff, 0) + /* carry */ + SUBX(5, 1, 0x80000000, -1) + /* carry */ + SUBX(6, 0x7fffffffffffffff, 0xffffffffffffffff, -1) + /* overflow */ + SUBX(7, 0x8000000000000000, 1, 0) + /* carry */ + SUBX(8, 0x7fffffffffffffff, 0x8000000000000000, -1) + /* overflow */ + SUBX(9, 0x8000000000000000, 0x7fffffffffffffff, 0) + /* carry+overflow */ + SUBX(10,1, 0x8000000000000000, -1) +#endif + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/bp.ok b/deps/lightning/check/bp.ok new file mode 100644 index 0000000..7e13ef0 --- /dev/null +++ b/deps/lightning/check/bp.ok @@ -0,0 +1 @@ +nfibs(32) = 2178309 diff --git a/deps/lightning/check/bp.tst b/deps/lightning/check/bp.tst new file mode 100644 index 0000000..9e6798d --- /dev/null +++ b/deps/lightning/check/bp.tst @@ -0,0 +1,46 @@ +.data 32 +fmt: +.c "nfibs(%d) = %d\n" + +.code + jmpi main + + name rfibs +rfibs: + prolog + arg $in + getarg %r0 $in /* R0 = N */ + beqi out %r0 0 + movr %v0 %r0 /* V0 = R0 */ + movi %r0 1 + blei_u out %v0 2 + subi %v1 %v0 1 /* V1 = N-1 */ + subi %v2 %v0 2 /* V1 = N-2 */ + prepare + pushargr %v1 + finishi rfibs + retval %v1 /* V1 = rfibs(N-1) */ + prepare + pushargr %v2 + finishi rfibs + retval %r0 /* R0 = rfibs(N-2) */ + addr %r0 %r0 %v1 +out: + retr %r0 + epilog + + name main +main: + prolog + prepare + pushargi 32 + finishi rfibs + retval %v0 + prepare + pushargi fmt + ellipsis + pushargi 32 + pushargr %v0 + finishi @printf + ret + epilog diff --git a/deps/lightning/check/branch.ok b/deps/lightning/check/branch.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/branch.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/branch.tst b/deps/lightning/check/branch.tst new file mode 100644 index 0000000..2252dff --- /dev/null +++ b/deps/lightning/check/branch.tst @@ -0,0 +1,563 @@ +#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 + +.data 12 +ok: +.c "ok\n" +. $($NaN = 0.0 / 0.0) + +#define BOP(N, Ls, Rs, Lu, Ru, R0, R1) \ + movi %R0 Ls \ + movi %R1 Rs \ + b##N##r N##r_##R0##_##R1 %R0 %R1 \ + calli @abort \ +N##r_##R0##_##R1: \ + b##N##i N##i_##R0##_##R1 %R0 Rs \ + calli @abort \ +N##i_##R0##_##R1: \ + movi %R0 Lu \ + movi %R1 Ru \ + b##N##r_u N##r_u_##R0##_##R1 %R0 %R1 \ + calli @abort \ +N##r_u_##R0##_##R1: \ + b##N##i_u N##i_u_##R0##_##R1 %R0 Ru \ + calli @abort \ +N##i_u_##R0##_##R1: \ + movi %R0 Ls \ + movi %R1 Rs \ + N##r %R0 %R0 %R1 \ + beqi _##N##r_##R0##_##R1 %R0 1 \ + calli @abort \ +_##N##r_##R0##_##R1: \ + movi %R0 Ls \ + N##i %R1 %R0 Rs \ + beqi _##N##i_##R0##_##R1 %R1 1 \ + calli @abort \ +_##N##i_##R0##_##R1: \ + movi %R0 Lu \ + movi %R1 Ru \ + N##r_u %R0 %R0 %R1 \ + beqi _##N##r_u_##R0##_##R1 %R0 1 \ + calli @abort \ +_##N##r_u_##R0##_##R1: \ + movi %R0 Lu \ + N##i_u %R1 %R0 Ru \ + beqi _##N##i_u_##R0##_##R1 %R1 1 \ + calli @abort \ +_##N##i_u_##R0##_##R1: + +#define EB(N, L, R, R0, R1) \ + movi %R0 L \ + movi %R1 R \ + b##N##r N##r_##R0##_##R1 %R0 %R1 \ + calli @abort \ +N##r_##R0##_##R1: \ + b##N##i N##i_##R0##_##R1 %R0 R \ + calli @abort \ +N##i_##R0##_##R1: \ + movi %R0 L \ + movi %R1 R \ + N##r %R0 %R0 %R1 \ + beqi _##N##r_##R0##_##R1 %R0 1 \ + calli @abort \ +_##N##r_##R0##_##R1: \ + movi %R0 L \ + N##i %R1 %R0 R \ + beqi _##N##i_##R0##_##R1 %R1 1 \ + calli @abort \ +_##N##i_##R0##_##R1: + +#define XEB(N, L, R, R0, R1) \ + movi %R0 L \ + movi %R1 R \ + b##N##r N##r_##R0##_##R1 %R0 %R1 \ + calli @abort \ +N##r_##R0##_##R1: \ + b##N##i N##i_##R0##_##R1 %R0 R \ + calli @abort \ +N##i_##R0##_##R1: + +#define XBOP(N, Ls, Rs, Lu, Ru, R0, R1) \ + movi %R0 Ls \ + movi %R1 Rs \ + b##N##r N##r_##R0##_##R1 %R0 %R1 \ + calli @abort \ +N##r_##R0##_##R1: \ + movi %R0 Ls \ + b##N##i N##i_##R0##_##R1 %R0 Rs \ + calli @abort \ +N##i_##R0##_##R1: \ + movi %R0 Lu \ + movi %R1 Ru \ + b##N##r_u N##r_u_##R0##_##R1 %R0 %R1 \ + calli @abort \ +N##r_u_##R0##_##R1: \ + movi %R0 Lu \ + b##N##i_u N##i_u_##R0##_##R1 %R0 Ru \ + calli @abort \ +N##i_u_##R0##_##R1: + +#define BOPI(N, Ls, Rs, Lu, Ru) \ + BOP(N, Ls, Rs, Lu, Ru, v0, v1) \ + BOP(N, Ls, Rs, Lu, Ru, v0, v2) \ + BOP(N, Ls, Rs, Lu, Ru, v0, r0) \ + BOP(N, Ls, Rs, Lu, Ru, v0, r1) \ + BOP(N, Ls, Rs, Lu, Ru, v0, r2) \ + BOP(N, Ls, Rs, Lu, Ru, v1, v0) \ + BOP(N, Ls, Rs, Lu, Ru, v1, v2) \ + BOP(N, Ls, Rs, Lu, Ru, v1, r0) \ + BOP(N, Ls, Rs, Lu, Ru, v1, r1) \ + BOP(N, Ls, Rs, Lu, Ru, v1, r2) \ + BOP(N, Ls, Rs, Lu, Ru, v2, v0) \ + BOP(N, Ls, Rs, Lu, Ru, v2, v1) \ + BOP(N, Ls, Rs, Lu, Ru, v2, r0) \ + BOP(N, Ls, Rs, Lu, Ru, v2, r1) \ + BOP(N, Ls, Rs, Lu, Ru, v2, r2) \ + BOP(N, Ls, Rs, Lu, Ru, r0, v0) \ + BOP(N, Ls, Rs, Lu, Ru, r0, v1) \ + BOP(N, Ls, Rs, Lu, Ru, r0, v2) \ + BOP(N, Ls, Rs, Lu, Ru, r0, r1) \ + BOP(N, Ls, Rs, Lu, Ru, r0, r2) \ + BOP(N, Ls, Rs, Lu, Ru, r1, v0) \ + BOP(N, Ls, Rs, Lu, Ru, r1, v1) \ + BOP(N, Ls, Rs, Lu, Ru, r1, v2) \ + BOP(N, Ls, Rs, Lu, Ru, r1, r0) \ + BOP(N, Ls, Rs, Lu, Ru, r1, r2) \ + BOP(N, Ls, Rs, Lu, Ru, r2, v0) \ + BOP(N, Ls, Rs, Lu, Ru, r2, v1) \ + BOP(N, Ls, Rs, Lu, Ru, r2, v2) \ + BOP(N, Ls, Rs, Lu, Ru, r2, r0) \ + BOP(N, Ls, Rs, Lu, Ru, r2, r1) + +#define EBI(N, L, R) \ + EB(N, L, R, v0, v1) \ + EB(N, L, R, v0, v2) \ + EB(N, L, R, v0, r0) \ + EB(N, L, R, v0, r1) \ + EB(N, L, R, v0, r2) \ + EB(N, L, R, v1, v0) \ + EB(N, L, R, v1, v2) \ + EB(N, L, R, v1, r0) \ + EB(N, L, R, v1, r1) \ + EB(N, L, R, v1, r2) \ + EB(N, L, R, v2, v0) \ + EB(N, L, R, v2, v1) \ + EB(N, L, R, v2, r0) \ + EB(N, L, R, v2, r1) \ + EB(N, L, R, v2, r2) \ + EB(N, L, R, r0, v0) \ + EB(N, L, R, r0, v1) \ + EB(N, L, R, r0, v2) \ + EB(N, L, R, r0, r1) \ + EB(N, L, R, r0, r2) \ + EB(N, L, R, r1, v0) \ + EB(N, L, R, r1, v1) \ + EB(N, L, R, r1, v2) \ + EB(N, L, R, r1, r0) \ + EB(N, L, R, r1, r2) \ + EB(N, L, R, r2, v0) \ + EB(N, L, R, r2, v1) \ + EB(N, L, R, r2, v2) \ + EB(N, L, R, r2, r0) \ + EB(N, L, R, r2, r1) + + +#define XEBI(N, L, R) \ + XEB(N, L, R, v0, v1) \ + XEB(N, L, R, v0, v2) \ + XEB(N, L, R, v0, r0) \ + XEB(N, L, R, v0, r1) \ + XEB(N, L, R, v0, r2) \ + XEB(N, L, R, v1, v0) \ + XEB(N, L, R, v1, v2) \ + XEB(N, L, R, v1, r0) \ + XEB(N, L, R, v1, r1) \ + XEB(N, L, R, v1, r2) \ + XEB(N, L, R, v2, v0) \ + XEB(N, L, R, v2, v1) \ + XEB(N, L, R, v2, r0) \ + XEB(N, L, R, v2, r1) \ + XEB(N, L, R, v2, r2) \ + XEB(N, L, R, r0, v0) \ + XEB(N, L, R, r0, v1) \ + XEB(N, L, R, r0, v2) \ + XEB(N, L, R, r0, r1) \ + XEB(N, L, R, r0, r2) \ + XEB(N, L, R, r1, v0) \ + XEB(N, L, R, r1, v1) \ + XEB(N, L, R, r1, v2) \ + XEB(N, L, R, r1, r0) \ + XEB(N, L, R, r1, r2) \ + XEB(N, L, R, r2, v0) \ + XEB(N, L, R, r2, v1) \ + XEB(N, L, R, r2, v2) \ + XEB(N, L, R, r2, r0) \ + XEB(N, L, R, r2, r1) + +#define XBOPI(N, Ls, Rs, Lu, Ru) \ + XBOP(N, Ls, Rs, Lu, Ru, v0, v1) \ + XBOP(N, Ls, Rs, Lu, Ru, v0, v2) \ + XBOP(N, Ls, Rs, Lu, Ru, v0, r0) \ + XBOP(N, Ls, Rs, Lu, Ru, v0, r1) \ + XBOP(N, Ls, Rs, Lu, Ru, v0, r2) \ + XBOP(N, Ls, Rs, Lu, Ru, v1, v0) \ + XBOP(N, Ls, Rs, Lu, Ru, v1, v2) \ + XBOP(N, Ls, Rs, Lu, Ru, v1, r0) \ + XBOP(N, Ls, Rs, Lu, Ru, v1, r1) \ + XBOP(N, Ls, Rs, Lu, Ru, v1, r2) \ + XBOP(N, Ls, Rs, Lu, Ru, v2, v0) \ + XBOP(N, Ls, Rs, Lu, Ru, v2, v1) \ + XBOP(N, Ls, Rs, Lu, Ru, v2, r0) \ + XBOP(N, Ls, Rs, Lu, Ru, v2, r1) \ + XBOP(N, Ls, Rs, Lu, Ru, v2, r2) \ + XBOP(N, Ls, Rs, Lu, Ru, r0, v0) \ + XBOP(N, Ls, Rs, Lu, Ru, r0, v1) \ + XBOP(N, Ls, Rs, Lu, Ru, r0, v2) \ + XBOP(N, Ls, Rs, Lu, Ru, r0, r1) \ + XBOP(N, Ls, Rs, Lu, Ru, r0, r2) \ + XBOP(N, Ls, Rs, Lu, Ru, r1, v0) \ + XBOP(N, Ls, Rs, Lu, Ru, r1, v1) \ + XBOP(N, Ls, Rs, Lu, Ru, r1, v2) \ + XBOP(N, Ls, Rs, Lu, Ru, r1, r0) \ + XBOP(N, Ls, Rs, Lu, Ru, r1, r2) \ + XBOP(N, Ls, Rs, Lu, Ru, r2, v0) \ + XBOP(N, Ls, Rs, Lu, Ru, r2, v1) \ + XBOP(N, Ls, Rs, Lu, Ru, r2, v2) \ + XBOP(N, Ls, Rs, Lu, Ru, r2, r0) \ + XBOP(N, Ls, Rs, Lu, Ru, r2, r1) + +#define TBOPF(N, T, L, R) \ + movi_##T %f0 L \ + movi_##T %f1 R \ + b##N##r##_##T N##r_##T %f0 %f1 \ + calli @abort \ +N##r_##T: \ + b##N##i##_##T N##i_##T %f0 R \ + calli @abort \ +N##i_##T: \ + movi_##T %f1 $NaN \ + b##N##r##_##T N##r_##T##_##u %f0 %f1 \ + jmpi N##r_##T##_##u0 \ +N##r_##T##_##u: \ + calli @abort \ +N##r##_##T##_##u0: \ + b##N##i##_##T N##i_##T##_##u %f0 $NaN \ + jmpi N##i_##T##_##u0 \ +N##i##_##T##_##u: \ + calli @abort \ +N##i##_##T##_##u0: +#define BOPF(N, L, R) \ + TBOPF(N, f, L, R) \ + TBOPF(N, d, L, R) + +#define TUBOPF(N, T, L, R) \ + movi_##T %f0 L \ + movi_##T %f1 R \ + b##N##r##_##T N##r_##T %f0 %f1 \ + calli @abort \ +N##r_##T: \ + b##N##i##_##T N##i_##T %f0 R \ + calli @abort \ +N##i_##T: \ + movi_##T %f1 $NaN \ + b##N##r##_##T N##r_##T##_##u %f0 %f1 \ + calli @abort \ +N##r_##T##_##u: \ + b##N##i##_##T N##i_##T##_##u %f0 $NaN \ + calli @abort \ +N##i##_##T##_##u: + +#define UBOPF(N, L, R) \ + TUBOPF(N, f, L, R) \ + TUBOPF(N, d, L, R) + +.code + prolog + + movi %r0 -1 + movi %r1 1 + bltr xltr_r0_r1 %r0 %r1 + calli @abort +xltr_r0_r1: + blti xlti_r0_r1 %r0 1 + calli @abort +xlti_r0_r1: + movi %r0 1 + movi %r1 -1 + bltr_u xltru_r0_r1 %r0 %r1 + calli @abort +xltru_r0_r1: + blti_u xltiu_r0_r1 %r0 -1 + calli @abort +xltiu_r0_r1: + movi %r0 -1 + movi %r1 -1 + bler xler_r0_r1 %r0 %r1 + calli @abort +xler_r0_r1: + blti xlei_r0_r1 %r0 1 + calli @abort +xlei_r0_r1: + movi %r0 1 + movi %r1 -1 + bltr_u xlteu_r0_r1 %r0 %r1 + calli @abort +xlteu_r0_r1: + blei_u xleiu_r0_r1 %r0 -1 + calli @abort +xleiu_r0_r1: + movi %r0 32 + movi %r1 32 + beqr xeqr_r0_r1 %r0 %r1 + calli @abort +xeqr_r0_r1: + beqi xeqi_r0_r1 %r0 32 + calli @abort +xeqi_r0_r1: + movi %r0 -2 + movi %r1 -2 + bger xger_r0_r1 %r0 %r1 + calli @abort +xger_r0_r1: + bgei xgei_r0_r1 %r0 -2 + calli @abort +xgei_r0_r1: + movi %r0 2 + movi %r1 2 + bger_u xgeru_r0_r1 %r0 %r1 + calli @abort +xgeru_r0_r1: + bgei_u xgeiu_r0_r1 %r0 2 + calli @abort +xgeiu_r0_r1: + movi %r0 2 + movi %r1 -2 + bgtr xgtr_r0_r1 %r0 %r1 + calli @abort +xgtr_r0_r1: + bgti xgti_r0_r1 %r0 -2 + calli @abort +xgti_r0_r1: + movi %r0 -2 + movi %r1 2 + bgtr_u xgtru_r0_r1 %r0 %r1 + calli @abort +xgtru_r0_r1: + bgti_u xgtiu_r0_r1 %r0 2 + calli @abort +xgtiu_r0_r1: + movi %r0 -3 + movi %r1 3 + bner xner_r0_r1 %r0 %r1 + calli @abort +xner_r0_r1: + bnei xnei_r0_r1 %r0 3 + calli @abort +xnei_r0_r1: + movi %r0 1 + movi %r1 3 + bmsr xmsr_r0_r1 %r0 %r1 + calli @abort +xmsr_r0_r1: + bmsi xmsi_r0_r1 %r0 3 + calli @abort +xmsi_r0_r1: + movi %r0 1 + movi %r1 2 + bmcr xmcr_r0_r1 %r0 %r1 + calli @abort +xmcr_r0_r1: + bmci xmci_r0_r1 %r0 2 + calli @abort +xmci_r0_r1: + movi %r0 I7f + movi %r1 1 + boaddr xoaddr_r0_r1 %r0 %r1 + calli @abort +xoaddr_r0_r1: + movi %r0 Iff + movi %r1 1 + boaddr_u xoaddr_u_r0_r1 %r0 %r1 + calli @abort +xoaddr_u_r0_r1: + movi %r0 I7f + boaddi xoaddi_r0_r1 %r0 1 + calli @abort +xoaddi_r0_r1: + movi %r0 Iff + boaddi_u xoaddi_u_r0_r1 %r0 1 + calli @abort +xoaddi_u_r0_r1: + movi %r0 I80 + movi %r1 1 + bxaddr xxaddr_r0_r1 %r0 %r1 + calli @abort +xxaddr_r0_r1: + movi %r0 I80 + bxaddi xxaddi_r0_r1 %r0 1 + calli @abort +xxaddi_r0_r1: + movi %r0 I7f + movi %r1 1 + bxaddr_u xxaddr_u_r0_r1 %r0 %r1 + calli @abort +xxaddr_u_r0_r1: + movi %r0 I7f + bxaddi_u xxaddi_u_r0_r1 %r0 1 + calli @abort +xxaddi_u_r0_r1: + movi %r0 I80 + movi %r1 1 + bosubr xosubr_r0_r1 %r0 %r1 + calli @abort +xosubr_r0_r1: + movi %r0 0 + movi %r1 1 + bosubr_u xosubr_u_r0_r1 %r0 %r1 + calli @abort +xosubr_u_r0_r1: + movi %r0 I80 + bosubi xosubi_r0_r1 %r0 1 + calli @abort +xosubi_r0_r1: + movi %r0 0 + bosubi_u xosubi_u_r0_r1 %r0 1 + calli @abort +xosubi_u_r0_r1: + movi %r0 I81 + movi %r1 1 + bxsubr xxsubr_r0_r1 %r0 %r1 + calli @abort +xxsubr_r0_r1: + movi %r0 I81 + bxsubi xxsubi_r0_r1 %r0 1 + calli @abort +xxsubi_r0_r1: + movi %r0 I80 + movi %r1 1 + bxsubr_u xxsubr_u_r0_r1 %r0 %r1 + calli @abort +xxsubr_u_r0_r1: + movi %r0 I80 + bxsubi_u xxsubi_u_r0_r1 %r0 1 + calli @abort +xxsubi_u_r0_r1: + movi_f %f0 1 + movi_f %f1 2 + bltr_f xltr_f_f0_f1 %f0 %f1 + calli @abort +xltr_f_f0_f1: + blti_f xlti_f_f0_f1 %f0 2 + calli @abort +xlti_f_f0_f1: + movi_f %f0 -1 + movi_f %f1 -1 + bler_f xler_f_f0_f1 %f0 %f1 + calli @abort +xler_f_f0_f1: + blei_f xlei_f_f0_f1 %f0 -1 + calli @abort +xlei_f_f0_f1: + movi_f %f0 -2 + movi_f %f1 -2 + beqr_f xeqr_f_f0_f1 %f0 %f1 + calli @abort +xeqr_f_f0_f1: + beqi_f xeqi_f_f0_f1 %f0 -2 + calli @abort +xeqi_f_f0_f1: + movi_f %f0 -3 + movi_f %f1 -3 + bger_f xger_f_f0_f1 %f0 %f1 + calli @abort +xger_f_f0_f1: + bgei_f xgei_f_f0_f1 %f0 -3 + calli @abort +xgei_f_f0_f1: + movi_f %f0 2 + movi_f %f1 1 + bgtr_f xgtr_f_f0_f1 %f0 %f1 + calli @abort +xgtr_f_f0_f1: + bgti_f xgti_f_f0_f1 %f0 1 + calli @abort +xgti_f_f0_f1: + movi_f %f0 0 + movi_f %f1 2 + bner_f xner_f_f0_f1 %f0 %f1 + calli @abort +xner_f_f0_f1: + bnei_f xnei_f_f0_f1 %f0 2 + calli @abort +xnei_f_f0_f1: + + 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) + movi_f %f0 5 + movi_f %f1 5 + bordr_f ordr_f %f0 %f1 + calli @abort +ordr_f: + bordi_f ordi_f %f0 1 + calli @abort +ordi_f: + bordi_f ordi_f_u %f0 $NaN + jmpi ordi_f_u0 +ordi_f_u: + calli @abort +ordi_f_u0: + movi_f %f0 5 + movi_f %f1 5 + bunordr_f unordr_f %f0 %f1 + jmpi unordr_f_0 +unordr_f: + calli @abort +unordr_f_0: + bunordi_f unordi_f %f0 1 + jmpi unordi_f_0 +unordi_f: + calli @abort +unordi_f_0: + bunordi_f unordi_f_1 %f0 $NaN + calli @abort +unordi_f_1: + + // just to know did not crash or abort + prepare + pushargi ok + ellipsis + finishi @printf + + ret + epilog diff --git a/deps/lightning/check/call.ok b/deps/lightning/check/call.ok new file mode 100644 index 0000000..cc119df --- /dev/null +++ b/deps/lightning/check/call.ok @@ -0,0 +1,4 @@ +forward +backward +forward +backward diff --git a/deps/lightning/check/call.tst b/deps/lightning/check/call.tst new file mode 100644 index 0000000..21068b6 --- /dev/null +++ b/deps/lightning/check/call.tst @@ -0,0 +1,272 @@ +#define def_wi(i) \ + name _w##i \ +_w##i: \ + prolog \ + arg $arg##i \ + getarg##i %r0 $arg##i \ + retr %r0 \ + epilog +#define def_wf(f) \ + name _w##f \ +_w##f: \ + prolog \ + arg##f $arg##f \ + getarg##f %f0 $arg##f \ + truncr##f %r0 %f0 \ + retr %r0 \ + epilog +#define def_fi(f, i) \ + name f##i \ +f##i: \ + prolog \ + arg $arg##i \ + getarg##i %r0 $arg##i \ + extr##f %f0 %r0 \ + retr##f %f0 \ + epilog +#define def_f(f) \ + name f##f \ +f##f: \ + prolog \ + arg##f $arg##f \ + getarg##f %f0 $arg##f \ + retr##f %f0 \ + epilog +#define def_ff(f, g) \ + name f##g \ + name f##g \ +f##g: \ + prolog \ + arg##g $arg##g \ + getarg##g %f0 $arg##g \ + extr##g##f %f0 %f0 \ + retr##f %f0 \ + epilog + +.data 32 +fstr: +.c "forward" +bstr: +.c "backward" + +.code + jmpi main + + 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) + + name main +main: + prolog + +#define _call_w(n, i, a, r) \ + prepare \ + pushargi a \ + finishi _w##i \ + retval %r0 \ + extr##i %r0 %r0 \ + beqi _w##i##_##n %r0 r \ + calli @abort \ +_w##i##_##n: +#define call_w(n, i, a, r) _call_w(n, i, a, r) +#define _call_wf(n, f, a, r) \ + prepare \ + pushargi##f a \ + finishi _w##f \ + retval %r0 \ + extr##f %f0 %r0 \ + beqi##f _w##f##_##n %f0 r \ + calli @abort \ +_w##f##_##n: +#define call_wf(n, f, a, r) _call_wf(n, f, a, r) +#define _call_fi(n, f, i, a, r) \ + prepare \ + pushargi a \ + finishi f##i \ + retval##f %f0 \ + beqi##f f##i##n %f0 r \ + calli @abort \ +f##i##n: +#define call_fi(n, f, i, a, r) _call_fi(n, f, i, a, r) +#define _call_f(n, f, a, r) \ + prepare \ + pushargi##f a \ + finishi f##f \ + retval##f %f0 \ + beqi##f f##f##n %f0 r \ + calli @abort \ +f##f##n: +#define call_f(n, f, a, r) _call_f(n, f, a, r) +#define _call_ff(n, f, g, a, r) \ + prepare \ + pushargi##g a \ + finishi f##g \ + retval##f %f0 \ + beqi##f f##g##n %f0 r \ + calli @abort \ +f##g##n: +#define call_ff(n, f, g, a, r) _call_ff(n, f, g, a, r) + +#define c7f 0x7f +#define c80 0x80 +#define c81 0x81 +#define cff 0xff +#define s7f 0x7fff +#define s80 0x8000 +#define s81 0x8001 +#define i7f 0x7fffffff +#define i80 0x80000000 +#define i81 0x80000001 +#define iff 0xffffffff +#define l7f 0x7fffffffffffffff +#define l80 0x8000000000000000 +#define l81 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 0xffffff80 +# define wc81 0xffffff81 +# define ws80 0xffff8000 +# define ws81 0xffff8001 +#else +# define wc80 0xffffffffffffff80 +# define wc81 0xffffffffffffff81 +# define ws80 0xffffffffffff8000 +# define ws81 0xffffffffffff8001 +# define wi80 0xffffffff80000000 +# define wi81 0xffffffff80000001 +#endif + + call_w(__LINE__, _c, c7f, c7f) + call_w(__LINE__, _c, c80, wc80) + call_w(__LINE__, _c, c81, wc81) + call_w(__LINE__, _uc, c7f, c7f) + call_w(__LINE__, _uc, c80, c80) + call_w(__LINE__, _uc, c81, c81) + call_w(__LINE__, _s, s7f, s7f) + call_w(__LINE__, _s, s80, ws80) + call_w(__LINE__, _s, s81, ws81) + call_w(__LINE__, _us, s7f, s7f) + call_w(__LINE__, _us, s80, s80) + call_w(__LINE__, _us, s81, s81) +#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, i7f, i7f) + call_w(__LINE__, _ui, i80, i80) + call_w(__LINE__, _ui, i81, i81) +#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, c7f, f7f) + call_fi(__LINE__, _f, _uc, c80, uf80) + call_fi(__LINE__, _f, _s, c7f, f7f) + call_fi(__LINE__, _f, _s, c80, uf80) + call_fi(__LINE__, _f, _us, c7f, f7f) + call_fi(__LINE__, _f, _us, c80, uf80) + call_fi(__LINE__, _f, _i, c7f, f7f) + call_fi(__LINE__, _f, _i, c80, uf80) +#if __WORDSIZE == 64 + call_fi(__LINE__, _f, _ui, c7f, f7f) + call_fi(__LINE__, _f, _ui, c80, uf80) + call_fi(__LINE__, _f, _l, c7f, f7f) + call_fi(__LINE__, _f, _l, c80, uf80) +#endif + call_fi(__LINE__, _d, _c, c7f, f7f) + call_fi(__LINE__, _d, _c, c80, f80) + call_fi(__LINE__, _d, _uc, c7f, f7f) + call_fi(__LINE__, _d, _uc, c80, uf80) + call_fi(__LINE__, _d, _s, c7f, f7f) + call_fi(__LINE__, _d, _s, c80, uf80) + call_fi(__LINE__, _d, _us, c7f, f7f) + call_fi(__LINE__, _d, _us, c80, uf80) + call_fi(__LINE__, _d, _i, c7f, f7f) + call_fi(__LINE__, _d, _i, c80, uf80) +#if __WORDSIZE == 64 + call_fi(__LINE__, _d, _ui, c7f, f7f) + call_fi(__LINE__, _d, _ui, c80, uf80) + call_fi(__LINE__, _d, _l, c7f, f7f) + call_fi(__LINE__, _d, _l, c80, 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) + + movi %r0 forward + callr %r0 + + calli iforward + + ret + epilog + + name backward +backward: + prolog + prepare + pushargi bstr + finishi @puts + ret + epilog + + name forward +forward: + prolog + prepare + pushargi fstr + finishi @puts + movi %r0 backward + callr %r0 + ret + epilog + + name iforward +iforward: + prolog + prepare + pushargi fstr + finishi @puts + calli backward + ret + epilog diff --git a/deps/lightning/check/carg.c b/deps/lightning/check/carg.c new file mode 100644 index 0000000..35b897e --- /dev/null +++ b/deps/lightning/check/carg.c @@ -0,0 +1,538 @@ +#include <lightning.h> +#include <stdio.h> + +/* Simple test for arguments handling, that also shows how to use + * arguments to store values. + * Register arguments, if available, are very fast, but are also + * very volatile on some ports, because some ports will do C calls + * to implement division, remainder, sometimes multiplication, or + * some float operations. + * Arguments in registers should be fetched in the prolog of the + * function, and if they must be saved, they should be saved in + * the prolog. + * The predicate macro "jit_arg_register_p(arg)" allows knowing if + * an argument lives in a register, where it is known for being a very + * fast to read/write temporary storage. + */ + +#define W jit_word_t +#define F jit_float32_t +#define D jit_float64_t + +jit_state_t *_jit; + +void +cw(W a1, W a2, W a3, W a4, W a5, W a6, W a7, W a8, + W a9, W a10, W a11, W a12, W a13, W a14, W a15, W a16) +{ + if ( a1 != 1 || a2 != 2 || a3 != 3 || a4 != 4 || + a5 != 5 || a6 != 6 || a7 != 7 || a8 != 8 || + a9 != 9 || a10 != 10 || a11 != 11 || a12 != 12 || + a13 != 13 || a14 != 14 || a15 != 15 || a16 != 16) + abort(); +} + +void +cf(F a1, F a2, F a3, F a4, F a5, F a6, F a7, F a8, + F a9, F a10, F a11, F a12, F a13, F a14, F a15, F a16) +{ + if ( a1 != 1 || a2 != 2 || a3 != 3 || a4 != 4 || + a5 != 5 || a6 != 6 || a7 != 7 || a8 != 8 || + a9 != 9 || a10 != 10 || a11 != 11 || a12 != 12 || + a13 != 13 || a14 != 14 || a15 != 15 || a16 != 16) + abort(); +} + +void +cd(D a1, D a2, D a3, D a4, D a5, D a6, D a7, D a8, + D a9, D a10, D a11, D a12, D a13, D a14, D a15, D a16) +{ + if ( a1 != 1 || a2 != 2 || a3 != 3 || a4 != 4 || + a5 != 5 || a6 != 6 || a7 != 7 || a8 != 8 || + a9 != 9 || a10 != 10 || a11 != 11 || a12 != 12 || + a13 != 13 || a14 != 14 || a15 != 15 || a16 != 16) + abort(); +} + +int +main(int argc, char *argv[]) +{ + void (*code)(void); + jit_node_t *jmp, *pass; + jit_node_t *jw, *jf, *jd; + jit_int32_t s1, s2, s3, s4, s5, s6, s7, s8, + s9, s10, s11, s12, s13, s14, s15, s16; + jit_node_t *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, + *a9, *a10, *a11, *a12, *a13, *a14, *a15, *a16; + + init_jit(argv[0]); + _jit = jit_new_state(); + + /* jump to "main" label */ + jmp = jit_jmpi(); + + /* Create jit function that + * o Receives 16 word arguments + * o Save in the stack any register argument. Also force register + * arguments to be clobbered to properly make the test + * o Calls a C function that receives 16 word arguments, with + * values different from the ones received by this function + * o Reload from stack any register argument + * o Validated all arguments were not modified in the known + * cases it could have been clobbered + */ + jw = jit_label(); + jit_name("jw"); + jit_note(__FILE__, __LINE__); + jit_prolog(); + a1 = jit_arg(); + a2 = jit_arg(); + a3 = jit_arg(); + a4 = jit_arg(); + a5 = jit_arg(); + a6 = jit_arg(); + a7 = jit_arg(); + a8 = jit_arg(); + a9 = jit_arg(); + a10 = jit_arg(); + a11 = jit_arg(); + a12 = jit_arg(); + a13 = jit_arg(); + a14 = jit_arg(); + a15 = jit_arg(); + a16 = jit_arg(); +#define SAVE_ARG(N) \ + do { \ + if (jit_arg_register_p(a##N)) { \ + s##N = jit_allocai(sizeof(W)); \ + jit_getarg(JIT_R0, a##N); \ + jit_stxi(s##N, JIT_FP, JIT_R0); \ + jit_putargi(-1, a##N); \ + } \ + } while (0) + SAVE_ARG(1); + SAVE_ARG(2); + SAVE_ARG(3); + SAVE_ARG(4); + SAVE_ARG(5); + SAVE_ARG(6); + SAVE_ARG(7); + SAVE_ARG(8); + SAVE_ARG(9); + SAVE_ARG(10); + SAVE_ARG(11); + SAVE_ARG(12); + SAVE_ARG(13); + SAVE_ARG(14); + SAVE_ARG(15); + SAVE_ARG(16); +#undef SAVE_ARG + jit_prepare(); + { + jit_pushargi(1); + jit_pushargi(2); + jit_pushargi(3); + jit_pushargi(4); + jit_pushargi(5); + jit_pushargi(6); + jit_pushargi(7); + jit_pushargi(8); + jit_pushargi(9); + jit_pushargi(10); + jit_pushargi(11); + jit_pushargi(12); + jit_pushargi(13); + jit_pushargi(14); + jit_pushargi(15); + jit_pushargi(16); + } + jit_finishi(cw); +#define LOAD_ARG(N) \ + do { \ + if (jit_arg_register_p(a##N)) { \ + jit_ldxi(JIT_R0, JIT_FP, s##N); \ + jit_putargr(JIT_R0, a##N); \ + } \ + } while (0) + LOAD_ARG(1); + LOAD_ARG(2); + LOAD_ARG(3); + LOAD_ARG(4); + LOAD_ARG(5); + LOAD_ARG(6); + LOAD_ARG(7); + LOAD_ARG(8); + LOAD_ARG(9); + LOAD_ARG(10); + LOAD_ARG(11); + LOAD_ARG(12); + LOAD_ARG(13); + LOAD_ARG(14); + LOAD_ARG(15); + LOAD_ARG(16); +#undef LOAD_ARG + pass = jit_forward(); +#define CHECK_ARG(N) \ + do { \ + jit_getarg(JIT_R0, a##N); \ + jit_patch_at(jit_beqi(JIT_R0, 17 - N), pass); \ + } while (0) + CHECK_ARG(1); + CHECK_ARG(2); + CHECK_ARG(3); + CHECK_ARG(4); + CHECK_ARG(5); + CHECK_ARG(6); + CHECK_ARG(7); + CHECK_ARG(8); + CHECK_ARG(9); + CHECK_ARG(10); + CHECK_ARG(11); + CHECK_ARG(12); + CHECK_ARG(13); + CHECK_ARG(14); + CHECK_ARG(15); + CHECK_ARG(16); +#undef CHECK_ARG + jit_calli(abort); + jit_link(pass); + jit_ret(); + jit_epilog(); + + /* Create jit function that + * o Receives 16 float arguments + * o Save in the stack any register argument. Also force register + * arguments to be clobbered to properly make the test + * o Calls a C function that receives 16 float arguments, with + * values different from the ones received by this function + * o Reload from stack any register argument + * o Validated all arguments were not modified in the known + * cases it could have been clobbered + */ + jf = jit_label(); + jit_name("jf"); + jit_note(__FILE__, __LINE__); + jit_prolog(); + a1 = jit_arg_f(); + a2 = jit_arg_f(); + a3 = jit_arg_f(); + a4 = jit_arg_f(); + a5 = jit_arg_f(); + a6 = jit_arg_f(); + a7 = jit_arg_f(); + a8 = jit_arg_f(); + a9 = jit_arg_f(); + a10 = jit_arg_f(); + a11 = jit_arg_f(); + a12 = jit_arg_f(); + a13 = jit_arg_f(); + a14 = jit_arg_f(); + a15 = jit_arg_f(); + a16 = jit_arg_f(); +#define SAVE_ARG(N) \ + do { \ + if (jit_arg_register_p(a##N)) { \ + s##N = jit_allocai(sizeof(F)); \ + jit_getarg_f(JIT_F0, a##N); \ + jit_stxi_f(s##N, JIT_FP, JIT_F0); \ + jit_putargi_f(-1, a##N); \ + } \ + } while (0) + SAVE_ARG(1); + SAVE_ARG(2); + SAVE_ARG(3); + SAVE_ARG(4); + SAVE_ARG(5); + SAVE_ARG(6); + SAVE_ARG(7); + SAVE_ARG(8); + SAVE_ARG(9); + SAVE_ARG(10); + SAVE_ARG(11); + SAVE_ARG(12); + SAVE_ARG(13); + SAVE_ARG(14); + SAVE_ARG(15); + SAVE_ARG(16); +#undef SAVE_ARG + jit_prepare(); + { + jit_pushargi_f(1); + jit_pushargi_f(2); + jit_pushargi_f(3); + jit_pushargi_f(4); + jit_pushargi_f(5); + jit_pushargi_f(6); + jit_pushargi_f(7); + jit_pushargi_f(8); + jit_pushargi_f(9); + jit_pushargi_f(10); + jit_pushargi_f(11); + jit_pushargi_f(12); + jit_pushargi_f(13); + jit_pushargi_f(14); + jit_pushargi_f(15); + jit_pushargi_f(16); + } + jit_finishi(cf); +#define LOAD_ARG(N) \ + do { \ + if (jit_arg_register_p(a##N)) { \ + jit_ldxi_f(JIT_F0, JIT_FP, s##N); \ + jit_putargr_f(JIT_F0, a##N); \ + } \ + } while (0) + LOAD_ARG(1); + LOAD_ARG(2); + LOAD_ARG(3); + LOAD_ARG(4); + LOAD_ARG(5); + LOAD_ARG(6); + LOAD_ARG(7); + LOAD_ARG(8); + LOAD_ARG(9); + LOAD_ARG(10); + LOAD_ARG(11); + LOAD_ARG(12); + LOAD_ARG(13); + LOAD_ARG(14); + LOAD_ARG(15); + LOAD_ARG(16); +#undef LOAD_ARG + pass = jit_forward(); +#define CHECK_ARG(N) \ + do { \ + jit_getarg_f(JIT_F0, a##N); \ + jit_patch_at(jit_beqi_f(JIT_F0, 17 - N), pass); \ + } while (0) + CHECK_ARG(1); + CHECK_ARG(2); + CHECK_ARG(3); + CHECK_ARG(4); + CHECK_ARG(5); + CHECK_ARG(6); + CHECK_ARG(7); + CHECK_ARG(8); + CHECK_ARG(9); + CHECK_ARG(10); + CHECK_ARG(11); + CHECK_ARG(12); + CHECK_ARG(13); + CHECK_ARG(14); + CHECK_ARG(15); + CHECK_ARG(16); +#undef CHECK_ARG + jit_calli(abort); + jit_link(pass); + jit_ret(); + jit_epilog(); + + /* Create jit function that + * o Receives 16 double arguments + * o Save in the stack any register argument. Also force register + * arguments to be clobbered to properly make the test + * o Calls a C function that receives 16 double arguments, with + * values different from the ones received by this function + * o Reload from stack any register argument + * o Validated all arguments were not modified in the known + * cases it could have been clobbered + */ + jd = jit_label(); + jit_name("jd"); + jit_note(__FILE__, __LINE__); + jit_prolog(); + a1 = jit_arg_d(); + a2 = jit_arg_d(); + a3 = jit_arg_d(); + a4 = jit_arg_d(); + a5 = jit_arg_d(); + a6 = jit_arg_d(); + a7 = jit_arg_d(); + a8 = jit_arg_d(); + a9 = jit_arg_d(); + a10 = jit_arg_d(); + a11 = jit_arg_d(); + a12 = jit_arg_d(); + a13 = jit_arg_d(); + a14 = jit_arg_d(); + a15 = jit_arg_d(); + a16 = jit_arg_d(); +#define SAVE_ARG(N) \ + do { \ + if (jit_arg_register_p(a##N)) { \ + s##N = jit_allocai(sizeof(D)); \ + jit_getarg_d(JIT_F0, a##N); \ + jit_stxi_d(s##N, JIT_FP, JIT_F0); \ + jit_putargi_d(-1, a##N); \ + } \ + } while (0) + SAVE_ARG(1); + SAVE_ARG(2); + SAVE_ARG(3); + SAVE_ARG(4); + SAVE_ARG(5); + SAVE_ARG(6); + SAVE_ARG(7); + SAVE_ARG(8); + SAVE_ARG(9); + SAVE_ARG(10); + SAVE_ARG(11); + SAVE_ARG(12); + SAVE_ARG(13); + SAVE_ARG(14); + SAVE_ARG(15); + SAVE_ARG(16); +#undef SAVE_ARG + jit_prepare(); + { + jit_pushargi_d(1); + jit_pushargi_d(2); + jit_pushargi_d(3); + jit_pushargi_d(4); + jit_pushargi_d(5); + jit_pushargi_d(6); + jit_pushargi_d(7); + jit_pushargi_d(8); + jit_pushargi_d(9); + jit_pushargi_d(10); + jit_pushargi_d(11); + jit_pushargi_d(12); + jit_pushargi_d(13); + jit_pushargi_d(14); + jit_pushargi_d(15); + jit_pushargi_d(16); + } + jit_finishi(cd); +#define LOAD_ARG(N) \ + do { \ + if (jit_arg_register_p(a##N)) { \ + jit_ldxi_d(JIT_F0, JIT_FP, s##N); \ + jit_putargr_d(JIT_F0, a##N); \ + } \ + } while (0) + LOAD_ARG(1); + LOAD_ARG(2); + LOAD_ARG(3); + LOAD_ARG(4); + LOAD_ARG(5); + LOAD_ARG(6); + LOAD_ARG(7); + LOAD_ARG(8); + LOAD_ARG(9); + LOAD_ARG(10); + LOAD_ARG(11); + LOAD_ARG(12); + LOAD_ARG(13); + LOAD_ARG(14); + LOAD_ARG(15); + LOAD_ARG(16); +#undef LOAD_ARG + pass = jit_forward(); +#define CHECK_ARG(N) \ + do { \ + jit_getarg_d(JIT_F0, a##N); \ + jit_patch_at(jit_beqi_d(JIT_F0, 17 - N), pass); \ + } while (0) + CHECK_ARG(1); + CHECK_ARG(2); + CHECK_ARG(3); + CHECK_ARG(4); + CHECK_ARG(5); + CHECK_ARG(6); + CHECK_ARG(7); + CHECK_ARG(8); + CHECK_ARG(9); + CHECK_ARG(10); + CHECK_ARG(11); + CHECK_ARG(12); + CHECK_ARG(13); + CHECK_ARG(14); + CHECK_ARG(15); + CHECK_ARG(16); +#undef CHECK_ARG + jit_calli(abort); + jit_link(pass); + jit_ret(); + jit_epilog(); + + /* Create a jit function that calls the 3 previous ones. + * o First call the function that receives 16 word arguments + * o Then call the function that receives 16 float arguments + * o Finally call the function that receives 16 double arguments + */ + jit_patch(jmp); + jit_name("main"); + jit_note(__FILE__, __LINE__); + jit_prolog(); + jit_prepare(); + { + jit_pushargi(16); + jit_pushargi(15); + jit_pushargi(14); + jit_pushargi(13); + jit_pushargi(12); + jit_pushargi(11); + jit_pushargi(10); + jit_pushargi(9); + jit_pushargi(8); + jit_pushargi(7); + jit_pushargi(6); + jit_pushargi(5); + jit_pushargi(4); + jit_pushargi(3); + jit_pushargi(2); + jit_pushargi(1); + } + jit_patch_at(jit_finishi(NULL), jw); + jit_prepare(); + { + jit_pushargi_f(16); + jit_pushargi_f(15); + jit_pushargi_f(14); + jit_pushargi_f(13); + jit_pushargi_f(12); + jit_pushargi_f(11); + jit_pushargi_f(10); + jit_pushargi_f(9); + jit_pushargi_f(8); + jit_pushargi_f(7); + jit_pushargi_f(6); + jit_pushargi_f(5); + jit_pushargi_f(4); + jit_pushargi_f(3); + jit_pushargi_f(2); + jit_pushargi_f(1); + } + jit_patch_at(jit_finishi(NULL), jf); + jit_prepare(); + { + jit_pushargi_d(16); + jit_pushargi_d(15); + jit_pushargi_d(14); + jit_pushargi_d(13); + jit_pushargi_d(12); + jit_pushargi_d(11); + jit_pushargi_d(10); + jit_pushargi_d(9); + jit_pushargi_d(8); + jit_pushargi_d(7); + jit_pushargi_d(6); + jit_pushargi_d(5); + jit_pushargi_d(4); + jit_pushargi_d(3); + jit_pushargi_d(2); + jit_pushargi_d(1); + } + jit_patch_at(jit_finishi(NULL), jd); + jit_ret(); + jit_epilog(); + + code = jit_emit(); + jit_clear_state(); + + (*code)(); + + jit_destroy_state(); + finish_jit(); + return (0); +} diff --git a/deps/lightning/check/carry.ok b/deps/lightning/check/carry.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/carry.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/carry.tst b/deps/lightning/check/carry.tst new file mode 100644 index 0000000..180d896 --- /dev/null +++ b/deps/lightning/check/carry.tst @@ -0,0 +1,186 @@ + +#define ix0 0 +#define lx0 0 +#define ix1 1 +#define lx1 1 +#define ix2 2 +#define lx2 2 +#define ix4 4 +#define lx4 4 +#if __WORDSIZE == 32 +# define ix7fe 0x7ffffffe +# define ix7f 0x7fffffff +# define ix80 0x80000000 +# define iff 0xffffffff +# define ife 0xfffffffe +# define ifd 0xfffffffd +# define ifc 0xfffffffc +#else +# define ix7fe 0x7ffffffffffffffe +# define ix7f 0x7fffffffffffffff +# define ix80 0x8000000000000000 +# define iff 0xffffffffffffffff +# define ife 0xfffffffffffffffe +# define ifd 0xfffffffffffffffd +# define ifc 0xfffffffffffffffc +#endif + +/* check jumps are taken and result value is correct */ +#define bopr_t(l, u, op, r0, r1, il, ir, iv) \ + movi %r0 il \ + movi %r1 ir \ + b##op##r##u op##u##r##l##r0##r1 %r0 %r1 \ + /* validate did jump */ \ + movi %r0 0x5a5a5a5a \ +op##u##r##l##r0##r1: \ + beqi op##u##r##l##ok##r0##r1 %r0 iv \ + calli @abort \ +op##u##r##l##ok##r0##r1: +#define bopi_t(l, u, op, r0, il, ir, iv) \ + movi %r0 il \ + b##op##i##u op##u##i##l##r0##r1 %r0 ir \ + /* validate did jump */ \ + movi %r0 0x5a5a5a5a \ +op##u##i##l##r0##r1: \ + beqi op##u##i##l##ok##r0##r1 %r0 iv \ + calli @abort \ +op##u##i##l##ok##r0##r1: +#define bopr_f(l, u, op, r0, r1, il, ir, iv) \ + movi %r0 il \ + movi %r1 ir \ + b##op##r##u op##u##r##l##r0##r1 %r0 %r1 \ + beqi op##u##r##l##ok##r0##r1 %r0 iv \ +op##u##r##l##r0##r1: \ + calli @abort \ +op##u##r##l##ok##r0##r1: +#define bopi_f(l, u, op, r0, il, ir, iv) \ + movi %r0 il \ + b##op##i##u op##u##i##l##r0##r1 %r0 ir \ + beqi op##u##i##l##ok##r0##r1 %r0 iv \ +op##u##i##l##r0##r1: \ + calli @abort \ +op##u##i##l##ok##r0##r1: +#define ccop(cc, l, u, op, r0, r1, il, ir, iv) \ + bopr##cc(l, u, op, r0, r1, i##il, i##ir, i##iv) \ + bopi##cc(l, u, op, r0, i##il, i##ir, i##iv) +#define tadd(l, u, r0, r1, il, ir, iv) \ + ccop(_t, l, u, oadd, r0, r1, il, ir, iv) \ + ccop(_f, l, u, xadd, r0, r1, il, ir, iv) +#define fadd(l, u, r0, r1, il, ir, iv) \ + ccop(_f, l, u, oadd, r0, r1, il, ir, iv) \ + ccop(_t, l, u, xadd, r0, r1, il, ir, iv) +#define tsub(l, u, r0, r1, il, ir, iv) \ + ccop(_t, l, u, osub, r0, r1, il, ir, iv) \ + ccop(_f, l, u, xsub, r0, r1, il, ir, iv) +#define fsub(l, u, r0, r1, il, ir, iv) \ + ccop(_f, l, u, osub, r0, r1, il, ir, iv) \ + ccop(_t, l, u, xsub, r0, r1, il, ir, iv) + +#define xopr6(l,op,r0,r1,r2,r3,r4,r5,llo,lhi,rlo,rhi,vlo,vhi) \ + movi %r1 llo \ + movi %r2 lhi \ + movi %r4 rlo \ + movi %r5 rhi \ + op##cr %r0 %r1 %r4 \ + op##xr %r3 %r2 %r5 \ + beqi op##l##L##r0##r1##r2##r3##r4##r5 %r0 vlo \ + calli @abort \ +op##l##L##r0##r1##r2##r3##r4##r5: \ + beqi op##l##H##r0##r1##r2##r3##r4##r5 %r3 vhi \ + calli @abort \ +op##l##H##r0##r1##r2##r3##r4##r5: +#define xopr4_(l,op,r0,r1,r2,r3,llo,lhi,rlo,rhi,vlo,vhi) \ + movi %r0 llo \ + movi %r1 lhi \ + movi %r2 rlo \ + movi %r3 rhi \ + op##cr %r0 %r0 %r2 \ + op##xr %r1 %r1 %r3 \ + beqi op##l##L_##r0##r1##r2##r3 %r0 vlo \ + calli @abort \ +op##l##L_##r0##r1##r2##r3: \ + beqi op##l##H_##r0##r1##r2##r3 %r1 vhi \ + calli @abort \ +op##l##H_##r0##r1##r2##r3: +#define xopr_4(l,op,r0,r1,r2,r3,llo,lhi,rlo,rhi,vlo,vhi) \ + movi %r0 rlo \ + movi %r1 rhi \ + movi %r2 llo \ + movi %r3 lhi \ + op##cr %r0 %r2 %r0 \ + op##xr %r1 %r3 %r1 \ + beqi op##l##_L##r0##r1##r2##r3 %r0 vlo \ + calli @abort \ +op##l##_L##r0##r1##r2##r3: \ + beqi op##l##_H##r0##r1##r2##r3 %r1 vhi \ + calli @abort \ +op##l##_H##r0##r1##r2##r3: + +#define xaddr(l,llo,lhi,rlo,rhi,vlo,vhi) \ + xopr6(l,add,r0,r1,r2,v0,v1,v2,i##llo,i##lhi,i##rlo,i##rhi,i##vlo,i##vhi) \ + xopr4_(l,add,r0,r1,r2,v0,i##llo,i##lhi,i##rlo,i##rhi,i##vlo,i##vhi) \ + xopr_4(l,add,r0,r1,r2,v0,i##llo,i##lhi,i##rlo,i##rhi,i##vlo,i##vhi) +#define xsubr(l,llo,lhi,rlo,rhi,vlo,vhi) \ + xopr6(l,sub,r0,r1,r2,v0,v1,v2,i##llo,i##lhi,i##rlo,i##rhi,i##vlo,i##vhi) \ + xopr4_(l,sub,r0,r1,r2,v0,i##llo,i##lhi,i##rlo,i##rhi,i##vlo,i##vhi) \ + xopr_4(l,sub,r0,r1,r2,v0,i##llo,i##lhi,i##rlo,i##rhi,i##vlo,i##vhi) + +.data 16 +ok: +.c "ok\n" + +.code + prolog + + tadd(__LINE__, , r0, r1, x7f, x1, x80) + fadd(__LINE__, , r0, r1, x7fe, x1, x7f) + tsub(__LINE__, , r0, r1, x80, x1, x7f) + fsub(__LINE__, , r0, r1, x7f, x1, x7fe) + tadd(__LINE__, _u, r0, r1, ff, x1, x0) + fadd(__LINE__, _u, r0, r1, x7f, x1, x80) + tsub(__LINE__, _u, r0, r1, x0, x1, ff) + fsub(__LINE__, _u, r0, r1, x80, x1, x7f) + + /* 0xffffffffffffffff + 1 = 0x10000000000000000 */ + xaddr(__LINE__, ff, ff, x1, x0, x0, x0) + + /* 1 + 0xffffffffffffffff = 0x10000000000000000 */ + xaddr(__LINE__, x1, x0, ff, ff, x0, x0) + + /* 0xfffffffeffffffff + 1 = 0xffffffff00000000 */ + xaddr(__LINE__, ff, fe, x1, x0, x0, ff) + + /* 1 + 0xfffffffeffffffff = 0xffffffff00000000 */ + xaddr(__LINE__, x1, x0, ff, fe, x0, ff) + + /* 0xfffffffefffffffe + 2 = 0xffffffff00000000 */ + xaddr(__LINE__, fe, fe, x2, x0, x0, ff) + + /* 2 + 0xfffffffefffffffe = 0xffffffff00000000 */ + xaddr(__LINE__, x2, x0, fe, fe, x0, ff) + + /* 0xffffffffffffffff - 1 = 0xfffffffffffffffe */ + xsubr(__LINE__, ff, ff, x1, x0, fe, ff) + + /* 1 - 0xffffffffffffffff = -0xfffffffffffffffe */ + xsubr(__LINE__, x1, x0, ff, ff, x2, x0) + + /* 0xfffffffeffffffff - 1 = 0xfffffffefffffffe */ + xsubr(__LINE__, ff, fe, x1, x0, fe, fe) + + /* 1 - 0xfffffffeffffffff = -0xfffffffefffffffe */ + xsubr(__LINE__, x1, x0, ff, fe, x2, x1) + + /* 0xfffffffefffffffe - 2 = 0xfffffffefffffffc */ + xsubr(__LINE__, fe, fe, x2, x0, fc, fe) + + /* 2 + 0xfffffffefffffffe = -0xfffffffefffffffc */ + xsubr(__LINE__, x2, x0, fe, fe, x4, x1) + + prepare + pushargi ok + ellipsis + finishi @printf + + ret + epilog diff --git a/deps/lightning/check/ccall.c b/deps/lightning/check/ccall.c new file mode 100644 index 0000000..9dae256 --- /dev/null +++ b/deps/lightning/check/ccall.c @@ -0,0 +1,903 @@ +#include <lightning.h> +#include <stdio.h> + +#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); \ + jit_node_t *n##T##0; +#define dat1(T) dat0(T) \ + T (*j##T##1)(T); \ + jit_node_t *n##T##1; +#define dat2(T) dat1(T) \ + T (*j##T##2)(T,T); \ + jit_node_t *n##T##2; +#define dat3(T) dat2(T) \ + T (*j##T##3)(T,T,T); \ + jit_node_t *n##T##3; +#define dat4(T) dat3(T) \ + T (*j##T##4)(T,T,T,T); \ + jit_node_t *n##T##4; +#define dat5(T) dat4(T) \ + T (*j##T##5)(T,T,T,T,T); \ + jit_node_t *n##T##5; +#define dat6(T) dat5(T) \ + T (*j##T##6)(T,T,T,T,T,T); \ + jit_node_t *n##T##6; +#define dat7(T) dat6(T) \ + T (*j##T##7)(T,T,T,T,T,T,T); \ + jit_node_t *n##T##7; +#define dat8(T) dat7(T) \ + T (*j##T##8)(T,T,T,T,T,T,T,T); \ + jit_node_t *n##T##8; +#define dat9(T) dat8(T) \ + T (*j##T##9)(T,T,T,T,T,T,T,T,T); \ + jit_node_t *n##T##9; +#define dat10(T) dat9(T) \ + T (*j##T##10)(T,T,T,T,T,T,T,T,T,T); \ + jit_node_t *n##T##10; +#define dat11(T) dat10(T) \ + T (*j##T##11)(T,T,T,T,T,T,T,T,T,T,T); \ + jit_node_t *n##T##11; +#define dat12(T) dat11(T) \ + T (*j##T##12)(T,T,T,T,T,T,T,T,T,T,T,T); \ + jit_node_t *n##T##12; +#define dat13(T) dat12(T) \ + T (*j##T##13)(T,T,T,T,T,T,T,T,T,T,T,T,T);\ + jit_node_t *n##T##13; +#define dat14(T) dat13(T) \ + T (*j##T##14)(T,T,T,T,T,T,T,T,T,T,T,T,T,T);\ + jit_node_t *n##T##14; +#define dat15(T) dat14(T) \ + T (*j##T##15)(T,T,T,T,T,T,T,T,T,T,T,T,T,T,T);\ + jit_node_t *n##T##15; +#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) \ +{ \ + return (0); \ +} +#define dcl1(T) \ +dcl0(T) \ +T C##T##1(T A) \ +{ \ + return (A); \ +} +#define dcl2(T) \ +dcl1(T) \ +T C##T##2(T A,T B) \ +{ \ + return (A-B); \ +} +#define dcl3(T) \ +dcl2(T) \ +T C##T##3(T A,T B,T C) \ +{ \ + return (A-B-C); \ +} +#define dcl4(T) \ +dcl3(T) \ +T C##T##4(T A,T B,T C,T D) \ +{ \ + return (A-B-C-D); \ +} +#define dcl5(T) \ +dcl4(T) \ +T C##T##5(T A,T B,T C,T D,T E) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + return ((*j##T##0)()); \ +} +#define dcl1(T) \ +dcl0(T) \ +T CJ##T##1(void) \ +{ \ + return ((*j##T##1)(1)); \ +} +#define dcl2(T) \ +dcl1(T) \ +T CJ##T##2(void) \ +{ \ + return ((*j##T##2)(1,2)); \ +} +#define dcl3(T) \ +dcl2(T) \ +T CJ##T##3(void) \ +{ \ + return ((*j##T##3)(1,2,3)); \ +} +#define dcl4(T) \ +dcl3(T) \ +T CJ##T##4(void) \ +{ \ + return ((*j##T##4)(1,2,3,4)); \ +} +#define dcl5(T) \ +dcl4(T) \ +T CJ##T##5(void) \ +{ \ + return ((*j##T##5)(1,2,3,4,5)); \ +} +#define dcl6(T) \ +dcl5(T) \ +T CJ##T##6(void) \ +{ \ + return ((*j##T##6)(1,2,3,4,5,6)); \ +} +#define dcl7(T) \ +dcl6(T) \ +T CJ##T##7(void) \ +{ \ + return ((*j##T##7)(1,2,3,4,5,6,7)); \ +} +#define dcl8(T) \ +dcl7(T) \ +T CJ##T##8(void) \ +{ \ + return ((*j##T##8)(1,2,3,4,5,6,7,8)); \ +} +#define dcl9(T) \ +dcl8(T) \ +T CJ##T##9(void) \ +{ \ + return ((*j##T##9)(1,2,3,4,5,6,7,8,9)); \ +} +#define dcl10(T) \ +dcl9(T) \ +T CJ##T##10(void) \ +{ \ + return ((*j##T##10)(1,2,3,4,5,6,7,8,9,10)); \ +} +#define dcl11(T) \ +dcl10(T) \ +T CJ##T##11(void) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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) \ +{ \ + 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 + +int +main(int argc, char *argv[]) +{ + jit_state_t *_jit; + jit_node_t *jmpi_main; + void (*function)(void); + jit_node_t *a1,*a2,*a3,*a4,*a5,*a6,*a7,*a8,*a9; + jit_node_t *a10,*a11,*a12,*a13,*a14,*a15; + jit_node_t *jmp; + + init_jit(argv[0]); + _jit = jit_new_state(); + + jmpi_main = jit_jmpi(); + + +#define arg0(T) /**/ +#define arg1(T) a1 = jit_arg##T(); +#define arg2(T) arg1(T) a2 = jit_arg##T(); +#define arg3(T) arg2(T) a3 = jit_arg##T(); +#define arg4(T) arg3(T) a4 = jit_arg##T(); +#define arg5(T) arg4(T) a5 = jit_arg##T(); +#define arg6(T) arg5(T) a6 = jit_arg##T(); +#define arg7(T) arg6(T) a7 = jit_arg##T(); +#define arg8(T) arg7(T) a8 = jit_arg##T(); +#define arg9(T) arg8(T) a9 = jit_arg##T(); +#define arg10(T) arg9(T) a10 = jit_arg##T(); +#define arg11(T) arg10(T) a11 = jit_arg##T(); +#define arg12(T) arg11(T) a12 = jit_arg##T(); +#define arg13(T) arg12(T) a13 = jit_arg##T(); +#define arg14(T) arg13(T) a14 = jit_arg##T(); +#define arg15(T) arg14(T) a15 = jit_arg##T(); + +#define get0(B,T,R) jit_movi##B(R##0,0); +#define get1(B,T,R) jit_getarg##B(R##0,a##1); +#define get2(B,T,R) \ + get1(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##2); \ + jit_subr##B(R##0, R##1, R##0); +#define get3(B,T,R) \ + get2(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##3); \ + jit_subr##B(R##0, R##1, R##0); +#define get4(B,T,R) \ + get3(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##4); \ + jit_subr##B(R##0, R##1, R##0); +#define get5(B,T,R) \ + get4(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##5); \ + jit_subr##B(R##0, R##1, R##0); +#define get6(B,T,R) \ + get5(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##6); \ + jit_subr##B(R##0, R##1, R##0); +#define get7(B,T,R) \ + get6(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##7); \ + jit_subr##B(R##0, R##1, R##0); +#define get8(B,T,R) \ + get7(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##8); \ + jit_subr##B(R##0, R##1, R##0); +#define get9(B,T,R) \ + get8(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##9); \ + jit_subr##B(R##0, R##1, R##0); +#define get10(B,T,R) \ + get9(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##10); \ + jit_subr##B(R##0, R##1, R##0); +#define get11(B,T,R) \ + get10(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##11); \ + jit_subr##B(R##0, R##1, R##0); +#define get12(B,T,R) \ + get11(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##12); \ + jit_subr##B(R##0, R##1, R##0); +#define get13(B,T,R) \ + get12(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##13); \ + jit_subr##B(R##0, R##1, R##0); +#define get14(B,T,R) \ + get13(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##14); \ + jit_subr##B(R##0, R##1, R##0); +#define get15(B,T,R) \ + get14(B,T,R); \ + jit_movr##B(R##1, R##0); \ + jit_getarg##T(R##0, a##15); \ + jit_subr##B(R##0, R##1, R##0); + +#if __WORDSIZE == 32 +# define jit_extr_i(u, v) /**/ +#else +# define jit_extr_l(u, v) /**/ +#endif + +#define strfy(n) #n +#define defi(T, N) \ + n##T##N = jit_name(strfy(n##T##N)); \ + jit_note("ccall.c", __LINE__); \ + jit_prolog(); \ + arg##N(); \ + get##N(,T,JIT_R) \ + jit_extr##T(JIT_R0, JIT_R0); \ + jit_retr(JIT_R0); \ + jit_epilog(); +#define deff(T, N) \ + n##T##N = jit_name(strfy(n##T##N)); \ + jit_note("ccall.c", __LINE__); \ + jit_prolog(); \ + arg##N(T); \ + get##N(T,T,JIT_F); \ + jit_retr##T(JIT_F0); \ + jit_epilog(); + +#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(jmpi_main); + jit_name("main"); + jit_note("ccall.c", __LINE__); + jit_prolog(); + +#define push0(T) /**/ +#define push1(T) jit_pushargi##T(1); +#define push2(T) push1(T) jit_pushargi##T(2); +#define push3(T) push2(T) jit_pushargi##T(3); +#define push4(T) push3(T) jit_pushargi##T(4); +#define push5(T) push4(T) jit_pushargi##T(5); +#define push6(T) push5(T) jit_pushargi##T(6); +#define push7(T) push6(T) jit_pushargi##T(7); +#define push8(T) push7(T) jit_pushargi##T(8); +#define push9(T) push8(T) jit_pushargi##T(9); +#define push10(T) push9(T) jit_pushargi##T(10); +#define push11(T) push10(T) jit_pushargi##T(11); +#define push12(T) push11(T) jit_pushargi##T(12); +#define push13(T) push12(T) jit_pushargi##T(13); +#define push14(T) push13(T) jit_pushargi##T(14); +#define push15(T) push14(T) jit_pushargi##T(15); + +#define calin(T,N) \ + jit_prepare(); \ + push##N() \ + jit_finishi(C##T##N); \ + jit_retval##T(JIT_R0); \ + jmp = jit_beqi(JIT_R0, T##N); \ + jit_calli(abort); \ + jit_patch(jmp); +#define calfn(T,N) \ + jit_prepare(); \ + push##N(T) \ + jit_finishi(C##T##N); \ + jit_retval##T(JIT_F0); \ + jmp = jit_beqi##T(JIT_F0, _w##N); \ + jit_calli(abort); \ + jit_patch(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) \ + jit_prepare(); \ + push##N() \ + jit_finishi(CJ##T##N); \ + jit_retval##T(JIT_R0); \ + jmp = jit_beqi(JIT_R0, T##N); \ + jit_calli(abort); \ + jit_patch(jmp); +#define calfn(T,N) \ + jit_prepare(); \ + push##N(T) \ + jit_finishi(CJ##T##N); \ + jit_retval##T(JIT_F0); \ + jmp = jit_beqi##T(JIT_F0, _w##N); \ + jit_calli(abort); \ + jit_patch(jmp); + cali(_c) + cali(_uc) + cali(_s) + cali(_us) + cali(_i) +#if __WORDSIZE == 64 + cali(_ui) + cali(_l) +#endif + calf(_f) + calf(_d) + + jit_ret(); + + function = jit_emit(); + +#define initn(T,N) j##T##N = jit_address(n##T##N); +#define init0(T) initn(T,0) +#define init1(T) init0(T) initn(T,1) +#define init2(T) init1(T) initn(T,2) +#define init3(T) init2(T) initn(T,3) +#define init4(T) init3(T) initn(T,4) +#define init5(T) init4(T) initn(T,5) +#define init6(T) init5(T) initn(T,6) +#define init7(T) init6(T) initn(T,7) +#define init8(T) init7(T) initn(T,8) +#define init9(T) init8(T) initn(T,9) +#define init10(T) init9(T) initn(T,10) +#define init11(T) init10(T) initn(T,11) +#define init12(T) init11(T) initn(T,12) +#define init13(T) init12(T) initn(T,13) +#define init14(T) init13(T) initn(T,14) +#define init15(T) init14(T) initn(T,15) +#define init(T) init15(T) + init(_c) + init(_uc) + init(_s) + init(_us) + init(_i) +#if __WORDSIZE == 64 + init(_ui) + init(_l) +#endif + init(_f) + init(_d) + +#if 0 + jit_print(); + jit_disassemble(); +#endif + + jit_clear_state(); + (*function)(); + jit_destroy_state(); + + finish_jit(); + + printf("ok\n"); + + return (0); +} diff --git a/deps/lightning/check/check.arm.sh b/deps/lightning/check/check.arm.sh new file mode 100755 index 0000000..2f576be --- /dev/null +++ b/deps/lightning/check/check.arm.sh @@ -0,0 +1,15 @@ +#!/bin/sh +test=`basename $0 | sed -e 's|\.arm$||'` +./lightning -mthumb=0 $srcdir/$test.tst | tr -d \\r > $test.out +if test $? != 0; then + exit $? +fi + +cmp -s $srcdir/$test.ok $test.out +result=$? +if test $result != 0; then + diff $srcdir/$test.ok $test.out + rm $test.out + exit 1 +fi +rm $test.out diff --git a/deps/lightning/check/check.arm.swf.sh b/deps/lightning/check/check.arm.swf.sh new file mode 100755 index 0000000..378b6d7 --- /dev/null +++ b/deps/lightning/check/check.arm.swf.sh @@ -0,0 +1,15 @@ +#!/bin/sh +test=`basename $0 | sed -e 's|\.arm\.swf$||'` +./lightning -mthumb=0 -mvfp=0 $srcdir/$test.tst | tr -d \\r > $test.out +if test $? != 0; then + exit $? +fi + +cmp -s $srcdir/$test.ok $test.out +result=$? +if test $result != 0; then + diff $srcdir/$test.ok $test.out + rm $test.out + exit 1 +fi +rm $test.out diff --git a/deps/lightning/check/check.arm4.swf.sh b/deps/lightning/check/check.arm4.swf.sh new file mode 100755 index 0000000..21926b6 --- /dev/null +++ b/deps/lightning/check/check.arm4.swf.sh @@ -0,0 +1,15 @@ +#!/bin/sh +test=`basename $0 | sed -e 's|\.arm4\.swf$||'` +./lightning -mcpu=4 -mthumb=0 -mvfp=0 $srcdir/$test.tst | tr -d \\r > $test.out +if test $? != 0; then + exit $? +fi + +cmp -s $srcdir/$test.ok $test.out +result=$? +if test $result != 0; then + diff $srcdir/$test.ok $test.out + rm $test.out + exit 1 +fi +rm $test.out diff --git a/deps/lightning/check/check.nodata.sh b/deps/lightning/check/check.nodata.sh new file mode 100755 index 0000000..0fbc4e9 --- /dev/null +++ b/deps/lightning/check/check.nodata.sh @@ -0,0 +1,15 @@ +#!/bin/sh +test=`basename $0 | sed -e 's|\.nodata$||'` +./lightning -d $srcdir/$test.tst | tr -d \\r > $test.out +if test $? != 0; then + exit $? +fi + +cmp -s $srcdir/$test.ok $test.out +result=$? +if test $result != 0; then + diff $srcdir/$test.ok $test.out + rm $test.out + exit 1 +fi +rm $test.out diff --git a/deps/lightning/check/check.sh b/deps/lightning/check/check.sh new file mode 100755 index 0000000..e0267a2 --- /dev/null +++ b/deps/lightning/check/check.sh @@ -0,0 +1,15 @@ +#!/bin/sh +test=`basename $0` +./lightning $srcdir/$test.tst | tr -d \\r > $test.out +if test $? != 0; then + exit $? +fi + +cmp -s $srcdir/$test.ok $test.out +result=$? +if test $result != 0; then + diff $srcdir/$test.ok $test.out + rm $test.out + exit 1 +fi +rm $test.out diff --git a/deps/lightning/check/check.swf.sh b/deps/lightning/check/check.swf.sh new file mode 100755 index 0000000..9494eef --- /dev/null +++ b/deps/lightning/check/check.swf.sh @@ -0,0 +1,15 @@ +#!/bin/sh +test=`basename $0 | sed -e 's|\.swf$||'` +./lightning -mvfp=0 $srcdir/$test.tst | tr -d \\r > $test.out +if test $? != 0; then + exit $? +fi + +cmp -s $srcdir/$test.ok $test.out +result=$? +if test $result != 0; then + diff $srcdir/$test.ok $test.out + rm $test.out + exit 1 +fi +rm $test.out diff --git a/deps/lightning/check/check.x87.nodata.sh b/deps/lightning/check/check.x87.nodata.sh new file mode 100755 index 0000000..1582e9f --- /dev/null +++ b/deps/lightning/check/check.x87.nodata.sh @@ -0,0 +1,15 @@ +#!/bin/sh +test=`basename $0 | sed -e 's|\.x87.nodata$||'` +./lightning -data=0 -mx87=1 $srcdir/$test.tst | tr -d \\r > $test.out +if test $? != 0; then + exit $? +fi + +cmp -s $srcdir/$test.ok $test.out +result=$? +if test $result != 0; then + diff $srcdir/$test.ok $test.out + rm $test.out + exit 1 +fi +rm $test.out diff --git a/deps/lightning/check/check.x87.sh b/deps/lightning/check/check.x87.sh new file mode 100755 index 0000000..c0245e1 --- /dev/null +++ b/deps/lightning/check/check.x87.sh @@ -0,0 +1,15 @@ +#!/bin/sh +test=`basename $0 | sed -e 's|\.x87$||'` +./lightning -mx87=1 $srcdir/$test.tst | tr -d \\r > $test.out +if test $? != 0; then + exit $? +fi + +cmp -s $srcdir/$test.ok $test.out +result=$? +if test $result != 0; then + diff $srcdir/$test.ok $test.out + rm $test.out + exit 1 +fi +rm $test.out diff --git a/deps/lightning/check/clobber.ok b/deps/lightning/check/clobber.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/clobber.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/clobber.tst b/deps/lightning/check/clobber.tst new file mode 100644 index 0000000..7530842 --- /dev/null +++ b/deps/lightning/check/clobber.tst @@ -0,0 +1,1050 @@ +/* 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 r0 +#define IR1 r1 +#define IR2 r2 +#define IR3 v0 +#define IR4 v1 +#define IR5 v2 +#define FR0 f0 +#define FR1 f1 +#define FR2 f2 +#define FR3 f3 +#define FR4 f4 +#define FR5 f5 + +#define setup() \ + movi %r0 IV0 \ + movi %r1 IV1 \ + movi %r2 IV2 \ + movi %v0 IV3 \ + movi %v1 IV4 \ + movi %v2 IV5 +#define setup_f() \ + movi_f %f0 FV0 \ + movi_f %f1 FV1 \ + movi_f %f2 FV2 \ + movi_f %f3 FV3 \ + movi_f %f4 FV4 \ + movi_f %f5 FV5 +#define setup_d() \ + movi_d %f0 FV0 \ + movi_d %f1 FV1 \ + movi_d %f2 FV2 \ + movi_d %f3 FV3 \ + movi_d %f4 FV4 \ + movi_d %f5 FV5 + +#define check(label, rn) \ + beqi label %IR##rn IV##rn \ + calli @abort \ +label: +#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) + +#define checkf(f, label, rn) \ + beqi##f label %FR##rn FV##rn \ + calli @abort \ +label: +#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() \ + movi %IR##i0 1 \ + op##i %IR##i1 %IR##i0 1 \ + check4(i, l, i2, i3, i4, i5) +#define aluic(l, op, i0, i1, i2, i3, i4, i5) \ + setup() \ + movi %IR##i0 1 \ + op##i %IR##i0 %IR##i0 1 \ + check5(ic, l, i1, i2, i3, i4, i5) +#define alur(l, op, i0, i1, i2, i3, i4, i5) \ + setup() \ + movi %IR##i0 1 \ + movi %IR##i1 1 \ + op##r %IR##i2 %IR##i0 %IR##i1 \ + check3(r, l, i3, i4, i5) +#define alurc0(l, op, i0, i1, i2, i3, i4, i5) \ + setup() \ + movi %IR##i0 1 \ + movi %IR##i1 1 \ + op##r %IR##i0 %IR##i0 %IR##i1 \ + check4(r0, l, i2, i3, i4, i5) +#define alurc1(l, op, i0, i1, i2, i3, i4, i5) \ + setup() \ + movi %IR##i0 1 \ + movi %IR##i1 1 \ + op##r %IR##i1 %IR##i0 %IR##i1 \ + check4(r1, l, i2, i3, i4, i5) +#define alurc2(l, op, i0, i1, i2, i3, i4, i5) \ + setup() \ + movi %IR##i0 1 \ + op##r %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() \ + movi##f %FR##f0 1.0 \ + op##i##f %FR##f1 %FR##f0 1.0 \ + checkf4(f, i, l, f2, f3, f4, f5) +#define fopic(f, l, op, f0, f1, f2, f3, f4, f5) \ + setup##f() \ + movi##f %FR##f0 1.0 \ + op##i##f %FR##f0 %FR##f0 1.0 \ + checkf5(f, ic, l, f1, f2, f3, f4, f5) +#define fopr(f, l, op, f0, f1, f2, f3, f4, f5) \ + setup##f() \ + movi##f %FR##f0 1.0 \ + movi##f %FR##f1 1.0 \ + op##r##f %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() \ + movi##f %FR##f0 1.0 \ + movi##f %FR##f1 1.0 \ + op##r##f %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() \ + movi##f %FR##f0 1.0 \ + movi##f %FR##f1 1.0 \ + op##r##f %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() \ + movi##f %FR##f0 1.0 \ + op##r##f %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() \ + movi %IR##i0 1 \ + op##ci %IR##i1 %IR##i0 1 \ + op##xi %IR##i2 %IR##i0 1 \ + check3(ii, l, i3, i4, i5) +#define aluxir(l, op, i0, i1, i2, i3, i4, i5) \ + setup() \ + movi %IR##i0 1 \ + op##ci %IR##i1 %IR##i0 1 \ + op##xr %IR##i2 %IR##i0 %IR##i1 \ + check3(ir, l, i3, i4, i5) +#define aluxri(l, op, i0, i1, i2, i3, i4, i5) \ + setup() \ + movi %IR##i0 1 \ + movi %IR##i1 1 \ + op##cr %IR##i2 %IR##i0 %IR##i1 \ + op##xi %IR##i0 %IR##i1 1 \ + check3(ri, l, i3, i4, i5) +#define aluxrr(l, op, i0, i1, i2, i3, i4, i5) \ + setup() \ + movi %IR##i0 1 \ + movi %IR##i1 1 \ + op##cr %IR##i2 %IR##i0 %IR##i1 \ + op##xr %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() \ + movi %IR##i0 1 \ + op##i_u %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() \ + movi %IR##i0 1 \ + op##i_u %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() \ + movi %IR##i0 1 \ + movi %IR##i1 1 \ + op##r_u %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() \ + movi %IR##i0 1 \ + movi %IR##i1 1 \ + op##r_u %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() \ + movi %IR##i0 1 \ + movi %IR##i1 1 \ + op##r_u %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() \ + movi %IR##i0 1 \ + op##r_u %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() \ + movi %IR##i0 1 \ + op %IR##i1 %IR##i0 \ + check4(rr, l, i2, i3, i4, i5) +#define unirc(l, op, i0, i1, i2, i3, i4, i5) \ + setup() \ + movi %IR##i0 1 \ + op %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() \ + movi##f %FR##f0 1 \ + op##f %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() \ + movi##f %FR##f0 1 \ + op##f %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() \ + movi##f %FR##f0 1.0 \ + op##i##f %IR##r0 %FR##f0 1.0 \ + 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() \ + movi##f %FR##f0 1.0 \ + movi##f %FR##f1 1.0 \ + op##r##f %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() \ + movi##f %FR##f0 1.0 \ + op##r##f %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() \ + movi %IR##i0 1 \ + check5(i, l, i1, i2, i3, i4, i5) +#define imvr(l, i0, i1, i2, i3, i4, i5) \ + setup() \ + movi %IR##i1 1 \ + movr %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() \ + movi##f %FR##f0 1 \ + checkf5(f, i, l, f1, f2, f3, f4, f5) +#define fmvr(f, l, f0, f1, f2, f3, f4, f5) \ + setup##f() \ + movi##f %FR##f1 1 \ + movr##f %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() \ + movi##f %FR##f0 1 \ + op %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() \ + movi##f %FR##f0 1 \ + op %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() \ + movi##f %FR##f0 1 \ + op##f %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() \ + movi %IR##r0 1 \ + op##f %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() \ + ldi##i %IR##r0 buff \ + check5(ldi##i, l, r1, r2, r3, r4, r5) +#define ildr(i, l, r0, r1, r2, r3, r4, r5) \ + setup() \ + movi %IR##r1 buff \ + ldr##i %IR##r0 %IR##r1 \ + check4(ldr##i, l, r2, r3, r4, r5) +#define ildr0(i, l, r0, r1, r2, r3, r4, r5) \ + setup() \ + movi %IR##r0 buff \ + ldr##i %IR##r0 %IR##r0 \ + check5(ldr##i, l, r1, r2, r3, r4, r5) +#define ildxi(i, l, r0, r1, r2, r3, r4, r5) \ + setup() \ + movi %IR##r1 buff \ + ldxi##i %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() \ + movi %IR##r1 buff \ + movi %IR##r2 off##i \ + ldxr##i %IR##r0 %IR##r1 %IR##r2 \ + check3(ldxr##i, l, r3, r4, r5) +#define ildxr0(i, l, r0, r1, r2, r3, r4, r5) \ + setup() \ + movi %IR##r1 buff \ + movi %IR##r0 off##i \ + ldxr##i %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() \ + movi %IR##r0 buff \ + movi %IR##r1 off##i \ + ldxr##i %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() \ + ldi##f %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() \ + movi %IR##r0 buff \ + ldr##f %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() \ + movi %IR##r0 buff \ + ldxi##f %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() \ + movi %IR##r0 buff \ + movi %IR##r1 off##f \ + ldxr##f %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() \ + sti##i buff %IR##r0 \ + check5(sti##i, l, r1, r2, r3, r4, r5) +#define istr(i, l, r0, r1, r2, r3, r4, r5) \ + setup() \ + movi %IR##r1 buff \ + str##i %IR##r1 %IR##r0 \ + check4(str##i, l, r2, r3, r4, r5) +#define istr0(i, l, r0, r1, r2, r3, r4, r5) \ + setup() \ + movi %IR##r1 buff \ + str##i %IR##r1 %IR##r0 \ + check4(str0##i, l, r2, r3, r4, r5) +#define istxi(i, l, r0, r1, r2, r3, r4, r5) \ + setup() \ + movi %IR##r1 buff \ + stxi##i 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() \ + movi %IR##r1 buff \ + movi %IR##r2 off##i \ + stxr##i %IR##r2 %IR##r1 %IR##r0 \ + check3(stxr##i, l, r3, r4, r5) +#define istxr0(i, l, r0, r1, r2, r3, r4, r5) \ + setup() \ + movi %IR##r1 buff \ + movi %IR##r0 off##i \ + stxr##i %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() \ + movi %IR##r0 buff \ + movi %IR##r1 off##i \ + stxr##i %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() \ + sti##f 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() \ + movi %IR##r0 buff \ + str##f %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() \ + movi %IR##r0 buff \ + stxi##f 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() \ + movi %IR##r0 buff \ + movi %IR##r1 off##f \ + stxr##f %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) + +/* Need a valid jump or simple optimization will remove it */ +#define bri(l, op, u, il, ir, r0, r1, r2, r3, r4, r5) \ + setup() \ + movi %IR##r0 il \ + b##op##i##u i##l##op##r0 %IR##r0 ir \ + calli @abort \ +i##l##op##r0: \ + check5(i, l, r1, r2, r3, r4, r5) +#define brr(l, op, u, il, ir, r0, r1, r2, r3, r4, r5) \ + setup() \ + movi %IR##r0 il \ + movi %IR##r1 ir \ + b##op##r##u r##l##op##r0 %IR##r0 %IR##r1 \ + calli @abort \ +r##l##op##r0: \ + 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() \ + movi##f %FR##f0 il \ + b##op##i##f i##l##op##f##f0 %FR##f0 ir \ + calli @abort \ +i##l##op##f##f0: \ + checkf5(f, i, l, f1, f2, f3, f4, f5) +#define bff(f, l, op, il, ir, f0, f1, f2, f3, f4, f5) \ + setup##f() \ + movi##f %FR##f0 il \ + movi##f %FR##f1 ir \ + b##op##r##f r##l##op##f##f0 %FR##f0 %FR##f1 \ + calli @abort \ +r##l##op##f##f0: \ + 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 + +.data 32 +buff: +.size 16 +ok: +.c "ok\n" + +.code + prolog + + 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) + alu(__LINE__, lt) + alu_u(__LINE__, lt) + fcmp(__LINE__, lt) + alu(__LINE__, le) + alu_u(__LINE__, le) + fcmp(__LINE__, le) + alu(__LINE__, eq) + fcmp(__LINE__, eq) + alu(__LINE__, ge) + alu_u(__LINE__, ge) + fcmp(__LINE__, ge) + alu(__LINE__, gt) + alu_u(__LINE__, gt) + fcmp(__LINE__, gt) + alu(__LINE__, ne) + fcmp(__LINE__, ne) + fcmp(__LINE__, unlt) + fcmp(__LINE__, unle) + fcmp(__LINE__, uneq) + fcmp(__LINE__, unge) + fcmp(__LINE__, ungt) + fcmp(__LINE__, ltgt) + fcmp(__LINE__, ord) + fcmp(__LINE__, unord) + 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__, htonr) + 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)) + + prepare + pushargi ok + ellipsis + finishi @printf + + ret + epilog diff --git a/deps/lightning/check/ctramp.c b/deps/lightning/check/ctramp.c new file mode 100644 index 0000000..941c7c1 --- /dev/null +++ b/deps/lightning/check/ctramp.c @@ -0,0 +1,123 @@ +#include <lightning.h> +#include <stdio.h> + +jit_state_t *_jit; +long top; +long stk[1024]; + +int +main(int argc, char *argv[]) +{ + void *address; + void (*call)(void*); + jit_state_t *frame_jit, *tramp_jit; + jit_node_t *arg, *done, *xfibs, *out, *ret1, *ret2; + + init_jit(argv[0]); + _jit = frame_jit = jit_new_state(); + jit_name("main"); + jit_prolog(); + jit_frame(64); + + arg = jit_arg(); + jit_getarg(JIT_R1, arg); + + /* Initialize language stack */ + jit_movi(JIT_R0, (jit_word_t)stk); + jit_sti(&top, JIT_R0); + + /* return address */ + done = jit_movi(JIT_R0, 0); + /* argument */ + jit_movi(JIT_V0, 32); + /* jump to code */ + jit_jmpr(JIT_R1); + jit_patch(done); + + jit_prepare(); + jit_pushargi((jit_word_t)"xfibs(%d) = %d\n"); + jit_ellipsis(); + jit_pushargi(32); + jit_pushargr(JIT_V0); + jit_finishi(printf); + jit_ret(); + jit_epilog(); + call = jit_emit(); + jit_clear_state(); + +#define SIZE sizeof(jit_word_t) + _jit = tramp_jit = jit_new_state(); + jit_name("xfibs"); + xfibs = jit_label(); + jit_prolog(); + jit_tramp(64); + out = jit_blti(JIT_V0, 2); + jit_subi(JIT_V1, JIT_V0, 1); /* V1 = N-1 */ + jit_subi(JIT_V2, JIT_V0, 2); /* V1 = N-2 */ + + /* save return address */ + jit_ldi(JIT_R1, &top); + jit_stxi(SIZE * 0, JIT_R1, JIT_R0); + /* save operands */ + jit_stxi(SIZE * 1, JIT_R1, JIT_V0); + jit_stxi(SIZE * 2, JIT_R1, JIT_V1); + jit_stxi(SIZE * 3, JIT_R1, JIT_V2); + /* adjust "language" stack */ + jit_addi(JIT_R1, JIT_R1, SIZE * 4); + jit_sti(&top, JIT_R1); + + /* return address */ + ret1 = jit_movi(JIT_R0, 0); + /* argument */ + jit_movr(JIT_V0, JIT_V1); + /* indirect goto */ + jit_patch_at(jit_jmpi(), xfibs); + jit_patch(ret1); + jit_movr(JIT_V1, JIT_V0); /* V1 = rfibs(N-1) */ + /* save V1 */ + jit_ldi(JIT_R1, &top); + jit_stxi(-SIZE * 2, JIT_R1, JIT_V1); + + /* reload V2 */ + jit_ldxi(JIT_V2, JIT_R1, -SIZE * 1); + + /* return address */ + ret2 = jit_movi(JIT_R0, 0); + /* argument */ + jit_movr(JIT_V0, JIT_V2); + /* indirect goto */ + jit_patch_at(jit_jmpi(), xfibs); + jit_patch(ret2); + jit_movr(JIT_V2, JIT_V0); /* V2 = rfibs(N-2) */ + + /* reload return address */ + jit_ldi(JIT_R1, &top); + jit_subi(JIT_R1, JIT_R1, SIZE * 4); + jit_ldxi(JIT_R0, JIT_R1, SIZE * 0); + /* reload operands */ + jit_ldxi(JIT_V0, JIT_R1, SIZE * 1); + jit_ldxi(JIT_V1, JIT_R1, SIZE * 2); + /* V2 already loaded */ + /* update "language" stack */ + jit_sti(&top, JIT_R1); + + jit_addi(JIT_V1, JIT_V1, 1); + jit_addr(JIT_V0, JIT_V1, JIT_V2); + jit_jmpr(JIT_R0); + + jit_patch(out); + jit_movi(JIT_V0, 1); + jit_jmpr(JIT_R0); + jit_epilog(); + + address = jit_emit(); + jit_clear_state(); + + (*call)(address); + + jit_destroy_state(); + + _jit = frame_jit; + jit_destroy_state(); + return 0; +} diff --git a/deps/lightning/check/cva_list.c b/deps/lightning/check/cva_list.c new file mode 100644 index 0000000..b0e668c --- /dev/null +++ b/deps/lightning/check/cva_list.c @@ -0,0 +1,1187 @@ +#include <lightning.h> +#include <stdarg.h> +#include <stdio.h> + +#define W jit_word_t +#define D jit_float64_t +#define VASTART(A) \ + va_list ap; \ + va_start(ap, A) +#define VARG2() a2 = va_arg(ap, jit_word_t); VARG3() +#define VARG3() a3 = va_arg(ap, jit_word_t); VARG4() +#define VARG4() a4 = va_arg(ap, jit_word_t); VARG5() +#define VARG5() a5 = va_arg(ap, jit_word_t); VARG6() +#define VARG6() a6 = va_arg(ap, jit_word_t); VARG7() +#define VARG7() a7 = va_arg(ap, jit_word_t); VARG8() +#define VARG8() a8 = va_arg(ap, jit_word_t); VARG9() +#define VARG9() a9 = va_arg(ap, jit_word_t); VARG10() +#define VARG10() a10 = va_arg(ap, jit_word_t); va_end(ap) + +#define VARGD2() a2 = va_arg(ap, jit_float64_t); VARGD3() +#define VARGD3() a3 = va_arg(ap, jit_float64_t); VARGD4() +#define VARGD4() a4 = va_arg(ap, jit_float64_t); VARGD5() +#define VARGD5() a5 = va_arg(ap, jit_float64_t); VARGD6() +#define VARGD6() a6 = va_arg(ap, jit_float64_t); VARGD7() +#define VARGD7() a7 = va_arg(ap, jit_float64_t); VARGD8() +#define VARGD8() a8 = va_arg(ap, jit_float64_t); VARGD9() +#define VARGD9() a9 = va_arg(ap, jit_float64_t); VARGD10() +#define VARGD10() a10 = va_arg(ap, jit_float64_t);va_end(ap) + +#define IDVARG2() a2 = va_arg(ap, jit_float64_t); IDVARG3() +#define IDVARG3() a3 = va_arg(ap, jit_word_t); IDVARG4() +#define IDVARG4() a4 = va_arg(ap, jit_float64_t); IDVARG5() +#define IDVARG5() a5 = va_arg(ap, jit_word_t); IDVARG6() +#define IDVARG6() a6 = va_arg(ap, jit_float64_t); IDVARG7() +#define IDVARG7() a7 = va_arg(ap, jit_word_t); IDVARG8() +#define IDVARG8() a8 = va_arg(ap, jit_float64_t); IDVARG9() +#define IDVARG9() a9 = va_arg(ap, jit_word_t); IDVARG10() +#define IDVARG10() a10 = va_arg(ap, jit_float64_t);va_end(ap) + +#define DIVARG2() a2 = va_arg(ap, jit_word_t); DIVARG3() +#define DIVARG3() a3 = va_arg(ap, jit_float64_t); DIVARG4() +#define DIVARG4() a4 = va_arg(ap, jit_word_t); DIVARG5() +#define DIVARG5() a5 = va_arg(ap, jit_float64_t); DIVARG6() +#define DIVARG6() a6 = va_arg(ap, jit_word_t); DIVARG7() +#define DIVARG7() a7 = va_arg(ap, jit_float64_t); DIVARG8() +#define DIVARG8() a8 = va_arg(ap, jit_word_t); DIVARG9() +#define DIVARG9() a9 = va_arg(ap, jit_float64_t); DIVARG10() +#define DIVARG10() a10 = va_arg(ap, jit_word_t); va_end(ap) + +#define CHECK() \ + do { \ + if (a1 != 1 || a2 != 2 || a3 != 3 || a4 != 4 || a5 != 5 || \ + a6 != 6 || a7 != 7 || a8 != 8 || a9 != 9 || a10 != 10) \ + abort(); \ + } while (0) + + +void i_iiiiiiiii(W a1, ...) +{ + W a2, a3, a4, a5, a6, a7, a8, a9, a10; + VASTART(a1); + VARG2(); + CHECK(); +} + +void ii_iiiiiiii(W a1, W a2, ...) +{ + W a3, a4, a5, a6, a7, a8, a9, a10; + VASTART(a2); + VARG3(); + CHECK(); +} + +void iii_iiiiiii(W a1, W a2, W a3, ...) +{ + W a4, a5, a6, a7, a8, a9, a10; + VASTART(a3); + VARG4(); + CHECK(); +} + +void iiii_iiiiii(W a1, W a2, W a3, W a4, ...) +{ + W a5, a6, a7, a8, a9, a10; + VASTART(a4); + VARG5(); + CHECK(); +} + +void iiiii_iiiii(W a1, W a2, W a3, W a4, W a5, ...) +{ + W a6, a7, a8, a9, a10; + VASTART(a5); + VARG6(); + CHECK(); +} + +void iiiiii_iiii(W a1, W a2, W a3, W a4, W a5, W a6, ...) +{ + W a7, a8, a9, a10; + VASTART(a6); + VARG7(); + CHECK(); +} + +void iiiiiii_iii(W a1, W a2, W a3, W a4, W a5, W a6, W a7, ...) +{ + W a8, a9, a10; + VASTART(a7); + VARG8(); + CHECK(); +} + +void iiiiiiii_ii(W a1, W a2, W a3, W a4, W a5, W a6, W a7, W a8, ...) +{ + W a9, a10; + VASTART(a8); + VARG9(); + CHECK(); +} + +void iiiiiiiii_i(W a1, W a2, W a3, W a4, W a5, W a6, W a7, W a8, W a9, ...) +{ + W a10; + VASTART(a9); + VARG10(); + CHECK(); +} + +void d_ddddddddd(D a1, ...) +{ + D a2, a3, a4, a5, a6, a7, a8, a9, a10; + VASTART(a1); + VARGD2(); + CHECK(); +} + +void dd_dddddddd(D a1, D a2, ...) +{ + D a3, a4, a5, a6, a7, a8, a9, a10; + VASTART(a2); + VARGD3(); + CHECK(); +} + +void ddd_ddddddd(D a1, D a2, D a3, ...) +{ + D a4, a5, a6, a7, a8, a9, a10; + VASTART(a3); + VARGD4(); + CHECK(); +} + +void dddd_dddddd(D a1, D a2, D a3, D a4, ...) +{ + D a5, a6, a7, a8, a9, a10; + VASTART(a4); + VARGD5(); + CHECK(); +} + +void ddddd_ddddd(D a1, D a2, D a3, D a4, D a5, ...) +{ + D a6, a7, a8, a9, a10; + VASTART(a5); + VARGD6(); + CHECK(); +} + +void dddddd_dddd(D a1, D a2, D a3, D a4, D a5, D a6, ...) +{ + D a7, a8, a9, a10; + VASTART(a6); + VARGD7(); + CHECK(); +} + +void ddddddd_ddd(D a1, D a2, D a3, D a4, D a5, D a6, D a7, ...) +{ + D a8, a9, a10; + VASTART(a7); + VARGD8(); + CHECK(); +} + +void dddddddd_dd(D a1, D a2, D a3, D a4, D a5, D a6, D a7, D a8, ...) +{ + D a9, a10; + VASTART(a8); + VARGD9(); + CHECK(); +} + +void ddddddddd_d(D a1, D a2, D a3, D a4, D a5, D a6, D a7, D a8, D a9, ...) +{ + D a10; + VASTART(a9); + VARGD10(); + CHECK(); +} + +void i_didididid(W a1, ...) +{ + W a3, a5, a7, a9; + D a2, a4, a6, a8, a10; + VASTART(a1); + IDVARG2(); + CHECK(); +} + +void id_idididid(W a1, D a2, ...) +{ + W a3, a5, a7, a9; + D a4, a6, a8, a10; + VASTART(a2); + IDVARG3(); + CHECK(); +} + +void idi_dididid(W a1, D a2, W a3, ...) +{ + W a5, a7, a9; + D a4, a6, a8, a10; + VASTART(a3); + IDVARG4(); + CHECK(); +} + +void idid_ididid(W a1, D a2, W a3, D a4, ...) +{ + W a5, a7, a9; + D a6, a8, a10; + VASTART(a4); + IDVARG5(); + CHECK(); +} + +void ididi_didid(W a1, D a2, W a3, D a4, W a5, ...) +{ + W a7, a9; + D a6, a8, a10; + VASTART(a5); + IDVARG6(); + CHECK(); +} + +void ididid_idid(W a1, D a2, W a3, D a4, W a5, D a6, ...) +{ + W a7, a9; + D a8, a10; + VASTART(a6); + IDVARG7(); + CHECK(); +} + +void idididi_did(W a1, D a2, W a3, D a4, W a5, D a6, W a7, ...) +{ + W a9; + D a8, a10; + VASTART(a7); + IDVARG8(); + CHECK(); +} + +void idididid_id(W a1, D a2, W a3, D a4, W a5, D a6, W a7, D a8, ...) +{ + W a9; + D a10; + VASTART(a8); + IDVARG9(); + CHECK(); +} + +void ididididi_d(W a1, D a2, W a3, D a4, W a5, D a6, W a7, D a8, W a9, ...) +{ + D a10; + VASTART(a9); + IDVARG10(); + CHECK(); +} + +void d_ididididi(D a1, ...) +{ + W a2, a4, a6, a8, a10; + D a3, a5, a7, a9; + VASTART(a1); + DIVARG2(); + CHECK(); +} + +void di_didididi(D a1, W a2, ...) +{ + W a4, a6, a8, a10; + D a3, a5, a7, a9; + VASTART(a2); + DIVARG3(); + CHECK(); +} + +void did_idididi(D a1, W a2, D a3, ...) +{ + W a4, a6, a8, a10; + D a5, a7, a9; + VASTART(a3); + DIVARG4(); + CHECK(); +} + +void didi_dididi(D a1, W a2, D a3, W a4, ...) +{ + W a6, a8, a10; + D a5, a7, a9; + VASTART(a4); + DIVARG5(); + CHECK(); +} + +void didid_ididi(D a1, W a2, D a3, W a4, D a5, ...) +{ + W a6, a8, a10; + D a7, a9; + VASTART(a5); + DIVARG6(); + CHECK(); +} + +void dididi_didi(D a1, W a2, D a3, W a4, D a5, W a6, ...) +{ + W a8, a10; + D a7, a9; + VASTART(a6); + DIVARG7(); + CHECK(); +} + +void dididid_idi(D a1, W a2, D a3, W a4, D a5, W a6, D a7, ...) +{ + W a8, a10; + D a9; + VASTART(a7); + DIVARG8(); + CHECK(); +} + +void didididi_di(D a1, W a2, D a3, W a4, D a5, W a6, D a7, W a8, ...) +{ + W a10; + D a9; + VASTART(a8); + DIVARG9(); + CHECK(); +} + +void didididid_i(D a1, W a2, D a3, W a4, D a5, W a6, D a7, W a8, D a9, ...) +{ + W a10; + VASTART(a9); + DIVARG10(); + CHECK(); +} + +void va_i_iiiiiiiii(W a1, va_list ap) +{ + W a2, a3, a4, a5, a6, a7, a8, a9, a10; + VARG2(); + CHECK(); +} + +void va_ii_iiiiiiii(W a1, W a2, va_list ap) +{ + W a3, a4, a5, a6, a7, a8, a9, a10; + VARG3(); + CHECK(); +} + +void va_iii_iiiiiii(W a1, W a2, W a3, va_list ap) +{ + W a4, a5, a6, a7, a8, a9, a10; + VARG4(); + CHECK(); +} + +void va_iiii_iiiiii(W a1, W a2, W a3, W a4, va_list ap) +{ + W a5, a6, a7, a8, a9, a10; + VARG5(); + CHECK(); +} + + +void va_d_ddddddddd(D a1, va_list ap) +{ + D a2, a3, a4, a5, a6, a7, a8, a9, a10; + VARGD2(); + CHECK(); +} + +void va_dd_dddddddd(D a1, D a2, va_list ap) +{ + D a3, a4, a5, a6, a7, a8, a9, a10; + VARGD3(); + CHECK(); +} + +void va_ddd_ddddddd(D a1, D a2, D a3, va_list ap) +{ + D a4, a5, a6, a7, a8, a9, a10; + VARGD4(); + CHECK(); +} + +void va_dddd_dddddd(D a1, D a2, D a3, D a4, va_list ap) +{ + D a5, a6, a7, a8, a9, a10; + VARGD5(); + CHECK(); +} + +void va_i_didididid(W a1, va_list ap) +{ + W a3, a5, a7, a9; + D a2, a4, a6, a8, a10; + IDVARG2(); + CHECK(); +} + +void va_id_idididid(W a1, D a2, va_list ap) +{ + W a3, a5, a7, a9; + D a4, a6, a8, a10; + IDVARG3(); + CHECK(); +} + +void va_idi_dididid(W a1, D a2, W a3, va_list ap) +{ + W a5, a7, a9; + D a4, a6, a8, a10; + IDVARG4(); + CHECK(); +} + +void va_idid_ididid(W a1, D a2, W a3, D a4, va_list ap) +{ + W a5, a7, a9; + D a6, a8, a10; + IDVARG5(); + CHECK(); +} + +void va_d_ididididi(D a1, va_list ap) +{ + W a2, a4, a6, a8, a10; + D a3, a5, a7, a9; + DIVARG2(); + CHECK(); +} + +void va_di_didididi(D a1, W a2, va_list ap) +{ + W a4, a6, a8, a10; + D a3, a5, a7, a9; + DIVARG3(); + CHECK(); +} + +void va_did_idididi(D a1, W a2, D a3, va_list ap) +{ + W a4, a6, a8, a10; + D a5, a7, a9; + DIVARG4(); + CHECK(); +} + +void va_didi_dididi(D a1, W a2, D a3, W a4, va_list ap) +{ + W a6, a8, a10; + D a5, a7, a9; + DIVARG5(); + CHECK(); +} + +#define PUSH1() jit_pushargi(1) +#define PUSH2() PUSH1(); jit_pushargi(2) +#define PUSH3() PUSH2(); jit_pushargi(3) +#define PUSH4() PUSH3(); jit_pushargi(4) +#define PUSH5() PUSH4(); jit_pushargi(5) +#define PUSH6() PUSH5(); jit_pushargi(6) +#define PUSH7() PUSH6(); jit_pushargi(7) +#define PUSH8() PUSH7(); jit_pushargi(8) +#define PUSH9() PUSH8(); jit_pushargi(9) +#define VPUSH2() jit_pushargi(2); VPUSH3() +#define VPUSH3() jit_pushargi(3); VPUSH4() +#define VPUSH4() jit_pushargi(4); VPUSH5() +#define VPUSH5() jit_pushargi(5); VPUSH6() +#define VPUSH6() jit_pushargi(6); VPUSH7() +#define VPUSH7() jit_pushargi(7); VPUSH8() +#define VPUSH8() jit_pushargi(8); VPUSH9() +#define VPUSH9() jit_pushargi(9); VPUSH10() +#define VPUSH10() jit_pushargi(10); +#define PUSHD1() jit_pushargi_d(1) +#define PUSHD2() PUSHD1(); jit_pushargi_d(2) +#define PUSHD3() PUSHD2(); jit_pushargi_d(3) +#define PUSHD4() PUSHD3(); jit_pushargi_d(4) +#define PUSHD5() PUSHD4(); jit_pushargi_d(5) +#define PUSHD6() PUSHD5(); jit_pushargi_d(6) +#define PUSHD7() PUSHD6(); jit_pushargi_d(7) +#define PUSHD8() PUSHD7(); jit_pushargi_d(8) +#define PUSHD9() PUSHD8(); jit_pushargi_d(9) +#define VPUSHD2() jit_pushargi_d(2); VPUSHD3() +#define VPUSHD3() jit_pushargi_d(3); VPUSHD4() +#define VPUSHD4() jit_pushargi_d(4); VPUSHD5() +#define VPUSHD5() jit_pushargi_d(5); VPUSHD6() +#define VPUSHD6() jit_pushargi_d(6); VPUSHD7() +#define VPUSHD7() jit_pushargi_d(7); VPUSHD8() +#define VPUSHD8() jit_pushargi_d(8); VPUSHD9() +#define VPUSHD9() jit_pushargi_d(9); VPUSHD10() +#define VPUSHD10() jit_pushargi_d(10); +#define IDPUSH1() jit_pushargi(1) +#define IDPUSH2() IDPUSH1(); jit_pushargi_d(2) +#define IDPUSH3() IDPUSH2(); jit_pushargi(3) +#define IDPUSH4() IDPUSH3(); jit_pushargi_d(4) +#define IDPUSH5() IDPUSH4(); jit_pushargi(5) +#define IDPUSH6() IDPUSH5(); jit_pushargi_d(6) +#define IDPUSH7() IDPUSH6(); jit_pushargi(7) +#define IDPUSH8() IDPUSH7(); jit_pushargi_d(8) +#define IDPUSH9() IDPUSH8(); jit_pushargi(9) +#define IDVPUSH2() jit_pushargi_d(2); IDVPUSH3() +#define IDVPUSH3() jit_pushargi(3); IDVPUSH4() +#define IDVPUSH4() jit_pushargi_d(4); IDVPUSH5() +#define IDVPUSH5() jit_pushargi(5); IDVPUSH6() +#define IDVPUSH6() jit_pushargi_d(6); IDVPUSH7() +#define IDVPUSH7() jit_pushargi(7); IDVPUSH8() +#define IDVPUSH8() jit_pushargi_d(8); IDVPUSH9() +#define IDVPUSH9() jit_pushargi(9); IDVPUSH10() +#define IDVPUSH10() jit_pushargi_d(10); +#define DIPUSH1() jit_pushargi_d(1) +#define DIPUSH2() DIPUSH1(); jit_pushargi(2) +#define DIPUSH3() DIPUSH2(); jit_pushargi_d(3) +#define DIPUSH4() DIPUSH3(); jit_pushargi(4) +#define DIPUSH5() DIPUSH4(); jit_pushargi_d(5) +#define DIPUSH6() DIPUSH5(); jit_pushargi(6) +#define DIPUSH7() DIPUSH6(); jit_pushargi_d(7) +#define DIPUSH8() DIPUSH7(); jit_pushargi(8) +#define DIPUSH9() DIPUSH8(); jit_pushargi_d(9) +#define DIVPUSH2() jit_pushargi(2); DIVPUSH3() +#define DIVPUSH3() jit_pushargi_d(3); DIVPUSH4() +#define DIVPUSH4() jit_pushargi(4); DIVPUSH5() +#define DIVPUSH5() jit_pushargi_d(5); DIVPUSH6() +#define DIVPUSH6() jit_pushargi(6); DIVPUSH7() +#define DIVPUSH7() jit_pushargi_d(7); DIVPUSH8() +#define DIVPUSH8() jit_pushargi(8); DIVPUSH9() +#define DIVPUSH9() jit_pushargi_d(9); DIVPUSH10() +#define DIVPUSH10() jit_pushargi(10); + +jit_state_t *_jit; + +int main(int argc, char *argv[]) +{ + void (*function)(void); + jit_node_t *jmpi_main; + jit_node_t *a1, *a2, *node; + jit_node_t *jva_i_iiiiiiiii, *jva_ii_iiiiiiii; + jit_node_t *jva_d_ddddddddd, *jva_dd_dddddddd; + jit_node_t *jva_i_didididid, *jva_id_idididid; + jit_node_t *jva_d_ididididi, *jva_di_didididi; + jit_node_t *jva_iii_iiiiiii, *jva_iiii_iiiiii; + jit_node_t *jva_ddd_ddddddd, *jva_dddd_dddddd; + jit_node_t *jva_idi_dididid, *jva_idid_ididid; + jit_node_t *jva_did_idididi, *jva_didi_dididi; + + init_jit(argv[0]); + _jit = jit_new_state(); + + jmpi_main = jit_jmpi(); + + /* Define simple functions to validate a jit_va_list_t + * is a valid va_list; these do not fetch arguments from + * the va_list. */ + jva_i_iiiiiiiii = jit_label(); + jit_name("va_i_iiiiiiiii"); + jit_prolog(); + a1 = jit_arg(); + jit_getarg(JIT_V1, a1); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_prepare(); + jit_pushargr(JIT_V1); + jit_va_push(JIT_V0); + jit_finishi(va_i_iiiiiiiii); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_ii_iiiiiiii = jit_label(); + jit_name("va_ii_iiiiiiii"); + jit_prolog(); + a1 = jit_arg(); + a2 = jit_arg(); + jit_getarg(JIT_V1, a1); + jit_getarg(JIT_V2, a2); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_prepare(); + jit_pushargr(JIT_V1); + jit_pushargr(JIT_V2); + jit_va_push(JIT_V0); + jit_finishi(va_ii_iiiiiiii); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_d_ddddddddd = jit_label(); + jit_name("va_d_ddddddddd"); + jit_prolog(); + a1 = jit_arg_d(); + jit_getarg_d(JIT_F3, a1); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_prepare(); + jit_pushargr_d(JIT_F3); + jit_va_push(JIT_V0); + jit_finishi(va_d_ddddddddd); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_dd_dddddddd = jit_label(); + jit_name("va_dd_dddddddd"); + jit_prolog(); + a1 = jit_arg_d(); + a2 = jit_arg_d(); + jit_getarg_d(JIT_F3, a1); + jit_getarg_d(JIT_F4, a2); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_prepare(); + jit_pushargr_d(JIT_F3); + jit_pushargr_d(JIT_F4); + jit_va_push(JIT_V0); + jit_finishi(va_dd_dddddddd); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_i_didididid = jit_label(); + jit_name("va_i_didididid"); + jit_prolog(); + a1 = jit_arg(); + jit_getarg(JIT_V1, a1); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_prepare(); + jit_pushargr(JIT_V1); + jit_va_push(JIT_V0); + jit_finishi(va_i_didididid); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_id_idididid = jit_label(); + jit_name("va_id_idididid"); + jit_prolog(); + a1 = jit_arg(); + a2 = jit_arg_d(); + jit_getarg(JIT_V1, a1); + jit_getarg_d(JIT_F3, a2); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_prepare(); + jit_pushargr(JIT_V1); + jit_pushargr_d(JIT_F3); + jit_va_push(JIT_V0); + jit_finishi(va_id_idididid); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_d_ididididi = jit_label(); + jit_name("va_d_ididididi"); + jit_prolog(); + a1 = jit_arg_d(); + jit_getarg_d(JIT_F3, a1); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_prepare(); + jit_pushargr_d(JIT_F3); + jit_va_push(JIT_V0); + jit_finishi(va_d_ididididi); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_di_didididi = jit_label(); + jit_name("va_di_didididi"); + jit_prolog(); + a1 = jit_arg_d(); + a2 = jit_arg(); + jit_getarg_d(JIT_F3, a1); + jit_getarg(JIT_V1, a2); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_prepare(); + jit_pushargr_d(JIT_F3); + jit_pushargr(JIT_V1); + jit_va_push(JIT_V0); + jit_finishi(va_di_didididi); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + + /* Define complex functions to validate a jit_va_list_t + * is a valid va_list; these do fetch arguments from + * the va_list, to ensure it does the correct operations + * fetching arguments, and pass a valid va_list to the + * C function. */ + jva_iii_iiiiiii = jit_label(); + jit_name("va_iii_iiiiiii"); + jit_prolog(); + a1 = jit_arg(); + jit_getarg(JIT_V1, a1); + node = jit_beqi(JIT_V1, 1); + jit_calli(abort); + jit_patch(node); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_va_arg(JIT_V1, JIT_V0); + jit_va_arg(JIT_V2, JIT_V0); + jit_prepare(); + jit_pushargi(1); + jit_pushargr(JIT_V1); + jit_pushargr(JIT_V2); + jit_va_push(JIT_V0); + jit_finishi(va_iii_iiiiiii); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_iiii_iiiiii = jit_label(); + jit_name("va_iiii_iiiiii"); + jit_prolog(); + a1 = jit_arg(); + a2 = jit_arg(); + jit_getarg(JIT_V1, a1); + node = jit_beqi(JIT_V1, 1); + jit_calli(abort); + jit_patch(node); + jit_getarg(JIT_V1, a2); + node = jit_beqi(JIT_V1, 2); + jit_calli(abort); + jit_patch(node); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_va_arg(JIT_V1, JIT_V0); + jit_va_arg(JIT_V2, JIT_V0); + jit_prepare(); + jit_pushargi(1); + jit_pushargi(2); + jit_pushargr(JIT_V1); + jit_pushargr(JIT_V2); + jit_va_push(JIT_V0); + jit_finishi(va_iiii_iiiiii); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_ddd_ddddddd = jit_label(); + jit_name("va_ddd_ddddddd"); + jit_prolog(); + a1 = jit_arg_d(); + jit_getarg_d(JIT_F3, a1); + node = jit_beqi_d(JIT_F3, 1); + jit_calli(abort); + jit_patch(node); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_va_arg_d(JIT_F3, JIT_V0); + jit_va_arg_d(JIT_F4, JIT_V0); + jit_prepare(); + jit_pushargi_d(1); + jit_pushargr_d(JIT_F3); + jit_pushargr_d(JIT_F4); + jit_va_push(JIT_V0); + jit_finishi(va_ddd_ddddddd); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_dddd_dddddd = jit_label(); + jit_name("va_dddd_dddddd"); + jit_prolog(); + a1 = jit_arg_d(); + a2 = jit_arg_d(); + jit_getarg_d(JIT_F3, a1); + node = jit_beqi_d(JIT_F3, 1); + jit_calli(abort); + jit_patch(node); + jit_getarg_d(JIT_F3, a2); + node = jit_beqi_d(JIT_F3, 2); + jit_calli(abort); + jit_patch(node); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_va_arg_d(JIT_F3, JIT_V0); + jit_va_arg_d(JIT_F4, JIT_V0); + jit_prepare(); + jit_pushargi_d(1); + jit_pushargi_d(2); + jit_pushargr_d(JIT_F3); + jit_pushargr_d(JIT_F4); + jit_va_push(JIT_V0); + jit_finishi(va_dddd_dddddd); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_idi_dididid = jit_label(); + jit_name("va_idi_dididid"); + jit_prolog(); + a1 = jit_arg(); + jit_getarg(JIT_V1, a1); + node = jit_beqi(JIT_V1, 1); + jit_calli(abort); + jit_patch(node); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_va_arg_d(JIT_F3, JIT_V0); + jit_va_arg(JIT_V1, JIT_V0); + jit_prepare(); + jit_pushargi(1); + jit_pushargr_d(JIT_F3); + jit_pushargr(JIT_V1); + jit_va_push(JIT_V0); + jit_finishi(va_idi_dididid); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_idid_ididid = jit_label(); + jit_name("va_idid_ididid"); + jit_prolog(); + a1 = jit_arg(); + a2 = jit_arg_d(); + jit_getarg(JIT_V1, a1); + node = jit_beqi(JIT_V1, 1); + jit_calli(abort); + jit_patch(node); + jit_getarg_d(JIT_F3, a2); + node = jit_beqi_d(JIT_F3, 2); + jit_calli(abort); + jit_patch(node); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_va_arg(JIT_V1, JIT_V0); + jit_va_arg_d(JIT_F3, JIT_V0); + jit_prepare(); + jit_pushargi(1); + jit_pushargi_d(2); + jit_pushargr(JIT_V1); + jit_pushargr_d(JIT_F3); + jit_va_push(JIT_V0); + jit_finishi(va_idid_ididid); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_did_idididi = jit_label(); + jit_name("va_did_idididi"); + jit_prolog(); + a1 = jit_arg_d(); + jit_getarg_d(JIT_F3, a1); + node = jit_beqi_d(JIT_F3, 1); + jit_calli(abort); + jit_patch(node); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_va_arg(JIT_V1, JIT_V0); + jit_va_arg_d(JIT_F3, JIT_V0); + jit_prepare(); + jit_pushargi_d(1); + jit_pushargr(JIT_V1); + jit_pushargr_d(JIT_F3); + jit_va_push(JIT_V0); + jit_finishi(va_did_idididi); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + jva_didi_dididi = jit_label(); + jit_name("va_didi_dididi"); + jit_prolog(); + a1 = jit_arg_d(); + a2 = jit_arg(); + jit_getarg_d(JIT_F3, a1); + node = jit_beqi_d(JIT_F3, 1); + jit_calli(abort); + jit_patch(node); + jit_getarg(JIT_V1, a2); + node = jit_beqi(JIT_V1, 2); + jit_calli(abort); + jit_patch(node); + jit_ellipsis(); + jit_va_start(JIT_V0); + jit_va_arg_d(JIT_F3, JIT_V0); + jit_va_arg(JIT_V1, JIT_V0); + jit_prepare(); + jit_pushargi_d(1); + jit_pushargi(2); + jit_pushargr_d(JIT_F3); + jit_pushargr(JIT_V1); + jit_va_push(JIT_V0); + jit_finishi(va_didi_dididi); + jit_va_end(JIT_V0); + jit_ret(); + jit_epilog(); + + jit_patch(jmpi_main); + jit_name("main"); + jit_prolog(); + + /* Check that lightning properly calls vararg functions */ + jit_prepare(); + PUSH1(); + jit_ellipsis(); + VPUSH2(); + jit_finishi(i_iiiiiiiii); + jit_prepare(); + PUSH2(); + jit_ellipsis(); + VPUSH3(); + jit_finishi(ii_iiiiiiii); + jit_prepare(); + PUSH3(); + jit_ellipsis(); + VPUSH4(); + jit_finishi(iii_iiiiiii); + jit_prepare(); + PUSH4(); + jit_ellipsis(); + VPUSH5(); + jit_finishi(iiii_iiiiii); + jit_prepare(); + PUSH5(); + jit_ellipsis(); + VPUSH6(); + jit_finishi(iiiii_iiiii); + jit_prepare(); + PUSH6(); + jit_ellipsis(); + VPUSH7(); + jit_finishi(iiiiii_iiii); + jit_prepare(); + PUSH7(); + jit_ellipsis(); + VPUSH8(); + jit_finishi(iiiiiii_iii); + jit_prepare(); + PUSH8(); + jit_ellipsis(); + VPUSH9(); + jit_finishi(iiiiiiii_ii); + jit_prepare(); + PUSH9(); + jit_ellipsis(); + VPUSH10(); + jit_finishi(iiiiiiiii_i); + jit_prepare(); + PUSHD1(); + jit_ellipsis(); + VPUSHD2(); + jit_finishi(d_ddddddddd); + jit_prepare(); + PUSHD2(); + jit_ellipsis(); + VPUSHD3(); + jit_finishi(dd_dddddddd); + jit_prepare(); + PUSHD3(); + jit_ellipsis(); + VPUSHD4(); + jit_finishi(ddd_ddddddd); + jit_prepare(); + PUSHD4(); + jit_ellipsis(); + VPUSHD5(); + jit_finishi(dddd_dddddd); + jit_prepare(); + PUSHD5(); + jit_ellipsis(); + VPUSHD6(); + jit_finishi(ddddd_ddddd); + jit_prepare(); + PUSHD6(); + jit_ellipsis(); + VPUSHD7(); + jit_finishi(dddddd_dddd); + jit_prepare(); + PUSHD7(); + jit_ellipsis(); + VPUSHD8(); + jit_finishi(ddddddd_ddd); + jit_prepare(); + PUSHD8(); + jit_ellipsis(); + VPUSHD9(); + jit_finishi(dddddddd_dd); + jit_prepare(); + PUSHD9(); + jit_ellipsis(); + VPUSHD10(); + jit_finishi(ddddddddd_d); + jit_prepare(); + IDPUSH1(); + jit_ellipsis(); + IDVPUSH2(); + jit_finishi(i_didididid); + jit_prepare(); + IDPUSH2(); + jit_ellipsis(); + IDVPUSH3(); + jit_finishi(id_idididid); + jit_prepare(); + IDPUSH3(); + jit_ellipsis(); + IDVPUSH4(); + jit_finishi(idi_dididid); + jit_prepare(); + IDPUSH4(); + jit_ellipsis(); + IDVPUSH5(); + jit_finishi(idid_ididid); + jit_prepare(); + IDPUSH5(); + jit_ellipsis(); + IDVPUSH6(); + jit_finishi(ididi_didid); + jit_prepare(); + IDPUSH6(); + jit_ellipsis(); + IDVPUSH7(); + jit_finishi(ididid_idid); + jit_prepare(); + IDPUSH7(); + jit_ellipsis(); + IDVPUSH8(); + jit_finishi(idididi_did); + jit_prepare(); + IDPUSH8(); + jit_ellipsis(); + IDVPUSH9(); + jit_finishi(idididid_id); + jit_prepare(); + IDPUSH9(); + jit_ellipsis(); + IDVPUSH10(); + jit_finishi(ididididi_d); + jit_prepare(); + DIPUSH1(); + jit_ellipsis(); + DIVPUSH2(); + jit_finishi(d_ididididi); + jit_prepare(); + DIPUSH2(); + jit_ellipsis(); + DIVPUSH3(); + jit_finishi(di_didididi); + jit_prepare(); + DIPUSH3(); + jit_ellipsis(); + DIVPUSH4(); + jit_finishi(did_idididi); + jit_prepare(); + DIPUSH4(); + jit_ellipsis(); + DIVPUSH5(); + jit_finishi(didi_dididi); + jit_prepare(); + DIPUSH5(); + jit_ellipsis(); + DIVPUSH6(); + jit_finishi(didid_ididi); + jit_prepare(); + DIPUSH6(); + jit_ellipsis(); + DIVPUSH7(); + jit_finishi(dididi_didi); + jit_prepare(); + DIPUSH7(); + jit_ellipsis(); + DIVPUSH8(); + jit_finishi(dididid_idi); + jit_prepare(); + DIPUSH8(); + jit_ellipsis(); + DIVPUSH9(); + jit_finishi(didididi_di); + jit_prepare(); + DIPUSH9(); + jit_ellipsis(); + DIVPUSH10(); + jit_finishi(didididid_i); + + /* Check that unmodified jit_va_list_t is a valid va_list */ + jit_prepare(); + PUSH1(); + jit_ellipsis(); + VPUSH2(); + jit_patch_at(jit_finishi(NULL), jva_i_iiiiiiiii); + jit_prepare(); + PUSH2(); + jit_ellipsis(); + VPUSH3(); + jit_patch_at(jit_finishi(NULL), jva_ii_iiiiiiii); + jit_prepare(); + PUSHD1(); + jit_ellipsis(); + VPUSHD2(); + jit_patch_at(jit_finishi(NULL), jva_d_ddddddddd); + jit_prepare(); + PUSHD2(); + jit_ellipsis(); + VPUSHD3(); + jit_patch_at(jit_finishi(NULL), jva_dd_dddddddd); + jit_prepare(); + IDPUSH1(); + jit_ellipsis(); + IDVPUSH2(); + jit_patch_at(jit_finishi(NULL), jva_i_didididid); + jit_prepare(); + IDPUSH2(); + jit_ellipsis(); + IDVPUSH3(); + jit_patch_at(jit_finishi(NULL), jva_id_idididid); + jit_prepare(); + DIPUSH1(); + jit_ellipsis(); + DIVPUSH2(); + jit_patch_at(jit_finishi(NULL), jva_d_ididididi); + jit_prepare(); + DIPUSH2(); + jit_ellipsis(); + DIVPUSH3(); + jit_patch_at(jit_finishi(NULL), jva_di_didididi); + + /* Check that modified jit_va_list_t is a valid va_list */ + jit_prepare(); + PUSH1(); + jit_ellipsis(); + VPUSH2(); + jit_patch_at(jit_finishi(NULL), jva_iii_iiiiiii); + jit_prepare(); + PUSH2(); + jit_ellipsis(); + VPUSH3(); + jit_patch_at(jit_finishi(NULL), jva_iiii_iiiiii); + jit_prepare(); + PUSHD1(); + jit_ellipsis(); + VPUSHD2(); + jit_patch_at(jit_finishi(NULL), jva_ddd_ddddddd); + jit_prepare(); + PUSHD2(); + jit_ellipsis(); + VPUSHD3(); + jit_patch_at(jit_finishi(NULL), jva_dddd_dddddd); + jit_prepare(); + IDPUSH1(); + jit_ellipsis(); + IDVPUSH2(); + jit_patch_at(jit_finishi(NULL), jva_idi_dididid); + jit_prepare(); + IDPUSH2(); + jit_ellipsis(); + IDVPUSH3(); + jit_patch_at(jit_finishi(NULL), jva_idid_ididid); + jit_prepare(); + DIPUSH1(); + jit_ellipsis(); + DIVPUSH2(); + jit_patch_at(jit_finishi(NULL), jva_did_idididi); + jit_prepare(); + DIPUSH2(); + jit_ellipsis(); + DIVPUSH3(); + jit_patch_at(jit_finishi(NULL), jva_didi_dididi); + + jit_ret(); + jit_epilog(); + + + function = jit_emit(); + jit_clear_state(); + //jit_disassemble(); + (*function)(); + jit_destroy_state(); + + finish_jit(); + + printf("ok\n"); + return 0; +} diff --git a/deps/lightning/check/cvt.ok b/deps/lightning/check/cvt.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/cvt.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/cvt.tst b/deps/lightning/check/cvt.tst new file mode 100644 index 0000000..1828259 --- /dev/null +++ b/deps/lightning/check/cvt.tst @@ -0,0 +1,380 @@ +.data 12 +ok: +.c "ok\n" + +#if __WORDSIZE == 32 +# define w7f 0x7fffffff +# define w80 0x80000000 +# define w81 0x80000001 +# define wff 0xffffffff +# define LEXTII2(N, R0, R1) +# define LEXTIC2(N, R0) +#else +# define w7f 0x7fffffffffffffff +# define w80 0x8000000000000000 +# define w81 0x8000000000000001 +# define wff 0xffffffffffffffff +# define i7f wff +# define ui7f 0xffffffff +# define i80 0 +# define ui80 0 +# define i81 1 +# define ui81 1 +# define iff wff +# define uiff 0xffffffff +# define LEXTII2(N, R0, R1) \ + EXTII2(N, i, R0, R1) \ + EXTII2(N, ui, R0, R1) +# define LEXTIC2(N, R0) \ + EXTIC2(N, i, R0) \ + EXTIC2(N, ui, R0) +#endif +#define c7f wff +#define uc7f 0xff +#define s7f wff +#define us7f 0xffff +#define c80 0 +#define uc80 0 +#define s80 0 +#define us80 0 +#define c81 1 +#define uc81 1 +#define s81 1 +#define us81 1 +#define cff wff +#define ucff 0xff +#define sff wff +#define usff 0xffff + +#define EXTII2(N, T, R0, R1) \ + movi %R0 w##N \ + extr_##T %R1 %R0 \ + beqi T##_##R0##_##R1##_##N %R1 T##N \ + calli @abort \ +T##_##R0##_##R1##_##N: +#define EXTII1(N, R0, R1) \ + EXTII2(N, c, R0, R1) \ + EXTII2(N, uc, R0, R1) \ + EXTII2(N, s, R0, R1) \ + EXTII2(N, us, R0, R1) \ + LEXTII2(N, R0, R1) +#define EXTII0(R0, R1) \ + EXTII1(7f, R0, R1) \ + EXTII1(80, R0, R1) \ + EXTII1(81, R0, R1) \ + EXTII1(ff, R0, R1) + +#define EXTIC2(N, T, R0) \ + movi %R0 w##N \ + extr_##T %R0 %R0 \ + beqi T##_##R0##_##N %R0 T##N \ + calli @abort \ +T##_##R0##_##N: +#define EXTIC1(N, R0) \ + EXTIC2(N, c, R0) \ + EXTIC2(N, uc, R0) \ + EXTIC2(N, s, R0) \ + EXTIC2(N, us, R0) \ + LEXTIC2(N, R0) +#define EXTIC0(R0) \ + EXTIC1(7f, R0) \ + EXTIC1(80, R0) \ + EXTIC1(81, R0) \ + EXTIC1(ff, R0) + +#define EXTII(V0, V1, V2, R0, R1, R2) \ + EXTII0(V0, V1) \ + EXTII0(V0, V2) \ + EXTII0(V0, R0) \ + EXTII0(V0, R1) \ + EXTII0(V0, R2) \ + EXTII0(V1, V0) \ + EXTII0(V1, V2) \ + EXTII0(V1, R0) \ + EXTII0(V1, R1) \ + EXTII0(V1, R2) \ + EXTII0(V2, V0) \ + EXTII0(V2, V1) \ + EXTII0(V2, R0) \ + EXTII0(V2, R1) \ + EXTII0(V2, R2) \ + EXTII0(R0, V0) \ + EXTII0(R0, V1) \ + EXTII0(R0, V2) \ + EXTII0(R0, R1) \ + EXTII0(R0, R2) \ + EXTII0(R1, V0) \ + EXTII0(R1, V1) \ + EXTII0(R1, V2) \ + EXTII0(R1, R0) \ + EXTII0(R1, R2) \ + EXTII0(R2, V0) \ + EXTII0(R2, V1) \ + EXTII0(R2, V2) \ + EXTII0(R2, R0) \ + EXTII0(R2, R1) \ + EXTIC0(V0) \ + EXTIC0(V1) \ + EXTIC0(V2) \ + EXTIC0(R0) \ + EXTIC0(R1) \ + EXTIC0(R2) + +#define EXIF1(N, V, R0, R1) \ + movi %R0 V \ + extr_f %R1 %R0 \ + beqi_f wf##_##R0##_##R1##_##N %R1 V \ +wf##_##R0##_##R1##_##N: +#define EXIF0(R0, R1) \ + EXIF1(0, -1, R0, R1) \ + EXIF1(1, 64, R0, R1) +#define EXIF(V0, V1, V2, R0, R1, R2, F0, F1, F2, F3, F4, F5) \ + EXIF0(V0, F0) \ + EXIF0(V1, F1) \ + EXIF0(V2, F2) \ + EXIF0(R0, F3) \ + EXIF0(R1, F4) \ + EXIF0(R2, F5) +#define EXID1(N, V, R0, R1) \ + movi %R0 V \ + extr_d %R1 %R0 \ + beqi_d wd##_##R0##_##R1##_##N %R1 V \ +wd##_##R0##_##R1##_##N: +#define EXID0(R0, R1) \ + EXID1(0, -1, R0, R1) \ + EXID1(1, 64, R0, R1) +#define EXID(V0, V1, V2, R0, R1, R2, F0, F1, F2, F3, F4, F5) \ + EXID0(V0, F0) \ + EXID0(V1, F1) \ + EXID0(V2, F2) \ + EXID0(R0, F3) \ + EXID0(R1, F4) \ + EXID0(R2, F5) + +#define EXFI1(N, V, R0, R1) \ + movi_f %R1 V \ + truncr_f %R0 %R1 \ + beqi fi##_##R0##_##R1##_##N %R0 V \ + calli @abort \ +fi##_##R0##_##R1##_##N: +#define EXFI0(R0, R1) \ + EXFI1(0, 42, R0, R1) \ + EXFI1(1, -128, R0, R1) +#define EXFI(V0, V1, V2, R0, R1, R2, F0, F1, F2, F3, F4, F5) \ + EXFI0(V0, F5) \ + EXFI0(V1, F4) \ + EXFI0(V2, F3) \ + EXFI0(R0, F2) \ + EXFI0(R1, F1) \ + EXFI0(R2, F0) +#define EXDI1(N, V, R0, R1) \ + movi_d %R1 V \ + truncr_d %R0 %R1 \ + beqi di##_##R0##_##R1##_##N %R0 V \ + calli @abort \ +di##_##R0##_##R1##_##N: +#define EXDI0(R0, R1) \ + EXDI1(0, 42, R0, R1) \ + EXDI1(1, -128, R0, R1) +#define EXDI(V0, V1, V2, R0, R1, R2, F0, F1, F2, F3, F4, F5) \ + EXDI0(V0, F5) \ + EXDI0(V1, F4) \ + EXDI0(V2, F3) \ + EXDI0(R0, F2) \ + EXDI0(R1, F1) \ + EXDI0(R2, F0) + +#define LEXFI1(N, V, R0, R1) \ + movi_f %R1 V \ + truncr_f_i %R0 %R1 \ + andi %R0 %R0 0xffffffff \ + beqi lfi##_##R0##_##R1##_##N %R0 $(V & 0xffffffff) \ + calli @abort \ +lfi##_##R0##_##R1##_##N: +#define LEXFI0(R0, R1) \ + LEXFI1(0, 42, R0, R1) \ + LEXFI1(1, -128, R0, R1) +#define LEXFI(V0, V1, V2, R0, R1, R2, F0, F1, F2, F3, F4, F5) \ + LEXFI0(V0, F5) \ + LEXFI0(V1, F4) \ + LEXFI0(V2, F3) \ + LEXFI0(R0, F2) \ + LEXFI0(R1, F1) \ + LEXFI0(R2, F0) +#define LEXDI1(N, V, R0, R1) \ + movi_d %R1 V \ + truncr_d_i %R0 %R1 \ + andi %R0 %R0 0xffffffff \ + beqi ldi##_##R0##_##R1##_##N %R0 $(V & 0xffffffff) \ + calli @abort \ +ldi##_##R0##_##R1##_##N: +#define LEXDI0(R0, R1) \ + LEXDI1(0, 42, R0, R1) \ + LEXDI1(1, -128, R0, R1) +#define LEXDI(V0, V1, V2, R0, R1, R2, F0, F1, F2, F3, F4, F5) \ + LEXDI0(V0, F5) \ + LEXDI0(V1, F4) \ + LEXDI0(V2, F3) \ + LEXDI0(R0, F2) \ + LEXDI0(R1, F1) \ + LEXDI0(R2, F0) + +#define EXTFD2(V, R0, R1) \ + movi_f %R0 V \ + extr_f_d %R1 %R0 \ + beqi_d fd##_##R0##_##R1 %R1 V \ + calli @abort \ +fd##_##R0##_##R1: +#define EXTFD1(R0, R1) \ + EXTFD2(1.25, R0, R1) +#define EXTFDC2(V, R0) \ + movi_f %R0 V \ + extr_f_d %R0 %R0 \ + beqi_d fdc##_##R0 %R0 V \ + calli @abort \ +fdc##_##R0: +#define EXTFDC1(R0) \ + EXTFDC2(-0.75, R0) +#define EXTFD(R0, R1, R2, R3, R4, R5) \ + EXTFD1(R0, R1) \ + EXTFD1(R0, R2) \ + EXTFD1(R0, R3) \ + EXTFD1(R0, R4) \ + EXTFD1(R0, R5) \ + EXTFDC1(R0) \ + EXTFDC1(R1) \ + EXTFDC1(R2) \ + EXTFDC1(R3) \ + EXTFDC1(R4) \ + EXTFDC1(R5) + +#define EXTDF2(V, R0, R1) \ + movi_d %R0 V \ + extr_d_f %R1 %R0 \ + beqi_f df##_##R0##_##R1 %R1 V \ + calli @abort \ +df##_##R0##_##R1: +#define EXTDF1(R0, R1) \ + EXTDF2(1.25, R0, R1) +#define EXTDFC2(V, R0) \ + movi_d %R0 V \ + extr_d_f %R0 %R0 \ + beqi_f dfc##_##R0 %R0 V \ + calli @abort \ +dfc##_##R0: +#define EXTDFC1(R0) \ + EXTDFC2(-0.75, R0) +#define EXTDF(R0, R1, R2, R3, R4, R5) \ + EXTDF1(R0, R1) \ + EXTDF1(R0, R2) \ + EXTDF1(R0, R3) \ + EXTDF1(R0, R4) \ + EXTDF1(R0, R5) \ + EXTDFC1(R0) \ + EXTDFC1(R1) \ + EXTDFC1(R2) \ + EXTDFC1(R3) \ + EXTDFC1(R4) \ + EXTDFC1(R5) + +.code + prolog + + /* simple sequence for easier disassembly reading and encoding check */ + movi %r0 w7f + extr_c %r1 %r0 + beqi xc %r1 c7f + calli @abort +xc: + movi %r0 w7f + extr_uc %r1 %r0 + beqi xuc %r1 uc7f + calli @abort +xuc: + movi %r0 w7f + extr_s %r1 %r0 + beqi xs %r1 s7f + calli @abort +xs: + movi %r0 w7f + extr_us %r1 %r0 + beqi xus %r1 us7f + calli @abort +xus: +#if __WORDSIZE == 64 + movi %r0 w7f + extr_i %r1 %r0 + beqi xi %r1 i7f + calli @abort +xi: + movi %r0 w7f + extr_ui %r1 %r0 + beqi xui %r1 ui7f + calli @abort +xui: +#endif + movi %r0 -2 + extr_f %f0 %r0 + beqi_f xif %f0 -2 + calli @abort +xif: + movi %r0 32 + extr_d %f0 %r0 + beqi_d xid %f0 32 + calli @abort +xid: + movi_f %f0 -128 + truncr_f %r0 %f0 + beqi xfi %r0 -128 + calli @abort +xfi: + movi_d %f0 -128 + truncr_d %r0 %f0 + beqi xdi %r0 -128 + calli @abort +xdi: +#if __WORDSIZE == 64 + movi_f %f0 -128 + truncr_f_i %r0 %f0 + andi %r0 %r0 0xffffffff + beqi yfi %r0 $(-128 & 0xffffffff) + calli @abort +yfi: + movi_d %f0 -128 + truncr_d_i %r0 %f0 + andi %r0 %r0 0xffffffff + beqi ydi %r0 $(-128 & 0xffffffff) + calli @abort +ydi: +#endif + movi_f %f0 0.5 + extr_f_d %f1 %f0 + beqi_d xfd %f1 0.5 + calli @abort +xfd: + movi_d %f0 0.5 + extr_d_f %f1 %f0 + beqi_f xdf %f1 0.5 + calli @abort +xdf: + + EXTII(v0, v1, v2, r0, r1, r2) + EXIF(v0, v1, v2, r0, r1, r2, f0, f1, f2, f3, f4, f5) + EXID(v0, v1, v2, r0, r1, r2, f0, f1, f2, f3, f4, f5) + EXFI(v0, v1, v2, r0, r1, r2, f0, f1, f2, f3, f4, f5) +#if __WORDSIZE == 64 + LEXFI(v0, v1, v2, r0, r1, r2, f0, f1, f2, f3, f4, f5) + LEXDI(v0, v1, v2, r0, r1, r2, f0, f1, f2, f3, f4, f5) +#endif + EXDI(v0, v1, v2, r0, r1, r2, f0, f1, f2, f3, f4, f5) + EXTFD(f0, f1, f2, f3, f4, f5) + EXTDF(f0, f1, f2, f3, f4, f5) + + // just to know did not abort + prepare + pushargi ok + ellipsis + finishi @printf + + ret + epilog diff --git a/deps/lightning/check/divi.ok b/deps/lightning/check/divi.ok new file mode 100644 index 0000000..c23cbd2 --- /dev/null +++ b/deps/lightning/check/divi.ok @@ -0,0 +1,6 @@ +40/8 = 5 (expected 5) +64/8 = 8 (expected 8) +80/8 = 10 (expected 10) +98304/32768 = 3 (expected 3) +65536/32768 = 2 (expected 2) +163840/32768 = 5 (expected 5) diff --git a/deps/lightning/check/divi.tst b/deps/lightning/check/divi.tst new file mode 100644 index 0000000..9c03ed8 --- /dev/null +++ b/deps/lightning/check/divi.tst @@ -0,0 +1,85 @@ +.data 128 +small_ops: +.i 40 64 80 +large_ops: +.i 98304 65536 163840 +fmt: +.c "%i/%i = %i (expected %i)\n" +x: +.c "%d\n" +.code + jmpi main + +#define generate_divider(operand) \ + name divider_##operand \ +divider_##operand: \ + prolog \ + arg $i \ + getarg %r1 $i \ + divi %r2 %r1 operand \ + retr %r2 \ + epilog +generate_divider(8) +generate_divider(32768) + +#define generate_test_divider(divisor) \ + name test_divider_##divisor \ +test_divider_##divisor: \ + prolog \ + allocai 4 $loc \ + arg $p \ + arg $c \ + getarg %v0 $p \ + getarg %v1 $c \ + muli %v1 %v1 4 \ + addr %v1 %v0 %v1 \ +loop_##divisor: \ + bger done_##divisor %v0 %v1 \ + ldr_i %v2 %v0 \ + prepare \ + pushargr %v2 \ + finishi divider_##divisor \ + retval %v2 \ + ldr_i %r2 %v0 \ + divi %r0 %r2 divisor \ + /* save div result */ \ + stxi_i $loc %fp %r0 \ + prepare \ + pushargi fmt \ + ellipsis \ + pushargr %r2 \ + pushargi divisor \ + pushargr %v2 \ + pushargr %r0 \ + finishi @printf \ + addi %v0 %v0 4 \ + /* reload div result */ \ + ldxi_i %r0 %fp $loc \ + beqr loop_##divisor %r0 %v2 \ + /* return if failed */ \ + reti 1 \ +done_##divisor: \ + reti 0 \ + epilog +generate_test_divider(8) +generate_test_divider(32768) + + name main +main: + prolog + prepare + pushargi small_ops + pushargi 3 + finishi test_divider_8 + retval %r0 + bnei fail %r0 0 + prepare + pushargi large_ops + pushargi 3 + finishi test_divider_32768 + retval %r0 + bnei fail %r0 0 + reti 0 +fail: + reti 1 + epilog diff --git a/deps/lightning/check/fib.ok b/deps/lightning/check/fib.ok new file mode 100644 index 0000000..7e13ef0 --- /dev/null +++ b/deps/lightning/check/fib.ok @@ -0,0 +1 @@ +nfibs(32) = 2178309 diff --git a/deps/lightning/check/fib.tst b/deps/lightning/check/fib.tst new file mode 100644 index 0000000..0835323 --- /dev/null +++ b/deps/lightning/check/fib.tst @@ -0,0 +1,62 @@ +.data 32 +format: +.c "nfibs(%d) = %d\n" + +.code + jmpi main + + name nfibs +nfibs: + prolog + arg $in + getarg %r0 $in // R0 = n + beqi ref %r0 0 + movr %r1 %r0 + movi %r0 1 + blei_u ref %r1 2 + subi %r2 %r1 2 + movr %r1 %r0 +loop: + subi %r2 %r2 1 // decr. counter + movr %v0 %r0 // V0 = R0 + addr %r0 %r0 %r1 // R0 = R0 + R1 + movr %r1 %v0 // R1 = V0 + bnei loop %r2 0 // if (R2) goto loop +ref: + retr %r0 // RET = R0 + epilog + + name main +main: + prolog + arg $argc + arg $argv + + getarg_i %r0 $argc + blei default %r0 1 + getarg %r0 $argv + addi %r0 %r0 $(__WORDSIZE >> 3) + ldr %r0 %r0 + prepare + pushargr %r0 + finishi @atoi + retval %r0 + jmpi call + +default: + movi %r0 32 + +call: + movr %v0 %r0 + prepare + pushargr %r0 + finishi nfibs + retval %r0 + prepare + pushargi format + ellipsis + pushargr %v0 + pushargr %r0 + finishi @printf + ret + epilog diff --git a/deps/lightning/check/float.ok b/deps/lightning/check/float.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/float.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/float.tst b/deps/lightning/check/float.tst new file mode 100644 index 0000000..ff5606a --- /dev/null +++ b/deps/lightning/check/float.tst @@ -0,0 +1,367 @@ + +.data 4 +ok: +.c "ok" + +. $($NaN = 0.0 / 0.0) +. $($pInf = 1.0 / 0.0) +. $($nInf = -1.0 / 0.0) +#if __WORDSIZE == 32 +# define x7f 0x7fffffff +# define x80 0x80000000 +#else +# define x7f 0x7fffffffffffffff +# define x80 0x8000000000000000 +#endif + +#if __mips__ || __sparc__ || __hppa__ || __riscv +# define wnan x7f +#elif __arm__ || __aarch64__ || __alpha__ +# define wnan 0 +#else +# define wnan x80 +#endif +#if __mips__ || __arm__ || __ppc__ || __sparc__ || __hppa__ || __aarch64__ || __s390__ || __riscv +# define wpinf x7f +#elif __alpha__ +/* (at least) bug compatible with gcc 4.2.3 -ieee */ +# define wpinf 0 +#else +# define wpinf x80 +#endif +#if __alpha__ +/* (at least) bug compatible with gcc 4.2.3 -ieee */ +# define wninf 0 +#else +# define wninf x80 +#endif + +/* ensure result is correct and 0 or 1 in the result register */ +#define xtcmp(l, t, op, r0, f0, f1, li, ri) \ + movi##t %f0 li \ + movi##t %f1 ri \ + op##r##t %r0 %f0 %f1 \ + bnei T##op##r##t##r0##f0##f1##l %r0 0 \ + calli @abort \ +T##op##r##t##r0##f0##f1##l: \ + movi##t %f0 li \ + movi##t %f1 ri \ + b##op##r##t bT##op##r##t##r0##f0##f1##l %f0 %f1 \ + calli @abort \ +bT##op##r##t##r0##f0##f1##l: \ + movi##t %f1 li \ + op##i##t %r0 %f0 ri \ + bnei T##op##i##t##r0##f0##f1##l %r0 0 \ + calli @abort \ +T##op##i##t##r0##f0##f1##l: \ + movi##t %f1 li \ + b##op##i##t bT##op##i##t##r0##f0##f1##l %f0 ri \ + calli @abort \ +bT##op##i##t##r0##f0##f1##l: \ + movi##t %f0 li \ + movi##t %f1 ri \ + op##r##t %r0 %f0 %f1 \ + beqi F##op##r##t##r0##f0##f1##l %r0 1 \ + calli @abort \ +F##op##r##t##r0##f0##f1##l: \ + movi##t %f1 li \ + op##i##t %r0 %f0 ri \ + beqi F##op##i##t##r0##f0##f1##l %r0 1 \ + calli @abort \ +F##op##i##t##r0##f0##f1##l: +#define tcmp1(l, t, op, r0, li, ri) \ + xtcmp(l, t, op, r0, f0, f1, li, ri) \ + xtcmp(l, t, op, r0, f1, f2, li, ri) \ + xtcmp(l, t, op, r0, f2, f3, li, ri) \ + xtcmp(l, t, op, r0, f3, f4, li, ri) \ + xtcmp(l, t, op, r0, f4, f5, li, ri) +#define tcmp0(l, t, op, li, ri) \ + tcmp1(l, t, op, v0, li, ri) \ + tcmp1(l, t, op, v1, li, ri) \ + tcmp1(l, t, op, v2, li, ri) \ + tcmp1(l, t, op, r0, li, ri) \ + tcmp1(l, t, op, r1, li, ri) \ + tcmp1(l, t, op, r2, li, ri) +#if __ia64__ +# define tcmp(l, op, li, ri) \ + xtcmp(l, _f, op, r0, f0, f1, li, ri) \ + xtcmp(l, _d, op, r0, f0, f1, li, ri) +#else +# define tcmp(l, op, li, ri) \ + tcmp0(l, _f, op, li, ri) \ + tcmp0(l, _d, op, li, ri) +#endif + +#define xfcmp(l, t, op, r0, f0, f1, li, ri) \ + movi##t %f0 li \ + movi##t %f1 ri \ + op##r##t %r0 %f0 %f1 \ + beqi T##op##r##t##r0##f0##f1##l %r0 0 \ + calli @abort \ +T##op##r##t##r0##f0##f1##l: \ + movi##t %f1 li \ + op##i##t %r0 %f0 ri \ + beqi T##op##i##t##r0##f0##f1##l %r0 0 \ + calli @abort \ +T##op##i##t##r0##f0##f1##l: \ + movi##t %f0 li \ + movi##t %f1 ri \ + op##r##t %r0 %f0 %f1 \ + bnei F##op##r##t##r0##f0##f1##l %r0 1 \ + calli @abort \ +F##op##r##t##r0##f0##f1##l: \ + movi##t %f1 li \ + op##i##t %r0 %f0 ri \ + bnei F##op##i##t##r0##f0##f1##l %r0 1 \ + calli @abort \ +F##op##i##t##r0##f0##f1##l: +#define fcmp1(l, t, op, r0, li, ri) \ + xfcmp(l, t, op, r0, f0, f1, li, ri) \ + xfcmp(l, t, op, r0, f1, f2, li, ri) \ + xfcmp(l, t, op, r0, f2, f3, li, ri) \ + xfcmp(l, t, op, r0, f3, f4, li, ri) \ + xfcmp(l, t, op, r0, f4, f5, li, ri) +#define fcmp0(l, t, op, li, ri) \ + fcmp1(l, t, op, v0, li, ri) \ + fcmp1(l, t, op, v1, li, ri) \ + fcmp1(l, t, op, v2, li, ri) \ + fcmp1(l, t, op, r0, li, ri) \ + fcmp1(l, t, op, r1, li, ri) \ + fcmp1(l, t, op, r2, li, ri) +#if __ia64__ +# define fcmp(l, op, li, ri) \ + xfcmp(l, _f, op, r0, f0, f1, li, ri) \ + xfcmp(l, _d, op, r0, f0, f1, li, ri) +#else +# define fcmp(l, op, li, ri) \ + fcmp0(l, _f, op, li, ri) \ + fcmp0(l, _d, op, li, ri) +#endif + +#define xf2w(l, f, r0, f0, iv, fv) \ + movi##f %f0 fv \ + truncr##f %r0 %f0 \ + beqi W##f##r0##f0##l %r0 iv \ + calli @abort \ +W##f##r0##f0##l: +#define f2w1(l, t, r0, iv, fv) \ + xf2w(l, t, r0, f0, iv, fv) \ + xf2w(l, t, r0, f1, iv, fv) \ + xf2w(l, t, r0, f2, iv, fv) \ + xf2w(l, t, r0, f3, iv, fv) \ + xf2w(l, t, r0, f4, iv, fv) \ + xf2w(l, t, r0, f5, iv, fv) +#define f2w0(l, t, iv, fv) \ + f2w1(l, t, v0, iv, fv) \ + f2w1(l, t, v1, iv, fv) \ + f2w1(l, t, v2, iv, fv) \ + f2w1(l, t, r0, iv, fv) \ + f2w1(l, t, r1, iv, fv) \ + f2w1(l, t, r2, iv, fv) +#if __ia64__ +# define f2w(l, iv, fv) \ + xf2w(l, _f, r0, f0, iv, fv) \ + xf2w(l, _d, r0, f0, iv, fv) +#else +# define f2w(l, iv, fv) \ + f2w0(l, _f, iv, fv) \ + f2w0(l, _d, iv, fv) +#endif + +.code + prolog + + tcmp(__LINE__, lt, 0, 1) + tcmp(__LINE__, lt, $nInf, $pInf) + tcmp(__LINE__, lt, $nInf, 0) + tcmp(__LINE__, lt, 0, $pInf) + fcmp(__LINE__, lt, $NaN, 0) + fcmp(__LINE__, lt, $NaN, $NaN) + fcmp(__LINE__, lt, $nInf, $NaN) + fcmp(__LINE__, lt, 1, 0) + fcmp(__LINE__, lt, 0, 0) + fcmp(__LINE__, lt, $pInf, $nInf) + fcmp(__LINE__, lt, 0, $nInf) + fcmp(__LINE__, lt, 0, $NaN) + + tcmp(__LINE__, le, 0, 1) + tcmp(__LINE__, le, 0, 0) + tcmp(__LINE__, le, 1, 1) + tcmp(__LINE__, le, $nInf, $pInf) + tcmp(__LINE__, le, $nInf, 0) + tcmp(__LINE__, le, 0, $pInf) + fcmp(__LINE__, le, $NaN, 0) + fcmp(__LINE__, le, $NaN, $NaN) + fcmp(__LINE__, le, $nInf, $NaN) + fcmp(__LINE__, le, 1, 0) + fcmp(__LINE__, le, $pInf, $nInf) + fcmp(__LINE__, le, 0, $nInf) + fcmp(__LINE__, le, 0, $NaN) + + tcmp(__LINE__, eq, 0, 0) + tcmp(__LINE__, eq, 1, 1) + fcmp(__LINE__, eq, $NaN, 0) + fcmp(__LINE__, eq, $NaN, $NaN) + fcmp(__LINE__, eq, $nInf, $NaN) + fcmp(__LINE__, eq, 0, 1) + fcmp(__LINE__, eq, 1, 0) + fcmp(__LINE__, eq, $pInf, $nInf) + fcmp(__LINE__, eq, 0, $nInf) + fcmp(__LINE__, eq, 0, $NaN) + + tcmp(__LINE__, ge, 1, 0) + tcmp(__LINE__, ge, 0, 0) + tcmp(__LINE__, ge, 1, 1) + tcmp(__LINE__, ge, $pInf, $nInf) + tcmp(__LINE__, ge, 0, $nInf) + tcmp(__LINE__, ge, $pInf, 0) + fcmp(__LINE__, ge, $NaN, 0) + fcmp(__LINE__, ge, $NaN, $NaN) + fcmp(__LINE__, ge, $nInf, $NaN) + fcmp(__LINE__, ge, 0, 1) + fcmp(__LINE__, ge, $nInf, $pInf) + fcmp(__LINE__, ge, $nInf, 0) + fcmp(__LINE__, ge, 0, $NaN) + + tcmp(__LINE__, gt, 1, 0) + tcmp(__LINE__, gt, $pInf, $nInf) + tcmp(__LINE__, gt, 0, $nInf) + tcmp(__LINE__, gt, $pInf, 0) + fcmp(__LINE__, gt, $NaN, 0) + fcmp(__LINE__, gt, $NaN, $NaN) + fcmp(__LINE__, gt, $nInf, $NaN) + fcmp(__LINE__, gt, 0, 1) + fcmp(__LINE__, gt, 0, 0) + fcmp(__LINE__, gt, $nInf, $pInf) + fcmp(__LINE__, gt, $nInf, 0) + fcmp(__LINE__, gt, 0, $NaN) + + tcmp(__LINE__, ne, 0, 1) + tcmp(__LINE__, ne, 1, 0) + tcmp(__LINE__, ne, $NaN, $NaN) + tcmp(__LINE__, ne, $nInf, $pInf) + tcmp(__LINE__, ne, $NaN, 0) + tcmp(__LINE__, ne, $nInf, $NaN) + tcmp(__LINE__, ne, $pInf, $nInf) + tcmp(__LINE__, ne, 0, $nInf) + tcmp(__LINE__, ne, 0, $NaN) + fcmp(__LINE__, ne, 0, 0) + fcmp(__LINE__, ne, 1, 1) + + tcmp(__LINE__, unlt, 0, 1) + tcmp(__LINE__, unlt, $nInf, $pInf) + tcmp(__LINE__, unlt, $nInf, 0) + tcmp(__LINE__, unlt, 0, $pInf) + tcmp(__LINE__, unlt, $NaN, 0) + tcmp(__LINE__, unlt, $NaN, $NaN) + tcmp(__LINE__, unlt, $nInf, $NaN) + tcmp(__LINE__, unlt, 0, $NaN) + fcmp(__LINE__, unlt, 1, 0) + fcmp(__LINE__, unlt, 0, 0) + fcmp(__LINE__, unlt, $pInf, $nInf) + fcmp(__LINE__, unlt, 0, $nInf) + + tcmp(__LINE__, unle, 0, 1) + tcmp(__LINE__, unle, 0, 0) + tcmp(__LINE__, unle, 1, 1) + tcmp(__LINE__, unle, $nInf, $pInf) + tcmp(__LINE__, unle, $nInf, 0) + tcmp(__LINE__, unle, 0, $pInf) + tcmp(__LINE__, unle, $NaN, 0) + tcmp(__LINE__, unle, $NaN, $NaN) + tcmp(__LINE__, unle, $nInf, $NaN) + tcmp(__LINE__, unle, 0, $NaN) + fcmp(__LINE__, unle, 1, 0) + fcmp(__LINE__, unle, $pInf, $nInf) + fcmp(__LINE__, unle, 0, $nInf) + + tcmp(__LINE__, uneq, 0, 0) + tcmp(__LINE__, uneq, 1, 1) + tcmp(__LINE__, uneq, $NaN, 0) + tcmp(__LINE__, uneq, $NaN, $NaN) + tcmp(__LINE__, uneq, $nInf, $NaN) + tcmp(__LINE__, uneq, 0, $NaN) + fcmp(__LINE__, uneq, 0, 1) + fcmp(__LINE__, uneq, 1, 0) + fcmp(__LINE__, uneq, $pInf, $nInf) + fcmp(__LINE__, uneq, 0, $nInf) + + tcmp(__LINE__, unge, 1, 0) + tcmp(__LINE__, unge, 0, 0) + tcmp(__LINE__, unge, 1, 1) + tcmp(__LINE__, unge, $pInf, $nInf) + tcmp(__LINE__, unge, 0, $nInf) + tcmp(__LINE__, unge, $pInf, 0) + tcmp(__LINE__, unge, $NaN, 0) + tcmp(__LINE__, unge, $NaN, $NaN) + tcmp(__LINE__, unge, $nInf, $NaN) + tcmp(__LINE__, unge, 0, $NaN) + fcmp(__LINE__, unge, 0, 1) + fcmp(__LINE__, unge, $nInf, $pInf) + fcmp(__LINE__, unge, $nInf, 0) + + tcmp(__LINE__, ungt, 1, 0) + tcmp(__LINE__, ungt, $pInf, $nInf) + tcmp(__LINE__, ungt, 0, $nInf) + tcmp(__LINE__, ungt, $pInf, 0) + tcmp(__LINE__, ungt, $NaN, 0) + tcmp(__LINE__, ungt, $NaN, $NaN) + tcmp(__LINE__, ungt, $nInf, $NaN) + tcmp(__LINE__, ungt, 0, $NaN) + fcmp(__LINE__, ungt, 0, 1) + fcmp(__LINE__, ungt, 0, 0) + fcmp(__LINE__, ungt, $nInf, $pInf) + fcmp(__LINE__, ungt, $nInf, 0) + + tcmp(__LINE__, ltgt, 0, 1) + tcmp(__LINE__, ltgt, 1, 0) + tcmp(__LINE__, ltgt, $nInf, $pInf) + tcmp(__LINE__, ltgt, $pInf, $nInf) + tcmp(__LINE__, ltgt, 0, $nInf) + fcmp(__LINE__, ltgt, $NaN, $NaN) + fcmp(__LINE__, ltgt, $NaN, 0) + fcmp(__LINE__, ltgt, $nInf, $NaN) + fcmp(__LINE__, ltgt, 0, $NaN) + fcmp(__LINE__, ltgt, 0, 0) + fcmp(__LINE__, ltgt, 1, 1) + + tcmp(__LINE__, ord, 0, 1) + tcmp(__LINE__, ord, 1, 0) + tcmp(__LINE__, ord, $nInf, $pInf) + tcmp(__LINE__, ord, $pInf, $nInf) + tcmp(__LINE__, ord, 0, $nInf) + tcmp(__LINE__, ord, 0, 0) + tcmp(__LINE__, ord, 1, 1) + fcmp(__LINE__, ord, $NaN, $NaN) + fcmp(__LINE__, ord, $NaN, 0) + fcmp(__LINE__, ord, $nInf, $NaN) + fcmp(__LINE__, ord, 0, $NaN) + + tcmp(__LINE__, unord, $NaN, $NaN) + tcmp(__LINE__, unord, $NaN, 0) + tcmp(__LINE__, unord, $nInf, $NaN) + tcmp(__LINE__, unord, 0, $NaN) + fcmp(__LINE__, unord, 0, 1) + fcmp(__LINE__, unord, 1, 0) + fcmp(__LINE__, unord, $nInf, $pInf) + fcmp(__LINE__, unord, $pInf, $nInf) + fcmp(__LINE__, unord, 0, $nInf) + fcmp(__LINE__, unord, 0, 0) + fcmp(__LINE__, unord, 1, 1) + + f2w(__LINE__, 0, 0) + f2w(__LINE__, 1, 1) + /* not all loongson agree on it */ +#if !__mips__ + f2w(__LINE__, wninf, $nInf) +#endif + f2w(__LINE__, wpinf, $pInf) + f2w(__LINE__, wnan, $NaN) + + prepare + pushargi ok + ellipsis + finishi @puts + + ret + epilog diff --git a/deps/lightning/check/fop_abs.ok b/deps/lightning/check/fop_abs.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/fop_abs.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/fop_abs.tst b/deps/lightning/check/fop_abs.tst new file mode 100644 index 0000000..cb7be14 --- /dev/null +++ b/deps/lightning/check/fop_abs.tst @@ -0,0 +1,31 @@ +#include "alu.inc" + +.code + prolog +#define ABS(N, T, I, V) FUN(N, T, abs, I, V) +#define UABS(N, T, I, V) UFUN(N, T, abs, I, V) + ABS(0, _f, -0.0, 0.0) + ABS(1, _f, 0.5, 0.5) + ABS(2, _f, -0.5, 0.5) + ABS(3, _f, $Inf, $Inf) + ABS(4, _f, $nInf, $Inf) + ABS(5, _f, 1.25, 1.25) + ABS(6, _f, -1.25, 1.25) + ABS(7, _f, $nInf, $Inf) + UABS(0, _f, $NaN, $NaN) + ABS(0, _d, -0.0, 0.0) + ABS(1, _d, 0.5, 0.5) + ABS(2, _d, -0.5, 0.5) + ABS(3, _d, $Inf, $Inf) + ABS(4, _d, $nInf, $Inf) + ABS(5, _d, 1.25, 1.25) + ABS(6, _d, -1.25, 1.25) + ABS(7, _d, $nInf, $Inf) + UABS(0, _d, $NaN, $NaN) + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/fop_sqrt.ok b/deps/lightning/check/fop_sqrt.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/fop_sqrt.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/fop_sqrt.tst b/deps/lightning/check/fop_sqrt.tst new file mode 100644 index 0000000..fa93dbc --- /dev/null +++ b/deps/lightning/check/fop_sqrt.tst @@ -0,0 +1,23 @@ +#include "alu.inc" + +.code + prolog +#define SQRT(N, T, I, V) FUN(N, T, sqrt, I, V) +#define USQRT(N, T, I, V) UFUN(N, T, sqrt, I, V) + SQRT(0, _f, -0.0, 0.0) + SQRT(1, _f, 4.0, 2.0) + SQRT(2, _f, 2.25, 1.5) + SQRT(3, _f, $Inf, $Inf) + USQRT(0, _f, $NaN, $NaN) + SQRT(0, _d, -0.0, 0.0) + SQRT(1, _d, 4.0, 2.0) + SQRT(2, _d, 2.25, 1.5) + SQRT(3, _d, $Inf, $Inf) + USQRT(0, _d, $NaN, $NaN) + + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/hton.ok b/deps/lightning/check/hton.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/hton.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/hton.tst b/deps/lightning/check/hton.tst new file mode 100644 index 0000000..fcaf147 --- /dev/null +++ b/deps/lightning/check/hton.tst @@ -0,0 +1,169 @@ +.data 16 +ok: +.c "ok\n" + +#define us12_i 0x1234 +#define us7f_i 0x7ff7 +#define us80_i 0x8008 +#define usff_i 0xffff +#define ui12_i 0x01234567 +#define ui7f_i 0x7f7ff7f7 +#define ui80_i 0x80800808 +#define uiff_i 0xffffffff +#define ul12_i 0x0123456789abcdef +#define ul7f_i 0x7f7f7f7ff7f7f7f7 +#define ul80_i 0x8080808008080808 +#define ulff_i 0xffffffffffffffff + +#if __WORDSIZE == 32 +# define xus12_i 0xffff1234 +# define xus7f_i 0x10107ff7 +# define xus80_i 0x81188008 +# define xusff_i 0xeaaeffff +#else +# define xus12_i 0xffffffffffff1234 +# define xus7f_i 0x1010100101017ff7 +# define xus80_i 0x8181811818818008 +# define xusff_i 0xeaeaeaaeaeaeffff +# define xui12_i 0xffffffff01234567 +# define xui7f_i 0x101001017f7ff7f7 +# define xui80_i 0x8181181880800808 +# define xuiff_i 0xeaeaaeaeffffffff +#endif + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define us12_o 0x3412 +# define us7f_o 0xf77f +# define us80_o 0x0880 +# define usff_o 0xffff +# define ui12_o 0x67452301 +# define ui7f_o 0xf7f77f7f +# define ui80_o 0x08088080 +# define uiff_o 0xffffffff +# define ul12_o 0xefcdab8967452301 +# define ul7f_o 0xf7f7f7f77f7f7f7f +# define ul80_o 0x0808080880808080 +# define ulff_o 0xffffffffffffffff +#else +# define us12_o us12_i +# define us7f_o us7f_i +# define us80_o us80_i +# define usff_o usff_i +# define ui12_o ui12_i +# define ui7f_o ui7f_i +# define ui80_o ui80_i +# define uiff_o uiff_i +# define ul12_o ul12_i +# define ul7f_o ul7f_i +# define ul80_o ul80_i +# define ulff_o ulff_i +#endif + +#define HTON4(I, O, T, R0, R1) \ + movi %R0 I \ + htonr_##T %R1 %R0 \ + beqi T##R0##R1##I %R1 O \ + calli @abort \ +T##R0##R1##I: + +#define HTON3(T, R0, R1) \ + HTON4(T##12_i, T##12_o, T, R0, R1) \ + HTON4(x##T##12_i, T##12_o, T, R0, R1) \ + HTON4(T##7f_i, T##7f_o, T, R0, R1) \ + HTON4(x##T##7f_i, T##7f_o, T, R0, R1) \ + HTON4(T##80_i, T##80_o, T, R0, R1) \ + HTON4(x##T##80_i, T##80_o, T, R0, R1) \ + HTON4(T##ff_i, T##ff_o, T, R0, R1) \ + HTON4(x##T##ff_i, T##ff_o, T, R0, R1) + +#define HTON3x(T, R0, R1) \ + HTON4(T##12_i, T##12_o, T, R0, R1) \ + HTON4(T##7f_i, T##7f_o, T, R0, R1) \ + HTON4(T##80_i, T##80_o, T, R0, R1) \ + HTON4(T##ff_i, T##ff_o, T, R0, R1) + +#define HTON2(T, V0, V1, V2, R0, R1, R2) \ + HTON3(T, V0, V0) \ + HTON3(T, V0, V1) \ + HTON3(T, V0, V2) \ + HTON3(T, V0, R0) \ + HTON3(T, V0, R1) \ + HTON3(T, V0, R2) \ + +#define HTON2x(T, V0, V1, V2, R0, R1, R2) \ + HTON3x(T, V0, V0) \ + HTON3x(T, V0, V1) \ + HTON3x(T, V0, V2) \ + HTON3x(T, V0, R0) \ + HTON3x(T, V0, R1) \ + HTON3x(T, V0, R2) \ + +#define HTON1(T, V0, V1, V2, R0, R1, R2) \ + HTON2(T, V0, V1, V2, R0, R1, R2) \ + HTON2(T, V1, V2, R0, R1, R2, V0) \ + HTON2(T, V2, R0, R1, R2, V0, V1) \ + HTON2(T, R0, R1, R2, V0, V1, V2) \ + HTON2(T, R1, R2, V0, V1, V2, R0) \ + HTON2(T, R2, V0, V1, V2, R0, R1) + +#define HTON1x(T, V0, V1, V2, R0, R1, R2) \ + HTON2x(T, V0, V1, V2, R0, R1, R2) \ + HTON2x(T, V1, V2, R0, R1, R2, V0) \ + HTON2x(T, V2, R0, R1, R2, V0, V1) \ + HTON2x(T, R0, R1, R2, V0, V1, V2) \ + HTON2x(T, R1, R2, V0, V1, V2, R0) \ + HTON2x(T, R2, V0, V1, V2, R0, R1) + +#if __WORDSIZE == 32 +# define HTON(V0, V1, V2, R0, R1, R2) \ + HTON1(us, V0, V1, V2, R0, R1, R2) \ + HTON1x(ui, V0, V1, V2, R0, R1, R2) +#else +# define HTON(V0, V1, V2, R0, R1, R2) \ + HTON1(us, V0, V1, V2, R0, R1, R2) \ + HTON1(ui, V0, V1, V2, R0, R1, R2) \ + HTON1x(ul, V0, V1, V2, R0, R1, R2) +#endif + +.code + prolog + /* simple sequence for easier disassembly reading and encoding check */ + movi %r0 us12_i + htonr_us %r1 %r0 + beqi us %r1 us12_o + calli @abort +us: + + movi %r0 xus12_i + htonr_us %r1 %r0 + beqi xus %r1 us12_o + calli @abort +xus: + movi %r0 ui12_i + htonr_ui %r1 %r0 + beqi ui %r1 ui12_o + calli @abort +ui: +#if __WORDSIZE == 64 + movi %r0 xui12_i + htonr_ui %r1 %r0 + beqi xui %r1 ui12_o + calli @abort +xui: + movi %r0 ul12_i + htonr_ul %r1 %r0 + beqi ul %r1 ul12_o + calli @abort +ul: +#endif + + HTON(v0, v1, v2, r0, r1, r2) + + // just to know did not abort + prepare + pushargi ok + ellipsis + finishi @printf + + ret + epilog diff --git a/deps/lightning/check/jmpr.ok b/deps/lightning/check/jmpr.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/jmpr.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/jmpr.tst b/deps/lightning/check/jmpr.tst new file mode 100644 index 0000000..669f54e --- /dev/null +++ b/deps/lightning/check/jmpr.tst @@ -0,0 +1,66 @@ +/* +This is a very simple check to a condition that on lightning 2.0.5 +could cause an assertion on some backends, due to correcting a problem +with temporaries that could not be saved/reloaded due to being used only +in the hardware instruction, or being considered live for too long on the +lightning instruction, and that could not be reloaded after the jump target +(or after false/true target on conditional branches). + +If this code in lib/lightning.c:_jit_update(): + + for (regno = 0; regno < _jitc->reglen; regno++) { + spec = jit_class(_rvs[regno].spec); + if (jit_regset_tstbit(mask, regno) && + (spec & (jit_class_gpr|jit_class_fpr)) && + !(spec & jit_class_sav)) + jit_regset_clrbit(mask, regno); + } + +were removed, this test case, on x86_64 would fail like this: + +lt-lightning: lightning.c:305: _jit_get_reg: Assertion `regspec & 0x02000000' failed. +Aborted (core dumped) + */ + +.data 32 +ret: +#if __WORDSIZE == 32 +.i 0 +#else +.l 0 +#endif +ok: +.c "ok" + +.code + prolog + jmpi start + +add_v1_v2: + addr %v1 %v1 %v2 + ldi %r0 ret + jmpr %r0 + +start: + movi %v1 1 + movi %v2 2 + movi %r0 ret_add_v1_v2 + sti ret %r0 + movi %v0 add_v1_v2 + jmpr %v0 + movi_d %f0 3 + beqi_d pass_movi_f0 %f0 3 + calli @abort +pass_movi_f0: + beqi pass_check_v2 %v2 2 + calli @abort +pass_check_v2: +ret_add_v1_v2: + beqi pass_add_v1_v2 %v1 3 + calli @abort +pass_add_v1_v2: + prepare + pushargi ok + finishi @puts + ret + epilog diff --git a/deps/lightning/check/ldst.inc b/deps/lightning/check/ldst.inc new file mode 100644 index 0000000..c2bc59a --- /dev/null +++ b/deps/lightning/check/ldst.inc @@ -0,0 +1,102 @@ +#if __WORDSIZE == 64 +# define L0 0x8000000000000001 +# define LL0 L0 +# define LC0 0xffffffffffffff81 +# define LS0 0xffffffffffff8001 +# define LI0 0xffffffff80000001 +# define L1 0x8000000000000000 +# define LL1 L1 +# define LC1 0xffffffffffffff80 +# define LS1 0xffffffffffff8000 +# define LI1 0xffffffff80000000 +# define L2 0x7fffffffffffffff +# define LL2 L2 +# define LC2 0x000000000000007f +# define LS2 0x0000000000007fff +# define LI2 0x000000007fffffff +# define L3 0xffffffffffffffff +# define LL3 L3 +# define LC3 0xffffffffffffffff +# define LS3 0xffffffffffffffff +# define LI3 0xffffffffffffffff +# define XC LC0 +# define XS LS0 +# define XI LI0 +#else +# define XC IC0 +# define XS IS0 +# define XI II0 +#endif +#define I0 0x80000001 +#define II0 I0 +#define IC0 0xffffff81 +#define IS0 0xffff8001 +#define I1 0x80000000 +#define II1 I1 +#define IC1 0xffffff80 +#define IS1 0xffff8000 +#define I2 0x7fffffff +#define II2 I2 +#define IC2 0x0000007f +#define IS2 0x00007fff +#define I3 0xffffffff +#define II3 I3 +#define IC3 0xffffffff +#define IS3 0xffffffff +#define S0 0x8001 +#define S1 0x8000 +#define S2 0x7fff +#define S3 0xffff +#define C0 0x81 +#define C1 0x80 +#define C2 0x7f +#define C3 0xff +#define F0 0.25 +#define F1 0.75 +#define F2 -0.25 +#define F3 -0.75 +#define D0 0.25 +#define D1 0.75 +#define D2 -0.25 +#define D3 -0.75 + +.data 512 +ok: +.c "ok\n" +.align 8 +t0: +c0: +.c 0 +uc0: +.c 0 +s0: +.s 0 +us0: +.s 0 +.align 4 +i0: +.i 0 +#if __WORDSIZE == 64 +ui0: +.i 0 +.align 8 +l0: +.l 0 +#endif +f0: +.f 0 +.align 8 +d0: +.d 0 + +. $($offc = c0 - t0) +. $($offuc = uc0 - t0) +. $($offs = s0 - t0) +. $($offus = us0 - t0) +. $($offi = i0 - t0) +#if __WORDSIZE == 64 +. $($offui = ui0 - t0) +. $($offl = l0 - t0) +#endif +. $($offf = f0 - t0) +. $($offd = d0 - t0) diff --git a/deps/lightning/check/ldsti.ok b/deps/lightning/check/ldsti.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/ldsti.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/ldsti.tst b/deps/lightning/check/ldsti.tst new file mode 100644 index 0000000..362cb84 --- /dev/null +++ b/deps/lightning/check/ldsti.tst @@ -0,0 +1,146 @@ +#include "ldst.inc" + +#if __WORDSIZE == 64 +# define LDSTL(N, R0) \ + sti_i ui0 %R0 \ + movi %R0 L##N \ + sti_l l0 %R0 + +# define SI(C, N, x, X, R0) \ + ldi_##x %R0 x##0 \ + beqi L##x##C %R0 L##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0) \ + UI(C, N, i, I, R0) \ + SI(C, N, l, L, R0) +#else +# define LDSTL(C, R0) +# define SI(C, N, x, X, R0) \ + ldi_##x %R0 x##0 \ + beqi L##x##C %R0 I##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0) + +#endif + +#define UI(C, N, x, X, R0) \ + ldi_u##x %R0 u##x##0 \ + beqi Lu##x##C %R0 X##N \ + calli @abort \ +Lu##x##C: + +#define FF(C, N, x, X, F0) \ + ldi_##x %F0 x##0 \ + beqi_##x L##x##C %F0 X##N \ +L##x##C: + +#define LDST1(X, N, R0, F0) \ + movi %R0 C##N \ + sti_c c0 %R0 \ + sti_c uc0 %R0 \ + movi %R0 S##N \ + sti_s s0 %R0 \ + sti_s us0 %R0 \ + movi %R0 I##N \ + sti_i i0 %R0 \ + LDSTL(N, R0) \ + movi_f %F0 F##N \ + sti_f f0 %F0 \ + movi_d %F0 D##N \ + sti_d d0 %F0 \ + SI(X, N, c, C, R0) \ + UI(X, N, c, C, R0) \ + SI(X, N, s, S, R0) \ + UI(X, N, s, S, R0) \ + SI(X, N, i, I, R0) \ + LDRL(X, N, R0) \ + FF(X, N, f, F, F0) \ + FF(X, N, d, D, F0) + +#define LDST0(R0, F0) \ + LDST1(0_##R0##_##F0, 0, R0, F0) \ + LDST1(1_##R0##_##F0, 1, R0, F0) \ + LDST1(2_##R0##_##F0, 2, R0, F0) \ + LDST1(3_##R0##_##F0, 3, R0, F0) + +#define LDST(V0, V1, V2, R0, R1, R2, F0, F1, F2, F3, F4, F5) \ + LDST0(V0, F0) \ + LDST0(V1, F1) \ + LDST0(V2, F3) \ + LDST0(R0, F4) \ + LDST0(R1, F5) \ + LDST0(R2, F0) + +.code + prolog + + /* Simple test to simplify validating encodings before + * brute force tests */ + movi %r1 0x81 + sti_c c0 %r1 + sti_c uc0 %r1 + movi %r1 0x8001 + sti_s s0 %r1 + sti_s us0 %r1 + movi %r1 0x80000001 + sti_i i0 %r1 +#if __WORDSIZE == 64 + sti_i ui0 %r1 + movi %r1 0x8000000000000001 + sti_l l0 %r1 +#endif + movi_f %f0 0.5 + sti_f f0 %f0 + movi_d %f0 0.25 + sti_d d0 %f0 + ldi_c %r1 c0 + beqi Lc %r1 XC + calli @abort +Lc: + ldi_uc %r1 uc0 + beqi Luc %r1 0x81 + calli @abort +Luc: + ldi_s %r1 s0 + beqi Ls %r1 XS + calli @abort +Ls: + ldi_us %r1 us0 + beqi Lus %r1 0x8001 + calli @abort +Lus: + ldi_i %r1 i0 + beqi Li %r1 XI + calli @abort +Li: +#if __WORDSIZE == 64 + ldi_ui %r1 ui0 + beqi Lui %r1 0x80000001 + calli @abort +Lui: + ldi_l %r1 l0 + beqi Ll %r1 0x8000000000000001 + calli @abort +Ll: +#endif + ldi_f %f0 f0 + beqi_f Lf %f0 0.5 + calli @abort +Lf: + ldi_d %f0 d0 + beqi_d Ld %f0 0.25 + calli @abort +Ld: + + LDST(v0, v1, v2, r0, r1, r2, f0, f1, f2, f3, f4, f5) + // just to know did not abort + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/ldstr-c.ok b/deps/lightning/check/ldstr-c.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/ldstr-c.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/ldstr-c.tst b/deps/lightning/check/ldstr-c.tst new file mode 100644 index 0000000..6ddc86e --- /dev/null +++ b/deps/lightning/check/ldstr-c.tst @@ -0,0 +1,155 @@ +#include "ldst.inc" + +#if __WORDSIZE == 64 +# define LDSTL(N, R0, R1) \ + movi %R0 $(t0 + $offui) \ + str_i %R0 %R1 \ + movi %R0 $(t0 + $offl) \ + movi %R1 L##N \ + str_l %R0 %R1 + +# define SI(C, N, x, X, R0) \ + movi %R0 $(t0 + $off##x) \ + ldr_##x %R0 %R0 \ + beqi L##x##C %R0 L##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0, R1) \ + UI(C, N, i, I, R0) \ + SI(C, N, l, L, R0) +#else +# define LDSTL(C, R0, R1) +# define SI(C, N, x, X, R0) \ + movi %R0 $(t0 + $off##x) \ + ldr_##x %R0 %R0 \ + beqi L##x##C %R0 I##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0, R1) + +#endif + +#define UI(C, N, x, X, R0) \ + movi %R0 $(t0 + $offu##x) \ + ldr_u##x %R0 %R0 \ + beqi Lu##x##C %R0 X##N \ + calli @abort \ +Lu##x##C: + +#define LDST1(X, N, R0, R1) \ + movi %R0 $(t0 + $offc) \ + movi %R1 C##N \ + str_c %R0 %R1 \ + movi %R0 $(t0 + $offuc) \ + str_c %R0 %R1 \ + movi %R0 $(t0 + $offs) \ + movi %R1 S##N \ + str_s %R0 %R1 \ + movi %R0 $(t0 + $offus) \ + str_s %R0 %R1 \ + movi %R0 $(t0 + $offi) \ + movi %R1 I##N \ + str_i %R0 %R1 \ + LDSTL(N, R0, R1) \ + movi %R0 $(t0 + $offf) \ + SI(X, N, c, C, R0) \ + UI(X, N, c, C, R0) \ + SI(X, N, s, S, R0) \ + UI(X, N, s, S, R0) \ + SI(X, N, i, I, R0) \ + LDRL(X, N, R0, R1) \ + +#define LDST0(R0, R1) \ + LDST1(0_##R0##_##R1, 0, R0, R1) \ + LDST1(1_##R0##_##R1, 1, R0, R1) \ + LDST1(2_##R0##_##R1, 2, R0, R1) \ + LDST1(3_##R0##_##R1, 3, R0, R1) + +#define LDST(V0, V1, V2, R0, R1, R2) \ + LDST0(V0, V1) \ + LDST0(V0, V2) \ + LDST0(V0, R0) \ + LDST0(V0, R1) \ + LDST0(V0, R2) \ + LDST0(V1, V0) \ + LDST0(V1, V2) \ + LDST0(V1, R0) \ + LDST0(V1, R1) \ + LDST0(V1, R2) \ + LDST0(V2, R0) \ + LDST0(V2, R1) \ + LDST0(V2, R2) + +.code + prolog + + /* Simple test to simplify validating encodings before + * brute force tests */ + movi %r0 $(t0 + $offc) + movi %r1 0x81 + str_c %r0 %r1 + movi %r0 $(t0 + $offuc) + str_c %r0 %r1 + movi %r0 $(t0 + $offs) + movi %r1 0x8001 + str_s %r0 %r1 + movi %r0 $(t0 + $offus) + str_s %r0 %r1 + movi %r0 $(t0 + $offi) + movi %r1 0x80000001 + str_i %r0 %r1 +#if __WORDSIZE == 64 + movi %r0 $(t0 + $offui) + str_i %r0 %r1 + movi %r0 $(t0 + $offl) + movi %r1 0x8000000000000001 + str_l %r0 %r1 +#endif + movi %r0 $(t0 + $offc) + ldr_c %r0 %r0 + beqi Lc %r0 XC + calli @abort +Lc: + movi %r0 $(t0 + $offuc) + ldr_uc %r0 %r0 + beqi Luc %r0 0x81 + calli @abort +Luc: + movi %r0 $(t0 + $offs) + ldr_s %r0 %r0 + beqi Ls %r0 XS + calli @abort +Ls: + movi %r0 $(t0 + $offus) + ldr_us %r0 %r0 + beqi Lus %r0 0x8001 + calli @abort +Lus: + movi %r0 $(t0 + $offi) + ldr_i %r0 %r0 + beqi Li %r0 XI + calli @abort +Li: +#if __WORDSIZE == 64 + movi %r0 $(t0 + $offui) + ldr_ui %r0 %r0 + beqi Lui %r0 0x80000001 + calli @abort +Lui: + movi %r0 $(t0 + $offl) + ldr_l %r0 %r0 + beqi Ll %r0 0x8000000000000001 + calli @abort +Ll: +#endif + + LDST(v0, v1, v2, r0, r1, r2) + // just to know did not abort + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/ldstr.ok b/deps/lightning/check/ldstr.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/ldstr.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/ldstr.tst b/deps/lightning/check/ldstr.tst new file mode 100644 index 0000000..1ed26b1 --- /dev/null +++ b/deps/lightning/check/ldstr.tst @@ -0,0 +1,183 @@ +#include "ldst.inc" + +#if __WORDSIZE == 64 +# define LDSTL(N, R0, R1) \ + movi %R0 $(t0 + $offui) \ + str_i %R0 %R1 \ + movi %R0 $(t0 + $offl) \ + movi %R1 L##N \ + str_l %R0 %R1 + +# define SI(C, N, x, X, R0, R1) \ + movi %R0 $(t0 + $off##x) \ + ldr_##x %R1 %R0 \ + beqi L##x##C %R1 L##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0, R1) \ + UI(C, N, i, I, R0, R1) \ + SI(C, N, l, L, R0, R1) +#else +# define LDSTL(C, R0, R1) +# define SI(C, N, x, X, R0, R1) \ + movi %R0 $(t0 + $off##x) \ + ldr_##x %R1 %R0 \ + beqi L##x##C %R1 I##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0, R1) + +#endif + +#define UI(C, N, x, X, R0, R1) \ + movi %R0 $(t0 + $offu##x) \ + ldr_u##x %R1 %R0 \ + beqi Lu##x##C %R1 X##N \ + calli @abort \ +Lu##x##C: + +#define FF(C, N, x, X, R0, F0) \ + movi %R0 $(t0 + $off##x) \ + ldr_##x %F0 %R0 \ + beqi_##x L##x##C %F0 X##N \ +L##x##C: + +#define LDST1(X, N, R0, R1, F0) \ + movi %R0 $(t0 + $offc) \ + movi %R1 C##N \ + str_c %R0 %R1 \ + movi %R0 $(t0 + $offuc) \ + str_c %R0 %R1 \ + movi %R0 $(t0 + $offs) \ + movi %R1 S##N \ + str_s %R0 %R1 \ + movi %R0 $(t0 + $offus) \ + str_s %R0 %R1 \ + movi %R0 $(t0 + $offi) \ + movi %R1 I##N \ + str_i %R0 %R1 \ + LDSTL(N, R0, R1) \ + movi %R0 $(t0 + $offf) \ + movi_f %F0 F##N \ + str_f %R0 %F0 \ + movi %R0 $(t0 + $offd) \ + movi_d %F0 D##N \ + str_d %R0 %F0 \ + SI(X, N, c, C, R0, R1) \ + UI(X, N, c, C, R0, R1) \ + SI(X, N, s, S, R0, R1) \ + UI(X, N, s, S, R0, R1) \ + SI(X, N, i, I, R0, R1) \ + LDRL(X, N, R0, R1) \ + FF(X, N, f, F, R0, F0) \ + FF(X, N, d, D, R0, F0) + +#define LDST0(R0, R1, F0) \ + LDST1(0_##R0##_##R1##_##F0, 0, R0, R1, F0) \ + LDST1(1_##R0##_##R1##_##F0, 1, R0, R1, F0) \ + LDST1(2_##R0##_##R1##_##F0, 2, R0, R1, F0) \ + LDST1(3_##R0##_##R1##_##F0, 3, R0, R1, F0) + +#define LDST(V0, V1, V2, R0, R1, R2, F0, F1, F2, F3, F4, F5) \ + LDST0(V0, V1, F0) \ + LDST0(V0, V2, F1) \ + LDST0(V0, R0, F3) \ + LDST0(V0, R1, F4) \ + LDST0(V0, R2, F5) \ + LDST0(V1, V2, F0) \ + LDST0(V1, R0, F1) \ + LDST0(V1, R1, F2) \ + LDST0(V1, R2, F3) \ + LDST0(V2, R0, F4) \ + LDST0(V2, R1, F5) \ + LDST0(V2, R2, F0) + +.code + prolog + + /* Simple test to simplify validating encodings before + * brute force tests */ + movi %r0 $(t0 + $offc) + movi %r1 0x81 + str_c %r0 %r1 + movi %r0 $(t0 + $offuc) + str_c %r0 %r1 + movi %r0 $(t0 + $offs) + movi %r1 0x8001 + str_s %r0 %r1 + movi %r0 $(t0 + $offus) + str_s %r0 %r1 + movi %r0 $(t0 + $offi) + movi %r1 0x80000001 + str_i %r0 %r1 +#if __WORDSIZE == 64 + movi %r0 $(t0 + $offui) + str_i %r0 %r1 + movi %r0 $(t0 + $offl) + movi %r1 0x8000000000000001 + str_l %r0 %r1 +#endif + movi %r0 $(t0 + $offf) + movi_f %f0 0.5 + str_f %r0 %f0 + movi %r0 $(t0 + $offd) + movi_d %f0 0.25 + str_d %r0 %f0 + movi %r0 $(t0 + $offc) + ldr_c %r1 %r0 + beqi Lc %r1 XC + calli @abort +Lc: + movi %r0 $(t0 + $offuc) + ldr_uc %r1 %r0 + beqi Luc %r1 0x81 + calli @abort +Luc: + movi %r0 $(t0 + $offs) + ldr_s %r1 %r0 + beqi Ls %r1 XS + calli @abort +Ls: + movi %r0 $(t0 + $offus) + ldr_us %r1 %r0 + beqi Lus %r1 0x8001 + calli @abort +Lus: + movi %r0 $(t0 + $offi) + ldr_i %r1 %r0 + beqi Li %r1 XI + calli @abort +Li: +#if __WORDSIZE == 64 + movi %r0 $(t0 + $offui) + ldr_ui %r1 %r0 + beqi Lui %r1 0x80000001 + calli @abort +Lui: + movi %r0 $(t0 + $offl) + ldr_l %r1 %r0 + beqi Ll %r1 0x8000000000000001 + calli @abort +Ll: +#endif + movi %r0 $(t0 + $offf) + ldr_f %f0 %r0 + beqi_f Lf %f0 0.5 + calli @abort +Lf: + movi %r0 $(t0 + $offd) + ldr_d %f0 %r0 + beqi_d Ld %f0 0.25 + calli @abort +Ld: + + LDST(v0, v1, v2, r0, r1, r2, f0, f1, f2, f3, f4, f5) + // just to know did not abort + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/ldstxi-c.ok b/deps/lightning/check/ldstxi-c.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/ldstxi-c.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/ldstxi-c.tst b/deps/lightning/check/ldstxi-c.tst new file mode 100644 index 0000000..1ad0168 --- /dev/null +++ b/deps/lightning/check/ldstxi-c.tst @@ -0,0 +1,158 @@ +#include "ldst.inc" + +#if __WORDSIZE == 64 +# define LDSTL(N, R0, R1) \ + stxi_i $offui %R0 %R1 \ + movi %R1 L##N \ + stxi_l $offl %R0 %R1 + +# define SI(C, N, x, X, R0) \ + ldxi_##x %R0 %R0 $off##x \ + beqi L##x##C %R0 L##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0, R1) \ + UI(C, N, i, I, R0) \ + movi %R0 t0 \ + SI(C, N, l, L, R0) +#else +# define LDSTL(C, R0, R1) +# define SI(C, N, x, X, R0) \ + ldxi_##x %R0 %R0 $off##x \ + beqi L##x##C %R0 I##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0, R1) + +#endif + +#define UI(C, N, x, X, R0) \ + ldxi_u##x %R0 %R0 $offu##x \ + beqi Lu##x##C %R0 X##N \ + calli @abort \ +Lu##x##C: + +#define LDST1(X, N, R0, R1) \ + movi %R0 t0 \ + movi %R1 C##N \ + stxi_c $offc %R0 %R1 \ + stxi_c $offuc %R0 %R1 \ + movi %R1 S##N \ + stxi_s $offs %R0 %R1 \ + stxi_s $offus %R0 %R1 \ + movi %R1 I##N \ + stxi_i $offi %R0 %R1 \ + LDSTL(N, R0, R1) \ + SI(X, N, c, C, R0) \ + movi %R0 t0 \ + UI(X, N, c, C, R0) \ + movi %R0 t0 \ + SI(X, N, s, S, R0) \ + movi %R0 t0 \ + UI(X, N, s, S, R0) \ + movi %R0 t0 \ + SI(X, N, i, I, R0) \ + movi %R0 t0 \ + LDRL(X, N, R0, R1) \ + +#define LDST0(R0, R1) \ + LDST1(0_##R0##_##R1, 0, R0, R1) \ + LDST1(1_##R0##_##R1, 1, R0, R1) \ + LDST1(2_##R0##_##R1, 2, R0, R1) \ + LDST1(3_##R0##_##R1, 3, R0, R1) + +#define LDST(V0, V1, V2, R0, R1, R2) \ + LDST0(V0, V1) \ + LDST0(V0, V2) \ + LDST0(V0, R0) \ + LDST0(V0, R1) \ + LDST0(V0, R2) \ + LDST0(V1, V2) \ + LDST0(V1, R0) \ + LDST0(V1, R1) \ + LDST0(V1, R2) \ + LDST0(V2, R0) \ + LDST0(V2, R1) \ + LDST0(V2, R2) \ + LDST0(R0, V0) \ + LDST0(R0, V1) \ + LDST0(R0, V2) \ + LDST0(R0, R1) \ + LDST0(R0, R2) \ + LDST0(R1, V0) \ + LDST0(R1, V1) \ + LDST0(R1, V2) \ + LDST0(R1, R0) \ + LDST0(R1, R2) \ + LDST0(R2, V0) \ + LDST0(R2, V1) \ + LDST0(R2, V2) \ + LDST0(R2, R0) \ + LDST0(R2, R1) + +.code + prolog + + /* Simple test to simplify validating encodings before + * brute force tests */ + movi %r0 t0 + movi %r1 0x81 + stxi_c $offc %r0 %r1 + stxi_c $offuc %r0 %r1 + movi %r1 0x8001 + stxi_s $offs %r0 %r1 + stxi_s $offus %r0 %r1 + movi %r1 0x80000001 + stxi_i $offi %r0 %r1 +#if __WORDSIZE == 64 + stxi_i $offui %r0 %r1 + movi %r1 0x8000000000000001 + stxi_l $offl %r0 %r1 +#endif + ldxi_c %r0 %r0 $offc + beqi Lc %r0 XC + calli @abort +Lc: + movi %r0 t0 + ldxi_uc %r0 %r0 $offuc + beqi Luc %r0 0x81 + calli @abort +Luc: + movi %r0 t0 + ldxi_s %r0 %r0 $offs + beqi Ls %r0 XS + calli @abort +Ls: + movi %r0 t0 + ldxi_us %r0 %r0 $offus + beqi Lus %r0 0x8001 + calli @abort +Lus: + movi %r0 t0 + ldxi_i %r0 %r0 $offi + beqi Li %r0 XI + calli @abort +Li: +#if __WORDSIZE == 64 + movi %r0 t0 + ldxi_ui %r0 %r0 $offui + beqi Lui %r0 0x80000001 + calli @abort +Lui: + movi %r0 t0 + ldxi_l %r0 %r0 $offl + beqi Ll %r0 0x8000000000000001 + calli @abort +Ll: +#endif + + LDST(v0, v1, v2, r0, r1, r2) + // just to know did not abort + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/ldstxi.ok b/deps/lightning/check/ldstxi.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/ldstxi.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/ldstxi.tst b/deps/lightning/check/ldstxi.tst new file mode 100644 index 0000000..574521a --- /dev/null +++ b/deps/lightning/check/ldstxi.tst @@ -0,0 +1,154 @@ +#include "ldst.inc" + +#if __WORDSIZE == 64 +# define LDSTL(N, R0, R1) \ + stxi_i $offui %R0 %R1 \ + movi %R1 L##N \ + stxi_l $offl %R0 %R1 + +# define SI(C, N, x, X, R0, R1) \ + ldxi_##x %R1 %R0 $off##x \ + beqi L##x##C %R1 L##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0, R1) \ + UI(C, N, i, I, R0, R1) \ + SI(C, N, l, L, R0, R1) +#else +# define LDSTL(C, R0, R1) +# define SI(C, N, x, X, R0, R1) \ + ldxi_##x %R1 %R0 $off##x \ + beqi L##x##C %R1 I##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0, R1) + +#endif + +#define UI(C, N, x, X, R0, R1) \ + ldxi_u##x %R1 %R0 $offu##x \ + beqi Lu##x##C %R1 X##N \ + calli @abort \ +Lu##x##C: + +#define FF(C, N, x, X, R0, F0) \ + ldxi_##x %F0 %R0 $off##x \ + beqi_##x L##x##C %F0 X##N \ +L##x##C: + +#define LDST1(X, N, R0, R1, F0) \ + movi %R0 t0 \ + movi %R1 C##N \ + stxi_c $offc %R0 %R1 \ + stxi_c $offuc %R0 %R1 \ + movi %R1 S##N \ + stxi_s $offs %R0 %R1 \ + stxi_s $offus %R0 %R1 \ + movi %R1 I##N \ + stxi_i $offi %R0 %R1 \ + LDSTL(N, R0, R1) \ + movi_f %F0 F##N \ + stxi_f $offf %R0 %F0 \ + movi_d %F0 D##N \ + stxi_d $offd %R0 %F0 \ + SI(X, N, c, C, R0, R1) \ + UI(X, N, c, C, R0, R1) \ + SI(X, N, s, S, R0, R1) \ + UI(X, N, s, S, R0, R1) \ + SI(X, N, i, I, R0, R1) \ + LDRL(X, N, R0, R1) \ + FF(X, N, f, F, R0, F0) \ + FF(X, N, d, D, R0, F0) + +#define LDST0(R0, R1, F0) \ + LDST1(0_##R0##_##R1##_##F0, 0, R0, R1, F0) \ + LDST1(1_##R0##_##R1##_##F0, 1, R0, R1, F0) \ + LDST1(2_##R0##_##R1##_##F0, 2, R0, R1, F0) \ + LDST1(3_##R0##_##R1##_##F0, 3, R0, R1, F0) + +#define LDST(V0, V1, V2, R0, R1, R2, F0, F1, F2, F3, F4, F5) \ + LDST0(V0, V1, F0) \ + LDST0(V0, V2, F1) \ + LDST0(V0, R0, F3) \ + LDST0(V0, R1, F4) \ + LDST0(V0, R2, F5) \ + LDST0(V1, V2, F0) \ + LDST0(V1, R0, F1) \ + LDST0(V1, R1, F2) \ + LDST0(V1, R2, F3) \ + LDST0(V2, R0, F4) \ + LDST0(V2, R1, F5) \ + LDST0(V2, R2, F0) + +.code + prolog + + /* Simple test to simplify validating encodings before + * brute force tests */ + movi %r0 t0 + movi %r1 0x81 + stxi_c $offc %r0 %r1 + stxi_c $offuc %r0 %r1 + movi %r1 0x8001 + stxi_s $offs %r0 %r1 + stxi_s $offus %r0 %r1 + movi %r1 0x80000001 + stxi_i $offi %r0 %r1 +#if __WORDSIZE == 64 + stxi_i $offui %r0 %r1 + movi %r1 0x8000000000000001 + stxi_l $offl %r0 %r1 +#endif + movi_f %f0 0.5 + stxi_f $offf %r0 %f0 + movi_d %f0 0.25 + stxi_d $offd %r0 %f0 + ldxi_c %r1 %r0 $offc + beqi Lc %r1 XC + calli @abort +Lc: + ldxi_uc %r1 %r0 $offuc + beqi Luc %r1 0x81 + calli @abort +Luc: + ldxi_s %r1 %r0 $offs + beqi Ls %r1 XS + calli @abort +Ls: + ldxi_us %r1 %r0 $offus + beqi Lus %r1 0x8001 + calli @abort +Lus: + ldxi_i %r1 %r0 $offi + beqi Li %r1 XI + calli @abort +Li: +#if __WORDSIZE == 64 + ldxi_ui %r1 %r0 $offui + beqi Lui %r1 0x80000001 + calli @abort +Lui: + ldxi_l %r1 %r0 $offl + beqi Ll %r1 0x8000000000000001 + calli @abort +Ll: +#endif + ldxi_f %f0 %r0 $offf + beqi_f Lf %f0 0.5 + calli @abort +Lf: + ldxi_d %f0 %r0 $offd + beqi_d Ld %f0 0.25 + calli @abort +Ld: + + LDST(v0, v1, v2, r0, r1, r2, f0, f1, f2, f3, f4, f5) + // just to know did not abort + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/ldstxr-c.ok b/deps/lightning/check/ldstxr-c.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/ldstxr-c.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/ldstxr-c.tst b/deps/lightning/check/ldstxr-c.tst new file mode 100644 index 0000000..cd770a6 --- /dev/null +++ b/deps/lightning/check/ldstxr-c.tst @@ -0,0 +1,219 @@ +#include "ldst.inc" + +#if __WORDSIZE == 64 +# define LDSTL(N, R0, R1, R2) \ + movi %R2 $offui \ + stxr_i %R2 %R0 %R1 \ + movi %R1 L##N \ + movi %R2 $offl \ + stxr_l %R2 %R0 %R1 + +# define SI(C, N, x, X, R0, R1) \ + movi %R1 $off##x \ + ldxr_##x %R1 %R0 %R1 \ + beqi L##x##C##0 %R1 L##X##N \ + calli @abort \ +L##x##C##0: \ + movi %R1 $off##x \ + ldxr_##x %R0 %R0 %R1 \ + beqi L##x##C##1 %R0 L##X##N \ + calli @abort \ +L##x##C##1: + +# define LDRL(C, N, R0, R1, R2) \ + UI(C, N, i, I, R0, R1) \ + movi %R0 t0 \ + SI(C, N, l, L, R0, R1) +#else +# define LDSTL(C, R0, R1, R2) +# define SI(C, N, x, X, R0, R1) \ + movi %R1 $off##x \ + ldxr_##x %R1 %R0 %R1 \ + beqi L##x##C##0 %R1 I##X##N \ + calli @abort \ +L##x##C##0: \ + movi %R1 $off##x \ + ldxr_##x %R0 %R0 %R1 \ + beqi L##x##C##1 %R0 I##X##N \ + calli @abort \ +L##x##C##1: + +# define LDRL(C, N, R0, R1, R2) + +#endif + +#define UI(C, N, x, X, R0, R1) \ + movi %R1 $offu##x \ + ldxr_u##x %R1 %R0 %R1 \ + beqi Lu##x##C##0 %R1 X##N \ + calli @abort \ +Lu##x##C##0: \ + movi %R1 $offu##x \ + ldxr_u##x %R0 %R0 %R1 \ + beqi Lu##x##C##1 %R0 X##N \ + calli @abort \ +Lu##x##C##1: + +#define LDST1(X, N, R0, R1, R2) \ + movi %R0 t0 \ + movi %R1 C##N \ + movi %R2 $offc \ + stxr_c %R2 %R0 %R1 \ + movi %R2 $offuc \ + stxr_c %R2 %R0 %R1 \ + movi %R1 S##N \ + movi %R2 $offs \ + stxr_s %R2 %R0 %R1 \ + movi %R2 $offus \ + stxr_s %R2 %R0 %R1 \ + movi %R1 I##N \ + movi %R2 $offi \ + stxr_i %R2 %R0 %R1 \ + LDSTL(N, R0, R1, R2) \ + SI(X, N, c, C, R0, R1) \ + movi %R0 t0 \ + UI(X, N, c, C, R0, R1) \ + movi %R0 t0 \ + SI(X, N, s, S, R0, R1) \ + movi %R0 t0 \ + UI(X, N, s, S, R0, R1) \ + movi %R0 t0 \ + SI(X, N, i, I, R0, R1) \ + movi %R0 t0 \ + LDRL(X, N, R0, R1, R2) \ + +#define LDST0(R0, R1, R2) \ + LDST1(0_##R0##_##R1##_##R2, 0, R0, R1, R2) \ + LDST1(1_##R0##_##R1##_##R2, 1, R0, R1, R2) \ + LDST1(2_##R0##_##R1##_##R2, 2, R0, R1, R2) \ + LDST1(3_##R0##_##R1##_##R2, 3, R0, R1, R2) + +#define LDST(V0, V1, V2, R0, R1, R2) \ + LDST0(V1, V2, V0) \ + LDST0(V1, R0, V0) \ + LDST0(V1, R1, V0) \ + LDST0(V1, R2, V0) \ + LDST0(V0, R0, V1) \ + LDST0(V0, R1, V1) \ + LDST0(V0, R2, V1) \ + LDST0(V0, V2, V1) \ + LDST0(V2, V0, V1) \ + LDST0(V2, R0, V1) \ + LDST0(V2, R1, V1) \ + LDST0(V2, R2, V1) \ + LDST0(R0, R1, V2) \ + LDST0(R0, R2, V2) + +.code + prolog + + /* Simple test to simplify validating encodings before + * brute force tests */ + movi %r0 t0 + movi %r1 0x81 + movi %r2 $offc + stxr_c %r2 %r0 %r1 + movi %r2 $offuc + stxr_c %r2 %r0 %r1 + movi %r1 0x8001 + movi %r2 $offs + stxr_s %r2 %r0 %r1 + movi %r2 $offus + stxr_s %r2 %r0 %r1 + movi %r1 0x80000001 + movi %r2 $offi + stxr_i %r2 %r0 %r1 +#if __WORDSIZE == 64 + movi %r2 $offui + stxr_i %r2 %r0 %r1 + movi %r1 0x8000000000000001 + movi %r2 $offl + stxr_l %r2 %r0 %r1 +#endif + movi %r1 $offc + ldxr_c %r1 %r0 %r1 + beqi Lc0 %r1 XC + calli @abort +Lc0: + movi %r1 $offc + ldxr_c %r0 %r0 %r1 + beqi Lc1 %r0 XC + calli @abort +Lc1: + movi %r0 t0 + movi %r1 $offuc + ldxr_uc %r1 %r0 %r1 + beqi Luc0 %r1 0x81 + calli @abort +Luc0: + movi %r1 $offuc + ldxr_uc %r0 %r0 %r1 + beqi Luc1 %r0 0x81 + calli @abort +Luc1: + movi %r0 t0 + movi %r1 $offs + ldxr_s %r1 %r0 %r1 + beqi Ls0 %r1 XS + calli @abort +Ls0: + movi %r1 $offs + ldxr_s %r0 %r0 %r1 + beqi Ls1 %r0 XS + calli @abort +Ls1: + movi %r0 t0 + movi %r1 $offus + ldxr_us %r1 %r0 %r1 + beqi Lus0 %r1 0x8001 + calli @abort +Lus0: + movi %r1 $offus + ldxr_us %r0 %r0 %r1 + beqi Lus1 %r0 0x8001 + calli @abort +Lus1: + movi %r0 t0 + movi %r1 $offi + ldxr_i %r1 %r0 %r1 + beqi Li0 %r1 XI + calli @abort +Li0: + movi %r1 $offi + ldxr_i %r0 %r0 %r1 + beqi Li1 %r0 XI + calli @abort +Li1: +#if __WORDSIZE == 64 + movi %r0 t0 + movi %r1 $offui + ldxr_ui %r1 %r0 %r1 + beqi Lui0 %r1 0x80000001 + calli @abort +Lui0: + movi %r1 $offui + ldxr_ui %r0 %r0 %r1 + beqi Lui1 %r0 0x80000001 + calli @abort +Lui1: + movi %r0 t0 + movi %r1 $offl + ldxr_l %r1 %r0 %r1 + beqi Ll0 %r1 0x8000000000000001 + calli @abort +Ll0: + movi %r1 $offl + ldxr_l %r0 %r0 %r1 + beqi Ll1 %r0 0x8000000000000001 + calli @abort +Ll1: +#endif + + LDST(v0, v1, v2, r0, r1, r2) + // just to know did not abort + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/ldstxr.ok b/deps/lightning/check/ldstxr.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/ldstxr.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/ldstxr.tst b/deps/lightning/check/ldstxr.tst new file mode 100644 index 0000000..14620dc --- /dev/null +++ b/deps/lightning/check/ldstxr.tst @@ -0,0 +1,209 @@ +#include "ldst.inc" + +#if __WORDSIZE == 64 +# define LDSTL(N, R0, R1, R2) \ + movi %R2 $offui \ + stxr_i %R2 %R0 %R1 \ + movi %R1 L##N \ + movi %R2 $offl \ + stxr_l %R2 %R0 %R1 + +# define SI(C, N, x, X, R0, R1, R2) \ + movi %R2 $off##x \ + ldxr_##x %R1 %R0 %R2 \ + beqi L##x##C %R1 L##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0, R1, R2) \ + UI(C, N, i, I, R0, R1, R2) \ + SI(C, N, l, L, R0, R1, R2) +#else +# define LDSTL(C, R0, R1, R2) +# define SI(C, N, x, X, R0, R1, R2) \ + movi %R2 $off##x \ + ldxr_##x %R1 %R0 %R2 \ + beqi L##x##C %R1 I##X##N \ + calli @abort \ +L##x##C: + +# define LDRL(C, N, R0, R1, R2) + +#endif + +#define UI(C, N, x, X, R0, R1, R2) \ + movi %R2 $offu##x \ + ldxr_u##x %R1 %R0 %R2 \ + beqi Lu##x##C %R1 X##N \ + calli @abort \ +Lu##x##C: + +#define FF(C, N, x, X, R0, R1, F0) \ + movi %R1 $off##x \ + ldxr_##x %F0 %R0 %R1 \ + beqi_##x L##x##C %F0 X##N \ +L##x##C: + +#define LDST1(X, N, R0, R1, R2, F0) \ + movi %R0 t0 \ + movi %R1 C##N \ + movi %R2 $offc \ + stxr_c %R2 %R0 %R1 \ + movi %R2 $offuc \ + stxr_c %R2 %R0 %R1 \ + movi %R1 S##N \ + movi %R2 $offs \ + stxr_s %R2 %R0 %R1 \ + movi %R2 $offus \ + stxr_s %R2 %R0 %R1 \ + movi %R1 I##N \ + movi %R2 $offi \ + stxr_i %R2 %R0 %R1 \ + LDSTL(N, R0, R1, R2) \ + movi_f %F0 F##N \ + movi %R2 $offf \ + stxr_f %R2 %R0 %F0 \ + movi_d %F0 D##N \ + movi %R2 $offd \ + stxr_d %R2 %R0 %F0 \ + SI(X, N, c, C, R0, R1, R2) \ + UI(X, N, c, C, R0, R1, R2) \ + SI(X, N, s, S, R0, R1, R2) \ + UI(X, N, s, S, R0, R1, R2) \ + SI(X, N, i, I, R0, R1, R2) \ + LDRL(X, N, R0, R1, R2) \ + FF(X, N, f, F, R0, R1, F0) \ + FF(X, N, d, D, R0, R1, F0) + +#define LDST0(R0, R1, R2, F0) \ + LDST1(0_##R0##_##R1##_##R2##_##F0, 0, R0, R1, R2, F0) \ + LDST1(1_##R0##_##R1##_##R2##_##F0, 1, R0, R1, R2, F0) \ + LDST1(2_##R0##_##R1##_##R2##_##F0, 2, R0, R1, R2, F0) \ + LDST1(3_##R0##_##R1##_##R2##_##F0, 3, R0, R1, R2, F0) + +#define LDST(V0, V1, V2, R0, R1, R2, F0, F1, F2, F3, F4, F5) \ + LDST0(V0, V1, R0, F0) \ + LDST0(V0, V1, R1, F1) \ + LDST0(V0, V1, R2, F2) \ + LDST0(V0, V2, R0, F3) \ + LDST0(V0, V2, R1, F4) \ + LDST0(V0, V2, R2, F5) \ + LDST0(V0, R0, V1, F0) \ + LDST0(V0, R0, V2, F1) \ + LDST0(V0, R0, R1, F2) \ + LDST0(V0, R0, R2, F3) \ + LDST0(V0, R0, V1, F4) \ + LDST0(V0, R1, V1, F5) \ + LDST0(V0, R1, V2, F0) \ + LDST0(V0, R1, R0, F1) \ + LDST0(V0, R1, R2, F2) \ + LDST0(V0, V1, V2, F3) \ + LDST0(V0, R1, R0, F4) \ + LDST0(V0, R1, R2, F5) \ + LDST0(R0, V1, V0, F0) \ + LDST0(R0, V1, R1, F1) \ + LDST0(R0, V1, R2, F2) \ + LDST0(R0, V2, V0, F3) \ + LDST0(R0, V2, R1, F4) \ + LDST0(R0, V2, R2, F5) \ + LDST0(R0, V0, V1, F0) \ + LDST0(R0, V0, V2, F1) \ + LDST0(R0, V0, R1, F2) \ + LDST0(R0, V0, R2, F3) \ + LDST0(R0, V0, V1, F4) \ + LDST0(R0, R1, V1, F5) \ + LDST0(R0, R1, V2, F0) \ + LDST0(R0, R1, V0, F1) \ + LDST0(R0, R1, R2, F2) \ + LDST0(R0, V1, V2, F3) \ + LDST0(R0, R1, V0, F4) \ + LDST0(R0, R1, R2, F5) + +.code + prolog + + /* Simple test to simplify validating encodings before + * brute force tests */ + movi %r0 t0 + movi %r1 0x81 + movi %r2 $offc + stxr_c %r2 %r0 %r1 + movi %r2 $offuc + stxr_c %r2 %r0 %r1 + movi %r1 0x8001 + movi %r2 $offs + stxr_s %r2 %r0 %r1 + movi %r2 $offus + stxr_s %r2 %r0 %r1 + movi %r1 0x80000001 + movi %r2 $offi + stxr_i %r2 %r0 %r1 +#if __WORDSIZE == 64 + movi %r2 $offui + stxr_i %r2 %r0 %r1 + movi %r1 0x8000000000000001 + movi %r2 $offl + stxr_l %r2 %r0 %r1 +#endif + movi_f %f0 0.5 + movi %r2 $offf + stxr_f %r2 %r0 %f0 + movi_d %f0 0.25 + movi %r2 $offd + stxr_d %r2 %r0 %f0 + movi %r2 $offc + ldxr_c %r1 %r0 %r2 + beqi Lc %r1 XC + calli @abort +Lc: + movi %r2 $offuc + ldxr_uc %r1 %r0 %r2 + beqi Luc %r1 0x81 + calli @abort +Luc: + movi %r2 $offs + ldxr_s %r1 %r0 %r2 + beqi Ls %r1 XS + calli @abort +Ls: + movi %r2 $offus + ldxr_us %r1 %r0 %r2 + beqi Lus %r1 0x8001 + calli @abort +Lus: + movi %r2 $offi + ldxr_i %r1 %r0 %r2 + beqi Li %r1 XI + calli @abort +Li: +#if __WORDSIZE == 64 + movi %r2 $offui + ldxr_ui %r1 %r0 %r2 + beqi Lui %r1 0x80000001 + calli @abort +Lui: + movi %r2 $offl + ldxr_l %r1 %r0 %r2 + beqi Ll %r1 0x8000000000000001 + calli @abort +Ll: +#endif + movi %r2 $offf + ldxr_f %f0 %r0 %r2 + beqi_f Lf %f0 0.5 + calli @abort +Lf: + movi %r2 $offd + ldxr_d %f0 %r0 %r2 + beqi_d Ld %f0 0.25 + calli @abort +Ld: + + LDST(v0, v1, v2, r0, r1, r2, f0, f1, f2, f3, f4, f5) + // just to know did not abort + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/lightning.c b/deps/lightning/check/lightning.c new file mode 100644 index 0000000..e60ef05 --- /dev/null +++ b/deps/lightning/check/lightning.c @@ -0,0 +1,4329 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#if HAVE_GETOPT_H +# include <getopt.h> +#else +# include <unistd.h> +#endif +#include <stdio.h> +#include <stdarg.h> +#include <lightning.h> +#include <dlfcn.h> + +#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) +# include <fpu_control.h> +#endif + +/* The label_t identifier clashes with a system definitions */ +#if defined(_AIX) || defined(__sun__) || defined(__osf__) +# define label_t l_label_t +#endif + +#if defined(__hpux) +# define DL_HANDLE RTLD_NEXT +#elif defined(__sgi) +static void *DL_HANDLE; +#elif defined(__osf__) +# define DL_HANDLE NULL +#else +# define DL_HANDLE RTLD_DEFAULT +#endif + +#if defined(__GNUC__) +# define noreturn __attribute__ ((noreturn)) +# define printf_format(f, v) __attribute__ ((format (printf, f, v))) +# define maybe_unused __attribute__ ((unused)) +#else +# define noreturn /**/ +# define printf_format(f, v) /**/ +# define maybe_unused /**/ +#endif + +#define check_data(length) \ + do { \ + if (data_offset + length > data_length) \ + error(".data too small (%ld < %ld)", \ + data_length, data_offset + length); \ + } while (0) + +#define get_label_by_name(name) ((label_t *)get_hash(labels, name)) + +#define PARSING_NONE 0 +#define PARSING_DATA 1 +#define PARSING_CODE 2 +#define MAX_IDENTIFIER 256 + +/* + * Types + */ +typedef struct instr instr_t; +typedef union value value_t; +typedef struct parser parser_t; +typedef struct label label_t; +typedef struct patch patch_t; +typedef struct symbol symbol_t; +typedef struct hash hash_t; +typedef struct entry entry_t; +typedef int (*function_t)(int argc, char *argv[]); + +typedef enum { + tok_eof = -1, + tok_symbol, + tok_char, + tok_int, + tok_float, + tok_pointer, + tok_string, + tok_register, + tok_dot, + tok_newline, + tok_semicollon, +} token_t; + +typedef enum { + skip_none, + skip_ws, + skip_nl, +} skip_t; + +typedef enum { + type_none, + type_c, + type_s, + type_i, + type_l, + type_f, + type_d, + type_p, +} type_t; + +#define compose(a, b) (((a) << 8) | b) +typedef enum { + expr_inc = compose('+', '+'), + expr_dec = compose('-', '-'), + expr_not = '!', + expr_com = '~', + expr_mul = '*', + expr_div = '/', + expr_rem = '%', + expr_add = '+', + expr_sub = '-', + expr_lsh = compose('<', '<'), + expr_rsh = compose('>', '>'), + expr_and = '&', + expr_or = '|', + expr_xor = '^', + expr_set = '=', + expr_mulset = compose('*', '='), + expr_divset = compose('/', '='), + expr_remset = compose('%', '='), + expr_addset = compose('+', '='), + expr_subset = compose('-', '='), + expr_lshset = compose(expr_lsh, '='), + expr_rshset = compose(expr_rsh, '='), + expr_andset = compose('&', '='), + expr_orset = compose('|', '='), + expr_xorset = compose('^', '='), + expr_lt = '<', + expr_le = compose('<', '='), + expr_eq = compose('=', '='), + expr_ne = compose('!', '='), + expr_gt = '>', + expr_ge = compose('>', '='), + expr_andand = compose('&', '&'), + expr_oror = compose('|', '|'), + expr_lparen = '(', + expr_rparen = ')', + expr_int = '0', + expr_float = '.', + expr_pointer = '@', + expr_symbol = '$', +} expr_t; +#undef compose + +struct instr { + instr_t *next; + const char *name; + void (*function)(void); + int flag; +}; + +union value { + jit_word_t i; + jit_uword_t ui; + float f; + double d; + void *p; + char *cp; + label_t *label; + patch_t *patch; +}; + +struct parser { + FILE *fp; + char name[256]; + int line; + int regval; + type_t regtype; + expr_t expr; + type_t type; + value_t value; + + /* variable length string buffer */ + char *string; + int length; + int offset; + + int newline; + expr_t putback; + int short_circuit; + int parsing; + + struct { + unsigned char buffer[4096]; + int offset; + int length; + } data; +}; + +typedef enum { + label_kind_data, + label_kind_code, + label_kind_code_forward, + label_kind_dynamic, +} label_kind_t; + +struct hash { + entry_t **entries; + int size; + int count; +}; + +struct entry { + entry_t *next; + char *name; + void *value; + int flag; +}; + +struct label { + label_t *next; + char *name; + void *value; + label_kind_t kind; +}; + +typedef enum { + patch_kind_jmp, + patch_kind_mov, + patch_kind_call, +} patch_kind_t; + +struct patch { + patch_t *next; + label_t *label; + void *value; + patch_kind_t kind; +}; + +/* minor support for expressions */ +struct symbol { + symbol_t *next; + char *name; + value_t value; + type_t type; +}; + +/* + * Prototypes + */ +static jit_gpr_t get_ireg(void); +static jit_fpr_t get_freg(void); +static symbol_t *get_symbol(void); +static void jmp_forward(void *value, label_t *label); +static void mov_forward(void *value, label_t *label); +static void call_forward(void *value, label_t *label); +static void make_arg(void *value); +static jit_pointer_t get_arg(void); +static jit_word_t get_imm(void); +static void live(void); +static void align(void); static void name(void); +static void prolog(void); +static void frame(void); static void tramp(void); +static void ellipsis(void); +static void allocai(void); static void allocar(void); +static void arg(void); +static void getarg_c(void); static void getarg_uc(void); +static void getarg_s(void); static void getarg_us(void); +static void getarg_i(void); +#if __WORDSIZE == 64 +static void getarg_ui(void); static void getarg_l(void); +#endif +static void getarg(void); +static void putargr(void); static void putargi(void); +static void addr(void); static void addi(void); +static void addxr(void); static void addxi(void); +static void addcr(void); static void addci(void); +static void subr(void); static void subi(void); +static void subxr(void); static void subxi(void); +static void subcr(void); static void subci(void); +static void rsbr(void); static void rsbi(void); +static void mulr(void); static void muli(void); +static void qmulr(void); static void qmuli(void); +static void qmulr_u(void); static void qmuli_u(void); +static void divr(void); static void divi(void); +static void divr_u(void); static void divi_u(void); +static void qdivr(void); static void qdivi(void); +static void qdivr_u(void); static void qdivi_u(void); +static void remr(void); static void remi(void); +static void remr_u(void); static void remi_u(void); +static void andr(void); static void andi(void); +static void orr(void); static void ori(void); +static void xorr(void); static void xori(void); +static void lshr(void); static void lshi(void); +static void rshr(void); static void rshi(void); +static void rshr_u(void); static void rshi_u(void); +static void negr(void); static void comr(void); +static void ltr(void); static void lti(void); +static void ltr_u(void); static void lti_u(void); +static void ler(void); static void lei(void); +static void ler_u(void); static void lei_u(void); +static void eqr(void); static void eqi(void); +static void ger(void); static void gei(void); +static void ger_u(void); static void gei_u(void); +static void gtr(void); static void gti(void); +static void gtr_u(void); static void gti_u(void); +static void ner(void); static void nei(void); +static void movr(void); static void movi(void); +static void extr_c(void); static void extr_uc(void); +static void extr_s(void); static void extr_us(void); +#if __WORDSIZE == 64 +static void extr_i(void); static void extr_ui(void); +#endif +static void htonr_us(void); static void ntohr_us(void); +static void htonr_ui(void); static void ntohr_ui(void); +#if __WORDSIZE == 64 +static void htonr_ul(void); static void ntohr_ul(void); +#endif +static void htonr(void); static void ntohr(void); +static void ldr_c(void); static void ldi_c(void); +static void ldr_uc(void); static void ldi_uc(void); +static void ldr_s(void); static void ldi_s(void); +static void ldr_us(void); static void ldi_us(void); +static void ldr_i(void); static void ldi_i(void); +#if __WORDSIZE == 64 +static void ldr_ui(void); static void ldi_ui(void); +static void ldr_l(void); static void ldi_l(void); +#endif +static void ldr(void); static void ldi(void); +static void ldxr_c(void); static void ldxi_c(void); +static void ldxr_uc(void); static void ldxi_uc(void); +static void ldxr_s(void); static void ldxi_s(void); +static void ldxr_us(void); static void ldxi_us(void); +static void ldxr_i(void); static void ldxi_i(void); +#if __WORDSIZE == 64 +static void ldxr_ui(void); static void ldxi_ui(void); +static void ldxr_l(void); static void ldxi_l(void); +#endif +static void ldxr(void); static void ldxi(void); +static void str_c(void); static void sti_c(void); +static void str_s(void); static void sti_s(void); +static void str_i(void); static void sti_i(void); +#if __WORDSIZE == 64 +static void str_l(void); static void sti_l(void); +#endif +static void str(void); static void sti(void); +static void stxr_c(void); static void stxi_c(void); +static void stxr_s(void); static void stxi_s(void); +static void stxr_i(void); static void stxi_i(void); +#if __WORDSIZE == 64 +static void stxr_l(void); static void stxi_l(void); +#endif +static void stxr(void); static void stxi(void); +static void bltr(void); static void blti(void); +static void bltr_u(void); static void blti_u(void); +static void bler(void); static void blei(void); +static void bler_u(void); static void blei_u(void); +static void beqr(void); static void beqi(void); +static void bger(void); static void bgei(void); +static void bger_u(void); static void bgei_u(void); +static void bgtr(void); static void bgti(void); +static void bgtr_u(void); static void bgti_u(void); +static void bner(void); static void bnei(void); +static void bmsr(void); static void bmsi(void); +static void bmcr(void); static void bmci(void); +static void boaddr(void); static void boaddi(void); +static void boaddr_u(void); static void boaddi_u(void); +static void bxaddr(void); static void bxaddi(void); +static void bxaddr_u(void); static void bxaddi_u(void); +static void bosubr(void); static void bosubi(void); +static void bosubr_u(void); static void bosubi_u(void); +static void bxsubr(void); static void bxsubi(void); +static void bxsubr_u(void); static void bxsubi_u(void); +static void jmpr(void); static void jmpi(void); +static void callr(void); static void calli(void); +static void prepare(void); +static void pushargr(void); static void pushargi(void); +static void finishr(void); static void finishi(void); +static void ret(void); +static void retr(void); static void reti(void); +static void retval_c(void); static void retval_uc(void); +static void retval_s(void); static void retval_us(void); +static void retval_i(void); +#if __WORDSIZE == 64 +static void retval_ui(void); static void retval_l(void); +#endif +static void retval(void); +static void epilog(void); +static void arg_f(void); static void getarg_f(void); +static void putargr_f(void); static void putargi_f(void); +static void addr_f(void); static void addi_f(void); +static void subr_f(void); static void subi_f(void); +static void rsbr_f(void); static void rsbi_f(void); +static void mulr_f(void); static void muli_f(void); +static void divr_f(void); static void divi_f(void); +static void negr_f(void); static void absr_f(void); +static void sqrtr_f(void); +static void ltr_f(void); static void lti_f(void); +static void ler_f(void); static void lei_f(void); +static void eqr_f(void); static void eqi_f(void); +static void ger_f(void); static void gei_f(void); +static void gtr_f(void); static void gti_f(void); +static void ner_f(void); static void nei_f(void); +static void unltr_f(void); static void unlti_f(void); +static void unler_f(void); static void unlei_f(void); +static void uneqr_f(void); static void uneqi_f(void); +static void unger_f(void); static void ungei_f(void); +static void ungtr_f(void); static void ungti_f(void); +static void ltgtr_f(void); static void ltgti_f(void); +static void ordr_f(void); static void ordi_f(void); +static void unordr_f(void); static void unordi_f(void); +static void truncr_f_i(void); +#if __WORDSIZE == 64 +static void truncr_f_l(void); +#endif +static void truncr_f(void); +static void extr_f(void); static void extr_d_f(void); +static void movr_f(void); static void movi_f(void); +static void ldr_f(void); static void ldi_f(void); +static void ldxr_f(void); static void ldxi_f(void); +static void str_f(void); static void sti_f(void); +static void stxr_f(void); static void stxi_f(void); +static void bltr_f(void); static void blti_f(void); +static void bler_f(void); static void blei_f(void); +static void beqr_f(void); static void beqi_f(void); +static void bger_f(void); static void bgei_f(void); +static void bgtr_f(void); static void bgti_f(void); +static void bner_f(void); static void bnei_f(void); +static void bunltr_f(void); static void bunlti_f(void); +static void bunler_f(void); static void bunlei_f(void); +static void buneqr_f(void); static void buneqi_f(void); +static void bunger_f(void); static void bungei_f(void); +static void bungtr_f(void); static void bungti_f(void); +static void bltgtr_f(void); static void bltgti_f(void); +static void bordr_f(void); static void bordi_f(void); +static void bunordr_f(void); static void bunordi_f(void); +static void pushargr_f(void); static void pushargi_f(void); +static void retr_f(void); static void reti_f(void); +static void retval_f(void); +static void arg_d(void); static void getarg_d(void); +static void putargr_d(void); static void putargi_d(void); +static void addr_d(void); static void addi_d(void); +static void subr_d(void); static void subi_d(void); +static void rsbr_d(void); static void rsbi_d(void); +static void mulr_d(void); static void muli_d(void); +static void divr_d(void); static void divi_d(void); +static void negr_d(void); static void absr_d(void); +static void sqrtr_d(void); +static void ltr_d(void); static void lti_d(void); +static void ler_d(void); static void lei_d(void); +static void eqr_d(void); static void eqi_d(void); +static void ger_d(void); static void gei_d(void); +static void gtr_d(void); static void gti_d(void); +static void ner_d(void); static void nei_d(void); +static void unltr_d(void); static void unlti_d(void); +static void unler_d(void); static void unlei_d(void); +static void uneqr_d(void); static void uneqi_d(void); +static void unger_d(void); static void ungei_d(void); +static void ungtr_d(void); static void ungti_d(void); +static void ltgtr_d(void); static void ltgti_d(void); +static void ordr_d(void); static void ordi_d(void); +static void unordr_d(void); static void unordi_d(void); +static void truncr_d_i(void); +#if __WORDSIZE == 64 +static void truncr_d_l(void); +#endif +static void truncr_d(void); +static void extr_d(void); static void extr_f_d(void); +static void movr_d(void); static void movi_d(void); +static void ldr_d(void); static void ldi_d(void); +static void ldxr_d(void); static void ldxi_d(void); +static void str_d(void); static void sti_d(void); +static void stxr_d(void); static void stxi_d(void); +static void bltr_d(void); static void blti_d(void); +static void bler_d(void); static void blei_d(void); +static void beqr_d(void); static void beqi_d(void); +static void bger_d(void); static void bgei_d(void); +static void bgtr_d(void); static void bgti_d(void); +static void bner_d(void); static void bnei_d(void); +static void bunltr_d(void); static void bunlti_d(void); +static void bunler_d(void); static void bunlei_d(void); +static void buneqr_d(void); static void buneqi_d(void); +static void bunger_d(void); static void bungei_d(void); +static void bungtr_d(void); static void bungti_d(void); +static void bltgtr_d(void); static void bltgti_d(void); +static void bordr_d(void); static void bordi_d(void); +static void bunordr_d(void); static void bunordi_d(void); +static void pushargr_d(void); static void pushargi_d(void); +static void retr_d(void); static void reti_d(void); +static void retval_d(void); +static void vastart(void); static void vapush(void); +static void vaarg(void); static void vaarg_d(void); +static void vaend(void); + +static void error(const char *format, ...) noreturn printf_format(1, 2); +static void warn(const char *format, ...) printf_format(1, 2) maybe_unused; +static void message(const char *kind, const char *format, va_list ap); + +static int getch(void); +static int getch_noeof(void); +static int ungetch(int ch); +static int skipws(void); +static int skipnl(void); +static int skipct(void); +static int skipcp(void); +static jit_word_t get_int(skip_t skip); +static jit_uword_t get_uint(skip_t skip); +static double get_float(skip_t skip); +static float make_float(double d); +static void *get_pointer(skip_t skip); +static label_t *get_label(skip_t skip); +static token_t regname(void); +static token_t identifier(int ch); +static void get_data(type_t type); +static void dot(void); +static token_t number(int ch); +static int escape(int ch); +static token_t string(void); +static token_t dynamic(void); +static token_t character(void); +static void expression_prim(void); +static void expression_inc(int pre); +static void expression_dec(int pre); +static void expression_unary(void); +static void expression_mul(void); +static void expression_add(void); +static void expression_shift(void); +static void expression_bit(void); +static void expression_rel(void); +static void expression_cond(void); +static token_t expression(void); +static token_t primary(skip_t skip); +static void parse(void); +static int execute(int argc, char *argv[]); + +static void *xmalloc(size_t size); +static void *xrealloc(void *pointer, size_t size); +static void *xcalloc(size_t nmemb, size_t size); + +static label_t *new_label(label_kind_t kind, char *name, void *value); +static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value); +static int bcmp_symbols(const void *left, const void *right); +static int qcmp_symbols(const void *left, const void *right); +static symbol_t *new_symbol(char *name); +static symbol_t *get_symbol_by_name(char *name); + +static hash_t *new_hash(void); +static int hash_string(char *name); +static void put_hash(hash_t *hash, entry_t *entry); +static entry_t *get_hash(hash_t *hash, char *name); +static void rehash(hash_t *hash); + +/* + * Initialization + */ +static jit_state_t *_jit; +static int flag_verbose; +static int flag_data; +static int flag_disasm; +static char *progname; +static parser_t parser; +static hash_t *labels; +static int label_offset; +static patch_t *patches; +static symbol_t **symbols; +static int symbol_length; +static int symbol_offset; +static hash_t *instrs; +static char *data; +static size_t data_offset, data_length; +static instr_t instr_vector[] = { +#define entry(value) { NULL, #value, value } +#define entry2(name, function) { NULL, name, function } + entry(live), + entry(align), entry(name), + entry(prolog), + entry(frame), entry(tramp), + entry(ellipsis), + entry(allocai), entry(allocar), + entry(arg), + entry(getarg_c), entry(getarg_uc), + entry(getarg_s), entry(getarg_us), + entry(getarg_i), +#if __WORDSIZE == 64 + entry(getarg_ui), entry(getarg_l), +#endif + entry(getarg), + entry(putargr), entry(putargi), + entry(addr), entry(addi), + entry(addxr), entry(addxi), + entry(addcr), entry(addci), + entry(subr), entry(subi), + entry(subxr), entry(subxi), + entry(subcr), entry(subci), + entry(rsbr), entry(rsbi), + entry(mulr), entry(muli), + entry(qmulr), entry(qmuli), + entry(qmulr_u), entry(qmuli_u), + entry(divr), entry(divi), + entry(divr_u), entry(divi_u), + entry(qdivr), entry(qdivi), + entry(qdivr_u), entry(qdivi_u), + entry(remr), entry(remi), + entry(remr_u), entry(remi_u), + entry(andr), entry(andi), + entry(orr), entry(ori), + entry(xorr), entry(xori), + entry(lshr), entry(lshi), + entry(rshr), entry(rshi), + entry(rshr_u), entry(rshi_u), + entry(negr), entry(comr), + entry(ltr), entry(lti), + entry(ltr_u), entry(lti_u), + entry(ler), entry(lei), + entry(ler_u), entry(lei_u), + entry(eqr), entry(eqi), + entry(ger), entry(gei), + entry(ger_u), entry(gei_u), + entry(gtr), entry(gti), + entry(gtr_u), entry(gti_u), + entry(ner), entry(nei), + entry(movr), entry(movi), + entry(extr_c), entry(extr_uc), + entry(extr_s), entry(extr_us), +#if __WORDSIZE == 64 + entry(extr_i), entry(extr_ui), +#endif + entry(htonr_us), entry(ntohr_us), + entry(htonr_ui), entry(ntohr_ui), +#if __WORDSIZE == 64 + entry(htonr_ul), entry(ntohr_ul), +#endif + entry(htonr), entry(ntohr), + entry(ldr_c), entry(ldi_c), + entry(ldr_uc), entry(ldi_uc), + entry(ldr_s), entry(ldi_s), + entry(ldr_us), entry(ldi_us), + entry(ldr_i), entry(ldi_i), +#if __WORDSIZE == 64 + entry(ldr_ui), entry(ldi_ui), + entry(ldr_l), entry(ldi_l), +#endif + entry(ldr), entry(ldi), + entry(ldxr_c), entry(ldxi_c), + entry(ldxr_uc), entry(ldxi_uc), + entry(ldxr_s), entry(ldxi_s), + entry(ldxr_us), entry(ldxi_us), + entry(ldxr_i), entry(ldxi_i), +#if __WORDSIZE == 64 + entry(ldxr_ui), entry(ldxi_ui), + entry(ldxr_l), entry(ldxi_l), +#endif + entry(ldxr), entry(ldxi), + entry(str_c), entry(sti_c), + entry(str_s), entry(sti_s), + entry(str_i), entry(sti_i), +#if __WORDSIZE == 64 + entry(str_l), entry(sti_l), +#endif + entry(str), entry(sti), + entry(stxr_c), entry(stxi_c), + entry(stxr_s), entry(stxi_s), + entry(stxr_i), entry(stxi_i), +#if __WORDSIZE == 64 + entry(stxr_l), entry(stxi_l), +#endif + entry(stxr), entry(stxi), + entry(bltr), entry(blti), + entry(bltr_u), entry(blti_u), + entry(bler), entry(blei), + entry(bler_u), entry(blei_u), + entry(beqr), entry(beqi), + entry(bger), entry(bgei), + entry(bger_u), entry(bgei_u), + entry(bgtr), entry(bgti), + entry(bgtr_u), entry(bgti_u), + entry(bner), entry(bnei), + entry(bmsr), entry(bmsi), + entry(bmcr), entry(bmci), + entry(boaddr), entry(boaddi), + entry(boaddr_u), entry(boaddi_u), + entry(bxaddr), entry(bxaddi), + entry(bxaddr_u), entry(bxaddi_u), + entry(bosubr), entry(bosubi), + entry(bosubr_u), entry(bosubi_u), + entry(bxsubr), entry(bxsubi), + entry(bxsubr_u), entry(bxsubi_u), + entry(jmpr), entry(jmpi), + entry(callr), entry(calli), + entry(prepare), + entry(pushargr), entry(pushargi), + entry(finishr), entry(finishi), + entry(ret), + entry(retr), entry(reti), + entry(retval_c), entry(retval_uc), + entry(retval_s), entry(retval_us), + entry(retval_i), +#if __WORDSIZE == 64 + entry(retval_ui), entry(retval_l), +#endif + entry(retval), + entry(epilog), + entry(arg_f), entry(getarg_f), + entry(putargr_f), entry(putargi_f), + entry(addr_f), entry(addi_f), + entry(subr_f), entry(subi_f), + entry(rsbr_f), entry(rsbi_f), + entry(mulr_f), entry(muli_f), + entry(divr_f), entry(divi_f), + entry(negr_f), entry(absr_f), + entry(sqrtr_f), + entry(ltr_f), entry(lti_f), + entry(ler_f), entry(lei_f), + entry(eqr_f), entry(eqi_f), + entry(ger_f), entry(gei_f), + entry(gtr_f), entry(gti_f), + entry(ner_f), entry(nei_f), + entry(unltr_f), entry(unlti_f), + entry(unler_f), entry(unlei_f), + entry(uneqr_f), entry(uneqi_f), + entry(unger_f), entry(ungei_f), + entry(ungtr_f), entry(ungti_f), + entry(ltgtr_f), entry(ltgti_f), + entry(ordr_f), entry(ordi_f), + entry(unordr_f), entry(unordi_f), + entry(truncr_f_i), +#if __WORDSIZE == 64 + entry(truncr_f_l), +#endif + entry(truncr_f), + entry(extr_f), entry(extr_d_f), + entry(movr_f), entry(movi_f), + entry(ldr_f), entry(ldi_f), + entry(ldxr_f), entry(ldxi_f), + entry(str_f), entry(sti_f), + entry(stxr_f), entry(stxi_f), + entry(bltr_f), entry(blti_f), + entry(bler_f), entry(blei_f), + entry(beqr_f), entry(beqi_f), + entry(bger_f), entry(bgei_f), + entry(bgtr_f), entry(bgti_f), + entry(bner_f), entry(bnei_f), + entry(bunltr_f), entry(bunlti_f), + entry(bunler_f), entry(bunlei_f), + entry(buneqr_f), entry(buneqi_f), + entry(bunger_f), entry(bungei_f), + entry(bungtr_f), entry(bungti_f), + entry(bltgtr_f), entry(bltgti_f), + entry(bordr_f), entry(bordi_f), + entry(bunordr_f), entry(bunordi_f), + entry(pushargr_f), entry(pushargi_f), + entry(retr_f), entry(reti_f), + entry(retval_f), + entry(arg_d), entry(getarg_d), + entry(putargr_d), entry(putargi_d), + entry(addr_d), entry(addi_d), + entry(subr_d), entry(subi_d), + entry(rsbr_d), entry(rsbi_d), + entry(mulr_d), entry(muli_d), + entry(divr_d), entry(divi_d), + entry(negr_d), entry(absr_d), + entry(sqrtr_d), + entry(ltr_d), entry(lti_d), + entry(ler_d), entry(lei_d), + entry(eqr_d), entry(eqi_d), + entry(ger_d), entry(gei_d), + entry(gtr_d), entry(gti_d), + entry(ner_d), entry(nei_d), + entry(unltr_d), entry(unlti_d), + entry(unler_d), entry(unlei_d), + entry(uneqr_d), entry(uneqi_d), + entry(unger_d), entry(ungei_d), + entry(ungtr_d), entry(ungti_d), + entry(ltgtr_d), entry(ltgti_d), + entry(ordr_d), entry(ordi_d), + entry(unordr_d), entry(unordi_d), + entry(truncr_d_i), +#if __WORDSIZE == 64 + entry(truncr_d_l), +#endif + entry(truncr_d), + entry(extr_d), entry(extr_f_d), + entry(movr_d), entry(movi_d), + entry(ldr_d), entry(ldi_d), + entry(ldxr_d), entry(ldxi_d), + entry(str_d), entry(sti_d), + entry(stxr_d), entry(stxi_d), + entry(bltr_d), entry(blti_d), + entry(bler_d), entry(blei_d), + entry(beqr_d), entry(beqi_d), + entry(bger_d), entry(bgei_d), + entry(bgtr_d), entry(bgti_d), + entry(bner_d), entry(bnei_d), + entry(bunltr_d), entry(bunlti_d), + entry(bunler_d), entry(bunlei_d), + entry(buneqr_d), entry(buneqi_d), + entry(bunger_d), entry(bungei_d), + entry(bungtr_d), entry(bungti_d), + entry(bltgtr_d), entry(bltgti_d), + entry(bordr_d), entry(bordi_d), + entry(bunordr_d), entry(bunordi_d), + entry(pushargr_d), entry(pushargi_d), + entry(retr_d), entry(reti_d), + entry(retval_d), + entry2("va_start", vastart), + entry2("va_push", vapush), + entry2("va_arg", vaarg), + entry2("va_arg_d", vaarg_d), + entry2("va_end", vaend), +#undef entry +}; + +/* + * Implementation + */ +static jit_gpr_t +get_ireg(void) +{ + if (primary(skip_ws) != tok_register) + error("bad register"); + if (parser.regtype != type_l) + error("bad int register"); + + return ((jit_gpr_t)parser.regval); +} + +static jit_fpr_t +get_freg(void) +{ + if (primary(skip_ws) != tok_register) + error("bad register"); + if (parser.regtype != type_d) + error("bad float register"); + + return ((jit_fpr_t)parser.regval); +} + +static symbol_t * +get_symbol(void) +{ + symbol_t *symbol; + int ch = skipws(); + + if (ch != '$') + error("expecting variable"); + (void)identifier('$'); + if (parser.string[1] == '\0') + error("expecting variable"); + if ((symbol = get_symbol_by_name(parser.string)) == NULL) + symbol = new_symbol(parser.string); + + return (symbol); +} + +static void +jmp_forward(void *value, label_t *label) +{ + (void)new_patch(patch_kind_jmp, label, value); +} + +static void +mov_forward(void *value, label_t *label) +{ + (void)new_patch(patch_kind_mov, label, value); +} + +static void +call_forward(void *value, label_t *label) +{ + (void)new_patch(patch_kind_call, label, value); +} + +static void +make_arg(void *value) +{ + symbol_t *symbol = get_symbol(); + + symbol->type = type_p; + symbol->value.p = value; +} + +static jit_pointer_t +get_arg(void) +{ + symbol_t *symbol = get_symbol(); + + if (symbol->type != type_p) + error("bad argument %s type", symbol->name); + + return symbol->value.p; +} + +static jit_word_t +get_imm(void) +{ + int ch; + label_t *label; + jit_word_t value; + ch = skipws(); + switch (ch) { + case '+': case '-': case '0' ... '9': + ungetch(ch); + value = get_int(skip_none); + break; + case '\'': + character(); + value = parser.value.i; + break; + case '$': + switch (expression()) { + case tok_int: + case tok_pointer: + value = parser.value.i; + break; + default: + error("expecting immediate"); + } + break; + case '@': + dynamic(); + value = (jit_word_t)parser.value.p; + break; + default: + ungetch(ch); + label = get_label(skip_none); + if (label->kind == label_kind_data) + value = (jit_word_t)label->value; + else + error("expecting immediate"); + break; + } + return (value); +} + +#define entry(name) \ +static void \ +name(void) \ +{ \ + jit_##name(); \ +} +#define entry_ca(name) \ +static void \ +name(void) \ +{ \ + make_arg(jit_##name()); \ +} +#define entry_ia(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(); \ + jit_pointer_t ac = get_arg(); \ + jit_##name(r0, ac); \ +} +#define entry_im(name) \ +static void \ +name(void) \ +{ \ + jit_word_t im = get_imm(); \ + jit_##name(im); \ +} +#define entry_ir(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(); \ + jit_##name(r0); \ +} +#define entry_ima(name) \ +static void \ +name(void) \ +{ \ + jit_word_t im = get_imm(); \ + jit_pointer_t ac = get_arg(); \ + jit_##name(im, ac); \ +} +#define entry_ir_ir_ir(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \ + jit_##name(r0, r1, r2); \ +} +#define entry_ir_ir_im(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \ + jit_word_t im = get_imm(); \ + jit_##name(r0, r1, im); \ +} +#define entry_ir_ir_ir_ir(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), \ + r2 = get_ireg(), r3 = get_ireg(); \ + jit_##name(r0, r1, r2, r3); \ +} +#define entry_ir_ir_ir_im(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(), r1 = get_ireg(), r2 = get_ireg(); \ + jit_word_t im = get_imm(); \ + jit_##name(r0, r1, r2, im); \ +} +#define entry_ir_ir(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \ + jit_##name(r0, r1); \ +} +#define entry_ir_im(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(); \ + jit_word_t im = get_imm(); \ + jit_##name(r0, im); \ +} +#define entry_ir_pm(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(); \ + void *pm = get_pointer(skip_ws); \ + jit_##name(r0, pm); \ +} +#define entry_pm_ir(name) \ +static void \ +name(void) \ +{ \ + void *pm = get_pointer(skip_ws); \ + jit_gpr_t r0 = get_ireg(); \ + jit_##name(pm, r0); \ +} +#define entry_im_ir_ir(name) \ +static void \ +name(void) \ +{ \ + jit_word_t im = get_imm(); \ + jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \ + (void)jit_##name(im, r0, r1); \ +} +#define entry_lb_ir_ir(name) \ +static void \ +name(void) \ +{ \ + jit_node_t *jmp; \ + label_t *label = get_label(skip_ws); \ + jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \ + if (label->kind == label_kind_code_forward) \ + jmp_forward((void *)jit_##name(r0, r1), label); \ + else { \ + jmp = jit_##name(r0, r1); \ + jit_patch_at(jmp, (jit_node_t *)label->value); \ + } \ +} +#define entry_lb_ir_im(name) \ +static void \ +name(void) \ +{ \ + jit_node_t *jmp; \ + label_t *label = get_label(skip_ws); \ + jit_gpr_t r0 = get_ireg(); \ + jit_word_t im = get_imm(); \ + if (label->kind == label_kind_code_forward) \ + jmp_forward((void *)jit_##name(r0, im), label); \ + else { \ + jmp = jit_##name(r0, im); \ + jit_patch_at(jmp, (jit_node_t *)label->value); \ + } \ +} +#define entry_lb(name) \ +static void \ +name(void) \ +{ \ + jit_node_t *jmp; \ + label_t *label = get_label(skip_ws); \ + if (label->kind == label_kind_code_forward) \ + jmp_forward((void *)jit_##name(), label); \ + else { \ + jmp = jit_##name(); \ + jit_patch_at(jmp, (jit_node_t *)label->value); \ + } \ +} +#define entry_pm(name) \ +static void \ +name(void) \ +{ \ + void *pm = get_pointer(skip_ws); \ + jit_##name(pm); \ +} +#define entry_fa(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(); \ + jit_pointer_t ac = get_arg(); \ + jit_##name(r0, ac); \ +} +#define entry_fma(name) \ +static void \ +name(void) \ +{ \ + jit_float64_t im = get_float(skip_ws); \ + jit_pointer_t ac = get_arg(); \ + jit_##name(im, ac); \ +} +#define entry_fr_fr_fr(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(), r1 = get_freg(), r2 = get_freg(); \ + jit_##name(r0, r1, r2); \ +} +#define entry_fr_fr_fm(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(), r1 = get_freg(); \ + jit_float64_t im = get_float(skip_ws); \ + jit_##name(r0, r1, make_float(im)); \ +} +#define entry_fr_fr_dm(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(), r1 = get_freg(); \ + jit_float64_t im = get_float(skip_ws); \ + jit_##name(r0, r1, im); \ +} +#define entry_fr_fr(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(), r1 = get_freg(); \ + jit_##name(r0, r1); \ +} +#define entry_ir_fr_fr(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(); \ + jit_fpr_t r1 = get_freg(), r2 = get_freg(); \ + jit_##name(r0, r1, r2); \ +} +#define entry_ir_fr_fm(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(); \ + jit_fpr_t r1 = get_freg(); \ + jit_float64_t im = get_float(skip_ws); \ + jit_##name(r0, r1, make_float(im)); \ +} +#define entry_ir_fr_dm(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(); \ + jit_fpr_t r1 = get_freg(); \ + jit_float64_t im = get_float(skip_ws); \ + jit_##name(r0, r1, im); \ +} +#define entry_ir_fr(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(); \ + jit_fpr_t r1 = get_freg(); \ + jit_##name(r0, r1); \ +} +#define entry_fr_ir(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(); \ + jit_gpr_t r1 = get_ireg(); \ + jit_##name(r0, r1); \ +} +#define entry_fr_fm(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(); \ + jit_float64_t im = get_float(skip_ws); \ + jit_##name(r0, make_float(im)); \ +} +#define entry_fr_dm(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(); \ + jit_float64_t im = get_float(skip_ws); \ + jit_##name(r0, im); \ +} +#define entry_fr_pm(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(); \ + void *pm = get_pointer(skip_ws); \ + jit_##name(r0, pm); \ +} +#define entry_fr_ir_ir(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(); \ + jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \ + jit_##name(r0, r1, r2); \ +} +#define entry_fr_ir_im(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(); \ + jit_gpr_t r1 = get_ireg(); \ + jit_word_t im = get_imm(); \ + jit_##name(r0, r1, im); \ +} +#define entry_pm_fr(name) \ +static void \ +name(void) \ +{ \ + void *pm = get_pointer(skip_ws); \ + jit_fpr_t r0 = get_freg(); \ + jit_##name(pm, r0); \ +} +#define entry_ir_ir_fr(name) \ +static void \ +name(void) \ +{ \ + jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); \ + jit_fpr_t r2 = get_freg(); \ + jit_##name(r0, r1, r2); \ +} +#define entry_im_ir_fr(name) \ +static void \ +name(void) \ +{ \ + jit_word_t im = get_imm(); \ + jit_gpr_t r0 = get_ireg(); \ + jit_fpr_t r1 = get_freg(); \ + jit_##name(im, r0, r1); \ +} +#define entry_lb_fr_fr(name) \ +static void \ +name(void) \ +{ \ + jit_node_t *jmp; \ + label_t *label = get_label(skip_ws); \ + jit_fpr_t r0 = get_freg(), r1 = get_freg(); \ + if (label->kind == label_kind_code_forward) \ + jmp_forward((void *)jit_##name(r0, r1), label); \ + else { \ + jmp = jit_##name(r0, r1); \ + jit_patch_at(jmp, (jit_node_t *)label->value); \ + } \ +} +#define entry_lb_fr_fm(name) \ +static void \ +name(void) \ +{ \ + jit_node_t *jmp; \ + label_t *label = get_label(skip_ws); \ + jit_fpr_t r0 = get_freg(); \ + jit_float64_t im = get_float(skip_ws); \ + if (label->kind == label_kind_code_forward) \ + jmp_forward((void *)jit_##name(r0, make_float(im)), label); \ + else { \ + jmp = jit_##name(r0, make_float(im)); \ + jit_patch_at(jmp, (jit_node_t *)label->value); \ + } \ +} +#define entry_lb_fr_dm(name) \ +static void \ +name(void) \ +{ \ + jit_node_t *jmp; \ + label_t *label = get_label(skip_ws); \ + jit_fpr_t r0 = get_freg(); \ + jit_float64_t im = get_float(skip_ws); \ + if (label->kind == label_kind_code_forward) \ + jmp_forward((void *)jit_##name(r0, im), label); \ + else { \ + jmp = jit_##name(r0, im); \ + jit_patch_at(jmp, (jit_node_t *)label->value); \ + } \ +} +#define entry_fr(name) \ +static void \ +name(void) \ +{ \ + jit_fpr_t r0 = get_freg(); \ + jit_##name(r0); \ +} +#define entry_fm(name) \ +static void \ +name(void) \ +{ \ + jit_float64_t im = get_float(skip_ws); \ + jit_##name(make_float(im)); \ +} +#define entry_dm(name) \ +static void \ +name(void) \ +{ \ + jit_float64_t im = get_float(skip_ws); \ + jit_##name(im); \ +} +#define entry_fn(name) \ +static void \ +name(void) \ +{ \ + int ch; \ + label_t *label; \ + void *value; \ + ch = skipws(); \ + switch (ch) { \ + case '0' ... '9': \ + ungetch(ch); \ + value = (void *)(jit_word_t)get_uint(skip_none); \ + break; \ + case '$': \ + switch (expression()) { \ + case tok_int: \ + value = (void *)parser.value.i; \ + break; \ + case tok_pointer: \ + value = parser.value.p; \ + break; \ + default: \ + error("expecting pointer"); \ + } \ + break; \ + case '@': \ + dynamic(); \ + value = parser.value.p; \ + break; \ + default: \ + ungetch(ch); \ + label = get_label(skip_none); \ + if (label->kind == label_kind_code_forward) \ + call_forward((void *)jit_##name(NULL), label); \ + else \ + jit_patch_at(jit_##name(NULL), label->value); \ + return; \ + } \ + jit_##name(value); \ +} +static void +name(void) { + int ch = skipws(); + (void)identifier(ch); + jit_name(parser.string); +} +static void +live(void) { + if (primary(skip_ws) != tok_register) + error("bad register"); + jit_live(parser.regval); +} +entry_im(align) +entry(prolog) +entry_im(frame) entry_im(tramp) +entry(ellipsis) +void +allocai(void) { + symbol_t *symbol; + jit_word_t i, im = get_imm(); + i = jit_allocai(im); + symbol = get_symbol(); + symbol->type = type_l; + symbol->value.i = i; +} +entry_ir_ir(allocar) +entry_ca(arg) +entry_ia(getarg_c) entry_ia(getarg_uc) +entry_ia(getarg_s) entry_ia(getarg_us) +entry_ia(getarg_i) +#if __WORDSIZE == 64 +entry_ia(getarg_ui) entry_ia(getarg_l) +#endif +entry_ia(getarg) +entry_ia(putargr) entry_ima(putargi) +entry_ir_ir_ir(addr) entry_ir_ir_im(addi) +entry_ir_ir_ir(addxr) entry_ir_ir_im(addxi) +entry_ir_ir_ir(addcr) entry_ir_ir_im(addci) +entry_ir_ir_ir(subr) entry_ir_ir_im(subi) +entry_ir_ir_ir(subxr) entry_ir_ir_im(subxi) +entry_ir_ir_ir(subcr) entry_ir_ir_im(subci) +entry_ir_ir_ir(rsbr) entry_ir_ir_im(rsbi) +entry_ir_ir_ir(mulr) entry_ir_ir_im(muli) +entry_ir_ir_ir_ir(qmulr) entry_ir_ir_ir_im(qmuli) +entry_ir_ir_ir_ir(qmulr_u) entry_ir_ir_ir_im(qmuli_u) +entry_ir_ir_ir(divr) entry_ir_ir_im(divi) +entry_ir_ir_ir(divr_u) entry_ir_ir_im(divi_u) +entry_ir_ir_ir_ir(qdivr) entry_ir_ir_ir_im(qdivi) +entry_ir_ir_ir_ir(qdivr_u) entry_ir_ir_ir_im(qdivi_u) +entry_ir_ir_ir(remr) entry_ir_ir_im(remi) +entry_ir_ir_ir(remr_u) entry_ir_ir_im(remi_u) +entry_ir_ir_ir(andr) entry_ir_ir_im(andi) +entry_ir_ir_ir(orr) entry_ir_ir_im(ori) +entry_ir_ir_ir(xorr) entry_ir_ir_im(xori) +entry_ir_ir_ir(lshr) entry_ir_ir_im(lshi) +entry_ir_ir_ir(rshr) entry_ir_ir_im(rshi) +entry_ir_ir_ir(rshr_u) entry_ir_ir_im(rshi_u) +entry_ir_ir(negr) entry_ir_ir(comr) +entry_ir_ir_ir(ltr) entry_ir_ir_im(lti) +entry_ir_ir_ir(ltr_u) entry_ir_ir_im(lti_u) +entry_ir_ir_ir(ler) entry_ir_ir_im(lei) +entry_ir_ir_ir(ler_u) entry_ir_ir_im(lei_u) +entry_ir_ir_ir(eqr) entry_ir_ir_im(eqi) +entry_ir_ir_ir(ger) entry_ir_ir_im(gei) +entry_ir_ir_ir(ger_u) entry_ir_ir_im(gei_u) +entry_ir_ir_ir(gtr) entry_ir_ir_im(gti) +entry_ir_ir_ir(gtr_u) entry_ir_ir_im(gti_u) +entry_ir_ir_ir(ner) entry_ir_ir_im(nei) +entry_ir_ir(movr) +static void +movi(void) +{ + int ch; + label_t *label; + void *value; + jit_gpr_t r0 = get_ireg(); + ch = skipws(); + switch (ch) { + case '+': case '-': + case '0' ... '9': + ungetch(ch); + value = (void *)(jit_word_t)get_uint(skip_none); + break; + case '\'': + character(); + value = (void *)parser.value.i; + break; + case '$': + switch (expression()) { + case tok_int: + value = (void *)parser.value.i; + break; + case tok_pointer: + value = parser.value.p; + break; + default: + error("expecting pointer"); + } + break; + case '@': + dynamic(); + value = parser.value.p; + break; + default: + ungetch(ch); + label = get_label(skip_none); + if (label->kind == label_kind_code || + label->kind == label_kind_code_forward) { + mov_forward((void *)jit_movi(r0, 0), label); + return; + } + value = label->value; + break; + } + jit_movi(r0, (jit_word_t)value); +} +entry_ir_ir(extr_c) entry_ir_ir(extr_uc) +entry_ir_ir(extr_s) entry_ir_ir(extr_us) +#if __WORDSIZE == 64 +entry_ir_ir(extr_i) entry_ir_ir(extr_ui) +#endif +entry_ir_ir(htonr_us) entry_ir_ir(ntohr_us) +entry_ir_ir(htonr_ui) entry_ir_ir(ntohr_ui) +#if __WORDSIZE == 64 +entry_ir_ir(htonr_ul) entry_ir_ir(ntohr_ul) +#endif +entry_ir_ir(htonr) entry_ir_ir(ntohr) +entry_ir_ir(ldr_c) entry_ir_pm(ldi_c) +entry_ir_ir(ldr_uc) entry_ir_pm(ldi_uc) +entry_ir_ir(ldr_s) entry_ir_pm(ldi_s) +entry_ir_ir(ldr_us) entry_ir_pm(ldi_us) +entry_ir_ir(ldr_i) entry_ir_pm(ldi_i) +#if __WORDSIZE == 64 +entry_ir_ir(ldr_ui) entry_ir_pm(ldi_ui) +entry_ir_ir(ldr_l) entry_ir_pm(ldi_l) +#endif +entry_ir_ir(ldr) entry_ir_pm(ldi) +entry_ir_ir_ir(ldxr_c) entry_ir_ir_im(ldxi_c) +entry_ir_ir_ir(ldxr_uc) entry_ir_ir_im(ldxi_uc) +entry_ir_ir_ir(ldxr_s) entry_ir_ir_im(ldxi_s) +entry_ir_ir_ir(ldxr_us) entry_ir_ir_im(ldxi_us) +entry_ir_ir_ir(ldxr_i) entry_ir_ir_im(ldxi_i) +#if __WORDSIZE == 64 +entry_ir_ir_ir(ldxr_ui) entry_ir_ir_im(ldxi_ui) +entry_ir_ir_ir(ldxr_l) entry_ir_ir_im(ldxi_l) +#endif +entry_ir_ir_ir(ldxr) entry_ir_ir_im(ldxi) +entry_ir_ir(str_c) entry_pm_ir(sti_c) +entry_ir_ir(str_s) entry_pm_ir(sti_s) +entry_ir_ir(str_i) entry_pm_ir(sti_i) +#if __WORDSIZE == 64 +entry_ir_ir(str_l) entry_pm_ir(sti_l) +#endif +entry_ir_ir(str) entry_pm_ir(sti) +entry_ir_ir_ir(stxr_c) entry_im_ir_ir(stxi_c) +entry_ir_ir_ir(stxr_s) entry_im_ir_ir(stxi_s) +entry_ir_ir_ir(stxr_i) entry_im_ir_ir(stxi_i) +#if __WORDSIZE == 64 +entry_ir_ir_ir(stxr_l) entry_im_ir_ir(stxi_l) +#endif +entry_ir_ir_ir(stxr) entry_im_ir_ir(stxi) +entry_lb_ir_ir(bltr) entry_lb_ir_im(blti) +entry_lb_ir_ir(bltr_u) entry_lb_ir_im(blti_u) +entry_lb_ir_ir(bler) entry_lb_ir_im(blei) +entry_lb_ir_ir(bler_u) entry_lb_ir_im(blei_u) +entry_lb_ir_ir(beqr) entry_lb_ir_im(beqi) +entry_lb_ir_ir(bger) entry_lb_ir_im(bgei) +entry_lb_ir_ir(bger_u) entry_lb_ir_im(bgei_u) +entry_lb_ir_ir(bgtr) entry_lb_ir_im(bgti) +entry_lb_ir_ir(bgtr_u) entry_lb_ir_im(bgti_u) +entry_lb_ir_ir(bner) entry_lb_ir_im(bnei) +entry_lb_ir_ir(bmsr) entry_lb_ir_im(bmsi) +entry_lb_ir_ir(bmcr) entry_lb_ir_im(bmci) +entry_lb_ir_ir(boaddr) entry_lb_ir_im(boaddi) +entry_lb_ir_ir(boaddr_u) entry_lb_ir_im(boaddi_u) +entry_lb_ir_ir(bxaddr) entry_lb_ir_im(bxaddi) +entry_lb_ir_ir(bxaddr_u) entry_lb_ir_im(bxaddi_u) +entry_lb_ir_ir(bosubr) entry_lb_ir_im(bosubi) +entry_lb_ir_ir(bosubr_u) entry_lb_ir_im(bosubi_u) +entry_lb_ir_ir(bxsubr) entry_lb_ir_im(bxsubi) +entry_lb_ir_ir(bxsubr_u) entry_lb_ir_im(bxsubi_u) +entry_ir(jmpr) entry_lb(jmpi) +entry_ir(callr) entry_fn(calli) +entry(prepare) +entry_ir(pushargr) entry_im(pushargi) +entry_ir(finishr) entry_fn(finishi) +entry(ret) +entry_ir(retr) entry_im(reti) +entry_ir(retval_c) entry_ir(retval_uc) +entry_ir(retval_s) entry_ir(retval_us) +entry_ir(retval_i) +#if __WORDSIZE == 64 +entry_ir(retval_ui) entry_ir(retval_l) +#endif +entry_ir(retval) +entry(epilog) +entry_ca(arg_f) entry_fa(getarg_f) +entry_fa(putargr_f) entry_fma(putargi_f) +entry_fr_fr_fr(addr_f) entry_fr_fr_fm(addi_f) +entry_fr_fr_fr(subr_f) entry_fr_fr_fm(subi_f) +entry_fr_fr_fr(rsbr_f) entry_fr_fr_fm(rsbi_f) +entry_fr_fr_fr(mulr_f) entry_fr_fr_fm(muli_f) +entry_fr_fr_fr(divr_f) entry_fr_fr_fm(divi_f) +entry_fr_fr(negr_f) entry_fr_fr(absr_f) +entry_fr_fr(sqrtr_f) +entry_ir_fr_fr(ltr_f) entry_ir_fr_fm(lti_f) +entry_ir_fr_fr(ler_f) entry_ir_fr_fm(lei_f) +entry_ir_fr_fr(eqr_f) entry_ir_fr_fm(eqi_f) +entry_ir_fr_fr(ger_f) entry_ir_fr_fm(gei_f) +entry_ir_fr_fr(gtr_f) entry_ir_fr_fm(gti_f) +entry_ir_fr_fr(ner_f) entry_ir_fr_fm(nei_f) +entry_ir_fr_fr(unltr_f) entry_ir_fr_fm(unlti_f) +entry_ir_fr_fr(unler_f) entry_ir_fr_fm(unlei_f) +entry_ir_fr_fr(uneqr_f) entry_ir_fr_fm(uneqi_f) +entry_ir_fr_fr(unger_f) entry_ir_fr_fm(ungei_f) +entry_ir_fr_fr(ungtr_f) entry_ir_fr_fm(ungti_f) +entry_ir_fr_fr(ltgtr_f) entry_ir_fr_fm(ltgti_f) +entry_ir_fr_fr(ordr_f) entry_ir_fr_fm(ordi_f) +entry_ir_fr_fr(unordr_f) entry_ir_fr_fm(unordi_f) +entry_ir_fr(truncr_f_i) +#if __WORDSIZE == 64 +entry_ir_fr(truncr_f_l) +#endif +entry_ir_fr(truncr_f) +entry_fr_ir(extr_f) entry_fr_fr(extr_d_f) +entry_fr_fr(movr_f) entry_fr_fm(movi_f) +entry_fr_ir(ldr_f) entry_fr_pm(ldi_f) +entry_fr_ir_ir(ldxr_f) entry_fr_ir_im(ldxi_f) +entry_ir_fr(str_f) entry_pm_fr(sti_f) +entry_ir_ir_fr(stxr_f) entry_im_ir_fr(stxi_f) +entry_lb_fr_fr(bltr_f) entry_lb_fr_fm(blti_f) +entry_lb_fr_fr(bler_f) entry_lb_fr_fm(blei_f) +entry_lb_fr_fr(beqr_f) entry_lb_fr_fm(beqi_f) +entry_lb_fr_fr(bger_f) entry_lb_fr_fm(bgei_f) +entry_lb_fr_fr(bgtr_f) entry_lb_fr_fm(bgti_f) +entry_lb_fr_fr(bner_f) entry_lb_fr_fm(bnei_f) +entry_lb_fr_fr(bunltr_f) entry_lb_fr_fm(bunlti_f) +entry_lb_fr_fr(bunler_f) entry_lb_fr_fm(bunlei_f) +entry_lb_fr_fr(buneqr_f) entry_lb_fr_fm(buneqi_f) +entry_lb_fr_fr(bunger_f) entry_lb_fr_fm(bungei_f) +entry_lb_fr_fr(bungtr_f) entry_lb_fr_fm(bungti_f) +entry_lb_fr_fr(bltgtr_f) entry_lb_fr_fm(bltgti_f) +entry_lb_fr_fr(bordr_f) entry_lb_fr_fm(bordi_f) +entry_lb_fr_fr(bunordr_f) entry_lb_fr_fm(bunordi_f) +entry_fr(pushargr_f) entry_fm(pushargi_f) +entry_fr(retr_f) entry_fm(reti_f) +entry_fr(retval_f) +entry_ca(arg_d) entry_fa(getarg_d) +entry_fa(putargr_d) entry_fma(putargi_d) +entry_fr_fr_fr(addr_d) entry_fr_fr_dm(addi_d) +entry_fr_fr_fr(subr_d) entry_fr_fr_dm(subi_d) +entry_fr_fr_fr(rsbr_d) entry_fr_fr_dm(rsbi_d) +entry_fr_fr_fr(mulr_d) entry_fr_fr_dm(muli_d) +entry_fr_fr_fr(divr_d) entry_fr_fr_dm(divi_d) +entry_fr_fr(negr_d) entry_fr_fr(absr_d) +entry_fr_fr(sqrtr_d) +entry_ir_fr_fr(ltr_d) entry_ir_fr_dm(lti_d) +entry_ir_fr_fr(ler_d) entry_ir_fr_dm(lei_d) +entry_ir_fr_fr(eqr_d) entry_ir_fr_dm(eqi_d) +entry_ir_fr_fr(ger_d) entry_ir_fr_dm(gei_d) +entry_ir_fr_fr(gtr_d) entry_ir_fr_dm(gti_d) +entry_ir_fr_fr(ner_d) entry_ir_fr_dm(nei_d) +entry_ir_fr_fr(unltr_d) entry_ir_fr_dm(unlti_d) +entry_ir_fr_fr(unler_d) entry_ir_fr_dm(unlei_d) +entry_ir_fr_fr(uneqr_d) entry_ir_fr_dm(uneqi_d) +entry_ir_fr_fr(unger_d) entry_ir_fr_dm(ungei_d) +entry_ir_fr_fr(ungtr_d) entry_ir_fr_dm(ungti_d) +entry_ir_fr_fr(ltgtr_d) entry_ir_fr_dm(ltgti_d) +entry_ir_fr_fr(ordr_d) entry_ir_fr_dm(ordi_d) +entry_ir_fr_fr(unordr_d) entry_ir_fr_dm(unordi_d) +entry_ir_fr(truncr_d_i) +#if __WORDSIZE == 64 +entry_ir_fr(truncr_d_l) +#endif +entry_ir_fr(truncr_d) +entry_fr_ir(extr_d) entry_fr_fr(extr_f_d) +entry_fr_fr(movr_d) entry_fr_dm(movi_d) +entry_fr_ir(ldr_d) entry_fr_pm(ldi_d) +entry_fr_ir_ir(ldxr_d) entry_fr_ir_im(ldxi_d) +entry_ir_fr(str_d) entry_pm_fr(sti_d) +entry_ir_ir_fr(stxr_d) entry_im_ir_fr(stxi_d) +entry_lb_fr_fr(bltr_d) entry_lb_fr_dm(blti_d) +entry_lb_fr_fr(bler_d) entry_lb_fr_dm(blei_d) +entry_lb_fr_fr(beqr_d) entry_lb_fr_dm(beqi_d) +entry_lb_fr_fr(bger_d) entry_lb_fr_dm(bgei_d) +entry_lb_fr_fr(bgtr_d) entry_lb_fr_dm(bgti_d) +entry_lb_fr_fr(bner_d) entry_lb_fr_dm(bnei_d) +entry_lb_fr_fr(bunltr_d) entry_lb_fr_dm(bunlti_d) +entry_lb_fr_fr(bunler_d) entry_lb_fr_dm(bunlei_d) +entry_lb_fr_fr(buneqr_d) entry_lb_fr_dm(buneqi_d) +entry_lb_fr_fr(bunger_d) entry_lb_fr_dm(bungei_d) +entry_lb_fr_fr(bungtr_d) entry_lb_fr_dm(bungti_d) +entry_lb_fr_fr(bltgtr_d) entry_lb_fr_dm(bltgti_d) +entry_lb_fr_fr(bordr_d) entry_lb_fr_dm(bordi_d) +entry_lb_fr_fr(bunordr_d) entry_lb_fr_dm(bunordi_d) +entry_fr(pushargr_d) entry_dm(pushargi_d) +entry_fr(retr_d) entry_dm(reti_d) +entry_fr(retval_d) +static void +vastart(void) +{ + jit_gpr_t r0 = get_ireg(); + jit_va_start(r0); +} +static void +vapush(void) +{ + jit_gpr_t r0 = get_ireg(); + jit_va_push(r0); +} +static void +vaarg(void) +{ + jit_gpr_t r0 = get_ireg(), r1 = get_ireg(); + jit_va_arg(r0, r1); +} +static void +vaarg_d(void) +{ + jit_fpr_t r0 = get_freg(); + jit_gpr_t r1 = get_ireg(); + jit_va_arg_d(r0, r1); +} +static void +vaend(void) +{ + jit_gpr_t r0 = get_ireg(); + jit_va_end(r0); +} +#undef entry_fn +#undef entry_fm +#undef entry_dm +#undef entry_lb_fr_fm +#undef entry_lb_fr_dm +#undef entry_lb_fr_fr +#undef entry_im_ir_fr +#undef entry_ir_ir_fr +#undef entry_pm_fr +#undef entry_fr_ir_ir +#undef entry_fr_ir_im +#undef entry_fr_pm +#undef entry_fr_fm +#undef entry_fr_dm +#undef entry_fr_ir +#undef entry_ir_fr +#undef entry_ir_fr_fm +#undef entry_ir_fr_dm +#undef entry_ir_fr_fr +#undef entry_fr_fr +#undef entry_fr_fr_fm +#undef entry_fr_fr_dm +#undef entry_fr_fr_fr +#undef entry_fma +#undef entry_fa +#undef entry_pm +#undef entry_lb +#undef entry_lb_ir_im +#undef entry_lb_ir_ir +#undef entry_im_ir_ir +#undef entry_pm_ir +#undef entry_ir_pm +#undef entry_ir_im +#undef entry_ir_ir +#undef entry_ir_ir_im +#undef entry_ir_ir_ir +#undef entry_ima +#undef entry_ir +#undef entry_im +#undef entry_ia +#undef entry_ca +#undef entry + +static void +error(const char *format, ...) +{ + va_list ap; + int length; + char *string; + + va_start(ap, format); + message("error", format, ap); + va_end(ap); + length = parser.data.length - parser.data.offset; + string = (char *)(parser.data.buffer + parser.data.offset - 1); + if (length > 77) + strcpy(string + 74, "..."); + else + parser.data.buffer[parser.data.length - 1] = '\0'; + fprintf(stderr, "(%s)\n", string); + exit(-1); +} + +static void +warn(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + message("warning", format, ap); + va_end(ap); +} + +static void +message(const char *kind, const char *format, va_list ap) +{ + fprintf(stderr, "%s:%d: %s: ", parser.name, + parser.line - parser.newline, kind); + vfprintf(stderr, format, ap); + fputc('\n', stderr); +} + +static int +getch(void) +{ + int ch; + + if (parser.data.offset < parser.data.length) + ch = parser.data.buffer[parser.data.offset++]; + else { + /* keep first offset for ungetch */ + if ((parser.data.length = fread(parser.data.buffer + 1, 1, + sizeof(parser.data.buffer) - 1, + parser.fp) + 1) <= 1) { + ch = EOF; + parser.data.offset = 1; + } + else { + ch = parser.data.buffer[1]; + parser.data.offset = 2; + } + } + if ((parser.newline = ch == '\n')) + ++parser.line; + + return (ch); +} + +static int +getch_noeof(void) +{ + int ch = getch(); + + if (ch == EOF) + error("unexpected end of file"); + + return (ch); +} + +static int +ungetch(int ch) +{ + if ((parser.newline = ch == '\n')) + --parser.line; + + if (parser.data.offset) + parser.data.buffer[--parser.data.offset] = ch; + else + /* overwrite */ + parser.data.buffer[0] = ch; + + return (ch); +} + +static int +skipws(void) +{ + int ch; + + for (ch = getch();; ch = getch()) { + switch (ch) { + case '/': + ch = skipct(); + break; + case '#': + ch = skipcp(); + break; + } + switch (ch) { + case ' ': case '\f': case '\r': case '\t': + break; + default: + return (ch); + } + } +} + +static int +skipnl(void) +{ + int ch; + + for (ch = getch();; ch = getch()) { + switch (ch) { + case '/': + ch = skipct(); + break; + case '#': + ch = skipcp(); + break; + } + switch (ch) { + case ' ': case '\f': case '\n': case '\r': case '\t': + break; + /* handle as newline */ + case ';': + break; + default: + return (ch); + } + } +} + +static int +skipct(void) +{ + int ch; + + ch = getch(); + switch (ch) { + case '/': + for (ch = getch(); ch != '\n' && ch != EOF; ch = getch()) + ; + return (ch); + case '*': + for (; ch != '/';) { + while (getch_noeof() != '*') + ; + while ((ch = getch_noeof()) == '*') + ; + } + return (getch()); + default: + ungetch(ch); + return ('/'); + } +} + +static int +skipcp(void) +{ + int ch; + + for (ch = getch(); ch != '\n' && ch != EOF; ch = getch()) { + switch (ch) { + case '0' ... '9': + if ((number(ch)) == tok_int) + parser.line = parser.value.i - 1; + break; + case '"': + string(); + if (parser.offset >= (int)sizeof(parser.name)) { + strncpy(parser.name, parser.string, sizeof(parser.name)); + parser.name[sizeof(parser.name) - 1] = '\0'; + } + else + strcpy(parser.name, parser.string); + break; + default: + break; + } + } + + return (ch); +} + +static jit_word_t +get_int(skip_t skip) +{ + switch (primary(skip)) { + case tok_int: + break; + case tok_pointer: + parser.type = type_l; + parser.value.i = (jit_word_t)parser.value.p; + break; + default: + error("expecting integer"); + } + + return (parser.value.i); +} + +static jit_uword_t +get_uint(skip_t skip) +{ + switch (primary(skip)) { + case tok_char: case tok_int: + break; + case tok_pointer: + parser.type = type_l; + parser.value.ui = (jit_uword_t)parser.value.p; + break; + default: + error("expecting integer"); + } + + return (parser.value.ui); +} + +static double +get_float(skip_t skip) +{ + switch (primary(skip)) { + case tok_char: + case tok_int: + parser.type = type_d; + parser.value.d = parser.value.i; + break; + case tok_float: + break; + default: + error("expecting float"); + } + + return (parser.value.d); +} + +/* Workaround gcc not converting unordered values from double to + * float (as done in other architectures) on s390 */ +static float +make_float(double d) +{ + /* This is an workaround to a bug in Hercules s390 emulator, + * and at least HP-UX ia64 not have these */ +#if defined(HAVE_ISNAN) && defined(HAVE_ISINF) + if (isnan(d)) return ( 0.0f/0.0f); + if (isinf(d)) { + if (d > 0.0) return ( 1.0f/0.0f); + else return (-1.0f/0.0f); + } +#endif + return ((float)d); +} + +static void * +get_pointer(skip_t skip) +{ + label_t *label; + token_t token = primary(skip); + + switch (token) { + case tok_symbol: + label = get_label_by_name(parser.string); + if (label == NULL) + error("bad identifier %s", parser.string); + switch (label->kind) { + case label_kind_data: + case label_kind_code: + break; + case label_kind_code_forward: + /* as expression arguments */ + error("forward references not implemented"); + break; + case label_kind_dynamic: + break; + } + parser.type = type_p; + return (parser.value.p = label->value); + case tok_int: + parser.type = type_p; + return (parser.value.p = (void *)parser.value.ui); + case tok_pointer: + return (parser.value.p); + default: error("bad pointer"); + } +} + +static label_t * +get_label(skip_t skip) +{ + label_t *label; + int ch = skipws(); + + switch (ch) { + case '@': + (void)dynamic(); + break; + case 'a' ... 'z': case 'A' ... 'Z': case '_': + (void)identifier(ch); + break; + default: + error("expecting label/immediate"); + } + if ((label = get_label_by_name(parser.string)) == NULL) + label = new_label(label_kind_code_forward, + parser.string, jit_forward()); + + return (label); +} + +static token_t +regname(void) +{ + jit_word_t num; + int check = 1, ch = getch(); + + switch (ch) { + case 'r': + parser.regtype = type_l; + switch (ch = getch()) { + case '0': parser.regval = JIT_R0; break; + case '1': parser.regval = JIT_R1; break; + case '2': parser.regval = JIT_R2; break; + case '(': + num = get_int(skip_none); + if (num < 0 || num >= JIT_R_NUM) goto fail; + parser.regval = JIT_R(num); + if (getch() != ')') goto fail; + check = 0; + break; + default: goto fail; + } + break; + case 'v': + parser.regtype = type_l; + switch (ch = getch()) { + case '0': parser.regval = JIT_V0; break; + case '1': parser.regval = JIT_V1; break; + case '2': parser.regval = JIT_V2; break; + default: goto fail; + case '(': + num = get_int(skip_none); + if (num < 0 || num >= JIT_V_NUM) goto fail; + parser.regval = JIT_V(num); + if (getch() != ')') goto fail; + check = 0; + break; + } + break; + case 'f': + parser.regtype = type_d; + switch (ch = getch()) { + case '0': parser.regval = JIT_F0; break; + case '1': parser.regval = JIT_F1; break; + case '2': parser.regval = JIT_F2; break; + case '3': parser.regval = JIT_F3; break; + case '4': parser.regval = JIT_F4; break; + case '5': parser.regval = JIT_F5; break; + case 'p': + parser.regtype = type_l; /* oops */ + parser.regval = JIT_FP; break; + case '(': + num = get_int(skip_none); + if (num < 0 || num >= JIT_F_NUM) goto fail; + parser.regval = JIT_F(num); + if (getch() != ')') goto fail; + check = 0; + break; + default: goto fail; + } + break; + default: + fail: + error("bad register"); + } + if (check) { + ch = getch(); + if ((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || + ch == '_') + goto fail; + ungetch(ch); + } + + return (tok_register); +} + +static token_t +identifier(int ch) +{ + parser.string[0] = ch; + for (parser.offset = 1;;) { + switch ((ch = getch())) { + case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9' : case '_': + if (parser.offset + 1 >= MAX_IDENTIFIER) { + parser.string[parser.offset] = '\0'; + error("bad identifier %s", parser.string); + } + parser.string[parser.offset++] = ch; + break; + default: + parser.string[parser.offset] = '\0'; + ungetch(ch); + return (tok_symbol); + } + } +} + +static void +get_data(type_t type) +{ + int ch; + token_t token; + char *test = data; + + for (;;) { + switch (type) { + case type_c: + switch (token = primary(skip_ws)) { + case tok_char: case tok_int: + check_data(sizeof(signed char)); + *(signed char *)(data + data_offset) = parser.value.i; + data_offset += sizeof(char); + break; + case tok_string: + check_data(parser.offset); + memcpy(data + data_offset, parser.string, + parser.offset); + data_offset += parser.offset; + break; + case tok_newline: + case tok_semicollon: + if (test == data) error("syntax error"); + return; + default: error("bad initializer"); + } + break; + case type_s: + check_data(sizeof(signed short)); + *(signed short *)(data + data_offset) = get_int(skip_ws); + data_offset += sizeof(short); + break; + case type_i: + check_data(sizeof(signed int)); + *(signed int *)(data + data_offset) = get_int(skip_ws); + data_offset += sizeof(int); + break; + case type_l: + check_data(sizeof(jit_word_t)); + *(jit_word_t *)(data + data_offset) = get_int(skip_ws); + data_offset += sizeof(jit_word_t); + break; + case type_f: + check_data(sizeof(float)); + *(float *)(data + data_offset) = get_float(skip_ws); + data_offset += sizeof(float); + break; + case type_d: + check_data(sizeof(double)); + *(double *)(data + data_offset) = get_float(skip_ws); + data_offset += sizeof(double); + break; + case type_p: + /* FIXME **patch if realloc** */ + check_data(sizeof(void*)); + *(void **)(data + data_offset) = get_pointer(skip_ws); + data_offset += sizeof(void*); + break; + default: + abort(); + } + ch = skipws(); + if (ch == '\n' || ch == ';' || ch == EOF) + break; + ungetch(ch); + } +} + +static void +dot(void) +{ + int ch; + size_t offset, length; + + switch (ch = getch_noeof()) { + case '$': + /* use .$(expression) for non side effects expression */ + (void)expression(); + return; + case 'a' ... 'z': case 'A' ... 'Z': case '_': + (void)identifier(ch); + break; + default: + ungetch(ch); + if (skipws() != '$') + error("expecting symbol"); + /* allow spaces before an expression */ + (void)expression(); + return; + } + if (parser.string[1] == '\0') { + switch (parser.string[0]) { + case 'c': get_data(type_c); break; + case 's': get_data(type_s); break; + case 'i': get_data(type_i); break; + case 'l': get_data(type_l); break; + case 'f': get_data(type_f); break; + case 'd': get_data(type_d); break; + case 'p': get_data(type_p); break; + default: error("bad type .%c", parser.string[0]); + } + } + else if (strcmp(parser.string, "data") == 0) { + if (parser.parsing != PARSING_NONE) + error(".data must be specified once and be the first section"); + parser.parsing = PARSING_DATA; + data_length = get_int(skip_ws); + data = (char *)xcalloc(1, data_length); + } + else if (strcmp(parser.string, "code") == 0) { + if (parser.parsing != PARSING_NONE && + parser.parsing != PARSING_DATA) + error(".code must be specified once only"); + parser.parsing = PARSING_CODE; + } + else if (strcmp(parser.string, "align") == 0) { + length = get_int(skip_ws); + if (parser.parsing != PARSING_DATA) + error(".align must be in .data"); + if (length > 1 && length <= 4096 && !(length & (length - 1))) { + offset = data_offset; + offset += length - ((offset + length) % length); + check_data(offset - data_offset); + data_offset = offset; + } + else + error("bad .align %ld (must be a power of 2, >= 2 && <= 4096)", + (jit_word_t)length); + } + else if (strcmp(parser.string, "size") == 0) { + length = get_int(skip_ws); + if (parser.parsing != PARSING_DATA) + error(".size must be in .data"); + check_data(length); + data_offset += length; + } + else if (strcmp(parser.string, "disasm") == 0) + flag_disasm = 1; + else + error("unknown command .%s", parser.string); +} + +static token_t +number(int ch) +{ + char buffer[1024], *endptr; + int integer = 1, offset = 0, neg = 0, e = 0, d = 0, base = 10; + + for (;; ch = getch()) { + switch (ch) { + case '-': + if (offset == 0) { + neg = 1; + continue; + } + if (offset && buffer[offset - 1] != 'e') { + ungetch(ch); + goto done; + } + break; + case '+': + if (offset == 0) + continue; + if (offset && buffer[offset - 1] != 'e') { + ungetch(ch); + goto done; + } + break; + case '.': + if (d) + goto fail; + d = 1; + base = 10; + integer = 0; + break; + case '0': + if (offset == 0 && base == 10) { + base = 8; + continue; + } + break; + case 'b': + if (offset == 0 && base == 8) { + base = 2; + continue; + } + if (base != 16) + goto fail; + break; + case '1': + break; + case '2' ... '7': + if (base < 8) + goto fail; + break; + case '8': case '9': + if (base < 10) + goto fail; + break; + case 'x': + if (offset == 0 && base == 8) { + base = 16; + continue; + } + goto fail; + case 'a': case 'c': case 'd': case 'f': + if (base < 16) + goto fail; + break; + case 'e': + if (e) + goto fail; + if (base != 16) { + e = 1; + base = 10; + integer = 0; + } + break; + case '_': case 'g' ... 'w': case 'y': case 'z': case 'A' ... 'Z': + fail: + buffer[offset++] = '\0'; + error("bad constant %s", buffer); + default: + ungetch(ch); + goto done; + } + if (offset + 1 >= (int)sizeof(buffer)) + goto fail; + buffer[offset++] = ch; + } +done: + /* check for literal 0 */ + if (offset == 0 && base == 8) buffer[offset++] = '0'; + buffer[offset] = '\0'; + if (integer) { +#if _WIN32 +# define STRTOUL strtoull +#else +# define STRTOUL strtoul +#endif + parser.value.ui = STRTOUL(buffer, &endptr, base); + parser.type = type_l; + if (neg) + parser.value.i = -parser.value.i; + } + else { + parser.type = type_d; + parser.value.d = strtod(buffer, &endptr); + if (neg) + parser.value.d = -parser.value.d; + } + if (*endptr) + goto fail; + + return (integer ? tok_int : tok_float); +} + +static int +escape(int ch) +{ + switch (ch) { + case 'a': ch = '\a'; break; + case 'b': ch = '\b'; break; + case 'f': ch = '\f'; break; + case 'n': ch = '\n'; break; + case 'r': ch = '\r'; break; + case 't': ch = '\t'; break; + case 'v': ch = '\v'; break; + default: break; + } + + return (ch); +} + +static token_t +string(void) +{ + int ch, esc = 0; + + for (parser.offset = 0;;) { + switch (ch = getch_noeof()) { + case '\\': + if (esc) goto append; + esc = 1; + break; + case '"': + if (!esc) { + parser.string[parser.offset++] = '\0'; + parser.value.p = parser.string; + parser.type = type_p; + return (tok_string); + } + /* FALLTHROUGH */ + default: + append: + if (esc) { + ch = escape(ch); + esc = 0; + } + if (parser.offset + 1 >= parser.length) { + parser.length += 4096; + parser.string = (char *)xrealloc(parser.string, + parser.length); + } + parser.string[parser.offset++] = ch; + break; + } + } +} + +static token_t +character(void) +{ + int ch, esc = 0; + + if ((ch = getch_noeof()) == '\\') { + esc = 1; + ch = getch(); + } + if (getch_noeof() != '\'') + error("bad single byte char"); + if (esc) + ch = escape(ch); + parser.type = type_l; + parser.value.i = ch & 0xff; + + return (tok_char); +} + +static token_t +dynamic(void) +{ + label_t *label; + void *value; + char *string; + (void)identifier('@'); + if ((label = get_label_by_name(parser.string)) == NULL) { +#if __CYGWIN__ ||_WIN32 + /* FIXME kludge to pass varargs test case, otherwise, + * will not print/scan float values */ + if (strcmp(parser.string + 1, "sprintf") == 0) + value = sprintf; + else if (strcmp(parser.string + 1, "sscanf") == 0) + value = sscanf; + else +#endif + { + value = dlsym(DL_HANDLE, parser.string + 1); + if ((string = dlerror())) + error("%s", string); + } + label = new_label(label_kind_dynamic, parser.string, value); + } + parser.type = type_p; + parser.value.p = label->value; + + return (tok_pointer); +} + +static void +expression_prim(void) +{ + int ch; + token_t token; + label_t *label; + symbol_t *symbol; + + if (parser.putback) { + parser.expr = parser.putback; + parser.putback = (expr_t)0; + return; + } + switch (ch = skipws()) { + case '!': + if ((ch = getch_noeof()) == '=') parser.expr = expr_ne; + else { + ungetch(ch); parser.expr = expr_not; + } + break; + case '~': parser.expr = expr_com; + break; + case '*': + if ((ch = getch_noeof()) == '=') parser.expr = expr_mulset; + else { + ungetch(ch); parser.expr = expr_mul; + } + break; + case '/': + if ((ch = getch_noeof()) == '=') parser.expr = expr_divset; + else { + ungetch(ch); parser.expr = expr_div; + } + break; + case '%': + if ((ch = getch_noeof()) == '=') parser.expr = expr_remset; + else { + ungetch(ch); parser.expr = expr_rem; + } + break; + case '+': + switch (ch = getch_noeof()) { + case '+': parser.expr = expr_inc; + break; + case '=': parser.expr = expr_addset; + break; + default: ungetch(ch); parser.expr = expr_add; + break; + } + break; + case '-': + switch (ch = getch_noeof()) { + case '-': parser.expr = expr_dec; + break; + case '=': parser.expr = expr_subset; + break; + default: ungetch(ch); parser.expr = expr_sub; + break; + } + break; + case '<': + switch (ch = getch_noeof()) { + case '=': parser.expr = expr_le; + break; + case '<': ch = getch_noeof(); + if (ch == '=') parser.expr = expr_lshset; + else { + ungetch(ch); parser.expr = expr_lsh; + } + break; + default: ungetch(ch); parser.expr = expr_lt; + break; + } + break; + case '>': + switch (ch = getch_noeof()) { + case '=': parser.expr = expr_ge; + break; + case '>': ch = getch_noeof(); + if (ch == '=') parser.expr = expr_rshset; + else { + ungetch(ch); parser.expr = expr_rsh; + } + break; + default: ungetch(ch); parser.expr = expr_gt; + break; + } + break; + case '&': + switch (ch = getch_noeof()) { + case '=': parser.expr = expr_andset; + break; + case '&': parser.expr = expr_andand; + break; + default: ungetch(ch); parser.expr = expr_and; + break; + } + break; + case '|': + switch (ch = getch_noeof()) { + case '=': parser.expr = expr_orset; + break; + case '|': parser.expr = expr_oror; + break; + default: ungetch(ch); parser.expr = expr_or; + break; + } + break; + case '^': + if ((ch = getch_noeof()) == '=') parser.expr = expr_xorset; + else { + ungetch(ch); parser.expr = expr_xor; + } + break; + case '=': + if ((ch = getch_noeof()) == '=') parser.expr = expr_eq; + else { + ungetch(ch); parser.expr = expr_set; + } + break; + case '(': parser.expr = expr_lparen; + break; + case ')': parser.expr = expr_rparen; + break; + case '0' ... '9': + token = number(ch); + parser.expr = token == tok_int ? expr_int : expr_float; + break; + case '@': + (void)dynamic(); + parser.expr = expr_pointer; + break; + case '$': + identifier('$'); + /* no support for nested expressions */ + if (parser.string[0] == '\0') + error("syntax error"); + parser.expr = expr_symbol; + if ((symbol = get_symbol_by_name(parser.string)) != NULL) { + parser.type = symbol->type; + parser.value = symbol->value; + } + else + /* only create symbol on assignment */ + parser.type = type_none; + break; + case 'a' ... 'z': case 'A' ... 'Z': case '_': + identifier(ch); + if ((label = get_label_by_name(parser.string))) { + if (label->kind == label_kind_code_forward) + error("forward value for %s not supported", + parser.string); + parser.expr = expr_pointer; + parser.type = type_p; + parser.value.p = label->value; + } + else + error("invalid identifier %s", parser.string); + break; + case '\'': + character(); + parser.expr = expr_int; + break; + case '"': + /* not smart enough to put it in data and/or relocate it, etc */ + error("must declare strings as data"); + default: + error("syntax error"); + } +} + +static void +expression_inc(int pre) +{ + symbol_t *symbol; + + if (pre) { + expression_prim(); + if (parser.expr != expr_symbol) + error("syntax error"); + } + if ((symbol = get_symbol_by_name(parser.string)) == NULL) { + if (!parser.short_circuit) + error("undefined symbol %s", symbol->name); + } + if (!parser.short_circuit) { + parser.type = symbol->type; + if (!pre) + parser.value = symbol->value; + switch (symbol->type) { + case type_l: + ++symbol->value.i; + break; + case type_d: + /* should really be an error */ + symbol->value.d += 1.0; + break; + default: + ++parser.value.cp; + break; + } + if (pre) + parser.value = symbol->value; + } + expression_prim(); +} + +static void +expression_dec(int pre) +{ + symbol_t *symbol; + + if (pre) { + expression_prim(); + if (parser.expr != expr_symbol) + error("syntax error"); + } + if ((symbol = get_symbol_by_name(parser.string)) == NULL) { + if (!parser.short_circuit) + error("undefined symbol %s", symbol->name); + } + if (!parser.short_circuit) { + parser.type = symbol->type; + if (!pre) + parser.value = symbol->value; + switch (symbol->type) { + case type_l: + --symbol->value.i; + break; + case type_d: + /* should really be an error */ + symbol->value.d -= 1.0; + break; + default: + --parser.value.cp; + break; + } + if (pre) + parser.value = symbol->value; + } + expression_prim(); +} + +static void +expression_unary(void) +{ + symbol_t *symbol; + char buffer[256]; + + expression_prim(); + switch (parser.expr) { + case expr_add: + expression_unary(); + switch (parser.type) { + case type_l: + case type_d: + break; + default: + error("syntax error"); + } + break; + case expr_sub: + expression_unary(); + switch (parser.type) { + case type_l: + parser.value.i = -parser.value.i; + break; + case type_d: + parser.value.d = -parser.value.d; + break; + default: + error("syntax error"); + } + break; + case expr_inc: + expression_inc(1); + break; + case expr_dec: + expression_dec(1); + break; + case expr_not: + expression_unary(); + switch (parser.type) { + case type_l: + parser.value.i = !parser.value.i; + break; + case type_d: + parser.value.i = parser.value.d != 0; + break; + case type_p: + parser.value.i = parser.value.p != NULL; + break; + default: + error("syntax error"); + } + parser.type = type_l; + break; + case expr_com: + expression_unary(); + if (parser.type != type_l) + error("syntax error"); + parser.value.i = ~parser.value.i; + break; + case expr_lparen: + expression_cond(); + if (parser.expr != expr_rparen) + error("syntax error"); + expression_prim(); + break; + case expr_symbol: + strcpy(buffer, parser.string); + expression_prim(); + switch (parser.expr) { + case expr_set: + if ((symbol = get_symbol_by_name(buffer)) == NULL) { + if (!parser.short_circuit) + symbol = new_symbol(buffer); + } + expression_cond(); + set: + if (!parser.short_circuit) { + if (symbol == NULL) + error("syntax error"); + symbol->type = parser.type; + symbol->value = parser.value; + } + break; + case expr_mulset: parser.putback = expr_mul; + goto check; + case expr_divset: parser.putback = expr_div; + goto check; + case expr_remset: parser.putback = expr_rem; + goto check; + case expr_addset: parser.putback = expr_add; + goto check; + case expr_subset: parser.putback = expr_sub; + goto check; + case expr_lshset: parser.putback = expr_lsh; + goto check; + case expr_rshset: parser.putback = expr_rsh; + goto check; + case expr_andset: parser.putback = expr_and; + goto check; + case expr_orset: parser.putback = expr_or; + goto check; + case expr_xorset: parser.putback = expr_xor; + check: + if ((symbol = get_symbol_by_name(buffer)) == NULL) { + if (!parser.short_circuit) + error("undefined symbol %s", buffer); + parser.type = type_l; + parser.value.i = 1; + } + switch (parser.putback) { + case expr_mul: case expr_div: case expr_rem: + expression_mul(); + break; + case expr_add: case expr_sub: + expression_add(); + break; + case expr_lsh: case expr_rsh: + expression_shift(); + break; + case expr_and: case expr_or: case expr_xor: + expression_bit(); + break; + default: + abort(); + } + goto set; + case expr_inc: + expression_inc(0); + break; + case expr_dec: + expression_dec(0); + break; + default: + break; + } + break; + case expr_int: + case expr_float: + case expr_pointer: + /* make next token available */ + expression_prim(); + default: + break; + } +} + +static void +expression_mul(void) +{ + type_t type; + value_t value; + + expression_unary(); + switch (parser.type) { + case type_l: case type_d: case type_p: break; + default: return; + } + for (;;) { + switch (parser.expr) { + case expr_mul: + type = parser.type, value = parser.value; + expression_unary(); + switch (parser.type) { + case type_l: + if (type == type_l) + value.i *= parser.value.i; + else + value.d *= parser.value.i; + break; + case type_d: + if (type == type_l) { + type = type_d; + value.d = value.i; + } + value.d *= parser.value.d; + break; + default: + error("invalid operand"); + } + parser.type = type, parser.value = value; + break; + case expr_div: + type = parser.type, value = parser.value; + expression_unary(); + switch (parser.type) { + case type_l: + if (type == type_l) { + if (parser.value.i == 0) + error("divide by zero"); + value.i /= parser.value.i; + } + else + value.d /= parser.value.i; + break; + case type_d: + if (type == type_l) { + type = type_d; + value.d = value.i; + } + value.d /= parser.value.d; + break; + default: + error("invalid operand"); + } + parser.type = type, parser.value = value; + break; + case expr_rem: + type = parser.type, value = parser.value; + expression_unary(); + switch (parser.type) { + case type_l: + if (type == type_l) { + if (parser.value.i == 0) + error("divide by zero"); + value.i %= parser.value.i; + } + else + error("invalid operand"); + break; + default: + error("invalid operand"); + } + parser.type = type, parser.value = value; + break; + default: + return; + } + } +} + +static void +expression_add(void) +{ + type_t type; + value_t value; + + expression_mul(); + switch (parser.type) { + case type_l: case type_d: case type_p: break; + default: return; + } + for (;;) { + switch (parser.expr) { + case expr_add: + type = parser.type, value = parser.value; + expression_mul(); + switch (parser.type) { + case type_l: + switch (type) { + case type_l: + value.i += parser.value.i; + break; + case type_d: + value.d += parser.value.i; + break; + default: + value.cp += parser.value.i; + break; + } + break; + case type_d: + switch (type) { + case type_l: + type = type_d; + value.d = value.i; + break; + case type_d: + break; + default: + error("invalid operand"); + } + value.d += parser.value.d; + break; + case type_p: + switch (type) { + case type_l: + type = type_p; + value.cp = value.i + parser.value.cp; + break; + default: + error("invalid operand"); + } + break; + default: + error("invalid operand"); + } + parser.type = type, parser.value = value; + break; + case expr_sub: + type = parser.type, value = parser.value; + expression_mul(); + switch (parser.type) { + case type_l: + switch (type) { + case type_l: + value.i -= parser.value.i; + break; + case type_d: + value.d -= parser.value.i; + break; + default: + value.cp -= parser.value.i; + break; + } + break; + case type_d: + switch (type) { + case type_l: + type = type_d; + value.d = value.i; + break; + case type_d: + break; + default: + error("invalid operand"); + } + value.d -= parser.value.d; + break; + case type_p: + switch (type) { + case type_p: + type = type_l; + value.i = value.cp - parser.value.cp; + break; + default: + error("invalid operand"); + } + break; + default: + error("invalid operand"); + } + parser.type = type, parser.value = value; + break; + default: + return; + } + } +} + +static void +expression_shift(void) +{ + jit_word_t value; + expression_add(); + + switch (parser.type) { + case type_l: case type_d: case type_p: break; + default: return; + } + for (;;) { + switch (parser.expr) { + case expr_lsh: + value = parser.value.i; + if (parser.type != type_l) + error("invalid operand"); + expression_add(); + if (parser.type != type_l) + error("invalid operand"); + value <<= parser.value.i; + parser.value.i = value; + break; + case expr_rsh: + value = parser.value.i; + if (parser.type != type_l) + error("invalid operand"); + expression_add(); + if (parser.type != type_l) + error("invalid operand"); + value >>= parser.value.i; + parser.value.i = value; + break; + default: + return; + } + } +} + +static void +expression_bit(void) +{ + jit_word_t i; + + expression_shift(); + switch (parser.type) { + case type_l: case type_d: case type_p: break; + default: return; + } + for (;;) { + switch (parser.expr) { + case expr_and: + if (parser.type != type_l) + error("invalid operand"); + i = parser.value.i; + expression_shift(); + if (parser.type != type_l) + error("invalid operand"); + i &= parser.value.i; + parser.value.i = i; + break; + case expr_or: + if (parser.type != type_l) + error("invalid operand"); + i = parser.value.i; + expression_shift(); + if (parser.type != type_l) + error("invalid operand"); + i |= parser.value.i; + parser.value.i = i; + break; + case expr_xor: + if (parser.type != type_l) + error("invalid operand"); + i = parser.value.i; + expression_shift(); + if (parser.type != type_l) + error("invalid operand"); + i ^= parser.value.i; + parser.value.i = i; + break; + default: + return; + } + } +} + +static void +expression_rel(void) +{ + type_t type; + value_t value; + + expression_bit(); + switch (parser.type) { + case type_l: case type_d: case type_p: break; + default: return; + } + for (;;) { + switch (parser.expr) { + case expr_lt: + type = parser.type, value = parser.value; + expression_bit(); + switch (parser.type) { + case type_l: + switch (type) { + case type_l: + value.i = value.i < parser.value.i; + break; + case type_d: + value.i = value.d < parser.value.i; + break; + default: + value.i = (jit_word_t)value.p < parser.value.i; + break; + } + break; + case type_d: + switch (type) { + case type_l: + value.i = value.i < parser.value.d; + break; + case type_d: + value.i = value.d < parser.value.d; + break; + default: + error("invalid operand"); + } + break; + case type_p: + switch (type) { + case type_l: + value.i = value.i < (jit_word_t)parser.value.p; + break; + case type_d: + error("invalid operand"); + default: + value.i = (jit_word_t)value.p < (jit_word_t)parser.value.p; + break; + } + break; + default: + error("invalid operand"); + } + parser.type = type_l, parser.value = value; + break; + case expr_le: + type = parser.type, value = parser.value; + expression_bit(); + switch (parser.type) { + case type_l: + switch (type) { + case type_l: + value.i = value.i <= parser.value.i; + break; + case type_d: + value.i = value.d <= parser.value.i; + break; + default: + value.i = (jit_word_t)value.p <= parser.value.i; + break; + } + break; + case type_d: + switch (type) { + case type_l: + value.i = value.i <= parser.value.d; + break; + case type_d: + value.i = value.d <= parser.value.d; + break; + default: + value.i = (jit_word_t)value.p <= parser.value.d; + break; + } + break; + case type_p: + switch (type) { + case type_l: + value.i = value.i <= (jit_word_t)parser.value.p; + break; + case type_d: + error("invalid operand"); + default: + value.i = (jit_word_t)value.p <= (jit_word_t)parser.value.p; + break; + } + break; + default: + error("invalid operand"); + } + parser.type = type_l, parser.value = value; + break; + case expr_eq: + type = parser.type, value = parser.value; + expression_bit(); + switch (parser.type) { + case type_l: + switch (type) { + case type_l: + value.i = value.i == parser.value.i; + break; + case type_d: + value.i = value.d == parser.value.i; + break; + default: + value.i = (jit_word_t)value.p == parser.value.i; + break; + } + break; + case type_d: + switch (type) { + case type_l: + value.i = value.i == parser.value.d; + break; + case type_d: + value.i = value.d == parser.value.d; + break; + default: + error("invalid operand"); + } + break; + case type_p: + switch (type) { + case type_l: + value.i = value.i == (jit_word_t)parser.value.p; + break; + case type_d: + error("invalid operand"); + default: + value.i = value.p == parser.value.p; + break; + } + break; + default: + error("invalid operand"); + } + parser.type = type_l, parser.value = value; + break; + case expr_ge: + type = parser.type, value = parser.value; + expression_bit(); + switch (parser.type) { + case type_l: + switch (type) { + case type_l: + value.i = value.i >= parser.value.i; + break; + case type_d: + value.i = value.d >= parser.value.i; + break; + default: + value.i = (jit_word_t)value.p >= parser.value.i; + break; + } + break; + case type_d: + switch (type) { + case type_l: + value.i = value.i >= parser.value.d; + break; + case type_d: + value.i = value.d >= parser.value.d; + break; + default: + error("invalid operand"); + } + break; + case type_p: + switch (type) { + case type_l: + value.i = value.i >= (jit_word_t)parser.value.p; + break; + case type_d: + error("invalid operand"); + default: + value.i = (jit_word_t)value.p >= (jit_word_t)parser.value.p; + break; + } + break; + default: + error("invalid operand"); + } + parser.type = type_l, parser.value = value; + break; + case expr_gt: + type = parser.type, value = parser.value; + expression_bit(); + switch (parser.type) { + case type_l: + switch (type) { + case type_l: + value.i = value.i > parser.value.i; + break; + case type_d: + value.i = value.d > parser.value.i; + break; + default: + value.i = (jit_word_t)value.p > parser.value.i; + break; + } + break; + case type_d: + switch (type) { + case type_l: + value.i = value.i > parser.value.d; + break; + case type_d: + value.i = value.d > parser.value.d; + break; + default: + error("invalid operand"); + } + break; + case type_p: + switch (type) { + case type_l: + value.i = value.i > (jit_word_t)parser.value.p; + break; + case type_d: + error("invalid operand"); + default: + value.i = (jit_word_t)value.p > (jit_word_t)parser.value.p; + break; + } + break; + default: + error("invalid operand"); + } + parser.type = type_l, parser.value = value; + break; + case expr_ne: + type = parser.type, value = parser.value; + expression_bit(); + switch (parser.type) { + case type_l: + switch (type) { + case type_l: + value.i = value.i != parser.value.i; + break; + case type_d: + value.i = value.d != parser.value.i; + break; + default: + value.i = (jit_word_t)value.p != parser.value.i; + break; + } + break; + case type_d: + switch (type) { + case type_l: + value.i = value.i != parser.value.d; + break; + case type_d: + value.i = value.d != parser.value.d; + break; + default: + error("invalid operand"); + } + break; + case type_p: + switch (type) { + case type_l: + value.i = value.i != (jit_word_t)parser.value.p; + break; + case type_d: + error("invalid operand"); + default: + value.i = value.p != parser.value.p; + break; + } + break; + default: + error("invalid operand"); + } + parser.type = type_l, parser.value = value; + break; + default: + return; + } + } +} + +static void +expression_cond(void) +{ + type_t type; + value_t value; + int short_circuit; + + expression_rel(); + switch (parser.type) { + case type_l: case type_d: case type_p: break; + default: return; + } + for (;;) { + switch (parser.expr) { + case expr_andand: + type = parser.type, value = parser.value; + switch (type) { + case type_l: + short_circuit = value.i == 0; + break; + case type_d: + short_circuit = value.d == 0.0; + break; + default: + short_circuit = value.p == NULL; + break; + } + parser.short_circuit += short_circuit; + expression_rel(); + parser.short_circuit -= short_circuit; + switch (parser.type) { + case type_l: + switch (type) { + case type_l: + value.i = value.i && parser.value.i; + break; + case type_d: + value.i = value.d && parser.value.i; + break; + default: + value.i = value.p && parser.value.i; + break; + } + break; + case type_d: + switch (type) { + case type_l: + value.i = value.i && parser.value.d; + break; + case type_d: + value.i = value.d && parser.value.d; + break; + default: + value.i = value.p && parser.value.d; + break; + } + break; + case type_p: + switch (type) { + case type_l: + value.i = value.i && parser.value.p; + break; + case type_d: + value.i = value.d && parser.value.p; + break; + default: + value.i = value.p && parser.value.p; + break; + } + break; + default: + error("invalid operand"); + } + parser.type = type_l, parser.value.i = value.i; + break; + case expr_oror: + type = parser.type, value = parser.value; + switch (type) { + case type_l: + short_circuit = value.i != 0; + break; + case type_d: + short_circuit = value.d != 0.0; + break; + default: + short_circuit = value.p != NULL; + break; + } + parser.short_circuit += short_circuit; + expression_rel(); + parser.short_circuit -= short_circuit; + switch (parser.type) { + case type_l: + switch (type) { + case type_l: + value.i = value.i || parser.value.i; + break; + case type_d: + value.i = value.d || parser.value.i; + break; + default: + value.i = value.p || parser.value.i; + break; + } + break; + case type_d: + switch (type) { + case type_l: + value.i = value.i || parser.value.d; + break; + case type_d: + value.i = value.d || parser.value.d; + break; + default: + value.i = value.p || parser.value.d; + break; + } + break; + case type_p: + switch (type) { + case type_l: + value.i = value.i || parser.value.p; + break; + case type_d: + value.i = value.d || parser.value.p; + break; + default: + value.i = value.p || parser.value.p; + break; + } + break; + default: + error("invalid operand"); + } + parser.type = type_l, parser.value.i = value.i; + break; + default: + return; + } + } +} + +static token_t +expression(void) +{ + symbol_t *symbol; + + (void)identifier('$'); + if (parser.string[1] == '\0') { + if (getch_noeof() != '(') + error("bad symbol or expression"); + parser.type = type_none; + expression_cond(); + if (parser.expr != expr_rparen) + error("bad expression"); + switch (parser.type) { + case type_l: + return (tok_int); + case type_d: + return (tok_float); + case type_p: + return (tok_pointer); + default: + error("bad expression"); + } + } + else if ((symbol = get_symbol_by_name(parser.string))) { + switch (parser.type = symbol->type) { + case type_l: + parser.value.i = symbol->value.i; + return (tok_int); + case type_d: + parser.value.d = symbol->value.d; + return (tok_float); + default: + parser.value.p = symbol->value.p; + return (tok_pointer); + } + } + else + error("undefined symbol %s", parser.string); +} + +static token_t +primary(skip_t skip) +{ + int ch; + + switch (skip) { + case skip_none: ch = getch(); break; + case skip_ws: ch = skipws(); break; + case skip_nl: ch = skipnl(); break; + default: abort(); + } + switch (ch) { + case '%': + return (regname()); + case 'a' ... 'z': case 'A' ... 'Z': case '_': + return (identifier(ch)); + case '0' ... '9': case '+': case '-': + return (number(ch)); + case '.': + return (tok_dot); + case '"': + return (string()); + case '\'': + return (character()); + case '@': + return (dynamic()); + case '$': + return (expression()); + case EOF: + return (tok_eof); + case '\n': + return (tok_newline); + case ';': + return (tok_semicollon); + default: + error("syntax error"); + } +} + +static void +parse(void) +{ + int ch; + token_t token; + instr_t *instr; + label_t *label; + void *value; + + for (;;) { + switch (token = primary(skip_nl)) { + case tok_symbol: + ch = getch_noeof(); + if (ch == ':') { + if ((label = get_label_by_name(parser.string))) { + if (label->kind == label_kind_code_forward) { + label->kind = label_kind_code; + jit_link(label->value); + jit_note(parser.name, parser.line); + } + else + error("label %s: redefined", parser.string); + } + else { + if (parser.parsing == PARSING_DATA) { + value = data + data_offset; + label = new_label(label_kind_data, + parser.string, value); + } + else if (parser.parsing == PARSING_CODE) { + value = jit_label(); + jit_note(parser.name, parser.line); + label = new_label(label_kind_code, + parser.string, value); + } + else + error("label not in .code or .data"); + } + break; + } + ungetch(ch); + if ((instr = + (instr_t *)get_hash(instrs, parser.string)) == NULL) + error("unhandled symbol %s", parser.string); + if (parser.parsing != PARSING_CODE) + error(".code must be specified before instructions"); + (*instr->function)(); + break; + case tok_dot: + dot(); + break; + case tok_eof: + return; + default: + error("syntax error"); + } + } +} + +static int +execute(int argc, char *argv[]) +{ + int result; + label_t *label; + function_t function; + patch_t *patch, *next; + + for (patch = patches; patch; patch = next) { + next = patch->next; + label = patch->label; + if (label->kind == label_kind_code_forward) + error("undefined label %s", label->name); + switch (patch->kind) { + case patch_kind_jmp: + case patch_kind_mov: + case patch_kind_call: + jit_patch_at(patch->value, label->value); + break; + default: + abort(); + } + free(patch); + patch = next; + } + + if (flag_data == 0) { + jit_realize(); + jit_set_data(NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE); + } + + function = jit_emit(); + if (flag_verbose > 1 || flag_disasm) { + jit_print(); + fprintf(stdout, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n"); + } + if (flag_verbose > 0 || flag_disasm) { + jit_disassemble(); + fprintf(stdout, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n"); + } + + jit_clear_state(); + if (flag_disasm) + result = 0; + else + result = (*function)(argc, argv); + jit_destroy_state(); + + return (result); +} + +static void * +xmalloc(size_t size) +{ + void *pointer = malloc(size); + + if (pointer == NULL) + error("out of memory"); + + return (pointer); +} + +static void * +xrealloc(void *pointer, size_t size) +{ + pointer = realloc(pointer, size); + + if (pointer == NULL) + error("out of memory"); + + return (pointer); +} + +static void * +xcalloc(size_t nmemb, size_t size) +{ + void *pointer = calloc(nmemb, size); + + if (pointer == NULL) + error("out of memory"); + + return (pointer); +} + +static label_t * +new_label(label_kind_t kind, char *name, void *value) +{ + label_t *label; + + label = (label_t *)xmalloc(sizeof(label_t)); + label->kind = kind; + label->name = strdup(name); + label->value = value; + put_hash(labels, (entry_t *)label); + label_offset++; + return (label); +} + +static patch_t * +new_patch(patch_kind_t kind, label_t *label, void *value) +{ + patch_t *patch = (patch_t *)xmalloc(sizeof(patch_t)); + patch->kind = kind; + patch->label = label; + patch->value = value; + patch->next = patches; + patches = patch; + + return (patch); +} + +static int +bcmp_symbols(const void *left, const void *right) +{ + return (strcmp((char *)left, (*(symbol_t **)right)->name)); +} + +static int +qcmp_symbols(const void *left, const void *right) +{ + return (strcmp((*(symbol_t **)left)->name, (*(symbol_t **)right)->name)); +} + +static symbol_t * +new_symbol(char *name) +{ + symbol_t *symbol; + + if ((symbol_offset & 15) == 0) { + if ((symbol_length += 16) == 16) + symbols = (symbol_t **)xmalloc(sizeof(symbol_t *) * + symbol_length); + else + symbols = (symbol_t **)xrealloc(symbols, sizeof(symbol_t *) * + symbol_length); + } + symbol = (symbol_t *)xmalloc(sizeof(symbol_t)); + symbol->name = strdup(name); + symbols[symbol_offset++] = symbol; + qsort(symbols, symbol_offset, sizeof(symbol_t *), qcmp_symbols); + + return (symbol); +} + +static symbol_t * +get_symbol_by_name(char *name) +{ + symbol_t **symbol_pointer; + + if (symbols == NULL) + return (NULL); + symbol_pointer = (symbol_t **)bsearch(name, symbols, symbol_offset, + sizeof(symbol_t *), bcmp_symbols); + + return (symbol_pointer ? *symbol_pointer : NULL); +} + +static hash_t * +new_hash(void) +{ + hash_t *hash; + + hash = (hash_t *)xmalloc(sizeof(hash_t)); + hash->count = 0; + hash->entries = (entry_t **)xcalloc(hash->size = 32, sizeof(void *)); + + return (hash); +} + +static int +hash_string(char *name) +{ + char *ptr; + int key; + + for (key = 0, ptr = name; *ptr; ptr++) + key = (key << (key & 1)) ^ *ptr; + + return (key); +} + +static void +put_hash(hash_t *hash, entry_t *entry) +{ + entry_t *prev, *ptr; + int key = hash_string(entry->name) & (hash->size - 1); + + for (prev = ptr = hash->entries[key]; ptr; prev = ptr, ptr = ptr->next) { + if (strcmp(entry->name, ptr->name) == 0) + error("duplicated entry %s", entry->name); + } + if (prev == NULL) + hash->entries[key] = entry; + else + prev->next = entry; + entry->next = NULL; + ++hash->count; + if (hash->count > hash->size * 0.75) + rehash(hash); +} + +static entry_t * +get_hash(hash_t *hash, char *name) +{ + entry_t *entry; + int key = hash_string(name) & (hash->size - 1); + + for (entry = hash->entries[key]; entry; entry = entry->next) { + if (strcmp(entry->name, name) == 0) + return (entry); + } + return (NULL); +} + +static void +rehash(hash_t *hash) +{ + int i, size, key; + entry_t *entry, *next, **entries; + + entries = (entry_t **)xcalloc(size = hash->size * 2, sizeof(void *)); + for (i = 0; i < hash->size; i++) { + for (entry = hash->entries[i]; entry; entry = next) { + next = entry->next; + key = hash_string(entry->name) & (size - 1); + entry->next = entries[key]; + entries[key] = entry; + } + } + free(hash->entries); + hash->entries = entries; + hash->size = size; +} + +static void +usage(void) +{ +#if HAVE_GETOPT_LONG_ONLY + fprintf(stderr, "\ +Usage: %s [jit assembler options] file [jit program options]\n\ +Jit assembler options:\n\ + -help Display this information\n\ + -v[0-3] Verbose output level\n\ + -d Do not use a data buffer\n\ + -D<macro>[=<val>] Preprocessor options\n" +# if defined(__i386__) && __WORDSIZE == 32 +" -mx87=1 Force using x87 when sse2 available\n" +# endif +# if defined(__i386__) || defined(__x86_64__) +" -msse4_1=0 Do not use sse4_1 instructions when available\n" +# endif +# if defined(__arm__) +" -mcpu=<val> Force cpu version (4, 5, 6 or 7)\n\ + -mthumb[=0|1] Enable or disable thumb\n\ + -mvfp=<val> Set vpf version (0 to disable)\n\ + -mneon[=0|1] Enable or disable neon\n" +# endif + , progname); +#else + fprintf(stderr, "\ +Usage: %s [jit assembler options] file [jit program options]\n\ +Jit assembler options:\n\ + -h Display this information\n\ + -v Verbose output level\n\ + -D<macro>[=<val>] Preprocessor options\n", progname); +#endif + finish_jit(); + exit(1); +} + +int +main(int argc, char *argv[]) +{ +#if HAVE_GETOPT_LONG_ONLY + static const char *short_options = "dv::"; + static struct option long_options[] = { + { "help", 0, 0, 'h' }, + { "data", 2, 0, 'd' }, +# if defined(__i386__) && __WORDSIZE == 32 + { "mx87", 2, 0, '7' }, +# endif +# if defined(__i386__) || defined(__x86_64__) + { "msse4_1", 2, 0, '4' }, +# endif +# if defined(__arm__) + { "mcpu", 2, 0, 'c' }, + { "mthumb", 2, 0, 't' }, + { "mvfp", 2, 0, 'f' }, + { "mneon", 2, 0, 'n' }, +# endif + { 0, 0, 0, 0 } + }; +#else +#endif /* HAVE_GETOPT_LONG_ONLY */ + int offset; + char *endptr; + int opt_index; + int opt_short; + char cmdline[8192]; + +#if defined(__CYGWIN__) + /* Cause a compile warning about redefinition without dllimport + * attribute, *but* cause correct linkage if liblightning.a is + * linked to binutils (that happens to have an internal + * getopt* implementation and an apparently conflicting + * optind global variable) */ + extern int optind; + optind = 1; +#endif + + progname = argv[0]; + + init_jit(progname); + +#if defined(__sgi) + DL_HANDLE = dlopen(NULL, RTLD_LAZY); +#endif + + flag_data = 1; +#if HAVE_GETOPT_LONG_ONLY + for (;;) { + if ((opt_short = getopt_long_only(argc, argv, short_options, + long_options, &opt_index)) < 0) + break; + switch (opt_short) { + case 'h': + default: + usage(); + break; + case 'v': + if (optarg) { + flag_verbose = strtol(optarg, &endptr, 10); + if (*endptr || flag_verbose < 0) + usage(); + } + else + flag_verbose = 1; + break; + case 'd': + flag_data = 0; + break; +#if defined(__i386__) && __WORDSIZE == 32 + case '7': + if (optarg) { + if (strcmp(optarg, "") == 0 || strcmp(optarg, "1") == 0) + jit_cpu.sse2 = 0; + else if (strcmp(optarg, "0")) + usage(); + } + else + jit_cpu.sse2 = 0; + break; +#endif +#if defined(__i386__) || defined(__x86_64__) + case '4': + if (optarg) { + if (strcmp(optarg, "0") == 0) + jit_cpu.sse4_2 = 0; + else if (strcmp(optarg, "1")) + usage(); + } + break; +#endif +#if defined(__arm__) + case 'c': + if (optarg) { + offset = strtol(optarg, &endptr, 10); + if (*endptr || offset < 0) + usage(); + if (offset < jit_cpu.version) + jit_cpu.version = offset; + } + break; + case 't': + if (optarg) { + if (strcmp(optarg, "0") == 0) + jit_cpu.thumb = 0; + else if (strcmp(optarg, "1") && strcmp(optarg, "2")) + usage(); + } + break; + case 'f': +# if !defined(__ARM_PCS_VFP) + /* Do not allow overrinding hard float abi */ + if (optarg) { + offset = strtol(optarg, &endptr, 10); + if (*endptr || offset < 0) + usage(); + if (offset < jit_cpu.vfp) + jit_cpu.vfp = offset; + } +# endif + break; + case 'n': + if (optarg) { + if (strcmp(optarg, "0") == 0) + jit_cpu.neon = 0; + else if (strcmp(optarg, "1")) + usage(); + } + break; +#endif + } + } +#else + while ((opt_short = getopt(argc, argv, "hvd")) >= 0) { + if (opt_short == 'v') + ++flag_verbose; + else if (opt_short == 'd') + flag_data = 0; + else + usage(); + } +#endif + + opt_index = optind; +#if defined(__hpux) + /* Workaround */ + if (opt_index < argc && argv[opt_index][0] == '-') + ++opt_index; +#endif + if (opt_index < 0 || opt_index >= argc) + usage(); + if (strcmp(argv[opt_index], "-") == 0) + strcpy(parser.name, "<stdin>"); + else { + if ((endptr = strrchr(argv[opt_index], '/')) == NULL) + endptr = argv[opt_index]; + else + ++endptr; + strncpy(parser.name, endptr, sizeof(parser.name)); + parser.name[sizeof(parser.name) - 1] = '\0'; + } +#if __clang__ +# define cc "clang" +#else +# define cc "gcc" +#endif + opt_short = snprintf(cmdline, sizeof(cmdline), cc " -E -x c %s", argv[opt_index]); + for (++opt_index; opt_index < argc; opt_index++) { + if (argv[opt_index][0] == '-') + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " %s", argv[opt_index]); + else { + --opt_index; + break; + } + } + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__WORDSIZE=%d", __WORDSIZE); + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__LITTLE_ENDIAN=%d", __LITTLE_ENDIAN); + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__BIG_ENDIAN=%d", __BIG_ENDIAN); + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__BYTE_ORDER=%d", __BYTE_ORDER); +#if defined(__i386__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__i386__=1"); +#endif +#if defined(__x86_64__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__x86_64__=1"); +#endif +#if defined(__mips__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__mips__=1"); +#endif +#if defined(__arm__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__arm__=1"); +#endif +#if defined(__powerpc__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__ppc__=1"); +#endif +#if defined(__sparc__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__sparc__=1"); +#endif +#if defined(__ia64__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__ia64__=1"); +#endif +#if defined(__hppa__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__hppa__=1"); +#endif +#if defined(_AIX) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D_AIX=1"); +#endif +#if defined(__sgi__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__sgi__=1"); +#endif +#if defined(__aarch64__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__aarch64__=1"); +#endif +#if defined(__s390__) || defined(__s390x__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__s390__=1"); +#endif +#if defined(__alpha__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__alpha__=1"); +#endif + if ((parser.fp = popen(cmdline, "r")) == NULL) + error("cannot execute %s", cmdline); + + parser.line = 1; + parser.string = (char *)xmalloc(parser.length = 4096); + +#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) + /* double precision 0x200 + * round nearest 0x000 + * invalid operation mask 0x001 + * denormalized operand mask 0x002 + * zero divide mask 0x004 + * precision (inexact) mask 0x020 + */ + { + fpu_control_t fpu_control = 0x027f; + _FPU_SETCW(fpu_control); + } +#endif + + _jit = jit_new_state(); + + instrs = new_hash(); + for (offset = 0; + offset < (int)(sizeof(instr_vector) / sizeof(instr_vector[0])); + offset++) + put_hash(instrs, (entry_t *)(instr_vector + offset)); + + labels = new_hash(); + + parse(); + pclose(parser.fp); + parser.fp = NULL; + + for (opt_short = 0; opt_index < argc; opt_short++, opt_index++) + argv[opt_short] = argv[opt_index]; + argv[opt_short] = NULL; + argc = opt_short; + execute(argc, argv); + + finish_jit(); + + return (0); +} diff --git a/deps/lightning/check/nodata.c b/deps/lightning/check/nodata.c new file mode 100644 index 0000000..0e594c3 --- /dev/null +++ b/deps/lightning/check/nodata.c @@ -0,0 +1,106 @@ +/* + * Simple test of using an alternate buffer for the code. + */ + +#include <lightning.h> +#include <stdio.h> +#include <assert.h> +#include <sys/mman.h> +#if defined(__sgi) +# include <fcntl.h> +#endif + +#ifndef MAP_ANON +# define MAP_ANON MAP_ANONYMOUS +# ifndef MAP_ANONYMOUS +# define MAP_ANONYMOUS 0 +# endif +#endif + +#if !defined(__sgi) +#define mmap_fd -1 +#endif + +jit_uint8_t *data; +jit_state_t *_jit; +jit_word_t data_length; +jit_word_t note_length; +#if defined(__sgi) +int mmap_fd; +#endif +void (*function)(void); + +void +gencode(jit_word_t flags) +{ + jit_word_t offset; + jit_word_t length; + + _jit = jit_new_state(); + + jit_name("main"); + jit_prolog(); + jit_prepare(); + jit_pushargi((jit_word_t)"%f\n"); + jit_ellipsis(); + jit_pushargi_d(1.5); + jit_finishi(printf); + jit_note("nodata.c", __LINE__); + + /* call to jit_realize() is only required when using an alternate + * code buffer. Note that not using mmap'ed memory may not work + * on several ports and/or operating system versions */ + jit_realize(); + + if (jit_get_data(&data_length, ¬e_length) != NULL) + abort(); + + length = 0; + if (!(flags & JIT_DISABLE_DATA)) + length += data_length; + if (!(flags & JIT_DISABLE_NOTE)) + length += note_length; + + /* check that a too small buffer fails */ + if (flags) + jit_set_data(length ? data : NULL, length, flags); + + /* and calling again with enough space works */ + offset = (length + 7) & -8; + function = jit_emit(); + if (function == NULL) + abort(); + + jit_clear_state(); + (*function)(); + jit_destroy_state(); +} + +int +main(int argc, char *argv[]) +{ +#if defined(__sgi) + mmap_fd = open("/dev/zero", O_RDWR); +#endif + + data = mmap(NULL, 4096, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, mmap_fd, 0); + assert(data != MAP_FAILED); +#if defined(__sgi) + close(mmap_fd); +#endif + + init_jit(argv[0]); + + gencode(0); + gencode(JIT_DISABLE_DATA); + gencode(JIT_DISABLE_NOTE); + gencode(JIT_DISABLE_DATA | JIT_DISABLE_NOTE); + + finish_jit(); + + munmap(data, 4096); + + return (0); +} diff --git a/deps/lightning/check/put.ok b/deps/lightning/check/put.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/put.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/put.tst b/deps/lightning/check/put.tst new file mode 100644 index 0000000..a7e39e1 --- /dev/null +++ b/deps/lightning/check/put.tst @@ -0,0 +1,428 @@ +.data 8 +ok: +.c "ok" + +.code + jmpi main + + name putr +putr: + prolog + frame 160 + arg $ac + arg $auc + arg $as + arg $aus + arg $ai +#if __WORDSIZE == 64 + arg $aui + arg $al +#endif + arg_f $af + arg_d $ad + arg $a +#if __WORDSIZE == 64 + arg $_l + arg $_ui +#endif + arg $_i + arg $_us + arg $_s + arg $_uc + arg $_c + getarg_c %r0 $ac + negr %r0 %r0 + putargr %r0 $ac + getarg_uc %r0 $auc + negr %r0 %r0 + putargr %r0 $auc + getarg_s %r0 $as + negr %r0 %r0 + putargr %r0 $as + getarg_us %r0 $aus + negr %r0 %r0 + putargr %r0 $aus + getarg_i %r0 $ai + negr %r0 %r0 + putargr %r0 $ai +#if __WORDSIZE == 64 + getarg_ui %r0 $aui + negr %r0 %r0 + putargr %r0 $aui + getarg_l %r0 $al + negr %r0 %r0 + putargr %r0 $al +#endif + getarg_f %f0 $af + negr_f %f0 %f0 + putargr_f %f0 $af + getarg_d %f0 $ad + negr_d %f0 %f0 + putargr_d %f0 $ad + getarg %r0 $a + negr %r0 %r0 + putargr %r0 $a +#if __WORDSIZE == 64 + getarg_l %r0 $_l + negr %r0 %r0 + putargr %r0 $_l + getarg_ui %r0 $_ui + negr %r0 %r0 + putargr %r0 $_ui +#endif + getarg_i %r0 $_i + negr %r0 %r0 + putargr %r0 $_i + getarg_us %r0 $_us + negr %r0 %r0 + putargr %r0 $_us + getarg_s %r0 $_s + negr %r0 %r0 + putargr %r0 $_s + getarg_uc %r0 $_uc + negr %r0 %r0 + putargr %r0 $_uc + getarg_c %r0 $_c + negr %r0 %r0 + putargr %r0 $_c + jmpi _putr +rputr: + putargi 17 $ac + putargi 16 $auc + putargi 15 $as + putargi 14 $aus + putargi 13 $ai +#if __WORDSIZE == 64 + putargi 12 $aui + putargi 11 $al +#endif + putargi_f 10 $af + putargi_d 9 $ad + putargi 8 $a +#if __WORDSIZE == 64 + putargi 7 $_l + putargi 6 $_ui +#endif + putargi 5 $_i + putargi 4 $_us + putargi 3 $_s + putargi 2 $_uc + putargi 1 $_c + jmpi _puti +rputi: + ret + epilog + + name _putr +_putr: + prolog + tramp 160 + arg $ac + arg $auc + arg $as + arg $aus + arg $ai +#if __WORDSIZE == 64 + arg $aui + arg $al +#endif + arg_f $af + arg_d $ad + arg $a +#if __WORDSIZE == 64 + arg $_l + arg $_ui +#endif + arg $_i + arg $_us + arg $_s + arg $_uc + arg $_c + getarg_c %r0 $ac + beqi rac %r0 -1 + calli @abort +rac: + getarg_uc %r0 $auc + beqi rauc %r0 $(-2 & 0xff) + calli @abort +rauc: + getarg_s %r0 $as + beqi ras %r0 -3 + calli @abort +ras: + getarg_us %r0 $aus + beqi raus %r0 $(-4 & 0xffff) + calli @abort +raus: + getarg_i %r0 $ai + beqi rai %r0 -5 + calli @abort +rai: +#if __WORDSIZE == 64 + getarg_ui %r0 $aui + beqi raui %r0 $(-6 & 0xffffffff) + calli @abort +raui: + getarg_l %r0 $al + beqi ral %r0 -7 + calli @abort +ral: +#endif + getarg_f %f0 $af + beqi_f raf %f0 -8 + calli @abort +raf: + getarg_d %f0 $ad + beqi_d rad %f0 -9 + calli @abort +rad: + getarg %r0 $a + beqi ra %r0 -10 + calli @abort +ra: +#if __WORDSIZE == 64 + getarg %r0 $_l + beqi r_l %r0 -11 + calli @abort +r_l: + getarg_ui %r0 $_ui + beqi r_ui %r0 $(-12 & 0xffffffff) + calli @abort +r_ui: +#endif + getarg_i %r0 $_i + beqi r_i %r0 -13 + calli @abort +r_i: + getarg_us %r0 $_us + beqi r_us %r0 $(-14 & 0xffff) + calli @abort +r_us: + getarg_s %r0 $_s + beqi r_s %r0 -15 + calli @abort +r_s: + getarg_uc %r0 $_uc + beqi r_uc %r0 $(-16 & 0xff) + calli @abort +r_uc: + getarg_c %r0 $_c + beqi r_c %r0 -17 + calli @abort +r_c: + jmpi rputr + epilog + + name _puti +_puti: + prolog + tramp 160 + arg $ac + arg $auc + arg $as + arg $aus + arg $ai +#if __WORDSIZE == 64 + arg $aui + arg $al +#endif + arg_f $af + arg_d $ad + arg $a +#if __WORDSIZE == 64 + arg $_l + arg $_ui +#endif + arg $_i + arg $_us + arg $_s + arg $_uc + arg $_c + getarg_c %r0 $ac + beqi iac %r0 17 + calli @abort +iac: + getarg_uc %r0 $auc + beqi iauc %r0 16 + calli @abort +iauc: + getarg_s %r0 $as + beqi ias %r0 15 + calli @abort +ias: + getarg_us %r0 $aus + beqi iaus %r0 14 + calli @abort +iaus: + getarg_i %r0 $ai + beqi iai %r0 13 + calli @abort +iai: +#if __WORDSIZE == 64 + getarg_ui %r0 $aui + beqi iaui %r0 12 + calli @abort +iaui: + getarg_l %r0 $al + beqi ial %r0 11 + calli @abort +ial: +#endif + getarg_f %f0 $af + beqi_f iaf %f0 10 + calli @abort +iaf: + getarg_d %f0 $ad + beqi_d iad %f0 9 + calli @abort +iad: + getarg %r0 $a + beqi ia %r0 8 + calli @abort +ia: +#if __WORDSIZE == 64 + getarg %r0 $_l + beqi i_l %r0 7 + calli @abort +i_l: + getarg_ui %r0 $_ui + beqi i_ui %r0 6 + calli @abort +i_ui: +#endif + getarg_i %r0 $_i + beqi i_i %r0 5 + calli @abort +i_i: + getarg_us %r0 $_us + beqi i_us %r0 4 + calli @abort +i_us: + getarg_s %r0 $_s + beqi i_s %r0 3 + calli @abort +i_s: + getarg_uc %r0 $_uc + beqi i_uc %r0 2 + calli @abort +i_uc: + getarg_c %r0 $_c + beqi i_c %r0 1 + calli @abort +i_c: + jmpi rputi + epilog + + name putf +putf: + prolog + frame 56 + arg $i1 + arg_d $d1 + arg_f $f1 + arg_f $f2 + arg_f $f3 + arg $i2 + arg_d $d2 + getarg %r0 $i1 + addi %r0 %r0 1 + putargr %r0 $i1 + getarg_d %f0 $d1 + addi_d %f0 %f0 1 + putargr_d %f0 $d1 + getarg_f %f0 $f1 + addi_f %f0 %f0 1 + putargr_f %f0 $f1 + getarg_f %f0 $f2 + subi_f %f0 %f0 1 + putargr_f %f0 $f2 + putargi_f -5 $f3 + putargi -6 $i2 + putargi_d -7 $d2 + jmpi _putf +rputf: + ret + epilog + + name _putf +_putf: + prolog + tramp 56 + arg $i1 + arg_d $d1 + arg_f $f1 + arg_f $f2 + arg_f $f3 + arg $i2 + arg_d $d2 + getarg %r0 $i1 + beqi fi1 %r0 2 + calli @abort +fi1: + getarg_d %f0 $d1 + beqi_d fd1 %f0 3 + calli @abort +fd1: + getarg_f %f0 $f1 + beqi_f ff1 %f0 4 + calli @abort +ff1: + getarg_f %f0 $f2 + beqi_f ff2 %f0 3 + calli @abort +ff2: + getarg_f %f0 $f3 + beqi_f ff3 %f0 -5 + calli @abort +ff3: + getarg %r0 $i2 + beqi fi2 %r0 -6 + calli @abort +fi2: + getarg_d %f0 $d2 + beqi_d fd2 %f0 -7 + calli @abort +fd2: + jmpi rputf + epilog + + name main +main: + prolog + prepare + pushargi 1 + pushargi 2 + pushargi 3 + pushargi 4 + pushargi 5 +#if __WORDSIZE == 64 + pushargi 6 + pushargi 7 +#endif + pushargi_f 8 + pushargi_d 9 + pushargi 10 +#if __WORDSIZE == 64 + pushargi 11 + pushargi 12 +#endif + pushargi 13 + pushargi 14 + pushargi 15 + pushargi 16 + pushargi 17 + finishi putr + prepare + pushargi 1 + pushargi_d 2 + pushargi_f 3 + pushargi_f 4 + pushargi_f 5 + pushargi 6 + pushargi_d 7 + finishi putf + prepare + pushargi ok + finishi @puts + ret + epilog diff --git a/deps/lightning/check/qalu.inc b/deps/lightning/check/qalu.inc new file mode 100644 index 0000000..9daca82 --- /dev/null +++ b/deps/lightning/check/qalu.inc @@ -0,0 +1,122 @@ +.data 8 +ok: +.c "ok\n" + +/* r0,r1 = r2 op r3 */ +#define QALUR(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + movi %R2 I0 \ + movi %R3 I1 \ + OP##r##T %R0 %R1 %R2 %R3 \ + bnei OP##T##N##rlo##R0##R1##R2##R3 %R0 LO \ + bnei OP##T##N##rlo##R0##R1##R2##R3 %R1 HI \ + bnei OP##T##N##rlo##R0##R1##R2##R3 %R2 I0 \ + beqi OP##T##N##rhi##R0##R1##R2##R3 %R3 I1 \ +OP##T##N##rlo##R0##R1##R2##R3: \ + calli @abort \ +OP##T##N##rhi##R0##R1##R2##R3: + +/* r0,r1 = r2 op i0 */ +#define QALUI(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + movi %R2 I0 \ + movi %R3 HI \ + OP##i##T %R0 %R1 %R2 I1 \ + bnei OP##T##N##ilo##R0##R1##R2##R3 %R0 LO \ + bner OP##T##N##ilo##R0##R1##R2##R3 %R1 %R3 \ + beqi OP##T##N##ihi##R0##R1##R2##R3 %R2 I0 \ +OP##T##N##ilo##R0##R1##R2##R3: \ + calli @abort \ +OP##T##N##ihi##R0##R1##R2##R3: + +/* r0,r1 = r0 op r1 */ +#define QALUX(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + movi %R0 I0 \ + movi %R1 I1 \ + movi %R2 LO \ + movi %R3 HI \ + OP##r##T %R0 %R1 %R0 %R1 \ + bner OP##T##N##0lo##R0##R1##R2##R3 %R0 %R2 \ + beqr OP##T##N##0hi##R0##R1##R2##R3 %R1 %R3 \ +OP##T##N##0lo##R0##R1##R2##R3: \ + calli @abort \ +OP##T##N##0hi##R0##R1##R2##R3: + +/* r0,r1 = r1 op r0 */ +#define QALUY(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + movi %R1 I0 \ + movi %R0 I1 \ + movi %R2 LO \ + movi %R3 HI \ + OP##r##T %R0 %R1 %R1 %R0 \ + bner OP##T##N##1lo##R0##R1##R2##R3 %R0 %R2 \ + beqr OP##T##N##1hi##R0##R1##R2##R3 %R1 %R3 \ +OP##T##N##1lo##R0##R1##R2##R3: \ + calli @abort \ +OP##T##N##1hi##R0##R1##R2##R3: + +/* r0,r1 = r0 op r3 */ +#define QALUZ(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + movi %R0 I0 \ + movi %R3 I1 \ + movi %R2 LO \ + OP##r##T %R0 %R1 %R0 %R3 \ + bner OP##T##N##2lo##R0##R1##R2##R3 %R0 %R2 \ + bnei OP##T##N##2lo##R0##R1##R2##R3 %R1 HI \ + beqi OP##T##N##2hi##R0##R1##R2##R3 %R3 I1 \ +OP##T##N##2lo##R0##R1##R2##R3: \ + calli @abort \ +OP##T##N##2hi##R0##R1##R2##R3: + +/* r0,r1 = r2 op r1 */ +#define QALUW(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + movi %R2 I0 \ + movi %R1 I1 \ + movi %R3 LO \ + OP##r##T %R0 %R1 %R2 %R1 \ + bner OP##T##N##3lo##R0##R1##R2##R3 %R0 %R3 \ + bnei OP##T##N##3lo##R0##R1##R2##R3 %R1 HI \ + beqi OP##T##N##3hi##R0##R1##R2##R3 %R2 I0 \ +OP##T##N##3lo##R0##R1##R2##R3: \ + calli @abort \ +OP##T##N##3hi##R0##R1##R2##R3: + +#define QALU2(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + QALUR(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + QALUI(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + QALUX(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + QALUY(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + QALUZ(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + QALUW(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) + +#define QALU1(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + QALU2(N, T, OP, I0, I1, LO, HI, R0, R1, R2, R3) \ + QALU2(N, T, OP, I0, I1, LO, HI, R0, R1, R3, R2) \ + QALU2(N, T, OP, I0, I1, LO, HI, R0, R2, R1, R3) \ + QALU2(N, T, OP, I0, I1, LO, HI, R0, R2, R3, R1) \ + QALU2(N, T, OP, I0, I1, LO, HI, R0, R3, R1, R2) \ + QALU2(N, T, OP, I0, I1, LO, HI, R0, R3, R2, R1) \ + QALU2(N, T, OP, I0, I1, LO, HI, R1, R0, R2, R3) \ + QALU2(N, T, OP, I0, I1, LO, HI, R1, R0, R3, R2) \ + QALU2(N, T, OP, I0, I1, LO, HI, R1, R2, R0, R3) \ + QALU2(N, T, OP, I0, I1, LO, HI, R1, R2, R3, R0) \ + QALU2(N, T, OP, I0, I1, LO, HI, R1, R3, R0, R2) \ + QALU2(N, T, OP, I0, I1, LO, HI, R1, R3, R2, R0) \ + QALU2(N, T, OP, I0, I1, LO, HI, R2, R1, R0, R3) \ + QALU2(N, T, OP, I0, I1, LO, HI, R2, R1, R3, R0) \ + QALU2(N, T, OP, I0, I1, LO, HI, R2, R0, R1, R3) \ + QALU2(N, T, OP, I0, I1, LO, HI, R2, R0, R3, R1) \ + QALU2(N, T, OP, I0, I1, LO, HI, R2, R3, R1, R0) \ + QALU2(N, T, OP, I0, I1, LO, HI, R2, R3, R0, R1) \ + QALU2(N, T, OP, I0, I1, LO, HI, R3, R1, R2, R0) \ + QALU2(N, T, OP, I0, I1, LO, HI, R3, R1, R0, R2) \ + QALU2(N, T, OP, I0, I1, LO, HI, R3, R2, R1, R0) \ + QALU2(N, T, OP, I0, I1, LO, HI, R3, R2, R0, R1) \ + QALU2(N, T, OP, I0, I1, LO, HI, R3, R0, R1, R2) \ + QALU2(N, T, OP, I0, I1, LO, HI, R3, R0, R2, R1) + +#define QALU(N, T, OP, I0, I1, LO, HI) \ + QALU1(N, T, OP, I0, I1, LO, HI, v0, v1, v2, r0) \ + QALU1(N, T, OP, I0, I1, LO, HI, v0, v1, v2, r1) \ + QALU1(N, T, OP, I0, I1, LO, HI, v0, v1, v2, r2) \ + QALU1(N, T, OP, I0, I1, LO, HI, v1, v2, r0, r1) \ + QALU1(N, T, OP, I0, I1, LO, HI, v1, v2, r0, r2) \ + QALU1(N, T, OP, I0, I1, LO, HI, v2, r0, r1, r2) diff --git a/deps/lightning/check/qalu_div.ok b/deps/lightning/check/qalu_div.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/qalu_div.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/qalu_div.tst b/deps/lightning/check/qalu_div.tst new file mode 100644 index 0000000..198dfbb --- /dev/null +++ b/deps/lightning/check/qalu_div.tst @@ -0,0 +1,18 @@ +#include "qalu.inc" + +.code + prolog +#define QDIV(N, I0, I1, LO, HI) QALU(N, , qdiv, I0, I1, LO, HI) +#define UQDIV(N, I0, I1, LO, HI) QALU(N, _u, qdiv, I0, I1, LO, HI) + QDIV(0, 10, 3, 3, 1) + QDIV(1, -33, 9, -3, -6) + QDIV(2, -41, -7, 5, -6) + QDIV(3, 65536, 4096, 16, 0) + UQDIV(4, -1, -2, 1, 1) + UQDIV(5, -2, -5, 1, 3) + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/qalu_mul.ok b/deps/lightning/check/qalu_mul.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/qalu_mul.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/qalu_mul.tst b/deps/lightning/check/qalu_mul.tst new file mode 100644 index 0000000..64b95a9 --- /dev/null +++ b/deps/lightning/check/qalu_mul.tst @@ -0,0 +1,31 @@ +#include "qalu.inc" + +.code + prolog +#define QMUL(N, I0, I1, LO, HI) QALU(N, , qmul, I0, I1, LO, HI) +#define UQMUL(N, I0, I1, LO, HI) QALU(N, _u, qmul, I0, I1, LO, HI) + QMUL(0, -2, -1, 2, 0) + QMUL(1, 0, -1, 0, 0) + QMUL(2, -1, 0, 0, 0) + QMUL(3, 1, -1, -1, -1) +#if __WORDSIZE == 32 + QMUL(4, 0x7ffff, 0x7ffff, 0xfff00001, 0x3f) + UQMUL(5, 0xffffff, 0xffffff, 0xfe000001, 0xffff) + QMUL(6, 0x80000000, -2, 0, 1) + QMUL(7, 0x80000000, 2, 0, -1) + QMUL(8, 0x80000001, 3, 0x80000003, -2) + QMUL(9, 0x80000001, -3, 0x7ffffffd, 1) +#else + QMUL(4, 0x7ffffffff, 0x7ffffffff, 0xfffffff000000001, 0x3f) + UQMUL(5, 0xffffffffff, 0xffffffffff, 0xfffffe0000000001, 0xffff) + QMUL(6, 0x8000000000000000, -2, 0, 1) + QMUL(7, 0x8000000000000000, 2, 0, -1) + QMUL(8, 0x8000000000000001, 3, 0x8000000000000003, -2) + QMUL(9, 0x8000000000000001, -3, 0x7ffffffffffffffd, 1) +#endif + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/range.ok b/deps/lightning/check/range.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/range.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/range.tst b/deps/lightning/check/range.tst new file mode 100644 index 0000000..35ddf64 --- /dev/null +++ b/deps/lightning/check/range.tst @@ -0,0 +1,504 @@ +#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 rsb(a, b) $(b - a) +#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) + +#define alu2(N, X, L, R, V) \ + movi %r1 L \ + N##i %r0 %r1 R \ + beqi X %r0 V \ + calli @abort \ +X: +#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, 3, N, $(3<<N)) +#define _rsh(N) \ + alu2(rsh, R##N, $(1<<63), N, $((1<<63)>>N)) + +#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 reset(V) \ + prepare \ + pushargi buf \ + pushargi V \ + pushargi $(M64 + 8) \ + finishi @memset + +#define stx(T, N, O, V) \ + movi %r0 V \ + stxi##T O %v0 %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) \ + movi %r0 0 \ + ldxi##T %r0 %v0 O \ + beqi ldx##T##N##M %r0 V \ + calli @abort \ +ldx##T##N##M: +#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) \ + movi##T %f0 V \ + stxi##T O %v0 %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) \ + movi##T %f0 0 \ + ldxi##T %f0 %v0 O \ + beqi##T ldf##T##N##M %f0 V \ + calli @abort \ +ldf##T##N##M: +#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) \ + movi %v0 buf \ + stx2(_c, a, 0x5a) \ + ldx2(_c, a, 0x5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx2(_c, b, 0x5a) \ + ldx2(_c, b, 0x5a) +#define ldst_uc() \ + reset(0xa5) \ + movi %v0 buf \ + stx2(_c, a, 0x5a) \ + ldx2(_uc, a, 0x5a) \ + movi %v0 $(buf + M64) \ + stx2(_c, b, 0x5a) \ + ldx2(_uc, b, 0x5a) +#define ldst_s() \ + reset(0xa5) \ + movi %v0 buf \ + stx2(_s, a, 0x5a5a) \ + ldx2(_s, a, 0x5a5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx2(_s, b, 0x5a5a) \ + ldx2(_s, b, 0x5a5a) +#define ldst_us() \ + reset(0xa5) \ + movi %v0 buf \ + stx2(_s, a, 0x5a5a) \ + ldx2(_us, a, 0x5a5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx2(_s, b, 0x5a5a) \ + ldx2(_us, b, 0x5a5a) +#define ldst_i() \ + reset(0xa5) \ + movi %v0 buf \ + stx4(_i, a, 0x5a5a5a5a) \ + ldx4(_i, a, 0x5a5a5a5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx4(_i, b, 0x5a5a5a5a) \ + ldx4(_i, b, 0x5a5a5a5a) +#define ldst_ui() \ + reset(0xa5) \ + movi %v0 buf \ + stx4(_i, a, 0x5a5a5a5a) \ + ldx4(_ui, a, 0x5a5a5a5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx4(_i, b, 0x5a5a5a5a) \ + ldx4(_ui, b, 0x5a5a5a5a) +#define ldst_l() \ + reset(0xa5) \ + movi %v0 buf \ + stx8(_l, a, 0x5a5a5a5a5a5a5a5a) \ + ldx8(_l, a, 0x5a5a5a5a5a5a5a5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx8(_l, b, 0x5a5a5a5a5a5a5a5a) \ + ldx8(_l, b, 0x5a5a5a5a5a5a5a5a) +#define ldst_f() \ + reset(0xa5) \ + movi %v0 buf \ + stf4(_f, a, 0.5) \ + ldf4(_f, a, 0.5) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stf4(_f, b, 0.5) \ + ldf4(_f, b, 0.5) +#define ldst_d() \ + reset(0xa5) \ + movi %v0 buf \ + stf8(_d, a, 0.5) \ + ldf8(_d, a, 0.5) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stf8(_d, b, 0.5) \ + ldf8(_d, b, 0.5) + +.data 67112960 +buf: +.size M64 +.size 8 +ok: +.c "ok" + +.code + prolog + + alu(add) + alu(sub) + alu(rsb) + 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() + + prepare + pushargi ok + finishi @puts + ret + epilog diff --git a/deps/lightning/check/ranger.ok b/deps/lightning/check/ranger.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/ranger.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/ranger.tst b/deps/lightning/check/ranger.tst new file mode 100644 index 0000000..de80196 --- /dev/null +++ b/deps/lightning/check/ranger.tst @@ -0,0 +1,507 @@ +#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 rsb(a, b) $(b - a) +#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) + +#define alu2(N, X, L, R, V) \ + movi %r1 L \ + movi %r2 R \ + N##r %r0 %r1 %r2 \ + beqi X %r0 V \ + calli @abort \ +X: +#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, 3, N, $(3<<N)) +#define _rsh(N) \ + alu2(rsh, R##N, $(1<<63), N, $((1<<63)>>N)) + +#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 reset(V) \ + prepare \ + pushargi buf \ + pushargi V \ + pushargi $(M64 + 8) \ + finishi @memset + +#define stx(T, N, O, V) \ + movi %r0 V \ + movi %r1 O \ + stxr##T %r1 %v0 %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) \ + movi %r0 0 \ + ldxi##T %r0 %v0 O \ + beqi ldx##T##N##M %r0 V \ + calli @abort \ +ldx##T##N##M: +#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) \ + movi##T %f0 V \ + movi %r0 O \ + stxr##T %r0 %v0 %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) \ + movi##T %f0 0 \ + ldxi##T %f0 %v0 O \ + beqi##T ldf##T##N##M %f0 V \ + calli @abort \ +ldf##T##N##M: +#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) \ + movi %v0 buf \ + stx2(_c, a, 0x5a) \ + ldx2(_c, a, 0x5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx2(_c, b, 0x5a) \ + ldx2(_c, b, 0x5a) +#define ldst_uc() \ + reset(0xa5) \ + movi %v0 buf \ + stx2(_c, a, 0x5a) \ + ldx2(_uc, a, 0x5a) \ + movi %v0 $(buf + M64) \ + stx2(_c, b, 0x5a) \ + ldx2(_uc, b, 0x5a) +#define ldst_s() \ + reset(0xa5) \ + movi %v0 buf \ + stx2(_s, a, 0x5a5a) \ + ldx2(_s, a, 0x5a5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx2(_s, b, 0x5a5a) \ + ldx2(_s, b, 0x5a5a) +#define ldst_us() \ + reset(0xa5) \ + movi %v0 buf \ + stx2(_s, a, 0x5a5a) \ + ldx2(_us, a, 0x5a5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx2(_s, b, 0x5a5a) \ + ldx2(_us, b, 0x5a5a) +#define ldst_i() \ + reset(0xa5) \ + movi %v0 buf \ + stx4(_i, a, 0x5a5a5a5a) \ + ldx4(_i, a, 0x5a5a5a5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx4(_i, b, 0x5a5a5a5a) \ + ldx4(_i, b, 0x5a5a5a5a) +#define ldst_ui() \ + reset(0xa5) \ + movi %v0 buf \ + stx4(_i, a, 0x5a5a5a5a) \ + ldx4(_ui, a, 0x5a5a5a5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx4(_i, b, 0x5a5a5a5a) \ + ldx4(_ui, b, 0x5a5a5a5a) +#define ldst_l() \ + reset(0xa5) \ + movi %v0 buf \ + stx8(_l, a, 0x5a5a5a5a5a5a5a5a) \ + ldx8(_l, a, 0x5a5a5a5a5a5a5a5a) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stx8(_l, b, 0x5a5a5a5a5a5a5a5a) \ + ldx8(_l, b, 0x5a5a5a5a5a5a5a5a) +#define ldst_f() \ + reset(0xa5) \ + movi %v0 buf \ + stf4(_f, a, 0.5) \ + ldf4(_f, a, 0.5) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stf4(_f, b, 0.5) \ + ldf4(_f, b, 0.5) +#define ldst_d() \ + reset(0xa5) \ + movi %v0 buf \ + stf8(_d, a, 0.5) \ + ldf8(_d, a, 0.5) \ + reset(0xa5) \ + movi %v0 $(buf + M64) \ + stf8(_d, b, 0.5) \ + ldf8(_d, b, 0.5) + +.data 67112960 +buf: +.size M64 +.size 8 +ok: +.c "ok" + +.code + prolog + + alu(add) + alu(sub) + alu(rsb) + 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() + + prepare + pushargi ok + finishi @puts + ret + epilog diff --git a/deps/lightning/check/ret.ok b/deps/lightning/check/ret.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/ret.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/ret.tst b/deps/lightning/check/ret.tst new file mode 100644 index 0000000..de1d82c --- /dev/null +++ b/deps/lightning/check/ret.tst @@ -0,0 +1,51 @@ +.data 16 +ok: +.c "ok" + +.code + jmpi main + +/* + * very simple test on purpose because otherwise it would not trigger + * the bug where the retr %r0 or retr_d %f0 would be omitted because + * the argument was already the return register, but the register end + * clobbered by another instruction, like the div*, and the wrong + * value returned because the retr* was removed and this way, lost + * information that the register was live at function exit. + */ + +check_r0: + prolog + movi %r0 1 + movi %r2 10 + // on x86 this changes %rax on other arches could use %r0 as temporary + divi %r1 %r2 3 + // %r0 must still be 1 + retr %r0 + epilog + +check_f0: + prolog + movi_d %f0 0.5 + movi_d %f2 10 + divi_d %f1 %f2 3 + retr_d %f0 + epilog + +main: + prolog + calli check_r0 + retval %r1 + beqi r0_ok %r1 1 + calli @abort +r0_ok: + calli check_f0 + retval_d %f1 + beqi_d f0_ok %f1 0.5 + calli @abort +f0_ok: + prepare + pushargi ok + finishi @puts + ret + epilog diff --git a/deps/lightning/check/rpn.ok b/deps/lightning/check/rpn.ok new file mode 100644 index 0000000..b686c13 --- /dev/null +++ b/deps/lightning/check/rpn.ok @@ -0,0 +1,6 @@ + +C: 0 10 20 30 40 50 60 70 80 90 100 +F: 32 50 68 86 104 122 140 158 176 194 212 + +F: 32 50 68 86 104 122 140 158 176 194 212 +C: 0 10 20 30 40 50 60 70 80 90 100 diff --git a/deps/lightning/check/rpn.tst b/deps/lightning/check/rpn.tst new file mode 100644 index 0000000..62ef8d6 --- /dev/null +++ b/deps/lightning/check/rpn.tst @@ -0,0 +1,183 @@ +.data 256 +.$($int = 4) +C: +.c "\nC:" +F: +.c "\nF:" +format: +.c "%3d " +newline: +.c "\n" + +.code + jmpi main + + name c2f +c2f: + prolog + arg $in + + allocai $(32 * $int) $index + + getarg %r2 $in + + // 32x9*5/+ + movi %r0 32 + + // x9*5/+ + stxi_i $index %fp %r0 +. $($index = $index + $int) + movr %r0 %r2 + + // 9*5/+ + stxi_i $index %fp %r0 +. $($index = $index + $int) + movi %r0 9 + + // *5/+ +. $($index = $index - $int) + ldxi_i %r1 %fp $index + mulr %r0 %r1 %r0 + + // 5/+ + stxi_i $index %fp %r0 +. $($index = $index + $int) + movi %r0 5 + + // /+ +. $($index = $index - $int) + ldxi_i %r1 %fp $index + divr %r0 %r1 %r0 + + // + +. $($index = $index - $int) + ldxi_i %r1 %fp $index + addr %r0 %r1 %r0 + + retr %r0 + epilog + + name f2c +f2c: + prolog + arg $in + + allocai $(32 * $int) $index + + getarg %r2 $in + + // x32-5*9/ + stxi_i $index %fp %r0 +. $($index = $index + $int) + movr %r0 %r2 + + // 32-5*9/ + stxi_i $index %fp %r0 +. $($index = $index + $int) + movi %r0 32 + + // -5*9/ +. $($index = $index - $int) + ldxi_i %r1 %fp $index + subr %r0 %r1 %r0 + + // 5*9/ + stxi_i $index %fp %r0 +. $($index = $index + $int) + movi %r0 5 + + // *9/ +. $($index = $index - $int) + ldxi_i %r1 %fp $index + mulr %r0 %r1 %r0 + + // 9/ + stxi_i $index %fp %r0 +. $($index = $index + $int) + movi %r0 9 + + // / +. $($index = $index - $int) + ldxi_i %r1 %fp $index + divr %r0 %r1 %r0 + + retr %r0 + epilog + +//----------------------------------------------------------------------- + name main +main: + prolog + + prepare + pushargi C + ellipsis + finishi @printf + movi %v0 0 +loopC: + prepare + pushargi format + ellipsis + pushargr %v0 + finishi @printf + addi %v0 %v0 10 + blei loopC %v0 100 + prepare + pushargi F + ellipsis + finishi @printf + movi %v0 0 +loopC2F: + prepare + pushargr %v0 + finishi c2f + retval %r0 + prepare + pushargi format + ellipsis + pushargr %r0 + finishi @printf + addi %v0 %v0 10 + blei loopC2F %v0 100 + prepare + pushargi newline + ellipsis + finishi @printf + + prepare + pushargi F + ellipsis + finishi @printf + movi %v0 32 +loopF: + prepare + pushargi format + ellipsis + pushargr %v0 + finishi @printf + addi %v0 %v0 18 + blei loopF %v0 212 + prepare + pushargi C + ellipsis + finishi @printf + movi %v0 32 +loopF2C: + prepare + pushargr %v0 + finishi f2c + retval %r0 + prepare + pushargi format + ellipsis + pushargr %r0 + finishi @printf + addi %v0 %v0 18 + blei loopF2C %v0 212 + prepare + pushargi newline + ellipsis + finishi @printf + + ret + epilog diff --git a/deps/lightning/check/run-test b/deps/lightning/check/run-test new file mode 100755 index 0000000..e8369d6 --- /dev/null +++ b/deps/lightning/check/run-test @@ -0,0 +1,10 @@ +#! /bin/sh + +ok=`echo $1 | sed -e 's@\.\(x87\|arm\|swf\)@@'` +$1 | tr -d \\r > $1.log +if cmp -s $srcdir/$ok.ok $1.log; then + rm $1.log +else + diff $srcdir/$ok.ok $1.log + exit 1 +fi diff --git a/deps/lightning/check/self.c b/deps/lightning/check/self.c new file mode 100644 index 0000000..7cfbb94 --- /dev/null +++ b/deps/lightning/check/self.c @@ -0,0 +1,136 @@ +#include <lightning.h> +#include <stdio.h> +#include <assert.h> + +int +main(int argc, char *argv[]) +{ + jit_state_t *_jit; + + /* Same JIT_XY are not constants */ + init_jit(argv[0]); + + _jit = jit_new_state(); + assert(JIT_R0 == jit_r(0)); + (void)jit_callee_save_p(JIT_R0); + assert(JIT_R1 == jit_r(1)); + (void)jit_callee_save_p(JIT_R1); + assert(JIT_R2 == jit_r(2)); + (void)jit_callee_save_p(JIT_R2); +#if defined(JIT_R3) + assert(JIT_R3 == jit_r(3)); + (void)jit_callee_save_p(JIT_R3); +# if defined(JIT_R4) + assert(JIT_R4 == jit_r(4)); + (void)jit_callee_save_p(JIT_R4); +# if defined(JIT_R5) + assert(JIT_R5 == jit_r(5)); + (void)jit_callee_save_p(JIT_R5); +# if defined(JIT_R6) + assert(JIT_R6 == jit_r(6)); + (void)jit_callee_save_p(JIT_R6); +# if defined(JIT_R7) + assert(JIT_R7 == jit_r(7)); + (void)jit_callee_save_p(JIT_R7); +# endif +# endif +# endif +# endif +#endif + assert(JIT_V0 == jit_v(0)); + assert(jit_callee_save_p(JIT_V0)); + assert(JIT_V1 == jit_v(1)); + assert(jit_callee_save_p(JIT_V1)); + assert(JIT_V2 == jit_v(2)); + assert(jit_callee_save_p(JIT_V2)); +#if defined(JIT_V3) + assert(JIT_V3 == jit_v(3)); + assert(jit_callee_save_p(JIT_V3)); +# if defined(JIT_V4) + assert(JIT_V4 == jit_v(4)); + assert(jit_callee_save_p(JIT_V4)); +# if defined(JIT_V5) + assert(JIT_V5 == jit_v(5)); + assert(jit_callee_save_p(JIT_V5)); +# if defined(JIT_V6) + assert(JIT_V6 == jit_v(6)); + assert(jit_callee_save_p(JIT_V6)); +# if defined(JIT_V7) + assert(JIT_V7 == jit_v(7)); + assert(jit_callee_save_p(JIT_V7)); +# if defined(JIT_V8) + assert(JIT_V8 == jit_v(8)); + assert(jit_callee_save_p(JIT_V8)); +# if defined(JIT_V9) + assert(JIT_V9 == jit_v(9)); + assert(jit_callee_save_p(JIT_V9)); +# if defined(JIT_V10) + assert(JIT_V10 == jit_v(10)); + assert(jit_callee_save_p(JIT_V10)); +# if defined(JIT_V11) + assert(JIT_V11 == jit_v(11)); + assert(jit_callee_save_p(JIT_V11)); +# if defined(JIT_V12) + assert(JIT_V12 == jit_v(12)); + assert(jit_callee_save_p(JIT_V12)); +# if defined(JIT_V13) + assert(JIT_V13 == jit_v(13)); + assert(jit_callee_save_p(JIT_V13)); +# if defined(JIT_V14) + assert(JIT_V14 == jit_v(14)); + assert(jit_callee_save_p(JIT_V14)); +# if defined(JIT_V15) + assert(JIT_V15 == jit_v(15)); + assert(jit_callee_save_p(JIT_V15)); +# if defined(JIT_V16) + assert(JIT_V16 == jit_v(16)); + assert(jit_callee_save_p(JIT_V16)); +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +#endif + assert(JIT_F0 == jit_f(0)); + (void)jit_callee_save_p(JIT_F0); + assert(JIT_F1 == jit_f(1)); + (void)jit_callee_save_p(JIT_F1); + assert(JIT_F2 == jit_f(2)); + (void)jit_callee_save_p(JIT_F2); + assert(JIT_F3 == jit_f(3)); + (void)jit_callee_save_p(JIT_F3); + assert(JIT_F4 == jit_f(4)); + (void)jit_callee_save_p(JIT_F4); + assert(JIT_F5 == jit_f(5)); + (void)jit_callee_save_p(JIT_F5); +#if defined(JIT_F6) + assert(JIT_F6 == jit_f(6)); + (void)jit_callee_save_p(JIT_F6); +# if defined(JIT_F7) + assert(JIT_F7 == jit_f(7)); + (void)jit_callee_save_p(JIT_F7); +# if defined(JIT_F8) + assert(JIT_F8 == jit_f(8)); + (void)jit_callee_save_p(JIT_F8); +# if defined(JIT_F9) + assert(JIT_F9 == jit_f(9)); + (void)jit_callee_save_p(JIT_F9); +# endif +# endif +# endif +#endif + + jit_clear_state(); + jit_destroy_state(); + finish_jit(); + + return (0); +} diff --git a/deps/lightning/check/setcode.c b/deps/lightning/check/setcode.c new file mode 100644 index 0000000..0047f34 --- /dev/null +++ b/deps/lightning/check/setcode.c @@ -0,0 +1,89 @@ +/* + * Simple test of using an alternate buffer for the code. + */ + +#include <lightning.h> +#include <stdio.h> +#include <assert.h> +#include <sys/mman.h> +#if defined(__sgi) +# include <fcntl.h> +#endif + +#ifndef MAP_ANON +# define MAP_ANON MAP_ANONYMOUS +# ifndef MAP_ANONYMOUS +# define MAP_ANONYMOUS 0 +# endif +#endif + +#if !defined(__sgi) +#define mmap_fd -1 +#endif + +int +main(int argc, char *argv[]) +{ + jit_uint8_t *ptr; + jit_state_t *_jit; + jit_word_t length; +#if defined(__sgi) + int mmap_fd; +#endif + void (*function)(void); + +#if defined(__sgi) + mmap_fd = open("/dev/zero", O_RDWR); +#endif + + ptr = mmap(NULL, 1024 * 1024, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, mmap_fd, 0); + assert(ptr != MAP_FAILED); +#if defined(__sgi) + close(mmap_fd); +#endif + + init_jit(argv[0]); + _jit = jit_new_state(); + + jit_prolog(); + jit_prepare(); + jit_pushargi((jit_word_t)"%s\n"); + jit_ellipsis(); + jit_pushargi((jit_word_t)"ok"); + jit_finishi(printf); + + /* call to jit_realize() is only required when using an alternate + * code buffer. Note that not using mmap'ed memory may not work + * on several ports and/or operating system versions */ + jit_realize(); + + length = 0; + if (jit_get_code(&length) != NULL) + abort(); + + if (length <= 4) + abort(); + + /* check that a too small buffer fails */ + jit_set_code(ptr, 4); + function = jit_emit(); + if (function != NULL) + abort(); + + /* and calling again with enough space works */ + jit_set_code(ptr, 1024 * 1024); + function = jit_emit(); + if (function == NULL) + abort(); + + jit_clear_state(); + (*function)(); + jit_destroy_state(); + finish_jit(); + + munmap(ptr, 1024 * 1024); + + return (0); +} diff --git a/deps/lightning/check/stack.ok b/deps/lightning/check/stack.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/stack.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/stack.tst b/deps/lightning/check/stack.tst new file mode 100644 index 0000000..e699719 --- /dev/null +++ b/deps/lightning/check/stack.tst @@ -0,0 +1,358 @@ +#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_f 4 +#define szof_d 8 + +#define FILL(T) \ + name fill##T \ +fill##T: \ + prolog \ + arg $argp \ + getarg %v0 $argp \ + arg $argi \ + getarg %r0 $argi \ + muli %r0 %r0 szof##T \ + addr %v1 %v0 %r0 \ + movi %r0 0 \ +fill##T##loop: \ + bger fill##T##done %v0 %v1 \ + str##T %v0 %r0 \ + addi %r0 %r0 1 \ + addi %v0 %v0 szof##T \ + jmpi fill##T##loop \ +fill##T##done: \ + ret \ + epilog +#define FILLF(T) \ + name fill##T \ +fill##T: \ + prolog \ + arg $argp \ + getarg %v0 $argp \ + arg $argi \ + getarg %r0 $argi \ + muli %r0 %r0 szof##T \ + addr %v1 %v0 %r0 \ + movi##T %f0 0.0 \ +fill##T##loop: \ + bger fill##T##done %v0 %v1 \ + str##T %v0 %f0 \ + addi##T %f0 %f0 1.0 \ + addi %v0 %v0 szof##T \ + jmpi fill##T##loop \ +fill##T##done: \ + ret \ + epilog + +#define fill_uc fill_c +#define fill_us fill_s +#define fill_ui fill_i + +#define ARG( T, N) arg $arg##T##N +#define ARGF( T, N) arg##T $arg##T##N +#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) \ + getarg %r0 $arg##T##V \ + ldxi##T %r1 %v0 $(V * szof##T) \ + beqr N##T##V %r0 %r1 \ + calli @abort \ +N##T##V: +#define CHKF(N, T, V) \ + getarg##T %f0 $arg##T##V \ + ldxi##T %f1 %v0 $(V * szof##T) \ + beqr##T N##T##V %f0 %f1 \ + calli @abort \ +N##T##V: + +#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) pushargi V +#define PUSHF( T, V) pushargi##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) \ + name test##T##_0 \ +test##T##_0: \ + prolog \ + ret \ + epilog + +#define DEFN(N, M, T) \ + name test##T##_##N \ +test##T##_##N: \ + prolog \ + arg $argp \ + /* stack buffer in %v0 */ \ + getarg %v0 $argp \ + ARG##T(N) \ + /* validate arguments */ \ + GET##T(N, M) \ + /* heap buffer in %v1 */ \ + prepare \ + pushargi $(N * szof##T) \ + finishi @malloc \ + retval %v1 \ + /* copy stack bufer to heap buffer */ \ + prepare \ + pushargr %v1 \ + pushargr %v0 \ + pushargi $(N * szof##T) \ + finishi MEMCPY \ + /* stack buffer for next function in %v2 */ \ + allocai $(M * szof##T) $index \ + addi %v2 %fp $index \ + /* fill stack buffer for next function */ \ + prepare \ + pushargr %v2 \ + pushargi M \ + finishi fill##T \ + /* call next function */ \ + prepare \ + pushargr %v2 \ + PUSH##T(M) \ + finishi test##T##_##M \ + /* validate stack buffer */ \ + prepare \ + pushargr %v1 \ + pushargr %v0 \ + pushargi $(N * szof##T) \ + finishi @memcmp \ + retval %r0 \ + beqi test##T##_##N##_done %r0 0 \ + calli @abort \ +test##T##_##N##_done: \ + /* release heap bufer */ \ + prepare \ + pushargr %v1 \ + finishi @free \ + ret \ + epilog + +/* top function */ +#define DEFX(T) \ + name test##T##_17 \ +test##T##_17: \ + prolog \ + /* heap buffer in %v1 */ \ + prepare \ + pushargi $(16 * szof##T) \ + finishi @malloc \ + retval %v1 \ + /* stack buffer for next function in %v2 */ \ + allocai $(16 * szof##T) $index \ + addi %v2 %fp $index \ + /* fill stack buffer for next function */ \ + prepare \ + pushargr %v2 \ + pushargi 16 \ + finishi fill##T \ + /* copy stack buffer to heap buffer */ \ + prepare \ + pushargr %v1 \ + pushargr %v2 \ + pushargi $(16 * szof##T) \ + finishi MEMCPY \ + /* call next function */ \ + prepare \ + pushargr %v2 \ + PUSH##T(16) \ + finishi test##T##_16 \ + /* validate stack buffer */ \ + prepare \ + pushargr %v1 \ + pushargr %v2 \ + pushargi $(16 * szof##T) \ + finishi @memcmp \ + retval %r0 \ + beqi test##T##_17_done %r0 0 \ + calli @abort \ +test##T##_17_done: \ + /* release heap bufer */ \ + prepare \ + pushargr %v1 \ + finishi @free \ + ret \ + epilog + +#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) calli test##T##_17 + +.data 16 +ok: +.c "ok\n" +.code + jmpi main + +#if _AIX +# define MEMCPY memcpy +/* error: Function not implemented (memcpy) */ + name memcpy +memcpy: + prolog + arg $dst + arg $src + arg $len + getarg %r0 $dst + getarg %r1 $src + getarg %r2 $len + movr %v1 %r0 + blti memcpy_done %r2 1 +memcpy_loop: + subi %r2 %r2 1 + ldxr_c %v0 %r1 %r2 + stxr_c %r2 %r0 %v0 + bgti memcpy_loop %r2 0 +memcpy_done: + retr %v1 + epilog +#else +# define MEMCPY @memcpy +#endif + + FILL(_c) + FILL(_s) + FILL(_i) +#if __WORDSIZE == 64 + FILL(_l) +#endif + FILLF(_f) + FILLF(_d) + + DEF(_c) + DEF(_uc) + DEF(_s) + DEF(_us) + DEF(_i) +#if __WORDSIZE == 64 + DEF(_ui) + DEF(_l) +#endif + DEF(_f) + DEF(_d) + + name main +main: + prolog + + CALL(_c) + CALL(_uc) + CALL(_s) + CALL(_us) + CALL(_i) +#if __WORDSIZE == 64 + CALL(_ui) + CALL(_l) +#endif + CALL(_f) + CALL(_d) + + prepare + pushargi ok + ellipsis + finishi @printf + + ret + epilog diff --git a/deps/lightning/check/tramp.ok b/deps/lightning/check/tramp.ok new file mode 100644 index 0000000..6adb29f --- /dev/null +++ b/deps/lightning/check/tramp.ok @@ -0,0 +1 @@ +xfibs(32) = 7049155 diff --git a/deps/lightning/check/tramp.tst b/deps/lightning/check/tramp.tst new file mode 100644 index 0000000..faf63d2 --- /dev/null +++ b/deps/lightning/check/tramp.tst @@ -0,0 +1,111 @@ +#if __WORDSIZE == 32 +# define SIZE 4 +#else +# define SIZE 8 +#endif +.data 8192 +fmt: +.c "xfibs(%d) = %d\n" +/* Simulate a language specific stack */ +.align SIZE +top: +/* Top, or base of the stack */ +.size SIZE +stk: +.size 8160 + +.code + jmpi main + +/* Usually a trampoline is created before the code that uses it, but + * for testing purposes it is not required. + * In this test case, it would mean "main" would be converted in a + * different jit_state_t to native code, before xfibs was know. + */ + name xfibs +xfibs: + /* return address is in %r0 */ + /* argument and return value in %v0 */ + prolog + tramp 64 + blti_u out %v0 2 + subi %v1 %v0 1 /* V1 = N-1 */ + subi %v2 %v0 2 /* V1 = N-2 */ + + /* save return address */ + ldi %r1 top + stxi $(SIZE * 0) %r1 %r0 + /* save operands */ + stxi $(SIZE * 1) %r1 %v0 + stxi $(SIZE * 2) %r1 %v1 + stxi $(SIZE * 3) %r1 %v2 + /* adjust "language" stack */ + addi %r1 %r1 $(SIZE * 4) + sti top %r1 + + /* return address */ + movi %r0 ret1 + /* argument */ + movr %v0 %v1 + /* indirect goto */ + jmpi xfibs +ret1: + movr %v1 %v0 /* V1 = rfibs(N-1) */ + /* save V1 */ + ldi %r1 top + stxi $(-SIZE * 2) %r1 %v1 + + /* reload V2 */ + ldxi %v2 %r1 $(-SIZE * 1) + + /* return address */ + movi %r0 ret2 + /* argument */ + movr %v0 %v2 + /* indirect goto */ + jmpi xfibs +ret2: + movr %v2 %v0 /* V2 = rfibs(N-2) */ + + /* reload return address */ + ldi %r1 top + subi %r1 %r1 $(SIZE * 4) + ldxi %r0 %r1 $(SIZE * 0) + /* reload operands */ + ldxi %v0 %r1 $(SIZE * 1) + ldxi %v1 %r1 $(SIZE * 2) + /* V2 already loaded */ + /* update "language" stack */ + sti top %r1 + + addi %v1 %v1 1 + addr %v0 %v1 %v2 + jmpr %r0 +out: + movi %v0 1 + jmpr %r0 + epilog + + name main +main: + prolog + frame 64 + + /* Initialize language stack */ + movi %r0 stk + sti top %r0 + + /* return address */ + movi %r0 done + /* argument */ + movi %v0 32 + jmpi xfibs +done: + prepare + pushargi fmt + ellipsis + pushargi 32 + pushargr %v0 + finishi @printf + ret + epilog diff --git a/deps/lightning/check/va_list.ok b/deps/lightning/check/va_list.ok new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/deps/lightning/check/va_list.ok @@ -0,0 +1 @@ +ok diff --git a/deps/lightning/check/va_list.tst b/deps/lightning/check/va_list.tst new file mode 100644 index 0000000..ad704c9 --- /dev/null +++ b/deps/lightning/check/va_list.tst @@ -0,0 +1,743 @@ +.data 8 +ok: +.c "ok\n" +.code + jmpi main + +#define BEGIN(L) \ +L: \ + prolog +#define VA_START() \ + ellipsis \ + va_start %v0 +#define VARG(L,N) \ + va_arg %r0 %v0 \ + beqi L##N %r0 N \ + calli @abort \ +L##N: +#define VARGD(L,N) \ + va_arg_d %f0 %v0 \ + beqi_d L##N %f0 N \ + calli @abort \ +L##N: +#define VA_END() \ + va_end %v0 \ + ret \ + epilog +#define ARG(N) arg $arg##N +#define ARGD(N) arg_d $arg##N +#define GET(L,N) \ + getarg %r0 $arg##N \ + beqi L##N %r0 N \ + calli @abort \ +L##N: +#define GETD(L,N) \ + getarg_d %f0 $arg##N \ + beqi_d L##N %f0 N \ + calli @abort \ +L##N: + +#define ARG1() ARG(1) +#define ARG2() ARG1() ARG(2) +#define ARG3() ARG2() ARG(3) +#define ARG4() ARG3() ARG(4) +#define ARG5() ARG4() ARG(5) +#define ARG6() ARG5() ARG(6) +#define ARG7() ARG6() ARG(7) +#define ARG8() ARG7() ARG(8) +#define ARG9() ARG8() ARG(9) +#define GET1(L) GET(L,1) +#define GET2(L) GET1(L) GET(L,2) +#define GET3(L) GET2(L) GET(L,3) +#define GET4(L) GET3(L) GET(L,4) +#define GET5(L) GET4(L) GET(L,5) +#define GET6(L) GET5(L) GET(L,6) +#define GET7(L) GET6(L) GET(L,7) +#define GET8(L) GET7(L) GET(L,8) +#define GET9(L) GET8(L) GET(L,9) +#define ARGD1() ARGD(1) +#define ARGD2() ARGD1() ARGD(2) +#define ARGD3() ARGD2() ARGD(3) +#define ARGD4() ARGD3() ARGD(4) +#define ARGD5() ARGD4() ARGD(5) +#define ARGD6() ARGD5() ARGD(6) +#define ARGD7() ARGD6() ARGD(7) +#define ARGD8() ARGD7() ARGD(8) +#define ARGD9() ARGD8() ARGD(9) +#define GETD1(L) GETD(L,1) +#define GETD2(L) GETD1(L) GETD(L,2) +#define GETD3(L) GETD2(L) GETD(L,3) +#define GETD4(L) GETD3(L) GETD(L,4) +#define GETD5(L) GETD4(L) GETD(L,5) +#define GETD6(L) GETD5(L) GETD(L,6) +#define GETD7(L) GETD6(L) GETD(L,7) +#define GETD8(L) GETD7(L) GETD(L,8) +#define GETD9(L) GETD8(L) GETD(L,9) +#define IDARG1() ARG(1) +#define IDARG2() IDARG1() ARGD(2) +#define IDARG3() IDARG2() ARG(3) +#define IDARG4() IDARG3() ARGD(4) +#define IDARG5() IDARG4() ARG(5) +#define IDARG6() IDARG5() ARGD(6) +#define IDARG7() IDARG6() ARG(7) +#define IDARG8() IDARG7() ARGD(8) +#define IDARG9() IDARG8() ARG(9) +#define IDGET1(L) GET(L,1) +#define IDGET2(L) IDGET1(L) GETD(L,2) +#define IDGET3(L) IDGET2(L) GET(L,3) +#define IDGET4(L) IDGET3(L) GETD(L,4) +#define IDGET5(L) IDGET4(L) GET(L,5) +#define IDGET6(L) IDGET5(L) GETD(L,6) +#define IDGET7(L) IDGET6(L) GET(L,7) +#define IDGET8(L) IDGET7(L) GETD(L,8) +#define IDGET9(L) IDGET8(L) GET(L,9) +#define DIARG1() ARGD(1) +#define DIARG2() DIARG1() ARG(2) +#define DIARG3() DIARG2() ARGD(3) +#define DIARG4() DIARG3() ARG(4) +#define DIARG5() DIARG4() ARGD(5) +#define DIARG6() DIARG5() ARG(6) +#define DIARG7() DIARG6() ARGD(7) +#define DIARG8() DIARG7() ARG(8) +#define DIARG9() DIARG8() ARGD(9) +#define DIGET1(L) GETD(L,1) +#define DIGET2(L) DIGET1(L) GET(L,2) +#define DIGET3(L) DIGET2(L) GETD(L,3) +#define DIGET4(L) DIGET3(L) GET(L,4) +#define DIGET5(L) DIGET4(L) GETD(L,5) +#define DIGET6(L) DIGET5(L) GET(L,6) +#define DIGET7(L) DIGET6(L) GETD(L,7) +#define DIGET8(L) DIGET7(L) GET(L,8) +#define DIGET9(L) DIGET8(L) GETD(L,9) + +#define VARG1(L) \ + VARG(L, 10) +#define VARG2(L) \ + VARG(L, 9) \ + VARG1(L) +#define VARG3(L) \ + VARG(L, 8) \ + VARG2(L) +#define VARG4(L) \ + VARG(L, 7) \ + VARG3(L) +#define VARG5(L) \ + VARG(L, 6) \ + VARG4(L) +#define VARG6(L) \ + VARG(L, 5) \ + VARG5(L) +#define VARG7(L) \ + VARG(L, 4) \ + VARG6(L) +#define VARG8(L) \ + VARG(L, 3) \ + VARG7(L) +#define VARG9(L) \ + VARG(L, 2) \ + VARG8(L) +#define VARG10(L) \ + VARG(L, 1) \ + VARG9(L) +#define VARGD1(L) \ + VARGD(L, 10) +#define VARGD2(L) \ + VARGD(L, 9) \ + VARGD1(L) +#define VARGD3(L) \ + VARGD(L, 8) \ + VARGD2(L) +#define VARGD4(L) \ + VARGD(L, 7) \ + VARGD3(L) +#define VARGD5(L) \ + VARGD(L, 6) \ + VARGD4(L) +#define VARGD6(L) \ + VARGD(L, 5) \ + VARGD5(L) +#define VARGD7(L) \ + VARGD(L, 4) \ + VARGD6(L) +#define VARGD8(L) \ + VARGD(L, 3) \ + VARGD7(L) +#define VARGD9(L) \ + VARGD(L, 2) \ + VARGD8(L) +#define VARGD10(L) \ + VARGD(L, 1) \ + VARGD9(L) +#define IDVARG1(L) \ + VARGD(L, 10) +#define IDVARG2(L) \ + VARG(L, 9) \ + IDVARG1(L) +#define IDVARG3(L) \ + VARGD(L, 8) \ + IDVARG2(L) +#define IDVARG4(L) \ + VARG(L, 7) \ + IDVARG3(L) +#define IDVARG5(L) \ + VARGD(L, 6) \ + IDVARG4(L) +#define IDVARG6(L) \ + VARG(L, 5) \ + IDVARG5(L) +#define IDVARG7(L) \ + VARGD(L, 4) \ + IDVARG6(L) +#define IDVARG8(L) \ + VARG(L, 3) \ + IDVARG7(L) +#define IDVARG9(L) \ + VARGD(L, 2) \ + IDVARG8(L) +#define IDVARG10(L) \ + VARG(L, 1) \ + IDVARG9(L) +#define DIVARG1(L) \ + VARG(L, 10) +#define DIVARG2(L) \ + VARGD(L, 9) \ + DIVARG1(L) +#define DIVARG3(L) \ + VARG(L, 8) \ + DIVARG2(L) +#define DIVARG4(L) \ + VARGD(L, 7) \ + DIVARG3(L) +#define DIVARG5(L) \ + VARG(L, 6) \ + DIVARG4(L) +#define DIVARG6(L) \ + VARGD(L, 5) \ + DIVARG5(L) +#define DIVARG7(L) \ + VARG(L, 4) \ + DIVARG6(L) +#define DIVARG8(L) \ + VARGD(L, 3) \ + DIVARG7(L) +#define DIVARG9(L) \ + VARG(L, 2) \ + DIVARG8(L) +#define DIVARG10(L) \ + VARGD(L, 1) \ + DIVARG9(L) + +BEGIN(_iiiiiiiiii) + VA_START() + VARG10(_iiiiiiiiii) + VA_END() +BEGIN(i_iiiiiiiii) + ARG1() + GET1(i_iiiiiiiii) + VA_START() + VARG9(i_iiiiiiiii) + VA_END() +BEGIN(ii_iiiiiiii) + ARG2() + GET2(ii_iiiiiiii) + VA_START() + VARG8(ii_iiiiiiii) + VA_END() +BEGIN(iii_iiiiiii) + ARG3() + GET3(iii_iiiiiii) + VA_START() + VARG7(iii_iiiiiii) + VA_END() +BEGIN(iiii_iiiiii) + ARG4() + GET4(iiii_iiiiii) + VA_START() + VARG6(iiii_iiiiii) + VA_END() +BEGIN(iiiii_iiiii) + ARG5() + GET5(iiiii_iiiii) + VA_START() + VARG5(iiiii_iiiii) + VA_END() +BEGIN(iiiiii_iiii) + ARG6() + GET6(iiiiii_iiii) + VA_START() + VARG4(iiiiii_iiii) + VA_END() +BEGIN(iiiiiii_iii) + ARG7() + GET7(iiiiiii_iii) + VA_START() + VARG3(iiiiiii_iii) + VA_END() +BEGIN(iiiiiiii_ii) + ARG8() + GET8(iiiiiiii_ii) + VA_START() + VARG2(iiiiiiii_ii) + VA_END() +BEGIN(iiiiiiiii_i) + ARG9() + GET9(iiiiiiiii_i) + VA_START() + VARG1(iiiiiiiii_i) + VA_END() +BEGIN(_dddddddddd) + VA_START() + VARGD10(_dddddddddd) + VA_END() +BEGIN(d_ddddddddd) + ARGD1() + GETD1(d_ddddddddd) + VA_START() + VARGD9(d_ddddddddd) + VA_END() +BEGIN(dd_dddddddd) + ARGD2() + GETD2(dd_dddddddd) + VA_START() + VARGD8(dd_dddddddd) + VA_END() +BEGIN(ddd_ddddddd) + ARGD3() + GETD3(ddd_ddddddd) + VA_START() + VARGD7(ddd_ddddddd) + VA_END() +BEGIN(dddd_dddddd) + ARGD4() + GETD4(dddd_dddddd) + VA_START() + VARGD6(dddd_dddddd) + VA_END() +BEGIN(ddddd_ddddd) + ARGD5() + GETD5(ddddd_ddddd) + VA_START() + VARGD5(ddddd_ddddd) + VA_END() +BEGIN(dddddd_dddd) + ARGD6() + GETD6(dddddd_dddd) + VA_START() + VARGD4(dddddd_dddd) + VA_END() +BEGIN(ddddddd_ddd) + ARGD7() + GETD7(ddddddd_ddd) + VA_START() + VARGD3(ddddddd_ddd) + VA_END() +BEGIN(dddddddd_dd) + ARGD8() + GETD8(dddddddd_dd) + VA_START() + VARGD2(dddddddd_dd) + VA_END() +BEGIN(ddddddddd_d) + ARGD9() + GETD9(ddddddddd_d) + VA_START() + VARGD1(ddddddddd_d) + VA_END() +BEGIN(_ididididid) + VA_START() + IDVARG10(_ididididid) + VA_END() +BEGIN(i_didididid) + IDARG1() + IDGET1(i_didididid) + VA_START() + IDVARG9(i_didididid) + VA_END() +BEGIN(id_idididid) + IDARG2() + IDGET2(id_idididid) + VA_START() + IDVARG8(id_idididid) + VA_END() +BEGIN(idi_dididid) + IDARG3() + IDGET3(idi_dididid) + VA_START() + IDVARG7(idi_dididid) + VA_END() +BEGIN(idid_ididid) + IDARG4() + IDGET4(idid_ididid) + VA_START() + IDVARG6(idid_ididid) + VA_END() +BEGIN(ididi_didid) + IDARG5() + IDGET5(ididi_didid) + VA_START() + IDVARG5(ididi_didid) + VA_END() +BEGIN(ididid_idid) + IDARG6() + IDGET6(ididid_idid) + VA_START() + IDVARG4(ididid_idid) + VA_END() +BEGIN(idididi_did) + IDARG7() + IDGET7(idididi_did) + VA_START() + IDVARG3(idididi_did) + VA_END() +BEGIN(idididid_id) + IDARG8() + IDGET8(idididid_id) + VA_START() + IDVARG2(idididid_id) + VA_END() +BEGIN(ididididi_d) + IDARG9() + IDGET9(ididididi_d) + VA_START() + IDVARG1(ididididi_d) + VA_END() +BEGIN(_dididididi) + VA_START() + DIVARG10(_dididididi) + VA_END() +BEGIN(d_ididididi) + DIARG1() + DIGET1(d_ididididi) + VA_START() + DIVARG9(d_ididididi) + VA_END() +BEGIN(di_didididi) + DIARG2() + DIGET2(di_didididi) + VA_START() + DIVARG8(di_didididi) + VA_END() +BEGIN(did_idididi) + DIARG3() + DIGET3(did_idididi) + VA_START() + DIVARG7(did_idididi) + VA_END() +BEGIN(didi_dididi) + DIARG4() + DIGET4(didi_dididi) + VA_START() + DIVARG6(didi_dididi) + VA_END() +BEGIN(didid_ididi) + DIARG5() + DIGET5(didid_ididi) + VA_START() + DIVARG5(didid_ididi) + VA_END() +BEGIN(dididi_didi) + DIARG6() + DIGET6(dididi_didi) + VA_START() + DIVARG4(dididi_didi) + VA_END() +BEGIN(dididid_idi) + DIARG7() + DIGET7(dididid_idi) + VA_START() + DIVARG3(dididid_idi) + VA_END() +BEGIN(didididi_di) + DIARG8() + DIGET8(didididi_di) + VA_START() + DIVARG2(didididi_di) + VA_END() +BEGIN(didididid_i) + DIARG9() + DIGET9(didididid_i) + VA_START() + DIVARG1(didididid_i) + VA_END() + +#define PUSH1() pushargi 1 +#define PUSH2() PUSH1() pushargi 2 +#define PUSH3() PUSH2() pushargi 3 +#define PUSH4() PUSH3() pushargi 4 +#define PUSH5() PUSH4() pushargi 5 +#define PUSH6() PUSH5() pushargi 6 +#define PUSH7() PUSH6() pushargi 7 +#define PUSH8() PUSH7() pushargi 8 +#define PUSH9() PUSH8() pushargi 9 +#define VPUSH1() pushargi 1 VPUSH2() +#define VPUSH2() pushargi 2 VPUSH3() +#define VPUSH3() pushargi 3 VPUSH4() +#define VPUSH4() pushargi 4 VPUSH5() +#define VPUSH5() pushargi 5 VPUSH6() +#define VPUSH6() pushargi 6 VPUSH7() +#define VPUSH7() pushargi 7 VPUSH8() +#define VPUSH8() pushargi 8 VPUSH9() +#define VPUSH9() pushargi 9 VPUSH10() +#define VPUSH10() pushargi 10 +#define PUSHD1() pushargi_d 1 +#define PUSHD2() PUSHD1() pushargi_d 2 +#define PUSHD3() PUSHD2() pushargi_d 3 +#define PUSHD4() PUSHD3() pushargi_d 4 +#define PUSHD5() PUSHD4() pushargi_d 5 +#define PUSHD6() PUSHD5() pushargi_d 6 +#define PUSHD7() PUSHD6() pushargi_d 7 +#define PUSHD8() PUSHD7() pushargi_d 8 +#define PUSHD9() PUSHD8() pushargi_d 9 +#define VPUSHD1() pushargi_d 1 VPUSHD2() +#define VPUSHD2() pushargi_d 2 VPUSHD3() +#define VPUSHD3() pushargi_d 3 VPUSHD4() +#define VPUSHD4() pushargi_d 4 VPUSHD5() +#define VPUSHD5() pushargi_d 5 VPUSHD6() +#define VPUSHD6() pushargi_d 6 VPUSHD7() +#define VPUSHD7() pushargi_d 7 VPUSHD8() +#define VPUSHD8() pushargi_d 8 VPUSHD9() +#define VPUSHD9() pushargi_d 9 VPUSHD10() +#define VPUSHD10() pushargi_d 10 +#define IDPUSH1() pushargi 1 +#define IDPUSH2() IDPUSH1() pushargi_d 2 +#define IDPUSH3() IDPUSH2() pushargi 3 +#define IDPUSH4() IDPUSH3() pushargi_d 4 +#define IDPUSH5() IDPUSH4() pushargi 5 +#define IDPUSH6() IDPUSH5() pushargi_d 6 +#define IDPUSH7() IDPUSH6() pushargi 7 +#define IDPUSH8() IDPUSH7() pushargi_d 8 +#define IDPUSH9() IDPUSH8() pushargi 9 +#define IDVPUSH1() pushargi 1 IDVPUSH2() +#define IDVPUSH2() pushargi_d 2 IDVPUSH3() +#define IDVPUSH3() pushargi 3 IDVPUSH4() +#define IDVPUSH4() pushargi_d 4 IDVPUSH5() +#define IDVPUSH5() pushargi 5 IDVPUSH6() +#define IDVPUSH6() pushargi_d 6 IDVPUSH7() +#define IDVPUSH7() pushargi 7 IDVPUSH8() +#define IDVPUSH8() pushargi_d 8 IDVPUSH9() +#define IDVPUSH9() pushargi 9 IDVPUSH10() +#define IDVPUSH10() pushargi_d 10 +#define DIPUSH1() pushargi_d 1 +#define DIPUSH2() DIPUSH1() pushargi 2 +#define DIPUSH3() DIPUSH2() pushargi_d 3 +#define DIPUSH4() DIPUSH3() pushargi 4 +#define DIPUSH5() DIPUSH4() pushargi_d 5 +#define DIPUSH6() DIPUSH5() pushargi 6 +#define DIPUSH7() DIPUSH6() pushargi_d 7 +#define DIPUSH8() DIPUSH7() pushargi 8 +#define DIPUSH9() DIPUSH8() pushargi_d 9 +#define DIVPUSH1() pushargi_d 1 DIVPUSH2() +#define DIVPUSH2() pushargi 2 DIVPUSH3() +#define DIVPUSH3() pushargi_d 3 DIVPUSH4() +#define DIVPUSH4() pushargi 4 DIVPUSH5() +#define DIVPUSH5() pushargi_d 5 DIVPUSH6() +#define DIVPUSH6() pushargi 6 DIVPUSH7() +#define DIVPUSH7() pushargi_d 7 DIVPUSH8() +#define DIVPUSH8() pushargi 8 DIVPUSH9() +#define DIVPUSH9() pushargi_d 9 DIVPUSH10() +#define DIVPUSH10() pushargi 10 + +main: + prolog + prepare + ellipsis + VPUSH1() + finishi _iiiiiiiiii + prepare + PUSH1() + ellipsis + VPUSH2() + finishi i_iiiiiiiii + prepare + PUSH2() + ellipsis + VPUSH3() + finishi ii_iiiiiiii + prepare + PUSH3() + ellipsis + VPUSH4() + finishi iii_iiiiiii + prepare + PUSH4() + ellipsis + VPUSH5() + finishi iiii_iiiiii + prepare + PUSH5() + ellipsis + VPUSH6() + finishi iiiii_iiiii + prepare + PUSH6() + ellipsis + VPUSH7() + finishi iiiiii_iiii + prepare + PUSH7() + ellipsis + VPUSH8() + finishi iiiiiii_iii + prepare + PUSH8() + ellipsis + VPUSH9() + finishi iiiiiiii_ii + prepare + PUSH9() + ellipsis + VPUSH10() + finishi iiiiiiiii_i + prepare + ellipsis + VPUSHD1() + finishi _dddddddddd + prepare + PUSHD1() + ellipsis + VPUSHD2() + finishi d_ddddddddd + prepare + PUSHD2() + ellipsis + VPUSHD3() + finishi dd_dddddddd + prepare + PUSHD3() + ellipsis + VPUSHD4() + finishi ddd_ddddddd + prepare + PUSHD4() + ellipsis + VPUSHD5() + finishi dddd_dddddd + prepare + PUSHD5() + ellipsis + VPUSHD6() + finishi ddddd_ddddd + prepare + PUSHD6() + ellipsis + VPUSHD7() + finishi dddddd_dddd + prepare + PUSHD7() + ellipsis + VPUSHD8() + finishi ddddddd_ddd + prepare + PUSHD8() + ellipsis + VPUSHD9() + finishi dddddddd_dd + prepare + PUSHD9() + ellipsis + VPUSHD10() + finishi ddddddddd_d + prepare + ellipsis + IDVPUSH1() + finishi _ididididid + prepare + IDPUSH1() + ellipsis + IDVPUSH2() + finishi i_didididid + prepare + IDPUSH2() + ellipsis + IDVPUSH3() + finishi id_idididid + prepare + IDPUSH3() + ellipsis + IDVPUSH4() + finishi idi_dididid + prepare + IDPUSH4() + ellipsis + IDVPUSH5() + finishi idid_ididid + prepare + IDPUSH5() + ellipsis + IDVPUSH6() + finishi ididi_didid + prepare + IDPUSH6() + ellipsis + IDVPUSH7() + finishi ididid_idid + prepare + IDPUSH7() + ellipsis + IDVPUSH8() + finishi idididi_did + prepare + IDPUSH8() + ellipsis + IDVPUSH9() + finishi idididid_id + prepare + IDPUSH9() + ellipsis + IDVPUSH10() + finishi ididididi_d + prepare + ellipsis + DIVPUSH1() + finishi _dididididi + prepare + DIPUSH1() + ellipsis + DIVPUSH2() + finishi d_ididididi + prepare + DIPUSH2() + ellipsis + DIVPUSH3() + finishi di_didididi + prepare + DIPUSH3() + ellipsis + DIVPUSH4() + finishi did_idididi + prepare + DIPUSH4() + ellipsis + DIVPUSH5() + finishi didi_dididi + prepare + DIPUSH5() + ellipsis + DIVPUSH6() + finishi didid_ididi + prepare + DIPUSH6() + ellipsis + DIVPUSH7() + finishi dididi_didi + prepare + DIPUSH7() + ellipsis + DIVPUSH8() + finishi dididid_idi + prepare + DIPUSH8() + ellipsis + DIVPUSH9() + finishi didididi_di + prepare + DIPUSH9() + ellipsis + DIVPUSH10() + finishi didididid_i + prepare + pushargi ok + ellipsis + finishi @printf + ret + epilog diff --git a/deps/lightning/check/varargs.ok b/deps/lightning/check/varargs.ok new file mode 100644 index 0000000..e103283 --- /dev/null +++ b/deps/lightning/check/varargs.ok @@ -0,0 +1,4 @@ +0 1 2 3 4 5 6 7 8 9 +0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +0 0.0 1 1.0 2 2.0 3 3.0 4 4.0 5 5.0 6 6.0 7 7.0 8 8.0 9 9.0 +0.0 0 1.0 1 2.0 2 3.0 3 4.0 4 5.0 5 6.0 6 7.0 7 8.0 8 9.0 9 diff --git a/deps/lightning/check/varargs.tst b/deps/lightning/check/varargs.tst new file mode 100644 index 0000000..11131d9 --- /dev/null +++ b/deps/lightning/check/varargs.tst @@ -0,0 +1,398 @@ +.data 1024 +ifmt: +.c "%d %d %d %d %d %d %d %d %d %d\n" +.align 4 +ichk: +.i 9 8 7 6 5 4 3 2 1 0 +dfmt: +.c "%.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f\n" +lfmt: +.c "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n" +.align 8 +dchk: +.d 9.0 8.0 7.0 6.0 5.0 4.0 3.0 2.0 1.0 0.0 +idfmt: +.c "%d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f\n" +ldfmt: +.c "%d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf\n" +difmt: +.c "%.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d\n" +dlfmt: +.c "%lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d\n" +.align 8 +buff: +.size 256 + +.code + prolog + + /* + sprintf(buff, "%d %d %d %d %d %d %d %d %d %d\n", + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + */ + prepare + pushargi buff + pushargi ifmt + ellipsis + pushargi 0 + pushargi 1 + pushargi 2 + pushargi 3 + pushargi 4 + pushargi 5 + pushargi 6 + pushargi 7 + pushargi 8 + pushargi 9 + finishi @sprintf + + /* + sscanf(buff, "%d %d %d %d %d %d %d %d %d %d\n", + ichk+0, ichk+1, ichk+2, ichk+3, ichk+4, + ichk+5, ichk+6, ichk+7, ichk+8, ichk+9); + */ + movi %v0 ichk + prepare + pushargi buff + pushargi ifmt + ellipsis + pushargr %v0 /* 0 */ + addi %v0 %v0 4 + pushargr %v0 /* 1 */ + addi %v0 %v0 4 + pushargr %v0 /* 2 */ + addi %v0 %v0 4 + pushargr %v0 /* 3 */ + addi %v0 %v0 4 + pushargr %v0 /* 4 */ + addi %v0 %v0 4 + pushargr %v0 /* 5 */ + addi %v0 %v0 4 + pushargr %v0 /* 6 */ + addi %v0 %v0 4 + pushargr %v0 /* 7 */ + addi %v0 %v0 4 + pushargr %v0 /* 8 */ + addi %v0 %v0 4 + pushargr %v0 /* 9 */ + finishi @sscanf + + movi %v0 ichk + movi %r0 0 +loopi: + ldr_i %r1 %v0 + beqr nexti %r0 %r1 + calli @abort +nexti: + addi %r0 %r0 1 + bgei outi %r0 10 + addi %v0 %v0 4 + jmpi loopi +outi: + + prepare + pushargi buff + ellipsis + finishi @printf + + /* + sprintf(buff, + "%.1f %.1f %.1f %.1f %.1f " + "%.1f %.1f %.1f %.1f %.1f\n", + 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0); + */ + prepare + pushargi buff + pushargi dfmt + ellipsis + pushargi_d 0.0 + pushargi_d 1.0 + pushargi_d 2.0 + pushargi_d 3.0 + pushargi_d 4.0 + pushargi_d 5.0 + pushargi_d 6.0 + pushargi_d 7.0 + pushargi_d 8.0 + pushargi_d 9.0 + finishi @sprintf + + /* + sscanf(buff, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n", + dchk+0, dchk+1, dchk+2, dchk+3, dchk+4, + dchk+5, dchk+6, dchk+7, dchk+8, dchk+9); + */ + movi %v0 dchk + prepare + pushargi buff + pushargi lfmt + ellipsis + pushargr %v0 /* 0 */ + addi %v0 %v0 8 + pushargr %v0 /* 1 */ + addi %v0 %v0 8 + pushargr %v0 /* 2 */ + addi %v0 %v0 8 + pushargr %v0 /* 3 */ + addi %v0 %v0 8 + pushargr %v0 /* 4 */ + addi %v0 %v0 8 + pushargr %v0 /* 5 */ + addi %v0 %v0 8 + pushargr %v0 /* 6 */ + addi %v0 %v0 8 + pushargr %v0 /* 7 */ + addi %v0 %v0 8 + pushargr %v0 /* 8 */ + addi %v0 %v0 8 + pushargr %v0 /* 9 */ + finishi @sscanf + + movi %v0 dchk + movi_d %f0 0.0 +loopd: + ldr_d %f1 %v0 + beqr_d nextd %f0 %f1 + calli @abort +nextd: + addi_d %f0 %f0 1.0 + bgei_d outd %f0 10.0 + addi %v0 %v0 8 + jmpi loopd +outd: + + prepare + pushargi buff + ellipsis + finishi @printf + + /* + sprintf(buff, + "%d %.1f %d %.1f %d %.1f %d %.1f %d %.1f " + "%d %.1f %d %.1f %d %.1f %d %.1f %d %.1f\n", + 0, 0.0, 1, 1.0, 2, 2.0, 3, 3.0, 4, 4.0, + 5, 5.0, 6, 6.0, 7, 7.0, 8, 8.0, 9, 9.0); + */ + prepare + pushargi buff + pushargi idfmt + ellipsis + pushargi 0 + pushargi_d 0.0 + pushargi 1 + pushargi_d 1.0 + pushargi 2 + pushargi_d 2.0 + pushargi 3 + pushargi_d 3.0 + pushargi 4 + pushargi_d 4.0 + pushargi 5 + pushargi_d 5.0 + pushargi 6 + pushargi_d 6.0 + pushargi 7 + pushargi_d 7.0 + pushargi 8 + pushargi_d 8.0 + pushargi 9 + pushargi_d 9.0 + finishi @sprintf + + /* + sscanf(buff, + "%d %lf %d %lf %d %lf %d %lf %d %lf " + "%d %lf %d %lf %d %lf %d %lf %d %lf\n", + ichk+0, dchk+0, ichk+1, dchk+1, ichk+2, + dchk+2, ichk+3, dchk+3, ichk+4, dchk+4, + ichk+5, dchk+5, ichk+6, dchk+6, ichk+7, + dchk+7, ichk+8, dchk+8, ichk+9, dchk+9); + */ + movi %v0 ichk + movi %v1 dchk + prepare + pushargi buff + pushargi ldfmt + ellipsis + pushargr %v0 /* 0 */ + addi %v0 %v0 4 + pushargr %v1 + addi %v1 %v1 8 + pushargr %v0 /* 1 */ + addi %v0 %v0 4 + pushargr %v1 + addi %v1 %v1 8 + pushargr %v0 /* 2 */ + addi %v0 %v0 4 + pushargr %v1 + addi %v1 %v1 8 + pushargr %v0 /* 3 */ + addi %v0 %v0 4 + pushargr %v1 + addi %v1 %v1 8 + pushargr %v0 /* 4 */ + addi %v0 %v0 4 + pushargr %v1 + addi %v1 %v1 8 + pushargr %v0 /* 5 */ + addi %v0 %v0 4 + pushargr %v1 + addi %v1 %v1 8 + pushargr %v0 /* 6 */ + addi %v0 %v0 4 + pushargr %v1 + addi %v1 %v1 8 + pushargr %v0 /* 7 */ + addi %v0 %v0 4 + pushargr %v1 + addi %v1 %v1 8 + pushargr %v0 /* 8 */ + addi %v0 %v0 4 + pushargr %v1 + addi %v1 %v1 8 + pushargr %v0 /* 9 */ + pushargr %v1 + finishi @sscanf + + movi %v0 ichk + movi %v1 dchk + movi %r0 0 + movi_d %f0 0.0 +loopid: + ldr_i %r1 %v0 + beqr checkd %r0 %r1 + calli @abort +checkd: + ldr_d %f1 %v1 + beqr_d nextid %f0 %f1 + calli @abort +nextid: + addi %r0 %r0 1 + addi_d %f0 %f0 1.0 + bgei outid %r0 10 + addi %v0 %v0 4 + addi %v1 %v1 8 + jmpi loopid +outid: + + prepare + pushargi buff + ellipsis + finishi @printf + + /* + sprintf(buff, + "%.1f %d %.1f %d %.1f %d %.1f %d %.1f %d " + "%.1f %d %.1f %d %.1f %d %.1f %d %.1f %d\n", + 0.0, 0, 1.0, 1, 2.0, 2, 3.0, 3, 4.0, 4, + 5, 5.0, 6.0, 6, 7.0, 7, 8.0, 8, 9.0, 9); + */ + prepare + pushargi buff + pushargi difmt + ellipsis + pushargi_d 0.0 + pushargi 0 + pushargi_d 1.0 + pushargi 1 + pushargi_d 2.0 + pushargi 2 + pushargi_d 3.0 + pushargi 3 + pushargi_d 4.0 + pushargi 4 + pushargi_d 5.0 + pushargi 5 + pushargi_d 6.0 + pushargi 6 + pushargi_d 7.0 + pushargi 7 + pushargi_d 8.0 + pushargi 8 + pushargi_d 9.0 + pushargi 9 + finishi @sprintf + + /* + sscanf(buff, + "%lf %d %lf %d %lf %d %lf %d %lf %d " + "%lf %d %lf %d %lf %d %lf %d %lf %d \n", + dchk+0, ichk+0, dchk+1, ichk+1, dchk+2, + ichk+2, dchk+3, ichk+3, dchk+4, ichk+4, + dchk+5, ichk+5, dchk+6, ichk+6, dchk+7, + ichk+7, dchk+8, ichk+8, dchk+9, ichk+9); + */ + movi %v0 dchk + movi %v1 ichk + prepare + pushargi buff + pushargi dlfmt + ellipsis + pushargr %v0 /* 0 */ + addi %v0 %v0 8 + pushargr %v1 + addi %v1 %v1 4 + pushargr %v0 /* 1 */ + addi %v0 %v0 8 + pushargr %v1 + addi %v1 %v1 4 + pushargr %v0 /* 2 */ + addi %v0 %v0 8 + pushargr %v1 + addi %v1 %v1 4 + pushargr %v0 /* 3 */ + addi %v0 %v0 8 + pushargr %v1 + addi %v1 %v1 4 + pushargr %v0 /* 4 */ + addi %v0 %v0 8 + pushargr %v1 + addi %v1 %v1 4 + pushargr %v0 /* 5 */ + addi %v0 %v0 8 + pushargr %v1 + addi %v1 %v1 4 + pushargr %v0 /* 6 */ + addi %v0 %v0 8 + pushargr %v1 + addi %v1 %v1 4 + pushargr %v0 /* 7 */ + addi %v0 %v0 8 + pushargr %v1 + addi %v1 %v1 4 + pushargr %v0 /* 8 */ + addi %v0 %v0 8 + pushargr %v1 + addi %v1 %v1 4 + pushargr %v0 /* 9 */ + pushargr %v1 + finishi @sscanf + + movi %v0 ichk + movi %v1 dchk + movi %r0 0 + movi_d %f0 0.0 +loopdi: + ldr_i %r1 %v0 + beqr check_d %r0 %r1 + calli @abort +check_d: + ldr_d %f1 %v1 + beqr_d nextdi %f0 %f1 + calli @abort +nextdi: + addi %r0 %r0 1 + addi_d %f0 %f0 1.0 + bgei outdi %r0 10 + addi %v0 %v0 4 + addi %v1 %v1 8 + jmpi loopdi +outdi: + + prepare + pushargi buff + ellipsis + finishi @printf + + ret + epilog |