aboutsummaryrefslogtreecommitdiff
path: root/src/ejit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ejit.c')
-rw-r--r--src/ejit.c142
1 files changed, 97 insertions, 45 deletions
diff --git a/src/ejit.c b/src/ejit.c
index 0701b90..e8ff99e 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -545,10 +545,22 @@ void ejit_calli(struct ejit_func *s, struct ejit_func *f, size_t argc,
for (size_t i = 0; i < argc; ++i) {
switch (args[i].kind) {
- 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;
+ 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();
}
}
@@ -556,73 +568,113 @@ void ejit_calli(struct ejit_func *s, struct ejit_func *f, size_t argc,
emit_insn_op(s, EJIT_OP_CALLI, f);
}
-void ejit_escapei_i(struct ejit_func *s, ejit_escape_i_t 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])
{
+ 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, 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;
+ 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, EJIT_OP_ESCAPEI_I, f);
+ emit_insn_oxr(s, op, target);
}
-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_i(struct ejit_func *s, struct ejit_gpr target,
+ size_t argc, const struct ejit_operand args[argc])
{
- s->use_64 = true;
- 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, 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();
- }
- }
+ ejit_callr(s, EJIT_OP_CALLR_I, target, argc, args);
+}
+
+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);
+}
- emit_insn_op(s, EJIT_OP_ESCAPEI_L, f);
+void ejit_callr_f(struct ejit_func *s, struct ejit_gpr target,
+ size_t argc, const struct ejit_operand args[argc])
+{
+ ejit_callr(s, EJIT_OP_CALLR_F, 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])
+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);
+}
+
+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, 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;
+ 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, EJIT_OP_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])
{
- 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, 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();
- }
- }
+ 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, EJIT_OP_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)