aboutsummaryrefslogtreecommitdiff
path: root/src/ejit.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-10-22 17:40:09 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-10-22 17:43:44 +0300
commit7f7b22674ed8e9633cd0e47662508c3641e9f967 (patch)
tree6e692c9ec8f6cb0672f626d5be54601ec23aef63 /src/ejit.c
parent60a53db87421667a268f60b58c5a02eebb289d6b (diff)
downloadejit-7f7b22674ed8e9633cd0e47662508c3641e9f967.tar.gz
ejit-7f7b22674ed8e9633cd0e47662508c3641e9f967.zip
use type-specific vectors instead of generic ones
+ An attempt at speeding up function calls in the interpreted mode
Diffstat (limited to 'src/ejit.c')
-rw-r--r--src/ejit.c127
1 files changed, 69 insertions, 58 deletions
diff --git a/src/ejit.c b/src/ejit.c
index 74c0ced..86329de 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -9,35 +9,35 @@ static void emit_insn_i(struct ejit_func *f, enum ejit_opcode op, size_t r0,
size_t r1, int64_t o)
{
struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .o = o};
- vec_append(&f->insns, &i);
+ insns_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)
{
struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .r2 = r2};
- vec_append(&f->insns, &i);
+ insns_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)
{
struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .p = p};
- vec_append(&f->insns, &i);
+ insns_append(&f->insns, i);
}
static void emit_insn_f(struct ejit_func *f, enum ejit_opcode op, size_t r0,
size_t r1, float d)
{
struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .f = d};
- vec_append(&f->insns, &i);
+ insns_append(&f->insns, i);
}
static void emit_insn_d(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);
+ insns_append(&f->insns, i);
}
struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc,
@@ -48,8 +48,8 @@ struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc,
f->rtype = rtype;
- f->insns = vec_create(sizeof(struct ejit_insn));
- f->labels = vec_create(sizeof(size_t));
+ f->insns = insns_create();
+ f->labels = labels_create();
f->arena = NULL;
f->size = 0;
@@ -98,11 +98,11 @@ void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr,
/* just get labels, don't actually run anything yet */
ejit_interp(f, 0, NULL, NULL, false, &labels);
foreach_vec(ii, f->insns) {
- struct ejit_insn i = vect_at(struct ejit_insn, f->insns, ii);
+ struct ejit_insn i = *insns_at(&f->insns, ii);
void *addr = labels[i.op];
assert(addr);
i.addr = addr;
- vect_at(struct ejit_insn, f->insns, ii) = i;
+ *insns_at(&f->insns, ii) = i;
}
/* doesn't really matter what we put here as long as it isn't 0 */
@@ -114,24 +114,24 @@ void ejit_destroy_func(struct ejit_func *f)
if (f->arena)
munmap(f->arena, f->size);
- vec_destroy(&f->insns);
- vec_destroy(&f->labels);
+ insns_destroy(&f->insns);
+ labels_destroy(&f->labels);
free(f);
}
struct ejit_label ejit_label(struct ejit_func *f)
{
- size_t addr = vec_len(&f->insns);
- vec_append(&f->labels, &addr);
+ size_t addr = insns_len(&f->insns);
+ labels_append(&f->labels, addr);
return (struct ejit_label){.addr = addr};
}
void ejit_patch(struct ejit_func *f, struct ejit_reloc r, struct ejit_label l)
{
- struct ejit_insn i = vect_at(struct ejit_insn, f->insns, r.insn);
+ struct ejit_insn i = *insns_at(&f->insns, r.insn);
/** @todo some assert that checks the opcode? */
i.r0 = l.addr;
- vect_at(struct ejit_insn, f->insns, r.insn) = i;
+ *insns_at(&f->insns, r.insn) = i;
}
void ejit_calli(struct ejit_func *s, struct ejit_func *f, size_t argc,
@@ -952,14 +952,14 @@ void ejit_truncr_f_64(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BNER, 0, r0.r, r1.r);
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 = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BNEI, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -967,7 +967,7 @@ struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
struct ejit_reloc ejit_bner_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BNER_F, 0, r0.f, r1.f);
return (struct ejit_reloc){.insn = addr};
}
@@ -975,7 +975,7 @@ struct ejit_reloc ejit_bner_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_reloc ejit_bner_d(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BNER_D, 0, r0.f, r1.f);
return (struct ejit_reloc){.insn = addr};
}
@@ -983,14 +983,14 @@ struct ejit_reloc ejit_bner_d(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_reloc ejit_beqr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BEQR, 0, r0.r, r1.r);
return (struct ejit_reloc){.insn = addr};
}
struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BEQI, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -998,7 +998,7 @@ struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
struct ejit_reloc ejit_beqr_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BEQR_F, 0, r0.f, r1.f);
return (struct ejit_reloc){.insn = addr};
}
@@ -1006,7 +1006,7 @@ struct ejit_reloc ejit_beqr_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_reloc ejit_beqr_d(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BEQR_D, 0, r0.f, r1.f);
return (struct ejit_reloc){.insn = addr};
}
@@ -1014,7 +1014,7 @@ struct ejit_reloc ejit_beqr_d(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_reloc ejit_bger(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGER, 0, r0.r, r1.r);
return (struct ejit_reloc){.insn = addr};
}
@@ -1022,7 +1022,7 @@ struct ejit_reloc ejit_bger(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bger_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGER_U, 0, r0.r, r1.r);
return (struct ejit_reloc){.insn = addr};
}
@@ -1030,14 +1030,14 @@ struct ejit_reloc ejit_bger_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bger_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGER_F, 0, r0.f, r1.f);
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 = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BGEI, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1045,7 +1045,7 @@ struct ejit_reloc ejit_bgei(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
struct ejit_reloc ejit_bgei_u(struct ejit_func *s, struct ejit_gpr r0,
int64_t o)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BGEI_U, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1053,7 +1053,7 @@ struct ejit_reloc ejit_bgei_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bler(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGER, 0, r1.r, r0.r);
return (struct ejit_reloc){.insn = addr};
}
@@ -1061,7 +1061,7 @@ struct ejit_reloc ejit_bler(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bler_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGER_U, 0, r1.r, r0.r);
return (struct ejit_reloc){.insn = addr};
}
@@ -1069,7 +1069,7 @@ struct ejit_reloc ejit_bler_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bler_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGER_F, 0, r1.f, r0.f);
return (struct ejit_reloc){.insn = addr};
}
@@ -1077,14 +1077,14 @@ struct ejit_reloc ejit_bler_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_reloc ejit_bler_d(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGER_D, 0, r1.f, r0.f);
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 = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BLEI, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1092,14 +1092,14 @@ struct ejit_reloc ejit_blei(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
struct ejit_reloc ejit_blei_u(struct ejit_func *s, struct ejit_gpr r0,
int64_t o)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BLEI_U, 0, r0.r, 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 = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BGTI, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1107,7 +1107,7 @@ struct ejit_reloc ejit_bgti(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
struct ejit_reloc ejit_bgti_u(struct ejit_func *s, struct ejit_gpr r0,
int64_t o)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BGTI_U, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1115,7 +1115,7 @@ struct ejit_reloc ejit_bgti_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bgtr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGTR, 0, r0.r, r1.r);
return (struct ejit_reloc){.insn = addr};
}
@@ -1123,7 +1123,7 @@ struct ejit_reloc ejit_bgtr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bgtr_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGTR_U, 0, r0.r, r1.r);
return (struct ejit_reloc){.insn = addr};
}
@@ -1131,7 +1131,7 @@ struct ejit_reloc ejit_bgtr_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bgtr_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGTR_F, 0, r0.f, r1.f);
return (struct ejit_reloc){.insn = addr};
}
@@ -1139,7 +1139,7 @@ struct ejit_reloc ejit_bgtr_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_reloc ejit_bgtr_d(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGTR_D, 0, r0.f, r1.f);
return (struct ejit_reloc){.insn = addr};
}
@@ -1147,7 +1147,7 @@ struct ejit_reloc ejit_bgtr_d(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGTR, 0, r1.r, r0.r);
return (struct ejit_reloc){.insn = addr};
}
@@ -1155,7 +1155,7 @@ struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bltr_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGTR_U, 0, r1.r, r0.r);
return (struct ejit_reloc){.insn = addr};
}
@@ -1163,7 +1163,7 @@ struct ejit_reloc ejit_bltr_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_reloc ejit_bltr_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGTR_F, 0, r1.f, r0.f);
return (struct ejit_reloc){.insn = addr};
}
@@ -1171,14 +1171,14 @@ struct ejit_reloc ejit_bltr_f(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_reloc ejit_bltr_d(struct ejit_func *s, struct ejit_fpr r0,
struct ejit_fpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_r(s, BGTR_D, 0, r1.f, r0.f);
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 = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BLTI, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1186,28 +1186,28 @@ struct ejit_reloc ejit_blti(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
struct ejit_reloc ejit_blti_u(struct ejit_func *s, struct ejit_gpr r0,
int64_t o)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BLTI_U, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
struct ejit_reloc ejit_jmp(struct ejit_func *s)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, JMP, 0, 0, 0);
return (struct ejit_reloc){.insn = addr};
}
struct ejit_reloc ejit_jmpr(struct ejit_func *s, struct ejit_gpr r0)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, JMPR, 0, r0.r, 0);
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 = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BMCI, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1215,14 +1215,14 @@ struct ejit_reloc ejit_bmci(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
struct ejit_reloc ejit_bmcr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BMCR, 0, r0.r, r1.r);
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 = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BMSI, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1230,7 +1230,7 @@ struct ejit_reloc ejit_bmsi(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
struct ejit_reloc ejit_bmsr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
- size_t addr = vec_len(&s->insns);
+ size_t addr = insns_len(&s->insns);
emit_insn_i(s, BMSR, 0, r0.r, r1.r);
return (struct ejit_reloc){.insn = addr};
}
@@ -1238,17 +1238,17 @@ struct ejit_reloc ejit_bmsr(struct ejit_func *s, struct ejit_gpr r0,
static struct interp_state create_interp_state()
{
struct interp_state state;
- state.gprs = vec_create(sizeof(int64_t));
- state.fprs = vec_create(sizeof(double));
- state.args = vec_create(sizeof(struct ejit_arg));
+ state.gprs = gprs_create();
+ state.fprs = fprs_create();
+ state.args = args_create();
return state;
}
static void destroy_interp_state(struct interp_state state)
{
- vec_destroy(&state.gprs);
- vec_destroy(&state.fprs);
- vec_destroy(&state.args);
+ gprs_destroy(&state.gprs);
+ fprs_destroy(&state.fprs);
+ args_destroy(&state.args);
}
long ejit_run_interp(struct ejit_func *f, size_t argc,
@@ -1262,6 +1262,17 @@ long ejit_run_interp(struct ejit_func *f, size_t argc,
return ejit_interp(f, argc, args, state, true, NULL).r;
}
+double ejit_run_interp_f(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));
+ if (f->arena)
+ return ((ejit_escape_f_t)f->arena)(argc, args);
+
+ return ejit_interp(f, argc, args, state, true, NULL).d;
+}
+
int64_t ejit_run_func(struct ejit_func *f, size_t argc,
struct ejit_arg args[argc])
{