mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
tcg: Pass TCGHelperInfo to tcg_gen_callN
In preparation for compiling tcg/ only once, eliminate the all_helpers array. Instantiate the info structs for the generic helpers in accel/tcg/, and the structs for the target-specific helpers in each translate.c. Since we don't see all of the info structs at startup, initialize at first use, using g_once_init_* to make sure we don't race while doing so. Reviewed-by: Anton Johansson <anjo@rev.ng> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
0f4e14c25a
commit
d53106c997
31 changed files with 282 additions and 175 deletions
|
@ -1,81 +1,96 @@
|
|||
/* Helper file for declaring TCG helper functions.
|
||||
This one expands generation functions for tcg opcodes. */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Helper file for declaring TCG helper functions.
|
||||
* This one expands generation functions for tcg opcodes.
|
||||
* Define HELPER_H for the header file to be expanded,
|
||||
* and static inline to change from global file scope.
|
||||
*/
|
||||
|
||||
#ifndef HELPER_GEN_H
|
||||
#define HELPER_GEN_H
|
||||
|
||||
#include "tcg/tcg.h"
|
||||
#include "tcg/helper-info.h"
|
||||
#include "exec/helper-head.h"
|
||||
|
||||
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
|
||||
extern TCGHelperInfo glue(helper_info_, name); \
|
||||
static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
|
||||
{ \
|
||||
tcg_gen_callN(HELPER(name), dh_retvar(ret), 0, NULL); \
|
||||
tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 0, NULL); \
|
||||
}
|
||||
|
||||
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
|
||||
extern TCGHelperInfo glue(helper_info_, name); \
|
||||
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
|
||||
dh_arg_decl(t1, 1)) \
|
||||
{ \
|
||||
TCGTemp *args[1] = { dh_arg(t1, 1) }; \
|
||||
tcg_gen_callN(HELPER(name), dh_retvar(ret), 1, args); \
|
||||
TCGTemp *args[1] = { dh_arg(t1, 1) }; \
|
||||
tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 1, args); \
|
||||
}
|
||||
|
||||
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
|
||||
extern TCGHelperInfo glue(helper_info_, name); \
|
||||
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
|
||||
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2)) \
|
||||
{ \
|
||||
TCGTemp *args[2] = { dh_arg(t1, 1), dh_arg(t2, 2) }; \
|
||||
tcg_gen_callN(HELPER(name), dh_retvar(ret), 2, args); \
|
||||
TCGTemp *args[2] = { dh_arg(t1, 1), dh_arg(t2, 2) }; \
|
||||
tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 2, args); \
|
||||
}
|
||||
|
||||
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
|
||||
extern TCGHelperInfo glue(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)) \
|
||||
{ \
|
||||
TCGTemp *args[3] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3) }; \
|
||||
tcg_gen_callN(HELPER(name), dh_retvar(ret), 3, args); \
|
||||
TCGTemp *args[3] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3) }; \
|
||||
tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 3, args); \
|
||||
}
|
||||
|
||||
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
|
||||
extern TCGHelperInfo glue(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)) \
|
||||
{ \
|
||||
TCGTemp *args[4] = { dh_arg(t1, 1), dh_arg(t2, 2), \
|
||||
dh_arg(t3, 3), dh_arg(t4, 4) }; \
|
||||
tcg_gen_callN(HELPER(name), dh_retvar(ret), 4, args); \
|
||||
TCGTemp *args[4] = { dh_arg(t1, 1), dh_arg(t2, 2), \
|
||||
dh_arg(t3, 3), dh_arg(t4, 4) }; \
|
||||
tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 4, args); \
|
||||
}
|
||||
|
||||
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
|
||||
extern TCGHelperInfo glue(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(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
|
||||
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
|
||||
{ \
|
||||
TCGTemp *args[5] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
|
||||
dh_arg(t4, 4), dh_arg(t5, 5) }; \
|
||||
tcg_gen_callN(HELPER(name), dh_retvar(ret), 5, args); \
|
||||
TCGTemp *args[5] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
|
||||
dh_arg(t4, 4), dh_arg(t5, 5) }; \
|
||||
tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 5, args); \
|
||||
}
|
||||
|
||||
#define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \
|
||||
extern TCGHelperInfo glue(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(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)) \
|
||||
{ \
|
||||
TCGTemp *args[6] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
|
||||
dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6) }; \
|
||||
tcg_gen_callN(HELPER(name), dh_retvar(ret), 6, args); \
|
||||
TCGTemp *args[6] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
|
||||
dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6) }; \
|
||||
tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 6, args); \
|
||||
}
|
||||
|
||||
#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7)\
|
||||
extern TCGHelperInfo glue(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(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)) \
|
||||
{ \
|
||||
TCGTemp *args[7] = { 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) }; \
|
||||
tcg_gen_callN(HELPER(name), dh_retvar(ret), 7, args); \
|
||||
TCGTemp *args[7] = { 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) }; \
|
||||
tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 7, args); \
|
||||
}
|
||||
|
||||
#include "helper.h"
|
||||
|
@ -90,6 +105,5 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
|
|||
#undef DEF_HELPER_FLAGS_5
|
||||
#undef DEF_HELPER_FLAGS_6
|
||||
#undef DEF_HELPER_FLAGS_7
|
||||
#undef GEN_HELPER
|
||||
|
||||
#endif /* HELPER_GEN_H */
|
||||
|
|
96
include/exec/helper-info.c.inc
Normal file
96
include/exec/helper-info.c.inc
Normal file
|
@ -0,0 +1,96 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Helper file for declaring TCG helper functions.
|
||||
* This one expands info structures for tcg helpers.
|
||||
* Define HELPER_H for the header file to be expanded.
|
||||
*/
|
||||
|
||||
#include "tcg/tcg.h"
|
||||
#include "tcg/helper-info.h"
|
||||
#include "exec/helper-head.h"
|
||||
|
||||
/*
|
||||
* Need one more level of indirection before stringification
|
||||
* to get all the macros expanded first.
|
||||
*/
|
||||
#define str(s) #s
|
||||
|
||||
#define DEF_HELPER_FLAGS_0(NAME, FLAGS, RET) \
|
||||
TCGHelperInfo glue(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) = { \
|
||||
.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) = { \
|
||||
.func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(RET), \
|
||||
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
|
||||
| dh_typemask(T2, 2) \
|
||||
};
|
||||
|
||||
#define DEF_HELPER_FLAGS_3(NAME, FLAGS, RET, T1, T2, T3) \
|
||||
TCGHelperInfo glue(helper_info_, NAME) = { \
|
||||
.func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(RET), \
|
||||
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
|
||||
| dh_typemask(T2, 2) | dh_typemask(T3, 3) \
|
||||
};
|
||||
|
||||
#define DEF_HELPER_FLAGS_4(NAME, FLAGS, RET, T1, T2, T3, T4) \
|
||||
TCGHelperInfo glue(helper_info_, NAME) = { \
|
||||
.func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(RET), \
|
||||
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
|
||||
| dh_typemask(T2, 2) | dh_typemask(T3, 3) \
|
||||
| dh_typemask(T4, 4) \
|
||||
};
|
||||
|
||||
#define DEF_HELPER_FLAGS_5(NAME, FLAGS, RET, T1, T2, T3, T4, T5) \
|
||||
TCGHelperInfo glue(helper_info_, NAME) = { \
|
||||
.func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(RET), \
|
||||
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
|
||||
| dh_typemask(T2, 2) | dh_typemask(T3, 3) \
|
||||
| dh_typemask(T4, 4) | dh_typemask(T5, 5) \
|
||||
};
|
||||
|
||||
#define DEF_HELPER_FLAGS_6(NAME, FLAGS, RET, T1, T2, T3, T4, T5, T6) \
|
||||
TCGHelperInfo glue(helper_info_, NAME) = { \
|
||||
.func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(RET), \
|
||||
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
|
||||
| dh_typemask(T2, 2) | dh_typemask(T3, 3) \
|
||||
| dh_typemask(T4, 4) | dh_typemask(T5, 5) \
|
||||
| dh_typemask(T6, 6) \
|
||||
};
|
||||
|
||||
#define DEF_HELPER_FLAGS_7(NAME, FLAGS, RET, T1, T2, T3, T4, T5, T6, T7) \
|
||||
TCGHelperInfo glue(helper_info_, NAME) = { \
|
||||
.func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(RET), \
|
||||
.typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
|
||||
| dh_typemask(T2, 2) | dh_typemask(T3, 3) \
|
||||
| dh_typemask(T4, 4) | dh_typemask(T5, 5) \
|
||||
| dh_typemask(T6, 6) | dh_typemask(T7, 7) \
|
||||
};
|
||||
|
||||
#include HELPER_H
|
||||
|
||||
#undef str
|
||||
#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
|
||||
#undef DEF_HELPER_FLAGS_6
|
||||
#undef DEF_HELPER_FLAGS_7
|
|
@ -1,75 +0,0 @@
|
|||
/* Helper file for declaring TCG helper functions.
|
||||
This one defines data structures private to tcg.c. */
|
||||
|
||||
#ifndef HELPER_TCG_H
|
||||
#define HELPER_TCG_H
|
||||
|
||||
#include "exec/helper-head.h"
|
||||
|
||||
/* Need one more level of indirection before stringification
|
||||
to get all the macros expanded first. */
|
||||
#define str(s) #s
|
||||
|
||||
#define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
|
||||
{ .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) \
|
||||
{ .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) \
|
||||
{ .func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(ret), \
|
||||
.typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
|
||||
| dh_typemask(t2, 2) },
|
||||
|
||||
#define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \
|
||||
{ .func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(ret), \
|
||||
.typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
|
||||
| dh_typemask(t2, 2) | dh_typemask(t3, 3) },
|
||||
|
||||
#define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \
|
||||
{ .func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(ret), \
|
||||
.typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
|
||||
| dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) },
|
||||
|
||||
#define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \
|
||||
{ .func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(ret), \
|
||||
.typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
|
||||
| dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
|
||||
| dh_typemask(t5, 5) },
|
||||
|
||||
#define DEF_HELPER_FLAGS_6(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6) \
|
||||
{ .func = HELPER(NAME), .name = str(NAME), \
|
||||
.flags = FLAGS | dh_callflag(ret), \
|
||||
.typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
|
||||
| dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
|
||||
| dh_typemask(t5, 5) | dh_typemask(t6, 6) },
|
||||
|
||||
#define DEF_HELPER_FLAGS_7(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6, t7) \
|
||||
{ .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
|
||||
.typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
|
||||
| dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
|
||||
| dh_typemask(t5, 5) | dh_typemask(t6, 6) | dh_typemask(t7, 7) },
|
||||
|
||||
#include "helper.h"
|
||||
#include "accel/tcg/tcg-runtime.h"
|
||||
#include "accel/tcg/plugin-helpers.h"
|
||||
|
||||
#undef str
|
||||
#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
|
||||
#undef DEF_HELPER_FLAGS_6
|
||||
#undef DEF_HELPER_FLAGS_7
|
||||
|
||||
#endif /* HELPER_TCG_H */
|
|
@ -131,6 +131,7 @@ typedef struct ReservedRegion ReservedRegion;
|
|||
typedef struct SavedIOTLB SavedIOTLB;
|
||||
typedef struct SHPCDevice SHPCDevice;
|
||||
typedef struct SSIBus SSIBus;
|
||||
typedef struct TCGHelperInfo TCGHelperInfo;
|
||||
typedef struct TranslationBlock TranslationBlock;
|
||||
typedef struct VirtIODevice VirtIODevice;
|
||||
typedef struct Visitor Visitor;
|
||||
|
|
|
@ -40,12 +40,17 @@ typedef struct TCGCallArgumentLoc {
|
|||
unsigned tmp_subindex : 2;
|
||||
} TCGCallArgumentLoc;
|
||||
|
||||
typedef struct TCGHelperInfo {
|
||||
struct TCGHelperInfo {
|
||||
void *func;
|
||||
const char *name;
|
||||
|
||||
/* Used with g_once_init_enter. */
|
||||
#ifdef CONFIG_TCG_INTERPRETER
|
||||
ffi_cif *cif;
|
||||
#else
|
||||
uintptr_t init;
|
||||
#endif
|
||||
|
||||
unsigned typemask : 32;
|
||||
unsigned flags : 8;
|
||||
unsigned nr_in : 8;
|
||||
|
@ -54,6 +59,6 @@ typedef struct TCGHelperInfo {
|
|||
|
||||
/* Maximum physical arguments are constrained by TCG_TYPE_I128. */
|
||||
TCGCallArgumentLoc in[MAX_CALL_IARGS * (128 / TCG_TARGET_REG_BITS)];
|
||||
} TCGHelperInfo;
|
||||
};
|
||||
|
||||
#endif /* TCG_HELPER_INFO_H */
|
||||
|
|
|
@ -937,7 +937,7 @@ typedef struct TCGTargetOpDef {
|
|||
|
||||
bool tcg_op_supported(TCGOpcode op);
|
||||
|
||||
void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
|
||||
void tcg_gen_callN(TCGHelperInfo *, TCGTemp *ret, int nargs, TCGTemp **args);
|
||||
|
||||
TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs);
|
||||
void tcg_op_remove(TCGContext *s, TCGOp *op);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue