aboutsummaryrefslogtreecommitdiff
path: root/src/interp.c
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/interp.c
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/interp.c')
-rw-r--r--src/interp.c124
1 files changed, 124 insertions, 0 deletions
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);