aboutsummaryrefslogtreecommitdiff
path: root/src/interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interp.c')
-rw-r--r--src/interp.c67
1 files changed, 38 insertions, 29 deletions
diff --git a/src/interp.c b/src/interp.c
index 049498a..6ef414d 100644
--- a/src/interp.c
+++ b/src/interp.c
@@ -150,6 +150,12 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
[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,
@@ -222,29 +228,29 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
if (!run) {
*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)(paramc, params)
+ .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)(paramc, params)
+ .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)(paramc, params)
+ .f = ((ejit_escape_f_t)f->extern_call)(paramc, params)
};
return (union interp_ret){
- .i = ((ejit_escape_i_t)f->arena)(paramc, params)
+ .i = ((ejit_escape_i_t)f->extern_call)(paramc, params)
};
}
@@ -256,9 +262,9 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
};
size_t argc = 0;
- int64_t *gpr = alloca(sizeof(int64_t) * gpr_stats_len(&f->gpr));
- union fpr *fpr = alloca(sizeof(int64_t) * fpr_stats_len(&f->fpr));
- struct ejit_arg *args = alloca(sizeof(struct ejit_arg) * f->max_args);
+ 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,
@@ -276,7 +282,7 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
DISPATCH();
DO(END);
- goto zero_out;
+ return (union interp_ret){.i = 0};
DISPATCH();
DO(MOVI);
@@ -791,6 +797,22 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
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();
@@ -1087,45 +1109,32 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
/* 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:
- return (union interp_ret){.f = retval_f};
-
-out_int:
- return (union interp_ret){.i = retval};
-
-zero_out:
return (union interp_ret){.i = 0};
}