aboutsummaryrefslogtreecommitdiff
path: root/src/interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interp.c')
-rw-r--r--src/interp.c657
1 files changed, 333 insertions, 324 deletions
diff --git a/src/interp.c b/src/interp.c
index f8ba927..894be30 100644
--- a/src/interp.c
+++ b/src/interp.c
@@ -5,262 +5,270 @@
/* this is the body of a given ejit_interp function, it assumes there's an
* external int64_t retval and double retval_f into which it places the value to
* be returned. Included from src/interp.c */
-union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *state, bool run, void ***labels_wb)
+union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg params[paramc], void ***labels_wb)
{
- static void *labels[OPCODE_COUNT] = {
- [MOVI] = &&MOVI,
- [MOVI_F] = &&MOVI_F,
- [MOVI_D] = &&MOVI_D,
- [MOVR] = &&MOVR,
- [MOVR_F] = &&MOVR_F,
- [MOVR_D] = &&MOVR_D,
-
- [EXTR8] = &&EXTR8,
- [EXTR16] = &&EXTR16,
- [EXTR32] = &&EXTR32,
- [EXTRU8] = &&EXTRU8,
- [EXTRU16] = &&EXTRU16,
- [EXTRU32] = &&EXTRU32,
- [EXTRF] = &&EXTRF,
- [EXTRD] = &&EXTRD,
-
- [ADDR] = &&ADDR,
- [ADDR_F] = &&ADDR_F,
- [ADDR_D] = &&ADDR_D,
- [ADDI] = &&ADDI,
-
- [ABSR_F] = &&ABSR_F,
- [ABSR_D] = &&ABSR_D,
-
- [SUBR] = &&SUBR,
- [SUBR_F] = &&SUBR_F,
- [SUBR_D] = &&SUBR_D,
- [SUBI] = &&SUBI,
-
- [MULR] = &&MULR,
- [MULR_F] = &&MULR_F,
- [MULR_D] = &&MULR_D,
-
- [DIVR] = &&DIVR,
- [DIVR_U] = &&DIVR_U,
- [DIVR_F] = &&DIVR_F,
- [DIVR_D] = &&DIVR_D,
-
- [REMR] = &&REMR,
- [REMR_U] = &&REMR_U,
-
- [LSHI] = &&LSHI,
- [LSHR] = &&LSHR,
- [RSHI] = &&RSHI,
- [RSHR] = &&RSHR,
- [RSHI_U] = &&RSHI_U,
- [RSHR_U] = &&RSHR_U,
-
- [ANDR] = &&ANDR,
- [ANDI] = &&ANDI,
-
- [ORR] = &&ORR,
- [ORI] = &&ORI,
-
- [XORR] = &&XORR,
- [XORI] = &&XORI,
-
- [COMR] = &&COMR,
- [NEGR] = &&NEGR,
- [NEGR_F] = &&NEGR_F,
- [NEGR_D] = &&NEGR_D,
-
- [EQR] = &&EQR,
- [EQR_F] = &&EQR_F,
- [EQR_D] = &&EQR_D,
-
- [NER] = &&NER,
- [NER_F] = &&NER_F,
- [NER_D] = &&NER_D,
-
- [GTR] = &&GTR,
- [GTR_U] = &&GTR_U,
- [GTR_F] = &&GTR_F,
- [GTR_D] = &&GTR_D,
-
- [GER] = &&GER,
- [GER_U] = &&GER_U,
- [GER_F] = &&GER_F,
- [GER_D] = &&GER_D,
-
- [STI8] = &&STI8,
- [STI16] = &&STI16,
- [STI32] = &&STI32,
- [STI64] = &&STI64,
- [STIF] = &&STIF,
- [STID] = &&STID,
-
- [STXI8] = &&STXI8,
- [STXI16] = &&STXI16,
- [STXI32] = &&STXI32,
- [STXI64] = &&STXI64,
- [STXIF] = &&STXIF,
- [STXID] = &&STXID,
-
- [STXR8] = &&STXR8,
- [STXR16] = &&STXR16,
- [STXR32] = &&STXR32,
- [STXR64] = &&STXR64,
- [STXRF] = &&STXRF,
- [STXRD] = &&STXRD,
-
- [LDI8] = &&LDI8,
- [LDI16] = &&LDI16,
- [LDI32] = &&LDI32,
- [LDI64] = &&LDI64,
- [LDIU8] = &&LDIU8,
- [LDIU16] = &&LDIU16,
- [LDIU32] = &&LDIU32,
- [LDIU64] = &&LDIU64,
- [LDIF] = &&LDIF,
- [LDID] = &&LDID,
-
- [LDXI8] = &&LDXI8,
- [LDXI16] = &&LDXI16,
- [LDXI32] = &&LDXI32,
- [LDXI64] = &&LDXI64,
- [LDXIU8] = &&LDXIU8,
- [LDXIU16] = &&LDXIU16,
- [LDXIU32] = &&LDXIU32,
- [LDXIU64] = &&LDXIU64,
- [LDXIF] = &&LDXIF,
- [LDXID] = &&LDXID,
-
- [LDXR8] = &&LDXR8,
- [LDXR16] = &&LDXR16,
- [LDXR32] = &&LDXR32,
- [LDXR64] = &&LDXR64,
- [LDXRU8] = &&LDXRU8,
- [LDXRU16] = &&LDXRU16,
- [LDXRU32] = &&LDXRU32,
- [LDXRU64] = &&LDXRU64,
- [LDXRF] = &&LDXRF,
- [LDXRD] = &&LDXRD,
-
- [TRUNCR_D_32] = &&TRUNCR_D_32,
- [TRUNCR_D_64] = &&TRUNCR_D_64,
- [TRUNCR_F_32] = &&TRUNCR_F_32,
- [TRUNCR_F_64] = &&TRUNCR_F_64,
-
- [BNER] = &&BNER,
- [BNEI] = &&BNEI,
- [BNER_F] = &&BNER_F,
- [BNER_D] = &&BNER_D,
-
- [BEQR] = &&BEQR,
- [BEQI] = &&BEQI,
- [BEQR_F] = &&BEQR_F,
- [BEQR_D] = &&BEQR_D,
-
- [BGER] = &&BGER,
- [BGER_U] = &&BGER_U,
- [BGEI] = &&BGEI,
- [BGEI_U] = &&BGEI_U,
- [BGER_F] = &&BGER_F,
- [BGER_D] = &&BGER_D,
-
- [BLEI] = &&BLEI,
- [BLEI_U] = &&BLEI_U,
-
- [BGTR] = &&BGTR,
- [BGTR_U] = &&BGTR_U,
- [BGTI] = &&BGTI,
- [BGTI_U] = &&BGTI_U,
- [BGTR_F] = &&BGTR_F,
- [BGTR_D] = &&BGTR_D,
-
- [BLTI] = &&BLTI,
- [BLTI_U] = &&BLTI_U,
-
- [JMP] = &&JMP,
- [JMPR] = &&JMPR,
-
- [BMCI] = &&BMCI,
- [BMCR] = &&BMCR,
- [BMSI] = &&BMSI,
- [BMSR] = &&BMSR,
-
- [RETR] = &&RETR,
- [RETI] = &&RETI,
- [RETR_F] = &&RETR_F,
- [RETI_F] = &&RETI_F,
- [RETR_D] = &&RETR_D,
- [RETI_D] = &&RETI_D,
-
- [RETVAL] = &&RETVAL,
- [RETVAL_F] = &&RETVAL_F,
- [RETVAL_D] = &&RETVAL_D,
-
- [ARG] = &&ARG,
- [ARG_I] = &&ARG_I,
- [ARG_F] = &&ARG_F,
- [ARG_FI] = &&ARG_FI,
-
- [PARAM] = &&PARAM,
- [PARAM_F] = &&PARAM_F,
-
- [CALLI_I] = &&CALLI_I,
- [CALLI_L] = &&CALLI_L,
- [CALLI_F] = &&CALLI_F,
- [CALLI_D] = &&CALLI_D,
- [ESCAPEI_I] = &&ESCAPEI_I,
- [ESCAPEI_F] = &&ESCAPEI_F,
- [ESCAPEI_L] = &&ESCAPEI_L,
- [ESCAPEI_D] = &&ESCAPEI_D,
-
- [START] = &&START,
- [END] = &&END,
+ static void *labels[EJIT_OPCODE_COUNT] = {
+ [EJIT_OP_MOVI] = &&MOVI,
+ [EJIT_OP_MOVI_F] = &&MOVI_F,
+ [EJIT_OP_MOVI_D] = &&MOVI_D,
+ [EJIT_OP_MOVR] = &&MOVR,
+ [EJIT_OP_MOVR_F] = &&MOVR_F,
+ [EJIT_OP_MOVR_D] = &&MOVR_D,
+
+ [EJIT_OP_EXTR8] = &&EXTR8,
+ [EJIT_OP_EXTR16] = &&EXTR16,
+ [EJIT_OP_EXTR32] = &&EXTR32,
+ [EJIT_OP_EXTRU8] = &&EXTRU8,
+ [EJIT_OP_EXTRU16] = &&EXTRU16,
+ [EJIT_OP_EXTRU32] = &&EXTRU32,
+ [EJIT_OP_EXTRF] = &&EXTRF,
+ [EJIT_OP_EXTRD] = &&EXTRD,
+
+ [EJIT_OP_ADDR] = &&ADDR,
+ [EJIT_OP_ADDR_F] = &&ADDR_F,
+ [EJIT_OP_ADDR_D] = &&ADDR_D,
+ [EJIT_OP_ADDI] = &&ADDI,
+
+ [EJIT_OP_ABSR_F] = &&ABSR_F,
+ [EJIT_OP_ABSR_D] = &&ABSR_D,
+
+ [EJIT_OP_SUBR] = &&SUBR,
+ [EJIT_OP_SUBR_F] = &&SUBR_F,
+ [EJIT_OP_SUBR_D] = &&SUBR_D,
+ [EJIT_OP_SUBI] = &&SUBI,
+
+ [EJIT_OP_MULR] = &&MULR,
+ [EJIT_OP_MULR_F] = &&MULR_F,
+ [EJIT_OP_MULR_D] = &&MULR_D,
+
+ [EJIT_OP_DIVR] = &&DIVR,
+ [EJIT_OP_DIVR_U] = &&DIVR_U,
+ [EJIT_OP_DIVR_F] = &&DIVR_F,
+ [EJIT_OP_DIVR_D] = &&DIVR_D,
+
+ [EJIT_OP_REMR] = &&REMR,
+ [EJIT_OP_REMR_U] = &&REMR_U,
+
+ [EJIT_OP_LSHI] = &&LSHI,
+ [EJIT_OP_LSHR] = &&LSHR,
+ [EJIT_OP_RSHI] = &&RSHI,
+ [EJIT_OP_RSHR] = &&RSHR,
+ [EJIT_OP_RSHI_U] = &&RSHI_U,
+ [EJIT_OP_RSHR_U] = &&RSHR_U,
+
+ [EJIT_OP_ANDR] = &&ANDR,
+ [EJIT_OP_ANDI] = &&ANDI,
+
+ [EJIT_OP_ORR] = &&ORR,
+ [EJIT_OP_ORI] = &&ORI,
+
+ [EJIT_OP_XORR] = &&XORR,
+ [EJIT_OP_XORI] = &&XORI,
+
+ [EJIT_OP_COMR] = &&COMR,
+ [EJIT_OP_NEGR] = &&NEGR,
+ [EJIT_OP_NEGR_F] = &&NEGR_F,
+ [EJIT_OP_NEGR_D] = &&NEGR_D,
+
+ [EJIT_OP_EQR] = &&EQR,
+ [EJIT_OP_EQR_F] = &&EQR_F,
+ [EJIT_OP_EQR_D] = &&EQR_D,
+
+ [EJIT_OP_NER] = &&NER,
+ [EJIT_OP_NER_F] = &&NER_F,
+ [EJIT_OP_NER_D] = &&NER_D,
+
+ [EJIT_OP_GTR] = &&GTR,
+ [EJIT_OP_GTR_U] = &&GTR_U,
+ [EJIT_OP_GTR_F] = &&GTR_F,
+ [EJIT_OP_GTR_D] = &&GTR_D,
+
+ [EJIT_OP_GER] = &&GER,
+ [EJIT_OP_GER_U] = &&GER_U,
+ [EJIT_OP_GER_F] = &&GER_F,
+ [EJIT_OP_GER_D] = &&GER_D,
+
+ [EJIT_OP_STI8] = &&STI8,
+ [EJIT_OP_STI16] = &&STI16,
+ [EJIT_OP_STI32] = &&STI32,
+ [EJIT_OP_STI64] = &&STI64,
+ [EJIT_OP_STIF] = &&STIF,
+ [EJIT_OP_STID] = &&STID,
+
+ [EJIT_OP_STXI8] = &&STXI8,
+ [EJIT_OP_STXI16] = &&STXI16,
+ [EJIT_OP_STXI32] = &&STXI32,
+ [EJIT_OP_STXI64] = &&STXI64,
+ [EJIT_OP_STXIF] = &&STXIF,
+ [EJIT_OP_STXID] = &&STXID,
+
+ [EJIT_OP_STXR8] = &&STXR8,
+ [EJIT_OP_STXR16] = &&STXR16,
+ [EJIT_OP_STXR32] = &&STXR32,
+ [EJIT_OP_STXR64] = &&STXR64,
+ [EJIT_OP_STXRF] = &&STXRF,
+ [EJIT_OP_STXRD] = &&STXRD,
+
+ [EJIT_OP_LDI8] = &&LDI8,
+ [EJIT_OP_LDI16] = &&LDI16,
+ [EJIT_OP_LDI32] = &&LDI32,
+ [EJIT_OP_LDI64] = &&LDI64,
+ [EJIT_OP_LDIU8] = &&LDIU8,
+ [EJIT_OP_LDIU16] = &&LDIU16,
+ [EJIT_OP_LDIU32] = &&LDIU32,
+ [EJIT_OP_LDIU64] = &&LDIU64,
+ [EJIT_OP_LDIF] = &&LDIF,
+ [EJIT_OP_LDID] = &&LDID,
+
+ [EJIT_OP_LDXI8] = &&LDXI8,
+ [EJIT_OP_LDXI16] = &&LDXI16,
+ [EJIT_OP_LDXI32] = &&LDXI32,
+ [EJIT_OP_LDXI64] = &&LDXI64,
+ [EJIT_OP_LDXIU8] = &&LDXIU8,
+ [EJIT_OP_LDXIU16] = &&LDXIU16,
+ [EJIT_OP_LDXIU32] = &&LDXIU32,
+ [EJIT_OP_LDXIU64] = &&LDXIU64,
+ [EJIT_OP_LDXIF] = &&LDXIF,
+ [EJIT_OP_LDXID] = &&LDXID,
+
+ [EJIT_OP_LDXR8] = &&LDXR8,
+ [EJIT_OP_LDXR16] = &&LDXR16,
+ [EJIT_OP_LDXR32] = &&LDXR32,
+ [EJIT_OP_LDXR64] = &&LDXR64,
+ [EJIT_OP_LDXRU8] = &&LDXRU8,
+ [EJIT_OP_LDXRU16] = &&LDXRU16,
+ [EJIT_OP_LDXRU32] = &&LDXRU32,
+ [EJIT_OP_LDXRU64] = &&LDXRU64,
+ [EJIT_OP_LDXRF] = &&LDXRF,
+ [EJIT_OP_LDXRD] = &&LDXRD,
+
+ [EJIT_OP_TRUNCR_D_32] = &&TRUNCR_D_32,
+ [EJIT_OP_TRUNCR_D_64] = &&TRUNCR_D_64,
+ [EJIT_OP_TRUNCR_F_32] = &&TRUNCR_F_32,
+ [EJIT_OP_TRUNCR_F_64] = &&TRUNCR_F_64,
+
+ [EJIT_OP_SQRTR_F] = &&SQRTR_F,
+ [EJIT_OP_SQRTR_D] = &&SQRTR_D,
+
+ [EJIT_OP_MINR_F] = &&MINR_F,
+ [EJIT_OP_MINR_D] = &&MINR_D,
+
+ [EJIT_OP_MAXR_F] = &&MAXR_F,
+ [EJIT_OP_MAXR_D] = &&MAXR_D,
+
+ [EJIT_OP_BNER] = &&BNER,
+ [EJIT_OP_BNEI] = &&BNEI,
+ [EJIT_OP_BNER_F] = &&BNER_F,
+ [EJIT_OP_BNER_D] = &&BNER_D,
+
+ [EJIT_OP_BEQR] = &&BEQR,
+ [EJIT_OP_BEQI] = &&BEQI,
+ [EJIT_OP_BEQR_F] = &&BEQR_F,
+ [EJIT_OP_BEQR_D] = &&BEQR_D,
+
+ [EJIT_OP_BGER] = &&BGER,
+ [EJIT_OP_BGER_U] = &&BGER_U,
+ [EJIT_OP_BGEI] = &&BGEI,
+ [EJIT_OP_BGEI_U] = &&BGEI_U,
+ [EJIT_OP_BGER_F] = &&BGER_F,
+ [EJIT_OP_BGER_D] = &&BGER_D,
+
+ [EJIT_OP_BLEI] = &&BLEI,
+ [EJIT_OP_BLEI_U] = &&BLEI_U,
+
+ [EJIT_OP_BGTR] = &&BGTR,
+ [EJIT_OP_BGTR_U] = &&BGTR_U,
+ [EJIT_OP_BGTI] = &&BGTI,
+ [EJIT_OP_BGTI_U] = &&BGTI_U,
+ [EJIT_OP_BGTR_F] = &&BGTR_F,
+ [EJIT_OP_BGTR_D] = &&BGTR_D,
+
+ [EJIT_OP_BLTI] = &&BLTI,
+ [EJIT_OP_BLTI_U] = &&BLTI_U,
+
+ [EJIT_OP_JMP] = &&JMP,
+ [EJIT_OP_JMPR] = &&JMPR,
+
+ [EJIT_OP_BMCI] = &&BMCI,
+ [EJIT_OP_BMCR] = &&BMCR,
+ [EJIT_OP_BMSI] = &&BMSI,
+ [EJIT_OP_BMSR] = &&BMSR,
+
+ [EJIT_OP_RETR] = &&RETR,
+ [EJIT_OP_RETI] = &&RETI,
+ [EJIT_OP_RETR_F] = &&RETR_F,
+ [EJIT_OP_RETI_F] = &&RETI_F,
+ [EJIT_OP_RETR_D] = &&RETR_D,
+ [EJIT_OP_RETI_D] = &&RETI_D,
+
+ [EJIT_OP_RETVAL] = &&RETVAL,
+ [EJIT_OP_RETVAL_F] = &&RETVAL_F,
+ [EJIT_OP_RETVAL_D] = &&RETVAL_D,
+
+ [EJIT_OP_ARG] = &&ARG,
+ [EJIT_OP_ARG_I] = &&ARG_I,
+ [EJIT_OP_ARG_F] = &&ARG_F,
+ [EJIT_OP_ARG_FI] = &&ARG_FI,
+
+ [EJIT_OP_PARAM] = &&PARAM,
+ [EJIT_OP_PARAM_F] = &&PARAM_F,
+
+ [EJIT_OP_CALLR_I] = &&CALLR_I,
+ [EJIT_OP_CALLR_L] = &&CALLR_L,
+ [EJIT_OP_CALLR_F] = &&CALLR_F,
+ [EJIT_OP_CALLR_D] = &&CALLR_D,
+ [EJIT_OP_CALLI] = &&CALLI,
+
+ [EJIT_OP_TAILR] = &&TAILR,
+ [EJIT_OP_TAILI] = &&TAILI,
+
+ [EJIT_OP_ESCAPEI_I] = &&ESCAPEI_I,
+ [EJIT_OP_ESCAPEI_L] = &&ESCAPEI_L,
+ [EJIT_OP_ESCAPEI_F] = &&ESCAPEI_F,
+ [EJIT_OP_ESCAPEI_D] = &&ESCAPEI_D,
+
+ [EJIT_OP_START] = &&START,
+ [EJIT_OP_END] = &&END,
};
- if (!run) {
+ if (labels_wb) {
*labels_wb = labels;
- goto zero_out;
+ return (union interp_ret){.i = 0};
}
assert(f->size && "trying to run a function that hasn't been compiled");
-
- if (f->arena) {
+ if (f->extern_call) {
if (f->rtype == EJIT_INT64 || f->rtype == EJIT_UINT64)
return (union interp_ret){
- .i = ((ejit_escape_l_t)f->arena)(argc, args)
+ .i = ((ejit_escape_l_t)f->extern_call)(paramc, params)
};
if (f->rtype == EJIT_DOUBLE)
return (union interp_ret){
- .f = ((ejit_escape_d_t)f->arena)(argc, args)
+ .f = ((ejit_escape_d_t)f->extern_call)(paramc, params)
};
if (f->rtype == EJIT_FLOAT)
return (union interp_ret){
- .f = ((ejit_escape_f_t)f->arena)(argc, args)
+ .f = ((ejit_escape_f_t)f->extern_call)(paramc, params)
};
return (union interp_ret){
- .i = ((ejit_escape_i_t)f->arena)(argc, args)
+ .i = ((ejit_escape_i_t)f->extern_call)(paramc, params)
};
}
- int64_t retval = 0; double retval_f = 0.0;
-
- size_t prev_gprs = gprs_len(&state->gprs);
- size_t prev_fprs = fprs_len(&state->fprs);
- size_t prev_argc = args_len(&state->args);
-
- gprs_reserve(&state->gprs, prev_gprs + gpr_stats_len(&f->gpr));
- fprs_reserve(&state->fprs, prev_fprs + fpr_stats_len(&f->fpr));
-
+top:
+ union interp_ret retval = {.i = 0};
union fpr {
double d;
float f;
};
- int64_t *gpr = ((int64_t *)state->gprs.buf) + prev_gprs;
- union fpr *fpr = ((union fpr *)state->fprs.buf) + prev_fprs;
+ size_t argc = 0;
+ int64_t gpr[gpr_stats_len(&f->gpr)];
+ union fpr fpr[fpr_stats_len(&f->fpr)];
+ struct ejit_arg args[f->max_args];
struct ejit_insn *insns = f->insns.buf;
/* retval is kind of an unfortunate extra bit of state to keep track of,
@@ -278,7 +286,7 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args
DISPATCH();
DO(END);
- goto zero_out;
+ return (union interp_ret){.i = 0};
DISPATCH();
DO(MOVI);
@@ -789,6 +797,30 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args
gpr[i.r0] = (int64_t)fpr[i.r1].f;
DISPATCH();
+ DO(SQRTR_F);
+ fpr[i.r0].f = sqrt(fpr[i.r1].f);
+ DISPATCH();
+
+ DO(MINR_F);
+ fpr[i.r0].f = fminf(fpr[i.r1].f, fpr[i.r2].f);
+ DISPATCH();
+
+ DO(MINR_D);
+ fpr[i.r0].d = fmin(fpr[i.r1].d, fpr[i.r2].d);
+ DISPATCH();
+
+ DO(MAXR_F);
+ fpr[i.r0].f = fmaxf(fpr[i.r1].f, fpr[i.r2].f);
+ DISPATCH();
+
+ DO(MAXR_D);
+ fpr[i.r0].d = fmax(fpr[i.r1].d, fpr[i.r2].d);
+ DISPATCH();
+
+ DO(SQRTR_D);
+ fpr[i.r0].d = sqrt(fpr[i.r1].d);
+ DISPATCH();
+
DO(BNER);
if (gpr[i.r1] != gpr[i.r2])
JUMP(i.r0);
@@ -966,37 +998,48 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args
DISPATCH();
DO(RETVAL);
- gpr[i.r0] = retval;
+ gpr[i.r0] = retval.i;
DISPATCH();
DO(RETVAL_F);
- fpr[i.r0].f = retval_f;
+ fpr[i.r0].f = retval.f;
DISPATCH();
DO(RETVAL_D);
- fpr[i.r0].d = retval_f;
+ fpr[i.r0].d = retval.f;
DISPATCH();
DO(PARAM);
- gpr[i.r2] = args[i.r0].u64;
+ switch (i.r1) {
+ case EJIT_INT8: gpr[i.r2] = params[i.r0].i8; break;
+ case EJIT_INT16: gpr[i.r2] = params[i.r0].i16; break;
+ case EJIT_INT32: gpr[i.r2] = params[i.r0].i32; break;
+ case EJIT_INT64: gpr[i.r2] = params[i.r0].i64; break;
+ case EJIT_UINT8: gpr[i.r2] = params[i.r0].u8; break;
+ case EJIT_UINT16: gpr[i.r2] = params[i.r0].u16; break;
+ case EJIT_UINT32: gpr[i.r2] = params[i.r0].u32; break;
+ case EJIT_UINT64: gpr[i.r2] = params[i.r0].u64; break;
+ case EJIT_POINTER: gpr[i.r2] = (int64_t)params[i.r0].p; break;
+ default: abort();
+ }
DISPATCH();
DO(PARAM_F);
if (i.r1 == EJIT_FLOAT)
- fpr[i.r2].f = args[i.r0].f;
+ fpr[i.r2].f = params[i.r0].f;
else
- fpr[i.r2].d = args[i.r0].d;
+ fpr[i.r2].d = params[i.r0].d;
DISPATCH();
DO(ARG);
struct ejit_arg a = ejit_build_arg(i.r1, gpr[i.r2]);
- args_append(&state->args, a);
+ args[argc++] = a;
DISPATCH();
DO(ARG_I);
struct ejit_arg a = ejit_build_arg(i.r1, i.o);
- args_append(&state->args, a);
+ args[argc++] = a;
DISPATCH();
DO(ARG_F);
@@ -1006,7 +1049,7 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args
else
a = ejit_build_arg_f(i.r1, fpr[i.r2].f);
- args_append(&state->args, a);
+ args[argc++] = a;
DISPATCH();
DO(ARG_FI);
@@ -1014,145 +1057,111 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args
if (i.r1 == EJIT_DOUBLE)
a = ejit_build_arg_f(i.r1, i.d);
else
- a = ejit_build_arg_f(i.r1, i.f);
+ a = ejit_build_arg_f(i.r1, i.d);
- args_append(&state->args, a);
+ args[argc++] = a;
DISPATCH();
- DO(CALLI_I);
- struct ejit_func *f = i.p;
- size_t argc = args_len(&state->args) - prev_argc;
- struct ejit_arg *args = state->args.buf + prev_argc;
+ DO(TAILI);
+ f = (struct ejit_func *)i.p;
+
+ assert(!f->direct_call && "trying to interpret compiled fun");
- retval = ejit_run(f, argc, args, state, true, NULL).i;
+ paramc = argc;
+ for (size_t i = 0; i < argc; ++i)
+ params[i] = args[i];
- gpr = state->gprs.buf + prev_gprs;
- fpr = (union fpr *)state->fprs.buf + prev_fprs;
- args_shrink(&state->args, prev_argc);
+ goto top;
DISPATCH();
- DO(CALLI_L);
- struct ejit_func *f = i.p;
- size_t argc = args_len(&state->args) - prev_argc;
- struct ejit_arg *args = state->args.buf + prev_argc;
+ DO(TAILR);
+ f = (struct ejit_func *)gpr[i.r1];
- retval = ejit_run(f, argc, args, state, true, NULL).i;
+ /** @todo we could potentially just interpret the func as a fallback
+ * instead of aborting here, but this is good enough for now */
+ assert(!f->direct_call && "trying to interpret compiled fun");
- gpr = state->gprs.buf + prev_gprs;
- fpr = (union fpr *)state->fprs.buf + prev_fprs;
- args_shrink(&state->args, prev_argc);
- DISPATCH();
+ paramc = argc;
+ for (size_t i = 0; i < argc; ++i)
+ params[i] = args[i];
- DO(CALLI_F);
- struct ejit_func *f = i.p;
- size_t argc = args_len(&state->args) - prev_argc;
- struct ejit_arg *args = state->args.buf + prev_argc;
+ goto top;
+ DISPATCH();
- retval_f = ejit_run(f, argc, args, state, true, NULL).f;
+ DO(CALLR_I);
+ retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL);
+ argc = 0;
+ DISPATCH();
- gpr = state->gprs.buf + prev_gprs;
- fpr = (union fpr *)state->fprs.buf + prev_fprs;
- args_shrink(&state->args, prev_argc);
+ DO(CALLR_L);
+ retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL);
+ argc = 0;
DISPATCH();
- DO(CALLI_D);
- struct ejit_func *f = i.p;
- size_t argc = args_len(&state->args) - prev_argc;
- struct ejit_arg *args = state->args.buf + prev_argc;
+ DO(CALLR_F);
+ retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL);
+ argc = 0;
+ DISPATCH();
- retval_f = ejit_run(f, argc, args, state, true, NULL).f;
+ DO(CALLR_D);
+ retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL);
+ argc = 0;
+ DISPATCH();
- gpr = state->gprs.buf + prev_gprs;
- fpr = (union fpr *)state->fprs.buf + prev_fprs;
- args_shrink(&state->args, prev_argc);
+ DO(CALLI);
+ retval = ejit_run((struct ejit_func *)i.p, argc, args, NULL);
+ argc = 0;
DISPATCH();
DO(ESCAPEI_I);
- ejit_escape_i_t f = i.p;
- size_t argc = args_len(&state->args) - prev_argc;
- struct ejit_arg *args = state->args.buf + prev_argc;
-
- retval = f(argc, args);
-
- args_shrink(&state->args, prev_argc);
+ retval.i = ((ejit_escape_i_t)i.p)(argc, args);
+ argc = 0;
DISPATCH();
DO(ESCAPEI_L);
- ejit_escape_l_t f = i.p;
- size_t argc = args_len(&state->args) - prev_argc;
- struct ejit_arg *args = state->args.buf + prev_argc;
-
- retval = f(argc, args);
-
- args_shrink(&state->args, prev_argc);
+ retval.i = ((ejit_escape_l_t)i.p)(argc, args);
+ argc = 0;
DISPATCH();
DO(ESCAPEI_F);
- ejit_escape_f_t f = i.p;
- size_t argc = args_len(&state->args) - prev_argc;
- struct ejit_arg *args = state->args.buf + prev_argc;
-
- retval_f = f(argc, args);
-
- args_shrink(&state->args, prev_argc);
+ retval.f = ((ejit_escape_f_t)i.p)(argc, args);
+ argc = 0;
DISPATCH();
DO(ESCAPEI_D);
- ejit_escape_d_t f = i.p;
- size_t argc = args_len(&state->args) - prev_argc;
- struct ejit_arg *args = state->args.buf + prev_argc;
-
- retval_f = f(argc, args);
-
- args_shrink(&state->args, prev_argc);
+ retval.f = ((ejit_escape_d_t)i.p)(argc, args);
+ argc = 0;
DISPATCH();
/* dispatch is technically unnecessary for returns, but keep it for
* symmetry */
DO(RETR);
- retval = gpr[i.r1];
- goto out_int;
+ return (union interp_ret){.i = gpr[i.r1]};
DISPATCH();
DO(RETI);
- retval = i.o;
- goto out_int;
+ return (union interp_ret){.i = i.o};
DISPATCH();
DO(RETR_F);
- retval_f = fpr[i.r1].f;
- goto out_float;
+ return (union interp_ret){.f = fpr[i.r1].f};
DISPATCH();
DO(RETR_D);
- retval_f = fpr[i.r1].d;
- goto out_float;
+ return (union interp_ret){.f = fpr[i.r1].d};
DISPATCH();
DO(RETI_F);
- retval_f = i.f;
- goto out_float;
+ return (union interp_ret){.f = i.f};
DISPATCH();
DO(RETI_D);
- retval_f = i.d;
- goto out_float;
+ return (union interp_ret){.f = i.d};
DISPATCH();
#undef DISPATCH
#undef JUMP
#undef DO
-out_float:
- gprs_shrink(&state->gprs, prev_gprs);
- fprs_shrink(&state->fprs, prev_fprs);
- return (union interp_ret){.f = retval_f};
-
-out_int:
- gprs_shrink(&state->gprs, prev_gprs);
- fprs_shrink(&state->fprs, prev_fprs);
- return (union interp_ret){.i = retval};
-
-zero_out:
return (union interp_ret){.i = 0};
}