diff options
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | include/ejit/ejit.h | 131 | ||||
-rwxr-xr-x | scripts/gen-tests | 6 | ||||
-rw-r--r-- | src/common.h | 8 | ||||
-rw-r--r-- | src/ejit.c | 39 | ||||
-rw-r--r-- | src/interp.c | 18 | ||||
-rw-r--r-- | tests/addr.c | 7 | ||||
-rw-r--r-- | tests/addr_f.c | 37 | ||||
-rw-r--r-- | tests/addx.c | 88 | ||||
-rw-r--r-- | tests/andi.c | 40 | ||||
-rw-r--r-- | tests/andr.c | 140 | ||||
-rw-r--r-- | tests/beqi.c | 41 | ||||
-rw-r--r-- | tests/beqr.c | 49 |
13 files changed, 369 insertions, 238 deletions
@@ -0,0 +1,3 @@ ++ Check in compiler backend that nobody accidentally uses 64bit values on 32bit +systems ++ (MAYBE) Check that there aren't duplicate destinations in operand list? diff --git a/include/ejit/ejit.h b/include/ejit/ejit.h index 5152d8d..1869be9 100644 --- a/include/ejit/ejit.h +++ b/include/ejit/ejit.h @@ -26,19 +26,19 @@ enum ejit_type }; /* can be kind of dangerous since we default to a pointer, hmm */ -#define EJIT_TYPE(x)\ - _Generic((typeof(x))(0),\ - int8_t: EJIT_INT8,\ - int16_t: EJIT_INT16,\ - int32_t: EJIT_INT32,\ - int64_t: EJIT_INT64,\ - uint8_t: EJIT_UINT8,\ - uint16_t: EJIT_UINT16,\ - uint32_t: EJIT_UINT32,\ - uint64_t: EJIT_UINT64,\ - float: EJIT_FLOAT,\ - double: EJIT_DOUBLE,\ - default: EJIT_POINTER) +#define EJIT_TYPE(x) \ + _Generic((typeof(x))(0), \ + int8_t: EJIT_INT8, \ + int16_t: EJIT_INT16, \ + int32_t: EJIT_INT32, \ + int64_t: EJIT_INT64, \ + uint8_t: EJIT_UINT8, \ + uint16_t: EJIT_UINT16, \ + uint32_t: EJIT_UINT32, \ + uint64_t: EJIT_UINT64, \ + float: EJIT_FLOAT, \ + double: EJIT_DOUBLE, \ + default: EJIT_POINTER) struct ejit_arg { union { @@ -166,19 +166,21 @@ struct ejit_func; struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc, const struct ejit_operand args[argc]); -void ejit_compile_func(struct ejit_func *f, size_t gpr, size_t fpr, bool use_64); +void ejit_compile_func(struct ejit_func *f, size_t gpr, size_t fpr, + bool use_64); void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr, bool use_64, bool try_jit); int64_t ejit_run_func(struct ejit_func *f, size_t argc, - struct ejit_arg args[argc]); + struct ejit_arg args[argc]); static inline int64_t ejit_run_func_1(struct ejit_func *f, struct ejit_arg a0) { return ejit_run_func(f, 1, &a0); } -static inline int64_t ejit_run_func_2(struct ejit_func *f, struct ejit_arg a0, struct ejit_arg a1) +static inline int64_t ejit_run_func_2(struct ejit_func *f, struct ejit_arg a0, + struct ejit_arg a1) { struct ejit_arg args[2] = {a0, a1}; return ejit_run_func(f, 2, args); @@ -192,6 +194,13 @@ static inline double ejit_run_func_f_1(struct ejit_func *f, struct ejit_arg a0) return ejit_run_func_f(f, 1, &a0); } +static inline double ejit_run_func_f_2(struct ejit_func *f, struct ejit_arg a0, + struct ejit_arg a1) +{ + struct ejit_arg args[2] = {a0, a1}; + return ejit_run_func_f(f, 2, args); +} + void ejit_destroy_func(struct ejit_func *s); #define EJIT_GPR(x) ((struct ejit_gpr){.r = (x)}) @@ -252,25 +261,25 @@ static inline struct ejit_arg ejit_double(double a) return (struct ejit_arg){.d = a, .type = EJIT_DOUBLE}; } -#define EJIT_ARG(x, t) \ - _Generic((t)(0), \ - int8_t: ejit_i8, \ - int16_t: ejit_i16, \ - int32_t: ejit_i32, \ - int64_t: ejit_i64, \ - uint8_t: ejit_i8, \ - uint16_t: ejit_i16, \ - uint32_t: ejit_i32, \ - uint64_t: ejit_i64, \ - float: ejit_float, \ - double: ejit_double, \ +#define EJIT_ARG(x, t) \ + _Generic((t)(0), \ + int8_t: ejit_i8, \ + int16_t: ejit_i16, \ + int32_t: ejit_i32, \ + int64_t: ejit_i64, \ + uint8_t: ejit_i8, \ + uint16_t: ejit_i16, \ + uint32_t: ejit_i32, \ + uint64_t: ejit_i64, \ + float: ejit_float, \ + double: ejit_double, \ default: ejit_pointer \ )(x) #define EJIT_AUTO(x) \ EJIT_ARG(x, typeof(x)) -static inline ejit_use64(struct ejit_arg a) +static inline bool ejit_use64(struct ejit_arg a) { if (a.type == EJIT_INT64 || a.type == EJIT_UINT64) return true; @@ -308,7 +317,7 @@ void ejit_retval(struct ejit_func *s, struct ejit_gpr r0); void ejit_retval_f(struct ejit_func *s, struct ejit_fpr r0); /* move from r1 to r0 */ -void ejit_movi(struct ejit_func *s, struct ejit_gpr r0, long i); +void ejit_movi(struct ejit_func *s, struct ejit_gpr r0, int64_t i); void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1); void ejit_movr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1); @@ -327,27 +336,34 @@ void ejit_ldi_d(struct ejit_func *s, struct ejit_fpr r0, void *p); /* from r1 + o to r0 */ void ejit_ldxi_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_ldxi_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_ldxi_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_ldxi_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); void ejit_ldxi_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_ldxi_u16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_ldxi_u32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_ldxi_u64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); void ejit_ldxi_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_ldxi_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, - long o); + int64_t o); void ejit_sti_8(struct ejit_func *s, struct ejit_gpr r0, void *p); void ejit_sti_16(struct ejit_func *s, struct ejit_gpr r0, void *p); @@ -364,34 +380,42 @@ void ejit_sti_d(struct ejit_func *s, struct ejit_fpr r0, void *p); /* from r0 to r1 + o */ void ejit_stxi_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_stxi_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_stxi_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_stxi_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); void ejit_stxi_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, - long o); + int64_t o); + void ejit_stxi_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, - long o); + int64_t o); void ejit_addr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2); + void ejit_addr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2); + void ejit_addi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); void ejit_absr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1); void ejit_subr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2); + void ejit_subr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2); + void ejit_subi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o); + int64_t o); void ejit_mulr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2); @@ -403,6 +427,10 @@ void ejit_divr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, void ejit_divr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2); +void ejit_andr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2); +void ejit_andi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o); + void ejit_negr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1); void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, @@ -412,9 +440,10 @@ void ejit_ltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1); -struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, long o); -struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, long o); -struct ejit_reloc ejit_bgti(struct ejit_func *s, struct ejit_gpr r0, long o); +struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, int64_t o); +struct ejit_reloc ejit_beqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1); +struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, int64_t o); +struct ejit_reloc ejit_bgti(struct ejit_func *s, struct ejit_gpr r0, int64_t o); struct ejit_reloc ejit_jmp(struct ejit_func *s); void ejit_patch(struct ejit_func *s, struct ejit_reloc r, struct ejit_label l); diff --git a/scripts/gen-tests b/scripts/gen-tests index 934f13f..542bb7b 100755 --- a/scripts/gen-tests +++ b/scripts/gen-tests @@ -3,7 +3,8 @@ PREFIX=JIT_TEST for s in ${@} do - exe="tests/test-jit-$(basename ${s%.*})" + src="${s#*/}" + exe="tests/test-jit-${src%.*}" dep="tests/${exe}.d" echo "${PREFIX} += ${exe}" >> tests.mk @@ -16,7 +17,8 @@ done PREFIX=BCODE_TESTS for s in ${@} do - exe="tests/test-bcode-$(basename ${s%.*})" + src="${s#*/}" + exe="tests/test-bcode-${src%.*}" dep="tests/${exe}.d" echo "${PREFIX} += ${exe}" >> tests.mk diff --git a/src/common.h b/src/common.h index 1e21e89..37332aa 100644 --- a/src/common.h +++ b/src/common.h @@ -67,11 +67,15 @@ enum ejit_opcode { DIVR, NEGR, + ANDR, + ANDI, + EQR, LTR, BLTR, BNEI, + BEQR, BEQI, BGTI, JMP, @@ -115,7 +119,7 @@ struct ejit_insn { union { size_t r2; void *p; - long o; + int64_t o; double d; }; }; @@ -150,7 +154,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, void ***labels_wb); int64_t ejit_run_interp(struct ejit_func *f, size_t argc, - struct ejit_arg args[argc], struct interp_state *state); + struct ejit_arg args[argc], struct interp_state *state); bool ejit_compile(struct ejit_func *f, bool use_64); @@ -6,7 +6,7 @@ #include "common.h" static void emit_insn_i(struct ejit_func *f, enum ejit_opcode op, size_t r0, - size_t r1, long o) + size_t r1, int64_t o) { struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .o = o}; vec_append(&f->insns, &i); @@ -183,13 +183,13 @@ void ejit_retval(struct ejit_func *s, struct ejit_gpr r0) } void ejit_stxi_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o) + int64_t o) { emit_insn_i(s, STXI64, r0.r, r1.r, o); } void ejit_ldxi_u64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o) + int64_t o) { emit_insn_i(s, LDXIU64, r0.r, r1.r, o); } @@ -204,7 +204,7 @@ void ejit_retr_f(struct ejit_func *s, struct ejit_fpr r0) emit_insn_r(s, RETR_F, r0.f, 0, 0); } -void ejit_reti(struct ejit_func *s, long i) +void ejit_reti(struct ejit_func *s, int64_t i) { emit_insn_i(s, RETI, 0, 0, i); } @@ -227,7 +227,7 @@ void ejit_addr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, } void ejit_addi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - long o) + int64_t o) { emit_insn_i(s, ADDI, r0.r, r1.r, o); } @@ -267,12 +267,24 @@ void ejit_divr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, emit_insn_r(s, DIVR, r0.r, r1.r, r2.r); } +void ejit_andr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, ANDR, r0.r, r1.r, r2.r); +} + +void ejit_andi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, ANDI, r0.r, r1.r, o); +} + void ejit_negr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { emit_insn_i(s, NEGR, r0.r, r1.r, 0); } -void ejit_movi(struct ejit_func *s, struct ejit_gpr r0, long o) +void ejit_movi(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { emit_insn_i(s, MOVI, r0.r, 0, o); } @@ -305,21 +317,28 @@ struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0, return (struct ejit_reloc){.insn = addr}; } -struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, long o) +struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = vec_len(&s->insns); emit_insn_i(s, BNEI, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } -struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, long o) +struct ejit_reloc ejit_beqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) +{ + size_t addr = vec_len(&s->insns); + emit_insn_r(s, BEQR, 0, r0.r, r1.r); + return (struct ejit_reloc){.insn = addr}; +} + +struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = vec_len(&s->insns); emit_insn_i(s, BEQI, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } -struct ejit_reloc ejit_bgti(struct ejit_func *s, struct ejit_gpr r0, long o) +struct ejit_reloc ejit_bgti(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = vec_len(&s->insns); emit_insn_i(s, BGTI, 0, r0.r, o); @@ -336,7 +355,7 @@ struct ejit_reloc ejit_jmp(struct ejit_func *s) static struct interp_state create_interp_state() { struct interp_state state; - state.gprs = vec_create(sizeof(long)); + state.gprs = vec_create(sizeof(int64_t)); state.fprs = vec_create(sizeof(double)); state.args = vec_create(sizeof(struct ejit_arg)); return state; diff --git a/src/interp.c b/src/interp.c index 3395537..059b1d3 100644 --- a/src/interp.c +++ b/src/interp.c @@ -26,6 +26,9 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [MULR] = &&MULR, [DIVR] = &&DIVR, + [ANDR] = &&ANDR, + [ANDI] = &&ANDI, + [EQR] = &&EQR, [LTR] = &<R, @@ -34,6 +37,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [BLTR] = &&BLTR, [BNEI] = &&BNEI, + [BEQR] = &&BEQR, [BEQI] = &&BEQI, [BGTI] = &&BGTI, @@ -146,6 +150,14 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = gpr[i.r1] / gpr[i.r2]; DISPATCH(); + DO(ANDR); + gpr[i.r0] = gpr[i.r1] & gpr[i.r2]; + DISPATCH(); + + DO(ANDI); + gpr[i.r0] = gpr[i.r1] & i.o; + DISPATCH(); + DO(EQR); gpr[i.r0] = gpr[i.r1] == gpr[i.r2]; DISPATCH(); @@ -176,6 +188,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, DISPATCH(); + DO(BEQR); + if (gpr[i.r1] == gpr[i.r2]) + JUMP(i.r0); + + DISPATCH(); + DO(BEQI); if (gpr[i.r1] == i.o) JUMP(i.r0); diff --git a/tests/addr.c b/tests/addr.c index 472030f..b67eb29 100644 --- a/tests/addr.c +++ b/tests/addr.c @@ -2,8 +2,7 @@ #include <assert.h> #include "do_jit.h" -int -main (int argc, char *argv[]) +int main() { struct ejit_operand operands[2] = { EJIT_OPERAND_GPR(0, EJIT_TYPE(long)), @@ -17,6 +16,8 @@ main (int argc, char *argv[]) ejit_select_compile_func(f, 2, 0, EJIT_USE64(long), do_jit); - assert(ejit_run_func_2(f, EJIT_ARG(42, long), EJIT_ARG(69, long)) == 111); + assert(ejit_run_func_2(f, + EJIT_ARG(42, long), + EJIT_ARG(69, long)) == 111); ejit_destroy_func(f); } diff --git a/tests/addr_f.c b/tests/addr_f.c index 2aa9002..6562134 100644 --- a/tests/addr_f.c +++ b/tests/addr_f.c @@ -1,27 +1,24 @@ -#include "test.h" +#include <ejit/ejit.h> +#include <assert.h> +#include "do_jit.h" -static void -run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size) +int main() { - jit_begin(j, arena_base, arena_size); - size_t align = jit_enter_jit_abi(j, 0, 0, 0); - jit_load_args_2(j, jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F0), - jit_operand_fpr (JIT_OPERAND_ABI_DOUBLE, JIT_F1)); + struct ejit_operand operands[2] = { + EJIT_OPERAND_FPR(0, EJIT_TYPE(double)), + EJIT_OPERAND_FPR(1, EJIT_TYPE(double)) + }; - jit_addr_d(j, JIT_F0, JIT_F0, JIT_F1); - jit_leave_jit_abi(j, 0, 0, align); - jit_retr_d(j, JIT_F0); + struct ejit_func *f = ejit_create_func(EJIT_TYPE(double), 2, operands); - size_t size = 0; - void* ret = jit_end(j, &size); + ejit_addr_f(f, EJIT_FPR(0), EJIT_FPR(0), EJIT_FPR(1)); + ejit_retr_f(f, EJIT_FPR(0)); - double (*f)(double, double) = ret; - ASSERT(f(42., 69.) == 111.); - ASSERT(f(42.5, 69.5) == 112.); -} + ejit_select_compile_func(f, 0, 2, EJIT_USE64(double), do_jit); -int -main (int argc, char *argv[]) -{ - return main_helper(argc, argv, run_test); + assert(ejit_run_func_f_2(f, EJIT_ARG(42., double), + EJIT_ARG(69., double)) == 111.); + assert(ejit_run_func_f_2(f, EJIT_ARG(42.5, double), + EJIT_ARG(69.5, double)) == 112.); + ejit_destroy_func(f); } diff --git a/tests/addx.c b/tests/addx.c index 94b2f19..eed95ba 100644 --- a/tests/addx.c +++ b/tests/addx.c @@ -1,63 +1,79 @@ -#include "test.h" +/* still not entirely sure about semantics, should 32bit systems report carry on + * 32bit or 64bit internal register sizes? */ +#warning "carry operations unimplemented but TODO" +int main(){ +} + +/* would look something like this */ +#if 0 +#include <ejit/ejit.h> +#include <assert.h> +#include "do_jit.h" -static void -run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size) +int main() { - jit_begin(j, arena_base, arena_size); - size_t align = jit_enter_jit_abi(j, 0, 0, 0); - jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0), - jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1)); + struct ejit_operand operands[2] = { + EJIT_OPERAND_GPR(0, EJIT_TYPE(long)), + EJIT_OPERAND_GPR(1, EJIT_TYPE(long)) + }; + struct ejit_func *f = ejit_create_func(EJIT_TYPE(long), 2, operands); - jit_movi(j, JIT_R2, 0); - jit_addcr(j, JIT_R0, JIT_R0, JIT_R1); - jit_addxi(j, JIT_R2, JIT_R2, 0); - jit_leave_jit_abi(j, 0, 0, align); - jit_retr(j, JIT_R2); + ejit_movi(j, EJIT_GPR(2), EJIT_GPR(0)); + ejit_addcr(j, EJIT_GPR(0), EJIT_GPR(0), EJIT_GPR(1)); + ejit_addxi(j, EJIT_GPR(2), EJIT_GPR(2), 0); + ejit_retr(j, EJIT_GPR(2)); - size_t size = 0; - void* ret = jit_end(j, &size); + ejit_select_compile_func(f, 3, 0, EJIT_USE64(long), do_jit); jit_word_t (*f)(jit_word_t, jit_word_t) = ret; - ASSERT(f(0, 0) == 0); + assert(ejit_run_func_2(f, EJIT_ARG(0, long), EJIT_ARG(0, long)) == 0); #if EJIT_WORDSIZE == 32 /* carry */ - ASSERT(f(0xffffffff, 0xffffffff) == 1); + assert(ejit_run_func_2(f, + EJIT_ARG(0xffffffff, long), + EJIT_ARG(0xffffffff, long)) == 1); /* overflow */ - ASSERT(f(0x7fffffff, 1) == 0); + assert(ejit_run_func_2(f, + EJIT_ARG(0x7fffffff long), + EJIT_ARG(1, long)) == 0); + /* overflow */ - ASSERT(f(0x7fffffff, 0x7fffffff) == 0); + assert(ejit_run_func_2(f, + EJIT_ARG(0x7fffffff, long), + EJIT_ARG(0x7fffffff, long)) == 0); + /* carry */ - ASSERT(f(0x7fffffff, 0x80000000) == 0); + assert(ejit_run_func_2(f, + EJIT_ARG(0x7fffffff, long), + EJIT_ARG(0x80000000, long)) == 0); + /* carry+overflow */ - ASSERT(f(0x80000000, 0x80000000) == 1); + assert(ejit_run_func_2(f, + EJIT_ARG(0x80000000, long), + EJIT_ARG(0x80000000, long)) == 1); #else /* nothing */ - ASSERT(f(0xffffffff, 0xffffffff) == 0); + assert(f(0xffffffff, 0xffffffff) == 0); /* nothing */ - ASSERT(f(0x7fffffff, 1) == 0); + assert(f(0x7fffffff, 1) == 0); /* nothing */ - ASSERT(f(0x7fffffff, 0x7fffffff) == 0); + assert(f(0x7fffffff, 0x7fffffff) == 0); /* nothing */ - ASSERT(f(0x7fffffff, 0x80000000) == 0); + assert(f(0x7fffffff, 0x80000000) == 0); /* nothing */ - ASSERT(f(0x80000000, 0x80000000) == 0); + assert(f(0x80000000, 0x80000000) == 0); /* carry */ - ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 1); + assert(f(0xffffffffffffffff, 0xffffffffffffffff) == 1); /* overflow */ - ASSERT(f(0x7fffffffffffffff, 1) == 0); + assert(f(0x7fffffffffffffff, 1) == 0); /* overflow */ - ASSERT(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0); + assert(f(0x7fffffffffffffff, 0x7fffffffffffffff) == 0); /* overflow */ - ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0); + assert(f(0x7fffffffffffffff, 0x8000000000000000) == 0); /* carry+overflow */ - ASSERT(f(0x8000000000000000, 0x8000000000000000) == 1); + assert(f(0x8000000000000000, 0x8000000000000000) == 1); #endif } - -int -main (int argc, char *argv[]) -{ - return main_helper(argc, argv, run_test); -} +#endif diff --git a/tests/andi.c b/tests/andi.c index fa3551b..e41a424 100644 --- a/tests/andi.c +++ b/tests/andi.c @@ -1,31 +1,23 @@ -#include "test.h" +#include <ejit/ejit.h> +#include <assert.h> +#include "do_jit.h" -static void -run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size) +int main() { - jit_begin(j, arena_base, arena_size); - size_t align = jit_enter_jit_abi(j, 0, 0, 0); - jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0)); + struct ejit_operand operands[1] = { + EJIT_OPERAND_GPR(0, EJIT_TYPE(long)) + }; - jit_andi(j, JIT_R0, JIT_R0, 1); - jit_leave_jit_abi(j, 0, 0, align); - jit_retr(j, JIT_R0); + struct ejit_func *f = ejit_create_func(EJIT_TYPE(long), 1, operands); - size_t size = 0; - void* ret = jit_end(j, &size); + ejit_andi(f, EJIT_GPR(0), EJIT_GPR(0), 1); + ejit_retr(f, EJIT_GPR(0)); - jit_word_t (*f)(jit_word_t) = ret; + ejit_select_compile_func(f, 1, 0, EJIT_USE64(long), do_jit); - ASSERT(f(0x7fffffff) == 1); - ASSERT(f(0x80000000) == 0); -#if EJIT_WORDSIZE == 64 - ASSERT(f(0x7fffffffffffffff) == 1); - ASSERT(f(0x8000000000000000) == 0); -#endif -} - -int -main (int argc, char *argv[]) -{ - return main_helper(argc, argv, run_test); + assert(ejit_run_func_1(f, EJIT_ARG(0x7fffffff, long)) == 1); + assert(ejit_run_func_1(f, EJIT_ARG(0x80000000, long)) == 0); + assert(ejit_run_func_1(f, EJIT_ARG(0x7fffffffffffffff, long)) == 1); + assert(ejit_run_func_1(f, EJIT_ARG(0x8000000000000000, long)) == 0); + ejit_destroy_func(f); } diff --git a/tests/andr.c b/tests/andr.c index c4aaeaf..e714794 100644 --- a/tests/andr.c +++ b/tests/andr.c @@ -1,48 +1,100 @@ -#include "test.h" +#include <ejit/ejit.h> +#include <assert.h> +#include "do_jit.h" -static void -run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size) +int main() { - jit_begin(j, arena_base, arena_size); - size_t align = jit_enter_jit_abi(j, 0, 0, 0); - jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0), - jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1)); - - jit_andr(j, JIT_R0, JIT_R0, JIT_R1); - jit_leave_jit_abi(j, 0, 0, align); - jit_retr(j, JIT_R0); - - size_t size = 0; - void* ret = jit_end(j, &size); - - jit_word_t (*f)(jit_word_t, jit_word_t) = ret; - - ASSERT(f(0x7fffffff, 1) == 1); - ASSERT(f(1, 0x7fffffff) == 1); - ASSERT(f(0x80000000, 1) == 0); - ASSERT(f(1, 0x80000000) == 0); - ASSERT(f(0x7fffffff, 0x80000000) == 0); - ASSERT(f(0x80000000, 0x7fffffff) == 0); - ASSERT(f(0x7fffffff, 0xffffffff) == 0x7fffffff); - ASSERT(f(0xffffffff, 0x7fffffff) == 0x7fffffff); - ASSERT(f(0xffffffff, 0xffffffff) == 0xffffffff); - ASSERT(f(0x7fffffff, 0) == 0); - ASSERT(f(0, 0x7fffffff) == 0); -#if EJIT_WORDSIZE == 64 - ASSERT(f(0x7fffffffffffffff, 1) == 1); - ASSERT(f(1, 0x7fffffffffffffff) == 1); - ASSERT(f(0x8000000000000000, 1) == 0); - ASSERT(f(1, 0x8000000000000000) == 0); - ASSERT(f(0x7fffffffffffffff, 0x8000000000000000) == 0); - ASSERT(f(0x8000000000000000, 0x7fffffffffffffff) == 0); - ASSERT(f(0x7fffffffffffffff, 0xffffffffffffffff) == 0x7fffffffffffffff); - ASSERT(f(0xffffffffffffffff, 0x7fffffffffffffff) == 0x7fffffffffffffff); - ASSERT(f(0xffffffffffffffff, 0xffffffffffffffff) == 0xffffffffffffffff); -#endif -} + struct ejit_operand operands[2] = { + EJIT_OPERAND_GPR(0, EJIT_TYPE(long)), + EJIT_OPERAND_GPR(1, EJIT_TYPE(long)) + }; -int -main (int argc, char *argv[]) -{ - return main_helper(argc, argv, run_test); + struct ejit_func *f = ejit_create_func(EJIT_TYPE(long), 2, operands); + + ejit_andr(f, EJIT_GPR(0), EJIT_GPR(0), EJIT_GPR(1)); + ejit_retr(f, EJIT_GPR(0)); + + ejit_select_compile_func(f, 1, 0, EJIT_USE64(long), do_jit); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x7fffffff, long), + EJIT_ARG(1, long)) == 1); + + assert(ejit_run_func_2(f, + EJIT_ARG(1, long), + EJIT_ARG(0x7fffffff, long)) == 1); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x80000000, long), + EJIT_ARG(1, long)) == 0); + + assert(ejit_run_func_2(f, + EJIT_ARG(1, long), + EJIT_ARG(0x80000000, long)) == 0); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x7fffffff, long), + EJIT_ARG(0x80000000, long)) == 0); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x80000000, long), + EJIT_ARG(0x7fffffff, long)) == 0); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x7fffffff, long), + EJIT_ARG(0xffffffff, long)) == 0x7fffffff); + + assert(ejit_run_func_2(f, + EJIT_ARG(0xffffffff, long), + EJIT_ARG(0x7fffffff, long)) == 0x7fffffff); + + assert(ejit_run_func_2(f, + EJIT_ARG(0xffffffff, long), + EJIT_ARG(0xffffffff, long)) == 0xffffffff); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x7fffffff, long), + EJIT_ARG(0, long)) == 0); + + assert(ejit_run_func_2(f, + EJIT_ARG(0, long), + EJIT_ARG(0x7fffffff, long)) == 0); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x7fffffffffffffff, long), + EJIT_ARG(1, long)) == 1); + assert(ejit_run_func_2(f, + EJIT_ARG(1, long), + EJIT_ARG(0x7fffffffffffffff, long)) == 1); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x8000000000000000, long), + EJIT_ARG(1, long)) == 0); + + assert(ejit_run_func_2(f, + EJIT_ARG(1, long), + EJIT_ARG(0x8000000000000000, long)) == 0); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x7fffffffffffffff, long), + EJIT_ARG(0x8000000000000000, long)) == 0); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x8000000000000000, long), + EJIT_ARG(0x7fffffffffffffff, long)) == 0); + + assert(ejit_run_func_2(f, + EJIT_ARG(0x7fffffffffffffff, long), + EJIT_ARG(0xffffffffffffffff, long)) + == 0x7fffffffffffffff); + + assert(ejit_run_func_2(f, + EJIT_ARG(0xffffffffffffffff, long), + EJIT_ARG(0x7fffffffffffffff, long)) + == 0x7fffffffffffffff); + + assert((uint64_t)ejit_run_func_2(f, + EJIT_ARG(0xffffffffffffffff, long), + EJIT_ARG(0xffffffffffffffff, long)) + == 0xffffffffffffffff); } diff --git a/tests/beqi.c b/tests/beqi.c index b366a8e..147cd50 100644 --- a/tests/beqi.c +++ b/tests/beqi.c @@ -1,28 +1,27 @@ -#include "test.h" +#include <ejit/ejit.h> +#include <assert.h> +#include "do_jit.h" -static void -run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size) +int main() { - jit_begin(j, arena_base, arena_size); - size_t align = jit_enter_jit_abi(j, 0, 0, 0); - jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0)); + struct ejit_operand operands[1] = { + EJIT_OPERAND_GPR(0, EJIT_TYPE(long)) + }; - jit_reloc_t r = jit_beqi(j, JIT_R0, 0); - jit_leave_jit_abi(j, 0, 0, align); - jit_reti(j, 0); - jit_patch_here(j, r); - jit_leave_jit_abi(j, 0, 0, align); - jit_reti(j, 1); + struct ejit_func *f = ejit_create_func(EJIT_TYPE(long), 1, operands); - jit_word_t (*f)(jit_word_t) = jit_end(j, NULL); + struct ejit_reloc r = ejit_beqi(f, EJIT_GPR(0), 0); + ejit_reti(f, 0); - ASSERT(f(0) == 1); - ASSERT(f(1) == 0); - ASSERT(f(-1) == 0); -} + struct ejit_label l = ejit_label(f); + ejit_patch(f, r, l); + ejit_reti(f, 1); -int -main (int argc, char *argv[]) -{ - return main_helper(argc, argv, run_test); + ejit_select_compile_func(f, 1, 0, EJIT_USE64(long), do_jit); + + assert(ejit_run_func_1(f, EJIT_ARG(0, long)) == 1); + assert(ejit_run_func_1(f, EJIT_ARG(1, long)) == 0); + assert(ejit_run_func_1(f, EJIT_ARG(-1, long)) == 0); + + ejit_destroy_func(f); } diff --git a/tests/beqr.c b/tests/beqr.c index 0cc4476..109b48c 100644 --- a/tests/beqr.c +++ b/tests/beqr.c @@ -1,32 +1,31 @@ -#include "test.h" +#include <ejit/ejit.h> +#include <assert.h> +#include "do_jit.h" -static void -run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size) +int main() { - jit_begin(j, arena_base, arena_size); - size_t align = jit_enter_jit_abi(j, 0, 0, 0); - jit_load_args_2(j, jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R0), - jit_operand_gpr (JIT_OPERAND_ABI_WORD, JIT_R1)); + struct ejit_operand operands[2] = { + EJIT_OPERAND_GPR(0, EJIT_TYPE(long)), + EJIT_OPERAND_GPR(1, EJIT_TYPE(long)) + }; - jit_reloc_t r = jit_beqr(j, JIT_R0, JIT_R1); - jit_leave_jit_abi(j, 0, 0, align); - jit_reti(j, 0); - jit_patch_here(j, r); - jit_leave_jit_abi(j, 0, 0, align); - jit_reti(j, 1); + struct ejit_func *f = ejit_create_func(EJIT_TYPE(long), 2, operands); - jit_word_t (*f)(jit_word_t, jit_word_t) = jit_end(j, NULL); + struct ejit_reloc r = ejit_beqr(f, EJIT_GPR(0), EJIT_GPR(1)); + ejit_reti(f, 0); - ASSERT(f(0, 0) == 1); - ASSERT(f(0, 1) == 0); - ASSERT(f(1, 0) == 0); - ASSERT(f(-1, 0) == 0); - ASSERT(f(0, -1) == 0); - ASSERT(f(1, 1) == 1); -} + struct ejit_label l = ejit_label(f); + ejit_patch(f, r, l); + ejit_reti(f, 1); -int -main (int argc, char *argv[]) -{ - return main_helper(argc, argv, run_test); + ejit_select_compile_func(f, 2, 0, EJIT_USE64(long), do_jit); + + assert(ejit_run_func_2(f, EJIT_ARG(0, long), EJIT_ARG(0, long)) == 1); + assert(ejit_run_func_2(f, EJIT_ARG(0, long), EJIT_ARG(1, long)) == 0); + assert(ejit_run_func_2(f, EJIT_ARG(1, long), EJIT_ARG(0, long)) == 0); + assert(ejit_run_func_2(f, EJIT_ARG(-1, long), EJIT_ARG(0, long)) == 0); + assert(ejit_run_func_2(f, EJIT_ARG(0, long), EJIT_ARG(-1, long)) == 0); + assert(ejit_run_func_2(f, EJIT_ARG(1, long), EJIT_ARG(1, long)) == 1); + + ejit_destroy_func(f); } |