diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-07-13 20:56:26 +0300 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-07-13 20:56:26 +0300 |
commit | ae9e103995c1d809be7b8717905593e7dbbf9d17 (patch) | |
tree | 0ceaf6ee66e1d67bb8d0b9dd6f37b5687e4c2f09 /src | |
parent | e618924df98d4ee5037db86c768a8c8014e49c4c (diff) | |
download | ejit-ae9e103995c1d809be7b8717905593e7dbbf9d17.tar.gz ejit-ae9e103995c1d809be7b8717905593e7dbbf9d17.zip |
bytecode tests pass
Diffstat (limited to 'src')
-rw-r--r-- | src/common.h | 33 | ||||
-rw-r--r-- | src/ejit.c | 184 | ||||
-rw-r--r-- | src/interp.c | 143 |
3 files changed, 343 insertions, 17 deletions
diff --git a/src/common.h b/src/common.h index e9f0b69..1e08961 100644 --- a/src/common.h +++ b/src/common.h @@ -6,6 +6,7 @@ enum ejit_opcode { MOVI, + MOVI_F, MOVR, MOVR_F, @@ -46,10 +47,6 @@ enum ejit_opcode { STI16, STI32, STI64, - STIU8, - STIU16, - STIU32, - STIU64, STIF, STID, @@ -57,13 +54,16 @@ enum ejit_opcode { STXI16, STXI32, STXI64, - STXIU8, - STXIU16, - STXIU32, - STXIU64, STXIF, STXID, + STXR8, + STXR16, + STXR32, + STXR64, + STXRF, + STXRD, + EXTR8, EXTR16, EXTR32, @@ -88,17 +88,32 @@ enum ejit_opcode { DIVR_U, DIVR_F, - NEGR, + REMR, + REMR_U, + COMR, + NEGR, + NEGR_F, LSHI, LSHR, RSHI, + RSHI_U, RSHR, + RSHR_U, ANDR, ANDI, + ORR, + ORI, + + XORR, + XORI, + + TRUNCR_D_32, + TRUNCR_D_64, + EQR, NER, GTR, @@ -197,6 +197,36 @@ void ejit_retval_f(struct ejit_func *s, struct ejit_fpr r0) emit_insn_i(s, RETVAL_F, r0.f, 0, 0); } +void ejit_sti_8(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, STI8, r0.r, 0, p); +} + +void ejit_sti_16(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, STI16, r0.r, 0, p); +} + +void ejit_sti_32(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, STI32, r0.r, 0, p); +} + +void ejit_sti_64(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, STI64, r0.r, 0, p); +} + +void ejit_sti_f(struct ejit_func *s, struct ejit_fpr r0, void *p) +{ + emit_insn_p(s, STIF, r0.f, 0, p); +} + +void ejit_sti_d(struct ejit_func *s, struct ejit_fpr r0, void *p) +{ + emit_insn_p(s, STID, r0.f, 0, p); +} + void ejit_stxi_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { @@ -233,6 +263,42 @@ void ejit_stxi_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, emit_insn_i(s, STXID, r0.f, r1.r, o); } +void ejit_stxr_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, STXR8, r0.r, r1.r, r2.r); +} + +void ejit_stxr_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, STXR16, r0.r, r1.r, r2.r); +} + +void ejit_stxr_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, STXR32, r0.r, r1.r, r2.r); +} + +void ejit_stxr_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, STXR64, r0.r, r1.r, r2.r); +} + +void ejit_stxr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, STXRF, r0.f, r1.r, r2.r); +} + +void ejit_stxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, STXRD, r0.f, r1.r, r2.r); +} + void ejit_ldi_i8(struct ejit_func *s, struct ejit_gpr r0, void *p) { emit_insn_p(s, LDI8, r0.r, 0, p); @@ -403,6 +469,11 @@ void ejit_ldxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, emit_insn_r(s, LDXRD, r0.f, r1.r, r2.r); } +void ejit_ret(struct ejit_func *s) +{ + emit_insn_i(s, END, 0, 0, 0); +} + void ejit_retr(struct ejit_func *s, struct ejit_gpr r0) { emit_insn_r(s, RETR, r0.r, 0, 0); @@ -500,6 +571,12 @@ void ejit_mulr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, emit_insn_r(s, MULR, r0.r, r1.r, r2.r); } +void ejit_mulr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, + struct ejit_fpr r2) +{ + emit_insn_r(s, MULR_F, r0.f, r1.f, r2.f); +} + void ejit_divr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { @@ -518,6 +595,18 @@ void ejit_divr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, emit_insn_r(s, DIVR_F, r0.f, r1.f, r2.f); } +void ejit_remr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, REMR, r0.r, r1.r, r2.r); +} + +void ejit_remr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, REMR_U, r0.r, r1.r, r2.r); +} + void ejit_lshi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, int64_t o) { @@ -536,12 +625,24 @@ void ejit_rshi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, emit_insn_i(s, RSHI, r0.r, r1.r, o); } +void ejit_rshi_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, RSHI_U, r0.r, r1.r, o); +} + void ejit_rshr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { emit_insn_r(s, RSHR, r0.r, r1.r, r2.r); } +void ejit_rshr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, RSHR_U, r0.r, r1.r, r2.r); +} + void ejit_andr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { @@ -554,6 +655,30 @@ 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_orr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, ORR, r0.r, r1.r, r2.r); +} + +void ejit_ori(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, ORI, r0.r, r1.r, o); +} + +void ejit_xorr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, XORR, r0.r, r1.r, r2.r); +} + +void ejit_xori(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, XORI, 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); @@ -564,11 +689,21 @@ 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); } +void ejit_negr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) +{ + emit_insn_i(s, NEGR_F, r0.f, r1.f, 0); +} + void ejit_movi(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { emit_insn_i(s, MOVI, r0.r, 0, o); } +void ejit_movi_f(struct ejit_func *s, struct ejit_fpr r0, double o) +{ + emit_insn_f(s, MOVI_F, r0.f, 0, o); +} + void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { if (r0.r == r1.r) @@ -577,6 +712,14 @@ void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) emit_insn_i(s, MOVR, r0.r, r1.r, 0); } +void ejit_movr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) +{ + if (r0.f == r1.f) + return; + + emit_insn_i(s, MOVR_F, r0.f, r1.f, 0); +} + void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { @@ -589,6 +732,18 @@ void ejit_eqr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1, emit_insn_r(s, EQR_F, r0.r, r1.f, r2.f); } +void ejit_ner(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, NER, r0.r, r1.r, r2.r); +} + +void ejit_ner_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1, + struct ejit_fpr r2) +{ + emit_insn_r(s, NER_F, r0.r, r1.f, r2.f); +} + void ejit_gtr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { @@ -610,19 +765,19 @@ void ejit_gtr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1, void ejit_ltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_r(s, GER, r0.r, r2.r, r1.r); + emit_insn_r(s, GTR, r0.r, r2.r, r1.r); } void ejit_ltr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_r(s, GER_U, r0.r, r2.r, r1.r); + emit_insn_r(s, GTR_U, r0.r, r2.r, r1.r); } void ejit_ltr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1, struct ejit_fpr r2) { - emit_insn_r(s, GER_F, r0.r, r2.f, r1.f); + emit_insn_r(s, GTR_F, r0.r, r2.f, r1.f); } void ejit_ger(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, @@ -646,19 +801,31 @@ void ejit_ger_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1, void ejit_ler(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_r(s, GTR, r0.r, r2.r, r1.r); + emit_insn_r(s, GER, r0.r, r2.r, r1.r); } void ejit_ler_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { - emit_insn_r(s, GTR_U, r0.r, r2.r, r1.r); + emit_insn_r(s, GER_U, r0.r, r2.r, r1.r); } void ejit_ler_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1, struct ejit_fpr r2) { - emit_insn_r(s, GTR_F, r0.r, r2.f, r1.f); + emit_insn_r(s, GER_F, r0.r, r2.f, r1.f); +} + +void ejit_truncr_d_32(struct ejit_func *s, struct ejit_gpr r0, + struct ejit_fpr r1) +{ + emit_insn_i(s, TRUNCR_D_32, r0.r, r1.f, 0); +} + +void ejit_truncr_d_64(struct ejit_func *s, struct ejit_gpr r0, + struct ejit_fpr r1) +{ + emit_insn_i(s, TRUNCR_D_64, r0.r, r1.f, 0); } struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0, @@ -942,12 +1109,13 @@ long ejit_run_interp(struct ejit_func *f, size_t argc, return ejit_interp(f, argc, args, state, true, NULL).r; } -long ejit_run_func(struct ejit_func *f, size_t argc, struct ejit_arg args[argc]) +int64_t ejit_run_func(struct ejit_func *f, size_t argc, + struct ejit_arg args[argc]) { assert(f->size && "trying to run a function that hasn't been compiled"); assert(f->rtype == EJIT_VOID || ejit_int_type(f->rtype)); if (f->arena) - return ((ejit_escape_t)f->arena)(argc, args); + return (int64_t)((ejit_escape_t)f->arena)(argc, args); struct interp_state state = create_interp_state(); long r = ejit_interp(f, argc, args, &state, true, NULL).r; diff --git a/src/interp.c b/src/interp.c index 30a7672..a86b754 100644 --- a/src/interp.c +++ b/src/interp.c @@ -10,6 +10,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, { static void *labels[OPCODE_COUNT] = { [MOVI] = &&MOVI, + [MOVI_F] = &&MOVI_F, [MOVR] = &&MOVR, [MOVR_F] = &&MOVR_F, @@ -31,21 +32,34 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [SUBI] = &&SUBI, [MULR] = &&MULR, + [MULR_F] = &&MULR_F, [DIVR] = &&DIVR, [DIVR_U] = &&DIVR_U, [DIVR_F] = &&DIVR_F, + [REMR] = &&REMR, + [REMR_U] = &&REMR_U, + [LSHI] = &&LSHI, [LSHR] = &&LSHR, [RSHI] = &&RSHI, [RSHR] = &&RSHR, + [RSHI_U] = &&RSHI_U, + [RSHR_U] = &&RSHR_U, [ANDR] = &&ANDR, [ANDI] = &&ANDI, + [ORR] = &&ORR, + [ORI] = &&ORI, + + [XORR] = &&XORR, + [XORI] = &&XORI, + [COMR] = &&COMR, [NEGR] = &&NEGR, + [NEGR_F] = &&NEGR_F, [EQR] = &&EQR, [EQR_F] = &&EQR_F, @@ -61,6 +75,13 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [GER_U] = &&GER_U, [GER_F] = &&GER_F, + [STI8] = &&STI8, + [STI16] = &&STI16, + [STI32] = &&STI32, + [STI64] = &&STI64, + [STIF] = &&STIF, + [STID] = &&STID, + [STXI8] = &&STXI8, [STXI16] = &&STXI16, [STXI32] = &&STXI32, @@ -68,6 +89,13 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [STXIF] = &&STXIF, [STXID] = &&STXID, + [STXR8] = &&STXR8, + [STXR16] = &&STXR16, + [STXR32] = &&STXR32, + [STXR64] = &&STXR64, + [STXRF] = &&STXRF, + [STXRD] = &&STXRD, + [LDI8] = &&LDI8, [LDI16] = &&LDI16, [LDI32] = &&LDI32, @@ -101,6 +129,9 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [LDXRF] = &&LDXRF, [LDXRD] = &&LDXRD, + [TRUNCR_D_32] = &&TRUNCR_D_32, + [TRUNCR_D_64] = &&TRUNCR_D_64, + [BNER] = &&BNER, [BNEI] = &&BNEI, [BNER_F] = &&BNER_F, @@ -202,6 +233,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = i.o; DISPATCH(); + DO(MOVI_F); + fpr[i.r0] = i.d; + DISPATCH(); + DO(MOVR); gpr[i.r0] = gpr[i.r1]; DISPATCH(); @@ -266,6 +301,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = gpr[i.r1] * gpr[i.r2]; DISPATCH(); + DO(MULR_F); + fpr[i.r0] = fpr[i.r1] * fpr[i.r2]; + DISPATCH(); + DO(DIVR); gpr[i.r0] = gpr[i.r1] / gpr[i.r2]; DISPATCH(); @@ -274,6 +313,14 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = (uint64_t)gpr[i.r1] / (uint64_t)gpr[i.r2]; DISPATCH(); + DO(REMR); + gpr[i.r0] = gpr[i.r1] % gpr[i.r2]; + DISPATCH(); + + DO(REMR_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(); @@ -294,6 +341,14 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = gpr[i.r1] >> gpr[i.r2]; DISPATCH(); + DO(RSHI_U); + gpr[i.r0] = (uint64_t)gpr[i.r1] >> i.o; + DISPATCH(); + + DO(RSHR_U); + gpr[i.r0] = (uint64_t)gpr[i.r1] >> gpr[i.r2]; + DISPATCH(); + DO(ANDR); gpr[i.r0] = gpr[i.r1] & gpr[i.r2]; DISPATCH(); @@ -302,6 +357,22 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = gpr[i.r1] & i.o; DISPATCH(); + DO(ORR); + gpr[i.r0] = gpr[i.r1] | gpr[i.r2]; + DISPATCH(); + + DO(ORI); + gpr[i.r0] = gpr[i.r1] | i.o; + DISPATCH(); + + DO(XORR); + gpr[i.r0] = gpr[i.r1] ^ gpr[i.r2]; + DISPATCH(); + + DO(XORI); + gpr[i.r0] = gpr[i.r1] ^ i.o; + DISPATCH(); + DO(COMR); gpr[i.r0] = ~gpr[i.r1]; DISPATCH(); @@ -310,6 +381,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = -gpr[i.r1]; DISPATCH(); + DO(NEGR_F); + fpr[i.r0] = -fpr[i.r1]; + DISPATCH(); + DO(EQR); gpr[i.r0] = gpr[i.r1] == gpr[i.r2]; DISPATCH(); @@ -350,6 +425,36 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr[i.r0] = fpr[i.r1] >= fpr[i.r2]; DISPATCH(); + DO(STI8); + int8_t *addr = (int8_t *)(i.p); + *addr = gpr[i.r0]; + DISPATCH(); + + DO(STI16); + int16_t *addr = (int16_t *)(i.p); + *addr = gpr[i.r0]; + DISPATCH(); + + DO(STI32); + int32_t *addr = (int32_t *)(i.p); + *addr = gpr[i.r0]; + DISPATCH(); + + DO(STI64); + int64_t *addr = (int64_t *)(i.p); + *addr = gpr[i.r0]; + DISPATCH(); + + DO(STIF); + float *addr = (float *)(i.p); + *addr = fpr[i.r0]; + DISPATCH(); + + DO(STID); + double *addr = (double *)(i.p); + *addr = fpr[i.r0]; + DISPATCH(); + DO(STXI8); int8_t *addr = (int8_t *)(gpr[i.r1] + i.o); *addr = gpr[i.r0]; @@ -380,6 +485,36 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, *addr = fpr[i.r0]; DISPATCH(); + DO(STXR8); + int8_t *addr = (int8_t *)(gpr[i.r1] + gpr[i.r2]); + *addr = gpr[i.r0]; + DISPATCH(); + + DO(STXR16); + int16_t *addr = (int16_t *)(gpr[i.r1] + gpr[i.r2]); + *addr = gpr[i.r0]; + DISPATCH(); + + DO(STXR32); + int32_t *addr = (int32_t *)(gpr[i.r1] + gpr[i.r2]); + *addr = gpr[i.r0]; + DISPATCH(); + + DO(STXR64); + int64_t *addr = (int64_t *)(gpr[i.r1] + gpr[i.r2]); + *addr = gpr[i.r0]; + DISPATCH(); + + DO(STXRF); + float *addr = (float *)(gpr[i.r1] + gpr[i.r2]); + *addr = fpr[i.r0]; + DISPATCH(); + + DO(STXRD); + double *addr = (double *)(gpr[i.r1] + gpr[i.r2]); + *addr = fpr[i.r0]; + DISPATCH(); + DO(LDI8); int8_t *addr = (int8_t *)i.p; gpr[i.r0] = *addr; @@ -530,6 +665,14 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, fpr[i.r0] = *addr; DISPATCH(); + DO(TRUNCR_D_32); + gpr[i.r0] = (int32_t)fpr[i.r1]; + DISPATCH(); + + DO(TRUNCR_D_64); + gpr[i.r0] = (int64_t)fpr[i.r1]; + DISPATCH(); + DO(BNER); if (gpr[i.r1] != gpr[i.r2]) JUMP(i.r0); |