Use target-specific assembler names and helper metadata for TCG helpers
when multiple targets share a binary. The generated prototype maps the
generic C helper name to a target-specific linker symbol, for example:
helper_raise_exception
__asm__("helper_i386_raise_exception")
This lets target helper definitions keep generic C names while avoiding
linker symbol collisions between targets.
Signed-off-by: Yonggang Luo <[email protected]>
---
include/exec/helper-gen-common.h | 26 ++++++++++++++++
include/exec/helper-gen.h.inc | 48 +++++++++++++++---------------
include/exec/helper-head.h.inc | 25 ++++++++++++++++
include/exec/helper-info.c.inc | 24 ++++++++++-----
include/exec/helper-proto-common.h | 26 ++++++++++++++++
include/exec/helper-proto.h.inc | 18 ++++++-----
meson.build | 6 +++-
7 files changed, 132 insertions(+), 41 deletions(-)
diff --git a/include/exec/helper-gen-common.h b/include/exec/helper-gen-common.h
index 834590dc4e..c05edb5f3e 100644
--- a/include/exec/helper-gen-common.h
+++ b/include/exec/helper-gen-common.h
@@ -7,8 +7,34 @@
#ifndef HELPER_GEN_COMMON_H
#define HELPER_GEN_COMMON_H
+#undef HELPER_INFO
+#define HELPER_INFO(name) CORE_HELPER_INFO(name)
+
+#define HELPER_H "accel/tcg/cpu-exec-common.h"
+#include "exec/helper-gen.h.inc"
+#undef HELPER_H
+
+#define HELPER_H "accel/tcg/cpu-exec.h"
+#include "exec/helper-gen.h.inc"
+#undef HELPER_H
+
#define HELPER_H "accel/tcg/tcg-runtime.h"
#include "exec/helper-gen.h.inc"
#undef HELPER_H
+#define HELPER_H "accel/tcg/ldst_common.h"
+#include "exec/helper-gen.h.inc"
+#undef HELPER_H
+
+#define HELPER_H "accel/tcg/atomic_common.h"
+#include "exec/helper-gen.h.inc"
+#undef HELPER_H
+
+#define HELPER_H "accel/tcg/tcg-runtime-gvec.h"
+#include "exec/helper-gen.h.inc"
+#undef HELPER_H
+
+#undef HELPER_INFO
+#define HELPER_INFO(name) TARGET_HELPER_INFO(name)
+
#endif /* HELPER_GEN_COMMON_H */
diff --git a/include/exec/helper-gen.h.inc b/include/exec/helper-gen.h.inc
index dabe138e20..95715bde1e 100644
--- a/include/exec/helper-gen.h.inc
+++ b/include/exec/helper-gen.h.inc
@@ -11,88 +11,88 @@
#include "exec/helper-head.h.inc"
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
-extern TCGHelperInfo glue(helper_info_, name); \
+extern TCGHelperInfo HELPER_INFO(name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
{ \
- tcg_gen_call0(glue(helper_info_,name).func, \
- &glue(helper_info_,name), dh_retvar(ret)); \
+ tcg_gen_call0(HELPER_INFO(name).func, \
+ &HELPER_INFO(name), dh_retvar(ret)); \
}
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
-extern TCGHelperInfo glue(helper_info_, name); \
+extern TCGHelperInfo HELPER_INFO(name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1)) \
{ \
- tcg_gen_call1(glue(helper_info_,name).func, \
- &glue(helper_info_,name), dh_retvar(ret), \
+ tcg_gen_call1(HELPER_INFO(name).func, \
+ &HELPER_INFO(name), dh_retvar(ret), \
dh_arg(t1, 1)); \
}
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
-extern TCGHelperInfo glue(helper_info_, name); \
+extern TCGHelperInfo HELPER_INFO(name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2)) \
{ \
- tcg_gen_call2(glue(helper_info_,name).func, \
- &glue(helper_info_,name), dh_retvar(ret), \
+ tcg_gen_call2(HELPER_INFO(name).func, \
+ &HELPER_INFO(name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2)); \
}
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
-extern TCGHelperInfo glue(helper_info_, name); \
+extern TCGHelperInfo HELPER_INFO(name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
{ \
- tcg_gen_call3(glue(helper_info_,name).func, \
- &glue(helper_info_,name), dh_retvar(ret), \
+ tcg_gen_call3(HELPER_INFO(name).func, \
+ &HELPER_INFO(name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3)); \
}
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
-extern TCGHelperInfo glue(helper_info_, name); \
+extern TCGHelperInfo HELPER_INFO(name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), \
dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
{ \
- tcg_gen_call4(glue(helper_info_,name).func, \
- &glue(helper_info_,name), dh_retvar(ret), \
+ tcg_gen_call4(HELPER_INFO(name).func, \
+ &HELPER_INFO(name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2), \
dh_arg(t3, 3), dh_arg(t4, 4)); \
}
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
-extern TCGHelperInfo glue(helper_info_, name); \
+extern TCGHelperInfo HELPER_INFO(name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
{ \
- tcg_gen_call5(glue(helper_info_,name).func, \
- &glue(helper_info_,name), dh_retvar(ret), \
+ tcg_gen_call5(HELPER_INFO(name).func, \
+ &HELPER_INFO(name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
dh_arg(t4, 4), dh_arg(t5, 5)); \
}
#define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \
-extern TCGHelperInfo glue(helper_info_, name); \
+extern TCGHelperInfo HELPER_INFO(name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6)) \
{ \
- tcg_gen_call6(glue(helper_info_,name).func, \
- &glue(helper_info_,name), dh_retvar(ret), \
+ tcg_gen_call6(HELPER_INFO(name).func, \
+ &HELPER_INFO(name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6)); \
}
#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7)\
-extern TCGHelperInfo glue(helper_info_, name); \
+extern TCGHelperInfo HELPER_INFO(name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6), \
dh_arg_decl(t7, 7)) \
{ \
- tcg_gen_call7(glue(helper_info_,name).func, \
- &glue(helper_info_,name), dh_retvar(ret), \
+ tcg_gen_call7(HELPER_INFO(name).func, \
+ &HELPER_INFO(name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \
dh_arg(t7, 7)); \
diff --git a/include/exec/helper-head.h.inc b/include/exec/helper-head.h.inc
index 7dec5f5b06..61e106cd56 100644
--- a/include/exec/helper-head.h.inc
+++ b/include/exec/helper-head.h.inc
@@ -8,7 +8,32 @@
#include "fpu/softfloat-types.h"
+#define TCG_TARGET_HELPER_INFO_I(prefix, name) helper_info_##prefix##_##name
+#define TCG_TARGET_HELPER_INFO(prefix, name) \
+ TCG_TARGET_HELPER_INFO_I(prefix, name)
+#define TCG_HELPER_STRINGIFY_I(value) #value
+#define TCG_HELPER_STRINGIFY(value) TCG_HELPER_STRINGIFY_I(value)
+
+#ifdef TCG_HELPER_PREFIX
+#define TARGET_HELPER_INFO(name) \
+ TCG_TARGET_HELPER_INFO(TCG_HELPER_PREFIX, name)
+#define TARGET_HELPER_ASM(name) \
+ __asm__("helper_" TCG_HELPER_STRINGIFY(TCG_HELPER_PREFIX) "_" #name)
+#else
+#define TARGET_HELPER_INFO(name) glue(helper_info_, name)
+#define TARGET_HELPER_ASM(name)
+#endif
+
+#define CORE_HELPER_INFO(name) glue(helper_info_, name)
+#define CORE_HELPER_ASM(name)
+
#define HELPER(name) glue(helper_, name)
+#ifndef HELPER_INFO
+#define HELPER_INFO(name) TARGET_HELPER_INFO(name)
+#endif
+#ifndef HELPER_ASM
+#define HELPER_ASM(name) TARGET_HELPER_ASM(name)
+#endif
/* Some types that make sense in C, but not for TCG. */
#define dh_alias_i32 i32
diff --git a/include/exec/helper-info.c.inc b/include/exec/helper-info.c.inc
index c551736d49..815546c818 100644
--- a/include/exec/helper-info.c.inc
+++ b/include/exec/helper-info.c.inc
@@ -16,21 +16,24 @@
#define str(s) #s
#define DEF_HELPER_FLAGS_0(NAME, FLAGS, RET) \
- TCGHelperInfo glue(helper_info_, NAME) = { \
+ TCGHelperInfo HELPER_INFO(NAME) = \
+ { \
.func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(RET), \
.typemask = dh_typemask(RET, 0) \
};
#define DEF_HELPER_FLAGS_1(NAME, FLAGS, RET, T1) \
- TCGHelperInfo glue(helper_info_, NAME) = { \
+ TCGHelperInfo HELPER_INFO(NAME) = \
+ { \
.func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(RET), \
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
};
#define DEF_HELPER_FLAGS_2(NAME, FLAGS, RET, T1, T2) \
- TCGHelperInfo glue(helper_info_, NAME) = { \
+ TCGHelperInfo HELPER_INFO(NAME) = \
+ { \
.func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(RET), \
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
@@ -38,7 +41,8 @@
};
#define DEF_HELPER_FLAGS_3(NAME, FLAGS, RET, T1, T2, T3) \
- TCGHelperInfo glue(helper_info_, NAME) = { \
+ TCGHelperInfo HELPER_INFO(NAME) = \
+ { \
.func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(RET), \
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
@@ -46,7 +50,8 @@
};
#define DEF_HELPER_FLAGS_4(NAME, FLAGS, RET, T1, T2, T3, T4) \
- TCGHelperInfo glue(helper_info_, NAME) = { \
+ TCGHelperInfo HELPER_INFO(NAME) = \
+ { \
.func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(RET), \
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
@@ -55,7 +60,8 @@
};
#define DEF_HELPER_FLAGS_5(NAME, FLAGS, RET, T1, T2, T3, T4, T5) \
- TCGHelperInfo glue(helper_info_, NAME) = { \
+ TCGHelperInfo HELPER_INFO(NAME) = \
+ { \
.func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(RET), \
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
@@ -64,7 +70,8 @@
};
#define DEF_HELPER_FLAGS_6(NAME, FLAGS, RET, T1, T2, T3, T4, T5, T6) \
- TCGHelperInfo glue(helper_info_, NAME) = { \
+ TCGHelperInfo HELPER_INFO(NAME) = \
+ { \
.func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(RET), \
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
@@ -74,7 +81,8 @@
};
#define DEF_HELPER_FLAGS_7(NAME, FLAGS, RET, T1, T2, T3, T4, T5, T6, T7) \
- TCGHelperInfo glue(helper_info_, NAME) = { \
+ TCGHelperInfo HELPER_INFO(NAME) = \
+ { \
.func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(RET), \
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
diff --git a/include/exec/helper-proto-common.h
b/include/exec/helper-proto-common.h
index 76e6c25bec..01a0be10c6 100644
--- a/include/exec/helper-proto-common.h
+++ b/include/exec/helper-proto-common.h
@@ -9,10 +9,36 @@
#include "qemu/atomic128.h" /* for HAVE_CMPXCHG128 */
+#undef HELPER_ASM
+#define HELPER_ASM(name) CORE_HELPER_ASM(name)
+
+#define HELPER_H "accel/tcg/cpu-exec-common.h"
+#include "exec/helper-proto.h.inc"
+#undef HELPER_H
+
+#define HELPER_H "accel/tcg/cpu-exec.h"
+#include "exec/helper-proto.h.inc"
+#undef HELPER_H
+
#define HELPER_H "accel/tcg/tcg-runtime.h"
#include "exec/helper-proto.h.inc"
#undef HELPER_H
+#define HELPER_H "accel/tcg/ldst_common.h"
+#include "exec/helper-proto.h.inc"
+#undef HELPER_H
+
+#define HELPER_H "accel/tcg/atomic_common.h"
+#include "exec/helper-proto.h.inc"
+#undef HELPER_H
+
+#define HELPER_H "accel/tcg/tcg-runtime-gvec.h"
+#include "exec/helper-proto.h.inc"
+#undef HELPER_H
+
+#undef HELPER_ASM
+#define HELPER_ASM(name) TARGET_HELPER_ASM(name)
+
#include "accel/tcg/getpc.h"
#endif /* HELPER_PROTO_COMMON_H */
diff --git a/include/exec/helper-proto.h.inc b/include/exec/helper-proto.h.inc
index f8e57e43ce..b7e3b10ed7 100644
--- a/include/exec/helper-proto.h.inc
+++ b/include/exec/helper-proto.h.inc
@@ -21,35 +21,37 @@
#define DEF_HELPER_ATTR __attribute__((noinline))
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
-dh_ctype(ret) HELPER(name) (void) DEF_HELPER_ATTR;
+dh_ctype(ret) HELPER(name) (void) HELPER_ASM(name) DEF_HELPER_ATTR;
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
-dh_ctype(ret) HELPER(name) (dh_ctype(t1)) DEF_HELPER_ATTR;
+dh_ctype(ret) HELPER(name) (dh_ctype(t1)) HELPER_ASM(name) DEF_HELPER_ATTR;
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
-dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)) DEF_HELPER_ATTR;
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)) \
+ HELPER_ASM(name) DEF_HELPER_ATTR;
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), \
- dh_ctype(t3)) DEF_HELPER_ATTR;
+ dh_ctype(t3)) HELPER_ASM(name) DEF_HELPER_ATTR;
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
- dh_ctype(t4)) DEF_HELPER_ATTR;
+ dh_ctype(t4)) HELPER_ASM(name) DEF_HELPER_ATTR;
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
- dh_ctype(t4), dh_ctype(t5)) DEF_HELPER_ATTR;
+ dh_ctype(t4), dh_ctype(t5)) \
+ HELPER_ASM(name) DEF_HELPER_ATTR;
#define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
dh_ctype(t4), dh_ctype(t5), \
- dh_ctype(t6)) DEF_HELPER_ATTR;
+ dh_ctype(t6)) HELPER_ASM(name) DEF_HELPER_ATTR;
#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7) \
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \
- dh_ctype(t7)) DEF_HELPER_ATTR;
+ dh_ctype(t7)) HELPER_ASM(name) DEF_HELPER_ATTR;
#define IN_HELPER_PROTO
diff --git a/meson.build b/meson.build
index cae1591cd2..3cadf5b215 100644
--- a/meson.build
+++ b/meson.build
@@ -4161,7 +4161,10 @@ foreach target_base_arch, config_base_arch :
config_base_arch_mak
# prevent common code to access cpu compile time definition,
# but still allow access to cpu.h
- target_c_args = ['-DCPU_DEFS_H']
+ target_c_args = [
+ '-DCPU_DEFS_H',
+ '-DTCG_HELPER_PREFIX=' + target_base_arch.to_lower()
+ ]
target_system_c_args = target_c_args + ['-DCOMPILING_SYSTEM_VS_USER',
'-DCONFIG_SOFTMMU']
if target_base_arch in target_common_arch
@@ -4277,6 +4280,7 @@ foreach target : target_dirs
arch_deps = []
c_args = ['-DCOMPILING_PER_TARGET',
'-DCONFIG_TARGET="@[email protected]"'.format(target),
+ '-DTCG_HELPER_PREFIX=' + target_base_arch.to_lower()
]
link_args = emulator_link_args
--
2.55.0.windows.3