tcg: Factor init_ffi_layouts() out of tcg_context_init()

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20221111074101.2069454-27-richard.henderson@linaro.org>
[PMD: Split from bigger patch]
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20221122180804.938-3-philmd@linaro.org>
This commit is contained in:
Philippe Mathieu-Daudé 2022-11-22 19:08:03 +01:00 committed by Richard Henderson
parent c6ef8c7b35
commit 0c22e17658
1 changed files with 44 additions and 39 deletions

View File

@ -573,7 +573,49 @@ static ffi_type *typecode_to_ffi(int argmask)
}
g_assert_not_reached();
}
#endif
static void init_ffi_layouts(void)
{
/* g_direct_hash/equal for direct comparisons on uint32_t. */
ffi_table = g_hash_table_new(NULL, NULL);
for (int i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
uint32_t typemask = all_helpers[i].typemask;
gpointer hash = (gpointer)(uintptr_t)typemask;
struct {
ffi_cif cif;
ffi_type *args[];
} *ca;
ffi_status status;
int nargs;
if (g_hash_table_lookup(ffi_table, hash)) {
continue;
}
/* Ignoring the return type, find the last non-zero field. */
nargs = 32 - clz32(typemask >> 3);
nargs = DIV_ROUND_UP(nargs, 3);
ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
ca->cif.rtype = typecode_to_ffi(typemask & 7);
ca->cif.nargs = nargs;
if (nargs != 0) {
ca->cif.arg_types = ca->args;
for (int j = 0; j < nargs; ++j) {
int typecode = extract32(typemask, (j + 1) * 3, 3);
ca->args[j] = typecode_to_ffi(typecode);
}
}
status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
ca->cif.rtype, ca->cif.arg_types);
assert(status == FFI_OK);
g_hash_table_insert(ffi_table, hash, (gpointer)&ca->cif);
}
}
#endif /* CONFIG_TCG_INTERPRETER */
typedef struct TCGCumulativeArgs {
int arg_idx; /* tcg_gen_callN args[] */
@ -768,44 +810,7 @@ static void tcg_context_init(unsigned max_cpus)
}
#ifdef CONFIG_TCG_INTERPRETER
/* g_direct_hash/equal for direct comparisons on uint32_t. */
ffi_table = g_hash_table_new(NULL, NULL);
for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
struct {
ffi_cif cif;
ffi_type *args[];
} *ca;
uint32_t typemask = all_helpers[i].typemask;
gpointer hash = (gpointer)(uintptr_t)typemask;
ffi_status status;
int nargs;
if (g_hash_table_lookup(ffi_table, hash)) {
continue;
}
/* Ignoring the return type, find the last non-zero field. */
nargs = 32 - clz32(typemask >> 3);
nargs = DIV_ROUND_UP(nargs, 3);
ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
ca->cif.rtype = typecode_to_ffi(typemask & 7);
ca->cif.nargs = nargs;
if (nargs != 0) {
ca->cif.arg_types = ca->args;
for (int j = 0; j < nargs; ++j) {
int typecode = extract32(typemask, (j + 1) * 3, 3);
ca->args[j] = typecode_to_ffi(typecode);
}
}
status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
ca->cif.rtype, ca->cif.arg_types);
assert(status == FFI_OK);
g_hash_table_insert(ffi_table, hash, (gpointer)&ca->cif);
}
init_ffi_layouts();
#endif
tcg_target_init(s);