aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2025-04-05 13:46:09 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2025-04-05 13:46:09 +0300
commit42f89542550033a3f22700e6b0fd71627a252f96 (patch)
treeb92fe73c326cb631f6fbb0bc37bc1f653dcd2079 /src
parent441ddf9277f878b83c8d093def51b27285353fed (diff)
downloadejit-42f89542550033a3f22700e6b0fd71627a252f96.tar.gz
ejit-42f89542550033a3f22700e6b0fd71627a252f96.zip
implement minr_d/maxr_d
Diffstat (limited to 'src')
-rw-r--r--src/common.h6
-rw-r--r--src/compile/compile.c46
-rw-r--r--src/ejit.c26
-rw-r--r--src/interp.c22
4 files changed, 100 insertions, 0 deletions
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 38c368f..dcf662b 100644
--- a/src/compile/compile.c
+++ b/src/compile/compile.c
@@ -1977,6 +1977,46 @@ static void resolve_relocs(jit_state_t *j, struct relocs *relocs, struct addrs *
}
}
+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)
{
@@ -2143,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;
diff --git a/src/ejit.c b/src/ejit.c
index 75f6a6a..c997a01 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -901,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);
}
@@ -1382,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 e7be77b..57dbfbe 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,
@@ -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();