From df0a5d738f5a9f15acc31d2bd515f0e391bad006 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 25 Mar 2019 15:08:05 +0100 Subject: [PATCH] Better loading of args to registers; add tests --- .gitignore | 3 + jit.h | 12 +++- jit/x86.c | 168 ++++++++++++++++++++++++++++++++++++++++---- tests/Makefile | 2 +- tests/test-addr_d.c | 28 ++++++++ tests/test-addr_f.c | 28 ++++++++ tests/test-addx.c | 65 +++++++++++++++++ 7 files changed, 291 insertions(+), 15 deletions(-) create mode 100644 tests/test-addr_d.c create mode 100644 tests/test-addr_f.c create mode 100644 tests/test-addx.c diff --git a/.gitignore b/.gitignore index dc7bc2589..ffa28c972 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ /lightning.info /tests/test-addr /tests/test-addi +/tests/test-addr_d +/tests/test-addr_f +/tests/test-addx diff --git a/jit.h b/jit.h index f52263f07..3b14591b0 100644 --- a/jit.h +++ b/jit.h @@ -127,7 +127,8 @@ typedef enum jit_arg_abi JIT_ARG_ABI_INT64, JIT_ARG_ABI_POINTER, JIT_ARG_ABI_FLOAT, - JIT_ARG_ABI_DOUBLE + JIT_ARG_ABI_DOUBLE, + JIT_ARG_ABI_INTMAX = CHOOSE_32_64(JIT_ARG_ABI_INT32, JIT_ARG_ABI_INT64) } jit_arg_abi_t; typedef struct jit_arg @@ -142,6 +143,12 @@ typedef struct jit_arg } loc; } jit_arg_t; +typedef union jit_anyreg +{ + jit_gpr_t gpr; + jit_fpr_t fpr; +} jit_anyreg_t; + JIT_API jit_bool_t init_jit(void); JIT_API jit_state_t *jit_new_state(void); @@ -166,6 +173,9 @@ JIT_API void jit_callr(jit_state_t *, jit_gpr_t f, const jit_arg_t args[]); JIT_API void jit_receive(jit_state_t*, size_t argc, const jit_arg_abi_t abi[], jit_arg_t args[]); +JIT_API void jit_load_args(jit_state_t *_jit, size_t argc, + const jit_arg_abi_t abi[], jit_arg_t args[], + const jit_anyreg_t regs[]); #define JIT_PROTO_0(stem, ret) \ ret jit_##stem (jit_state_t* _jit) diff --git a/jit/x86.c b/jit/x86.c index 1b617372a..08bda792a 100644 --- a/jit/x86.c +++ b/jit/x86.c @@ -363,6 +363,35 @@ jit_callr(jit_state_t *_jit, jit_gpr_t f, callr(_jit, f); } +static jit_bool_t +is_fpr_arg(jit_arg_abi_t arg) +{ + switch (arg) + { + case JIT_ARG_ABI_UINT8: + case JIT_ARG_ABI_INT8: + case JIT_ARG_ABI_UINT16: + case JIT_ARG_ABI_INT16: + case JIT_ARG_ABI_UINT32: + case JIT_ARG_ABI_INT32: + case JIT_ARG_ABI_UINT64: + case JIT_ARG_ABI_INT64: + case JIT_ARG_ABI_POINTER: + return 0; + case JIT_ARG_ABI_FLOAT: + case JIT_ARG_ABI_DOUBLE: + return 1; + default: + abort(); + } +} + +static jit_bool_t +is_gpr_arg(jit_arg_abi_t arg) +{ + return !is_fpr_arg(arg); +} + void jit_receive(jit_state_t *_jit, size_t argc, const jit_arg_abi_t abi[], jit_arg_t args[]) @@ -400,16 +429,7 @@ jit_receive(jit_state_t *_jit, #endif for (size_t i = 0; i < argc; i++) { - switch (abi[i]) { - case JIT_ARG_ABI_UINT8: - case JIT_ARG_ABI_INT8: - case JIT_ARG_ABI_UINT16: - case JIT_ARG_ABI_INT16: - case JIT_ARG_ABI_UINT32: - case JIT_ARG_ABI_INT32: - case JIT_ARG_ABI_UINT64: - case JIT_ARG_ABI_INT64: - case JIT_ARG_ABI_POINTER: + if (is_gpr_arg(abi[i])) { if (gpr_arg_idx < gpr_arg_count) { args[i].kind = JIT_ARG_LOC_GPR; args[i].loc.gpr = gpr_args[gpr_arg_idx]; @@ -417,9 +437,8 @@ jit_receive(jit_state_t *_jit, } else { abort(); } - break; - case JIT_ARG_ABI_FLOAT: - case JIT_ARG_ABI_DOUBLE: + } else { + ASSERT(is_fpr_arg(abi[i])); if (fpr_arg_idx < fpr_arg_count) { args[i].kind = JIT_ARG_LOC_FPR; args[i].loc.fpr = fpr_args[fpr_arg_idx]; @@ -427,7 +446,130 @@ jit_receive(jit_state_t *_jit, } else { abort(); } + } + } +} + +void +jit_load_args(jit_state_t *_jit, size_t argc, + const jit_arg_abi_t abi[], jit_arg_t args[], + const jit_anyreg_t regs[]) +{ + /* First shuffle the arguments in registers into position. */ + for (size_t i = 0; i < argc; i++) { + const jit_arg_t arg = args[i]; + const jit_anyreg_t reg = regs[i]; + switch (arg.kind) { + case JIT_ARG_LOC_IMM: + abort(); + case JIT_ARG_LOC_GPR: + { + if (arg.loc.gpr != reg.gpr) + /* Arg in a reg but it's not the right one. See if this reg + holds some other arg, and swap if so. */ + for (size_t j=i+1; j