aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2025-03-07 18:50:34 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2025-03-07 18:52:54 +0200
commitba9145b0b7af2a82c62f8dfa28807958af5d0c8d (patch)
tree52e14e07d82d57a305334f1300293d6b0af75aca
parent6d00dddef440590eaba9acdc9bbd093653d46519 (diff)
downloadejit-ba9145b0b7af2a82c62f8dfa28807958af5d0c8d.tar.gz
ejit-ba9145b0b7af2a82c62f8dfa28807958af5d0c8d.zip
make code a bit more robust
+ Should be more difficult to make mistakes in the future, ejit can now automatically keep track of how many register slots are used and if 64 bit mode is required. Slight runtime overhead, but not too bad.
-rw-r--r--.gitignore1
-rw-r--r--examples/loop.c5
-rw-r--r--examples/matrix_mult.c133
-rw-r--r--include/ejit/ejit.h19
-rw-r--r--scripts/makefile6
-rw-r--r--src/common.h1
-rw-r--r--src/compile/compile.c24
-rw-r--r--src/ejit.c871
-rw-r--r--src/interp.inc6
-rw-r--r--tests/andr64.c2
-rw-r--r--tests/ldi_d.c2
-rw-r--r--tests/ldi_f.c2
-rw-r--r--tests/stxi_16.c2
-rw-r--r--tests/stxi_32.c2
-rw-r--r--tests/stxi_8.c2
-rw-r--r--tests/stxi_d.c2
-rw-r--r--tests/stxi_f.c2
17 files changed, 741 insertions, 341 deletions
diff --git a/.gitignore b/.gitignore
index 6bdeaa9..c45d138 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ docs/output
build
ejit.o
test-*
+examples/matrix_mult
examples/loop
examples/fib
examples/*.d
diff --git a/examples/loop.c b/examples/loop.c
index f4f66ae..51ba2e9 100644
--- a/examples/loop.c
+++ b/examples/loop.c
@@ -20,10 +20,7 @@ int main()
ejit_patch(f, r, l);
- /* the highest location we used was 3, so we need to request 4 locations
- * for general purpose registers in total. No floating point registers,
- * so 0. */
- ejit_compile_func(f, 4, 0, true);
+ ejit_compile_func(f);
long result = ejit_run_func(f, 0, NULL); // no args so this is fine
printf("%ld\n", result);
diff --git a/examples/matrix_mult.c b/examples/matrix_mult.c
new file mode 100644
index 0000000..04ebb9d
--- /dev/null
+++ b/examples/matrix_mult.c
@@ -0,0 +1,133 @@
+#include <stdio.h>
+#include "../include/ejit/ejit.h"
+
+#define X 400
+int A[X][X];
+int B[X][X];
+int C[X][X];
+
+static void init_matrices(int A[X][X], int B[X][X])
+{
+ int counter = 0;
+ for (size_t i = 0; i < X; ++i)
+ for (size_t j = 0; j < X; ++j) {
+ A[i][j] = counter;
+ B[i][j] = counter;
+ C[i][j] = 0;
+
+ counter++;
+ }
+}
+
+static int hash(int C[X][X])
+{
+ int h = 0;
+ for (size_t i = 0; i < X; ++i)
+ for (size_t j = 0; j < X; ++j) {
+ h += C[i][j];
+ }
+
+ return h;
+}
+
+static struct ejit_func *compile()
+{
+#define IR EJIT_GPR(0)
+#define JR EJIT_GPR(1)
+#define KR EJIT_GPR(2)
+#define AR EJIT_GPR(3)
+#define BR EJIT_GPR(4)
+#define CR EJIT_GPR(5)
+#define AX EJIT_GPR(6)
+#define BX EJIT_GPR(7)
+#define CX EJIT_GPR(8)
+#define TMP EJIT_GPR(9)
+
+ struct ejit_operand args[3] = {
+ EJIT_OPERAND_GPR(3, EJIT_TYPE(int *)),
+ EJIT_OPERAND_GPR(4, EJIT_TYPE(int *)),
+ EJIT_OPERAND_GPR(5, EJIT_TYPE(int *))
+ };
+ struct ejit_func *f = ejit_create_func(EJIT_VOID, 3, args);
+
+ ejit_movi(f, IR, 0);
+ struct ejit_label out = ejit_label(f);
+ struct ejit_reloc outer = ejit_bgei(f, IR, X);
+
+ ejit_movi(f, JR, 0);
+ struct ejit_label mid = ejit_label(f);
+ struct ejit_reloc midder = ejit_bgei(f, JR, X);
+
+ ejit_movi(f, KR, 0);
+ struct ejit_label in = ejit_label(f);
+ struct ejit_reloc inner = ejit_bgei(f, KR, X);
+
+ /* A[i][k] at addr 4 * (i * 400 + k) */
+ ejit_movi(f, TMP, 400);
+ ejit_mulr(f, AX, IR, TMP);
+ ejit_addr(f, AX, AX, KR);
+ ejit_movi(f, TMP, 4);
+ ejit_lshi(f, AX, AX, 2);
+ EJIT_LDXR(f, int, AX, AR, AX);
+
+ /* B[k][j] at addr 4 * (k * 400 + j) */
+ ejit_movi(f, TMP, 400);
+ ejit_mulr(f, BX, KR, TMP);
+ ejit_addr(f, BX, BX, JR);
+ ejit_movi(f, TMP, 4);
+ ejit_lshi(f, BX, BX, 2);
+ EJIT_LDXR(f, int, BX, BR, BX);
+
+ /* C[i][j] at addr 4 * (i * 400 + j) */
+ ejit_movi(f, TMP, 400);
+ ejit_mulr(f, CX, IR, TMP);
+ ejit_addr(f, CX, CX, JR);
+ ejit_movi(f, TMP, 4);
+ /* reuse address */
+ ejit_lshi(f, TMP, CX, 2);
+ EJIT_LDXR(f, int, CX, CR, TMP);
+
+ ejit_mulr(f, AX, AX, BX);
+ ejit_addr(f, CX, CX, AX);
+
+ /* store result */
+ EJIT_STXR(f, int, CX, CR, TMP);
+
+ /* increment inner */
+ ejit_addi(f, KR, KR, 1);
+ ejit_patch(f, ejit_jmp(f), in);
+ /* end of inner */
+ ejit_patch(f, inner, ejit_label(f));
+
+ /* increment midder */
+ ejit_addi(f, JR, JR, 1);
+ ejit_patch(f, ejit_jmp(f), mid);
+ /* end of midder */
+ ejit_patch(f, midder, ejit_label(f));
+
+ /* increment outer */
+ ejit_addi(f, IR, IR, 1);
+ ejit_patch(f, ejit_jmp(f), out);
+ /* end of outer */
+ ejit_patch(f, outer, ejit_label(f));
+
+ /* return */
+ ejit_ret(f);
+ ejit_compile_func(f);
+ return f;
+}
+
+int main()
+{
+ init_matrices(A, B);
+ struct ejit_func *f = compile();
+ struct ejit_arg args[3] = {
+ EJIT_ARG(A, int *),
+ EJIT_ARG(B, int *),
+ EJIT_ARG(C, int *)
+ };
+ ejit_run_func(f, 3, args);
+ printf("%d\n", hash(C));
+ ejit_destroy_func(f);
+ return 0;
+}
diff --git a/include/ejit/ejit.h b/include/ejit/ejit.h
index 17fa0fb..aa7cc45 100644
--- a/include/ejit/ejit.h
+++ b/include/ejit/ejit.h
@@ -168,7 +168,7 @@ struct ejit_operand {
enum ejit_type type;
union {
- long r;
+ int64_t r;
double d;
};
};
@@ -178,8 +178,7 @@ struct ejit_func;
struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc,
const struct ejit_operand args[argc]);
-void ejit_compile_func(struct ejit_func *f, size_t gpr, size_t fpr,
- bool use_64);
+void ejit_compile_func(struct ejit_func *f);
void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr,
bool use_64, bool try_jit);
@@ -532,6 +531,20 @@ static inline void ejit_stxi_ptr(struct ejit_func *s, struct ejit_gpr r0,
double: ejit_stxi_d, \
default: ejit_stxi_ptr)((f), (r0), (r1), (o))
+#define EJIT_STXR(f, t, r0, r1, r2) \
+ _Generic((t)(0), \
+ int8_t: ejit_stxr_8, \
+ uint8_t: ejit_stxr_8, \
+ int16_t: ejit_stxr_16, \
+ uint16_t: ejit_stxr_16, \
+ int32_t: ejit_stxr_32, \
+ uint32_t: ejit_stxr_32, \
+ int64_t: ejit_stxr_64, \
+ uint64_t: ejit_stxr_64, \
+ float: ejit_stxr_f, \
+ double: ejit_stxr_d, \
+ default: ejit_stxi_ptr)((f), (r0), (r1), (r2))
+
void ejit_stxr_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2);
diff --git a/scripts/makefile b/scripts/makefile
index 0b4f42b..3f1e119 100644
--- a/scripts/makefile
+++ b/scripts/makefile
@@ -61,7 +61,11 @@ COMPILE_EJIT = $(COMPILE) $(EJIT_FLAGS)
ejit.o: $(EJIT_OBJS)
ld -relocatable $(EJIT_OBJS) -o $@
-examples: examples/loop examples/fib
+examples: examples/loop examples/fib examples/matrix_mult
+
+examples/matrix_mult: examples/matrix_mult.c ejit.o
+ $(COMPILE_EJIT) examples/matrix_mult.c ejit.o -o $@
+
examples/loop: examples/loop.c ejit.o
$(COMPILE_EJIT) examples/loop.c ejit.o -o $@
diff --git a/src/common.h b/src/common.h
index 5cc0c7f..cf5bdf6 100644
--- a/src/common.h
+++ b/src/common.h
@@ -255,6 +255,7 @@ struct ejit_func {
size_t gpr;
size_t fpr;
+ bool use_64;
void *arena;
void *direct_call;
diff --git a/src/compile/compile.c b/src/compile/compile.c
index 0411a3e..9a97b3a 100644
--- a/src/compile/compile.c
+++ b/src/compile/compile.c
@@ -63,7 +63,7 @@ static jit_off_t stack_loc_f(struct ejit_func *f, size_t l)
static jit_gpr_t getloc(struct ejit_func *f, jit_state_t *j, size_t l, size_t i)
{
- (void)(f);
+ assert(l < f->gpr);
if (l < jit_v_num())
return jit_v(l);
@@ -74,7 +74,7 @@ static jit_gpr_t getloc(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);
+ assert(l < f->fpr);
if (l < jit_vf_num())
return jit_vf(l);
@@ -85,7 +85,7 @@ static jit_fpr_t getloc_f(struct ejit_func *f, jit_state_t *j, size_t l,
static jit_fpr_t getloc_d(struct ejit_func *f, jit_state_t *j, size_t l,
size_t i)
{
- (void)(f);
+ assert(l < f->fpr);
if (l < jit_vf_num())
return jit_vf(l);
@@ -97,7 +97,7 @@ static jit_fpr_t getloc_d(struct ejit_func *f, jit_state_t *j, size_t l,
static jit_gpr_t getgpr(struct ejit_func *f, size_t l, size_t i)
{
- (void)(f);
+ assert(l < f->gpr);
if (l < jit_v_num())
return jit_v(l);
@@ -106,7 +106,7 @@ static jit_gpr_t getgpr(struct ejit_func *f, size_t l, size_t i)
static jit_fpr_t getfpr(struct ejit_func *f, size_t l, size_t i)
{
- (void)(f);
+ assert(l < f->fpr);
if (l < jit_vf_num())
return jit_vf(l);
@@ -115,7 +115,7 @@ static jit_fpr_t getfpr(struct ejit_func *f, size_t l, size_t i)
static void putloc(struct ejit_func *f, jit_state_t *j, size_t l, jit_gpr_t r)
{
- (void)(f);
+ assert(l < f->gpr);
if (l < jit_v_num()) {
assert(jit_v(l).regno == r.regno);
return;
@@ -126,6 +126,7 @@ static void putloc(struct ejit_func *f, jit_state_t *j, size_t l, jit_gpr_t r)
static void putloc_f(struct ejit_func *f, jit_state_t *j, size_t l, jit_fpr_t r)
{
+ assert(l < f->fpr);
if (l < jit_vf_num()) {
assert(jit_v(l).regno == r.regno);
return;
@@ -136,6 +137,7 @@ static void putloc_f(struct ejit_func *f, jit_state_t *j, size_t l, jit_fpr_t r)
static void putloc_d(struct ejit_func *f, jit_state_t *j, size_t l, jit_fpr_t r)
{
+ assert(l < f->fpr);
if (l < jit_vf_num()) {
assert(jit_v(l).regno == r.regno);
return;
@@ -1992,7 +1994,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case RETVAL_D: compile_retval_d(f, j, i); break;
case RETR: {
- jit_gpr_t r = getloc(f, j, i.r0, 0);
+ jit_gpr_t r = getloc(f, j, i.r1, 0);
/* R0 won't get overwritten by jit_leave_jit_abi */
jit_movr(j, JIT_R0, r);
jit_shrink_stack(j, stack);
@@ -2002,7 +2004,7 @@ 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_fpr_t r = getloc_f(f, j, i.r1, 0);
/* convert float to double so the return types match */
jit_extr_f_d(j, JIT_F0, r);
jit_shrink_stack(j, stack);
@@ -2012,7 +2014,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
}
case RETR_D: {
- jit_fpr_t r = getloc_d(f, j, i.r0, 0);
+ jit_fpr_t r = getloc_d(f, j, i.r1, 0);
jit_movr_d(j, JIT_F0, r);
jit_shrink_stack(j, stack);
jit_leave_jit_abi(j, gprs, fprs, frame);
@@ -2037,7 +2039,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case PARAM_F: {
jit_operand_t to;
- if (i.r0 < jit_vf_num()) {
+ if (i.r2 < jit_vf_num()) {
/* regular register */
to = jit_operand_fpr(jit_abi_from(i.r1),
jit_vf(i.r2));
@@ -2054,7 +2056,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena,
case PARAM: {
jit_operand_t to;
- if (i.r0 < jit_v_num()) {
+ if (i.r2 < jit_v_num()) {
/* regular register */
to = jit_operand_gpr(jit_abi_from(i.r1),
jit_v(i.r2));
diff --git a/src/ejit.c b/src/ejit.c
index 7a31c5a..34526b8 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -6,38 +6,275 @@
#include "common.h"
-static void emit_insn_i(struct ejit_func *f, enum ejit_opcode op, size_t r0,
- size_t r1, int64_t o)
+static size_t max(size_t a, size_t b)
{
- struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .o = o};
+ return a > b ? a : b;
+}
+
+static void update_gpr(struct ejit_func *f, struct ejit_gpr r0)
+{
+ /* +1 because we want to look at count, not index */
+ f->gpr = max(f->gpr, r0.r + 1);
+}
+
+static void update_fpr(struct ejit_func *f, struct ejit_fpr f0)
+{
+ f->fpr = max(f->fpr, f0.f + 1);
+}
+
+static void update_64(struct ejit_func *f, int64_t o)
+{
+ if (f->use_64)
+ return;
+
+ int32_t x = o >> 32;
+ f->use_64 = x != -1 && x != 0;
+}
+
+static void emit_insn_o(struct ejit_func *f, enum ejit_opcode op)
+{
+ struct ejit_insn i = {.op = op};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_oi(struct ejit_func *f, enum ejit_opcode op, int64_t o)
+{
+ update_64(f, o);
+ struct ejit_insn i = {.op = op, .o = o};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_oF(struct ejit_func *f, enum ejit_opcode op, float o)
+{
+ struct ejit_insn i = {.op = op, .f = o};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_oD(struct ejit_func *f, enum ejit_opcode op, double o)
+{
+ struct ejit_insn i = {.op = op, .d = o};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_of(struct ejit_func *f, enum ejit_opcode op, struct ejit_fpr f0)
+{
+ update_fpr(f, f0);
+ struct ejit_insn i = {.op = op, .r0 = f0.f};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_or(struct ejit_func *f, enum ejit_opcode op, struct ejit_gpr r0)
+{
+ update_gpr(f, r0);
+ struct ejit_insn i = {.op = op, .r0 = r0.r};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_ori(struct ejit_func *f, enum ejit_opcode op, struct ejit_gpr r0, int64_t o)
+{
+ update_gpr(f, r0);
+ update_64(f, o);
+ struct ejit_insn i = {.op = op, .r0 = r0.r, .o = o};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_oxf(struct ejit_func *f, enum ejit_opcode op, struct ejit_fpr f1)
+{
+ update_fpr(f, f1);
+ struct ejit_insn i = {.op = op, .r1 = f1.f};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_orri(struct ejit_func *f, enum ejit_opcode op, struct ejit_gpr r0,
+ struct ejit_gpr r1, int64_t o)
+{
+ update_gpr(f, r0);
+ update_gpr(f, r1);
+ update_64(f, o);
+ struct ejit_insn i = {.op = op, .r0 = r0.r, .r1 = r1.r, .o = o};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_ar(struct ejit_func *f, enum ejit_opcode op, size_t idx, enum ejit_type type, struct ejit_gpr r0)
+{
+ update_gpr(f, r0);
+ struct ejit_insn i = {.op = op, .r0 = idx, .r1 = type, .r2 = r0.r};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_ai(struct ejit_func *f, enum ejit_opcode op, size_t idx, enum ejit_type type, int64_t o)
+{
+ update_64(f, o);
+ struct ejit_insn i = {.op = op, .r0 = idx, .r1 = type, .o = o};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_af(struct ejit_func *f, enum ejit_opcode op, size_t idx, enum ejit_type type, struct ejit_fpr f0)
+{
+ update_fpr(f, f0);
+ struct ejit_insn i = {.op = op, .r0 = idx, .r1 = type, .r2 = f0.f};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_ad(struct ejit_func *f, enum ejit_opcode op, size_t idx, enum ejit_type type, double d)
+{
+ struct ejit_insn i = {.op = op, .r0 = idx, .r1 = type, .d = d};
insns_append(&f->insns, i);
}
-static void emit_insn_r(struct ejit_func *f, enum ejit_opcode op, size_t r0,
- size_t r1, size_t r2)
+static void emit_insn_orr(struct ejit_func *f, enum ejit_opcode op, struct ejit_gpr r0,
+ struct ejit_gpr r1)
{
- struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .r2 = r2};
+ update_gpr(f, r0);
+ update_gpr(f, r1);
+ struct ejit_insn i = {.op = op, .r0 = r0.r, .r1 = r1.r};
insns_append(&f->insns, i);
}
-static void emit_insn_p(struct ejit_func *f, enum ejit_opcode op, size_t r0,
- size_t r1, void *p)
+static void emit_insn_orrr(struct ejit_func *f, enum ejit_opcode op, struct ejit_gpr r0,
+ struct ejit_gpr r1, struct ejit_gpr r2)
{
- struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .p = p};
+ update_gpr(f, r0);
+ update_gpr(f, r1);
+ update_gpr(f, r2);
+ struct ejit_insn i = {.op = op, .r0 = r0.r, .r1 = r1.r, .r2 = r2.r};
insns_append(&f->insns, i);
}
-static void emit_insn_f(struct ejit_func *f, enum ejit_opcode op, size_t r0,
- size_t r1, float d)
+static void emit_insn_off(struct ejit_func *f, enum ejit_opcode op, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
- struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .f = d};
+ update_fpr(f, f0);
+ update_fpr(f, f1);
+ struct ejit_insn i = {.op = op, .r0 = f0.f, .r1 = f1.f};
insns_append(&f->insns, i);
}
-static void emit_insn_d(struct ejit_func *f, enum ejit_opcode op, size_t r0,
- size_t r1, double d)
+static void emit_insn_offf(struct ejit_func *f, enum ejit_opcode op, struct ejit_fpr f0,
+ struct ejit_fpr f1, struct ejit_fpr f2)
{
- struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .d = d};
+ update_fpr(f, f0);
+ update_fpr(f, f1);
+ update_fpr(f, f2);
+ struct ejit_insn i = {.op = op, .r0 = f0.f, .r1 = f1.f, .r2 = f2.f};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_orf(struct ejit_func *f, enum ejit_opcode op, struct ejit_gpr r0,
+ struct ejit_fpr f1)
+{
+ update_gpr(f, r0);
+ update_fpr(f, f1);
+ struct ejit_insn i = {.op = op, .r0 = r0.r, .r1 = f1.f};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_oxr(struct ejit_func *f, enum ejit_opcode op,
+ struct ejit_gpr r1)
+{
+ update_gpr(f, r1);
+ struct ejit_insn i = {.op = op, .r1 = r1.r};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_oxrr(struct ejit_func *f, enum ejit_opcode op,
+ struct ejit_gpr r1, struct ejit_gpr r2)
+{
+ update_gpr(f, r1);
+ update_gpr(f, r2);
+ struct ejit_insn i = {.op = op, .r1 = r1.r, .r2 = r2.r};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_oxri(struct ejit_func *f, enum ejit_opcode op,
+ struct ejit_gpr r1, int64_t o)
+{
+ update_gpr(f, r1);
+ update_64(f, o);
+ struct ejit_insn i = {.op = op, .r1 = r1.r, .o = o};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_ofr(struct ejit_func *f, enum ejit_opcode op, struct ejit_fpr f0,
+ struct ejit_gpr r1)
+{
+ update_fpr(f, f0);
+ update_gpr(f, r1);
+ struct ejit_insn i = {.op = op, .r0 = f0.f, .r1 = r1.r};
+ insns_append(&f->insns, i);
+}
+
+
+static void emit_insn_ofrr(struct ejit_func *f, enum ejit_opcode op, struct ejit_fpr f0,
+ struct ejit_gpr r1, struct ejit_gpr r2)
+{
+ update_fpr(f, f0);
+ update_gpr(f, r1);
+ update_gpr(f, r2);
+ struct ejit_insn i = {.op = op, .r0 = f0.f, .r1 = r1.r, .r2 = r2.r};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_ofri(struct ejit_func *f, enum ejit_opcode op, struct ejit_fpr f0,
+ struct ejit_gpr r1, int64_t o)
+{
+ update_fpr(f, f0);
+ update_gpr(f, r1);
+ update_64(f, o);
+ struct ejit_insn i = {.op = op, .r0 = f0.f, .r1 = r1.r, .o = o};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_orff(struct ejit_func *f, enum ejit_opcode op, struct ejit_gpr r0,
+ struct ejit_fpr f1, struct ejit_fpr f2)
+{
+ update_gpr(f, r0);
+ update_fpr(f, f1);
+ update_fpr(f, f2);
+ struct ejit_insn i = {.op = op, .r0 = r0.r, .r1 = f1.f, .r2 = f2.f};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_oxff(struct ejit_func *f, enum ejit_opcode op,
+ struct ejit_fpr f1, struct ejit_fpr f2)
+{
+ update_fpr(f, f1);
+ update_fpr(f, f2);
+ struct ejit_insn i = {.op = op, .r1 = f1.f, .r2 = f2.f};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_op(struct ejit_func *f, enum ejit_opcode op, void *p)
+{
+ struct ejit_insn i = {.op = op, .p = p};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_orp(struct ejit_func *f, enum ejit_opcode op, struct ejit_gpr r0, void *p)
+{
+ update_gpr(f, r0);
+ struct ejit_insn i = {.op = op, .r0 = r0.r, .p = p};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_ofp(struct ejit_func *f, enum ejit_opcode op, struct ejit_fpr f0, void *p)
+{
+ update_fpr(f, f0);
+ struct ejit_insn i = {.op = op, .r0 = f0.f, .p = p};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_ofF(struct ejit_func *f, enum ejit_opcode op, struct ejit_fpr f0, float d)
+{
+ update_fpr(f, f0);
+ struct ejit_insn i = {.op = op, .r0 = f0.f, .f = d};
+ insns_append(&f->insns, i);
+}
+
+static void emit_insn_ofD(struct ejit_func *f, enum ejit_opcode op, struct ejit_fpr f0, double d)
+{
+ update_fpr(f, f0);
+ struct ejit_insn i = {.op = op, .r0 = f0.f, .d = d};
insns_append(&f->insns, i);
}
@@ -54,41 +291,46 @@ struct ejit_func *ejit_create_func(enum ejit_type rtype, size_t argc,
f->arena = NULL;
f->direct_call = NULL;
f->size = 0;
+ f->gpr = 0;
+ f->fpr = 0;
+ f->use_64 = false;
for (size_t i = 0; i < argc; ++i) {
switch (args[i].kind) {
case EJIT_OPERAND_GPR: {
assert(ejit_int_type(args[i].type));
- emit_insn_r(f, PARAM, i, args[i].type, args[i].r);
+ emit_insn_ar(f, PARAM, i, args[i].type, EJIT_GPR(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);
+ emit_insn_af(f, PARAM_F, i, args[i].type, EJIT_FPR(args[i].r));
break;
}
default: abort();
}
}
- emit_insn_i(f, START, 0, 0, 0);
+ emit_insn_o(f, START);
return f;
}
-void ejit_compile_func(struct ejit_func *f, size_t gpr, size_t fpr, bool use_64)
+void ejit_compile_func(struct ejit_func *f)
{
- ejit_select_compile_func(f, gpr, fpr, use_64, true);
+ ejit_select_compile_func(f, f->gpr, f->fpr, f->use_64, true);
}
void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr,
bool use_64, bool try_jit)
{
/* emit a final end instruction in case user didn't do a return */
- emit_insn_i(f, END, 0, 0, 0);
+ emit_insn_o(f, END);
- f->gpr = gpr;
- f->fpr = fpr;
+ /* user can get some sanity checking done by passing these explicitly */
+ assert(gpr >= f->gpr);
+ assert(fpr >= f->fpr);
+ assert(!f->use_64 || (use_64 == f->use_64));
/* try to jit compile if possible */
if (try_jit && ejit_compile(f, use_64))
@@ -145,19 +387,15 @@ void ejit_calli(struct ejit_func *s, struct ejit_func *f, size_t argc,
{
for (size_t i = 0; i < argc; ++i) {
switch (args[i].kind) {
- case EJIT_OPERAND_GPR: emit_insn_r(s, ARG, i, args[i].type,
- args[i].r); break;
- case EJIT_OPERAND_FPR: emit_insn_r(s, ARG_F, i, args[i].type,
- args[i].r); break;
- case EJIT_OPERAND_IMM: emit_insn_i(s, ARG_I, i, args[i].type,
- args[i].r); break;
- case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, i, args[i].type,
- args[i].d); break;
+ case EJIT_OPERAND_GPR: emit_insn_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break;
+ case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break;
+ case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break;
+ case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break;
default: abort();
}
}
- emit_insn_p(s, CALLI, 0, 0, f);
+ emit_insn_op(s, CALLI, f);
}
void ejit_escapei(struct ejit_func *s, ejit_escape_t f, size_t argc,
@@ -165,19 +403,15 @@ void ejit_escapei(struct ejit_func *s, ejit_escape_t f, size_t argc,
{
for (size_t i = 0; i < argc; ++i) {
switch (args[i].kind) {
- case EJIT_OPERAND_GPR: emit_insn_r(s, ARG, i, args[i].type,
- args[i].r); break;
- case EJIT_OPERAND_FPR: emit_insn_r(s, ARG_F, i, args[i].type,
- args[i].r); break;
- case EJIT_OPERAND_IMM: emit_insn_r(s, ARG_I, i, args[i].type,
- args[i].r); break;
- case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, i, args[i].type,
- args[i].d); break;
+ case EJIT_OPERAND_GPR: emit_insn_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break;
+ case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break;
+ case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break;
+ case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break;
default: abort();
}
}
- emit_insn_p(s, ESCAPEI, 0, 0, f);
+ emit_insn_op(s, ESCAPEI, f);
}
void ejit_escapei_f(struct ejit_func *s, ejit_escape_f_t f, size_t argc,
@@ -185,600 +419,599 @@ void ejit_escapei_f(struct ejit_func *s, ejit_escape_f_t f, size_t argc,
{
for (size_t i = 0; i < argc; ++i) {
switch (args[i].kind) {
- case EJIT_OPERAND_GPR: emit_insn_r(s, ARG, i, args[i].type,
- args[i].r); break;
- case EJIT_OPERAND_FPR: emit_insn_r(s, ARG_F, i, args[i].type,
- args[i].r); break;
- case EJIT_OPERAND_IMM: emit_insn_r(s, ARG_I, i, args[i].type,
- args[i].r); break;
- case EJIT_OPERAND_FLT: emit_insn_f(s, ARG_FI, i, args[i].type,
- args[i].d); break;
+ case EJIT_OPERAND_GPR: emit_insn_ar(s, ARG, i, args[i].type, EJIT_GPR(args[i].r)); break;
+ case EJIT_OPERAND_FPR: emit_insn_af(s, ARG_F, i, args[i].type, EJIT_FPR(args[i].r)); break;
+ case EJIT_OPERAND_IMM: emit_insn_ai(s, ARG_I, i, args[i].type, args[i].r); break;
+ case EJIT_OPERAND_FLT: emit_insn_ad(s, ARG_FI, i, args[i].type, args[i].d); break;
default: abort();
}
}
- emit_insn_p(s, ESCAPEI_F, 0, 0, f);
+ emit_insn_op(s, ESCAPEI_F, f);
}
void ejit_retval(struct ejit_func *s, struct ejit_gpr r0)
{
- emit_insn_i(s, RETVAL, r0.r, 0, 0);
+ emit_insn_or(s, RETVAL, r0);
}
-void ejit_retval_f(struct ejit_func *s, struct ejit_fpr r0)
+void ejit_retval_f(struct ejit_func *s, struct ejit_fpr f0)
{
- emit_insn_i(s, RETVAL_F, r0.f, 0, 0);
+ emit_insn_of(s, RETVAL_F, f0);
}
-void ejit_retval_d(struct ejit_func *s, struct ejit_fpr r0)
+void ejit_retval_d(struct ejit_func *s, struct ejit_fpr f0)
{
- emit_insn_i(s, RETVAL_D, r0.f, 0, 0);
+ emit_insn_of(s, RETVAL_D, f0);
}
void ejit_sti_8(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, STI8, r0.r, 0, p);
+ emit_insn_orp(s, STI8, r0, p);
}
void ejit_sti_16(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, STI16, r0.r, 0, p);
+ emit_insn_orp(s, STI16, r0, p);
}
void ejit_sti_32(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, STI32, r0.r, 0, p);
+ emit_insn_orp(s, STI32, r0, p);
}
void ejit_sti_64(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, STI64, r0.r, 0, p);
+ s->use_64 = true;
+ emit_insn_orp(s, STI64, r0, p);
}
-void ejit_sti_f(struct ejit_func *s, struct ejit_fpr r0, void *p)
+void ejit_sti_f(struct ejit_func *s, struct ejit_fpr f0, void *p)
{
- emit_insn_p(s, STIF, r0.f, 0, p);
+ emit_insn_ofp(s, STIF, f0, p);
}
-void ejit_sti_d(struct ejit_func *s, struct ejit_fpr r0, void *p)
+void ejit_sti_d(struct ejit_func *s, struct ejit_fpr f0, void *p)
{
- emit_insn_p(s, STID, r0.f, 0, p);
+ emit_insn_ofp(s, STID, f0, p);
}
void ejit_stxi_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, STXI8, r0.r, r1.r, o);
+ emit_insn_orri(s, STXI8, r0, r1, o);
}
void ejit_stxi_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, STXI16, r0.r, r1.r, o);
+ emit_insn_orri(s, STXI16, r0, r1, o);
}
void ejit_stxi_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, STXI32, r0.r, r1.r, o);
+ emit_insn_orri(s, STXI32, r0, r1, o);
}
void ejit_stxi_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, STXI64, r0.r, r1.r, o);
+ s->use_64 = true;
+ emit_insn_orri(s, STXI64, r0, r1, o);
}
-void ejit_stxi_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
+void ejit_stxi_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, STXIF, r0.f, r1.r, o);
+ emit_insn_ofri(s, STXIF, f0, r1, o);
}
-void ejit_stxi_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
+void ejit_stxi_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, STXID, r0.f, r1.r, o);
+ emit_insn_ofri(s, STXID, f0, r1, o);
}
void ejit_stxr_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, STXR8, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, STXR8, r0, r1, r2);
}
void ejit_stxr_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, STXR16, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, STXR16, r0, r1, r2);
}
void ejit_stxr_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, STXR32, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, STXR32, r0, r1, r2);
}
void ejit_stxr_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, STXR64, r0.r, r1.r, r2.r);
+ s->use_64 = true;
+ emit_insn_orrr(s, STXR64, r0, r1, r2);
}
-void ejit_stxr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
+void ejit_stxr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, STXRF, r0.f, r1.r, r2.r);
+ emit_insn_ofrr(s, STXRF, f0, r1, r2);
}
-void ejit_stxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
+void ejit_stxr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, STXRD, r0.f, r1.r, r2.r);
+ emit_insn_ofrr(s, STXRD, f0, r1, r2);
}
void ejit_ldi_i8(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, LDI8, r0.r, 0, p);
+ emit_insn_orp(s, LDI8, r0, p);
}
void ejit_ldi_i16(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, LDI16, r0.r, 0, p);
+ emit_insn_orp(s, LDI16, r0, p);
}
void ejit_ldi_i32(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, LDI32, r0.r, 0, p);
+ emit_insn_orp(s, LDI32, r0, p);
}
void ejit_ldi_i64(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, LDI64, r0.r, 0, p);
+ emit_insn_orp(s, LDI64, r0, p);
}
void ejit_ldi_u8(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, LDIU8, r0.r, 0, p);
+ emit_insn_orp(s, LDIU8, r0, p);
}
void ejit_ldi_u16(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, LDIU16, r0.r, 0, p);
+ emit_insn_orp(s, LDIU16, r0, p);
}
void ejit_ldi_u32(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, LDIU32, r0.r, 0, p);
+ emit_insn_orp(s, LDIU32, r0, p);
}
void ejit_ldi_u64(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
- emit_insn_p(s, LDIU64, r0.r, 0, p);
+ emit_insn_orp(s, LDIU64, r0, p);
}
-void ejit_ldi_f(struct ejit_func *s, struct ejit_fpr r0, void *p)
+void ejit_ldi_f(struct ejit_func *s, struct ejit_fpr f0, void *p)
{
- emit_insn_p(s, LDIF, r0.f, 0, p);
+ emit_insn_ofp(s, LDIF, f0, p);
}
-void ejit_ldi_d(struct ejit_func *s, struct ejit_fpr r0, void *p)
+void ejit_ldi_d(struct ejit_func *s, struct ejit_fpr f0, void *p)
{
- emit_insn_p(s, LDID, r0.f, 0, p);
+ emit_insn_ofp(s, LDID, f0, p);
}
void ejit_ldxi_i8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LDXI8, r0.r, r1.r, o);
+ emit_insn_orri(s, LDXI8, r0, r1, o);
}
void ejit_ldxi_i16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LDXI16, r0.r, r1.r, o);
+ emit_insn_orri(s, LDXI16, r0, r1, o);
}
void ejit_ldxi_i32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LDXI32, r0.r, r1.r, o);
+ emit_insn_orri(s, LDXI32, r0, r1, o);
}
void ejit_ldxi_i64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LDXI64, r0.r, r1.r, o);
+ emit_insn_orri(s, LDXI64, r0, r1, o);
}
void ejit_ldxi_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LDXIU8, r0.r, r1.r, o);
+ emit_insn_orri(s, LDXIU8, r0, r1, o);
}
void ejit_ldxi_u16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LDXIU16, r0.r, r1.r, o);
+ emit_insn_orri(s, LDXIU16, r0, r1, o);
}
void ejit_ldxi_u32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LDXIU32, r0.r, r1.r, o);
+ emit_insn_orri(s, LDXIU32, r0, r1, o);
}
void ejit_ldxi_u64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LDXIU64, r0.r, r1.r, o);
+ emit_insn_orri(s, LDXIU64, r0, r1, o);
}
-void ejit_ldxi_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
+void ejit_ldxi_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LDXIF, r0.f, r1.r, o);
+ emit_insn_ofri(s, LDXIF, f0, r1, o);
}
-void ejit_ldxi_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
+void ejit_ldxi_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LDXID, r0.f, r1.r, o);
+ emit_insn_ofri(s, LDXID, f0, r1, o);
}
void ejit_ldxr_i8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LDXR8, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, LDXR8, r0, r1, r2);
}
void ejit_ldxr_i16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LDXR16, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, LDXR16, r0, r1, r2);
}
void ejit_ldxr_i32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LDXR32, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, LDXR32, r0, r1, r2);
}
void ejit_ldxr_i64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LDXR64, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, LDXR64, r0, r1, r2);
}
void ejit_ldxr_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LDXRU8, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, LDXRU8, r0, r1, r2);
}
void ejit_ldxr_u16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LDXRU16, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, LDXRU16, r0, r1, r2);
}
void ejit_ldxr_u32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LDXRU32, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, LDXRU32, r0, r1, r2);
}
void ejit_ldxr_u64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LDXIU64, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, LDXIU64, r0, r1, r2);
}
-void ejit_ldxr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
+void ejit_ldxr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LDXRF, r0.f, r1.r, r2.r);
+ emit_insn_ofrr(s, LDXRF, f0, r1, r2);
}
-void ejit_ldxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
+void ejit_ldxr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LDXRD, r0.f, r1.r, r2.r);
+ emit_insn_ofrr(s, LDXRD, f0, r1, r2);
}
void ejit_ret(struct ejit_func *s)
{
- emit_insn_i(s, END, 0, 0, 0);
+ emit_insn_o(s, END);
}
void ejit_retr(struct ejit_func *s, struct ejit_gpr r0)
{
- emit_insn_r(s, RETR, r0.r, 0, 0);
+ emit_insn_oxr(s, RETR, r0);
}
-void ejit_retr_f(struct ejit_func *s, struct ejit_fpr r0)
+void ejit_retr_f(struct ejit_func *s, struct ejit_fpr f0)
{
- emit_insn_r(s, RETR_F, r0.f, 0, 0);
+ emit_insn_oxf(s, RETR_F, f0);
}
-void ejit_retr_d(struct ejit_func *s, struct ejit_fpr r0)
+void ejit_retr_d(struct ejit_func *s, struct ejit_fpr f0)
{
- emit_insn_r(s, RETR_D, r0.f, 0, 0);
+ emit_insn_oxf(s, RETR_D, f0);
}
void ejit_reti(struct ejit_func *s, int64_t i)
{
- emit_insn_i(s, RETI, 0, 0, i);
+ emit_insn_oi(s, RETI, i);
}
void ejit_reti_f(struct ejit_func *s, float f)
{
- emit_insn_f(s, RETI_F, 0, 0, f);
+ emit_insn_oF(s, RETI_F, f);
}
void ejit_reti_d(struct ejit_func *s, double f)
{
- emit_insn_d(s, RETI_F, 0, 0, f);
+ emit_insn_oD(s, RETI_D, f);
}
void ejit_extr_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
- emit_insn_i(s, EXTR8, r0.r, r1.r, 0);
+ emit_insn_orr(s, EXTR8, r0, r1);
}
void ejit_extr_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
- emit_insn_i(s, EXTR16, r0.r, r1.r, 0);
+ emit_insn_orr(s, EXTR16, r0, r1);
}
void ejit_extr_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
- emit_insn_i(s, EXTR32, r0.r, r1.r, 0);
+ emit_insn_orr(s, EXTR32, r0, r1);
}
void ejit_extr_u8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
- emit_insn_i(s, EXTRU8, r0.r, r1.r, 0);
+ emit_insn_orr(s, EXTRU8, r0, r1);
}
void ejit_extr_u16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
- emit_insn_i(s, EXTRU16, r0.r, r1.r, 0);
+ emit_insn_orr(s, EXTRU16, r0, r1);
}
void ejit_extr_u32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
- emit_insn_i(s, EXTRU32, r0.r, r1.r, 0);
+ emit_insn_orr(s, EXTRU32, r0, r1);
}
-void ejit_extr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1)
+void ejit_extr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1)
{
- emit_insn_i(s, EXTRF, r0.f, r1.r, 0);
+ emit_insn_ofr(s, EXTRF, f0, r1);
}
-void ejit_extr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1)
+void ejit_extr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_gpr r1)
{
- emit_insn_i(s, EXTRD, r0.f, r1.r, 0);
+ emit_insn_ofr(s, EXTRD, f0, r1);
}
void ejit_addr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, ADDR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, ADDR, r0, r1, r2);
}
-void ejit_addr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_addr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, ADDR_F, r0.f, r1.f, r2.f);
+ emit_insn_offf(s, ADDR_F, f0, f1, f2);
}
-void ejit_addr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_addr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, ADDR_D, r0.f, r1.f, r2.f);
+ emit_insn_offf(s, ADDR_D, f0, f1, f2);
}
void ejit_addi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, ADDI, r0.r, r1.r, o);
+ emit_insn_orri(s, ADDI, r0, r1, o);
}
-void ejit_absr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+void ejit_absr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1)
{
- emit_insn_i(s, ABSR_F, r0.f, r1.f, 0);
+ emit_insn_off(s, ABSR_F, f0, f1);
}
-void ejit_absr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+void ejit_absr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1)
{
- emit_insn_i(s, ABSR_D, r0.f, r1.f, 0);
+ emit_insn_off(s, ABSR_D, f0, f1);
}
void ejit_subr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, SUBR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, SUBR, r0, r1, r2);
}
-void ejit_subr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_subr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, SUBR_F, r0.f, r1.f, r2.f);
+ emit_insn_offf(s, SUBR_F, f0, f1, f2);
}
-void ejit_subr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_subr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, SUBR_D, r0.f, r1.f, r2.f);
+ emit_insn_offf(s, SUBR_D, f0, f1, f2);
}
void ejit_subi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
long o)
{
- emit_insn_i(s, SUBI, r0.r, r1.r, o);
+ emit_insn_orri(s, SUBI, r0, r1, o);
}
void ejit_mulr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, MULR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, MULR, r0, r1, r2);
}
-void ejit_mulr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_mulr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, MULR_F, r0.f, r1.f, r2.f);
+ emit_insn_offf(s, MULR_F, f0, f1, f2);
}
-void ejit_mulr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_mulr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, MULR_D, r0.f, r1.f, r2.f);
+ emit_insn_offf(s, MULR_D, f0, f1, f2);
}
void ejit_divr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, DIVR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, DIVR, r0, r1, r2);
}
void ejit_divr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, DIVR_U, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, DIVR_U, r0, r1, r2);
}
-void ejit_divr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_divr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, DIVR_F, r0.f, r1.f, r2.f);
+ emit_insn_offf(s, DIVR_F, f0, f1, f2);
}
-void ejit_divr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_divr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, DIVR_D, r0.f, r1.f, r2.f);
+ emit_insn_offf(s, DIVR_D, f0, f1, f2);
}
void ejit_remr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, REMR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, REMR, r0, r1, r2);
}
void ejit_remr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, REMR_U, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, REMR_U, r0, r1, r2);
}
void ejit_lshi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, LSHI, r0.r, r1.r, o);
+ emit_insn_orri(s, LSHI, r0, r1, o);
}
void ejit_lshr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, LSHR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, LSHR, r0, r1, r2);
}
void ejit_rshi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, RSHI, r0.r, r1.r, o);
+ emit_insn_orri(s, RSHI, r0, r1, o);
}
void ejit_rshi_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, RSHI_U, r0.r, r1.r, o);
+ emit_insn_orri(s, RSHI_U, r0, r1, o);
}
void ejit_rshr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, RSHR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, RSHR, r0, r1, r2);
}
void ejit_rshr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, RSHR_U, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, RSHR_U, r0, r1, r2);
}
void ejit_andr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, ANDR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, ANDR, r0, r1, r2);
}
void ejit_andi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, ANDI, r0.r, r1.r, o);
+ emit_insn_orri(s, ANDI, r0, r1, o);
}
void ejit_orr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, ORR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, ORR, r0, r1, r2);
}
void ejit_ori(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, ORI, r0.r, r1.r, o);
+ emit_insn_orri(s, ORI, r0, r1, o);
}
void ejit_xorr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, XORR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, XORR, r0, r1, r2);
}
void ejit_xori(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
- emit_insn_i(s, XORI, r0.r, r1.r, o);
+ emit_insn_orri(s, XORI, r0, r1, o);
}
void ejit_comr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
- emit_insn_i(s, COMR, r0.r, r1.r, 0);
+ emit_insn_orr(s, COMR, r0, r1);
}
void ejit_negr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
- emit_insn_i(s, NEGR, r0.r, r1.r, 0);
+ emit_insn_orr(s, NEGR, r0, r1);
}
-void ejit_negr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+void ejit_negr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1)
{
- emit_insn_i(s, NEGR_F, r0.f, r1.f, 0);
+ emit_insn_off(s, NEGR_F, f0, f1);
}
-void ejit_negr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+void ejit_negr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1)
{
- emit_insn_i(s, NEGR_D, r0.f, r1.f, 0);
+ emit_insn_off(s, NEGR_D, f0, f1);
}
void ejit_movi(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
{
- emit_insn_i(s, MOVI, r0.r, 0, o);
+ emit_insn_ori(s, MOVI, r0, o);
}
-void ejit_movi_f(struct ejit_func *s, struct ejit_fpr r0, float o)
+void ejit_movi_f(struct ejit_func *s, struct ejit_fpr f0, float o)
{
- emit_insn_f(s, MOVI_F, r0.f, 0, o);
+ emit_insn_ofF(s, MOVI_F, f0, o);
}
-void ejit_movi_d(struct ejit_func *s, struct ejit_fpr r0, double o)
+void ejit_movi_d(struct ejit_func *s, struct ejit_fpr f0, double o)
{
- emit_insn_d(s, MOVI_D, r0.f, 0, o);
+ emit_insn_ofD(s, MOVI_D, f0, o);
}
void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
@@ -786,203 +1019,211 @@ void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
if (r0.r == r1.r)
return;
- emit_insn_i(s, MOVR, r0.r, r1.r, 0);
+ emit_insn_orr(s, MOVR, r0, r1);
}
-void ejit_movr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+void ejit_movr_f(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1)
{
- if (r0.f == r1.f)
+ if (f0.f == f1.f)
return;
- emit_insn_i(s, MOVR_F, r0.f, r1.f, 0);
+ emit_insn_off(s, MOVR_F, f0, f1);
}
-void ejit_movr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+void ejit_movr_d(struct ejit_func *s, struct ejit_fpr f0, struct ejit_fpr f1)
{
- if (r0.f == r1.f)
+ if (f0.f == f1.f)
return;
- emit_insn_i(s, MOVR_D, r0.f, r1.f, 0);
+ emit_insn_off(s, MOVR_D, f0, f1);
}
void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, EQR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, EQR, r0, r1, r2);
}
-void ejit_eqr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_eqr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, EQR_F, r0.r, r1.f, r2.f);
+ emit_insn_orff(s, EQR_F, r0, f1, f2);
}
-void ejit_eqr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_eqr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, EQR_D, r0.r, r1.f, r2.f);
+ emit_insn_orff(s, EQR_D, r0, f1, f2);
}
void ejit_ner(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, NER, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, NER, r0, r1, r2);
}
-void ejit_ner_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_ner_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, NER_F, r0.r, r1.f, r2.f);
+ emit_insn_orff(s, NER_F, r0, f1, f2);
}
-void ejit_ner_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_ner_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, NER_D, r0.r, r1.f, r2.f);
+ emit_insn_orff(s, NER_D, r0, f1, f2);
}
void ejit_gtr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GTR, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, GTR, r0, r1, r2);
}
void ejit_gtr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GTR_U, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, GTR_U, r0, r1, r2);
}
-void ejit_gtr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_gtr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, GTR_F, r0.r, r1.f, r2.f);
+ emit_insn_orff(s, GTR_F, r0, f1, f2);
}
-void ejit_gtr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_gtr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, GTR_D, r0.r, r1.f, r2.f);
+ emit_insn_orff(s, GTR_D, r0, f1, f2);
}
void ejit_ltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GTR, r0.r, r2.r, r1.r);
+ emit_insn_orrr(s, GTR, r0, r2, r1);
}
void ejit_ltr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GTR_U, r0.r, r2.r, r1.r);
+ emit_insn_orrr(s, GTR_U, r0, r2, r1);
}
-void ejit_ltr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_ltr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, GTR_F, r0.r, r2.f, r1.f);
+ emit_insn_orff(s, GTR_F, r0, f2, f1);
}
-void ejit_ltr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_ltr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, GTR_D, r0.r, r2.f, r1.f);
+ emit_insn_orff(s, GTR_D, r0, f2, f1);
}
void ejit_ger(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GER, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, GER, r0, r1, r2);
}
void ejit_ger_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GER_U, r0.r, r1.r, r2.r);
+ emit_insn_orrr(s, GER_U, r0, r1, r2);
}
-void ejit_ger_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_ger_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, GER_F, r0.r, r1.f, r2.f);
+ emit_insn_orff(s, GER_F, r0, f1, f2);
+}
+
+void ejit_ger_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
+{
+ emit_insn_orff(s, GER_D, r0, f1, f2);
}
void ejit_ler(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GER, r0.r, r2.r, r1.r);
+ emit_insn_orrr(s, GER, r0, r2, r1);
}
void ejit_ler_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GER_U, r0.r, r2.r, r1.r);
+ emit_insn_orrr(s, GER_U, r0, r2, r1);
}
-void ejit_ler_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_ler_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, GER_F, r0.r, r2.f, r1.f);
+ emit_insn_orff(s, GER_F, r0, f2, f1);
}
-void ejit_ler_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
- struct ejit_fpr r2)
+void ejit_ler_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr f1,
+ struct ejit_fpr f2)
{
- emit_insn_r(s, GER_D, r0.r, r2.f, r1.f);
+ emit_insn_orff(s, GER_D, r0, f2, f1);
}
void ejit_truncr_d_32(struct ejit_func *s, struct ejit_gpr r0,
- struct ejit_fpr r1)
+ struct ejit_fpr f1)
{
- emit_insn_i(s, TRUNCR_D_32, r0.r, r1.f, 0);
+ emit_insn_orf(s, TRUNCR_D_32, r0, f1);
}
void ejit_truncr_d_64(struct ejit_func *s, struct ejit_gpr r0,
- struct ejit_fpr r1)
+ struct ejit_fpr f1)
{
- emit_insn_i(s, TRUNCR_D_64, r0.r, r1.f, 0);
+ s->use_64 = true;
+ emit_insn_orf(s, TRUNCR_D_64, r0, f1);
}
void ejit_truncr_f_32(struct ejit_func *s, struct ejit_gpr r0,
- struct ejit_fpr r1)
+ struct ejit_fpr f1)
{
- emit_insn_i(s, TRUNCR_F_32, r0.r, r1.f, 0);
+ emit_insn_orf(s, TRUNCR_F_32, r0, f1);
}
void ejit_truncr_f_64(struct ejit_func *s, struct ejit_gpr r0,
- struct ejit_fpr r1)
+ struct ejit_fpr f1)
{
- emit_insn_i(s, TRUNCR_F_64, r0.r, r1.f, 0);
+ s->use_64 = true;
+ emit_insn_orf(s, TRUNCR_F_64, r0, f1);
}
struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BNER, 0, r0.r, r1.r);
+ emit_insn_oxrr(s, BNER, r0, r1);
return (struct ejit_reloc){.insn = addr};
}
struct ejit_reloc ejit_bnei(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
{
size_t addr = insns_len(&s->insns);
- emit_insn_i(s, BNEI, 0, r0.r, o);
+ emit_insn_oxri(s, BNEI, r0, o);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_bner_f(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_bner_f(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BNER_F, 0, r0.f, r1.f);
+ emit_insn_oxff(s, BNER_F, f0, f1);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_bner_d(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_bner_d(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BNER_D, 0, r0.f, r1.f);
+ emit_insn_oxff(s, BNER_D, f0, f1);
return (struct ejit_reloc){.insn = addr};
}
@@ -990,30 +1231,30 @@ struct ejit_reloc ejit_beqr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BEQR, 0, r0.r, r1.r);
+ emit_insn_oxrr(s, BEQR, r0, r1);
return (struct ejit_reloc){.insn = addr};
}
struct ejit_reloc ejit_beqi(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
{
size_t addr = insns_len(&s->insns);
- emit_insn_i(s, BEQI, 0, r0.r, o);
+ emit_insn_oxri(s, BEQI, r0, 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)
+struct ejit_reloc ejit_beqr_f(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BEQR_F, 0, r0.f, r1.f);
+ emit_insn_oxff(s, BEQR_F, f0, f1);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_beqr_d(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_beqr_d(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BEQR_D, 0, r0.f, r1.f);
+ emit_insn_oxff(s, BEQR_D, f0, f1);
return (struct ejit_reloc){.insn = addr};
}
@@ -1021,7 +1262,7 @@ struct ejit_reloc ejit_bger(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGER, 0, r0.r, r1.r);
+ emit_insn_oxrr(s, BGER, r0, r1);
return (struct ejit_reloc){.insn = addr};
}
@@ -1029,22 +1270,30 @@ struct ejit_reloc ejit_bger_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGER_U, 0, r0.r, r1.r);
+ emit_insn_oxrr(s, BGER_U, r0, r1);
+ return (struct ejit_reloc){.insn = addr};
+}
+
+struct ejit_reloc ejit_bger_f(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
+{
+ size_t addr = insns_len(&s->insns);
+ emit_insn_oxff(s, BGER_F, f0, f1);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_bger_f(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_bger_d(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGER_F, 0, r0.f, r1.f);
+ emit_insn_oxff(s, BGER_D, f0, f1);
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 = insns_len(&s->insns);
- emit_insn_i(s, BGEI, 0, r0.r, o);
+ emit_insn_oxri(s, BGEI, r0, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1052,7 +1301,7 @@ struct ejit_reloc ejit_bgei_u(struct ejit_func *s, struct ejit_gpr r0,
int64_t o)
{
size_t addr = insns_len(&s->insns);
- emit_insn_i(s, BGEI_U, 0, r0.r, o);
+ emit_insn_oxri(s, BGEI_U, r0, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1060,7 +1309,7 @@ struct ejit_reloc ejit_bler(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGER, 0, r1.r, r0.r);
+ emit_insn_oxrr(s, BGER, r1, r0);
return (struct ejit_reloc){.insn = addr};
}
@@ -1068,30 +1317,30 @@ struct ejit_reloc ejit_bler_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGER_U, 0, r1.r, r0.r);
+ emit_insn_oxrr(s, BGER_U, r1, r0);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_bler_f(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_bler_f(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGER_F, 0, r1.f, r0.f);
+ emit_insn_oxff(s, BGER_F, f1, f0);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_bler_d(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_bler_d(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGER_D, 0, r1.f, r0.f);
+ emit_insn_oxff(s, BGER_D, f1, f0);
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 = insns_len(&s->insns);
- emit_insn_i(s, BLEI, 0, r0.r, o);
+ emit_insn_oxri(s, BLEI, r0, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1099,14 +1348,14 @@ struct ejit_reloc ejit_blei_u(struct ejit_func *s, struct ejit_gpr r0,
int64_t o)
{
size_t addr = insns_len(&s->insns);
- emit_insn_i(s, BLEI_U, 0, r0.r, o);
+ emit_insn_oxri(s, BLEI_U, r0, 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 = insns_len(&s->insns);
- emit_insn_i(s, BGTI, 0, r0.r, o);
+ emit_insn_oxri(s, BGTI, r0, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1114,7 +1363,7 @@ struct ejit_reloc ejit_bgti_u(struct ejit_func *s, struct ejit_gpr r0,
int64_t o)
{
size_t addr = insns_len(&s->insns);
- emit_insn_i(s, BGTI_U, 0, r0.r, o);
+ emit_insn_oxri(s, BGTI_U, r0, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1122,7 +1371,7 @@ struct ejit_reloc ejit_bgtr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGTR, 0, r0.r, r1.r);
+ emit_insn_oxrr(s, BGTR, r0, r1);
return (struct ejit_reloc){.insn = addr};
}
@@ -1130,23 +1379,23 @@ struct ejit_reloc ejit_bgtr_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGTR_U, 0, r0.r, r1.r);
+ emit_insn_oxrr(s, BGTR_U, r0, r1);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_bgtr_f(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_bgtr_f(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGTR_F, 0, r0.f, r1.f);
+ emit_insn_oxff(s, BGTR_F, f0, f1);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_bgtr_d(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_bgtr_d(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGTR_D, 0, r0.f, r1.f);
+ emit_insn_oxff(s, BGTR_D, f0, f1);
return (struct ejit_reloc){.insn = addr};
}
@@ -1154,7 +1403,7 @@ struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGTR, 0, r1.r, r0.r);
+ emit_insn_oxrr(s, BGTR, r1, r0);
return (struct ejit_reloc){.insn = addr};
}
@@ -1162,30 +1411,30 @@ struct ejit_reloc ejit_bltr_u(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGTR_U, 0, r1.r, r0.r);
+ emit_insn_oxrr(s, BGTR_U, r1, r0);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_bltr_f(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_bltr_f(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGTR_F, 0, r1.f, r0.f);
+ emit_insn_oxff(s, BGTR_F, f1, f0);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_bltr_d(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_bltr_d(struct ejit_func *s, struct ejit_fpr f0,
+ struct ejit_fpr f1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_r(s, BGTR_D, 0, r1.f, r0.f);
+ emit_insn_oxff(s, BGTR_D, f1, f0);
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 = insns_len(&s->insns);
- emit_insn_i(s, BLTI, 0, r0.r, o);
+ emit_insn_oxri(s, BLTI, r0, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1193,28 +1442,28 @@ struct ejit_reloc ejit_blti_u(struct ejit_func *s, struct ejit_gpr r0,
int64_t o)
{
size_t addr = insns_len(&s->insns);
- emit_insn_i(s, BLTI_U, 0, r0.r, o);
+ emit_insn_oxri(s, BLTI_U, r0, o);
return (struct ejit_reloc){.insn = addr};
}
struct ejit_reloc ejit_jmp(struct ejit_func *s)
{
size_t addr = insns_len(&s->insns);
- emit_insn_i(s, JMP, 0, 0, 0);
+ emit_insn_o(s, JMP);
return (struct ejit_reloc){.insn = addr};
}
struct ejit_reloc ejit_jmpr(struct ejit_func *s, struct ejit_gpr r0)
{
size_t addr = insns_len(&s->insns);
- emit_insn_i(s, JMPR, 0, r0.r, 0);
+ emit_insn_oxr(s, JMPR, r0);
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 = insns_len(&s->insns);
- emit_insn_i(s, BMCI, 0, r0.r, o);
+ emit_insn_oxri(s, BMCI, r0, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1222,14 +1471,14 @@ struct ejit_reloc ejit_bmcr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_i(s, BMCR, 0, r0.r, r1.r);
+ emit_insn_oxrr(s, BMCR, r0, r1);
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 = insns_len(&s->insns);
- emit_insn_i(s, BMSI, 0, r0.r, o);
+ emit_insn_oxri(s, BMSI, r0, o);
return (struct ejit_reloc){.insn = addr};
}
@@ -1237,7 +1486,7 @@ struct ejit_reloc ejit_bmsr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
size_t addr = insns_len(&s->insns);
- emit_insn_i(s, BMSR, 0, r0.r, r1.r);
+ emit_insn_oxrr(s, BMSR, r0, r1);
return (struct ejit_reloc){.insn = addr};
}
diff --git a/src/interp.inc b/src/interp.inc
index 75e7ff2..735eb09 100644
--- a/src/interp.inc
+++ b/src/interp.inc
@@ -1036,7 +1036,7 @@
/* dispatch is technically unnecessary for returns, but keep it for
* symmetry */
DO(RETR);
- retval = gpr[i.r0];
+ retval = gpr[i.r1];
goto out;
DISPATCH();
@@ -1046,12 +1046,12 @@
DISPATCH();
DO(RETR_F);
- retval_f = fpr[i.r0].f;
+ retval_f = fpr[i.r1].f;
goto out;
DISPATCH();
DO(RETR_D);
- retval_f = fpr[i.r0].d;
+ retval_f = fpr[i.r1].d;
goto out;
DISPATCH();
diff --git a/tests/andr64.c b/tests/andr64.c
index 6d7f09e..3d56e39 100644
--- a/tests/andr64.c
+++ b/tests/andr64.c
@@ -16,7 +16,7 @@ int main(int argc, char *argv[])
ejit_andr(f, EJIT_GPR(0), EJIT_GPR(0), EJIT_GPR(1));
ejit_retr(f, EJIT_GPR(0));
- ejit_select_compile_func(f, 1, 0, EJIT_USE64(int64_t), do_jit);
+ ejit_select_compile_func(f, 2, 0, EJIT_USE64(int64_t), do_jit);
assert(erf2(f, EJIT_ARG(1, int64_t),
EJIT_ARG(0x7fffffff, int64_t)) == 1);
diff --git a/tests/ldi_d.c b/tests/ldi_d.c
index 15a48b4..949eaee 100644
--- a/tests/ldi_d.c
+++ b/tests/ldi_d.c
@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
ejit_ldi_d(f, EJIT_FPR(0), &data);
ejit_retr_d(f, EJIT_FPR(0));
- ejit_select_compile_func(f, 1, 0, EJIT_USE64(double), do_jit);
+ ejit_select_compile_func(f, 0, 1, EJIT_USE64(double), do_jit);
assert(ejit_run_func_f(f, 0, NULL) == data);
diff --git a/tests/ldi_f.c b/tests/ldi_f.c
index 76a4f34..d070387 100644
--- a/tests/ldi_f.c
+++ b/tests/ldi_f.c
@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
ejit_ldi_f(f, EJIT_FPR(0), &data);
ejit_retr_f(f, EJIT_FPR(0));
- ejit_select_compile_func(f, 1, 0, EJIT_USE64(float), do_jit);
+ ejit_select_compile_func(f, 0, 1, EJIT_USE64(float), do_jit);
assert(ejit_run_func_f(f, 0, NULL) == data);
diff --git a/tests/stxi_16.c b/tests/stxi_16.c
index 9b8ec52..9f98137 100644
--- a/tests/stxi_16.c
+++ b/tests/stxi_16.c
@@ -17,7 +17,7 @@ int main(int argc, char *argv[])
ejit_stxi_16(f, EJIT_GPR(1), EJIT_GPR(0), (uintptr_t)data);
ejit_ret(f);
- ejit_select_compile_func(f, 2, 0, EJIT_USE64(int), do_jit);
+ ejit_select_compile_func(f, 2, 0, EJIT_USE64(int) | EJIT_USE64(uintptr_t), do_jit);
assert(data[0] == 0x1212);
assert(data[1] == 0);
diff --git a/tests/stxi_32.c b/tests/stxi_32.c
index d64c22b..3f3b8f4 100644
--- a/tests/stxi_32.c
+++ b/tests/stxi_32.c
@@ -17,7 +17,7 @@ int main(int argc, char *argv[])
ejit_stxi_32(f, EJIT_GPR(1), EJIT_GPR(0), (uintptr_t)data);
ejit_ret(f);
- ejit_select_compile_func(f, 2, 0, EJIT_USE64(int32_t), do_jit);
+ ejit_select_compile_func(f, 2, 0, EJIT_USE64(int32_t) | EJIT_USE64(uintptr_t), do_jit);
assert(data[0] == 0x12121212);
assert(data[1] == 0x00);
diff --git a/tests/stxi_8.c b/tests/stxi_8.c
index db2aa5a..59ec4c7 100644
--- a/tests/stxi_8.c
+++ b/tests/stxi_8.c
@@ -17,7 +17,7 @@ int main(int argc, char *argv[])
ejit_stxi_8(f, EJIT_GPR(1), EJIT_GPR(0), (uintptr_t)data);
ejit_ret(f);
- ejit_select_compile_func(f, 2, 0, EJIT_USE64(int), do_jit);
+ ejit_select_compile_func(f, 2, 0, EJIT_USE64(int) | EJIT_USE64(uintptr_t), do_jit);
assert(data[0] == 0x12);
assert(data[1] == 0x00);
diff --git a/tests/stxi_d.c b/tests/stxi_d.c
index c2b9df7..128dbb7 100644
--- a/tests/stxi_d.c
+++ b/tests/stxi_d.c
@@ -17,7 +17,7 @@ int main(int argc, char *argv[])
ejit_stxi_d(f, EJIT_FPR(0), EJIT_GPR(0), (uintptr_t)data);
ejit_ret(f);
- ejit_select_compile_func(f, 1, 1, EJIT_USE64(double), do_jit);
+ ejit_select_compile_func(f, 1, 1, EJIT_USE64(double) | EJIT_USE64(uintptr_t), do_jit);
assert(data[0] == -1.0f);
assert(data[1] == 0.0f);
diff --git a/tests/stxi_f.c b/tests/stxi_f.c
index baac4b4..4c218ed 100644
--- a/tests/stxi_f.c
+++ b/tests/stxi_f.c
@@ -17,7 +17,7 @@ int main(int argc, char *argv[])
ejit_stxi_f(f, EJIT_FPR(0), EJIT_GPR(0), (uintptr_t)data);
ejit_ret(f);
- ejit_select_compile_func(f, 1, 1, EJIT_USE64(float), do_jit);
+ ejit_select_compile_func(f, 1, 1, EJIT_USE64(float) | EJIT_USE64(uintptr_t), do_jit);
assert(data[0] == -1.0);
assert(data[1] == 0.0);