mirror of https://github.com/xemu-project/xemu.git
tcg: Build ffi data structures for helpers
Add libffi as a build requirement for TCI. Add libffi to the dockerfiles to satisfy that requirement. Construct an ffi_cif structure for each unique typemask. Record the result in a separate hash table for later lookup; this allows helper_table to stay const. Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
fa52e66062
commit
22f15579fa
|
@ -9,6 +9,12 @@ tcg_ss.add(files(
|
||||||
'tcg-op-gvec.c',
|
'tcg-op-gvec.c',
|
||||||
'tcg-op-vec.c',
|
'tcg-op-vec.c',
|
||||||
))
|
))
|
||||||
tcg_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tci.c'))
|
|
||||||
|
if get_option('tcg_interpreter')
|
||||||
|
libffi = dependency('libffi', version: '>=3.0', required: true,
|
||||||
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
|
specific_ss.add(libffi)
|
||||||
|
specific_ss.add(files('tci.c'))
|
||||||
|
endif
|
||||||
|
|
||||||
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
|
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
|
||||||
|
|
58
tcg/tcg.c
58
tcg/tcg.c
|
@ -60,6 +60,10 @@
|
||||||
#include "exec/log.h"
|
#include "exec/log.h"
|
||||||
#include "tcg-internal.h"
|
#include "tcg-internal.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_TCG_INTERPRETER
|
||||||
|
#include <ffi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Forward declarations for functions declared in tcg-target.c.inc and
|
/* Forward declarations for functions declared in tcg-target.c.inc and
|
||||||
used here. */
|
used here. */
|
||||||
static void tcg_target_init(TCGContext *s);
|
static void tcg_target_init(TCGContext *s);
|
||||||
|
@ -539,6 +543,19 @@ static const TCGHelperInfo all_helpers[] = {
|
||||||
};
|
};
|
||||||
static GHashTable *helper_table;
|
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 int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
|
||||||
static void process_op_defs(TCGContext *s);
|
static void process_op_defs(TCGContext *s);
|
||||||
static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
|
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]);
|
(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);
|
tcg_target_init(s);
|
||||||
process_op_defs(s);
|
process_op_defs(s);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ ENV PACKAGES \
|
||||||
libaio-dev \
|
libaio-dev \
|
||||||
libbpf-dev \
|
libbpf-dev \
|
||||||
libcap-ng-dev \
|
libcap-ng-dev \
|
||||||
|
libffi-dev \
|
||||||
libjpeg-turbo-dev \
|
libjpeg-turbo-dev \
|
||||||
libnfs-dev \
|
libnfs-dev \
|
||||||
libpng-dev \
|
libpng-dev \
|
||||||
|
|
|
@ -17,6 +17,7 @@ ENV PACKAGES \
|
||||||
libbpf-devel \
|
libbpf-devel \
|
||||||
libepoxy-devel \
|
libepoxy-devel \
|
||||||
libfdt-devel \
|
libfdt-devel \
|
||||||
|
libffi-devel \
|
||||||
libgcrypt-devel \
|
libgcrypt-devel \
|
||||||
lzo-devel \
|
lzo-devel \
|
||||||
make \
|
make \
|
||||||
|
|
|
@ -26,6 +26,7 @@ RUN apt update && \
|
||||||
gdb-multiarch \
|
gdb-multiarch \
|
||||||
gettext \
|
gettext \
|
||||||
git \
|
git \
|
||||||
|
libffi-dev \
|
||||||
libncurses5-dev \
|
libncurses5-dev \
|
||||||
ninja-build \
|
ninja-build \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
|
|
|
@ -6,6 +6,7 @@ ENV PACKAGES \
|
||||||
findutils \
|
findutils \
|
||||||
gcc \
|
gcc \
|
||||||
git \
|
git \
|
||||||
|
libffi-devel.i686 \
|
||||||
libtasn1-devel.i686 \
|
libtasn1-devel.i686 \
|
||||||
libzstd-devel.i686 \
|
libzstd-devel.i686 \
|
||||||
make \
|
make \
|
||||||
|
|
|
@ -19,6 +19,7 @@ ENV PACKAGES \
|
||||||
mingw32-gmp \
|
mingw32-gmp \
|
||||||
mingw32-gnutls \
|
mingw32-gnutls \
|
||||||
mingw32-gtk3 \
|
mingw32-gtk3 \
|
||||||
|
mingw32-libffi \
|
||||||
mingw32-libjpeg-turbo \
|
mingw32-libjpeg-turbo \
|
||||||
mingw32-libpng \
|
mingw32-libpng \
|
||||||
mingw32-libtasn1 \
|
mingw32-libtasn1 \
|
||||||
|
|
|
@ -18,6 +18,7 @@ ENV PACKAGES \
|
||||||
mingw64-glib2 \
|
mingw64-glib2 \
|
||||||
mingw64-gmp \
|
mingw64-gmp \
|
||||||
mingw64-gtk3 \
|
mingw64-gtk3 \
|
||||||
|
mingw64-libffi \
|
||||||
mingw64-libjpeg-turbo \
|
mingw64-libjpeg-turbo \
|
||||||
mingw64-libpng \
|
mingw64-libpng \
|
||||||
mingw64-libtasn1 \
|
mingw64-libtasn1 \
|
||||||
|
|
|
@ -33,6 +33,7 @@ ENV PACKAGES \
|
||||||
libepoxy-devel \
|
libepoxy-devel \
|
||||||
libfdt-devel \
|
libfdt-devel \
|
||||||
libbpf-devel \
|
libbpf-devel \
|
||||||
|
libffi-devel \
|
||||||
libiscsi-devel \
|
libiscsi-devel \
|
||||||
libjpeg-devel \
|
libjpeg-devel \
|
||||||
libpmem-devel \
|
libpmem-devel \
|
||||||
|
|
|
@ -28,6 +28,7 @@ ENV PACKAGES \
|
||||||
libdrm-dev \
|
libdrm-dev \
|
||||||
libepoxy-dev \
|
libepoxy-dev \
|
||||||
libfdt-dev \
|
libfdt-dev \
|
||||||
|
libffi-dev \
|
||||||
libgbm-dev \
|
libgbm-dev \
|
||||||
libgnutls28-dev \
|
libgnutls28-dev \
|
||||||
libgtk-3-dev \
|
libgtk-3-dev \
|
||||||
|
|
|
@ -16,6 +16,7 @@ ENV PACKAGES \
|
||||||
libdrm-dev \
|
libdrm-dev \
|
||||||
libepoxy-dev \
|
libepoxy-dev \
|
||||||
libfdt-dev \
|
libfdt-dev \
|
||||||
|
libffi-dev \
|
||||||
libgbm-dev \
|
libgbm-dev \
|
||||||
libgtk-3-dev \
|
libgtk-3-dev \
|
||||||
libibverbs-dev \
|
libibverbs-dev \
|
||||||
|
|
|
@ -19,6 +19,7 @@ ENV PACKAGES flex bison \
|
||||||
libdrm-dev \
|
libdrm-dev \
|
||||||
libepoxy-dev \
|
libepoxy-dev \
|
||||||
libfdt-dev \
|
libfdt-dev \
|
||||||
|
libffi-dev \
|
||||||
libgbm-dev \
|
libgbm-dev \
|
||||||
libgtk-3-dev \
|
libgtk-3-dev \
|
||||||
libibverbs-dev \
|
libibverbs-dev \
|
||||||
|
|
Loading…
Reference in New Issue