aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-06-30 16:39:24 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-06-30 16:40:12 +0300
commite618924df98d4ee5037db86c768a8c8014e49c4c (patch)
treeabf7e2457f49c52d3ea6c6c5fb79577e5a4ad011 /src
parent451797936119d8236843c4e9aee4a47dc5cddd56 (diff)
downloadejit-e618924df98d4ee5037db86c768a8c8014e49c4c.tar.gz
ejit-e618924df98d4ee5037db86c768a8c8014e49c4c.zip
work through loads and stores
Diffstat (limited to 'src')
-rw-r--r--src/common.h24
-rw-r--r--src/ejit.c247
-rw-r--r--src/interp.c179
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,
diff --git a/src/ejit.c b/src/ejit.c
index c4e82b1..4f407aa 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -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);