From 26fcfcf333e852b256af8ed4ca7f9e497958f6d8 Mon Sep 17 00:00:00 2001
From: Kimplul <kimi.h.kuparinen@gmail.com>
Date: Sat, 13 Jul 2024 21:13:22 +0300
Subject: implement some float JIT handling

---
 src/compile/compile.c | 116 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 105 insertions(+), 11 deletions(-)

(limited to 'src/compile')

diff --git a/src/compile/compile.c b/src/compile/compile.c
index 014b7d3..aa16339 100644
--- a/src/compile/compile.c
+++ b/src/compile/compile.c
@@ -59,7 +59,17 @@ 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_gpr_t getreg(struct ejit_func *f, 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_d(j, jit_f(i), JIT_SP, stack_loc_f(f, l));
+	return jit_f(i);
+}
+
+static jit_gpr_t getgpr(struct ejit_func *f, size_t l, size_t i)
 {
 	(void)(f);
 	if (l < jit_v_num())
@@ -68,6 +78,14 @@ static jit_gpr_t getreg(struct ejit_func *f, size_t l, size_t i)
 	return jit_r(i);
 }
 
+static jit_fpr_t getfpr(struct ejit_func *f, size_t l, size_t i)
+{
+	if (l < jit_vf_num())
+		return jit_vf(l);
+
+	return jit_f(i);
+}
+
 static void putloc(struct ejit_func *f, jit_state_t *j, size_t l, jit_gpr_t r)
 {
 	(void)(f);
@@ -79,6 +97,16 @@ static void putloc(struct ejit_func *f, jit_state_t *j, size_t l, jit_gpr_t r)
 	jit_stxi(j, stack_loc(l), JIT_SP, r);
 }
 
