diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-06-26 21:51:15 +0300 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-06-26 21:51:15 +0300 |
commit | 827dec28e4c0b1c4972f1419e0ac23e4dbd9d916 (patch) | |
tree | ac2c01e1b0b7acdf8ce06823e416a49e19257aa5 /src/ejit.c | |
parent | 3bf4d1ada6df5c74aac2a371d5f1e05fd55b4f02 (diff) | |
download | ejit-827dec28e4c0b1c4972f1419e0ac23e4dbd9d916.tar.gz ejit-827dec28e4c0b1c4972f1419e0ac23e4dbd9d916.zip |
enough functionality to implement posthaste
Diffstat (limited to 'src/ejit.c')
-rw-r--r-- | src/ejit.c | 104 |
1 files changed, 89 insertions, 15 deletions
@@ -42,8 +42,8 @@ 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_i(f, PARAM, args[i].r, 0, args[i].type); break; - case EJIT_OPERAND_FPR: emit_insn_i(f, PARAM_F, args[i].r, 0, args[i].type); 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(); } } @@ -54,6 +54,9 @@ struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc, const stru void ejit_compile_func(struct ejit_func *f, size_t gpr, size_t fpr) { + /* emit a final end instruction in case user didn't do a return */ + emit_insn_i(f, END, 0, 0, 0); + f->gpr = gpr; f->fpr = fpr; @@ -68,7 +71,9 @@ void ejit_compile_func(struct ejit_func *f, size_t gpr, size_t fpr) ejit_interp(f, 0, NULL, false, &labels); foreach_vec(ii, f->insns) { struct ejit_insn i = vect_at(struct ejit_insn, f->insns, ii); - i.addr = labels[i.op]; + void *addr = labels[i.op]; + assert(addr); + i.addr = addr; vect_at(struct ejit_insn, f->insns, ii) = i; } } @@ -101,10 +106,10 @@ void ejit_calli(struct ejit_func *s, struct ejit_func *f, size_t argc, const str { for (size_t i = 0; i < argc; ++i) { switch (args[i].kind) { - case EJIT_OPERAND_GPR: emit_insn_i(s, ARG, args[i].r, args[i].type, 0); break; - case EJIT_OPERAND_FPR: emit_insn_i(s, ARG_F, args[i].r, args[i].type, 0); break; - case EJIT_OPERAND_IMM: emit_insn_i(s, ARG_I, 0, args[i].type, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, 0, 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(); } } @@ -116,10 +121,10 @@ void ejit_escapei(struct ejit_func *s, ejit_escape_t f, size_t argc, const struc { for (size_t i = 0; i < argc; ++i) { switch (args[i].kind) { - case EJIT_OPERAND_GPR: emit_insn_i(s, ARG, args[i].r, 0, 0); break; - case EJIT_OPERAND_FPR: emit_insn_i(s, ARG_F, args[i].r, 0, 0); break; - case EJIT_OPERAND_IMM: emit_insn_i(s, ARG_I, 0, 0, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, 0, 0, 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(); } } @@ -131,10 +136,10 @@ void ejit_escapei_f(struct ejit_func *s, ejit_escape_f_t f, size_t argc, const s { for (size_t i = 0; i < argc; ++i) { switch (args[i].kind) { - case EJIT_OPERAND_GPR: emit_insn_i(s, ARG, args[i].r, 0, 0); break; - case EJIT_OPERAND_FPR: emit_insn_i(s, ARG_F, args[i].r, 0, 0); break; - case EJIT_OPERAND_IMM: emit_insn_i(s, ARG_I, 0, 0, args[i].r); break; - case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, 0, 0, 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(); } } @@ -142,6 +147,21 @@ void ejit_escapei_f(struct ejit_func *s, ejit_escape_f_t f, size_t argc, const s emit_insn_p(s, ESCAPEI_F, 0, 0, f); } +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) +{ + 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) +{ + emit_insn_i(s, LDXIU64, r0.r, r1.r, o); +} + void ejit_ret(struct ejit_func *s, struct ejit_gpr r0) { emit_insn_r(s, RET, r0.r, 0, 0); @@ -182,11 +202,44 @@ void ejit_subr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, st emit_insn_r(s, SUBR_F, r0.f, r1.f, r2.f); } +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) +{ + emit_insn_r(s, DIVR, r0.r, r1.r, r2.r); +} + +void ejit_negr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) +{ + emit_insn_i(s, NEGR, r0.r, r1.r, 0); +} + void ejit_movi(struct ejit_func *s, struct ejit_gpr r0, long o) { emit_insn_i(s, MOVI, r0.r, 0, o); } +void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) +{ + if (r0.r == r1.r) + return; + + 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) +{ + 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) +{ + 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) { size_t addr = vec_len(&s->insns); @@ -194,6 +247,27 @@ struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit return (struct ejit_reloc){.insn = addr}; } +struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, long o) +{ + size_t addr = vec_len(&s->insns); + emit_insn_i(s, BNEI, 0, r0.r, o); + return (struct ejit_reloc){.insn = addr}; +} + +struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, long o) +{ + size_t addr = vec_len(&s->insns); + emit_insn_i(s, BEQI, 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); + emit_insn_i(s, JMP, 0, 0, 0); + return (struct ejit_reloc){.insn = addr}; +} + long ejit_run_func(struct ejit_func *f, size_t argc, struct ejit_arg args[argc]) { assert(f->gpr && "trying to run a function that hasn't been compiled"); |