aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2025-04-10 22:22:33 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2025-04-10 22:22:33 +0300
commit531d307d310881e69efc8ae8c8119f5f5799e0f9 (patch)
tree0038e06d042db954cd85f8b0076f5d1394a55421
parentbe5c83ba8e57bc67beee41bc2c7227e6b8ebd9d5 (diff)
downloadejit-tail.tar.gz
ejit-tail.zip
improve tests a bittail
+ Runs tests on all arches that I have easy access to
-rw-r--r--Makefile125
-rwxr-xr-xscripts/gen-tests2
-rw-r--r--src/compile/compile.c53
-rw-r--r--src/interp.c2
-rw-r--r--tests/makefile10
5 files changed, 157 insertions, 35 deletions
diff --git a/Makefile b/Makefile
index 7a482b7..548e5b8 100644
--- a/Makefile
+++ b/Makefile
@@ -12,16 +12,121 @@ check: all
@./scripts/gen-tests $$(echo tests/*.c)
$(MAKE) -f tests/makefile check
-# this kicks all unrecognised targets to the client script.
-# note that trying to compile individual files, e.g.
-#
-# make kernel.elf
-#
-# will not work, you would need
-#
-# make -f scripts/makefile kernel.elf
-#
-# instead
+# supported by jit
+.PHONY: check_linux_amd64
+check_linux_amd64:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/x86_64-linux-gnu \
+ $(MAKE) ARCH=amd64 CROSS_COMPILE=x86_64-linux-gnu- check
+
+.PHONY: check_linux_x86
+check_linux_x86:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/i686-linux-gnu \
+ $(MAKE) ARCH=x86 CROSS_COMPILE=i686-linux-gnu- check
+
+.PHONY: check_linux_aarch64
+check_linux_aarch64:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/aarch64-linux-gnu \
+ $(MAKE) ARCH=aarch64 CROSS_COMPILE=aarch64-linux-gnu- check
+
+.PHONY: check_linux_armhf
+check_linux_armhf:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf \
+ $(MAKE) ARCH=armhf CROSS_COMPILE=arm-linux-gnueabihf- check
+
+.PHONY: check_linux_powerpc64le
+check_linux_powerpc64le:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/powerpc64le-linux-gnu \
+ $(MAKE) ARCH=powerpc64le CROSS_COMPILE=powerpc64le-linux-gnu- check
+
+# note: older than revision 6
+.PHONY: check_linux_mips64el
+check_linux_mips64el:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/mips64el-linux-gnuabi64 \
+ $(MAKE) ARCH=mips64el CROSS_COMPILE=mips64el-linux-gnuabi64- check
+
+.PHONY: check_linux_mipsel
+check_linux_mipsel:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/mipsel-linux-gnu \
+ $(MAKE) ARCH=mipsel CROSS_COMPILE=mipsel-linux-gnu- check
+
+# not supported by jit atm
+.PHONY: check_linux_powerpc64
+check_linux_powerpc64:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/powerpc64-linux-gnu \
+ $(MAKE) ARCH=powerpc64 CROSS_COMPILE=powerpc64-linux-gnu- check
+
+.PHONY: check_linux_powerpc
+check_linux_powerpc:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/powerpc-linux-gnu \
+ $(MAKE) ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- check
+
+.PHONY: check_linux_sparc64
+check_linux_sparc64:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/sparc64-linux-gnu \
+ $(MAKE) ARCH=sparc64 CROSS_COMPILE=sparc64-linux-gnu- check
+
+.PHONY: check_linux_riscv64
+check_linux_riscv64:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/riscv64-linux-gnu \
+ $(MAKE) ARCH=riscv64 CROSS_COMPILE=riscv64-linux-gnu- check
+
+.PHONY: check_linux_s390x
+check_linux_s390x:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/s390x-linux-gnu \
+ $(MAKE) ARCH=s390x CROSS_COMPILE=s390x-linux-gnu- check
+
+.PHONY: check_linux_alpha
+check_linux_alpha:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/alpha-linux-gnu \
+ $(MAKE) ARCH=alpha CROSS_COMPILE=alpha-linux-gnu- check
+
+.PHONY: check_linux_hppa
+check_linux_hppa:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/hppa-linux-gnu \
+ $(MAKE) ARCH=hppa CROSS_COMPILE=hppa-linux-gnu- check
+
+.PHONY: check_linux_m68k
+check_linux_m68k:
+ $(MAKE) clean
+ QEMU_LD_PREFIX=/usr/m68k-linux-gnu \
+ $(MAKE) ARCH=m68k CROSS_COMPILE=m68k-linux-gnu- check
+
+.PHONY: check_linux
+check_linux:
+ $(MAKE) check_linux_amd64
+ $(MAKE) check_linux_x86
+ $(MAKE) check_linux_aarch64
+ $(MAKE) check_linux_armhf
+ $(MAKE) check_linux_powerpc64le
+ $(MAKE) check_linux_mips64el
+ $(MAKE) check_linux_mipsel
+ $(MAKE) check_linux_powerpc64
+ $(MAKE) check_linux_powerpc
+ $(MAKE) check_linux_sparc64
+ $(MAKE) check_linux_riscv64
+ $(MAKE) check_linux_s390x
+ $(MAKE) check_linux_alpha
+ $(MAKE) check_linux_hppa
+ $(MAKE) check_linux_m68k
+ # compiler+emulator not available or broken
+ #$(MAKE) check_linux_hppa64
+ #$(MAKE) check_linux_arc
+ #$(MAKE) check_linux_sh4
+
.DEFAULT: setup
$(MAKE) -f scripts/makefile $<
diff --git a/scripts/gen-tests b/scripts/gen-tests
index deac247..47ff9c9 100755
--- a/scripts/gen-tests
+++ b/scripts/gen-tests
@@ -12,4 +12,6 @@ do
echo "-include ${dep}" >> tests.mk
echo "${exe}: ${s} libejit.a" >> tests.mk
echo " \$(COMPILE_TEST) ${s} libejit.a -o ${exe} -lm" >> tests.mk
+ echo " ./${exe} \t# bytecode" >> tests.mk
+ echo " ./${exe} 1\t# jit" >> tests.mk
done
diff --git a/src/compile/compile.c b/src/compile/compile.c
index bfcb12d..5432bc1 100644
--- a/src/compile/compile.c
+++ b/src/compile/compile.c
@@ -52,6 +52,19 @@ static void assert_helper(const char *msg)
assert(false && msg);
}
+static bool gpr_free(size_t argc, jit_operand_t args[argc], jit_gpr_t r)
+{
+ for (size_t i = 0; i < argc; ++i) {
+ if (args[i].kind != JIT_OPERAND_KIND_GPR)
+ continue;
+
+ if (jit_gpr_regno(args[i].loc.gpr.gpr) == jit_gpr_regno(r))
+ return false;
+ }
+
+ return true;
+}
+
static void free_arena(void *arena, size_t size)
{
munmap(arena, size);
@@ -2489,7 +2502,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
* argument stack address */
jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_R0)
};
- compile_imm_call(j, &src, &dst, (void *)(uintptr_t)i.o, 2, args);
+ compile_imm_call(j, &src, &dst, (void *)i.p, 2, args);
restore_caller_save_regs(f, j);
operands_reset(&src);
@@ -2502,7 +2515,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
/* a bit of copy-paste between this and the next func,
* hmm */
assert(operands_len(&direct) <= 2);
- struct ejit_func *f = (struct ejit_func *)(uintptr_t)i.o;
+ struct ejit_func *f = (struct ejit_func *)i.p;
assert(f->direct_call);
jit_operand_t regs[2] = {
@@ -2560,32 +2573,44 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
(jit_imm_t)"trying to tail call interpreted function"));
jit_patch_here(j, direct_reloc);
#endif
+ size_t argc = operands_len(&direct);
+ /* r0 = target, r1 = arg1, r2 = arg2 */
jit_ldxi(j, JIT_R0, r, offsetof(struct ejit_func, direct_call));
- jit_operand_t regs[2] = {
+ jit_operand_t regs[3] = {
jit_operand_gpr(JIT_OPERAND_ABI_WORD, JIT_R1),
jit_operand_gpr(JIT_OPERAND_ABI_WORD, JIT_R2)
};
- jit_move_operands(j, regs, direct.buf, operands_len(&direct));
+ jit_move_operands(j, regs, direct.buf, argc);
/* with args safely in registers, reset stack/state
* while avoiding overwriting the call target */
- jit_gpr_t tmp = get_callr_temp(j);
- jit_movr(j, tmp, JIT_R0);
-
int frame_size = j->frame_size;
jit_shrink_stack(j, stack);
jit_leave_jit_abi(j, gprs, fprs, frame);
- /* now move args into place */
- jit_operand_t args[2] = {};
- foreach_vec(oi, direct) {
+ /* now move args into place, making sure we avoid our
+ * target register */
+ jit_operand_t args[3] = {};
+ for (size_t oi = 0; oi < argc; ++oi) {
args[oi] = *operands_at(&direct, oi);
}
- jit_locate_args(j, operands_len(&direct), args);
- jit_move_operands(j, args, regs, operands_len(&direct));
- jit_jmpr(j, tmp);
+ jit_locate_args(j, argc, args);
+
+ /* we know that at least one gpr must be free */
+ jit_gpr_t target = gpr_free(argc, args, JIT_R0) ? JIT_R0
+ : gpr_free(argc, args, JIT_R1) ? JIT_R1
+ : gpr_free(argc, args, JIT_R2) ? JIT_R2
+ : (abort(), JIT_R0);
+
+ /* move our target in JIT_R0 to whatever the free
+ * register is to avoid it being clobbered when we move
+ * the actual arguments */
+ args[argc] = jit_operand_gpr(JIT_OPERAND_ABI_POINTER, target);
+ regs[argc] = jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_R0);
+ jit_move_operands(j, args, regs, argc + 1);
+ jit_jmpr(j, target);
j->frame_size = frame_size;
operands_reset(&src);
@@ -2641,7 +2666,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case EJIT_OP_CALLI: {
save_caller_save_regs(f, j);
- struct ejit_func *f = (struct ejit_func *)(uintptr_t)i.o;
+ struct ejit_func *f = (struct ejit_func *)i.p;
#if __WORDSIZE != 64
assert(f->rtype != EJIT_INT64 && f->rtype != EJIT_UINT64);
#endif
diff --git a/src/interp.c b/src/interp.c
index 6f94f98..894be30 100644
--- a/src/interp.c
+++ b/src/interp.c
@@ -1063,7 +1063,7 @@ top:
DISPATCH();
DO(TAILI);
- f = (struct ejit_func *)(uintptr_t)i.o;
+ f = (struct ejit_func *)i.p;
assert(!f->direct_call && "trying to interpret compiled fun");
diff --git a/tests/makefile b/tests/makefile
index 081170f..53115de 100644
--- a/tests/makefile
+++ b/tests/makefile
@@ -32,14 +32,4 @@ COMPILE_TEST := $(COMPILER) $(WARNFLAGS) $(OPTFLAGS) $(LTOFLAGS) \
.PHONY: check
check: $(TESTS)
- @echo "Running bytecode tests..."
- @set -e; for test in $(TESTS); do \
- echo "Testing: $$test"; \
- ./$$test; \
- done
- @echo "Running jit tests..."
- @set -e; for test in $(TESTS); do \
- echo "Testing: $$test"; \
- ./$$test 1; \
- done
@echo "Success!"