diff options
-rw-r--r-- | scripts/makefile | 6 | ||||
-rwxr-xr-x | scripts/select-compile | 1 | ||||
-rw-r--r-- | src/compile/compile.c | 248 | ||||
-rw-r--r-- | src/ejit.c | 1 | ||||
-rw-r--r-- | src/interp.c | 10 |
5 files changed, 218 insertions, 48 deletions
diff --git a/scripts/makefile b/scripts/makefile index bd02c98..5178359 100644 --- a/scripts/makefile +++ b/scripts/makefile @@ -68,13 +68,13 @@ libejit.a: $(EJIT_OBJS) examples: examples/loop examples/fib examples/matrix_mult examples/matrix_mult: examples/matrix_mult.c libejit.a - $(COMPILE_EJIT) examples/matrix_mult.c libejit.a -o $@ + $(COMPILE_EJIT) examples/matrix_mult.c libejit.a -o $@ -lm examples/loop: examples/loop.c libejit.a - $(COMPILE_EJIT) examples/loop.c libejit.a -o $@ + $(COMPILE_EJIT) examples/loop.c libejit.a -o $@ -lm examples/fib: examples/fib.c libejit.a - $(COMPILE_EJIT) examples/fib.c libejit.a -o $@ + $(COMPILE_EJIT) examples/fib.c libejit.a -o $@ -lm # might lint some common things twice .PHONY: diff --git a/scripts/select-compile b/scripts/select-compile index 38fc7b0..37c67a1 100755 --- a/scripts/select-compile +++ b/scripts/select-compile @@ -13,6 +13,7 @@ case "$ARCH" in mips64el) echo "$JIT" ;; aarch64) echo "$JIT" ;; mipsel) echo "$JIT" ;; + armhf) echo "$JIT" ;; amd64) echo "$JIT" ;; x86*) echo "$JIT" ;; *) echo "$NOJIT" ;; diff --git a/src/compile/compile.c b/src/compile/compile.c index dac8dfd..38c368f 100644 --- a/src/compile/compile.c +++ b/src/compile/compile.c @@ -1927,7 +1927,7 @@ static void compile_trampoline(struct ejit_func *f, jit_state_t *j) jit_leave_jit_abi(j, 0, 0, frame); jit_ret(j); /* should just forward the return value */ - f->direct_call = jit_address(j); + f->direct_call = jit_address_to_function_pointer(jit_address(j)); jit_patch_here(j, r); operands_destroy(&args); @@ -1939,6 +1939,44 @@ static void compile_trampoline(struct ejit_func *f, jit_state_t *j) } } +static void resolve_top_reloc(jit_state_t *j, struct relocs *relocs, struct addrs *addrs, size_t ii) +{ + assert(relocs_len(relocs) != 0); + + struct reloc_helper h = *relocs_back(relocs); + if (h.to >= ii) + return; + + jit_addr_t a = *addrs_at(addrs, h.to); + jit_reloc_t r = h.r; + + assert(a); + jit_patch_there(j, r, a); + relocs_pop(relocs); +} + +static void resolve_relocs(jit_state_t *j, struct relocs *relocs, struct addrs *addrs, size_t ii) +{ + foreach_vec(ri, *relocs) { + struct reloc_helper h = *relocs_at(relocs, ri); + if (h.to != ii) + continue; + + jit_addr_t a = *addrs_at(addrs, ii); + jit_reloc_t r = h.r; + + assert(a); + jit_patch_there(j, r, a); + + /* 'shift' down */ + if (ri != relocs_len(relocs) - 1) + *relocs_at(relocs, ri) = *relocs_back(relocs); + + assert(relocs_len(relocs) != 0); + relocs_shrink(relocs, relocs_len(relocs) - 1); + } +} + static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, size_t size) { @@ -1960,7 +1998,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, struct operands dst = operands_create(); struct operands direct = operands_create(); - struct relocs relocs = relocs_create(sizeof(struct reloc_helper)); + struct relocs relocs = relocs_create(); struct addrs addrs = addrs_create(); addrs_reserve(&addrs, insns_len(&f->insns)); @@ -1972,6 +2010,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, 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++; } } @@ -2122,43 +2161,179 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, case EJIT_OP_GTR_F: compile_gtr_f(f, j, i); break; case EJIT_OP_GTR_D: compile_gtr_d(f, j, i); break; - case EJIT_OP_BMCI: compile_bmci(f, j, i, &relocs); break; - case EJIT_OP_BMCR: compile_bmcr(f, j, i, &relocs); break; + case EJIT_OP_BMCI: { + compile_bmci(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BMCR: { + compile_bmcr(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BMSI: { + compile_bmsi(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BMSR: { + compile_bmsr(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BEQR: { + compile_beqr(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BEQI: { + compile_beqi(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BEQR_F: { + compile_beqr_f(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BEQR_D: { + compile_beqr_d(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BNER: { + compile_bner(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BNEI: { + compile_bnei(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BNER_F: { + compile_bner_f(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BNER_D: { + compile_bner_d(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } - case EJIT_OP_BMSI: compile_bmsi(f, j, i, &relocs); break; - case EJIT_OP_BMSR: compile_bmsr(f, j, i, &relocs); break; + case EJIT_OP_BGER: { + compile_bger(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } - case EJIT_OP_BEQR: compile_beqr(f, j, i, &relocs); break; - case EJIT_OP_BEQI: compile_beqi(f, j, i, &relocs); break; - case EJIT_OP_BEQR_F: compile_beqr_f(f, j, i, &relocs); break; - case EJIT_OP_BEQR_D: compile_beqr_d(f, j, i, &relocs); break; + case EJIT_OP_BGER_U: { + compile_bger_u(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BGEI: { + compile_bgei(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BGEI_U: { + compile_bgei_u(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } - case EJIT_OP_BNER: compile_bner(f, j, i, &relocs); break; - case EJIT_OP_BNEI: compile_bnei(f, j, i, &relocs); break; - case EJIT_OP_BNER_F: compile_bner_f(f, j, i, &relocs); break; - case EJIT_OP_BNER_D: compile_bner_d(f, j, i, &relocs); break; + case EJIT_OP_BGER_F: { + compile_bger_f(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } - case EJIT_OP_BGER: compile_bger(f, j, i, &relocs); break; - case EJIT_OP_BGER_U: compile_bger_u(f, j, i, &relocs); break; - case EJIT_OP_BGEI: compile_bgei(f, j, i, &relocs); break; - case EJIT_OP_BGEI_U: compile_bgei_u(f, j, i, &relocs); break; - case EJIT_OP_BGER_F: compile_bger_f(f, j, i, &relocs); break; - case EJIT_OP_BGER_D: compile_bger_d(f, j, i, &relocs); break; + case EJIT_OP_BGER_D: { + compile_bger_d(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } - case EJIT_OP_BGTR: compile_bgtr(f, j, i, &relocs); break; - case EJIT_OP_BGTR_U: compile_bgtr_u(f, j, i, &relocs); break; - case EJIT_OP_BGTI: compile_bgti(f, j, i, &relocs); break; - case EJIT_OP_BGTI_U: compile_bgti_u(f, j, i, &relocs); break; - case EJIT_OP_BGTR_F: compile_bgtr_f(f, j, i, &relocs); break; - case EJIT_OP_BGTR_D: compile_bgtr_d(f, j, i, &relocs); break; + case EJIT_OP_BGTR: { + compile_bgtr(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } - case EJIT_OP_BLEI: compile_blei(f, j, i, &relocs); break; - case EJIT_OP_BLEI_U: compile_blei_u(f, j, i, &relocs); break; + case EJIT_OP_BGTR_U: { + compile_bgtr_u(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } - case EJIT_OP_BLTI: compile_blti(f, j, i, &relocs); break; - case EJIT_OP_BLTI_U: compile_blti_u(f, j, i, &relocs); break; + case EJIT_OP_BGTI: { + compile_bgti(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } - case EJIT_OP_JMP: compile_jmp(f, j, i, &relocs); break; + case EJIT_OP_BGTI_U: { + compile_bgti_u(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BGTR_F: { + compile_bgtr_f(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BGTR_D: { + compile_bgtr_d(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BLEI: { + compile_blei(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BLEI_U: { + compile_blei_u(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BLTI: { + compile_blti(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BLTI_U: { + compile_blti_u(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_JMP: { + compile_jmp(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } case EJIT_OP_ARG_I: { jit_operand_t type = jit_operand_imm(JIT_OPERAND_ABI_WORD, i.r1); @@ -2420,14 +2595,7 @@ calli: } } - foreach_vec(ri, relocs) { - struct reloc_helper h = *relocs_at(&relocs, ri); - jit_addr_t a = *addrs_at(&addrs, h.to); - jit_reloc_t r = h.r; - - assert(a); - jit_patch_there(j, r, a); - } + assert(relocs_len(&relocs) == 0); operands_destroy(&src); operands_destroy(&dst); @@ -2435,7 +2603,7 @@ calli: relocs_destroy(&relocs); addrs_destroy(&addrs); - if (jit_end(j, &size)) + if ((f->extern_call = jit_end(j, &size))) return 0; return size; @@ -345,6 +345,7 @@ struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc, f->fpr = fpr_stats_create(); f->arena = NULL; f->direct_call = NULL; + f->extern_call = NULL; f->size = 0; f->prio = 1; f->use_64 = false; diff --git a/src/interp.c b/src/interp.c index 049498a..e7be77b 100644 --- a/src/interp.c +++ b/src/interp.c @@ -227,24 +227,24 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa assert(f->size && "trying to run a function that hasn't been compiled"); - if (f->arena) { + if (f->extern_call) { if (f->rtype == EJIT_INT64 || f->rtype == EJIT_UINT64) return (union interp_ret){ - .i = ((ejit_escape_l_t)f->arena)(paramc, params) + .i = ((ejit_escape_l_t)f->extern_call)(paramc, params) }; if (f->rtype == EJIT_DOUBLE) return (union interp_ret){ - .f = ((ejit_escape_d_t)f->arena)(paramc, params) + .f = ((ejit_escape_d_t)f->extern_call)(paramc, params) }; if (f->rtype == EJIT_FLOAT) return (union interp_ret){ - .f = ((ejit_escape_f_t)f->arena)(paramc, params) + .f = ((ejit_escape_f_t)f->extern_call)(paramc, params) }; return (union interp_ret){ - .i = ((ejit_escape_i_t)f->arena)(paramc, params) + .i = ((ejit_escape_i_t)f->extern_call)(paramc, params) }; } |