diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-10-22 17:40:09 +0300 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-10-22 17:43:44 +0300 |
commit | 7f7b22674ed8e9633cd0e47662508c3641e9f967 (patch) | |
tree | 6e692c9ec8f6cb0672f626d5be54601ec23aef63 | |
parent | 60a53db87421667a268f60b58c5a02eebb289d6b (diff) | |
download | ejit-7f7b22674ed8e9633cd0e47662508c3641e9f967.tar.gz ejit-7f7b22674ed8e9633cd0e47662508c3641e9f967.zip |
use type-specific vectors instead of generic ones
+ An attempt at speeding up function calls in the interpreted mode
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | examples/fib.c | 84 | ||||
-rw-r--r-- | examples/loop.c (renamed from examples/main.c) | 4 | ||||
-rw-r--r-- | scripts/makefile | 9 | ||||
-rw-r--r-- | src/common.h | 35 | ||||
-rw-r--r-- | src/compile/compile.c | 223 | ||||
-rw-r--r-- | src/ejit.c | 127 | ||||
-rw-r--r-- | src/interp.c | 48 | ||||
-rw-r--r-- | src/vec.h | 83 |
9 files changed, 380 insertions, 236 deletions
@@ -4,5 +4,6 @@ docs/output build ejit.o test-* -examples/exec +examples/loop +examples/fib examples/*.d diff --git a/examples/fib.c b/examples/fib.c new file mode 100644 index 0000000..fe2b215 --- /dev/null +++ b/examples/fib.c @@ -0,0 +1,84 @@ +#include <stdio.h> +#include <time.h> + +#include "../include/ejit/ejit.h" + +struct ejit_func *compile() +{ + struct ejit_operand args[1] = { + EJIT_OPERAND_GPR(0, EJIT_INT64) /* loc 0 contains n */ + }; + struct ejit_func *f = ejit_create_func(EJIT_INT64, 1, args); + struct ejit_reloc recurse = ejit_bgti(f, EJIT_GPR(0), 2); /* n <= 2 */ + ejit_reti(f, 1); + + struct ejit_label label = ejit_label(f); + ejit_patch(f, recurse, label); + + /* fib(n - 1) */ + ejit_subi(f, EJIT_GPR(0), EJIT_GPR(0), 1); + struct ejit_operand arg[1] = { + EJIT_OPERAND_GPR(0, EJIT_INT64) + }; + ejit_calli(f, f, 1, arg); + ejit_retval(f, EJIT_GPR(1)); /* loc 1 contains temp result */ + + /* fib(n - 2) */ + ejit_subi(f, EJIT_GPR(0), EJIT_GPR(0), 1); + ejit_calli(f, f, 1, arg); + ejit_retval(f, EJIT_GPR(0)); /* loc 0 now contains second temp result */ + + ejit_addr(f, EJIT_GPR(0), EJIT_GPR(0), EJIT_GPR(1)); /* add results */ + ejit_retr(f, EJIT_GPR(0)); + + bool try_jit = true; +#ifdef NOJIT + try_jit = false; +#endif + + /* the highest location we used was 1, so we need to request 2 locations + * for general purpose registers in total. No floating point registers, + * so 0. */ + ejit_select_compile_func(f, 2, 0, true, try_jit); + return f; +} + +int main(int argc, char *argv[]) +{ + if(argc != 3){ + fprintf(stderr, "Usage: %s compile_num loop_num\n", argv[0]); + return -1; + } + + size_t compile_num = strtoull(argv[1], 0, 0); + struct ejit_func **info = calloc(compile_num, sizeof(struct ejit_func *)); + + clock_t t = clock(); + for(size_t i = 0; i < compile_num; ++i){ + info[i] = compile(); + } + t = clock() - t; + + double compile_time_total = ((double)t) / CLOCKS_PER_SEC; + double compile_time_one = compile_time_total / compile_num; + printf("Compilation for n = %lu took %fs (1/%f).\n", + compile_num, compile_time_total, compile_time_one); + + size_t run_num = strtoull(argv[2], 0, 0); + t = clock(); + struct ejit_arg arg[1] = { + (struct ejit_arg){.type = EJIT_INT64, .l = run_num} + }; + size_t result = ejit_run_func(info[0], 1, arg); + t = clock() - t; + + double run_time_total = ((double)t) / CLOCKS_PER_SEC; + printf("Running loop for n = %lu took %fs with res %lu\n", + run_num, run_time_total, result); + + for(size_t i = 0; i < compile_num; ++i) + ejit_destroy_func(info[i]); + + free(info); + return 0; +} diff --git a/examples/main.c b/examples/loop.c index 1677023..f4f66ae 100644 --- a/examples/main.c +++ b/examples/loop.c @@ -16,14 +16,14 @@ int main() ejit_addr(f, EJIT_GPR(2), EJIT_GPR(2), EJIT_GPR(3)); // add 1 to i struct ejit_reloc r = ejit_bltr(f, EJIT_GPR(2), EJIT_GPR(1)); // if i is less than limit - ejit_ret(f, EJIT_GPR(0)); // return total + ejit_retr(f, EJIT_GPR(0)); // return total ejit_patch(f, r, l); /* the highest location we used was 3, so we need to request 4 locations * for general purpose registers in total. No floating point registers, * so 0. */ - ejit_compile_func(f, 4, 0); + ejit_compile_func(f, 4, 0, true); long result = ejit_run_func(f, 0, NULL); // no args so this is fine printf("%ld\n", result); diff --git a/scripts/makefile b/scripts/makefile index b8978f6..c1de16e 100644 --- a/scripts/makefile +++ b/scripts/makefile @@ -57,9 +57,12 @@ COMPILE_EJIT = $(COMPILE) $(EJIT_FLAGS) ejit.o: $(EJIT_OBJS) ld -relocatable $(EJIT_OBJS) -o $@ -examples: examples/exec -examples/exec: examples/main.c ejit.o - $(COMPILE_EJIT) examples/main.c ejit.o -o $@ +examples: examples/loop examples/fib +examples/loop: examples/loop.c ejit.o + $(COMPILE_EJIT) examples/loop.c ejit.o -o $@ + +examples/fib: examples/fib.c ejit.o + $(COMPILE_EJIT) examples/fib.c ejit.o -o $@ # might lint some common things twice .PHONY: diff --git a/src/common.h b/src/common.h index b7038d8..eb91409 100644 --- a/src/common.h +++ b/src/common.h @@ -1,7 +1,23 @@ #ifndef EJIT_COMMON_H #define EJIT_COMMON_H +#include <ejit/ejit.h> #include <stdbool.h> + +#define VEC_TYPE struct ejit_arg +#define VEC_NAME args +#include "vec.h" + +#define VEC_TYPE int64_t +#define VEC_NAME gprs +#include "vec.h" + +#define VEC_TYPE double +#define VEC_NAME fprs +#include "vec.h" + +#define VEC_TYPE size_t +#define VEC_NAME labels #include "vec.h" enum ejit_opcode { @@ -228,9 +244,13 @@ struct ejit_insn { }; }; +#define VEC_TYPE struct ejit_insn +#define VEC_NAME insns +#include "vec.h" + struct ejit_func { - struct vec insns; - struct vec labels; + struct insns insns; + struct labels labels; enum ejit_type rtype; size_t gpr; @@ -247,9 +267,9 @@ union interp_ret { }; struct interp_state { - struct vec gprs; - struct vec fprs; - struct vec args; + struct gprs gprs; + struct fprs fprs; + struct args args; }; union interp_ret ejit_interp(struct ejit_func *f, size_t argc, @@ -258,7 +278,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, void ***labels_wb); int64_t ejit_run_interp(struct ejit_func *f, size_t argc, - struct ejit_arg args[argc], struct interp_state *state); + struct ejit_arg args[static argc], struct interp_state *state); + +double ejit_run_interp_f(struct ejit_func *f, size_t argc, + struct ejit_arg args[static argc], struct interp_state *state); bool ejit_compile(struct ejit_func *f, bool use_64); diff --git a/src/compile/compile.c b/src/compile/compile.c index 929dfa1..804a29f 100644 --- a/src/compile/compile.c +++ b/src/compile/compile.c @@ -2,6 +2,23 @@ #include "../../deps/lightening/lightening/lightening.c" #include "../common.h" +#define VEC_TYPE jit_operand_t +#define VEC_NAME operands +#include "../vec.h" + +struct reloc_helper { + jit_reloc_t r; + size_t to; +}; + +#define VEC_TYPE struct reloc_helper +#define VEC_NAME relocs +#include "../vec.h" + +#define VEC_TYPE jit_addr_t +#define VEC_NAME addrs +#include "../vec.h" + static void *alloc_arena(size_t size) { return mmap(NULL, size, @@ -44,11 +61,6 @@ static jit_off_t stack_loc_f(struct ejit_func *f, size_t l) } -struct reloc_helper { - jit_reloc_t r; - size_t to; -}; - static jit_gpr_t getloc(struct ejit_func *f, jit_state_t *j, size_t l, size_t i) { (void)(f); @@ -131,9 +143,9 @@ static void putloc_d(struct ejit_func *f, jit_state_t *j, size_t l, jit_fpr_t r) jit_stxi_d(j, stack_loc_f(f, l), JIT_SP, r); } -static void compile_label(jit_state_t *j, size_t ii, struct vec *labels) +static void compile_label(jit_state_t *j, size_t ii, struct addrs *addrs) { - vect_at(jit_addr_t, *labels, ii) = jit_address(j); + *addrs_at(addrs, ii) = jit_address(j); } static void compile_movi(struct ejit_func *f, jit_state_t *j, @@ -1218,280 +1230,280 @@ static void compile_gtr_f(struct ejit_func *f, jit_state_t *j, } static void compile_bmci(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bmci(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bmcr(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bmcr(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bmsi(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bmsi(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bmsr(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bmsr(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_beqi(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_beqi(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_beqr(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_beqr(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_beqr_f(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_f(f, j, i.r1, 0); jit_fpr_t r2 = getloc_f(f, j, i.r2, 1); jit_reloc_t r = jit_beqr_f(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_beqr_d(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_d(f, j, i.r1, 0); jit_fpr_t r2 = getloc_d(f, j, i.r2, 1); jit_reloc_t r = jit_beqr_d(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bnei(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bnei(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bner(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bner(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bner_f(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_f(f, j, i.r1, 0); jit_fpr_t r2 = getloc_f(f, j, i.r2, 1); jit_reloc_t r = jit_bner_f(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bner_d(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_d(f, j, i.r1, 0); jit_fpr_t r2 = getloc_d(f, j, i.r2, 1); jit_reloc_t r = jit_bner_d(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bger(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bger(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bger_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bger_u(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgei(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bgei(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgei_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bgei_u(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bger_f(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_f(f, j, i.r1, 0); jit_fpr_t r2 = getloc_f(f, j, i.r2, 1); jit_reloc_t r = jit_bger_f(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bger_d(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_d(f, j, i.r1, 0); jit_fpr_t r2 = getloc_d(f, j, i.r2, 1); jit_reloc_t r = jit_bger_d(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgtr(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bgtr(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgtr_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bgtr_u(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgti(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bgti(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgti_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bgti_u(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgtr_f(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_f(f, j, i.r1, 0); jit_fpr_t r2 = getloc_f(f, j, i.r2, 1); jit_reloc_t r = jit_bgtr_f(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgtr_d(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_d(f, j, i.r1, 0); jit_fpr_t r2 = getloc_d(f, j, i.r2, 1); jit_reloc_t r = jit_bgtr_d(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_blei(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_blei(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_blei_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_blei_u(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_blti(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_blti(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_blti_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_blti_u(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_jmp(struct ejit_func *f, jit_state_t *j, struct ejit_insn i, - struct vec *relocs) + struct relocs *relocs) { (void)(f); jit_reloc_t r = jit_jmp(j); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_retval(struct ejit_func *f, jit_state_t *j, @@ -1573,23 +1585,23 @@ static jit_off_t type_offset(struct ejit_insn i) type); } -static void fixup_operands(struct vec *operands, size_t fixup) +static void fixup_operands(struct operands *operands, size_t fixup) { foreach_vec(i, *operands) { - jit_operand_t op = vect_at(jit_operand_t, *operands, i); + jit_operand_t op = *operands_at(operands, i); if (op.kind != JIT_OPERAND_KIND_MEM) continue; op.loc.mem.offset += fixup; - vect_at(jit_operand_t, *operands, i) = op; + *operands_at(operands, i) = op; } } -static void compile_imm_call(jit_state_t *j, struct vec *src, struct vec *dst, +static void compile_imm_call(jit_state_t *j, struct operands *src, struct operands *dst, void *addr, size_t argc, jit_operand_t args[argc]) { /* each move is type + arg, so twofold */ - size_t movec = vec_len(src) / 2; + size_t movec = operands_len(src) / 2; size_t fixup = jit_align_stack(j, movec * sizeof(struct ejit_arg)); fixup_operands(src, fixup); /* note, do not fix up destination! */ @@ -1598,8 +1610,8 @@ static void compile_imm_call(jit_state_t *j, struct vec *src, struct vec *dst, jit_calli(j, addr, argc, args); jit_shrink_stack(j, fixup); - vec_reset(src); - vec_reset(dst); + operands_reset(src); + operands_reset(dst); } static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, @@ -1618,24 +1630,24 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, size_t stack = jit_align_stack(j, stack_size(f)); - struct vec src = vec_create(sizeof(jit_operand_t)); - struct vec dst = vec_create(sizeof(jit_operand_t)); + struct operands src = operands_create(); + struct operands dst = operands_create(); - struct vec relocs = vec_create(sizeof(struct reloc_helper)); - struct vec labels = vec_create(sizeof(jit_addr_t)); - vec_reserve(&labels, vec_len(&f->insns)); + struct relocs relocs = relocs_create(sizeof(struct reloc_helper)); + struct addrs addrs = addrs_create(); + addrs_reserve(&addrs, insns_len(&f->insns)); size_t label = 0; foreach_vec(ii, f->insns) { /* if we've hit a label, add it to our vector of label addresses */ - if (label < vec_len(&f->labels)) { - if (vect_at(size_t, f->labels, label) == ii) { - compile_label(j, ii, &labels); + if (label < labels_len(&f->labels)) { + if (*labels_at(&f->labels, label) == ii) { + compile_label(j, ii, &addrs); label++; } } - struct ejit_insn i = vect_at(struct ejit_insn, f->insns, ii); + struct ejit_insn i = *insns_at(&f->insns, ii); switch (i.op) { case MOVR: compile_movr(f, j, i); break; case MOVR_F: compile_movr_f(f, j, i); break; @@ -1832,8 +1844,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, JIT_SP, stack_loc(i.r2)); } - vec_append(&src, &type); - vec_append(&src, &arg); + operands_append(&src, type); + operands_append(&src, arg); jit_operand_t to[2] = { jit_operand_mem(JIT_OPERAND_ABI_WORD, JIT_SP, @@ -1842,8 +1854,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, arg_offset(i)) }; - vec_append(&dst, &to[0]); - vec_append(&dst, &to[1]); + operands_append(&dst, to[0]); + operands_append(&dst, to[1]); break; } @@ -1864,8 +1876,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, stack_loc_f(f, i.r2)); } - vec_append(&src, &type); - vec_append(&src, &arg); + operands_append(&src, type); + operands_append(&src, arg); jit_operand_t to[2] = { jit_operand_mem(JIT_OPERAND_ABI_WORD, JIT_SP, @@ -1874,15 +1886,15 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, arg_offset(i)) }; - vec_append(&dst, &to[0]); - vec_append(&dst, &to[1]); + operands_append(&dst, to[0]); + operands_append(&dst, to[1]); break; } case ESCAPEI: { jit_operand_t args[2] = { jit_operand_imm(JIT_OPERAND_ABI_WORD, - vec_len(&src) / 2), + operands_len(&src) / 2), jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_SP) }; compile_imm_call(j, &src, &dst, (void *)i.o, 2, args); @@ -1892,7 +1904,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, case ESCAPEI_F: { jit_operand_t args[2] = { jit_operand_imm(JIT_OPERAND_ABI_WORD, - vec_len(&src) / 2), + operands_len(&src) / 2), jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_SP) }; compile_imm_call(j, &src, &dst, (void *)i.o, 2, args); @@ -1903,7 +1915,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, jit_operand_t args[3] = { jit_operand_imm(JIT_OPERAND_ABI_POINTER, i.o), jit_operand_imm(JIT_OPERAND_ABI_WORD, - vec_len(&src) / 2), + operands_len(&src) / 2), jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_SP) }; compile_imm_call(j, &src, &dst, ejit_run_func, 3, args); @@ -1978,8 +1990,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, stack_loc_f(f, i.r2)); } - vec_append(&src, &from); - vec_append(&dst, &to); + operands_append(&src, from); + operands_append(&dst, to); break; } @@ -2003,17 +2015,17 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, stack_loc(i.r2)); } - vec_append(&src, &from); - vec_append(&dst, &to); + operands_append(&src, from); + operands_append(&dst, to); break; } case START: { /* parameters should be done by now */ - jit_move_operands(j, dst.buf, src.buf, vec_len(&src)); + jit_move_operands(j, dst.buf, src.buf, operands_len(&src)); /* reuse for arguments */ - vec_reset(&dst); - vec_reset(&src); + operands_reset(&dst); + operands_reset(&src); break; } @@ -2022,19 +2034,18 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, } foreach_vec(ri, relocs) { - struct reloc_helper h = vect_at(struct reloc_helper, relocs, - ri); - jit_addr_t a = vect_at(jit_addr_t, labels, h.to); + 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); } - vec_destroy(&src); - vec_destroy(&dst); - vec_destroy(&relocs); - vec_destroy(&labels); + operands_destroy(&src); + operands_destroy(&dst); + relocs_destroy(&relocs); + addrs_destroy(&addrs); if (jit_end(j, &size)) return 0; @@ -9,35 +9,35 @@ static void emit_insn_i(struct ejit_func *f, enum ejit_opcode op, size_t r0, size_t r1, int64_t o) { struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .o = o}; - vec_append(&f->insns, &i); + insns_append(&f->insns, i); } static void emit_insn_r(struct ejit_func *f, enum ejit_opcode op, size_t r0, size_t r1, size_t r2) { struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .r2 = r2}; - vec_append(&f->insns, &i); + insns_append(&f->insns, i); } static void emit_insn_p(struct ejit_func *f, enum ejit_opcode op, size_t r0, size_t r1, void *p) { struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .p = p}; - vec_append(&f->insns, &i); + insns_append(&f->insns, i); } static void emit_insn_f(struct ejit_func *f, enum ejit_opcode op, size_t r0, size_t r1, float d) { struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .f = d}; - vec_append(&f->insns, &i); + insns_append(&f->insns, i); } static void emit_insn_d(struct ejit_func *f, enum ejit_opcode op, size_t r0, size_t r1, double d) { struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .d = d}; - vec_append(&f->insns, &i); + insns_append(&f->insns, i); } struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc, @@ -48,8 +48,8 @@ struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc, f->rtype = rtype; - f->insns = vec_create(sizeof(struct ejit_insn)); - f->labels = vec_create(sizeof(size_t)); + f->insns = insns_create(); + f->labels = labels_create(); f->arena = NULL; f->size = 0; @@ -98,11 +98,11 @@ void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr, /* just get labels, don't actually run anything yet */ ejit_interp(f, 0, NULL, NULL, false, &labels); foreach_vec(ii, f->insns) { - struct ejit_insn i = vect_at(struct ejit_insn, f->insns, ii); + struct ejit_insn i = *insns_at(&f->insns, ii); void *addr = labels[i.op]; assert(addr); i.addr = addr; - vect_at(struct ejit_insn, f->insns, ii) = i; + *insns_at(&f->insns, ii) = i; } /* doesn't really matter what we put here as long as it isn't 0 */ @@ -114,24 +114,24 @@ void ejit_destroy_func(struct ejit_func *f) if (f->arena) munmap(f->arena, f->size); - vec_destroy(&f->insns); - vec_destroy(&f->labels); + insns_destroy(&f->insns); + labels_destroy(&f->labels); free(f); } struct ejit_label ejit_label(struct ejit_func *f) { - size_t addr = vec_len(&f->insns); - vec_append(&f->labels, &addr); + size_t addr = insns_len(&f->insns); + labels_append(&f->labels, addr); return (struct ejit_label){.addr = addr}; } void ejit_patch(struct ejit_func *f, struct ejit_reloc r, struct ejit_label l) { - struct ejit_insn i = vect_at(struct ejit_insn, f->insns, r.insn); + struct ejit_insn i = *insns_at(&f->insns, r.insn); /** @todo some assert that checks the opcode? */ i.r0 = l.addr; - vect_at(struct ejit_insn, f->insns, r.insn) = i; + *insns_at(&f->insns, r.insn) = i; } void ejit_calli(struct ejit_func *s, struct ejit_func *f, size_t argc, @@ -952,14 +952,14 @@ void ejit_truncr_f_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BNER, 0, r0.r, r1.r); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BNEI, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } @@ -967,7 +967,7 @@ struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, int64_t o) struct ejit_reloc ejit_bner_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BNER_F, 0, r0.f, r1.f); return (struct ejit_reloc){.insn = addr}; } @@ -975,7 +975,7 @@ struct ejit_reloc ejit_bner_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_reloc ejit_bner_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BNER_D, 0, r0.f, r1.f); return (struct ejit_reloc){.insn = addr}; } @@ -983,14 +983,14 @@ struct ejit_reloc ejit_bner_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_reloc ejit_beqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BEQR, 0, r0.r, r1.r); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BEQI, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } @@ -998,7 +998,7 @@ struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, int64_t o) struct ejit_reloc ejit_beqr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BEQR_F, 0, r0.f, r1.f); return (struct ejit_reloc){.insn = addr}; } @@ -1006,7 +1006,7 @@ struct ejit_reloc ejit_beqr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_reloc ejit_beqr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BEQR_D, 0, r0.f, r1.f); return (struct ejit_reloc){.insn = addr}; } @@ -1014,7 +1014,7 @@ struct ejit_reloc ejit_beqr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_reloc ejit_bger(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGER, 0, r0.r, r1.r); return (struct ejit_reloc){.insn = addr}; } @@ -1022,7 +1022,7 @@ struct ejit_reloc ejit_bger(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bger_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGER_U, 0, r0.r, r1.r); return (struct ejit_reloc){.insn = addr}; } @@ -1030,14 +1030,14 @@ struct ejit_reloc ejit_bger_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bger_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGER_F, 0, r0.f, r1.f); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_bgei(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BGEI, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } @@ -1045,7 +1045,7 @@ struct ejit_reloc ejit_bgei(struct ejit_func *s, struct ejit_gpr r0, int64_t o) struct ejit_reloc ejit_bgei_u(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BGEI_U, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } @@ -1053,7 +1053,7 @@ struct ejit_reloc ejit_bgei_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bler(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGER, 0, r1.r, r0.r); return (struct ejit_reloc){.insn = addr}; } @@ -1061,7 +1061,7 @@ struct ejit_reloc ejit_bler(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bler_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGER_U, 0, r1.r, r0.r); return (struct ejit_reloc){.insn = addr}; } @@ -1069,7 +1069,7 @@ struct ejit_reloc ejit_bler_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bler_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGER_F, 0, r1.f, r0.f); return (struct ejit_reloc){.insn = addr}; } @@ -1077,14 +1077,14 @@ struct ejit_reloc ejit_bler_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_reloc ejit_bler_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGER_D, 0, r1.f, r0.f); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_blei(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BLEI, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } @@ -1092,14 +1092,14 @@ struct ejit_reloc ejit_blei(struct ejit_func *s, struct ejit_gpr r0, int64_t o) struct ejit_reloc ejit_blei_u(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BLEI_U, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_bgti(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BGTI, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } @@ -1107,7 +1107,7 @@ struct ejit_reloc ejit_bgti(struct ejit_func *s, struct ejit_gpr r0, int64_t o) struct ejit_reloc ejit_bgti_u(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BGTI_U, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } @@ -1115,7 +1115,7 @@ struct ejit_reloc ejit_bgti_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bgtr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGTR, 0, r0.r, r1.r); return (struct ejit_reloc){.insn = addr}; } @@ -1123,7 +1123,7 @@ struct ejit_reloc ejit_bgtr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bgtr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGTR_U, 0, r0.r, r1.r); return (struct ejit_reloc){.insn = addr}; } @@ -1131,7 +1131,7 @@ struct ejit_reloc ejit_bgtr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bgtr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGTR_F, 0, r0.f, r1.f); return (struct ejit_reloc){.insn = addr}; } @@ -1139,7 +1139,7 @@ struct ejit_reloc ejit_bgtr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_reloc ejit_bgtr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGTR_D, 0, r0.f, r1.f); return (struct ejit_reloc){.insn = addr}; } @@ -1147,7 +1147,7 @@ struct ejit_reloc ejit_bgtr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGTR, 0, r1.r, r0.r); return (struct ejit_reloc){.insn = addr}; } @@ -1155,7 +1155,7 @@ struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bltr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGTR_U, 0, r1.r, r0.r); return (struct ejit_reloc){.insn = addr}; } @@ -1163,7 +1163,7 @@ struct ejit_reloc ejit_bltr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_reloc ejit_bltr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGTR_F, 0, r1.f, r0.f); return (struct ejit_reloc){.insn = addr}; } @@ -1171,14 +1171,14 @@ struct ejit_reloc ejit_bltr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_reloc ejit_bltr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_r(s, BGTR_D, 0, r1.f, r0.f); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_blti(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BLTI, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } @@ -1186,28 +1186,28 @@ struct ejit_reloc ejit_blti(struct ejit_func *s, struct ejit_gpr r0, int64_t o) struct ejit_reloc ejit_blti_u(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BLTI_U, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_jmp(struct ejit_func *s) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, JMP, 0, 0, 0); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_jmpr(struct ejit_func *s, struct ejit_gpr r0) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, JMPR, 0, r0.r, 0); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_bmci(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BMCI, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } @@ -1215,14 +1215,14 @@ struct ejit_reloc ejit_bmci(struct ejit_func *s, struct ejit_gpr r0, int64_t o) struct ejit_reloc ejit_bmcr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BMCR, 0, r0.r, r1.r); return (struct ejit_reloc){.insn = addr}; } struct ejit_reloc ejit_bmsi(struct ejit_func *s, struct ejit_gpr r0, int64_t o) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BMSI, 0, r0.r, o); return (struct ejit_reloc){.insn = addr}; } @@ -1230,7 +1230,7 @@ struct ejit_reloc ejit_bmsi(struct ejit_func *s, struct ejit_gpr r0, int64_t o) struct ejit_reloc ejit_bmsr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { - size_t addr = vec_len(&s->insns); + size_t addr = insns_len(&s->insns); emit_insn_i(s, BMSR, 0, r0.r, r1.r); return (struct ejit_reloc){.insn = addr}; } @@ -1238,17 +1238,17 @@ struct ejit_reloc ejit_bmsr(struct ejit_func *s, struct ejit_gpr r0, static struct interp_state create_interp_state() { struct interp_state state; - state.gprs = vec_create(sizeof(int64_t)); - state.fprs = vec_create(sizeof(double)); - state.args = vec_create(sizeof(struct ejit_arg)); + state.gprs = gprs_create(); + state.fprs = fprs_create(); + state.args = args_create(); return state; } static void destroy_interp_state(struct interp_state state) { - vec_destroy(&state.gprs); - vec_destroy(&state.fprs); - vec_destroy(&state.args); + gprs_destroy(&state.gprs); + fprs_destroy(&state.fprs); + args_destroy(&state.args); } long ejit_run_interp(struct ejit_func *f, size_t argc, @@ -1262,6 +1262,17 @@ long ejit_run_interp(struct ejit_func *f, size_t argc, return ejit_interp(f, argc, args, state, true, NULL).r; } +double ejit_run_interp_f(struct ejit_func *f, size_t argc, + struct ejit_arg args[argc], struct interp_state *state) +{ + assert(f->gpr && "trying to run a function that hasn't been compiled"); + assert(f->rtype == EJIT_VOID || ejit_int_type(f->rtype)); + if (f->arena) + return ((ejit_escape_f_t)f->arena)(argc, args); + + return ejit_interp(f, argc, args, state, true, NULL).d; +} + int64_t ejit_run_func(struct ejit_func *f, size_t argc, struct ejit_arg args[argc]) { diff --git a/src/interp.c b/src/interp.c index 5618564..01121e5 100644 --- a/src/interp.c +++ b/src/interp.c @@ -219,12 +219,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, return (union interp_ret){.r = 0}; } - size_t prev_gprs = vec_len(&state->gprs); - size_t prev_fprs = vec_len(&state->fprs); - size_t prev_argc = vec_len(&state->args); + size_t prev_gprs = gprs_len(&state->gprs); + size_t prev_fprs = fprs_len(&state->fprs); + size_t prev_argc = args_len(&state->args); - vec_reserve(&state->gprs, prev_gprs + f->gpr); - vec_reserve(&state->fprs, prev_fprs + f->fpr); + gprs_reserve(&state->gprs, prev_gprs + f->gpr); + fprs_reserve(&state->fprs, prev_fprs + f->fpr); union fpr { double d; @@ -964,12 +964,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, DO(ARG); struct ejit_arg a = ejit_build_arg(i.r1, gpr[i.r2]); - vec_append(&state->args, &a); + args_append(&state->args, a); DISPATCH(); DO(ARG_I); struct ejit_arg a = ejit_build_arg(i.r1, i.o); - vec_append(&state->args, &a); + args_append(&state->args, a); DISPATCH(); DO(ARG_F); @@ -979,7 +979,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, else a = ejit_build_arg_f(i.r1, fpr[i.r2].f); - vec_append(&state->args, &a); + args_append(&state->args, a); DISPATCH(); DO(ARG_FI); @@ -989,12 +989,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, else a = ejit_build_arg_f(i.r1, i.f); - vec_append(&state->args, &a); + args_append(&state->args, a); DISPATCH(); DO(CALLI); struct ejit_func *f = i.p; - size_t argc = vec_len(&state->args) - prev_argc; + size_t argc = args_len(&state->args) - prev_argc; struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) + prev_argc; @@ -1002,32 +1002,42 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, gpr = ((long *)state->gprs.buf) + prev_gprs; fpr = ((union fpr *)state->fprs.buf) + prev_fprs; - vec_shrink(&state->args, prev_argc); + args_shrink(&state->args, prev_argc); DISPATCH(); DO(CALLI_F); + struct ejit_func *f = i.p; + size_t argc = args_len(&state->args) - prev_argc; + struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) + + prev_argc; + + retval_f = ejit_run_interp_f(f, argc, args, state); + + gpr = ((long *)state->gprs.buf) + prev_gprs; + fpr = ((union fpr *)state->fprs.buf) + prev_fprs; + args_shrink(&state->args, prev_argc); DISPATCH(); DO(ESCAPEI); ejit_escape_t f = i.p; - size_t argc = vec_len(&state->args) - prev_argc; + size_t argc = args_len(&state->args) - prev_argc; struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) + prev_argc; retval = f(argc, args); - vec_shrink(&state->args, prev_argc); + args_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; + size_t argc = args_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); + args_shrink(&state->args, prev_argc); DISPATCH(); /* dispatch is technically unnecessary for returns, but keep it for @@ -1067,12 +1077,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc, #undef DO out_int: - vec_shrink(&state->gprs, prev_gprs); - vec_shrink(&state->fprs, prev_fprs); + gprs_shrink(&state->gprs, prev_gprs); + fprs_shrink(&state->fprs, prev_fprs); return (union interp_ret){.r = retval}; out_float: - vec_shrink(&state->gprs, prev_gprs); - vec_shrink(&state->fprs, prev_fprs); + gprs_shrink(&state->gprs, prev_gprs); + fprs_shrink(&state->fprs, prev_fprs); return (union interp_ret){.d = retval_f}; } @@ -1,99 +1,99 @@ -#ifndef VEC_H -#define VEC_H +#ifndef VEC_TYPE +#error "Need vector type" +#endif + +#ifndef VEC_NAME +#error "Need vector name" +#endif #include <stddef.h> #include <stdlib.h> #include <string.h> #include <assert.h> -struct vec { +#define UNDERSCORE2(a, b) a##_##b +#define UNDERSCORE(a, b) UNDERSCORE2(a, b) +#define VEC(n) UNDERSCORE(VEC_NAME, n) + + +#define VEC_STRUCT VEC_NAME +struct VEC_STRUCT { size_t n; size_t s; - size_t ns; - void *buf; + VEC_TYPE *buf; }; -#define foreach_vec(iter, v) \ - for (size_t iter = 0; iter < vec_len(&v); ++iter) - -#define vect_at(type, v, i) \ - *(type *)vec_at(&v, i) - -#define vect_append(type, v, e) \ - vec_append(&v, (type *)(e)) - -#define vect_back(type, v) \ - *(type *)vec_back(&v) +#ifndef VEC_H +#define VEC_H -#define vect_pop(type, v) \ - *(type *)vec_pop(&v) +#define foreach_vec(iter, v) \ + for (size_t iter = 0; iter < (v).n; ++iter) #define vec_uninit(v) \ (v.buf == NULL) +#endif -static inline struct vec vec_create(size_t ns) +static inline struct VEC_STRUCT VEC(create)() { const size_t s = 8; - return (struct vec) { + return (struct VEC_STRUCT) { .n = 0, .s = s, - .ns = ns, - .buf = malloc(s * ns), + .buf = malloc(s * sizeof(VEC_TYPE)), }; } -static inline size_t vec_len(struct vec *v) +static inline size_t VEC(len)(struct VEC_STRUCT *v) { return v->n; } -static inline void *vec_at(struct vec *v, size_t i) +static inline VEC_TYPE *VEC(at)(struct VEC_STRUCT *v, size_t i) { assert(i < v->n && "out of vector bounds"); - return v->buf + i * v->ns; + return &v->buf[i]; } -static inline void *vec_back(struct vec *v) +static inline VEC_TYPE *VEC(back)(struct VEC_STRUCT *v) { assert(v->n); - return v->buf + (v->n - 1) * v->ns; + return &v->buf[v->n - 1]; } -static inline void *vec_pop(struct vec *v) +static inline VEC_TYPE *VEC(pop)(struct VEC_STRUCT *v) { assert(v->n && "attempting to pop empty vector"); v->n--; - return v->buf + v->n * v->ns; + return &v->buf[v->n]; } -static inline void vec_append(struct vec *v, void *n) +static inline void VEC(append)(struct VEC_STRUCT *v, VEC_TYPE n) { v->n++; if (v->n >= v->s) { v->s *= 2; - v->buf = realloc(v->buf, v->s * v->ns); + v->buf = realloc(v->buf, v->s * sizeof(VEC_TYPE)); } - void *p = vec_at(v, v->n - 1); - memcpy(p, n, v->ns); + v->buf[v->n - 1] = n; } -static inline void vec_reset(struct vec *v) +static inline void VEC(reset)(struct VEC_STRUCT *v) { v->n = 0; } -static inline void vec_destroy(struct vec *v) { +static inline void VEC(destroy)(struct VEC_STRUCT *v) { free(v->buf); } typedef int (*vec_comp_t)(void *a, void *b); -static inline void vec_sort(struct vec *v, vec_comp_t comp) +static inline void VEC(sort)(struct VEC_STRUCT *v, vec_comp_t comp) { - qsort(v->buf, v->n, v->ns, (__compar_fn_t)comp); + qsort(v->buf, v->n, sizeof(VEC_TYPE), (__compar_fn_t)comp); } -static inline void vec_reserve(struct vec *v, size_t n) +static inline void VEC(reserve)(struct VEC_STRUCT *v, size_t n) { if (v->n >= n) return; @@ -101,14 +101,15 @@ static inline void vec_reserve(struct vec *v, size_t n) v->n = n; if (v->s < v->n) { v->s *= 2; - v->buf = realloc(v->buf, v->s * v->ns); + v->buf = realloc(v->buf, v->s * sizeof(VEC_TYPE)); } } -static inline void vec_shrink(struct vec *v, size_t n) +static inline void VEC(shrink)(struct VEC_STRUCT *v, size_t n) { assert(v->n >= n); v->n = n; } -#endif /* VEC_H */ +#undef VEC_TYPE +#undef VEC_NAME |