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); +} | 
