diff options
Diffstat (limited to 'src/interp.c')
-rw-r--r-- | src/interp.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/interp.c b/src/interp.c index fe61c36..383599e 100644 --- a/src/interp.c +++ b/src/interp.c @@ -24,11 +24,17 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [SUBI] = &&SUBI, [MULR] = &&MULR, + [DIVR] = &&DIVR, + [DIVR_U] = &&DIVR_U, + [DIVR_F] = &&DIVR_F, [ANDR] = &&ANDR, [ANDI] = &&ANDI, + [COMR] = &&COMR, + [NEGR] = &&NEGR, + [EQR] = &&EQR, [EQR_F] = &&EQR_F, @@ -43,8 +49,23 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [GER_U] = &&GER_U, [GER_F] = &&GER_F, + [STXI8] = &&STXI8, + [STXI16] = &&STXI16, + [STXI32] = &&STXI32, [STXI64] = &&STXI64, + [STXIF] = &&STXIF, + [STXID] = &&STXID, + + [LDXI8] = &&LDXI8, + [LDXI16] = &&LDXI16, + [LDXI32] = &&LDXI32, + [LDXI64] = &&LDXI64, + [LDXIU8] = &&LDXIU8, + [LDXIU16] = &&LDXIU16, + [LDXIU32] = &&LDXIU32, [LDXIU64] = &&LDXIU64, + [LDXIF] = &&LDXIF, + [LDXID] = &&LDXID, [BNER] = &&BNER, [BNEI] = &&BNEI, @@ -87,6 +108,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [RETI_F] = &&RETI_F, [RETVAL] = &&RETVAL, + [RETVAL_F] = &&RETVAL_F, [ARG] = &&ARG, [ARG_I] = &&ARG_I, @@ -99,6 +121,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [CALLI] = &&CALLI, [CALLI_F] = &&CALLI_F, [ESCAPEI] = &&ESCAPEI, + [ESCAPEI_F] = &&ESCAPEI_F, [START] = &&START, [END] = &&END, @@ -188,6 +211,14 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = gpr[i.r1] / gpr[i.r2]; DISPATCH(); + DO(DIVR_U); + gpr[i.r0] = (uint64_t)gpr[i.r1] / (uint64_t)gpr[i.r2]; + DISPATCH(); + + DO(DIVR_F); + fpr[i.r0] = fpr[i.r1] / fpr[i.r2]; + DISPATCH(); + DO(ANDR); gpr[i.r0] = gpr[i.r1] & gpr[i.r2]; DISPATCH(); @@ -196,6 +227,14 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = gpr[i.r1] & i.o; DISPATCH(); + DO(COMR); + gpr[i.r0] = ~gpr[i.r1]; + DISPATCH(); + + DO(NEGR); + gpr[i.r0] = -gpr[i.r1]; + DISPATCH(); + DO(EQR); gpr[i.r0] = gpr[i.r1] == gpr[i.r2]; DISPATCH(); @@ -236,16 +275,86 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = fpr[i.r1] >= fpr[i.r2]; DISPATCH(); + DO(STXI8); + int8_t *addr = (int8_t *)(gpr[i.r1] + i.o); + *addr = gpr[i.r0]; + DISPATCH(); + + DO(STXI16); + int16_t *addr = (int16_t *)(gpr[i.r1] + i.o); + *addr = gpr[i.r0]; + DISPATCH(); + + DO(STXI32); + int32_t *addr = (int32_t *)(gpr[i.r1] + i.o); + *addr = gpr[i.r0]; + DISPATCH(); + DO(STXI64); int64_t *addr = (int64_t *)(gpr[i.r1] + i.o); *addr = gpr[i.r0]; DISPATCH(); + DO(STXIF); + float *addr = (float *)(gpr[i.r1] + i.o); + *addr = fpr[i.r0]; + DISPATCH(); + + DO(STXID); + double *addr = (double *)(gpr[i.r1] + i.o); + *addr = fpr[i.r0]; + DISPATCH(); + + DO(LDXI8); + int8_t *addr = (int8_t *)(gpr[i.r1] + i.o); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXI16); + int16_t *addr = (int16_t *)(gpr[i.r1] + i.o); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXI32); + int32_t *addr = (int32_t *)(gpr[i.r1] + i.o); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXI64); + int64_t *addr = (int64_t *)(gpr[i.r1] + i.o); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXIU8); + uint8_t *addr = (uint8_t *)(gpr[i.r1] + i.o); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXIU16); + uint16_t *addr = (uint16_t *)(gpr[i.r1] + i.o); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXIU32); + uint32_t *addr = (uint32_t *)(gpr[i.r1] + i.o); + gpr[i.r0] = *addr; + DISPATCH(); + DO(LDXIU64); uint64_t *addr = (uint64_t *)(gpr[i.r1] + i.o); gpr[i.r0] = *addr; DISPATCH(); + DO(LDXIF); + float *addr = (float *)(gpr[i.r1] + i.o); + fpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXID); + double *addr = (double *)(gpr[i.r1] + i.o); + fpr[i.r0] = *addr; + DISPATCH(); + DO(BNER); if (gpr[i.r1] != gpr[i.r2]) JUMP(i.r0); @@ -410,6 +519,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = retval; DISPATCH(); + DO(RETVAL_F); + fpr[i.r0] = retval_f; + DISPATCH(); + DO(PARAM); gpr[i.r2] = args[i.r0].u64; DISPATCH(); @@ -465,6 +578,17 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, vec_shrink(&state->args, prev_argc); DISPATCH(); + DO(ESCAPEI_F); + ejit_escape_f_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; + + retval_f = f(argc, args); + + vec_shrink(&state->args, prev_argc); + DISPATCH(); + /* dispatch is technically unnecessary for returns, but keep it for * symmetry */ DO(RETR); |