diff options
Diffstat (limited to 'src/ejit.c')
-rw-r--r-- | src/ejit.c | 137 |
1 files changed, 90 insertions, 47 deletions
@@ -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)); |