diff options
Diffstat (limited to 'src/compile/compile.c')
-rw-r--r-- | src/compile/compile.c | 1029 |
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); |