diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-06-30 00:53:34 +0300 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-06-30 00:53:34 +0300 |
commit | 451797936119d8236843c4e9aee4a47dc5cddd56 (patch) | |
tree | 5aed431a0058bbe00627659cefc8fef85a4e18bb /src | |
parent | 864a078cf9faf9b85a7a9042b4033d46847aea8f (diff) | |
download | ejit-451797936119d8236843c4e9aee4a47dc5cddd56.tar.gz ejit-451797936119d8236843c4e9aee4a47dc5cddd56.zip |
continue working through test cases
+ Remove overflow and more complicated floating point tests for now
Diffstat (limited to 'src')
-rw-r--r-- | src/common.h | 6 | ||||
-rw-r--r-- | src/ejit.c | 112 | ||||
-rw-r--r-- | src/interp.c | 124 |
3 files changed, 242 insertions, 0 deletions
diff --git a/src/common.h b/src/common.h index 1f21c74..218b589 100644 --- a/src/common.h +++ b/src/common.h @@ -64,8 +64,14 @@ enum ejit_opcode { SUBI, MULR, + MULR_F, + DIVR, + DIVR_U, + DIVR_F, + NEGR, + COMR, ANDR, ANDI, @@ -192,18 +192,107 @@ void ejit_retval(struct ejit_func *s, struct ejit_gpr r0) emit_insn_i(s, RETVAL, r0.r, 0, 0); } +void ejit_retval_f(struct ejit_func *s, struct ejit_fpr r0) +{ + emit_insn_i(s, RETVAL_F, r0.f, 0, 0); +} + +void ejit_stxi_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, STXI8, r0.r, r1.r, o); +} + +void ejit_stxi_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, STXI16, r0.r, r1.r, o); +} + +void ejit_stxi_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, STXI32, r0.r, r1.r, o); +} + void ejit_stxi_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { emit_insn_i(s, STXI64, r0.r, r1.r, o); } +void ejit_stxi_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, STXIF, r0.f, r1.r, o); +} + +void ejit_stxi_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, STXID, r0.f, r1.r, o); +} + +void ejit_ldxi_i8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, LDXI8, r0.r, r1.r, o); +} + +void ejit_ldxi_i16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, LDXI16, r0.r, r1.r, o); +} + +void ejit_ldxi_i32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, LDXI32, r0.r, r1.r, o); +} + +void ejit_ldxi_i64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, LDXI64, r0.r, r1.r, o); +} + +void ejit_ldxi_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, LDXIU8, r0.r, r1.r, o); +} + +void ejit_ldxi_u16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, LDXIU16, r0.r, r1.r, o); +} + +void ejit_ldxi_u32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, LDXIU32, r0.r, r1.r, o); +} + void ejit_ldxi_u64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { emit_insn_i(s, LDXIU64, r0.r, r1.r, o); } +void ejit_ldxi_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, LDXIF, r0.f, r1.r, o); +} + +void ejit_ldxi_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, LDXID, r0.f, r1.r, o); +} + void ejit_retr(struct ejit_func *s, struct ejit_gpr r0) { emit_insn_r(s, RETR, r0.r, 0, 0); @@ -277,6 +366,18 @@ void ejit_divr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, emit_insn_r(s, DIVR, r0.r, r1.r, r2.r); } +void ejit_divr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, DIVR_U, r0.r, r1.r, r2.r); +} + +void ejit_divr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, + struct ejit_fpr r2) +{ + emit_insn_r(s, DIVR_F, r0.f, r1.f, r2.f); +} + void ejit_andr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { @@ -289,6 +390,11 @@ void ejit_andi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, emit_insn_i(s, ANDI, r0.r, r1.r, o); } +void ejit_comr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) +{ + emit_insn_i(s, COMR, r0.r, r1.r, 0); +} + void ejit_negr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { emit_insn_i(s, NEGR, r0.r, r1.r, 0); @@ -313,6 +419,12 @@ void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, emit_insn_r(s, EQR, r0.r, r1.r, r2.r); } +void ejit_eqr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1, + struct ejit_fpr r2) +{ + emit_insn_r(s, EQR_F, r0.r, r1.f, r2.f); +} + void ejit_ltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { 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); |