diff options
Diffstat (limited to 'src/ejit.c')
-rw-r--r-- | src/ejit.c | 706 |
1 files changed, 395 insertions, 311 deletions
@@ -1,4 +1,5 @@ #include <assert.h> +#include <stdio.h> #include <sys/mman.h> #include <ejit/ejit.h> @@ -47,9 +48,12 @@ static void update_gpr(struct ejit_func *f, struct ejit_gpr r0) struct gpr_stat *gpr = gpr_stats_at(&f->gpr, r0.r); /* presumably first time we see this gpr */ /** @todo are branches faster than a memory write? */ - if (gpr->prio == 0) + if (gpr->prio == 0) { + gpr->start = insns_len(&f->insns); gpr->r = r0; + } + gpr->end = insns_len(&f->insns); gpr->prio += f->prio; } @@ -59,9 +63,12 @@ static void update_fpr(struct ejit_func *f, struct ejit_fpr f0) fpr_stats_append(&f->fpr, zero_fpr_stat()); struct fpr_stat *fpr = fpr_stats_at(&f->fpr, f0.f); - if (fpr->prio == 0) + if (fpr->prio == 0) { + fpr->start = insns_len(&f->insns); fpr->f = f0; + } + fpr->end = insns_len(&f->insns); fpr->prio += f->prio; } @@ -161,6 +168,8 @@ static void emit_insn_af(struct ejit_func *f, enum ejit_opcode op, size_t idx, e static void emit_insn_ad(struct ejit_func *f, enum ejit_opcode op, size_t idx, enum ejit_type type, double d) { + fprintf(stderr, "warning: immediate floats are currently not supported.\n" + "Consider moving values into FPRs.\n"); struct ejit_insn i = {.op = op, .r0 = idx, .r1 = type, .d = d}; insns_append(&f->insns, i); } @@ -336,9 +345,11 @@ struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc, f->fpr = fpr_stats_create(); f->arena = NULL; f->direct_call = NULL; + f->extern_call = NULL; f->size = 0; f->prio = 1; f->use_64 = false; + f->max_args = 0; for (size_t i = 0; i < argc; ++i) { types_append(&f->sign, args[i].type); @@ -346,20 +357,20 @@ struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc, switch (args[i].kind) { case EJIT_OPERAND_GPR: { assert(ejit_int_type(args[i].type)); - emit_insn_ar(f, PARAM, i, args[i].type, EJIT_GPR(args[i].r)); + emit_insn_ar(f, EJIT_OP_PARAM, i, args[i].type, EJIT_GPR(args[i].r)); break; } case EJIT_OPERAND_FPR: { assert(ejit_float_type(args[i].type)); - emit_insn_af(f, PARAM_F, i, args[i].type, EJIT_FPR(args[i].r)); + emit_insn_af(f, EJIT_OP_PARAM_F, i, args[i].type, EJIT_FPR(args[i].r)); break; } default: abort(); } } - emit_insn_o(f, START); + emit_insn_o(f, EJIT_OP_START); return f; } @@ -388,7 +399,7 @@ void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr, bool use_64, bool try_jit, bool im_scawed) { /* emit a final end instruction in case user didn't do a return */ - emit_insn_o(f, END); + emit_insn_o(f, EJIT_OP_END); /* user can get some sanity checking done by passing these explicitly */ assert(gpr >= gpr_stats_len(&f->gpr)); @@ -403,7 +414,7 @@ void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr, void **labels; /* just get labels, don't actually run anything yet */ - ejit_run(f, 0, NULL, NULL, false, &labels); + ejit_run(f, 0, NULL, &labels); foreach_vec(ii, f->insns) { struct ejit_insn i = *insns_at(&f->insns, ii); @@ -445,730 +456,819 @@ void ejit_patch(struct ejit_func *f, struct ejit_reloc r, struct ejit_label l) *insns_at(&f->insns, r.insn) = i; } -void ejit_calli_i(struct ejit_func *s, struct ejit_func *f, size_t argc, - const struct ejit_operand args[argc]) +void ejit_taili(struct ejit_func *s, struct ejit_func *f, + size_t argc, const struct ejit_operand args[argc]) { + assert(s->rtype == f->rtype); + + s->max_args = argc > s->max_args ? argc : s->max_args; check_operands(f, argc, args); + size_t gpr_args = 0, fpr_args = 0; for (size_t i = 0; i < argc; ++i) { switch (args[i].kind) { - case EJIT_OPERAND_GPR: emit_insn_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break; - case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break; - case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break; + case EJIT_OPERAND_GPR: + gpr_args++; + emit_insn_ar(s, EJIT_OP_ARG, i, args[i].type, EJIT_GPR(args[i].r)); + break; + + case EJIT_OPERAND_FPR: + fpr_args++; + emit_insn_af(s, EJIT_OP_ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); + break; + + case EJIT_OPERAND_IMM: + gpr_args++; + emit_insn_ai(s, EJIT_OP_ARG_I, i, args[i].type, args[i].r); + break; + + case EJIT_OPERAND_FLT: + fpr_args++; + emit_insn_ad(s, EJIT_OP_ARG_FI, i, args[i].type, args[i].d); + break; + default: abort(); } } - emit_insn_op(s, CALLI_I, f); + assert(gpr_args <= 2 && fpr_args == 0 + && "only 2 gpr args and 0 fpr args supported in tail calls for now"); + emit_insn_op(s, EJIT_OP_TAILI, f); } -void ejit_calli_l(struct ejit_func *s, struct ejit_func *f, size_t argc, +void ejit_tailr(struct ejit_func *s, struct ejit_gpr target, size_t argc, const struct ejit_operand args[argc]) { - s->use_64 = true; - check_operands(f, argc, args); + s->max_args = argc > s->max_args ? argc : s->max_args; + /* operands must match */ + check_operands(s, argc, args); + + size_t gpr_args = 0, fpr_args = 0; for (size_t i = 0; i < argc; ++i) { switch (args[i].kind) { - case EJIT_OPERAND_GPR: emit_insn_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break; - case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break; - case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break; + case EJIT_OPERAND_GPR: + gpr_args++; + emit_insn_ar(s, EJIT_OP_ARG, i, args[i].type, EJIT_GPR(args[i].r)); + break; + + case EJIT_OPERAND_FPR: + fpr_args++; + emit_insn_af(s, EJIT_OP_ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); + break; + + case EJIT_OPERAND_IMM: + gpr_args++; + emit_insn_ai(s, EJIT_OP_ARG_I, i, args[i].type, args[i].r); + break; + + case EJIT_OPERAND_FLT: + fpr_args++; + emit_insn_ad(s, EJIT_OP_ARG_FI, i, args[i].type, args[i].d); + break; + default: abort(); } } - emit_insn_op(s, CALLI_L, f); + assert(gpr_args <= 2 && fpr_args == 0 + && "only 2 gpr args and 0 fpr args supported in tail calls for now"); + emit_insn_oxr(s, EJIT_OP_TAILR, target); } -void ejit_calli_f(struct ejit_func *s, struct ejit_func *f, size_t argc, +void ejit_calli(struct ejit_func *s, struct ejit_func *f, size_t argc, const struct ejit_operand args[argc]) { + s->use_64 = f->rtype == EJIT_INT64 || f->rtype == EJIT_UINT64; + s->max_args = argc > s->max_args ? argc : s->max_args; check_operands(f, argc, args); for (size_t i = 0; i < argc; ++i) { switch (args[i].kind) { - case EJIT_OPERAND_GPR: emit_insn_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break; - case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break; - case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break; + case EJIT_OPERAND_GPR: + emit_insn_ar(s, EJIT_OP_ARG, i, args[i].type, EJIT_GPR(args[i].r)); + break; + + case EJIT_OPERAND_FPR: + emit_insn_af(s, EJIT_OP_ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); + break; + + case EJIT_OPERAND_IMM: + emit_insn_ai(s, EJIT_OP_ARG_I, i, args[i].type, args[i].r); + break; + + case EJIT_OPERAND_FLT: + emit_insn_ad(s, EJIT_OP_ARG_FI, i, args[i].type, args[i].d); + break; + default: abort(); } } - emit_insn_op(s, CALLI_F, f); + emit_insn_op(s, EJIT_OP_CALLI, f); } -void ejit_calli_d(struct ejit_func *s, struct ejit_func *f, size_t argc, - const struct ejit_operand args[argc]) +static void ejit_callr(struct ejit_func *s, enum ejit_opcode op, struct ejit_gpr target, + size_t argc, const struct ejit_operand args[argc]) { - check_operands(f, argc, args); + s->use_64 = op == EJIT_OP_CALLR_L; + s->max_args = argc > s->max_args ? argc : s->max_args; for (size_t i = 0; i < argc; ++i) { switch (args[i].kind) { - case EJIT_OPERAND_GPR: emit_insn_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break; - case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break; - case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break; + case EJIT_OPERAND_GPR: + emit_insn_ar(s, EJIT_OP_ARG, i, args[i].type, EJIT_GPR(args[i].r)); + break; + + case EJIT_OPERAND_FPR: + emit_insn_af(s, EJIT_OP_ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); + break; + + case EJIT_OPERAND_IMM: + emit_insn_ai(s, EJIT_OP_ARG_I, i, args[i].type, args[i].r); + break; + + case EJIT_OPERAND_FLT: + emit_insn_ad(s, EJIT_OP_ARG_FI, i, args[i].type, args[i].d); + break; + default: abort(); } } - emit_insn_op(s, CALLI_D, f); + emit_insn_oxr(s, op, target); } -void ejit_escapei_i(struct ejit_func *s, ejit_escape_i_t f, size_t argc, - const struct ejit_operand args[argc]) +void ejit_callr_i(struct ejit_func *s, struct ejit_gpr target, + 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_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break; - case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break; - case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break; - default: abort(); - } - } + ejit_callr(s, EJIT_OP_CALLR_I, target, argc, args); +} - emit_insn_op(s, ESCAPEI_I, f); +void ejit_callr_l(struct ejit_func *s, struct ejit_gpr target, + size_t argc, const struct ejit_operand args[argc]) +{ + ejit_callr(s, EJIT_OP_CALLR_L, target, argc, args); } -void ejit_escapei_l(struct ejit_func *s, ejit_escape_l_t f, size_t argc, - const struct ejit_operand args[argc]) +void ejit_callr_f(struct ejit_func *s, struct ejit_gpr target, + size_t argc, const struct ejit_operand args[argc]) { - s->use_64 = true; - for (size_t i = 0; i < argc; ++i) { - switch (args[i].kind) { - case EJIT_OPERAND_GPR: emit_insn_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break; - case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break; - case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break; - default: abort(); - } - } + ejit_callr(s, EJIT_OP_CALLR_F, target, argc, args); +} - emit_insn_op(s, ESCAPEI_L, f); +void ejit_callr_d(struct ejit_func *s, struct ejit_gpr target, + size_t argc, const struct ejit_operand args[argc]) +{ + ejit_callr(s, EJIT_OP_CALLR_D, target, argc, args); } -void ejit_escapei_f(struct ejit_func *s, ejit_escape_f_t f, size_t argc, - const struct ejit_operand args[argc]) +static void ejit_escapei(struct ejit_func *s, enum ejit_opcode op, void *f, + size_t argc, const struct ejit_operand args[argc]) { + s->use_64 = op == EJIT_OP_ESCAPEI_L; + s->max_args = argc > s->max_args ? argc : s->max_args; for (size_t i = 0; i < argc; ++i) { switch (args[i].kind) { - case EJIT_OPERAND_GPR: emit_insn_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break; - case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break; - case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break; + case EJIT_OPERAND_GPR: + emit_insn_ar(s, EJIT_OP_ARG, i, args[i].type, EJIT_GPR(args[i].r)); + break; + + case EJIT_OPERAND_FPR: + emit_insn_af(s, EJIT_OP_ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); + break; + + case EJIT_OPERAND_IMM: + emit_insn_ai(s, EJIT_OP_ARG_I, i, args[i].type, args[i].r); + break; + + case EJIT_OPERAND_FLT: + emit_insn_ad(s, EJIT_OP_ARG_FI, i, args[i].type, args[i].d); + break; + default: abort(); } } - emit_insn_op(s, ESCAPEI_F, f); + emit_insn_op(s, op, f); } -void ejit_escapei_d(struct ejit_func *s, ejit_escape_d_t f, size_t argc, - const struct ejit_operand args[argc]) +void ejit_escapei_i(struct ejit_func *s, ejit_escape_i_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_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break; - case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break; - case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break; - default: abort(); - } - } + ejit_escapei(s, EJIT_OP_ESCAPEI_I, f, argc, args); +} + +void ejit_escapei_l(struct ejit_func *s, ejit_escape_l_t f, + size_t argc, const struct ejit_operand args[argc]) +{ + ejit_escapei(s, EJIT_OP_ESCAPEI_L, f, argc, args); +} - emit_insn_op(s, ESCAPEI_D, f); +void ejit_escapei_f(struct ejit_func *s, ejit_escape_f_t f, + size_t argc, const struct ejit_operand args[argc]) +{ + ejit_escapei(s, EJIT_OP_ESCAPEI_F, f, argc, args); +} + +void ejit_escapei_d(struct ejit_func *s, ejit_escape_d_t f, + size_t argc, const struct ejit_operand args[argc]) +{ + ejit_escapei(s, EJIT_OP_ESCAPEI_D, f, argc, args); } void ejit_retval(struct ejit_func *s, struct ejit_gpr r0) { - emit_insn_or(s, RETVAL, r0); + emit_insn_or(s, EJIT_OP_RETVAL, r0); } void ejit_retval_f(struct ejit_func *s, struct ejit_fpr f0) { - emit_insn_of(s, RETVAL_F, f0); + emit_insn_of(s, EJIT_OP_RETVAL_F, f0); } void ejit_retval_d(struct ejit_func *s, struct ejit_fpr f0) { - emit_insn_of(s, RETVAL_D, f0); + emit_insn_of(s, EJIT_OP_RETVAL_D, f0); } void ejit_sti_8(struct ejit_func *s, struct ejit_gpr r0, void *p) { - emit_insn_orp(s, STI8, r0, p); + emit_insn_orp(s, EJIT_OP_STI8, r0, p); } void ejit_sti_16(struct ejit_func *s, struct ejit_gpr r0, void *p) { - emit_insn_orp(s, STI16, r0, p); + emit_insn_orp(s, EJIT_OP_STI16, r0, p); } void ejit_sti_32(struct ejit_func *s, struct ejit_gpr r0, void *p) { - emit_insn_orp(s, STI32, r0, p); + emit_insn_orp(s, EJIT_OP_STI32, r0, p); } void ejit_sti_64(struct ejit_func *s, struct ejit_gpr r0, void *p) { s->use_64 = true; - emit_insn_orp(s, STI64, r0, p); + emit_insn_orp(s, EJIT_OP_STI64, r0, p); } void ejit_sti_f(struct ejit_func *s, struct ejit_fpr f0, void *p) { - emit_insn_ofp(s, STIF, f0, p); + emit_insn_ofp(s, EJIT_OP_STIF, f0, p); } void ejit_sti_d(struct ejit_func *s, struct ejit_fpr f0, void *p) { - emit_insn_ofp(s, STID, f0, p); + emit_insn_ofp(s, EJIT_OP_STID, f0, p); } void ejit_stxi_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, STXI8, r0, r1, o); + emit_insn_orri(s, EJIT_OP_STXI8, r0, r1, o); } void ejit_stxi_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, STXI16, r0, r1, o); + emit_insn_orri(s, EJIT_OP_STXI16, r0, r1, o); } void ejit_stxi_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, STXI32, r0, r1, o); + emit_insn_orri(s, EJIT_OP_STXI32, r0, r1, o); } void ejit_stxi_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { s->use_64 = true; - emit_insn_orri(s, STXI64, r0, r1, o); + emit_insn_orri(s, EJIT_OP_STXI64, r0, r1, o); } void ejit_stxi_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1, int64_t o) { - emit_insn_ofri(s, STXIF, f0, r1, o); + emit_insn_ofri(s, EJIT_OP_STXIF, f0, r1, o); } void ejit_stxi_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1, int64_t o) { - emit_insn_ofri(s, STXID, f0, r1, o); + emit_insn_ofri(s, EJIT_OP_STXID, f0, r1, o); } void ejit_stxr_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, STXR8, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_STXR8, r0, r1, r2); } void ejit_stxr_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, STXR16, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_STXR16, r0, r1, r2); } void ejit_stxr_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, STXR32, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_STXR32, r0, r1, r2); } void ejit_stxr_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { s->use_64 = true; - emit_insn_orrr(s, STXR64, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_STXR64, r0, r1, r2); } void ejit_stxr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_ofrr(s, STXRF, f0, r1, r2); + emit_insn_ofrr(s, EJIT_OP_STXRF, f0, r1, r2); } void ejit_stxr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_ofrr(s, STXRD, f0, r1, r2); + emit_insn_ofrr(s, EJIT_OP_STXRD, f0, r1, r2); } void ejit_ldi_i8(struct ejit_func *s, struct ejit_gpr r0, void *p) { - emit_insn_orp(s, LDI8, r0, p); + emit_insn_orp(s, EJIT_OP_LDI8, r0, p); } void ejit_ldi_i16(struct ejit_func *s, struct ejit_gpr r0, void *p) { - emit_insn_orp(s, LDI16, r0, p); + emit_insn_orp(s, EJIT_OP_LDI16, r0, p); } void ejit_ldi_i32(struct ejit_func *s, struct ejit_gpr r0, void *p) { - emit_insn_orp(s, LDI32, r0, p); + emit_insn_orp(s, EJIT_OP_LDI32, r0, p); } void ejit_ldi_i64(struct ejit_func *s, struct ejit_gpr r0, void *p) { - emit_insn_orp(s, LDI64, r0, p); + emit_insn_orp(s, EJIT_OP_LDI64, r0, p); } void ejit_ldi_u8(struct ejit_func *s, struct ejit_gpr r0, void *p) { - emit_insn_orp(s, LDIU8, r0, p); + emit_insn_orp(s, EJIT_OP_LDIU8, r0, p); } void ejit_ldi_u16(struct ejit_func *s, struct ejit_gpr r0, void *p) { - emit_insn_orp(s, LDIU16, r0, p); + emit_insn_orp(s, EJIT_OP_LDIU16, r0, p); } void ejit_ldi_u32(struct ejit_func *s, struct ejit_gpr r0, void *p) { s->use_64 = true; - emit_insn_orp(s, LDIU32, r0, p); + emit_insn_orp(s, EJIT_OP_LDIU32, r0, p); } void ejit_ldi_u64(struct ejit_func *s, struct ejit_gpr r0, void *p) { s->use_64 = true; - emit_insn_orp(s, LDIU64, r0, p); + emit_insn_orp(s, EJIT_OP_LDIU64, r0, p); } void ejit_ldi_f(struct ejit_func *s, struct ejit_fpr f0, void *p) { - emit_insn_ofp(s, LDIF, f0, p); + emit_insn_ofp(s, EJIT_OP_LDIF, f0, p); } void ejit_ldi_d(struct ejit_func *s, struct ejit_fpr f0, void *p) { - emit_insn_ofp(s, LDID, f0, p); + emit_insn_ofp(s, EJIT_OP_LDID, f0, p); } void ejit_ldxi_i8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, LDXI8, r0, r1, o); + emit_insn_orri(s, EJIT_OP_LDXI8, r0, r1, o); } void ejit_ldxi_i16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, LDXI16, r0, r1, o); + emit_insn_orri(s, EJIT_OP_LDXI16, r0, r1, o); } void ejit_ldxi_i32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, LDXI32, r0, r1, o); + emit_insn_orri(s, EJIT_OP_LDXI32, r0, r1, o); } void ejit_ldxi_i64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, LDXI64, r0, r1, o); + emit_insn_orri(s, EJIT_OP_LDXI64, r0, r1, o); } void ejit_ldxi_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, LDXIU8, r0, r1, o); + emit_insn_orri(s, EJIT_OP_LDXIU8, r0, r1, o); } void ejit_ldxi_u16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, LDXIU16, r0, r1, o); + emit_insn_orri(s, EJIT_OP_LDXIU16, r0, r1, o); } void ejit_ldxi_u32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, LDXIU32, r0, r1, o); + emit_insn_orri(s, EJIT_OP_LDXIU32, r0, r1, o); } void ejit_ldxi_u64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, LDXIU64, r0, r1, o); + emit_insn_orri(s, EJIT_OP_LDXIU64, r0, r1, o); } void ejit_ldxi_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1, int64_t o) { - emit_insn_ofri(s, LDXIF, f0, r1, o); + emit_insn_ofri(s, EJIT_OP_LDXIF, f0, r1, o); } void ejit_ldxi_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1, int64_t o) { - emit_insn_ofri(s, LDXID, f0, r1, o); + emit_insn_ofri(s, EJIT_OP_LDXID, f0, r1, o); } void ejit_ldxr_i8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, LDXR8, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_LDXR8, r0, r1, r2); } void ejit_ldxr_i16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, LDXR16, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_LDXR16, r0, r1, r2); } void ejit_ldxr_i32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, LDXR32, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_LDXR32, r0, r1, r2); } void ejit_ldxr_i64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, LDXR64, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_LDXR64, r0, r1, r2); } void ejit_ldxr_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, LDXRU8, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_LDXRU8, r0, r1, r2); } void ejit_ldxr_u16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, LDXRU16, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_LDXRU16, r0, r1, r2); } void ejit_ldxr_u32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, LDXRU32, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_LDXRU32, r0, r1, r2); } void ejit_ldxr_u64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, LDXIU64, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_LDXIU64, r0, r1, r2); } void ejit_ldxr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_ofrr(s, LDXRF, f0, r1, r2); + emit_insn_ofrr(s, EJIT_OP_LDXRF, f0, r1, r2); } void ejit_ldxr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_ofrr(s, LDXRD, f0, r1, r2); + emit_insn_ofrr(s, EJIT_OP_LDXRD, f0, r1, r2); } void ejit_ret(struct ejit_func *s) { - emit_insn_o(s, END); + emit_insn_o(s, EJIT_OP_END); } void ejit_retr(struct ejit_func *s, struct ejit_gpr r0) { - emit_insn_oxr(s, RETR, r0); + assert(s->rtype != EJIT_FLOAT && s->rtype != EJIT_DOUBLE); + emit_insn_oxr(s, EJIT_OP_RETR, r0); } void ejit_retr_f(struct ejit_func *s, struct ejit_fpr f0) { - emit_insn_oxf(s, RETR_F, f0); + assert(s->rtype == EJIT_FLOAT); + emit_insn_oxf(s, EJIT_OP_RETR_F, f0); } void ejit_retr_d(struct ejit_func *s, struct ejit_fpr f0) { - emit_insn_oxf(s, RETR_D, f0); + assert(s->rtype == EJIT_DOUBLE); + emit_insn_oxf(s, EJIT_OP_RETR_D, f0); } void ejit_reti(struct ejit_func *s, int64_t i) { - emit_insn_oi(s, RETI, i); + assert(s->rtype != EJIT_FLOAT && s->rtype != EJIT_DOUBLE); + emit_insn_oi(s, EJIT_OP_RETI, i); } void ejit_reti_f(struct ejit_func *s, float f) { - emit_insn_oF(s, RETI_F, f); + assert(s->rtype == EJIT_FLOAT); + emit_insn_oF(s, EJIT_OP_RETI_F, f); } void ejit_reti_d(struct ejit_func *s, double f) { - emit_insn_oD(s, RETI_D, f); + assert(s->rtype == EJIT_DOUBLE); + emit_insn_oD(s, EJIT_OP_RETI_D, f); } void ejit_extr_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - emit_insn_orr(s, EXTR8, r0, r1); + emit_insn_orr(s, EJIT_OP_EXTR8, r0, r1); } void ejit_extr_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - emit_insn_orr(s, EXTR16, r0, r1); + emit_insn_orr(s, EJIT_OP_EXTR16, r0, r1); } void ejit_extr_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { s->use_64 = true; - emit_insn_orr(s, EXTR32, r0, r1); + emit_insn_orr(s, EJIT_OP_EXTR32, r0, r1); } void ejit_extr_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - emit_insn_orr(s, EXTRU8, r0, r1); + emit_insn_orr(s, EJIT_OP_EXTRU8, r0, r1); } void ejit_extr_u16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - emit_insn_orr(s, EXTRU16, r0, r1); + emit_insn_orr(s, EJIT_OP_EXTRU16, r0, r1); } void ejit_extr_u32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { s->use_64 = true; - emit_insn_orr(s, EXTRU32, r0, r1); + emit_insn_orr(s, EJIT_OP_EXTRU32, r0, r1); } void ejit_extr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1) { - emit_insn_ofr(s, EXTRF, f0, r1); + emit_insn_ofr(s, EJIT_OP_EXTRF, f0, r1); } void ejit_extr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1) { - emit_insn_ofr(s, EXTRD, f0, r1); + emit_insn_ofr(s, EJIT_OP_EXTRD, f0, r1); } void ejit_addr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, ADDR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_ADDR, r0, r1, r2); } void ejit_addr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_offf(s, ADDR_F, f0, f1, f2); + emit_insn_offf(s, EJIT_OP_ADDR_F, f0, f1, f2); } void ejit_addr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_offf(s, ADDR_D, f0, f1, f2); + emit_insn_offf(s, EJIT_OP_ADDR_D, f0, f1, f2); } void ejit_addi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, ADDI, r0, r1, o); + emit_insn_orri(s, EJIT_OP_ADDI, r0, r1, o); } void ejit_absr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { - emit_insn_off(s, ABSR_F, f0, f1); + emit_insn_off(s, EJIT_OP_ABSR_F, f0, f1); } void ejit_absr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { - emit_insn_off(s, ABSR_D, f0, f1); + emit_insn_off(s, EJIT_OP_ABSR_D, f0, f1); } void ejit_subr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, SUBR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_SUBR, r0, r1, r2); } void ejit_subr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_offf(s, SUBR_F, f0, f1, f2); + emit_insn_offf(s, EJIT_OP_SUBR_F, f0, f1, f2); } void ejit_subr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_offf(s, SUBR_D, f0, f1, f2); + emit_insn_offf(s, EJIT_OP_SUBR_D, f0, f1, f2); } void ejit_subi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, SUBI, r0, r1, o); + emit_insn_orri(s, EJIT_OP_SUBI, r0, r1, o); } void ejit_mulr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, MULR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_MULR, r0, r1, r2); } void ejit_mulr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_offf(s, MULR_F, f0, f1, f2); + emit_insn_offf(s, EJIT_OP_MULR_F, f0, f1, f2); } void ejit_mulr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_offf(s, MULR_D, f0, f1, f2); + emit_insn_offf(s, EJIT_OP_MULR_D, f0, f1, f2); } void ejit_divr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, DIVR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_DIVR, r0, r1, r2); } void ejit_divr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, DIVR_U, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_DIVR_U, r0, r1, r2); } void ejit_divr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_offf(s, DIVR_F, f0, f1, f2); + emit_insn_offf(s, EJIT_OP_DIVR_F, f0, f1, f2); } void ejit_divr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_offf(s, DIVR_D, f0, f1, f2); + emit_insn_offf(s, EJIT_OP_DIVR_D, f0, f1, f2); } void ejit_remr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, REMR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_REMR, r0, r1, r2); } void ejit_remr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, REMR_U, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_REMR_U, r0, r1, r2); } void ejit_lshi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, LSHI, r0, r1, o); + emit_insn_orri(s, EJIT_OP_LSHI, r0, r1, o); } void ejit_lshr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, LSHR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_LSHR, r0, r1, r2); } void ejit_rshi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, RSHI, r0, r1, o); + emit_insn_orri(s, EJIT_OP_RSHI, r0, r1, o); } void ejit_rshi_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, RSHI_U, r0, r1, o); + emit_insn_orri(s, EJIT_OP_RSHI_U, r0, r1, o); } void ejit_rshr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, RSHR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_RSHR, r0, r1, r2); } void ejit_rshr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, RSHR_U, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_RSHR_U, r0, r1, r2); } void ejit_andr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, ANDR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_ANDR, r0, r1, r2); } void ejit_andi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, ANDI, r0, r1, o); + emit_insn_orri(s, EJIT_OP_ANDI, r0, r1, o); } void ejit_orr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, ORR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_ORR, r0, r1, r2); } void ejit_ori(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, ORI, r0, r1, o); + emit_insn_orri(s, EJIT_OP_ORI, r0, r1, o); } void ejit_xorr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, XORR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_XORR, r0, r1, r2); } void ejit_xori(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { - emit_insn_orri(s, XORI, r0, r1, o); + emit_insn_orri(s, EJIT_OP_XORI, r0, r1, o); } void ejit_comr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - emit_insn_orr(s, COMR, r0, r1); + emit_insn_orr(s, EJIT_OP_COMR, r0, r1); } void ejit_negr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - emit_insn_orr(s, NEGR, r0, r1); + emit_insn_orr(s, EJIT_OP_NEGR, r0, r1); } void ejit_negr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { - emit_insn_off(s, NEGR_F, f0, f1); + emit_insn_off(s, EJIT_OP_NEGR_F, f0, f1); } void ejit_negr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { - emit_insn_off(s, NEGR_D, f0, f1); + emit_insn_off(s, EJIT_OP_NEGR_D, f0, f1); } void ejit_movi(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - emit_insn_ori(s, MOVI, r0, o); + emit_insn_ori(s, EJIT_OP_MOVI, r0, o); } void ejit_movi_f(struct ejit_func *s, struct ejit_fpr f0, float o) { - emit_insn_ofF(s, MOVI_F, f0, o); + emit_insn_ofF(s, EJIT_OP_MOVI_F, f0, o); } void ejit_movi_d(struct ejit_func *s, struct ejit_fpr f0, double o) { - emit_insn_ofD(s, MOVI_D, f0, o); + emit_insn_ofD(s, EJIT_OP_MOVI_D, f0, o); } void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) @@ -1176,7 +1276,7 @@ void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) if (r0.r == r1.r) return; - emit_insn_orr(s, MOVR, r0, r1); + emit_insn_orr(s, EJIT_OP_MOVR, r0, r1); } void ejit_movr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) @@ -1184,7 +1284,7 @@ void ejit_movr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) if (f0.f == f1.f) return; - emit_insn_off(s, MOVR_F, f0, f1); + emit_insn_off(s, EJIT_OP_MOVR_F, f0, f1); } void ejit_movr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) @@ -1192,179 +1292,209 @@ void ejit_movr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) if (f0.f == f1.f) return; - emit_insn_off(s, MOVR_D, f0, f1); + emit_insn_off(s, EJIT_OP_MOVR_D, f0, f1); } void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, EQR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_EQR, r0, r1, r2); } void ejit_eqr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, EQR_F, r0, f1, f2); + emit_insn_orff(s, EJIT_OP_EQR_F, r0, f1, f2); } void ejit_eqr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, EQR_D, r0, f1, f2); + emit_insn_orff(s, EJIT_OP_EQR_D, r0, f1, f2); } void ejit_ner(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, NER, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_NER, r0, r1, r2); } void ejit_ner_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, NER_F, r0, f1, f2); + emit_insn_orff(s, EJIT_OP_NER_F, r0, f1, f2); } void ejit_ner_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, NER_D, r0, f1, f2); + emit_insn_orff(s, EJIT_OP_NER_D, r0, f1, f2); } void ejit_gtr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, GTR, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_GTR, r0, r1, r2); } void ejit_gtr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, GTR_U, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_GTR_U, r0, r1, r2); } void ejit_gtr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, GTR_F, r0, f1, f2); + emit_insn_orff(s, EJIT_OP_GTR_F, r0, f1, f2); } void ejit_gtr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, GTR_D, r0, f1, f2); + emit_insn_orff(s, EJIT_OP_GTR_D, r0, f1, f2); } void ejit_ltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, GTR, r0, r2, r1); + emit_insn_orrr(s, EJIT_OP_GTR, r0, r2, r1); } void ejit_ltr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, GTR_U, r0, r2, r1); + emit_insn_orrr(s, EJIT_OP_GTR_U, r0, r2, r1); } void ejit_ltr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, GTR_F, r0, f2, f1); + emit_insn_orff(s, EJIT_OP_GTR_F, r0, f2, f1); } void ejit_ltr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, GTR_D, r0, f2, f1); + emit_insn_orff(s, EJIT_OP_GTR_D, r0, f2, f1); } void ejit_ger(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, GER, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_GER, r0, r1, r2); } void ejit_ger_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, GER_U, r0, r1, r2); + emit_insn_orrr(s, EJIT_OP_GER_U, r0, r1, r2); } void ejit_ger_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, GER_F, r0, f1, f2); + emit_insn_orff(s, EJIT_OP_GER_F, r0, f1, f2); } void ejit_ger_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, GER_D, r0, f1, f2); + emit_insn_orff(s, EJIT_OP_GER_D, r0, f1, f2); } void ejit_ler(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, GER, r0, r2, r1); + emit_insn_orrr(s, EJIT_OP_GER, r0, r2, r1); } void ejit_ler_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_orrr(s, GER_U, r0, r2, r1); + emit_insn_orrr(s, EJIT_OP_GER_U, r0, r2, r1); } void ejit_ler_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, GER_F, r0, f2, f1); + emit_insn_orff(s, EJIT_OP_GER_F, r0, f2, f1); } void ejit_ler_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1, struct ejit_fpr f2) { - emit_insn_orff(s, GER_D, r0, f2, f1); + emit_insn_orff(s, EJIT_OP_GER_D, r0, f2, f1); } void ejit_truncr_d_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1) { - emit_insn_orf(s, TRUNCR_D_32, r0, f1); + emit_insn_orf(s, EJIT_OP_TRUNCR_D_32, r0, f1); } void ejit_truncr_d_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1) { s->use_64 = true; - emit_insn_orf(s, TRUNCR_D_64, r0, f1); + emit_insn_orf(s, EJIT_OP_TRUNCR_D_64, r0, f1); } void ejit_truncr_f_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1) { - emit_insn_orf(s, TRUNCR_F_32, r0, f1); + emit_insn_orf(s, EJIT_OP_TRUNCR_F_32, r0, f1); } void ejit_truncr_f_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1) { s->use_64 = true; - emit_insn_orf(s, TRUNCR_F_64, r0, f1); + emit_insn_orf(s, EJIT_OP_TRUNCR_F_64, r0, f1); +} + +void ejit_sqrtr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) +{ + emit_insn_off(s, EJIT_OP_SQRTR_F, r0, r1); +} + +void ejit_sqrtr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) +{ + emit_insn_off(s, EJIT_OP_SQRTR_D, r0, r1); +} + +void ejit_minr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ + emit_insn_offf(s, EJIT_OP_MINR_F, r0, r1, r2); +} + +void ejit_minr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ + emit_insn_offf(s, EJIT_OP_MINR_D, r0, r1, r2); +} + +void ejit_maxr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ + emit_insn_offf(s, EJIT_OP_MAXR_F, r0, r1, r2); +} + +void ejit_maxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ + emit_insn_offf(s, EJIT_OP_MAXR_D, r0, r1, r2); } struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BNER, r0, r1); + emit_insn_oxrr(s, EJIT_OP_BNER, r0, r1); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BNEI, r0, o); + emit_insn_oxri(s, EJIT_OP_BNEI, r0, o); return (struct ejit_reloc){.insn = addr}; } @@ -1372,7 +1502,7 @@ struct ejit_reloc ejit_bner_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BNER_F, f0, f1); + emit_insn_oxff(s, EJIT_OP_BNER_F, f0, f1); return (struct ejit_reloc){.insn = addr}; } @@ -1380,7 +1510,7 @@ struct ejit_reloc ejit_bner_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BNER_D, f0, f1); + emit_insn_oxff(s, EJIT_OP_BNER_D, f0, f1); return (struct ejit_reloc){.insn = addr}; } @@ -1388,14 +1518,14 @@ struct ejit_reloc ejit_beqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BEQR, r0, r1); + emit_insn_oxrr(s, EJIT_OP_BEQR, r0, r1); 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 = insns_len(&s->insns); - emit_insn_oxri(s, BEQI, r0, o); + emit_insn_oxri(s, EJIT_OP_BEQI, r0, o); return (struct ejit_reloc){.insn = addr}; } @@ -1403,7 +1533,7 @@ struct ejit_reloc ejit_beqr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BEQR_F, f0, f1); + emit_insn_oxff(s, EJIT_OP_BEQR_F, f0, f1); return (struct ejit_reloc){.insn = addr}; } @@ -1411,7 +1541,7 @@ struct ejit_reloc ejit_beqr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BEQR_D, f0, f1); + emit_insn_oxff(s, EJIT_OP_BEQR_D, f0, f1); return (struct ejit_reloc){.insn = addr}; } @@ -1419,7 +1549,7 @@ struct ejit_reloc ejit_bger(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BGER, r0, r1); + emit_insn_oxrr(s, EJIT_OP_BGER, r0, r1); return (struct ejit_reloc){.insn = addr}; } @@ -1427,7 +1557,7 @@ struct ejit_reloc ejit_bger_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BGER_U, r0, r1); + emit_insn_oxrr(s, EJIT_OP_BGER_U, r0, r1); return (struct ejit_reloc){.insn = addr}; } @@ -1435,7 +1565,7 @@ struct ejit_reloc ejit_bger_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BGER_F, f0, f1); + emit_insn_oxff(s, EJIT_OP_BGER_F, f0, f1); return (struct ejit_reloc){.insn = addr}; } @@ -1443,14 +1573,14 @@ struct ejit_reloc ejit_bger_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BGER_D, f0, f1); + emit_insn_oxff(s, EJIT_OP_BGER_D, f0, f1); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_bgei(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BGEI, r0, o); + emit_insn_oxri(s, EJIT_OP_BGEI, r0, o); return (struct ejit_reloc){.insn = addr}; } @@ -1458,7 +1588,7 @@ struct ejit_reloc ejit_bgei_u(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BGEI_U, r0, o); + emit_insn_oxri(s, EJIT_OP_BGEI_U, r0, o); return (struct ejit_reloc){.insn = addr}; } @@ -1466,7 +1596,7 @@ struct ejit_reloc ejit_bler(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BGER, r1, r0); + emit_insn_oxrr(s, EJIT_OP_BGER, r1, r0); return (struct ejit_reloc){.insn = addr}; } @@ -1474,7 +1604,7 @@ struct ejit_reloc ejit_bler_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BGER_U, r1, r0); + emit_insn_oxrr(s, EJIT_OP_BGER_U, r1, r0); return (struct ejit_reloc){.insn = addr}; } @@ -1482,7 +1612,7 @@ struct ejit_reloc ejit_bler_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BGER_F, f1, f0); + emit_insn_oxff(s, EJIT_OP_BGER_F, f1, f0); return (struct ejit_reloc){.insn = addr}; } @@ -1490,14 +1620,14 @@ struct ejit_reloc ejit_bler_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BGER_D, f1, f0); + emit_insn_oxff(s, EJIT_OP_BGER_D, f1, f0); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_blei(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BLEI, r0, o); + emit_insn_oxri(s, EJIT_OP_BLEI, r0, o); return (struct ejit_reloc){.insn = addr}; } @@ -1505,14 +1635,14 @@ struct ejit_reloc ejit_blei_u(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BLEI_U, r0, o); + emit_insn_oxri(s, EJIT_OP_BLEI_U, r0, o); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_bgti(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BGTI, r0, o); + emit_insn_oxri(s, EJIT_OP_BGTI, r0, o); return (struct ejit_reloc){.insn = addr}; } @@ -1520,7 +1650,7 @@ struct ejit_reloc ejit_bgti_u(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BGTI_U, r0, o); + emit_insn_oxri(s, EJIT_OP_BGTI_U, r0, o); return (struct ejit_reloc){.insn = addr}; } @@ -1528,7 +1658,7 @@ struct ejit_reloc ejit_bgtr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BGTR, r0, r1); + emit_insn_oxrr(s, EJIT_OP_BGTR, r0, r1); return (struct ejit_reloc){.insn = addr}; } @@ -1536,7 +1666,7 @@ struct ejit_reloc ejit_bgtr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BGTR_U, r0, r1); + emit_insn_oxrr(s, EJIT_OP_BGTR_U, r0, r1); return (struct ejit_reloc){.insn = addr}; } @@ -1544,7 +1674,7 @@ struct ejit_reloc ejit_bgtr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BGTR_F, f0, f1); + emit_insn_oxff(s, EJIT_OP_BGTR_F, f0, f1); return (struct ejit_reloc){.insn = addr}; } @@ -1552,7 +1682,7 @@ struct ejit_reloc ejit_bgtr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BGTR_D, f0, f1); + emit_insn_oxff(s, EJIT_OP_BGTR_D, f0, f1); return (struct ejit_reloc){.insn = addr}; } @@ -1560,7 +1690,7 @@ struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BGTR, r1, r0); + emit_insn_oxrr(s, EJIT_OP_BGTR, r1, r0); return (struct ejit_reloc){.insn = addr}; } @@ -1568,7 +1698,7 @@ struct ejit_reloc ejit_bltr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BGTR_U, r1, r0); + emit_insn_oxrr(s, EJIT_OP_BGTR_U, r1, r0); return (struct ejit_reloc){.insn = addr}; } @@ -1576,7 +1706,7 @@ struct ejit_reloc ejit_bltr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BGTR_F, f1, f0); + emit_insn_oxff(s, EJIT_OP_BGTR_F, f1, f0); return (struct ejit_reloc){.insn = addr}; } @@ -1584,14 +1714,14 @@ struct ejit_reloc ejit_bltr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1) { size_t addr = insns_len(&s->insns); - emit_insn_oxff(s, BGTR_D, f1, f0); + emit_insn_oxff(s, EJIT_OP_BGTR_D, f1, f0); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_blti(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BLTI, r0, o); + emit_insn_oxri(s, EJIT_OP_BLTI, r0, o); return (struct ejit_reloc){.insn = addr}; } @@ -1599,28 +1729,28 @@ struct ejit_reloc ejit_blti_u(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BLTI_U, r0, o); + emit_insn_oxri(s, EJIT_OP_BLTI_U, r0, o); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_jmp(struct ejit_func *s) { size_t addr = insns_len(&s->insns); - emit_insn_o(s, JMP); + emit_insn_o(s, EJIT_OP_JMP); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_jmpr(struct ejit_func *s, struct ejit_gpr r0) { size_t addr = insns_len(&s->insns); - emit_insn_oxr(s, JMPR, r0); + emit_insn_oxr(s, EJIT_OP_JMPR, r0); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_bmci(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BMCI, r0, o); + emit_insn_oxri(s, EJIT_OP_BMCI, r0, o); return (struct ejit_reloc){.insn = addr}; } @@ -1628,14 +1758,14 @@ struct ejit_reloc ejit_bmcr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BMCR, r0, r1); + emit_insn_oxrr(s, EJIT_OP_BMCR, r0, r1); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_bmsi(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = insns_len(&s->insns); - emit_insn_oxri(s, BMSI, r0, o); + emit_insn_oxri(s, EJIT_OP_BMSI, r0, o); return (struct ejit_reloc){.insn = addr}; } @@ -1643,27 +1773,12 @@ struct ejit_reloc ejit_bmsr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { size_t addr = insns_len(&s->insns); - emit_insn_oxrr(s, BMSR, r0, r1); + emit_insn_oxrr(s, EJIT_OP_BMSR, r0, r1); return (struct ejit_reloc){.insn = addr}; } -static struct interp_state create_interp_state() -{ - struct interp_state state; - state.gprs = gprs_create(); - state.fprs = fprs_create(); - state.args = args_create(); - return state; -} - -static void destroy_interp_state(struct interp_state state) -{ - gprs_destroy(&state.gprs); - fprs_destroy(&state.fprs); - args_destroy(&state.args); -} - -long ejit_run_func_ctx_i(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *ctx) +long ejit_run_func_i(struct ejit_func *f, size_t argc, + struct ejit_arg args[argc]) { check_args(f, argc, args); assert((f->rtype == EJIT_VOID || ejit_int_type(f->rtype)) @@ -1672,64 +1787,29 @@ long ejit_run_func_ctx_i(struct ejit_func *f, size_t argc, struct ejit_arg args[ #endif ); - return ejit_run(f, argc, args, ctx, true, NULL).i; + return ejit_run(f, argc, args, NULL).i; } -long ejit_run_func_i(struct ejit_func *f, size_t argc, +int64_t ejit_run_func_l(struct ejit_func *f, size_t argc, struct ejit_arg args[argc]) { - struct interp_state state = create_interp_state(); - long r = ejit_run_func_ctx_i(f, argc, args, &state); - destroy_interp_state(state); - return r; -} - -int64_t ejit_run_func_ctx_l(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *ctx) -{ check_args(f, argc, args); assert(f->rtype == EJIT_INT64 || f->rtype == EJIT_UINT64); - return ejit_run(f, argc, args, ctx, true, NULL).i; -} - -int64_t ejit_run_func_l(struct ejit_func *f, size_t argc, - struct ejit_arg args[argc]) -{ - struct interp_state state = create_interp_state(); - int64_t r = ejit_run_func_ctx_l(f, argc, args, &state); - destroy_interp_state(state); - return r; + return ejit_run(f, argc, args, NULL).i; } -float ejit_run_func_ctx_f(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *ctx) +float ejit_run_func_f(struct ejit_func *f, size_t argc, struct ejit_arg args[argc]) { check_args(f, argc, args); assert(f->rtype == EJIT_FLOAT); - return ejit_run(f, argc, args, ctx, true, NULL).f; + return ejit_run(f, argc, args, NULL).f; } -float ejit_run_func_f(struct ejit_func *f, size_t argc, - struct ejit_arg args[argc]) -{ - struct interp_state state = create_interp_state(); - float r = ejit_run_func_ctx_f(f, argc, args, &state); - destroy_interp_state(state); - return r; -} - -double ejit_run_func_ctx_d(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *ctx) +double ejit_run_func_d(struct ejit_func *f, size_t argc, struct ejit_arg args[argc]) { check_args(f, argc, args); assert(f->rtype == EJIT_DOUBLE); - return ejit_run(f, argc, args, ctx, true, NULL).f; -} - -double ejit_run_func_d(struct ejit_func *f, size_t argc, - struct ejit_arg args[argc]) -{ - struct interp_state state = create_interp_state(); - double r = ejit_run_func_ctx_d(f, argc, args, &state); - destroy_interp_state(state); - return r; + return ejit_run(f, argc, args, NULL).f; } struct ejit_arg ejit_run_func(struct ejit_func *f, size_t argc, struct ejit_arg args[argc]) @@ -1748,6 +1828,10 @@ struct ejit_arg ejit_run_func(struct ejit_func *f, size_t argc, struct ejit_arg }; case EJIT_UINT64: + return (struct ejit_arg){ + .u64 = ejit_run_func_l(f, argc, args), + .type = f->rtype + }; case EJIT_INT64: return (struct ejit_arg){ .i64 = ejit_run_func_l(f, argc, args), @@ -1756,7 +1840,7 @@ struct ejit_arg ejit_run_func(struct ejit_func *f, size_t argc, struct ejit_arg default: return (struct ejit_arg){ - .i64 = ejit_run_func_i(f, argc, args), + .l = ejit_run_func_i(f, argc, args), .type = f->rtype }; } |