diff options
| m--------- | deps/conts | 0 | ||||
| -rw-r--r-- | scripts/makefile | 10 | ||||
| -rw-r--r-- | src/compile/compile.c | 17 | ||||
| -rw-r--r-- | src/interp.c | 14 | ||||
| -rw-r--r-- | tests/makefile | 5 | ||||
| -rw-r--r-- | tests/z_double_label.c | 38 |
6 files changed, 58 insertions, 26 deletions
diff --git a/deps/conts b/deps/conts -Subproject 5a4cb1b5a8ba258a23a62feab1e66cc7d0eba3b +Subproject 4670112f63966ac6d4c1d1894341b67fee931a3 diff --git a/scripts/makefile b/scripts/makefile index 6e3b972..39ac062 100644 --- a/scripts/makefile +++ b/scripts/makefile @@ -6,12 +6,8 @@ OPTFLAGS != [ "$(RELEASE)" != "0" ] \ LTO ?= 0 LTOFLAGS != [ "$(LTO)" != "0" ] \ - && echo "-flto=auto" - -DEBUG ?= 1 -DEBUGFLAGS != [ "$(DEBUG)" != "0" ] \ - && echo "-DDEBUG=1" \ - || echo "-DNDEBUG=1" + && echo "-flto=auto" \ + || echo DEPFLAGS = -MT $@ -MMD -MP -MF $@.d LINTFLAGS := -fsyntax-only @@ -43,7 +39,7 @@ OBFLAGS := -g WARNFLAGS := -Wall -Wextra COMPILE_FLAGS := $(CFLAGS) $(WARNFLAGS) $(OPTFLAGS) $(LTOFLAGS) \ - $(OBFLAGS) $(DEBUGFLAGS) + $(OBFLAGS) INCLUDE_FLAGS := -I include -I deps/conts/include diff --git a/src/compile/compile.c b/src/compile/compile.c index 5aab67e..7965f93 100644 --- a/src/compile/compile.c +++ b/src/compile/compile.c @@ -47,7 +47,7 @@ static void *alloc_arena(size_t size, bool im_scawed) MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } -static void assert_helper(const char *msg) +static inline void assert_helper(const char *msg) { assert(false && msg); } @@ -1974,6 +1974,10 @@ static void resolve_top_reloc(jit_state_t *j, struct relocs *relocs, struct addr assert(a); jit_patch_there(j, r, a); relocs_pop(relocs); + + /* hope this turns into a tailcall */ + if (relocs_len(relocs)) + resolve_top_reloc(j, relocs, addrs, ii); } static void resolve_relocs(jit_state_t *j, struct relocs *relocs, struct addrs *addrs, size_t ii) @@ -2066,12 +2070,11 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, size_t label = 0; for (size_t ii = 0; ii < insns_len(&f->insns); ++ii) { /* if we've hit a label, add it to our vector of label addresses */ - if (label < labels_len(&f->labels)) { - if (*labels_at(&f->labels, label) == ii) { - compile_label(j, ii, &addrs); - resolve_relocs(j, &relocs, &addrs, ii); - label++; - } + while (label < labels_len(&f->labels) + && *labels_at(&f->labels, label) == ii) { + compile_label(j, ii, &addrs); + resolve_relocs(j, &relocs, &addrs, ii); + label++; } struct ejit_insn i = *insns_at(&f->insns, ii); diff --git a/src/interp.c b/src/interp.c index 894be30..7fdd4b1 100644 --- a/src/interp.c +++ b/src/interp.c @@ -258,7 +258,7 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa }; } -top: +top:; union interp_ret retval = {.i = 0}; union fpr { double d; @@ -1019,7 +1019,7 @@ top: case EJIT_UINT16: gpr[i.r2] = params[i.r0].u16; break; case EJIT_UINT32: gpr[i.r2] = params[i.r0].u32; break; case EJIT_UINT64: gpr[i.r2] = params[i.r0].u64; break; - case EJIT_POINTER: gpr[i.r2] = (int64_t)params[i.r0].p; break; + case EJIT_POINTER: gpr[i.r2] = (int64_t)(intptr_t)params[i.r0].p; break; default: abort(); } DISPATCH(); @@ -1075,7 +1075,7 @@ top: DISPATCH(); DO(TAILR); - f = (struct ejit_func *)gpr[i.r1]; + f = (struct ejit_func *)(intptr_t)gpr[i.r1]; /** @todo we could potentially just interpret the func as a fallback * instead of aborting here, but this is good enough for now */ @@ -1089,22 +1089,22 @@ top: DISPATCH(); DO(CALLR_I); - retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL); + retval = ejit_run((struct ejit_func *)(intptr_t)gpr[i.r1], argc, args, NULL); argc = 0; DISPATCH(); DO(CALLR_L); - retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL); + retval = ejit_run((struct ejit_func *)(intptr_t)gpr[i.r1], argc, args, NULL); argc = 0; DISPATCH(); DO(CALLR_F); - retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL); + retval = ejit_run((struct ejit_func *)(intptr_t)gpr[i.r1], argc, args, NULL); argc = 0; DISPATCH(); DO(CALLR_D); - retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL); + retval = ejit_run((struct ejit_func *)(intptr_t)gpr[i.r1], argc, args, NULL); argc = 0; DISPATCH(); diff --git a/tests/makefile b/tests/makefile index 53115de..2328d0e 100644 --- a/tests/makefile +++ b/tests/makefile @@ -19,11 +19,6 @@ LTO ?= 0 LTOFLAGS != [ "$(LTO)" != "0" ] \ && echo "-flto=auto" -DEBUG ?= 1 -DEBUGFLAGS != [ "$(DEBUG)" != "0" ] \ - && echo "-DDEBUG=1" \ - || echo "-DNDEBUG=1" - OBFLAGS := -g WARNFLAGS := -Wall -Wextra INCLUDE_FLAGS := -I include diff --git a/tests/z_double_label.c b/tests/z_double_label.c new file mode 100644 index 0000000..4817d8c --- /dev/null +++ b/tests/z_double_label.c @@ -0,0 +1,38 @@ +#include <ejit/ejit.h> +#include <assert.h> +#include "do_jit.h" + +int main(int argc, char *argv[]) +{ + (void)argv; + bool do_jit = argc > 1; + struct ejit_func *f = ejit_create_func(EJIT_INT32, 0, NULL); + ejit_movi(f, EJIT_GPR(0), 0); + + struct ejit_reloc l1 = ejit_jmp(f); + struct ejit_label mid = ejit_label(f); + struct ejit_reloc l2 = ejit_jmp(f); + + /* patch relocs to same address with two separate labels. */ + ejit_patch(f, l1, ejit_label(f)); + ejit_patch(f, l2, ejit_label(f)); + + /* we came from the first jump, jump to the end */ + struct ejit_reloc end = ejit_beqi(f, EJIT_GPR(0), 1); + + /* set r0 to 1 to indicate that we've done the first jump */ + ejit_movi(f, EJIT_GPR(0), 1); + + /* jump in between the two jumps */ + ejit_patch(f, ejit_jmp(f), mid); + + ejit_patch(f, end, ejit_label(f)); + ejit_reti(f, 0); + + + ejit_select_compile_func(f, 1, 0, false, do_jit, true); + + assert(ejit_run_func_i(f, 0, NULL) == 0); + + ejit_destroy_func(f); +} |
