|
@@ -60,6 +60,10 @@
|
|
|
#include "exec/log.h"
|
|
|
#include "tcg-internal.h"
|
|
|
|
|
|
+#ifdef CONFIG_TCG_INTERPRETER
|
|
|
+#include <ffi.h>
|
|
|
+#endif
|
|
|
+
|
|
|
/* Forward declarations for functions declared in tcg-target.c.inc and
|
|
|
used here. */
|
|
|
static void tcg_target_init(TCGContext *s);
|
|
@@ -539,6 +543,19 @@ static const TCGHelperInfo all_helpers[] = {
|
|
|
};
|
|
|
static GHashTable *helper_table;
|
|
|
|
|
|
+#ifdef CONFIG_TCG_INTERPRETER
|
|
|
+static GHashTable *ffi_table;
|
|
|
+
|
|
|
+static ffi_type * const typecode_to_ffi[8] = {
|
|
|
+ [dh_typecode_void] = &ffi_type_void,
|
|
|
+ [dh_typecode_i32] = &ffi_type_uint32,
|
|
|
+ [dh_typecode_s32] = &ffi_type_sint32,
|
|
|
+ [dh_typecode_i64] = &ffi_type_uint64,
|
|
|
+ [dh_typecode_s64] = &ffi_type_sint64,
|
|
|
+ [dh_typecode_ptr] = &ffi_type_pointer,
|
|
|
+};
|
|
|
+#endif
|
|
|
+
|
|
|
static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
|
|
|
static void process_op_defs(TCGContext *s);
|
|
|
static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
|
|
@@ -582,6 +599,47 @@ static void tcg_context_init(unsigned max_cpus)
|
|
|
(gpointer)&all_helpers[i]);
|
|
|
}
|
|
|
|
|
|
+#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 (i = 0; i < nargs; ++i) {
|
|
|
+ int typecode = extract32(typemask, (i + 1) * 3, 3);
|
|
|
+ ca->args[i] = 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
|
|
|
+
|
|
|
tcg_target_init(s);
|
|
|
process_op_defs(s);
|
|
|
|