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:
Richard Henderson 2021-03-18 11:29:50 -06:00
parent 9d87e59585
commit 3e92aa3443
2 changed files with 34 additions and 29 deletions

View File

@ -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 */

View File

@ -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]));