diff options
Diffstat (limited to 'src/interp.c')
-rw-r--r-- | src/interp.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/src/interp.c b/src/interp.c index ed7e59c..3395537 100644 --- a/src/interp.c +++ b/src/interp.c @@ -1,8 +1,12 @@ #include <ejit/ejit.h> +#include <math.h> #include "common.h" -union interp_ret ejit_interp(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_interp(struct ejit_func *f, size_t argc, + struct ejit_arg args[argc], + struct interp_state *state, bool run, + void ***labels_wb) { static void *labels[OPCODE_COUNT] = { [MOVI] = &&MOVI, @@ -13,6 +17,8 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a [ADDR_F] = &&ADDR_F, [ADDI] = &&ADDI, + [ABSR_F] = &&ABSR_F, + [SUBR] = &&SUBR, [SUBR_F] = &&SUBR_F, [SUBI] = &&SUBI, @@ -33,10 +39,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a [JMP] = &&JMP, - [RET] = &&RET, - [RET_I] = &&RET_I, - [RET_F] = &&RET_F, - [RET_FI] = &&RET_FI, + [RETR] = &&RETR, + [RETI] = &&RETI, + [RETR_F] = &&RETR_F, + [RETI_F] = &&RETI_F, [RETVAL] = &&RETVAL, @@ -76,10 +82,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a /* retval is kind of an unfortunate extra bit of state to keep track of, * but having call and return value separated is pretty convenient for * void calls so I guess I don't mind? */ - long retval = 0; double retval_f = 0.; + int64_t retval = 0; double retval_f = 0.; size_t pc = 0; -#define DO(x) x: { struct ejit_insn i = insns[pc]; (void)i; +#define DO(x) x : { struct ejit_insn i = insns[pc]; (void)i; #define JUMP(a) goto *insns[pc = a].addr; #define DISPATCH() } goto *insns[++pc].addr; @@ -116,6 +122,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a gpr[i.r0] = gpr[i.r1] + i.o; DISPATCH(); + DO(ABSR_F); + fpr[i.r0] = fabs(fpr[i.r1]); + DISPATCH(); + DO(SUBR); gpr[i.r0] = gpr[i.r1] - gpr[i.r2]; DISPATCH(); @@ -187,7 +197,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a DISPATCH(); DO(PARAM); - gpr[i.r2] = args[i.r0].l; + gpr[i.r2] = args[i.r0].u64; DISPATCH(); DO(PARAM_F); @@ -217,7 +227,8 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a DO(CALLI); struct ejit_func *f = i.p; size_t argc = vec_len(&state->args) - prev_argc; - struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) + prev_argc; + struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) + + prev_argc; retval = ejit_run_interp(f, argc, args, state); @@ -232,7 +243,8 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a DO(ESCAPEI); ejit_escape_t f = i.p; size_t argc = vec_len(&state->args) - prev_argc; - struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) + prev_argc; + struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) + + prev_argc; retval = f(argc, args); @@ -241,22 +253,22 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a /* dispatch is technically unnecessary for returns, but keep it for * symmetry */ - DO(RET); + DO(RETR); retval = gpr[i.r0]; goto out_int; DISPATCH(); - DO(RET_I); + DO(RETI); retval = i.o; goto out_int; DISPATCH(); - DO(RET_F); + DO(RETR_F); retval_f = fpr[i.r0]; goto out_float; DISPATCH(); - DO(RET_FI); + DO(RETI_F); retval_f = i.d; goto out_float; DISPATCH(); |