aboutsummaryrefslogtreecommitdiff
path: root/src/compile/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile/compile.c')
-rw-r--r--src/compile/compile.c1029
1 files changed, 982 insertions, 47 deletions
diff --git a/src/compile/compile.c b/src/compile/compile.c
index e8e32b7..929dfa1 100644
--- a/src/compile/compile.c
+++ b/src/compile/compile.c
@@ -59,12 +59,26 @@ static jit_gpr_t getloc(struct ejit_func *f, jit_state_t *j, size_t l, size_t i)
return jit_r(i);
}
-static jit_fpr_t getloc_f(struct ejit_func *f, jit_state_t *j, size_t l, size_t i)
+static jit_fpr_t getloc_f(struct ejit_func *f, jit_state_t *j, size_t l,
+ size_t i)
{
(void)(f);
if (l < jit_vf_num())
return jit_vf(l);
+ jit_ldxi_f(j, jit_f(i), JIT_SP, stack_loc_f(f, l));
+ return jit_f(i);
+}
+
+static jit_fpr_t getloc_d(struct ejit_func *f, jit_state_t *j, size_t l,
+ size_t i)
+{
+ (void)(f);
+ if (l < jit_vf_num())
+ return jit_vf(l);
+
+ /* not that stack_loc_f assumes double, so floats technically take up
+ * more space than needed but at least we don't get any alignment issues */
jit_ldxi_d(j, jit_f(i), JIT_SP, stack_loc_f(f, l));
return jit_f(i);
}
@@ -104,6 +118,16 @@ static void putloc_f(struct ejit_func *f, jit_state_t *j, size_t l, jit_fpr_t r)
return;
}
+ jit_stxi_f(j, stack_loc_f(f, l), JIT_SP, r);
+}
+
+static void putloc_d(struct ejit_func *f, jit_state_t *j, size_t l, jit_fpr_t r)
+{
+ if (l < jit_vf_num()) {
+ assert(jit_v(l).regno == r.regno);
+ return;
+ }
+
jit_stxi_d(j, stack_loc_f(f, l), JIT_SP, r);
}
@@ -120,15 +144,49 @@ static void compile_movi(struct ejit_func *f, jit_state_t *j,
putloc(f, j, i.r0, r);
}
+static void compile_movi_f(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r = getfpr(f, i.r0, 0);
+ jit_movi_f(j, r, i.f);
+ putloc_f(f, j, i.r0, r);
+}
+
+static void compile_movi_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r = getfpr(f, i.r0, 0);
+ jit_movi_d(j, r, i.d);
+ putloc_d(f, j, i.r0, r);
+}
+
static void compile_movr(struct ejit_func *f, jit_state_t *j,
struct ejit_insn i)
{
jit_gpr_t to = getgpr(f, i.r0, 0);
- jit_gpr_t from = getgpr(f, i.r1, 1);
+ jit_gpr_t from = getloc(f, j, i.r1, 1);
jit_movr(j, to, from);
putloc(f, j, i.r0, to);
}
+static void compile_movr_f(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t to = getfpr(f, i.r0, 0);
+ jit_fpr_t from = getloc_f(f, j, i.r1, 1);
+ jit_movr_f(j, to, from);
+ putloc_f(f, j, i.r0, to);
+}
+
+static void compile_movr_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t to = getfpr(f, i.r0, 0);
+ jit_fpr_t from = getloc_d(f, j, i.r1, 1);
+ jit_movr_d(j, to, from);
+ putloc_d(f, j, i.r0, to);
+}
+
static void compile_addr(struct ejit_func *f, jit_state_t *j,
struct ejit_insn i)
{
@@ -167,6 +225,56 @@ static void compile_subi(struct ejit_func *f, jit_state_t *j,
putloc(f, j, i.r0, dst);
}
+static void compile_subr_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_subr_f(j, r0, r1, r2);
+ putloc_f(f, j, i.r0, r0);
+}
+
+static void compile_subr_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_subr_d(j, r0, r1, r2);
+ putloc_d(f, j, i.r0, r0);
+}
+
+static void compile_mulr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_mulr(j, r0, r1, r2);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_mulr_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_mulr_f(j, r0, r1, r2);
+ putloc_f(f, j, i.r0, r0);
+}
+
+static void compile_mulr_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_mulr_d(j, r0, r1, r2);
+ putloc_d(f, j, i.r0, r0);
+}
+
static void compile_andi(struct ejit_func *f, jit_state_t *j,
struct ejit_insn i)
{
@@ -186,28 +294,244 @@ static void compile_andr(struct ejit_func *f, jit_state_t *j,
putloc(f, j, i.r0, r0);
}
+static void compile_ori(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_ori(j, r0, r1, i.o);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_orr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_orr(j, r0, r1, r2);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_xori(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_xori(j, r0, r1, i.o);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_xorr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_xorr(j, r0, r1, r2);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_divr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_divr(j, r0, r1, r2);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_divr_u(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_divr_u(j, r0, r1, r2);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_divr_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_divr_d(j, r0, r1, r2);
+ putloc_d(f, j, i.r0, r0);
+}
+
+static void compile_divr_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_divr_f(j, r0, r1, r2);
+ putloc_f(f, j, i.r0, r0);
+}
+
+static void compile_remr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_remr(j, r0, r1, r2);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_remr_u(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_remr_u(j, r0, r1, r2);
+ putloc(f, j, i.r0, r0);
+}
+
static void compile_absr_f(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ 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_absr_d(j, r0, r1);
+ jit_absr_f(j, r0, r1);
putloc_f(f, j, i.r0, r0);
}
+static void compile_absr_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_absr_f(j, r0, r1);
+ putloc_d(f, j, i.r0, r0);
+}
+
static void compile_addr_f(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ 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_addr_d(j, r0, r1, r2);
+ jit_addr_f(j, r0, r1, r2);
putloc_f(f, j, i.r0, r0);
}
-static void compile_stxi8(struct ejit_func *f, jit_state_t *j,
+static void compile_addr_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_addr_d(j, r0, r1, r2);
+ putloc_d(f, j, i.r0, r0);
+}
+
+static void compile_lshi(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_lshi(j, r0, r1, i.o);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_lshr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_lshr(j, r0, r1, r2);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_rshi(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_rshi(j, r0, r1, i.o);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_rshi_u(struct ejit_func *f, jit_state_t *j,
struct ejit_insn i)
{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_rshi_u(j, r0, r1, i.o);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_rshr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_rshr(j, r0, r1, r2);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_rshr_u(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_rshr_u(j, r0, r1, r2);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_sti8(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getloc(f, j, i.r0, 0);
+ jit_sti_c(j, i.p, r0);
+}
+
+static void compile_sti16(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getloc(f, j, i.r0, 0);
+ jit_sti_s(j, i.p, r0);
+}
+
+static void compile_sti32(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getloc(f, j, i.r0, 0);
+ jit_sti_i(j, i.p, r0);
+}
+
+static void compile_sti64(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getloc(f, j, i.r0, 0);
+ jit_sti_l(j, i.p, r0);
+}
+
+static void compile_stif(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getloc_f(f, j, i.r0, 0);
+ jit_sti_f(j, i.p, r0);
+}
+
+static void compile_stid(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getloc_d(f, j, i.r0, 0);
+ jit_sti_d(j, i.p, r0);
+}
+
+static void compile_stxi8(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
jit_gpr_t r0 = getloc(f, j, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
jit_stxi_c(j, i.o, r1, r0);
@@ -238,24 +562,23 @@ static void compile_stxi64(struct ejit_func *f, jit_state_t *j,
}
static void compile_stxif(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_fpr_t r0 = getloc_f(f, j, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
- jit_extr_d_f(j, r0, r0);
jit_stxi_f(j, i.o, r1, r0);
}
static void compile_stxid(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
- jit_fpr_t r0 = getloc_f(f, j, i.r0, 0);
+ jit_fpr_t r0 = getloc_d(f, j, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
jit_stxi_d(j, i.o, r1, r0);
}
static void compile_stxr8(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getloc(f, j, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -291,26 +614,105 @@ static void compile_stxr64(struct ejit_func *f, jit_state_t *j,
}
static void compile_stxrf(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_fpr_t r0 = getloc_f(f, j, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
jit_gpr_t r2 = getloc(f, j, i.r2, 2);
- jit_extr_d_f(j, r0, r0);
jit_stxr_f(j, r2, r1, r0);
}
static void compile_stxrd(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
- jit_fpr_t r0 = getloc_f(f, j, i.r0, 0);
+ jit_fpr_t r0 = getloc_d(f, j, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
jit_gpr_t r2 = getloc(f, j, i.r2, 2);
jit_stxr_d(j, r2, r1, r0);
}
+static void compile_ldiu8(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_ldi_uc(j, r0, i.p);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_ldiu16(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_ldi_us(j, r0, i.p);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_ldiu32(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_ldi_ui(j, r0, i.p);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_ldiu64(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_ldi_l(j, r0, i.p);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_ldif(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getfpr(f, i.r0, 0);
+ jit_ldi_f(j, r0, i.p);
+ putloc_f(f, j, i.r0, r0);
+}
+
+static void compile_ldid(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getfpr(f, i.r0, 0);
+ jit_ldi_d(j, r0, i.p);
+ putloc_d(f, j, i.r0, r0);
+}
+
+static void compile_ldi8(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_ldi_c(j, r0, i.p);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_ldi16(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_ldi_s(j, r0, i.p);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_ldi32(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_ldi_i(j, r0, i.p);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_ldi64(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_ldi_l(j, r0, i.p);
+ putloc(f, j, i.r0, r0);
+}
+
static void compile_ldxiu8(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getgpr(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -345,8 +747,26 @@ static void compile_ldxiu64(struct ejit_func *f, jit_state_t *j,
putloc(f, j, i.r0, r0);
}
+static void compile_ldxif(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getfpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_ldxi_f(j, r0, r1, i.o);
+ putloc_f(f, j, i.r0, r0);
+}
+
+static void compile_ldxid(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getfpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_ldxi_d(j, r0, r1, i.o);
+ putloc_d(f, j, i.r0, r0);
+}
+
static void compile_ldxi8(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getgpr(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -355,7 +775,7 @@ static void compile_ldxi8(struct ejit_func *f, jit_state_t *j,
}
static void compile_ldxi16(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getgpr(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -364,7 +784,7 @@ static void compile_ldxi16(struct ejit_func *f, jit_state_t *j,
}
static void compile_ldxi32(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getgpr(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -373,7 +793,7 @@ static void compile_ldxi32(struct ejit_func *f, jit_state_t *j,
}
static void compile_ldxi64(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getgpr(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -382,7 +802,7 @@ static void compile_ldxi64(struct ejit_func *f, jit_state_t *j,
}
static void compile_ldxru8(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getgpr(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -422,7 +842,7 @@ static void compile_ldxru64(struct ejit_func *f, jit_state_t *j,
}
static void compile_ldxr8(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getgpr(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -432,7 +852,7 @@ static void compile_ldxr8(struct ejit_func *f, jit_state_t *j,
}
static void compile_ldxr16(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getgpr(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -442,7 +862,7 @@ static void compile_ldxr16(struct ejit_func *f, jit_state_t *j,
}
static void compile_ldxr32(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getgpr(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -452,7 +872,7 @@ static void compile_ldxr32(struct ejit_func *f, jit_state_t *j,
}
static void compile_ldxr64(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i)
+ struct ejit_insn i)
{
jit_gpr_t r0 = getgpr(f, i.r0, 0);
jit_gpr_t r1 = getloc(f, j, i.r1, 1);
@@ -461,6 +881,180 @@ static void compile_ldxr64(struct ejit_func *f, jit_state_t *j,
putloc(f, j, i.r0, r0);
}
+static void compile_ldxrf(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getfpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_ldxr_f(j, r0, r1, r2);
+ putloc_f(f, j, i.r0, r0);
+}
+
+static void compile_ldxrd(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getfpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_gpr_t r2 = getloc(f, j, i.r2, 2);
+ jit_ldxr_d(j, r0, r1, r2);
+ putloc_d(f, j, i.r0, r0);
+}
+
+static void compile_comr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_comr(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_negr(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_negr(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_negr_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_negr_f(j, r0, r1);
+ putloc_f(f, j, i.r0, r0);
+}
+
+static void compile_negr_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_negr_d(j, r0, r1);
+ putloc_d(f, j, i.r0, r0);
+}
+
+static void compile_extr8(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_extr_c(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_extr16(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_extr_s(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_extr32(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_extr_i(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_extru8(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_extr_uc(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_extru16(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_extr_us(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_extru32(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_extr_ui(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_extrf(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getfpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_extr_f(j, r0, r1);
+ putloc_f(f, j, i.r0, r0);
+}
+
+static void compile_extrd(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getfpr(f, i.r0, 0);
+ jit_gpr_t r1 = getloc(f, j, i.r1, 1);
+ jit_extr_d(j, r0, r1);
+ putloc_d(f, j, i.r0, r0);
+}
+
+static void compile_truncr_d_64(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_fpr_t r1 = getloc_d(f, j, i.r1, 1);
+ jit_truncr_d_l(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_truncr_d_32(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+#if __WORDSIZE == 64
+ return compile_truncr_d_64(f, j, i);
+#else
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_fpr_t r1 = getloc_d(f, j, i.r1, 1);
+ jit_truncr_d_i(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+#endif
+}
+
+
+static void compile_truncr_f_64(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_fpr_t r1 = getloc_f(f, j, i.r1, 1);
+ jit_truncr_f_l(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_truncr_f_32(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+#if __WORDSIZE == 64
+ return compile_truncr_f_64(f, j, i);
+#else
+ jit_gpr_t r0 = getgpr(f, i.r0, 0);
+ jit_fpr_t r1 = getloc_f(f, j, i.r1, 1);
+ jit_truncr_f_i(j, r0, r1);
+ putloc(f, j, i.r0, r0);
+#endif
+}
+
+
static void compile_reg_cmp(struct ejit_func *f, jit_state_t *j,
struct ejit_insn i,
jit_reloc_t (*bcomp)(jit_state_t *, jit_gpr_t,
@@ -490,13 +1084,141 @@ static void compile_reg_cmp(struct ejit_func *f, jit_state_t *j,
putloc(f, j, i.r0, r0);
}
+static void compile_reg_d_cmp(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i,
+ jit_reloc_t (*bcomp)(jit_state_t *,
+ jit_fpr_t,
+ jit_fpr_t)
+ )
+{
+ /* note that we don't check for register sameness due to NaN, which
+ * compares to itself as fast so we can't say for sure if r1 == r1 will
+ * return true */
+ jit_gpr_t r0 = getgpr(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_reloc_t branch = bcomp(j, r1, r2);
+
+ /* not equal */
+ jit_movi(j, r0, 0);
+ jit_reloc_t jump = jit_jmp(j);
+ jit_patch_there(j, branch, jit_address(j));
+
+ /* equal */
+ jit_movi(j, r0, 1);
+ jit_patch_there(j, jump, jit_address(j));
+
+ /* write final result */
+ putloc(f, j, i.r0, r0);
+}
+
+static void compile_reg_f_cmp(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i,
+ jit_reloc_t (*bcomp)(jit_state_t *,
+ jit_fpr_t,
+ jit_fpr_t)
+ )
+{
+ jit_gpr_t r0 = getgpr(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_reloc_t branch = bcomp(j, r1, r2);
+
+ /* not equal */
+ jit_movi(j, r0, 0);
+ jit_reloc_t jump = jit_jmp(j);
+ jit_patch_there(j, branch, jit_address(j));
+
+ /* equal */
+ jit_movi(j, r0, 1);
+ jit_patch_there(j, jump, jit_address(j));
+
+ /* write final result */
+ putloc(f, j, i.r0, r0);
+}
+
static void compile_eqr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
{
compile_reg_cmp(f, j, i, jit_beqr, 1);
}
+static void compile_eqr_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ compile_reg_d_cmp(f, j, i, jit_beqr_d);
+}
+
+static void compile_eqr_f(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ compile_reg_f_cmp(f, j, i, jit_beqr_f);
+}
+
+static void compile_ner(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+{
+ compile_reg_cmp(f, j, i, jit_bner, 0);
+}
+
+static void compile_ner_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ compile_reg_d_cmp(f, j, i, jit_bner_d);
+}
+
+static void compile_ner_f(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ compile_reg_f_cmp(f, j, i, jit_bner_f);
+}
+
+static void compile_ger(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+{
+ compile_reg_cmp(f, j, i, jit_bger, 1);
+}
+
+static void compile_ger_u(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ compile_reg_cmp(f, j, i, jit_bger_u, 1);
+}
+
+static void compile_ger_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ compile_reg_d_cmp(f, j, i, jit_bger_d);
+}
+
+static void compile_ger_f(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ compile_reg_f_cmp(f, j, i, jit_bger_f);
+}
+
+static void compile_gtr(struct ejit_func *f, jit_state_t *j, struct ejit_insn i)
+{
+ compile_reg_cmp(f, j, i, jit_bgtr, 0);
+}
+
+static void compile_gtr_u(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ compile_reg_cmp(f, j, i, jit_bgtr_u, 0);
+}
+
+static void compile_gtr_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ compile_reg_d_cmp(f, j, i, jit_bgtr_d);
+}
+
+static void compile_gtr_f(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ compile_reg_f_cmp(f, j, i, jit_bgtr_f);
+}
+
static void compile_bmci(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i, struct vec *relocs)
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_reloc_t r = jit_bmci(j, r1, i.o);
@@ -505,7 +1227,7 @@ static void compile_bmci(struct ejit_func *f, jit_state_t *j,
}
static void compile_bmcr(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i, struct vec *relocs)
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_gpr_t r2 = getloc(f, j, i.r2, 1);
@@ -515,7 +1237,7 @@ static void compile_bmcr(struct ejit_func *f, jit_state_t *j,
}
static void compile_bmsi(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i, struct vec *relocs)
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_reloc_t r = jit_bmsi(j, r1, i.o);
@@ -524,7 +1246,7 @@ static void compile_bmsi(struct ejit_func *f, jit_state_t *j,
}
static void compile_bmsr(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i, struct vec *relocs)
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_gpr_t r2 = getloc(f, j, i.r2, 1);
@@ -553,10 +1275,20 @@ static void compile_beqr(struct ejit_func *f, jit_state_t *j,
}
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 vec *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);
+}
+
+static void compile_beqr_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i, struct vec *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);
@@ -582,17 +1314,27 @@ static void compile_bner(struct ejit_func *f, jit_state_t *j,
}
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 vec *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);
+}
+
+static void compile_bner_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i, struct vec *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);
}
static void compile_bger(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i, struct vec *relocs)
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_gpr_t r2 = getloc(f, j, i.r2, 1);
@@ -602,7 +1344,7 @@ static void compile_bger(struct ejit_func *f, jit_state_t *j,
}
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 vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_gpr_t r2 = getloc(f, j, i.r2, 1);
@@ -612,7 +1354,7 @@ static void compile_bger_u(struct ejit_func *f, jit_state_t *j,
}
static void compile_bgei(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i, struct vec *relocs)
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_reloc_t r = jit_bgei(j, r1, i.o);
@@ -621,7 +1363,7 @@ static void compile_bgei(struct ejit_func *f, jit_state_t *j,
}
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 vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_reloc_t r = jit_bgei_u(j, r1, i.o);
@@ -630,17 +1372,27 @@ static void compile_bgei_u(struct ejit_func *f, jit_state_t *j,
}
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 vec *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);
+}
+
+static void compile_bger_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i, struct vec *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);
}
static void compile_bgtr(struct ejit_func *f, jit_state_t *j,
- struct ejit_insn i, struct vec *relocs)
+ struct ejit_insn i, struct vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_gpr_t r2 = getloc(f, j, i.r2, 1);
@@ -650,7 +1402,7 @@ static void compile_bgtr(struct ejit_func *f, jit_state_t *j,
}
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 vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_gpr_t r2 = getloc(f, j, i.r2, 1);
@@ -669,7 +1421,7 @@ static void compile_bgti(struct ejit_func *f, jit_state_t *j,
}
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 vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_reloc_t r = jit_bgti_u(j, r1, i.o);
@@ -678,10 +1430,20 @@ static void compile_bgti_u(struct ejit_func *f, jit_state_t *j,
}
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 vec *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);
+}
+
+static void compile_bgtr_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i, struct vec *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);
@@ -697,7 +1459,7 @@ static void compile_blei(struct ejit_func *f, jit_state_t *j,
}
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 vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_reloc_t r = jit_blei_u(j, r1, i.o);
@@ -715,7 +1477,7 @@ static void compile_blti(struct ejit_func *f, jit_state_t *j,
}
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 vec *relocs)
{
jit_gpr_t r1 = getloc(f, j, i.r1, 0);
jit_reloc_t r = jit_blti_u(j, r1, i.o);
@@ -740,6 +1502,24 @@ static void compile_retval(struct ejit_func *f, jit_state_t *j,
putloc(f, j, i.r0, r0);
}
+static void compile_retval_f(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getfpr(f, i.r0, 0);
+ jit_retval_d(j, r0);
+ /* convert double to float */
+ jit_extr_d_f(j, r0, r0);
+ putloc_f(f, j, i.r0, r0);
+}
+
+static void compile_retval_d(struct ejit_func *f, jit_state_t *j,
+ struct ejit_insn i)
+{
+ jit_fpr_t r0 = getfpr(f, i.r0, 0);
+ jit_retval_d(j, r0);
+ putloc_d(f, j, i.r0, r0);
+}
+
static enum jit_operand_abi jit_abi_from(enum ejit_type t)
{
switch (t) {
@@ -858,16 +1638,60 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
struct ejit_insn i = vect_at(struct ejit_insn, f->insns, ii);
switch (i.op) {
case MOVR: compile_movr(f, j, i); break;
+ case MOVR_F: compile_movr_f(f, j, i); break;
+ case MOVR_D: compile_movr_d(f, j, i); break;
+
case MOVI: compile_movi(f, j, i); break;
+ case MOVI_F: compile_movi_f(f, j, i); break;
+ case MOVI_D: compile_movi_d(f, j, i); break;
+
case ADDR: compile_addr(f, j, i); break;
case ADDI: compile_addi(f, j, i); break;
+ case ADDR_F: compile_addr_f(f, j, i); break;
+ case ADDR_D: compile_addr_d(f, j, i); break;
+
case SUBR: compile_subr(f, j, i); break;
case SUBI: compile_subi(f, j, i); break;
+ case SUBR_F: compile_subr_f(f, j, i); break;
+ case SUBR_D: compile_subr_d(f, j, i); break;
+
+ case MULR: compile_mulr(f, j, i); break;
+ case MULR_F: compile_mulr_f(f, j, i); break;
+ case MULR_D: compile_mulr_d(f, j, i); break;
+
case ANDI: compile_andi(f, j, i); break;
case ANDR: compile_andr(f, j, i); break;
- case ADDR_F: compile_addr_f(f, j, i); break;
+ case ORI: compile_ori(f, j, i); break;
+ case ORR: compile_orr(f, j, i); break;
+
+ case XORI: compile_xori(f, j, i); break;
+ case XORR: compile_xorr(f, j, i); break;
+
+ case DIVR: compile_divr(f, j, i); break;
+ case DIVR_U: compile_divr_u(f, j, i); break;
+ case DIVR_F: compile_divr_f(f, j, i); break;
+ case DIVR_D: compile_divr_d(f, j, i); break;
+
+ case REMR: compile_remr(f, j, i); break;
+ case REMR_U: compile_remr_u(f, j, i); break;
+
case ABSR_F: compile_absr_f(f, j, i); break;
+ case ABSR_D: compile_absr_d(f, j, i); break;
+
+ case LSHI: compile_lshi(f, j, i); break;
+ case LSHR: compile_lshr(f, j, i); break;
+ case RSHI: compile_rshi(f, j, i); break;
+ case RSHI_U: compile_rshi_u(f, j, i); break;
+ case RSHR: compile_rshr(f, j, i); break;
+ case RSHR_U: compile_rshr_u(f, j, i); break;
+
+ case STI8: compile_sti8(f, j, i); break;
+ case STI16: compile_sti16(f, j, i); break;
+ case STI32: compile_sti32(f, j, i); break;
+ case STI64: compile_sti64(f, j, i); break;
+ case STIF: compile_stif(f, j, i); break;
+ case STID: compile_stid(f, j, i); break;
case STXI8: compile_stxi8(f, j, i); break;
case STXI16: compile_stxi16(f, j, i); break;
@@ -883,6 +1707,17 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case STXRF: compile_stxrf(f, j, i); break;
case STXRD: compile_stxrd(f, j, i); break;
+ case LDI8: compile_ldi8(f, j, i); break;
+ case LDI16: compile_ldi16(f, j, i); break;
+ case LDI32: compile_ldi32(f, j, i); break;
+ case LDI64: compile_ldi64(f, j, i); break;
+ case LDIU8: compile_ldiu8(f, j, i); break;
+ case LDIU16: compile_ldiu16(f, j, i); break;
+ case LDIU32: compile_ldiu32(f, j, i); break;
+ case LDIU64: compile_ldiu64(f, j, i); break;
+ case LDIF: compile_ldif(f, j, i); break;
+ case LDID: compile_ldid(f, j, i); break;
+
case LDXI8: compile_ldxi8(f, j, i); break;
case LDXI16: compile_ldxi16(f, j, i); break;
case LDXI32: compile_ldxi32(f, j, i); break;
@@ -891,6 +1726,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case LDXIU16: compile_ldxiu16(f, j, i); break;
case LDXIU32: compile_ldxiu32(f, j, i); break;
case LDXIU64: compile_ldxiu64(f, j, i); break;
+ case LDXIF: compile_ldxif(f, j, i); break;
+ case LDXID: compile_ldxid(f, j, i); break;
case LDXR8: compile_ldxr8(f, j, i); break;
case LDXR16: compile_ldxr16(f, j, i); break;
@@ -900,8 +1737,46 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case LDXRU16: compile_ldxru16(f, j, i); break;
case LDXRU32: compile_ldxru32(f, j, i); break;
case LDXRU64: compile_ldxru64(f, j, i); break;
+ case LDXRF: compile_ldxrf(f, j, i); break;
+ case LDXRD: compile_ldxrd(f, j, i); break;
+
+ case COMR: compile_comr(f, j, i); break;
+
+ case NEGR: compile_negr(f, j, i); break;
+ case NEGR_F: compile_negr_f(f, j, i); break;
+ case NEGR_D: compile_negr_d(f, j, i); break;
+
+ case EXTR8: compile_extr8(f, j, i); break;
+ case EXTR16: compile_extr16(f, j, i); break;
+ case EXTR32: compile_extr32(f, j, i); break;
+ case EXTRU8: compile_extru8(f, j, i); break;
+ case EXTRU16: compile_extru16(f, j, i); break;
+ case EXTRU32: compile_extru32(f, j, i); break;
+ case EXTRF: compile_extrf(f, j, i); break;
+ case EXTRD: compile_extrd(f, j, i); break;
+
+ case TRUNCR_D_32: compile_truncr_d_32(f, j, i); break;
+ case TRUNCR_D_64: compile_truncr_d_64(f, j, i); break;
+ case TRUNCR_F_32: compile_truncr_f_32(f, j, i); break;
+ case TRUNCR_F_64: compile_truncr_f_64(f, j, i); break;
case EQR: compile_eqr(f, j, i); break;
+ case EQR_F: compile_eqr_f(f, j, i); break;
+ case EQR_D: compile_eqr_d(f, j, i); break;
+
+ case NER: compile_ner(f, j, i); break;
+ case NER_F: compile_ner_f(f, j, i); break;
+ case NER_D: compile_ner_d(f, j, i); break;
+
+ case GER: compile_ger(f, j, i); break;
+ case GER_U: compile_ger_u(f, j, i); break;
+ case GER_F: compile_ger_f(f, j, i); break;
+ case GER_D: compile_ger_d(f, j, i); break;
+
+ case GTR: compile_gtr(f, j, i); break;
+ case GTR_U: compile_gtr_u(f, j, i); break;
+ case GTR_F: compile_gtr_f(f, j, i); break;
+ case GTR_D: compile_gtr_d(f, j, i); break;
case BMCI: compile_bmci(f, j, i, &relocs); break;
case BMCR: compile_bmcr(f, j, i, &relocs); break;
@@ -912,21 +1787,26 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case BEQR: compile_beqr(f, j, i, &relocs); break;
case BEQI: compile_beqi(f, j, i, &relocs); break;
case BEQR_F: compile_beqr_f(f, j, i, &relocs); break;
+ case BEQR_D: compile_beqr_d(f, j, i, &relocs); break;
+
case BNER: compile_bner(f, j, i, &relocs); break;
case BNEI: compile_bnei(f, j, i, &relocs); break;
case BNER_F: compile_bner_f(f, j, i, &relocs); break;
+ case BNER_D: compile_bner_d(f, j, i, &relocs); break;
case BGER: compile_bger(f, j, i, &relocs); break;
case BGER_U: compile_bger_u(f, j, i, &relocs); break;
case BGEI: compile_bgei(f, j, i, &relocs); break;
case BGEI_U: compile_bgei_u(f, j, i, &relocs); break;
case BGER_F: compile_bger_f(f, j, i, &relocs); break;
+ case BGER_D: compile_bger_d(f, j, i, &relocs); break;
case BGTR: compile_bgtr(f, j, i, &relocs); break;
case BGTR_U: compile_bgtr_u(f, j, i, &relocs); break;
case BGTI: compile_bgti(f, j, i, &relocs); break;
case BGTI_U: compile_bgti_u(f, j, i, &relocs); break;
case BGTR_F: compile_bgtr_f(f, j, i, &relocs); break;
+ case BGTR_D: compile_bgtr_d(f, j, i, &relocs); break;
case BLEI: compile_blei(f, j, i, &relocs); break;
case BLEI_U: compile_blei_u(f, j, i, &relocs); break;
@@ -940,7 +1820,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
jit_operand_t type =
jit_operand_imm(JIT_OPERAND_ABI_WORD, i.r1);
jit_operand_t arg;
- if (i.r0 < jit_v_num()) {
+ if (i.r2 < jit_v_num()) {
/* regular register */
arg = jit_operand_gpr(jit_abi_from(i.r1),
jit_v(i.r2));
@@ -949,7 +1829,39 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
/* stack location, note that we'll fix up the SP
* offset before doing the actual call */
arg = jit_operand_mem(jit_abi_from(i.r1),
- JIT_SP, stack_loc(i.r0));
+ JIT_SP, stack_loc(i.r2));
+ }
+
+ vec_append(&src, &type);
+ vec_append(&src, &arg);
+
+ jit_operand_t to[2] = {
+ jit_operand_mem(JIT_OPERAND_ABI_WORD, JIT_SP,
+ type_offset(i)),
+ jit_operand_mem(jit_abi_from(i.r1), JIT_SP,
+ arg_offset(i))
+ };
+
+ vec_append(&dst, &to[0]);
+ vec_append(&dst, &to[1]);
+ break;
+ }
+
+ case ARG_F: {
+ jit_operand_t type =
+ jit_operand_imm(JIT_OPERAND_ABI_WORD, i.r1);
+ jit_operand_t arg;
+ if (i.r2 < jit_vf_num()) {
+ /* regular register */
+ arg = jit_operand_fpr(jit_abi_from(i.r1),
+ jit_vf(i.r2));
+ }
+ else {
+ /* stack location, note that we'll fix up the SP
+ * offset before doing the actual call */
+ arg = jit_operand_mem(jit_abi_from(i.r1),
+ JIT_SP,
+ stack_loc_f(f, i.r2));
}
vec_append(&src, &type);
@@ -977,6 +1889,16 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
break;
}
+ case ESCAPEI_F: {
+ jit_operand_t args[2] = {
+ jit_operand_imm(JIT_OPERAND_ABI_WORD,
+ vec_len(&src) / 2),
+ jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_SP)
+ };
+ compile_imm_call(j, &src, &dst, (void *)i.o, 2, args);
+ break;
+ }
+
case CALLI: {
jit_operand_t args[3] = {
jit_operand_imm(JIT_OPERAND_ABI_POINTER, i.o),
@@ -989,6 +1911,9 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
}
case RETVAL: compile_retval(f, j, i); break;
+ case RETVAL_F: compile_retval_f(f, j, i); break;
+ case RETVAL_D: compile_retval_d(f, j, i); break;
+
case RETR: {
jit_gpr_t r = getloc(f, j, i.r0, 0);
/* R0 won't get overwritten by jit_leave_jit_abi */
@@ -1001,13 +1926,23 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case RETR_F: {
jit_fpr_t r = getloc_f(f, j, i.r0, 0);
- jit_movr_f(j, JIT_F0, r);
+ /* convert float to double so the return types match */
+ jit_extr_f_d(j, JIT_F0, r);
jit_shrink_stack(j, stack);
jit_leave_jit_abi(j, gprs, fprs, frame);
jit_retr_f(j, JIT_F0);
break;
}
+ case RETR_D: {
+ jit_fpr_t r = getloc_d(f, j, i.r0, 0);
+ jit_movr_d(j, JIT_F0, r);
+ jit_shrink_stack(j, stack);
+ jit_leave_jit_abi(j, gprs, fprs, frame);
+ jit_retr_d(j, JIT_F0);
+ break;
+ }
+
case RETI: {
jit_shrink_stack(j, stack);
jit_leave_jit_abi(j, gprs, fprs, frame);