+static void putloc_f(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);
+}
+
 static void compile_label(jit_state_t *j, size_t ii, struct vec *labels)
 {
 	vect_at(jit_addr_t, *labels, ii) = jit_address(j);
@@ -87,7 +115,7 @@ static void compile_label(jit_state_t *j, size_t ii, struct vec *labels)
 static void compile_movi(struct ejit_func *f, jit_state_t *j,
                          struct ejit_insn i)
 {
-	jit_gpr_t r = getreg(f, i.r0, 0);
+	jit_gpr_t r = getgpr(f, i.r0, 0);
 	jit_movi(j, r, i.o);
 	putloc(f, j, i.r0, r);
 }
@@ -95,8 +123,8 @@ static void compile_movi(struct ejit_func *f, jit_state_t *j,
 static void compile_movr(struct ejit_func *f, jit_state_t *j,
                          struct ejit_insn i)
 {
-	jit_gpr_t to = getreg(f, i.r0, 0);
-	jit_gpr_t from = getreg(f, i.r1, 1);
+	jit_gpr_t to = getgpr(f, i.r0, 0);
+	jit_gpr_t from = getgpr(f, i.r1, 1);
 	jit_movr(j, to, from);
 	putloc(f, j, i.r0, to);
 }
@@ -104,7 +132,7 @@ static void compile_movr(struct ejit_func *f, jit_state_t *j,
 static void compile_addr(struct ejit_func *f, jit_state_t *j,
                          struct ejit_insn i)
 {
-	jit_gpr_t dst = getreg(f, i.r0, 0);
+	jit_gpr_t dst = getgpr(f, i.r0, 0);
 	jit_gpr_t src0 = getloc(f, j, i.r1, 1);
 	jit_gpr_t src1 = getloc(f, j, i.r2, 2);
 	jit_addr(j, dst, src0, src1);
@@ -114,7 +142,7 @@ static void compile_addr(struct ejit_func *f, jit_state_t *j,
 static void compile_addi(struct ejit_func *f, jit_state_t *j,
                          struct ejit_insn i)
 {
-	jit_gpr_t dst = getreg(f, i.r0, 0);
+	jit_gpr_t dst = getgpr(f, i.r0, 0);
 	jit_gpr_t src0 = getloc(f, j, i.r1, 1);
 	jit_addi(j, dst, src0, i.o);
 	putloc(f, j, i.r0, dst);
@@ -123,7 +151,7 @@ static void compile_addi(struct ejit_func *f, jit_state_t *j,
 static void compile_subr(struct ejit_func *f, jit_state_t *j,
                          struct ejit_insn i)
 {
-	jit_gpr_t dst = getreg(f, i.r0, 0);
+	jit_gpr_t dst = getgpr(f, i.r0, 0);
 	jit_gpr_t src0 = getloc(f, j, i.r1, 1);
 	jit_gpr_t src1 = getloc(f, j, i.r2, 2);
 	jit_subr(j, dst, src0, src1);
@@ -133,12 +161,40 @@ static void compile_subr(struct ejit_func *f, jit_state_t *j,
 static void compile_subi(struct ejit_func *f, jit_state_t *j,
                          struct ejit_insn i)
 {
-	jit_gpr_t dst = getreg(f, i.r0, 0);
+	jit_gpr_t dst = getgpr(f, i.r0, 0);
 	jit_gpr_t src0 = getloc(f, j, i.r1, 1);
 	jit_subi(j, dst, src0, i.o);
 	putloc(f, j, i.r0, dst);
 }
 
+static void compile_andi(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_andi(j, r0, r1, i.o);
+	putloc(f, j, i.r0, r0);
+}
+
+static void compile_absr_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_absr_d(j, r0, r1);
+	putloc_f(f, j, i.r0, r0);
+}
+
+static void compile_addr_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_addr_d(j, r0, r1, r2);
+	putloc_f(f, j, i.r0, r0);
+}
+
 static void compile_stxi64(struct ejit_func *f, jit_state_t *j,
                            struct ejit_insn i)
 {
@@ -150,7 +206,7 @@ static void compile_stxi64(struct ejit_func *f, jit_state_t *j,
 static void compile_ldxiu64(struct ejit_func *f, jit_state_t *j,
                             struct ejit_insn i)
 {
-	jit_gpr_t r0 = getreg(f, i.r0, 0);
+	jit_gpr_t r0 = getgpr(f, i.r0, 0);
 	jit_gpr_t r1 = getloc(f, j, i.r1, 1);
 	jit_ldxi_l(j, r0, r1, i.o);
 	putloc(f, j, i.r0, r0);
@@ -161,7 +217,7 @@ static void compile_reg_cmp(struct ejit_func *f, jit_state_t *j,
                             jit_reloc_t (*bcomp)(jit_state_t *, jit_gpr_t,
                                                  jit_gpr_t), long same)
 {
-	jit_gpr_t r0 = getreg(f, i.r0, 0);
+	jit_gpr_t r0 = getgpr(f, i.r0, 0);
 	if (i.r1 == i.r2) {
 		jit_movi(j, r0, same);
 		putloc(f, j, i.r0, r0);
@@ -229,7 +285,7 @@ static void compile_jmp(struct ejit_func *f, jit_state_t *j, struct ejit_insn i,
 static void compile_retval(struct ejit_func *f, jit_state_t *j,
                            struct ejit_insn i)
 {
-	jit_gpr_t r0 = getreg(f, i.r0, 0);
+	jit_gpr_t r0 = getgpr(f, i.r0, 0);
 	jit_retval(j, r0);
 	putloc(f, j, i.r0, r0);
 }
@@ -357,6 +413,10 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
 		case ADDI: compile_addi(f, j, i); break;
 		case SUBR: compile_subr(f, j, i); break;
 		case SUBI: compile_subi(f, j, i); break;
+		case ANDI: compile_andi(f, j, i); break;
+
+		case ADDR_F: compile_addr_f(f, j, i); break;
+		case ABSR_F: compile_absr_f(f, j, i); break;
 
 		case STXI64: compile_stxi64(f, j, i); break;
 		case LDXIU64: compile_ldxiu64(f, j, i); break;
@@ -431,6 +491,15 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
 			break;
 		}
 
+		case RETR_F: {
+			jit_fpr_t r = getloc_f(f, j, i.r0, 0);
+			jit_movr_f(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 RETI: {
 			jit_shrink_stack(j, stack);
 			jit_leave_jit_abi(j, gprs, fprs, frame);
@@ -446,6 +515,31 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
 			break;
 		}
 
+		case PARAM_F: {
+			/* move from argument stack to location */
+			jit_operand_t from = jit_operand_mem(
+				jit_abi_from(i.r1),
+				JIT_R1,
+				arg_offset(i)
+				);
+
+			jit_operand_t to;
+			if (i.r0 < jit_vf_num()) {
+				/* regular register */
+				to = jit_operand_fpr(jit_abi_from(i.r1),
+				                     jit_vf(i.r2));
+			}
+			else {
+				/* stack location */
+				to = jit_operand_mem(jit_abi_from(i.r1), JIT_SP,
+				                     stack_loc_f(f, i.r2));
+			}
+
+			vec_append(&src, &from);
+			vec_append(&dst, &to);
+			break;
+		}
+
 		case PARAM: {
 			/* move from argument stack to location */
 			jit_operand_t from = jit_operand_mem(
-- 
cgit v1.2.3