aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-06-30 00:53:34 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-06-30 00:53:34 +0300
commit451797936119d8236843c4e9aee4a47dc5cddd56 (patch)
tree5aed431a0058bbe00627659cefc8fef85a4e18bb /src
parent864a078cf9faf9b85a7a9042b4033d46847aea8f (diff)
downloadejit-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.h6
-rw-r--r--src/ejit.c112
-rw-r--r--src/interp.c124
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,
diff --git a/src/ejit.c b/src/ejit.c
index adba1cc..c4e82b1 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -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);