aboutsummaryrefslogtreecommitdiff
path: root/src/ejit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ejit.c')
-rw-r--r--src/ejit.c137
1 files changed, 90 insertions, 47 deletions
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));