From 9fe8ccf4ae09018fdde01a9d83f9db10ad354221 Mon Sep 17 00:00:00 2001
From: Kimplul <kimi.h.kuparinen@gmail.com>
Date: Sat, 29 Jun 2024 20:11:34 +0300
Subject: work through branching instructions

---
 src/ejit.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 224 insertions(+), 10 deletions(-)

(limited to 'src/ejit.c')

diff --git a/src/ejit.c b/src/ejit.c
index e708740..adba1cc 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -48,10 +48,17 @@ struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc,
 
 	for (size_t i = 0; i < argc; ++i) {
 		switch (args[i].kind) {
-		case EJIT_OPERAND_GPR: emit_insn_r(f, PARAM, i, args[i].type,
-			                           args[i].r); break;
-		case EJIT_OPERAND_FPR: emit_insn_r(f, PARAM_F, i, args[i].type,
-			                           args[i].r); break;
+		case EJIT_OPERAND_GPR: {
+			assert(ejit_int_type(args[i].type));
+			emit_insn_r(f, PARAM, i, args[i].type, args[i].r);
+			break;
+		}
+
+		case EJIT_OPERAND_FPR: {
+			assert(ejit_float_type(args[i].type));
+			emit_insn_r(f, PARAM_F, i, args[i].type, args[i].r);
+			break;
+		}
 		default: abort();
 		}
 	}
@@ -90,6 +97,9 @@ void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr,
 		i.addr = addr;
 		vect_at(struct ejit_insn, f->insns, ii) = i;
 	}
+
+	/* doesn't really matter what we put here as long as it isn't 0 */
+	f->size = 1;
 }
 
 void ejit_destroy_func(struct ejit_func *f)
@@ -306,14 +316,14 @@ void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
 void ejit_ltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
               struct ejit_gpr r2)
 {
-	emit_insn_r(s, LTR, r0.r, r1.r, r2.r);
+	emit_insn_r(s, GER, r0.r, r2.r, r1.r);
 }
 
-struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0,
+struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0,
                             struct ejit_gpr r1)
 {
 	size_t addr = vec_len(&s->insns);
-	emit_insn_r(s, BLTR, 0, r0.r, r1.r);
+	emit_insn_r(s, BNER, 0, r0.r, r1.r);
 	return (struct ejit_reloc){.insn = addr};
 }
 
@@ -324,7 +334,16 @@ struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
 	return (struct ejit_reloc){.insn = addr};
 }
 
-struct ejit_reloc ejit_beqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
+struct ejit_reloc ejit_bner_f(struct ejit_func *s, struct ejit_fpr r0,
+                              struct ejit_fpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BNER_F, 0, r0.f, r1.f);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_beqr(struct ejit_func *s, struct ejit_gpr r0,
+                            struct ejit_gpr r1)
 {
 	size_t addr = vec_len(&s->insns);
 	emit_insn_r(s, BEQR, 0, r0.r, r1.r);
@@ -338,6 +357,92 @@ struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
 	return (struct ejit_reloc){.insn = addr};
 }
 
