diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-06-30 16:39:24 +0300 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-06-30 16:40:12 +0300 |
commit | e618924df98d4ee5037db86c768a8c8014e49c4c (patch) | |
tree | abf7e2457f49c52d3ea6c6c5fb79577e5a4ad011 /src | |
parent | 451797936119d8236843c4e9aee4a47dc5cddd56 (diff) | |
download | ejit-e618924df98d4ee5037db86c768a8c8014e49c4c.tar.gz ejit-e618924df98d4ee5037db86c768a8c8014e49c4c.zip |
work through loads and stores
Diffstat (limited to 'src')
-rw-r--r-- | src/common.h | 24 | ||||
-rw-r--r-- | src/ejit.c | 247 | ||||
-rw-r--r-- | src/interp.c | 179 |
3 files changed, 445 insertions, 5 deletions
diff --git a/src/common.h b/src/common.h index 218b589..e9f0b69 100644 --- a/src/common.h +++ b/src/common.h @@ -31,6 +31,17 @@ enum ejit_opcode { LDXIF, LDXID, + LDXR8, + LDXR16, + LDXR32, + LDXR64, + LDXRU8, + LDXRU16, + LDXRU32, + LDXRU64, + LDXRF, + LDXRD, + STI8, STI16, STI32, @@ -53,6 +64,13 @@ enum ejit_opcode { STXIF, STXID, + EXTR8, + EXTR16, + EXTR32, + EXTRU8, + EXTRU16, + EXTRU32, + ADDR, ADDR_F, ADDI, @@ -73,6 +91,11 @@ enum ejit_opcode { NEGR, COMR, + LSHI, + LSHR, + RSHI, + RSHR, + ANDR, ANDI, @@ -117,6 +140,7 @@ enum ejit_opcode { BLTGTR_F, JMP, + JMPR, BMCI, BMCR, @@ -233,8 +233,58 @@ 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_ldi_i8(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, LDI8, r0.r, 0, p); +} + +void ejit_ldi_i16(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, LDI16, r0.r, 0, p); +} + +void ejit_ldi_i32(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, LDI32, r0.r, 0, p); +} + +void ejit_ldi_i64(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, LDI64, r0.r, 0, p); +} + +void ejit_ldi_u8(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, LDIU8, r0.r, 0, p); +} + +void ejit_ldi_u16(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, LDIU16, r0.r, 0, p); +} + +void ejit_ldi_u32(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, LDIU32, r0.r, 0, p); +} + +void ejit_ldi_u64(struct ejit_func *s, struct ejit_gpr r0, void *p) +{ + emit_insn_p(s, LDIU64, r0.r, 0, p); +} + +void ejit_ldi_f(struct ejit_func *s, struct ejit_fpr r0, void *p) +{ + emit_insn_p(s, LDIF, r0.f, 0, p); +} + +void ejit_ldi_d(struct ejit_func *s, struct ejit_fpr r0, void *p) +{ + emit_insn_p(s, LDID, r0.f, 0, p); +} + void ejit_ldxi_i8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - int64_t o) + int64_t o) { emit_insn_i(s, LDXI8, r0.r, r1.r, o); } @@ -258,7 +308,7 @@ void ejit_ldxi_i64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, } void ejit_ldxi_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, - int64_t o) + int64_t o) { emit_insn_i(s, LDXIU8, r0.r, r1.r, o); } @@ -282,17 +332,77 @@ void ejit_ldxi_u64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, } void ejit_ldxi_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, - int64_t o) + 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) + int64_t o) { emit_insn_i(s, LDXID, r0.f, r1.r, o); } +void ejit_ldxr_i8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LDXR8, r0.r, r1.r, r2.r); +} + +void ejit_ldxr_i16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LDXR16, r0.r, r1.r, r2.r); +} + +void ejit_ldxr_i32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LDXR32, r0.r, r1.r, r2.r); +} + +void ejit_ldxr_i64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LDXR64, r0.r, r1.r, r2.r); +} + +void ejit_ldxr_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LDXRU8, r0.r, r1.r, r2.r); +} + +void ejit_ldxr_u16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LDXRU16, r0.r, r1.r, r2.r); +} + +void ejit_ldxr_u32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LDXRU32, r0.r, r1.r, r2.r); +} + +void ejit_ldxr_u64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LDXIU64, r0.r, r1.r, r2.r); +} + +void ejit_ldxr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LDXRF, r0.f, r1.r, r2.r); +} + +void ejit_ldxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LDXRD, r0.f, r1.r, r2.r); +} + void ejit_retr(struct ejit_func *s, struct ejit_gpr r0) { emit_insn_r(s, RETR, r0.r, 0, 0); @@ -313,6 +423,36 @@ void ejit_reti_f(struct ejit_func *s, double f) emit_insn_f(s, RETI_F, 0, 0, f); } +void ejit_extr_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) +{ + emit_insn_i(s, EXTR8, r0.r, r1.r, 0); +} + +void ejit_extr_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) +{ + emit_insn_i(s, EXTR16, r0.r, r1.r, 0); +} + +void ejit_extr_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) +{ + emit_insn_i(s, EXTR32, r0.r, r1.r, 0); +} + +void ejit_extr_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) +{ + emit_insn_i(s, EXTRU8, r0.r, r1.r, 0); +} + +void ejit_extr_u16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) +{ + emit_insn_i(s, EXTRU16, r0.r, r1.r, 0); +} + +void ejit_extr_u32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) +{ + emit_insn_i(s, EXTRU32, r0.r, r1.r, 0); +} + void ejit_addr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { @@ -378,6 +518,30 @@ 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_lshi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, LSHI, r0.r, r1.r, o); +} + +void ejit_lshr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, LSHR, r0.r, r1.r, r2.r); +} + +void ejit_rshi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + int64_t o) +{ + emit_insn_i(s, RSHI, 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_andr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, struct ejit_gpr r2) { @@ -420,17 +584,83 @@ void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, } void ejit_eqr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1, - struct ejit_fpr r2) + struct ejit_fpr r2) { emit_insn_r(s, EQR_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) +{ + emit_insn_r(s, GTR, r0.r, r1.r, r2.r); +} + +void ejit_gtr_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, r1.r, r2.r); +} + +void ejit_gtr_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, r1.f, r2.f); +} + 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); } +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); +} + +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); +} + +void ejit_ger(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1, + struct ejit_gpr r2) +{ + emit_insn_r(s, GER, r0.r, r1.r, r2.r); +} + +void ejit_ger_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, r1.r, r2.r); +} + +void ejit_ger_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, r1.f, r2.f); +} + +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); +} + +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); +} + +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); +} + struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { @@ -648,6 +878,13 @@ struct ejit_reloc ejit_jmp(struct ejit_func *s) return (struct ejit_reloc){.insn = addr}; } +struct ejit_reloc ejit_jmpr(struct ejit_func *s, struct ejit_gpr r0) +{ + size_t addr = vec_len(&s->insns); + emit_insn_i(s, JMPR, 0, r0.r, 0); + return (struct ejit_reloc){.insn = addr}; +} + struct ejit_reloc ejit_bmci(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { size_t addr = vec_len(&s->insns); diff --git a/src/interp.c b/src/interp.c index 383599e..30a7672 100644 --- a/src/interp.c +++ b/src/interp.c @@ -13,6 +13,13 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [MOVR] = &&MOVR, [MOVR_F] = &&MOVR_F, + [EXTR8] = &&EXTR8, + [EXTR16] = &&EXTR16, + [EXTR32] = &&EXTR32, + [EXTRU8] = &&EXTRU8, + [EXTRU16] = &&EXTRU16, + [EXTRU32] = &&EXTRU32, + [ADDR] = &&ADDR, [ADDR_F] = &&ADDR_F, [ADDI] = &&ADDI, @@ -29,6 +36,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [DIVR_U] = &&DIVR_U, [DIVR_F] = &&DIVR_F, + [LSHI] = &&LSHI, + [LSHR] = &&LSHR, + [RSHI] = &&RSHI, + [RSHR] = &&RSHR, + [ANDR] = &&ANDR, [ANDI] = &&ANDI, @@ -56,6 +68,17 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [STXIF] = &&STXIF, [STXID] = &&STXID, + [LDI8] = &&LDI8, + [LDI16] = &&LDI16, + [LDI32] = &&LDI32, + [LDI64] = &&LDI64, + [LDIU8] = &&LDIU8, + [LDIU16] = &&LDIU16, + [LDIU32] = &&LDIU32, + [LDIU64] = &&LDIU64, + [LDIF] = &&LDIF, + [LDID] = &&LDID, + [LDXI8] = &&LDXI8, [LDXI16] = &&LDXI16, [LDXI32] = &&LDXI32, @@ -67,6 +90,17 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [LDXIF] = &&LDXIF, [LDXID] = &&LDXID, + [LDXR8] = &&LDXR8, + [LDXR16] = &&LDXR16, + [LDXR32] = &&LDXR32, + [LDXR64] = &&LDXR64, + [LDXRU8] = &&LDXRU8, + [LDXRU16] = &&LDXRU16, + [LDXRU32] = &&LDXRU32, + [LDXRU64] = &&LDXRU64, + [LDXRF] = &&LDXRF, + [LDXRD] = &&LDXRD, + [BNER] = &&BNER, [BNEI] = &&BNEI, [BNER_F] = &&BNER_F, @@ -96,6 +130,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, [BLTGTR_F] = &&BLTGTR_F, [JMP] = &&JMP, + [JMPR] = &&JMPR, [BMCI] = &&BMCI, [BMCR] = &&BMCR, @@ -175,6 +210,30 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, fpr[i.r0] = fpr[i.r1]; DISPATCH(); + DO(EXTR8); + gpr[i.r0] = (int8_t)gpr[i.r1]; + DISPATCH(); + + DO(EXTR16); + gpr[i.r0] = (int16_t)gpr[i.r1]; + DISPATCH(); + + DO(EXTR32); + gpr[i.r0] = (int32_t)gpr[i.r1]; + DISPATCH(); + + DO(EXTRU8); + gpr[i.r0] = (uint8_t)gpr[i.r1]; + DISPATCH(); + + DO(EXTRU16); + gpr[i.r0] = (uint16_t)gpr[i.r1]; + DISPATCH(); + + DO(EXTRU32); + gpr[i.r0] = (uint32_t)gpr[i.r1]; + DISPATCH(); + DO(ADDR); gpr[i.r0] = gpr[i.r1] + gpr[i.r2]; DISPATCH(); @@ -219,6 +278,22 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, fpr[i.r0] = fpr[i.r1] / fpr[i.r2]; DISPATCH(); + DO(LSHI); + gpr[i.r0] = gpr[i.r1] << i.o; + DISPATCH(); + + DO(LSHR); + gpr[i.r0] = gpr[i.r1] << gpr[i.r2]; + DISPATCH(); + + DO(RSHI); + gpr[i.r0] = gpr[i.r1] >> i.o; + DISPATCH(); + + DO(RSHR); + gpr[i.r0] = gpr[i.r1] >> gpr[i.r2]; + DISPATCH(); + DO(ANDR); gpr[i.r0] = gpr[i.r1] & gpr[i.r2]; DISPATCH(); @@ -305,6 +380,56 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, *addr = fpr[i.r0]; DISPATCH(); + DO(LDI8); + int8_t *addr = (int8_t *)i.p; + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDI16); + int16_t *addr = (int16_t *)i.p; + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDI32); + int32_t *addr = (int32_t *)i.p; + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDI64); + int64_t *addr = (int64_t *)i.p; + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDIU8); + uint8_t *addr = (uint8_t *)i.p; + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDIU16); + uint16_t *addr = (uint16_t *)i.p; + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDIU32); + uint32_t *addr = (uint32_t *)i.p; + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDIU64); + uint64_t *addr = (uint64_t *)i.p; + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDIF); + float *addr = (float *)i.p; + fpr[i.r0] = *addr; + DISPATCH(); + + DO(LDID); + double *addr = (double *)i.p; + fpr[i.r0] = *addr; + DISPATCH(); + DO(LDXI8); int8_t *addr = (int8_t *)(gpr[i.r1] + i.o); gpr[i.r0] = *addr; @@ -355,6 +480,56 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, fpr[i.r0] = *addr; DISPATCH(); + DO(LDXR8); + int8_t *addr = (int8_t *)(gpr[i.r1] + gpr[i.r2]); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXR16); + int16_t *addr = (int16_t *)(gpr[i.r1] + gpr[i.r2]); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXR32); + int32_t *addr = (int32_t *)(gpr[i.r1] + gpr[i.r2]); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXR64); + int64_t *addr = (int64_t *)(gpr[i.r1] + gpr[i.r2]); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXRU8); + uint8_t *addr = (uint8_t *)(gpr[i.r1] + gpr[i.r2]); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXRU16); + uint16_t *addr = (uint16_t *)(gpr[i.r1] + gpr[i.r2]); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXRU32); + uint32_t *addr = (uint32_t *)(gpr[i.r1] + gpr[i.r2]); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXRU64); + uint64_t *addr = (uint64_t *)(gpr[i.r1] + gpr[i.r2]); + gpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXRF); + float *addr = (float *)(gpr[i.r1] + gpr[i.r2]); + fpr[i.r0] = *addr; + DISPATCH(); + + DO(LDXRD); + double *addr = (double *)(gpr[i.r1] + gpr[i.r2]); + fpr[i.r0] = *addr; + DISPATCH(); + DO(BNER); if (gpr[i.r1] != gpr[i.r2]) JUMP(i.r0); @@ -491,6 +666,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, JUMP(i.r0); DISPATCH(); + DO(JMPR); + JUMP(gpr[i.r1]); + DISPATCH(); + DO(BMSR); if (gpr[i.r1] & gpr[i.r2]) JUMP(i.r0); |