diff options
m--------- | deps/lightening | 0 | ||||
-rw-r--r-- | include/ejit/ejit.h | 6 | ||||
-rw-r--r-- | scripts/makefile | 6 | ||||
-rwxr-xr-x | scripts/select-compile | 1 | ||||
-rw-r--r-- | src/common.h | 6 | ||||
-rw-r--r-- | src/compile/compile.c | 294 | ||||
-rw-r--r-- | src/ejit.c | 31 | ||||
-rw-r--r-- | src/interp.c | 67 | ||||
-rw-r--r-- | tests/maxr_d.c | 28 | ||||
-rw-r--r-- | tests/maxr_f.c | 28 | ||||
-rw-r--r-- | tests/minr_d.c | 28 | ||||
-rw-r--r-- | tests/minr_f.c | 28 |
12 files changed, 449 insertions, 74 deletions
diff --git a/deps/lightening b/deps/lightening -Subproject 6421af4db1570a6a5fc3a15f3bcb2601d854ed0 +Subproject 8d59c872edc5a21e7dd78768b291d0c4d8136e4 diff --git a/include/ejit/ejit.h b/include/ejit/ejit.h index b4b20c1..965103c 100644 --- a/include/ejit/ejit.h +++ b/include/ejit/ejit.h @@ -872,6 +872,12 @@ void ejit_truncr_d_64(struct ejit_func *s, struct ejit_gpr r0, void ejit_sqrtr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1); void ejit_sqrtr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1); +void ejit_minr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2); +void ejit_minr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2); + +void ejit_maxr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2); +void ejit_maxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2); + struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1); struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0, 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/common.h b/src/common.h index 661220b..69f1441 100644 --- a/src/common.h +++ b/src/common.h @@ -145,6 +145,12 @@ enum ejit_opcode { EJIT_OP_SQRTR_F, EJIT_OP_SQRTR_D, + EJIT_OP_MINR_F, + EJIT_OP_MINR_D, + + EJIT_OP_MAXR_F, + EJIT_OP_MAXR_D, + EJIT_OP_EQR, EJIT_OP_NER, EJIT_OP_GTR, diff --git a/src/compile/compile.c b/src/compile/compile.c index dac8dfd..dcf662b 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,84 @@ 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 void compile_maxr_f(struct ejit_func *f, jit_state_t *j, + struct ejit_insn i) +{ + jit_fpr_t r0 = getfpr(f, i.r0, 0); + jit_fpr_t r1 = getloc_f(f, j, i.r1, 1); + jit_fpr_t r2 = getloc_f(f, j, i.r2, 2); + jit_maxr_f(j, r0, r1, r2); + putloc_f(f, j, i.r0, r0); +} + +static void compile_maxr_d(struct ejit_func *f, jit_state_t *j, + struct ejit_insn i) +{ + jit_fpr_t r0 = getfpr(f, i.r0, 0); + jit_fpr_t r1 = getloc_d(f, j, i.r1, 1); + jit_fpr_t r2 = getloc_d(f, j, i.r2, 2); + jit_maxr_d(j, r0, r1, r2); + putloc_d(f, j, i.r0, r0); +} + +static void compile_minr_f(struct ejit_func *f, jit_state_t *j, + struct ejit_insn i) +{ + jit_fpr_t r0 = getfpr(f, i.r0, 0); + jit_fpr_t r1 = getloc_f(f, j, i.r1, 1); + jit_fpr_t r2 = getloc_f(f, j, i.r2, 2); + jit_minr_f(j, r0, r1, r2); + putloc_f(f, j, i.r0, r0); +} + +static void compile_minr_d(struct ejit_func *f, jit_state_t *j, + struct ejit_insn i) +{ + jit_fpr_t r0 = getfpr(f, i.r0, 0); + jit_fpr_t r1 = getloc_d(f, j, i.r1, 1); + jit_fpr_t r2 = getloc_d(f, j, i.r2, 2); + jit_minr_d(j, r0, r1, r2); + putloc_d(f, j, i.r0, r0); +} + static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, size_t size) { @@ -1960,7 +2038,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 +2050,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++; } } @@ -2104,6 +2183,12 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, case EJIT_OP_SQRTR_F: compile_sqrtr_f(f, j, i); break; case EJIT_OP_SQRTR_D: compile_sqrtr_d(f, j, i); break; + case EJIT_OP_MINR_F: compile_minr_f(f, j, i); break; + case EJIT_OP_MINR_D: compile_minr_d(f, j, i); break; + + case EJIT_OP_MAXR_F: compile_maxr_f(f, j, i); break; + case EJIT_OP_MAXR_D: compile_maxr_d(f, j, i); break; + case EJIT_OP_EQR: compile_eqr(f, j, i); break; case EJIT_OP_EQR_F: compile_eqr_f(f, j, i); break; case EJIT_OP_EQR_D: compile_eqr_d(f, j, i); break; @@ -2122,43 +2207,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_BGER: { + compile_bger(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + 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_BGER_F: { + compile_bger_f(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_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); + resolve_top_reloc(j, &relocs, &addrs, ii); + break; + } + + case EJIT_OP_BGTR_U: { + compile_bgtr_u(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_BGTI: { + compile_bgti(f, j, i, &relocs); + resolve_top_reloc(j, &relocs, &addrs, ii); + 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_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_BGTR_D: { + compile_bgtr_d(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_BLEI: { + compile_blei(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_BLEI_U: { + compile_blei_u(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_BLTI: { + compile_blti(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_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); 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 +2641,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 +2649,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; @@ -458,7 +459,7 @@ void ejit_patch(struct ejit_func *f, struct ejit_reloc r, struct ejit_label l) void ejit_calli_i(struct ejit_func *s, struct ejit_func *f, size_t argc, const struct ejit_operand args[argc]) { - f->max_args = argc > f->max_args ? argc : f->max_args; + s->max_args = argc > s->max_args ? argc : s->max_args; check_operands(f, argc, args); for (size_t i = 0; i < argc; ++i) { @@ -478,7 +479,7 @@ void ejit_calli_l(struct ejit_func *s, struct ejit_func *f, size_t argc, const struct ejit_operand args[argc]) { s->use_64 = true; - f->max_args = argc > f->max_args ? argc : f->max_args; + s->max_args = argc > s->max_args ? argc : s->max_args; check_operands(f, argc, args); for (size_t i = 0; i < argc; ++i) { @@ -900,31 +901,37 @@ void ejit_ret(struct ejit_func *s) void ejit_retr(struct ejit_func *s, struct ejit_gpr r0) { + assert(s->rtype != EJIT_FLOAT && s->rtype != EJIT_DOUBLE); emit_insn_oxr(s, EJIT_OP_RETR, r0); } void ejit_retr_f(struct ejit_func *s, struct ejit_fpr f0) { + assert(s->rtype == EJIT_FLOAT); emit_insn_oxf(s, EJIT_OP_RETR_F, f0); } void ejit_retr_d(struct ejit_func *s, struct ejit_fpr f0) { + assert(s->rtype == EJIT_DOUBLE); emit_insn_oxf(s, EJIT_OP_RETR_D, f0); } void ejit_reti(struct ejit_func *s, int64_t i) { + assert(s->rtype != EJIT_FLOAT && s->rtype != EJIT_DOUBLE); emit_insn_oi(s, EJIT_OP_RETI, i); } void ejit_reti_f(struct ejit_func *s, float f) { + assert(s->rtype == EJIT_FLOAT); emit_insn_oF(s, EJIT_OP_RETI_F, f); } void ejit_reti_d(struct ejit_func *s, double f) { + assert(s->rtype == EJIT_DOUBLE); emit_insn_oD(s, EJIT_OP_RETI_D, f); } @@ -1381,6 +1388,26 @@ void ejit_sqrtr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) emit_insn_off(s, EJIT_OP_SQRTR_D, r0, r1); } +void ejit_minr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ + emit_insn_offf(s, EJIT_OP_MINR_F, r0, r1, r2); +} + +void ejit_minr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ + emit_insn_offf(s, EJIT_OP_MINR_D, r0, r1, r2); +} + +void ejit_maxr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ + emit_insn_offf(s, EJIT_OP_MAXR_F, r0, r1, r2); +} + +void ejit_maxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1, struct ejit_fpr r2) +{ + emit_insn_offf(s, EJIT_OP_MAXR_D, r0, r1, r2); +} + struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1) { diff --git a/src/interp.c b/src/interp.c index 049498a..6ef414d 100644 --- a/src/interp.c +++ b/src/interp.c @@ -150,6 +150,12 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa [EJIT_OP_SQRTR_F] = &&SQRTR_F, [EJIT_OP_SQRTR_D] = &&SQRTR_D, + [EJIT_OP_MINR_F] = &&MINR_F, + [EJIT_OP_MINR_D] = &&MINR_D, + + [EJIT_OP_MAXR_F] = &&MAXR_F, + [EJIT_OP_MAXR_D] = &&MAXR_D, + [EJIT_OP_BNER] = &&BNER, [EJIT_OP_BNEI] = &&BNEI, [EJIT_OP_BNER_F] = &&BNER_F, @@ -222,29 +228,29 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa if (!run) { *labels_wb = labels; - goto zero_out; + return (union interp_ret){.i = 0}; } 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) }; } @@ -256,9 +262,9 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa }; size_t argc = 0; - int64_t *gpr = alloca(sizeof(int64_t) * gpr_stats_len(&f->gpr)); - union fpr *fpr = alloca(sizeof(int64_t) * fpr_stats_len(&f->fpr)); - struct ejit_arg *args = alloca(sizeof(struct ejit_arg) * f->max_args); + int64_t gpr[gpr_stats_len(&f->gpr)]; + union fpr fpr[fpr_stats_len(&f->fpr)]; + struct ejit_arg args[f->max_args]; struct ejit_insn *insns = f->insns.buf; /* retval is kind of an unfortunate extra bit of state to keep track of, @@ -276,7 +282,7 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa DISPATCH(); DO(END); - goto zero_out; + return (union interp_ret){.i = 0}; DISPATCH(); DO(MOVI); @@ -791,6 +797,22 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa fpr[i.r0].f = sqrt(fpr[i.r1].f); DISPATCH(); + DO(MINR_F); + fpr[i.r0].f = fminf(fpr[i.r1].f, fpr[i.r2].f); + DISPATCH(); + + DO(MINR_D); + fpr[i.r0].d = fmin(fpr[i.r1].d, fpr[i.r2].d); + DISPATCH(); + + DO(MAXR_F); + fpr[i.r0].f = fmaxf(fpr[i.r1].f, fpr[i.r2].f); + DISPATCH(); + + DO(MAXR_D); + fpr[i.r0].d = fmax(fpr[i.r1].d, fpr[i.r2].d); + DISPATCH(); + DO(SQRTR_D); fpr[i.r0].d = sqrt(fpr[i.r1].d); DISPATCH(); @@ -1087,45 +1109,32 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa /* dispatch is technically unnecessary for returns, but keep it for * symmetry */ DO(RETR); - retval = gpr[i.r1]; - goto out_int; + return (union interp_ret){.i = gpr[i.r1]}; DISPATCH(); DO(RETI); - retval = i.o; - goto out_int; + return (union interp_ret){.i = i.o}; DISPATCH(); DO(RETR_F); - retval_f = fpr[i.r1].f; - goto out_float; + return (union interp_ret){.f = fpr[i.r1].f}; DISPATCH(); DO(RETR_D); - retval_f = fpr[i.r1].d; - goto out_float; + return (union interp_ret){.f = fpr[i.r1].d}; DISPATCH(); DO(RETI_F); - retval_f = i.f; - goto out_float; + return (union interp_ret){.f = i.f}; DISPATCH(); DO(RETI_D); - retval_f = i.d; - goto out_float; + return (union interp_ret){.f = i.d}; DISPATCH(); #undef DISPATCH #undef JUMP #undef DO -out_float: - return (union interp_ret){.f = retval_f}; - -out_int: - return (union interp_ret){.i = retval}; - -zero_out: return (union interp_ret){.i = 0}; } diff --git a/tests/maxr_d.c b/tests/maxr_d.c new file mode 100644 index 0000000..3e35665 --- /dev/null +++ b/tests/maxr_d.c @@ -0,0 +1,28 @@ +#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_operand operands[2] = { + EJIT_OPERAND_FPR(0, EJIT_TYPE(double)), + EJIT_OPERAND_FPR(1, EJIT_TYPE(double)) + }; + + struct ejit_func *f = ejit_create_func(EJIT_TYPE(double), 2, operands); + + ejit_maxr_d(f, EJIT_FPR(2), EJIT_FPR(0), EJIT_FPR(1)); + ejit_retr_d(f, EJIT_FPR(2)); + + ejit_select_compile_func(f, 0, 3, EJIT_USE64(double), do_jit, true); + + assert(erfd2(f, EJIT_ARG(42., double), EJIT_ARG(69., double) + ) == 69.); + + assert(erfd2(f, EJIT_ARG(-42., double), EJIT_ARG(-69., double) + ) == -42.); + + ejit_destroy_func(f); +} diff --git a/tests/maxr_f.c b/tests/maxr_f.c new file mode 100644 index 0000000..581f867 --- /dev/null +++ b/tests/maxr_f.c @@ -0,0 +1,28 @@ +#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_operand operands[2] = { + EJIT_OPERAND_FPR(0, EJIT_TYPE(float)), + EJIT_OPERAND_FPR(1, EJIT_TYPE(float)) + }; + + struct ejit_func *f = ejit_create_func(EJIT_TYPE(float), 2, operands); + + ejit_maxr_f(f, EJIT_FPR(2), EJIT_FPR(0), EJIT_FPR(1)); + ejit_retr_f(f, EJIT_FPR(2)); + + ejit_select_compile_func(f, 0, 3, EJIT_USE64(float), do_jit, true); + + assert(erff2(f, EJIT_ARG(42., float), EJIT_ARG(69., float) + ) == 69.); + + assert(erff2(f, EJIT_ARG(-42., float), EJIT_ARG(-69., float) + ) == -42.); + + ejit_destroy_func(f); +} diff --git a/tests/minr_d.c b/tests/minr_d.c new file mode 100644 index 0000000..d0fb7c8 --- /dev/null +++ b/tests/minr_d.c @@ -0,0 +1,28 @@ +#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_operand operands[2] = { + EJIT_OPERAND_FPR(0, EJIT_TYPE(double)), + EJIT_OPERAND_FPR(1, EJIT_TYPE(double)) + }; + + struct ejit_func *f = ejit_create_func(EJIT_TYPE(double), 2, operands); + + ejit_minr_d(f, EJIT_FPR(2), EJIT_FPR(0), EJIT_FPR(1)); + ejit_retr_d(f, EJIT_FPR(2)); + + ejit_select_compile_func(f, 0, 3, EJIT_USE64(double), do_jit, true); + + assert(erfd2(f, EJIT_ARG(42., double), EJIT_ARG(69., double) + ) == 42.); + + assert(erfd2(f, EJIT_ARG(-42., double), EJIT_ARG(-69., double) + ) == -69.); + + ejit_destroy_func(f); +} diff --git a/tests/minr_f.c b/tests/minr_f.c new file mode 100644 index 0000000..b02ec06 --- /dev/null +++ b/tests/minr_f.c @@ -0,0 +1,28 @@ +#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_operand operands[2] = { + EJIT_OPERAND_FPR(0, EJIT_TYPE(float)), + EJIT_OPERAND_FPR(1, EJIT_TYPE(float)) + }; + + struct ejit_func *f = ejit_create_func(EJIT_TYPE(float), 2, operands); + + ejit_minr_f(f, EJIT_FPR(2), EJIT_FPR(0), EJIT_FPR(1)); + ejit_retr_f(f, EJIT_FPR(2)); + + ejit_select_compile_func(f, 0, 3, EJIT_USE64(float), do_jit, true); + + assert(erff2(f, EJIT_ARG(42., float), EJIT_ARG(69., float) + ) == 42.); + + assert(erff2(f, EJIT_ARG(-42., float), EJIT_ARG(-69., float) + ) == -69.); + + ejit_destroy_func(f); +} |