aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-06-29 14:20:07 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-06-29 14:20:07 +0300
commit49aa680ccdac46d1d2a7f9f250999b7ff7099548 (patch)
tree1de3bd5209feadfd147f7a05d1ac925f98b747b1 /src
parent29718f2e84478b296c3198ae6d35cfd5d79efb14 (diff)
downloadejit-49aa680ccdac46d1d2a7f9f250999b7ff7099548.tar.gz
ejit-49aa680ccdac46d1d2a7f9f250999b7ff7099548.zip
start adding tests
Diffstat (limited to 'src')
-rw-r--r--src/common.h20
-rw-r--r--src/compile/compile.c127
-rw-r--r--src/ejit.c137
-rw-r--r--src/interp.c40
4 files changed, 207 insertions, 117 deletions
diff --git a/src/common.h b/src/common.h
index 1f2289d..c3442c6 100644
--- a/src/common.h
+++ b/src/common.h
@@ -57,6 +57,8 @@ enum ejit_opcode {
ADDR_F,
ADDI,
+ ABSR_F,
+
SUBR,
SUBR_F,
SUBI,
@@ -88,10 +90,10 @@ enum ejit_opcode {
CALLI,
CALLI_F,
- RET,
- RET_I,
- RET_F,
- RET_FI,
+ RETR,
+ RETI,
+ RETR_F,
+ RETI_F,
RETVAL,
RETVAL_F,
@@ -132,7 +134,7 @@ struct ejit_func {
union interp_ret {
- long r;
+ int64_t r;
double d;
};
@@ -142,9 +144,13 @@ struct interp_state {
struct vec args;
};
-union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *state, bool run, void ***labels_wb);
+union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
+ struct ejit_arg args[argc],
+ struct interp_state *state, bool run,
+ void ***labels_wb);
-long ejit_run_interp(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *state);
+int64_t ejit_run_interp(struct ejit_func *f, size_t argc,
+ struct ejit_arg args[argc], struct interp_state *state);
bool ejit_compile(struct ejit_func *f);
diff --git a/src/compile/compile.c b/src/compile/compile.c
index c07a46a..c9a92a2 100644
--- a/src/compile/compile.c
+++ b/src/compile/compile.c
@@ -5,8 +5,8 @@
static void *alloc_arena(size_t size)
{
return mmap(NULL, size,
- PROT_EXEC | PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
static void free_arena(void *arena, size_t size)
@@ -27,7 +27,7 @@ static size_t frploc_count(struct ejit_func *f)
static size_t stack_size(struct ejit_func *f)
{
return grploc_count(f) * sizeof(jit_uword_t)
- + frploc_count(f) * sizeof(jit_float64_t);
+ + frploc_count(f) * sizeof(jit_float64_t);
}
static jit_off_t stack_loc(size_t l)
@@ -40,7 +40,7 @@ static jit_off_t stack_loc_f(struct ejit_func *f, size_t l)
{
assert(l >= jit_vf_num());
return grploc_count(f) * sizeof(jit_uword_t)
- + (l - jit_vf_num()) * sizeof(jit_float64_t);
+ + (l - jit_vf_num()) * sizeof(jit_float64_t);
}
@@ -84,14 +84,16 @@ static void compile_label(jit_state_t *j, size_t ii, struct vec *labels)
vect_at(jit_addr_t, *labels, ii) = jit_address(j);
}
-static void compile_movi(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+static void compile_movi(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
{
jit_gpr_t r = getreg(f, i.r0, 0);
jit_movi(j, r, i.o);
putloc(f, j, i.r0, r);
}
-static void compile_movr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+static void compile_movr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
{
jit_gpr_t to = getreg(f, i.r0, 0);
jit_gpr_t from = getreg(f, i.r1, 1);
@@ -99,7 +101,8 @@ static void compile_movr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i
putloc(f, j, i.r0, to);
}
-static void compile_addr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+static void compile_addr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
{
jit_gpr_t dst = getreg(f, i.r0, 0);
jit_gpr_t src0 = getloc(f, j, i.r1, 1);
@@ -108,7 +111,8 @@ static void compile_addr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i
putloc(f, j, i.r0, dst);
}
-static void compile_addi(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+static void compile_addi(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
{
jit_gpr_t dst = getreg(f, i.r0, 0);
jit_gpr_t src0 = getloc(f, j, i.r1, 1);
@@ -116,7 +120,8 @@ static void compile_addi(struct ejit_func *f, jit_state_t *j, struct ejit_insn i
putloc(f, j, i.r0, dst);
}
-static void compile_subr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+static void compile_subr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
{
jit_gpr_t dst = getreg(f, i.r0, 0);
jit_gpr_t src0 = getloc(f, j, i.r1, 1);
@@ -125,7 +130,8 @@ static void compile_subr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i
putloc(f, j, i.r0, dst);
}
-static void compile_subi(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+static void compile_subi(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
{
jit_gpr_t dst = getreg(f, i.r0, 0);
jit_gpr_t src0 = getloc(f, j, i.r1, 1);
@@ -133,14 +139,16 @@ static void compile_subi(struct ejit_func *f, jit_state_t *j, struct ejit_insn i
putloc(f, j, i.r0, dst);
}
-static void compile_stxi64(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+static void compile_stxi64(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
{
jit_gpr_t r0 = getloc(f, j, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
jit_stxi_l(j, i.o, r1, r0);
}
-static void compile_ldxiu64(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+static void compile_ldxiu64(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
{
jit_gpr_t r0 = getreg(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -148,8 +156,10 @@ static void compile_ldxiu64(struct ejit_func *f, jit_state_t *j, struct ejit_ins
putloc(f, j, i.r0, r0);
}
-static void compile_reg_cmp(struct ejit_func *f, jit_state_t *j, struct ejit_insn i,
- jit_reloc_t (*bcomp)(jit_state_t *, jit_gpr_t, jit_gpr_t), long same)
+static void compile_reg_cmp(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i,
+ jit_reloc_t (*bcomp)(jit_state_t *, jit_gpr_t,
+ jit_gpr_t), long same)
{
jit_gpr_t r0 = getreg(f, i.r0, 0);
if (i.r1 == i.r2) {
@@ -185,7 +195,8 @@ static void compile_ltr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
compile_reg_cmp(f, j, i, jit_bltr, 0);
}
-static void compile_bltr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i, struct vec *relocs)
+static void compile_bltr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t c0 = getloc(f, j, i.r1, 0);
jit_gpr_t c1 = getloc(f, j, i.r2, 1);
@@ -194,7 +205,8 @@ static void compile_bltr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i
vect_append(struct reloc_helper, *relocs, &h);
}
-static void compile_beqi(struct ejit_func *f, jit_state_t *j, struct ejit_insn i, struct vec *relocs)
+static void compile_beqi(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_reloc_t r = jit_beqi(j, r1, i.o);
@@ -202,7 +214,8 @@ static void compile_beqi(struct ejit_func *f, jit_state_t *j, struct ejit_insn i
vect_append(struct reloc_helper, *relocs, &h);
}
-static void compile_bnei(struct ejit_func *f, jit_state_t *j, struct ejit_insn i, struct vec *relocs)
+static void compile_bnei(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_reloc_t r = jit_bnei(j, r1, i.o);
@@ -210,7 +223,8 @@ static void compile_bnei(struct ejit_func *f, jit_state_t *j, struct ejit_insn i
vect_append(struct reloc_helper, *relocs, &h);
}
-static void compile_bgti(struct ejit_func *f, jit_state_t *j, struct ejit_insn i, struct vec *relocs)
+static void compile_bgti(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_reloc_t r = jit_bgti(j, r1, i.o);
@@ -218,7 +232,8 @@ static void compile_bgti(struct ejit_func *f, jit_state_t *j, struct ejit_insn i
vect_append(struct reloc_helper, *relocs, &h);
}
-static void compile_jmp(struct ejit_func *f, jit_state_t *j, struct ejit_insn i, struct vec *relocs)
+static void compile_jmp(struct ejit_func *f, jit_state_t *j, struct ejit_insn i,
+ struct vec *relocs)
{
(void)(f);
jit_reloc_t r = jit_jmp(j);
@@ -226,7 +241,8 @@ static void compile_jmp(struct ejit_func *f, jit_state_t *j, struct ejit_insn i,
vect_append(struct reloc_helper, *relocs, &h);
}
-static void compile_retval(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+static void compile_retval(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
{
jit_gpr_t r0 = getreg(f, i.r0, 0);
jit_retval(j, r0);
@@ -256,14 +272,14 @@ static enum jit_operand_abi jit_abi_from(enum ejit_type t)
static size_t arg_offsetof(enum ejit_type t)
{
switch (t) {
- case EJIT_INT8: return offsetof(struct ejit_arg, c);
- case EJIT_INT16: return offsetof(struct ejit_arg, s);
- case EJIT_INT32: return offsetof(struct ejit_arg, i);
- case EJIT_INT64: return offsetof(struct ejit_arg, l);
- case EJIT_UINT8: return offsetof(struct ejit_arg, uc);
- case EJIT_UINT16: return offsetof(struct ejit_arg, us);
- case EJIT_UINT32: return offsetof(struct ejit_arg, ui);
- case EJIT_UINT64: return offsetof(struct ejit_arg, ul);
+ case EJIT_INT8: return offsetof(struct ejit_arg, i8);
+ case EJIT_INT16: return offsetof(struct ejit_arg, i16);
+ case EJIT_INT32: return offsetof(struct ejit_arg, i32);
+ case EJIT_INT64: return offsetof(struct ejit_arg, i64);
+ case EJIT_UINT8: return offsetof(struct ejit_arg, u8);
+ case EJIT_UINT16: return offsetof(struct ejit_arg, u16);
+ case EJIT_UINT32: return offsetof(struct ejit_arg, u32);
+ case EJIT_UINT64: return offsetof(struct ejit_arg, u64);
case EJIT_POINTER: return offsetof(struct ejit_arg, p);
case EJIT_FLOAT: return offsetof(struct ejit_arg, f);
case EJIT_DOUBLE: return offsetof(struct ejit_arg, d);
@@ -282,7 +298,8 @@ static jit_off_t arg_offset(struct ejit_insn i)
static jit_off_t type_offset(struct ejit_insn i)
{
- return (sizeof(struct ejit_arg) * i.r0) + offsetof(struct ejit_arg, type);
+ return (sizeof(struct ejit_arg) * i.r0) + offsetof(struct ejit_arg,
+ type);
}
static void fixup_operands(struct vec *operands, size_t fixup)
@@ -297,7 +314,8 @@ static void fixup_operands(struct vec *operands, size_t fixup)
}
}
-static void compile_imm_call(jit_state_t *j, struct vec *src, struct vec *dst, void *addr, size_t argc, jit_operand_t args[argc])
+static void compile_imm_call(jit_state_t *j, struct vec *src, struct vec *dst,
+ void *addr, size_t argc, jit_operand_t args[argc])
{
/* each move is type + arg, so twofold */
size_t movec = vec_len(src) / 2;
@@ -313,7 +331,8 @@ static void compile_imm_call(jit_state_t *j, struct vec *src, struct vec *dst, v
vec_reset(dst);
}
-static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, size_t size)
+static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
+ size_t size)
{
jit_begin(j, arena, size);
size_t gprs = f->gpr >= jit_v_num() ? jit_v_num() : f->gpr;
@@ -323,8 +342,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
/* very important, argc we don't really do anything with but JIR_R1
* contains the argument stack! */
jit_load_args_2(j,
- jit_operand_gpr(JIT_OPERAND_ABI_WORD, JIT_R0),
- jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_R1));
+ jit_operand_gpr(JIT_OPERAND_ABI_WORD, JIT_R0),
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_R1));
size_t stack = jit_align_stack(j, stack_size(f));
@@ -367,24 +386,29 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case JMP: compile_jmp(f, j, i, &relocs); break;
case ARG: {
- jit_operand_t type = jit_operand_imm(JIT_OPERAND_ABI_WORD, i.r1);
+ jit_operand_t type =
+ jit_operand_imm(JIT_OPERAND_ABI_WORD, i.r1);
jit_operand_t arg;
if (i.r0 < jit_v_num()) {
/* regular register */
- arg = jit_operand_gpr(jit_abi_from(i.r1), jit_v(i.r2));
+ arg = jit_operand_gpr(jit_abi_from(i.r1),
+ jit_v(i.r2));
}
else {
/* stack location, note that we'll fix up the SP
* offset before doing the actual call */
- arg = jit_operand_mem(jit_abi_from(i.r1), JIT_SP, stack_loc(i.r0));
+ arg = jit_operand_mem(jit_abi_from(i.r1),
+ JIT_SP, stack_loc(i.r0));
}
vec_append(&src, &type);
vec_append(&src, &arg);
jit_operand_t to[2] = {
- jit_operand_mem(JIT_OPERAND_ABI_WORD, JIT_SP, type_offset(i)),
- jit_operand_mem(jit_abi_from(i.r1), JIT_SP, arg_offset(i))
+ jit_operand_mem(JIT_OPERAND_ABI_WORD, JIT_SP,
+ type_offset(i)),
+ jit_operand_mem(jit_abi_from(i.r1), JIT_SP,
+ arg_offset(i))
};
vec_append(&dst, &to[0]);
@@ -394,7 +418,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case ESCAPEI: {
jit_operand_t args[2] = {
- jit_operand_imm(JIT_OPERAND_ABI_WORD, vec_len(&src) / 2),
+ jit_operand_imm(JIT_OPERAND_ABI_WORD,
+ vec_len(&src) / 2),
jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_SP)
};
compile_imm_call(j, &src, &dst, (void *)i.o, 2, args);
@@ -404,7 +429,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case CALLI: {
jit_operand_t args[3] = {
jit_operand_imm(JIT_OPERAND_ABI_POINTER, i.o),
- jit_operand_imm(JIT_OPERAND_ABI_WORD, vec_len(&src) / 2),
+ jit_operand_imm(JIT_OPERAND_ABI_WORD,
+ vec_len(&src) / 2),
jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_SP)
};
compile_imm_call(j, &src, &dst, ejit_run_func, 3, args);
@@ -412,7 +438,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
}
case RETVAL: compile_retval(f, j, i); break;
- case RET: {
+ case RETR: {
jit_gpr_t r = getloc(f, j, i.r0, 0);
/* R0 won't get overwritten by jit_leave_jit_abi */
jit_movr(j, JIT_R0, r);
@@ -422,7 +448,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
break;
}
- case RET_I: {
+ case RETI: {
jit_shrink_stack(j, stack);
jit_leave_jit_abi(j, gprs, fprs, frame);
jit_reti(j, i.o);
@@ -440,19 +466,21 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case PARAM: {
/* move from argument stack to location */
jit_operand_t from = jit_operand_mem(
- jit_abi_from(i.r1),
- JIT_R1,
- arg_offset(i)
- );
+ jit_abi_from(i.r1),
+ JIT_R1,
+ arg_offset(i)
+ );
jit_operand_t to;
if (i.r0 < jit_v_num()) {
/* regular register */
- to = jit_operand_gpr(jit_abi_from(i.r1), jit_v(i.r2));
+ to = jit_operand_gpr(jit_abi_from(i.r1),
+ jit_v(i.r2));
}
else {
/* stack location */
- to = jit_operand_mem(jit_abi_from(i.r1), JIT_SP, stack_loc(i.r2));
+ to = jit_operand_mem(jit_abi_from(i.r1), JIT_SP,
+ stack_loc(i.r2));
}
vec_append(&src, &from);
@@ -474,7 +502,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
}
foreach_vec(ri, relocs) {
- struct reloc_helper h = vect_at(struct reloc_helper, relocs, ri);
+ struct reloc_helper h = vect_at(struct reloc_helper, relocs,
+ ri);
jit_addr_t a = vect_at(jit_addr_t, labels, h.to);
jit_reloc_t r = h.r;
diff --git a/src/ejit.c b/src/ejit.c
index b059c88..f6f4d8e 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -5,31 +5,36 @@
#include "common.h"
-static void emit_insn_i(struct ejit_func *f, enum ejit_opcode op, size_t r0, size_t r1, long o)
+static void emit_insn_i(struct ejit_func *f, enum ejit_opcode op, size_t r0,
+ size_t r1, long o)
{
struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .o = o};
vec_append(&f->insns, &i);
}
-static void emit_insn_r(struct ejit_func *f, enum ejit_opcode op, size_t r0, size_t r1, size_t r2)
+static void emit_insn_r(struct ejit_func *f, enum ejit_opcode op, size_t r0,
+ size_t r1, size_t r2)
{
struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .r2 = r2};
vec_append(&f->insns, &i);
}
-static void emit_insn_p(struct ejit_func *f, enum ejit_opcode op, size_t r0, size_t r1, void *p)
+static void emit_insn_p(struct ejit_func *f, enum ejit_opcode op, size_t r0,
+ size_t r1, void *p)
{
struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .p = p};
vec_append(&f->insns, &i);
}
-static void emit_insn_f(struct ejit_func *f, enum ejit_opcode op, size_t r0, size_t r1, double d)
+static void emit_insn_f(struct ejit_func *f, enum ejit_opcode op, size_t r0,
+ size_t r1, double d)
{
struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .d = d};
vec_append(&f->insns, &i);
}
-struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc, const struct ejit_operand args[argc])
+struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc,
+ const struct ejit_operand args[argc])
{
struct ejit_func *f = malloc(sizeof(struct ejit_func));
assert(f);
@@ -43,8 +48,10 @@ struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc, const stru
for (size_t i = 0; i < argc; ++i) {
switch (args[i].kind) {
- case EJIT_OPERAND_GPR: emit_insn_r(f, PARAM, i, args[i].type, args[i].r); break;
- case EJIT_OPERAND_FPR: emit_insn_r(f, PARAM_F, i, args[i].type, args[i].r); break;
+ case EJIT_OPERAND_GPR: emit_insn_r(f, PARAM, i, args[i].type,
+ args[i].r); break;
+ case EJIT_OPERAND_FPR: emit_insn_r(f, PARAM_F, i, args[i].type,
+ args[i].r); break;
default: abort();
}
}
@@ -58,7 +65,8 @@ void ejit_compile_func(struct ejit_func *f, size_t gpr, size_t fpr)
ejit_select_compile_func(f, gpr, fpr, true);
}
-void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr, bool try_jit)
+void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr,
+ bool try_jit)
{
/* emit a final end instruction in case user didn't do a return */
emit_insn_i(f, END, 0, 0, 0);
@@ -109,14 +117,19 @@ void ejit_patch(struct ejit_func *f, struct ejit_reloc r, struct ejit_label l)
vect_at(struct ejit_insn, f->insns, r.insn) = i;
}
-void ejit_calli(struct ejit_func *s, struct ejit_func *f, size_t argc, const struct ejit_operand args[argc])
+void ejit_calli(struct ejit_func *s, struct ejit_func *f, size_t argc,
+ const struct ejit_operand args[argc])
{
for (size_t i = 0; i < argc; ++i) {
switch (args[i].kind) {
- case EJIT_OPERAND_GPR: emit_insn_r(s, ARG, i, args[i].type, args[i].r); break;
- case EJIT_OPERAND_FPR: emit_insn_r(s, ARG_F, i, args[i].type, args[i].r); break;
- case EJIT_OPERAND_IMM: emit_insn_i(s, ARG_I, i, args[i].type, args[i].r); break;
- case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, i, args[i].type, args[i].d); break;
+ case EJIT_OPERAND_GPR: emit_insn_r(s, ARG, i, args[i].type,
+ args[i].r); break;
+ case EJIT_OPERAND_FPR: emit_insn_r(s, ARG_F, i, args[i].type,
+ args[i].r); break;
+ case EJIT_OPERAND_IMM: emit_insn_i(s, ARG_I, i, args[i].type,
+ args[i].r); break;
+ case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, i, args[i].type,
+ args[i].d); break;
default: abort();
}
}
@@ -124,14 +137,19 @@ void ejit_calli(struct ejit_func *s, struct ejit_func *f, size_t argc, const str
emit_insn_p(s, CALLI, 0, 0, f);
}
-void ejit_escapei(struct ejit_func *s, ejit_escape_t f, size_t argc, const struct ejit_operand args[argc])
+void ejit_escapei(struct ejit_func *s, ejit_escape_t f, size_t argc,
+ const struct ejit_operand args[argc])
{
for (size_t i = 0; i < argc; ++i) {
switch (args[i].kind) {
- case EJIT_OPERAND_GPR: emit_insn_r(s, ARG, i, args[i].type, args[i].r); break;
- case EJIT_OPERAND_FPR: emit_insn_r(s, ARG_F, i, args[i].type, args[i].r); break;
- case EJIT_OPERAND_IMM: emit_insn_r(s, ARG_I, i, args[i].type, args[i].r); break;
- case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, i, args[i].type, args[i].d); break;
+ case EJIT_OPERAND_GPR: emit_insn_r(s, ARG, i, args[i].type,
+ args[i].r); break;
+ case EJIT_OPERAND_FPR: emit_insn_r(s, ARG_F, i, args[i].type,
+ args[i].r); break;
+ case EJIT_OPERAND_IMM: emit_insn_r(s, ARG_I, i, args[i].type,
+ args[i].r); break;
+ case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, i, args[i].type,
+ args[i].d); break;
default: abort();
}
}
@@ -139,14 +157,19 @@ void ejit_escapei(struct ejit_func *s, ejit_escape_t f, size_t argc, const struc
emit_insn_p(s, ESCAPEI, 0, 0, f);
}
-void ejit_escapei_f(struct ejit_func *s, ejit_escape_f_t f, size_t argc, const struct ejit_operand args[argc])
+void ejit_escapei_f(struct ejit_func *s, ejit_escape_f_t f, size_t argc,
+ const struct ejit_operand args[argc])
{
for (size_t i = 0; i < argc; ++i) {
switch (args[i].kind) {
- case EJIT_OPERAND_GPR: emit_insn_r(s, ARG, i, args[i].type, args[i].r); break;
- case EJIT_OPERAND_FPR: emit_insn_r(s, ARG_F, i, args[i].type, args[i].r); break;
- case EJIT_OPERAND_IMM: emit_insn_r(s, ARG_I, i, args[i].type, args[i].r); break;
- case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, i, args[i].type, args[i].d); break;
+ case EJIT_OPERAND_GPR: emit_insn_r(s, ARG, i, args[i].type,
+ args[i].r); break;
+ case EJIT_OPERAND_FPR: emit_insn_r(s, ARG_F, i, args[i].type,
+ args[i].r); break;
+ case EJIT_OPERAND_IMM: emit_insn_r(s, ARG_I, i, args[i].type,
+ args[i].r); break;
+ case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, i, args[i].type,
+ args[i].d); break;
default: abort();
}
}
@@ -159,72 +182,87 @@ void ejit_retval(struct ejit_func *s, struct ejit_gpr r0)
emit_insn_i(s, RETVAL, r0.r, 0, 0);
}
-void ejit_stxi_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, long o)
+void ejit_stxi_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ long 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)
+void ejit_ldxi_u64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ long o)
{
emit_insn_i(s, LDXIU64, r0.r, r1.r, o);
}
-void ejit_ret(struct ejit_func *s, struct ejit_gpr r0)
+void ejit_retr(struct ejit_func *s, struct ejit_gpr r0)
{
- emit_insn_r(s, RET, r0.r, 0, 0);
+ emit_insn_r(s, RETR, r0.r, 0, 0);
}
-void ejit_ret_f(struct ejit_func *s, struct ejit_fpr r0)
+void ejit_retr_f(struct ejit_func *s, struct ejit_fpr r0)
{
- emit_insn_r(s, RET_F, r0.f, 0, 0);
+ emit_insn_r(s, RETR_F, r0.f, 0, 0);
}
-void ejit_ret_i(struct ejit_func *s, long i)
+void ejit_reti(struct ejit_func *s, long i)
{
- emit_insn_i(s, RET_I, 0, 0, i);
+ emit_insn_i(s, RETI, 0, 0, i);
}
-void ejit_ret_fi(struct ejit_func *s, double f)
+void ejit_reti_f(struct ejit_func *s, double f)
{
- emit_insn_f(s, RET_FI, 0, 0, f);
+ emit_insn_f(s, RETI_F, 0, 0, f);
}
-void ejit_addr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2)
+void ejit_addr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
{
emit_insn_r(s, ADDR, r0.r, r1.r, r2.r);
}
-void ejit_addr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2)
+void ejit_addr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
{
emit_insn_r(s, ADDR_F, r0.f, r1.f, r2.f);
}
-void ejit_addi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, long o)
+void ejit_addi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ long o)
{
emit_insn_i(s, ADDI, r0.r, r1.r, o);
}
-void ejit_subr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2)
+void ejit_absr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+{
+ emit_insn_i(s, ABSR_F, r0.f, r1.f, 0);
+}
+
+void ejit_subr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
{
emit_insn_r(s, SUBR, r0.r, r1.r, r2.r);
}
-void ejit_subr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2)
+void ejit_subr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
{
emit_insn_r(s, SUBR_F, r0.f, r1.f, r2.f);
}
-void ejit_subi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, long o)
+void ejit_subi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ long o)
{
emit_insn_i(s, SUBI, r0.r, r1.r, o);
}
-void ejit_mulr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2)
+void ejit_mulr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
{
emit_insn_r(s, MULR, r0.r, r1.r, r2.r);
}
-void ejit_divr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2)
+void ejit_divr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
{
emit_insn_r(s, DIVR, r0.r, r1.r, r2.r);
}
@@ -247,17 +285,20 @@ void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
emit_insn_i(s, MOVR, r0.r, r1.r, 0);
}
-void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2)
+void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
{
emit_insn_r(s, EQR, r0.r, r1.r, r2.r);
}
-void ejit_ltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2)
+void ejit_ltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
{
emit_insn_r(s, LTR, r0.r, r1.r, r2.r);
}
-struct ejit_reloc ejit_bltr(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)
{
size_t addr = vec_len(&s->insns);
emit_insn_r(s, BLTR, 0, r0.r, r1.r);
@@ -296,7 +337,7 @@ static struct interp_state create_interp_state()
{
struct interp_state state;
state.gprs = vec_create(sizeof(long));
- state.gprs = vec_create(sizeof(double));
+ state.fprs = vec_create(sizeof(double));
state.args = vec_create(sizeof(struct ejit_arg));
return state;
}
@@ -308,7 +349,8 @@ static void destroy_interp_state(struct interp_state state)
vec_destroy(&state.args);
}
-long ejit_run_interp(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *state)
+long ejit_run_interp(struct ejit_func *f, size_t argc,
+ struct ejit_arg args[argc], struct interp_state *state)
{
assert(f->gpr && "trying to run a function that hasn't been compiled");
assert(f->rtype == EJIT_VOID || ejit_int_type(f->rtype));
@@ -331,7 +373,8 @@ long ejit_run_func(struct ejit_func *f, size_t argc, struct ejit_arg args[argc])
return r;
}
-double ejit_run_func_f(struct ejit_func *f, size_t argc, struct ejit_arg args[argc])
+double ejit_run_func_f(struct ejit_func *f, size_t argc,
+ struct ejit_arg args[argc])
{
assert(f->fpr && "trying to run a function that hasn't been compiled");
assert(ejit_float_type(f->rtype));
diff --git a/src/interp.c b/src/interp.c
index ed7e59c..3395537 100644
--- a/src/interp.c
+++ b/src/interp.c
@@ -1,8 +1,12 @@
#include <ejit/ejit.h>
+#include <math.h>
#include "common.h"
-union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *state, bool run, void ***labels_wb)
+union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
+ struct ejit_arg args[argc],
+ struct interp_state *state, bool run,
+ void ***labels_wb)
{
static void *labels[OPCODE_COUNT] = {
[MOVI] = &&MOVI,
@@ -13,6 +17,8 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
[ADDR_F] = &&ADDR_F,
[ADDI] = &&ADDI,
+ [ABSR_F] = &&ABSR_F,
+
[SUBR] = &&SUBR,
[SUBR_F] = &&SUBR_F,
[SUBI] = &&SUBI,
@@ -33,10 +39,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
[JMP] = &&JMP,
- [RET] = &&RET,
- [RET_I] = &&RET_I,
- [RET_F] = &&RET_F,
- [RET_FI] = &&RET_FI,
+ [RETR] = &&RETR,
+ [RETI] = &&RETI,
+ [RETR_F] = &&RETR_F,
+ [RETI_F] = &&RETI_F,
[RETVAL] = &&RETVAL,
@@ -76,10 +82,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
/* retval is kind of an unfortunate extra bit of state to keep track of,
* but having call and return value separated is pretty convenient for
* void calls so I guess I don't mind? */
- long retval = 0; double retval_f = 0.;
+ int64_t retval = 0; double retval_f = 0.;
size_t pc = 0;
-#define DO(x) x: { struct ejit_insn i = insns[pc]; (void)i;
+#define DO(x) x : { struct ejit_insn i = insns[pc]; (void)i;
#define JUMP(a) goto *insns[pc = a].addr;
#define DISPATCH() } goto *insns[++pc].addr;
@@ -116,6 +122,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
gpr[i.r0] = gpr[i.r1] + i.o;
DISPATCH();
+ DO(ABSR_F);
+ fpr[i.r0] = fabs(fpr[i.r1]);
+ DISPATCH();
+
DO(SUBR);
gpr[i.r0] = gpr[i.r1] - gpr[i.r2];
DISPATCH();
@@ -187,7 +197,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
DISPATCH();
DO(PARAM);
- gpr[i.r2] = args[i.r0].l;
+ gpr[i.r2] = args[i.r0].u64;
DISPATCH();
DO(PARAM_F);
@@ -217,7 +227,8 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
DO(CALLI);
struct ejit_func *f = i.p;
size_t argc = vec_len(&state->args) - prev_argc;
- struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) + prev_argc;
+ struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) +
+ prev_argc;
retval = ejit_run_interp(f, argc, args, state);
@@ -232,7 +243,8 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
DO(ESCAPEI);
ejit_escape_t f = i.p;
size_t argc = vec_len(&state->args) - prev_argc;
- struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) + prev_argc;
+ struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) +
+ prev_argc;
retval = f(argc, args);
@@ -241,22 +253,22 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
/* dispatch is technically unnecessary for returns, but keep it for
* symmetry */
- DO(RET);
+ DO(RETR);
retval = gpr[i.r0];
goto out_int;
DISPATCH();
- DO(RET_I);
+ DO(RETI);
retval = i.o;
goto out_int;
DISPATCH();
- DO(RET_F);
+ DO(RETR_F);
retval_f = fpr[i.r0];
goto out_float;
DISPATCH();
- DO(RET_FI);
+ DO(RETI_F);
retval_f = i.d;
goto out_float;
DISPATCH();