diff options
Diffstat (limited to 'src/interp.c')
-rw-r--r-- | src/interp.c | 67 |
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}; } |