aboutsummaryrefslogtreecommitdiff
path: root/src/interp.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-06-29 14:20:07 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-06-29 14:20:07 +0300
commit49aa680ccdac46d1d2a7f9f250999b7ff7099548 (patch)
tree1de3bd5209feadfd147f7a05d1ac925f98b747b1 /src/interp.c
parent29718f2e84478b296c3198ae6d35cfd5d79efb14 (diff)
downloadejit-49aa680ccdac46d1d2a7f9f250999b7ff7099548.tar.gz
ejit-49aa680ccdac46d1d2a7f9f250999b7ff7099548.zip
start adding tests
Diffstat (limited to 'src/interp.c')
-rw-r--r--src/interp.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/src/interp.c b/src/interp.c
index ed7e59c..3395537 100644
--- a/src/interp.c
+++ b/src/interp.c
@@ -1,8 +1,12 @@
#include <ejit/ejit.h>
+#include <math.h>
#include "common.h"
-union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *state, bool run, void ***labels_wb)
+union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
+ struct ejit_arg args[argc],
+ struct interp_state *state, bool run,
+ void ***labels_wb)
{
static void *labels[OPCODE_COUNT] = {
[MOVI] = &&MOVI,
@@ -13,6 +17,8 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
[ADDR_F] = &&ADDR_F,
[ADDI] = &&ADDI,
+ [ABSR_F] = &&ABSR_F,
+
[SUBR] = &&SUBR,
[SUBR_F] = &&SUBR_F,
[SUBI] = &&SUBI,
@@ -33,10 +39,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
[JMP] = &&JMP,
- [RET] = &&RET,
- [RET_I] = &&RET_I,
- [RET_F] = &&RET_F,
- [RET_FI] = &&RET_FI,
+ [RETR] = &&RETR,
+ [RETI] = &&RETI,
+ [RETR_F] = &&RETR_F,
+ [RETI_F] = &&RETI_F,
[RETVAL] = &&RETVAL,
@@ -76,10 +82,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
/* retval is kind of an unfortunate extra bit of state to keep track of,
* but having call and return value separated is pretty convenient for
* void calls so I guess I don't mind? */
- long retval = 0; double retval_f = 0.;
+ int64_t retval = 0; double retval_f = 0.;
size_t pc = 0;
-#define DO(x) x: { struct ejit_insn i = insns[pc]; (void)i;
+#define DO(x) x : { struct ejit_insn i = insns[pc]; (void)i;
#define JUMP(a) goto *insns[pc = a].addr;
#define DISPATCH() } goto *insns[++pc].addr;
@@ -116,6 +122,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
gpr[i.r0] = gpr[i.r1] + i.o;
DISPATCH();
+ DO(ABSR_F);
+ fpr[i.r0] = fabs(fpr[i.r1]);
+ DISPATCH();
+
DO(SUBR);
gpr[i.r0] = gpr[i.r1] - gpr[i.r2];
DISPATCH();
@@ -187,7 +197,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
DISPATCH();
DO(PARAM);
- gpr[i.r2] = args[i.r0].l;
+ gpr[i.r2] = args[i.r0].u64;
DISPATCH();
DO(PARAM_F);
@@ -217,7 +227,8 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
DO(CALLI);
struct ejit_func *f = i.p;
size_t argc = vec_len(&state->args) - prev_argc;
- struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) + prev_argc;
+ struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) +
+ prev_argc;
retval = ejit_run_interp(f, argc, args, state);
@@ -232,7 +243,8 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
DO(ESCAPEI);
ejit_escape_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;
+ struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) +
+ prev_argc;
retval = f(argc, args);
@@ -241,22 +253,22 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, struct ejit_arg a
/* dispatch is technically unnecessary for returns, but keep it for
* symmetry */
- DO(RET);
+ DO(RETR);
retval = gpr[i.r0];
goto out_int;
DISPATCH();
- DO(RET_I);
+ DO(RETI);
retval = i.o;
goto out_int;
DISPATCH();
- DO(RET_F);
+ DO(RETR_F);
retval_f = fpr[i.r0];
goto out_float;
DISPATCH();
- DO(RET_FI);
+ DO(RETI_F);
retval_f = i.d;
goto out_float;
DISPATCH();