Signed-off-by: Richard Henderson <r...@twiddle.net> --- configure | 12 +++++++ include/exec/helper-ffi.h | 83 ++++++++++++++++++++++++++++++++++++++++++++ include/exec/helper-tcg.h | 18 ++++++---- target-i386/ops_sse_header.h | 6 ++++ target-ppc/helper.h | 1 + tcg/tcg.c | 11 ++++++ 6 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 include/exec/helper-ffi.h
diff --git a/configure b/configure index 46bc0c9..8c33f83 100755 --- a/configure +++ b/configure @@ -1755,6 +1755,18 @@ EOF fi ########################################## +# libffi check + +if test "$tcg_interpreter" != "no" ; then + if $pkg_config --atleast-version=3.0 libffi; then + LIBS="$LIBS `$pkg_config --libs libffi`" + QEMU_CFLAGS="$QEMU_CFLAGS `$pkg_config --cflags libffi`" + else + feature_not_found "tcg-interpreter" "Install libffi devel >= 3.0" + fi +fi + +########################################## # libseccomp check if test "$seccomp" != "no" ; then diff --git a/include/exec/helper-ffi.h b/include/exec/helper-ffi.h new file mode 100644 index 0000000..78579aa --- /dev/null +++ b/include/exec/helper-ffi.h @@ -0,0 +1,83 @@ +/* Helper file for declaring TCG helper functions. + This one defines data structures private to tcg.c. */ + +#ifndef HELPER_FFI_H +#define HELPER_FFI_H 1 + +#include <exec/helper-head.h> + +#define dh_ffitype_i32 &ffi_type_uint32 +#define dh_ffitype_s32 &ffi_type_sint32 +#define dh_ffitype_int &ffi_type_sint +#define dh_ffitype_i64 &ffi_type_uint64 +#define dh_ffitype_s64 &ffi_type_sint64 +#define dh_ffitype_f32 &ffi_type_uint32 +#define dh_ffitype_f64 &ffi_type_uint64 +#ifdef TARGET_LONG_BITS +# if TARGET_LONG_BITS == 32 +# define dh_ffitype_tl &ffi_type_uint32 +# else +# define dh_ffitype_tl &ffi_type_uint64 +# endif +#endif +#define dh_ffitype_ptr &ffi_type_pointer +#define dh_ffitype_void &ffi_type_void +#define dh_ffitype_noreturn &ffi_type_void +#define dh_ffitype_env &ffi_type_pointer +#define dh_ffitype(t) glue(dh_ffitype_, t) + +#define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \ + static ffi_cif cif_##NAME = { \ + .rtype = dh_ffitype(ret), .nargs = 0, \ + }; + +#define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \ + static ffi_type *cif_args_##NAME[1] = { dh_ffitype(t1) }; \ + static ffi_cif cif_##NAME = { \ + .rtype = dh_ffitype(ret), .nargs = 1, .arg_types = cif_args_##NAME, \ + }; + +#define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \ + static ffi_type *cif_args_##NAME[2] = { \ + dh_ffitype(t1), dh_ffitype(t2) \ + }; \ + static ffi_cif cif_##NAME = { \ + .rtype = dh_ffitype(ret), .nargs = 2, .arg_types = cif_args_##NAME, \ + }; + +#define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \ + static ffi_type *cif_args_##NAME[3] = { \ + dh_ffitype(t1), dh_ffitype(t2), dh_ffitype(t3) \ + }; \ + static ffi_cif cif_##NAME = { \ + .rtype = dh_ffitype(ret), .nargs = 3, .arg_types = cif_args_##NAME, \ + }; + +#define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \ + static ffi_type *cif_args_##NAME[4] = { \ + dh_ffitype(t1), dh_ffitype(t2), dh_ffitype(t3), dh_ffitype(t4) \ + }; \ + static ffi_cif cif_##NAME = { \ + .rtype = dh_ffitype(ret), .nargs = 4, .arg_types = cif_args_##NAME, \ + }; + +#define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \ + static ffi_type *cif_args_##NAME[5] = { \ + dh_ffitype(t1), dh_ffitype(t2), dh_ffitype(t3), \ + dh_ffitype(t4), dh_ffitype(t5) \ + }; \ + static ffi_cif cif_##NAME = { \ + .rtype = dh_ffitype(ret), .nargs = 5, .arg_types = cif_args_##NAME, \ + }; + +#include "helper.h" +#include "tcg-runtime.h" + +#undef DEF_HELPER_FLAGS_0 +#undef DEF_HELPER_FLAGS_1 +#undef DEF_HELPER_FLAGS_2 +#undef DEF_HELPER_FLAGS_3 +#undef DEF_HELPER_FLAGS_4 +#undef DEF_HELPER_FLAGS_5 + +#endif /* HELPER_FFI_H */ diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h index d704c81..c0c258f 100644 --- a/include/exec/helper-tcg.h +++ b/include/exec/helper-tcg.h @@ -6,31 +6,37 @@ #include <exec/helper-head.h> +#ifdef CONFIG_TCG_INTERPRETER +# define DO_CIF(NAME) .cif = &cif_##NAME, +#else +# define DO_CIF(NAME) +#endif + #define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \ - { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \ + { .func = HELPER(NAME), DO_CIF(NAME) .name = #NAME, .flags = FLAGS, \ .sizemask = dh_sizemask(ret, 0) }, #define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \ - { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \ + { .func = HELPER(NAME), DO_CIF(NAME) .name = #NAME, .flags = FLAGS, \ .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) }, #define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \ - { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \ + { .func = HELPER(NAME), DO_CIF(NAME) .name = #NAME, .flags = FLAGS, \ .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \ | dh_sizemask(t2, 2) }, #define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \ - { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \ + { .func = HELPER(NAME), DO_CIF(NAME) .name = #NAME, .flags = FLAGS, \ .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \ | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) }, #define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \ - { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \ + { .func = HELPER(NAME), DO_CIF(NAME) .name = #NAME, .flags = FLAGS, \ .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \ | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) }, #define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \ - { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \ + { .func = HELPER(NAME), DO_CIF(NAME) .name = #NAME, .flags = FLAGS, \ .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \ | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \ | dh_sizemask(t5, 5) }, diff --git a/target-i386/ops_sse_header.h b/target-i386/ops_sse_header.h index a68c7cc..35ec03b 100644 --- a/target-i386/ops_sse_header.h +++ b/target-i386/ops_sse_header.h @@ -27,13 +27,19 @@ #define dh_alias_Reg ptr #define dh_alias_XMMReg ptr #define dh_alias_MMXReg ptr + #define dh_ctype_Reg Reg * #define dh_ctype_XMMReg XMMReg * #define dh_ctype_MMXReg MMXReg * + #define dh_is_signed_Reg dh_is_signed_ptr #define dh_is_signed_XMMReg dh_is_signed_ptr #define dh_is_signed_MMXReg dh_is_signed_ptr +#define dh_ffitype_Reg dh_ffitype_ptr +#define dh_ffitype_XMMReg dh_ffitype_ptr +#define dh_ffitype_MMXReg dh_ffitype_ptr + DEF_HELPER_3(glue(psrlw, SUFFIX), void, env, Reg, Reg) DEF_HELPER_3(glue(psraw, SUFFIX), void, env, Reg, Reg) DEF_HELPER_3(glue(psllw, SUFFIX), void, env, Reg, Reg) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 08f3916..70a3d50 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -103,6 +103,7 @@ DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64) #define dh_alias_avr ptr #define dh_ctype_avr ppc_avr_t * #define dh_is_signed_avr dh_is_signed_ptr +#define dh_ffitype_avr dh_ffitype_ptr DEF_HELPER_3(vaddubm, void, avr, avr, avr) DEF_HELPER_3(vadduhm, void, avr, avr, avr) diff --git a/tcg/tcg.c b/tcg/tcg.c index 04280ef..11d1996 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -62,6 +62,10 @@ #include "elf.h" +#ifdef CONFIG_TCG_INTERPRETER +#include <ffi.h> +#endif + /* Forward declarations for functions declared in tcg-target.c and used here. */ static void tcg_target_init(TCGContext *s); static void tcg_target_qemu_prologue(TCGContext *s); @@ -309,6 +313,9 @@ void tcg_pool_reset(TCGContext *s) typedef struct TCGHelperInfo { void *func; +#ifdef CONFIG_TCG_INTERPRETER + ffi_cif *cif; +#endif const char *name; unsigned flags; unsigned sizemask; @@ -316,6 +323,10 @@ typedef struct TCGHelperInfo { #include "exec/helper-proto.h" +#ifdef CONFIG_TCG_INTERPRETER +#include "exec/helper-ffi.h" +#endif + static const TCGHelperInfo all_helpers[] = { #include "exec/helper-tcg.h" }; -- 1.9.0