+struct ejit_reloc ejit_beqr_f(struct ejit_func *s, struct ejit_fpr r0,
+                              struct ejit_fpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BEQR_F, 0, r0.f, r1.f);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bger(struct ejit_func *s, struct ejit_gpr r0,
+                            struct ejit_gpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGER, 0, r0.r, r1.r);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bger_u(struct ejit_func *s, struct ejit_gpr r0,
+                              struct ejit_gpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGER_U, 0, r0.r, r1.r);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bger_f(struct ejit_func *s, struct ejit_fpr r0,
+                              struct ejit_fpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGER_F, 0, r0.f, r1.f);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bgei(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BGEI, 0, r0.r, o);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bgei_u(struct ejit_func *s, struct ejit_gpr r0,
+                              int64_t o)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BGEI_U, 0, r0.r, o);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bler(struct ejit_func *s, struct ejit_gpr r0,
+                            struct ejit_gpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGER, 0, r1.r, r0.r);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bler_u(struct ejit_func *s, struct ejit_gpr r0,
+                              struct ejit_gpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGER_U, 0, r1.r, r0.r);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bler_f(struct ejit_func *s, struct ejit_fpr r0,
+                              struct ejit_fpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGER_F, 0, r1.f, r0.f);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_blei(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BLEI, 0, r0.r, o);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_blei_u(struct ejit_func *s, struct ejit_gpr r0,
+                              int64_t o)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BLEI_U, 0, r0.r, o);
+	return (struct ejit_reloc){.insn = addr};
+}
+
 struct ejit_reloc ejit_bgti(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
 {
 	size_t addr = vec_len(&s->insns);
@@ -345,6 +450,85 @@ struct ejit_reloc ejit_bgti(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
 	return (struct ejit_reloc){.insn = addr};
 }
 
+struct ejit_reloc ejit_bgti_u(struct ejit_func *s, struct ejit_gpr r0,
+                              int64_t o)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BGTI_U, 0, r0.r, o);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bgtr(struct ejit_func *s, struct ejit_gpr r0,
+                            struct ejit_gpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGTR, 0, r0.r, r1.r);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bgtr_u(struct ejit_func *s, struct ejit_gpr r0,
+                              struct ejit_gpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGTR_U, 0, r0.r, r1.r);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bgtr_f(struct ejit_func *s, struct ejit_fpr r0,
+                              struct ejit_fpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGTR_F, 0, r0.f, r1.f);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0,
+                            struct ejit_gpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGTR, 0, r1.r, r0.r);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bltr_u(struct ejit_func *s, struct ejit_gpr r0,
+                              struct ejit_gpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGTR_U, 0, r1.r, r0.r);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bltr_f(struct ejit_func *s, struct ejit_fpr r0,
+                              struct ejit_fpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BGTR_F, 0, r1.f, r0.f);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_blti(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BLTI, 0, r0.r, o);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_blti_u(struct ejit_func *s, struct ejit_gpr r0,
+                              int64_t o)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BLTI_U, 0, r0.r, o);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bltgtr_f(struct ejit_func *s, struct ejit_fpr r0,
+                                struct ejit_fpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_r(s, BLTGTR_F, 0, r0.f, r1.f);
+	return (struct ejit_reloc){.insn = addr};
+}
+
 struct ejit_reloc ejit_jmp(struct ejit_func *s)
 {
 	size_t addr = vec_len(&s->insns);
@@ -352,6 +536,36 @@ struct ejit_reloc ejit_jmp(struct ejit_func *s)
 	return (struct ejit_reloc){.insn = addr};
 }
 
+struct ejit_reloc ejit_bmci(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BMCI, 0, r0.r, o);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bmcr(struct ejit_func *s, struct ejit_gpr r0,
+                            struct ejit_gpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BMCR, 0, r0.r, r1.r);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bmsi(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BMSI, 0, r0.r, o);
+	return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bmsr(struct ejit_func *s, struct ejit_gpr r0,
+                            struct ejit_gpr r1)
+{
+	size_t addr = vec_len(&s->insns);
+	emit_insn_i(s, BMSR, 0, r0.r, r1.r);
+	return (struct ejit_reloc){.insn = addr};
+}
+
 static struct interp_state create_interp_state()
 {
 	struct interp_state state;
@@ -381,7 +595,7 @@ long ejit_run_interp(struct ejit_func *f, size_t argc,
 
 long ejit_run_func(struct ejit_func *f, size_t argc, struct ejit_arg args[argc])
 {
-	assert(f->gpr && "trying to run a function that hasn't been compiled");
+	assert(f->size && "trying to run a function that hasn't been compiled");
 	assert(f->rtype == EJIT_VOID || ejit_int_type(f->rtype));
 	if (f->arena)
 		return ((ejit_escape_t)f->arena)(argc, args);
@@ -395,7 +609,7 @@ long ejit_run_func(struct ejit_func *f, size_t argc, struct ejit_arg args[argc])
 double ejit_run_func_f(struct ejit_func *f, size_t argc,
                        struct ejit_arg args[argc])
 {
-	assert(f->fpr && "trying to run a function that hasn't been compiled");
+	assert(f->size && "trying to run a function that hasn't been compiled");
 	assert(ejit_float_type(f->rtype));
 	if (f->arena)
 		return ((ejit_escape_f_t)f->arena)(argc, args);
-- 
cgit v1.2.3