diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-04-01 22:16:25 +0300 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-04-01 22:16:25 +0300 |
commit | 478c92b425eca53a0d884fb8f5dea8d769016858 (patch) | |
tree | d5d85feb1b796530429221d51ab88c8c7f1a0b55 /src | |
parent | 4135845b93d5c0eab23ad5da526b03a911878d67 (diff) | |
download | ejit-478c92b425eca53a0d884fb8f5dea8d769016858.tar.gz ejit-478c92b425eca53a0d884fb8f5dea8d769016858.zip |
expose sqrt
+ Requires linking with libm in some cases, which is fine I suppose, but
kind of annoying
Diffstat (limited to 'src')
-rw-r--r-- | src/common.h | 3 | ||||
-rw-r--r-- | src/compile/compile.c | 20 | ||||
-rw-r--r-- | src/ejit.c | 10 | ||||
-rw-r--r-- | src/interp.c | 11 |
4 files changed, 44 insertions, 0 deletions
diff --git a/src/common.h b/src/common.h index 6a3c754..c690f8f 100644 --- a/src/common.h +++ b/src/common.h @@ -142,6 +142,9 @@ enum ejit_opcode { EJIT_OP_TRUNCR_F_32, EJIT_OP_TRUNCR_F_64, + EJIT_OP_SQRTR_F, + EJIT_OP_SQRTR_D, + EJIT_OP_EQR, EJIT_OP_NER, EJIT_OP_GTR, diff --git a/src/compile/compile.c b/src/compile/compile.c index b90ee54..580b7fa 100644 --- a/src/compile/compile.c +++ b/src/compile/compile.c @@ -1326,6 +1326,23 @@ static void compile_truncr_f_32(struct ejit_func *f, jit_state_t *j, #endif } +static void compile_sqrtr_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_sqrtr_f(j, r0, r1); + putloc_d(f, j, i.r0, r0); +} + +static void compile_sqrtr_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_sqrtr_d(j, r0, r1); + putloc_d(f, j, i.r0, r0); +} static void compile_reg_cmp(struct ejit_func *f, jit_state_t *j, struct ejit_insn i, @@ -2084,6 +2101,9 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, case EJIT_OP_TRUNCR_F_32: compile_truncr_f_32(f, j, i); break; case EJIT_OP_TRUNCR_F_64: compile_truncr_f_64(f, j, i); break; + 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_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; @@ -1371,6 +1371,16 @@ void ejit_truncr_f_64(struct ejit_func *s, struct ejit_gpr r0, emit_insn_orf(s, EJIT_OP_TRUNCR_F_64, r0, f1); } +void ejit_sqrtr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1) +{ + emit_insn_off(s, EJIT_OP_SQRTR_F, r0, r1); +} + +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); +} + 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 b858f26..2d9b7c7 100644 --- a/src/interp.c +++ b/src/interp.c @@ -147,6 +147,9 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa [EJIT_OP_TRUNCR_F_32] = &&TRUNCR_F_32, [EJIT_OP_TRUNCR_F_64] = &&TRUNCR_F_64, + [EJIT_OP_SQRTR_F] = &&SQRTR_F, + [EJIT_OP_SQRTR_D] = &&SQRTR_D, + [EJIT_OP_BNER] = &&BNER, [EJIT_OP_BNEI] = &&BNEI, [EJIT_OP_BNER_F] = &&BNER_F, @@ -784,6 +787,14 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa gpr[i.r0] = (int64_t)fpr[i.r1].f; DISPATCH(); + DO(SQRTR_F); + fpr[i.r0].f = sqrt(fpr[i.r1].f); + DISPATCH(); + + DO(SQRTR_D); + fpr[i.r0].d = sqrt(fpr[i.r1].d); + DISPATCH(); + DO(BNER); if (gpr[i.r1] != gpr[i.r2]) JUMP(i.r0); |