diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-03-26 13:17:58 +0200 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-03-26 13:17:58 +0200 |
commit | 67a13eb82534996fbd6ba2fc0c36d3e1284bcd8e (patch) | |
tree | 21561c3209cc77c79d32284541c01ab60fec7791 | |
parent | 912c07167705613c6db70e542723c7ec2c06c7ea (diff) | |
download | ejit-67a13eb82534996fbd6ba2fc0c36d3e1284bcd8e.tar.gz ejit-67a13eb82534996fbd6ba2fc0c36d3e1284bcd8e.zip |
handle immediates a bit better
+ Passing floats as immediate values is not supported in lightening, but
I might have a go at adding it since it seems like a useful feature at
some point
-rw-r--r-- | include/ejit/ejit.h | 4 | ||||
-rw-r--r-- | src/compile/compile.c | 25 | ||||
-rw-r--r-- | src/ejit.c | 3 | ||||
-rw-r--r-- | src/interp.c | 2 | ||||
-rw-r--r-- | tests/escapei_immediate_10.c | 73 |
5 files changed, 104 insertions, 3 deletions
diff --git a/include/ejit/ejit.h b/include/ejit/ejit.h index 48c4dda..d4bb725 100644 --- a/include/ejit/ejit.h +++ b/include/ejit/ejit.h @@ -157,7 +157,7 @@ static inline struct ejit_arg ejit_build_arg_f(enum ejit_type type, double x) a.type = type; switch (type) { - case EJIT_FLOAT: a.f = x; break; + case EJIT_FLOAT: a.f = (float)x; break; case EJIT_DOUBLE: a.d = x; break; default: abort(); } @@ -245,7 +245,7 @@ void ejit_destroy_func(struct ejit_func *s); .type = (t)}) #define EJIT_OPERAND_FLT(x, t) \ ((struct ejit_operand){ .kind = EJIT_OPERAND_FLT, \ - .r = (double)(x), \ + .d = (double)(x), \ .type = (t)}) /* maybe slight hack, but increase width to interpeter register width */ diff --git a/src/compile/compile.c b/src/compile/compile.c index c979305..50f12dc 100644 --- a/src/compile/compile.c +++ b/src/compile/compile.c @@ -2140,6 +2140,31 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, case JMP: compile_jmp(f, j, i, &relocs); break; + case ARG_I: { + jit_operand_t type = jit_operand_imm(JIT_OPERAND_ABI_WORD, i.r1); + jit_operand_t arg = jit_operand_imm(jit_abi_from(i.r1), i.o); + operands_append(&src, type); + operands_append(&src, arg); + operands_append(&direct, 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)) + }; + + operands_append(&dst, to[0]); + operands_append(&dst, to[1]); + break; + } + + case ARG_FI: { + assert(false && "immediate floats (currently?) not supported"); + abort(); + break; + } + case ARG: { size_t r2 = gpr_stats_at(&f->gpr, i.r2)->rno; jit_operand_t type = jit_operand_imm(JIT_OPERAND_ABI_WORD, i.r1); @@ -1,4 +1,5 @@ #include <assert.h> +#include <stdio.h> #include <sys/mman.h> #include <ejit/ejit.h> @@ -161,6 +162,8 @@ static void emit_insn_af(struct ejit_func *f, enum ejit_opcode op, size_t idx, e static void emit_insn_ad(struct ejit_func *f, enum ejit_opcode op, size_t idx, enum ejit_type type, double d) { + fprintf(stderr, "warning: immediate floats are currently not supported.\n" + "Consider moving values into FPRs.\n"); struct ejit_insn i = {.op = op, .r0 = idx, .r1 = type, .d = d}; insns_append(&f->insns, i); } diff --git a/src/interp.c b/src/interp.c index 80a9edc..aa40c53 100644 --- a/src/interp.c +++ b/src/interp.c @@ -1009,7 +1009,7 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa if (i.r1 == EJIT_DOUBLE) a = ejit_build_arg_f(i.r1, i.d); else - a = ejit_build_arg_f(i.r1, i.f); + a = ejit_build_arg_f(i.r1, i.d); args[argc++] = a; DISPATCH(); diff --git a/tests/escapei_immediate_10.c b/tests/escapei_immediate_10.c new file mode 100644 index 0000000..381c79f --- /dev/null +++ b/tests/escapei_immediate_10.c @@ -0,0 +1,73 @@ +#include <ejit/ejit.h> +#include <assert.h> +#include "do_jit.h" + +static int32_t func(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, + int32_t f, int32_t g, int32_t h, int32_t i, int32_t j) +{ + assert(a == 0); + assert(b == 1); + assert(c == 2); + assert(d == 3); + assert(e == 4); + assert(f == 5); + assert(g == 6); + assert(h == 7); + assert(i == 8); + assert(j == 9); + return 42; +} + +static long escape_func(size_t argc, const struct ejit_arg args[argc]) +{ + assert(argc == 10); + assert(args[0].type == EJIT_INT32); + assert(args[1].type == EJIT_INT32); + assert(args[3].type == EJIT_INT32); + assert(args[4].type == EJIT_INT32); + assert(args[5].type == EJIT_INT32); + assert(args[6].type == EJIT_INT32); + assert(args[7].type == EJIT_INT32); + assert(args[8].type == EJIT_INT32); + assert(args[9].type == EJIT_INT32); + + int32_t a = args[0].i32; + int32_t b = args[1].i32; + int32_t c = args[2].i32; + int32_t d = args[3].i32; + int32_t e = args[4].i32; + int32_t f = args[5].i32; + int32_t g = args[6].i32; + int32_t h = args[7].i32; + int32_t i = args[8].i32; + int32_t j = args[9].i32; + return func(a, b, c, d, e, f, g, h, i, j); +} + +int main(int argc, char *argv[]) +{ + (void)argv; + bool do_jit = argc > 1; + struct ejit_func *f = ejit_create_func(EJIT_INT32, 0, NULL); + struct ejit_operand args[10] = { + EJIT_OPERAND_IMM(0, EJIT_INT32), + EJIT_OPERAND_IMM(1, EJIT_INT32), + EJIT_OPERAND_IMM(2, EJIT_INT32), + EJIT_OPERAND_IMM(3, EJIT_INT32), + EJIT_OPERAND_IMM(4, EJIT_INT32), + EJIT_OPERAND_IMM(5, EJIT_INT32), + EJIT_OPERAND_IMM(6, EJIT_INT32), + EJIT_OPERAND_IMM(7, EJIT_INT32), + EJIT_OPERAND_IMM(8, EJIT_INT32), + EJIT_OPERAND_IMM(9, EJIT_INT32), + }; + ejit_escapei_i(f, escape_func, 10, args); + ejit_retval(f, EJIT_GPR(0)); + ejit_retr(f, EJIT_GPR(0)); + + ejit_select_compile_func(f, 11, 0, false, do_jit, true); + + assert(ejit_run_func_i(f, 0, NULL) == 42); + + ejit_destroy_func(f); +} |