tcg: Store the TCGHelperInfo in the TCGOp for call
This will give us both flags and typemask for use later. We also fix a dumping bug, wherein calls generated for plugins fail tcg_find_helper and print (null) instead of either a name or the raw function pointer. 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
9d87e59585
commit
3e92aa3443
@ -27,6 +27,13 @@
|
|||||||
|
|
||||||
#define TCG_HIGHWATER 1024
|
#define TCG_HIGHWATER 1024
|
||||||
|
|
||||||
|
typedef struct TCGHelperInfo {
|
||||||
|
void *func;
|
||||||
|
const char *name;
|
||||||
|
unsigned flags;
|
||||||
|
unsigned typemask;
|
||||||
|
} TCGHelperInfo;
|
||||||
|
|
||||||
extern TCGContext tcg_init_ctx;
|
extern TCGContext tcg_init_ctx;
|
||||||
extern TCGContext **tcg_ctxs;
|
extern TCGContext **tcg_ctxs;
|
||||||
extern unsigned int tcg_cur_ctxs;
|
extern unsigned int tcg_cur_ctxs;
|
||||||
@ -37,9 +44,14 @@ bool tcg_region_alloc(TCGContext *s);
|
|||||||
void tcg_region_initial_alloc(TCGContext *s);
|
void tcg_region_initial_alloc(TCGContext *s);
|
||||||
void tcg_region_prologue_set(TCGContext *s);
|
void tcg_region_prologue_set(TCGContext *s);
|
||||||
|
|
||||||
|
static inline const TCGHelperInfo *tcg_call_info(TCGOp *op)
|
||||||
|
{
|
||||||
|
return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
|
||||||
|
}
|
||||||
|
|
||||||
static inline unsigned tcg_call_flags(TCGOp *op)
|
static inline unsigned tcg_call_flags(TCGOp *op)
|
||||||
{
|
{
|
||||||
return op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
|
return tcg_call_info(op)->flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* TCG_INTERNAL_H */
|
#endif /* TCG_INTERNAL_H */
|
||||||
|
49
tcg/tcg.c
49
tcg/tcg.c
@ -532,13 +532,6 @@ void tcg_pool_reset(TCGContext *s)
|
|||||||
s->pool_current = NULL;
|
s->pool_current = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct TCGHelperInfo {
|
|
||||||
void *func;
|
|
||||||
const char *name;
|
|
||||||
unsigned flags;
|
|
||||||
unsigned typemask;
|
|
||||||
} TCGHelperInfo;
|
|
||||||
|
|
||||||
#include "exec/helper-proto.h"
|
#include "exec/helper-proto.h"
|
||||||
|
|
||||||
static const TCGHelperInfo all_helpers[] = {
|
static const TCGHelperInfo all_helpers[] = {
|
||||||
@ -1395,12 +1388,11 @@ bool tcg_op_supported(TCGOpcode op)
|
|||||||
void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
|
void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
|
||||||
{
|
{
|
||||||
int i, real_args, nb_rets, pi;
|
int i, real_args, nb_rets, pi;
|
||||||
unsigned typemask, flags;
|
unsigned typemask;
|
||||||
TCGHelperInfo *info;
|
const TCGHelperInfo *info;
|
||||||
TCGOp *op;
|
TCGOp *op;
|
||||||
|
|
||||||
info = g_hash_table_lookup(helper_table, (gpointer)func);
|
info = g_hash_table_lookup(helper_table, (gpointer)func);
|
||||||
flags = info->flags;
|
|
||||||
typemask = info->typemask;
|
typemask = info->typemask;
|
||||||
|
|
||||||
#ifdef CONFIG_PLUGIN
|
#ifdef CONFIG_PLUGIN
|
||||||
@ -1538,7 +1530,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
|
|||||||
real_args++;
|
real_args++;
|
||||||
}
|
}
|
||||||
op->args[pi++] = (uintptr_t)func;
|
op->args[pi++] = (uintptr_t)func;
|
||||||
op->args[pi++] = flags;
|
op->args[pi++] = (uintptr_t)info;
|
||||||
TCGOP_CALLI(op) = real_args;
|
TCGOP_CALLI(op) = real_args;
|
||||||
|
|
||||||
/* Make sure the fields didn't overflow. */
|
/* Make sure the fields didn't overflow. */
|
||||||
@ -1657,19 +1649,6 @@ static char *tcg_get_arg_str(TCGContext *s, char *buf,
|
|||||||
return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg));
|
return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find helper name. */
|
|
||||||
static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val)
|
|
||||||
{
|
|
||||||
const char *ret = NULL;
|
|
||||||
if (helper_table) {
|
|
||||||
TCGHelperInfo *info = g_hash_table_lookup(helper_table, (gpointer)val);
|
|
||||||
if (info) {
|
|
||||||
ret = info->name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char * const cond_name[] =
|
static const char * const cond_name[] =
|
||||||
{
|
{
|
||||||
[TCG_COND_NEVER] = "never",
|
[TCG_COND_NEVER] = "never",
|
||||||
@ -1760,15 +1739,29 @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
|
|||||||
col += qemu_log(" " TARGET_FMT_lx, a);
|
col += qemu_log(" " TARGET_FMT_lx, a);
|
||||||
}
|
}
|
||||||
} else if (c == INDEX_op_call) {
|
} else if (c == INDEX_op_call) {
|
||||||
|
const TCGHelperInfo *info = tcg_call_info(op);
|
||||||
|
void *func;
|
||||||
|
|
||||||
/* variable number of arguments */
|
/* variable number of arguments */
|
||||||
nb_oargs = TCGOP_CALLO(op);
|
nb_oargs = TCGOP_CALLO(op);
|
||||||
nb_iargs = TCGOP_CALLI(op);
|
nb_iargs = TCGOP_CALLI(op);
|
||||||
nb_cargs = def->nb_cargs;
|
nb_cargs = def->nb_cargs;
|
||||||
|
|
||||||
/* function name, flags, out args */
|
col += qemu_log(" %s ", def->name);
|
||||||
col += qemu_log(" %s %s,$0x%x,$%d", def->name,
|
|
||||||
tcg_find_helper(s, op->args[nb_oargs + nb_iargs]),
|
/*
|
||||||
tcg_call_flags(op), nb_oargs);
|
* Print the function name from TCGHelperInfo, if available.
|
||||||
|
* Note that plugins have a template function for the info,
|
||||||
|
* but the actual function pointer comes from the plugin.
|
||||||
|
*/
|
||||||
|
func = (void *)(uintptr_t)op->args[nb_oargs + nb_iargs];
|
||||||
|
if (func == info->func) {
|
||||||
|
col += qemu_log("%s", info->name);
|
||||||
|
} else {
|
||||||
|
col += qemu_log("plugin(%p)", func);
|
||||||
|
}
|
||||||
|
|
||||||
|
col += qemu_log("$0x%x,$%d", info->flags, nb_oargs);
|
||||||
for (i = 0; i < nb_oargs; i++) {
|
for (i = 0; i < nb_oargs; i++) {
|
||||||
col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf),
|
col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf),
|
||||||
op->args[i]));
|
op->args[i]));
|
||||||
|
Loading…
Reference in New Issue
Block a user