mirror of
https://github.com/qemu/qemu.git
synced 2025-01-26 07:23:24 +08:00
tcg: Pass number of arguments to tcg_emit_op() / tcg_op_insert_*()
In order to have variable size allocated TCGOp, pass the number of arguments we use (and would allocate) up to tcg_op_alloc(). This alters tcg_emit_op(), tcg_op_insert_before() and tcg_op_insert_after() prototypes. In tcg_op_alloc() ensure the number of arguments is in range. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> [PMD: Extracted from bigger patch] Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-Id: <20221218211832.73312-2-philmd@linaro.org>
This commit is contained in:
parent
f266bec890
commit
d44789434b
@ -258,10 +258,13 @@ static TCGOp *rm_ops(TCGOp *op)
|
||||
|
||||
static TCGOp *copy_op_nocheck(TCGOp **begin_op, TCGOp *op)
|
||||
{
|
||||
unsigned nargs = ARRAY_SIZE(op->args);
|
||||
|
||||
*begin_op = QTAILQ_NEXT(*begin_op, link);
|
||||
tcg_debug_assert(*begin_op);
|
||||
op = tcg_op_insert_after(tcg_ctx, op, (*begin_op)->opc);
|
||||
op = tcg_op_insert_after(tcg_ctx, op, (*begin_op)->opc, nargs);
|
||||
memcpy(op->args, (*begin_op)->args, sizeof(op->args));
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
|
@ -818,7 +818,7 @@ static inline void tcg_gen_plugin_cb_start(unsigned from, unsigned type,
|
||||
|
||||
static inline void tcg_gen_plugin_cb_end(void)
|
||||
{
|
||||
tcg_emit_op(INDEX_op_plugin_cb_end);
|
||||
tcg_emit_op(INDEX_op_plugin_cb_end, 0);
|
||||
}
|
||||
|
||||
#if TARGET_LONG_BITS == 32
|
||||
|
@ -1014,10 +1014,12 @@ bool tcg_op_supported(TCGOpcode op);
|
||||
|
||||
void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
|
||||
|
||||
TCGOp *tcg_emit_op(TCGOpcode opc);
|
||||
TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs);
|
||||
void tcg_op_remove(TCGContext *s, TCGOp *op);
|
||||
TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op, TCGOpcode opc);
|
||||
TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc);
|
||||
TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op,
|
||||
TCGOpcode opc, unsigned nargs);
|
||||
TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op,
|
||||
TCGOpcode opc, unsigned nargs);
|
||||
|
||||
/**
|
||||
* tcg_remove_ops_after:
|
||||
|
@ -962,7 +962,7 @@ static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add)
|
||||
rh = op->args[1];
|
||||
|
||||
/* The proper opcode is supplied by tcg_opt_gen_mov. */
|
||||
op2 = tcg_op_insert_before(ctx->tcg, op, 0);
|
||||
op2 = tcg_op_insert_before(ctx->tcg, op, 0, 2);
|
||||
|
||||
tcg_opt_gen_movi(ctx, op, rl, al);
|
||||
tcg_opt_gen_movi(ctx, op2, rh, ah);
|
||||
@ -1613,7 +1613,7 @@ static bool fold_multiply2(OptContext *ctx, TCGOp *op)
|
||||
rh = op->args[1];
|
||||
|
||||
/* The proper opcode is supplied by tcg_opt_gen_mov. */
|
||||
op2 = tcg_op_insert_before(ctx->tcg, op, 0);
|
||||
op2 = tcg_op_insert_before(ctx->tcg, op, 0, 2);
|
||||
|
||||
tcg_opt_gen_movi(ctx, op, rl, l);
|
||||
tcg_opt_gen_movi(ctx, op2, rh, h);
|
||||
|
@ -152,7 +152,7 @@ bool tcg_can_emit_vecop_list(const TCGOpcode *list,
|
||||
|
||||
void vec_gen_2(TCGOpcode opc, TCGType type, unsigned vece, TCGArg r, TCGArg a)
|
||||
{
|
||||
TCGOp *op = tcg_emit_op(opc);
|
||||
TCGOp *op = tcg_emit_op(opc, 2);
|
||||
TCGOP_VECL(op) = type - TCG_TYPE_V64;
|
||||
TCGOP_VECE(op) = vece;
|
||||
op->args[0] = r;
|
||||
@ -162,7 +162,7 @@ void vec_gen_2(TCGOpcode opc, TCGType type, unsigned vece, TCGArg r, TCGArg a)
|
||||
void vec_gen_3(TCGOpcode opc, TCGType type, unsigned vece,
|
||||
TCGArg r, TCGArg a, TCGArg b)
|
||||
{
|
||||
TCGOp *op = tcg_emit_op(opc);
|
||||
TCGOp *op = tcg_emit_op(opc, 3);
|
||||
TCGOP_VECL(op) = type - TCG_TYPE_V64;
|
||||
TCGOP_VECE(op) = vece;
|
||||
op->args[0] = r;
|
||||
@ -173,7 +173,7 @@ void vec_gen_3(TCGOpcode opc, TCGType type, unsigned vece,
|
||||
void vec_gen_4(TCGOpcode opc, TCGType type, unsigned vece,
|
||||
TCGArg r, TCGArg a, TCGArg b, TCGArg c)
|
||||
{
|
||||
TCGOp *op = tcg_emit_op(opc);
|
||||
TCGOp *op = tcg_emit_op(opc, 4);
|
||||
TCGOP_VECL(op) = type - TCG_TYPE_V64;
|
||||
TCGOP_VECE(op) = vece;
|
||||
op->args[0] = r;
|
||||
@ -185,7 +185,7 @@ void vec_gen_4(TCGOpcode opc, TCGType type, unsigned vece,
|
||||
static void vec_gen_6(TCGOpcode opc, TCGType type, unsigned vece, TCGArg r,
|
||||
TCGArg a, TCGArg b, TCGArg c, TCGArg d, TCGArg e)
|
||||
{
|
||||
TCGOp *op = tcg_emit_op(opc);
|
||||
TCGOp *op = tcg_emit_op(opc, 6);
|
||||
TCGOP_VECL(op) = type - TCG_TYPE_V64;
|
||||
TCGOP_VECE(op) = vece;
|
||||
op->args[0] = r;
|
||||
|
12
tcg/tcg-op.c
12
tcg/tcg-op.c
@ -33,20 +33,20 @@
|
||||
|
||||
void tcg_gen_op1(TCGOpcode opc, TCGArg a1)
|
||||
{
|
||||
TCGOp *op = tcg_emit_op(opc);
|
||||
TCGOp *op = tcg_emit_op(opc, 1);
|
||||
op->args[0] = a1;
|
||||
}
|
||||
|
||||
void tcg_gen_op2(TCGOpcode opc, TCGArg a1, TCGArg a2)
|
||||
{
|
||||
TCGOp *op = tcg_emit_op(opc);
|
||||
TCGOp *op = tcg_emit_op(opc, 2);
|
||||
op->args[0] = a1;
|
||||
op->args[1] = a2;
|
||||
}
|
||||
|
||||
void tcg_gen_op3(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3)
|
||||
{
|
||||
TCGOp *op = tcg_emit_op(opc);
|
||||
TCGOp *op = tcg_emit_op(opc, 3);
|
||||
op->args[0] = a1;
|
||||
op->args[1] = a2;
|
||||
op->args[2] = a3;
|
||||
@ -54,7 +54,7 @@ void tcg_gen_op3(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3)
|
||||
|
||||
void tcg_gen_op4(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3, TCGArg a4)
|
||||
{
|
||||
TCGOp *op = tcg_emit_op(opc);
|
||||
TCGOp *op = tcg_emit_op(opc, 4);
|
||||
op->args[0] = a1;
|
||||
op->args[1] = a2;
|
||||
op->args[2] = a3;
|
||||
@ -64,7 +64,7 @@ void tcg_gen_op4(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3, TCGArg a4)
|
||||
void tcg_gen_op5(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
|
||||
TCGArg a4, TCGArg a5)
|
||||
{
|
||||
TCGOp *op = tcg_emit_op(opc);
|
||||
TCGOp *op = tcg_emit_op(opc, 5);
|
||||
op->args[0] = a1;
|
||||
op->args[1] = a2;
|
||||
op->args[2] = a3;
|
||||
@ -75,7 +75,7 @@ void tcg_gen_op5(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
|
||||
void tcg_gen_op6(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
|
||||
TCGArg a4, TCGArg a5, TCGArg a6)
|
||||
{
|
||||
TCGOp *op = tcg_emit_op(opc);
|
||||
TCGOp *op = tcg_emit_op(opc, 6);
|
||||
op->args[0] = a1;
|
||||
op->args[1] = a2;
|
||||
op->args[2] = a3;
|
||||
|
30
tcg/tcg.c
30
tcg/tcg.c
@ -1479,7 +1479,7 @@ bool tcg_op_supported(TCGOpcode op)
|
||||
and endian swap in tcg_reg_alloc_call(). */
|
||||
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, max_args;
|
||||
unsigned typemask;
|
||||
const TCGHelperInfo *info;
|
||||
TCGOp *op;
|
||||
@ -1513,7 +1513,8 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
|
||||
}
|
||||
}
|
||||
|
||||
op = tcg_emit_op(INDEX_op_call);
|
||||
max_args = ARRAY_SIZE(op->args);
|
||||
op = tcg_emit_op(INDEX_op_call, max_args);
|
||||
|
||||
pi = 0;
|
||||
if (ret != NULL) {
|
||||
@ -1590,7 +1591,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
|
||||
|
||||
/* Make sure the fields didn't overflow. */
|
||||
tcg_debug_assert(TCGOP_CALLI(op) == real_args);
|
||||
tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
|
||||
tcg_debug_assert(pi <= max_args);
|
||||
|
||||
if (TCG_TARGET_CALL_ARG_I32 == TCG_CALL_ARG_EXTEND) {
|
||||
for (i = 0; i < nargs; ++i) {
|
||||
@ -2294,11 +2295,12 @@ void tcg_remove_ops_after(TCGOp *op)
|
||||
}
|
||||
}
|
||||
|
||||
static TCGOp *tcg_op_alloc(TCGOpcode opc)
|
||||
static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs)
|
||||
{
|
||||
TCGContext *s = tcg_ctx;
|
||||
TCGOp *op;
|
||||
|
||||
assert(nargs < ARRAY_SIZE(op->args));
|
||||
if (likely(QTAILQ_EMPTY(&s->free_ops))) {
|
||||
op = tcg_malloc(sizeof(TCGOp));
|
||||
} else {
|
||||
@ -2312,23 +2314,25 @@ static TCGOp *tcg_op_alloc(TCGOpcode opc)
|
||||
return op;
|
||||
}
|
||||
|
||||
TCGOp *tcg_emit_op(TCGOpcode opc)
|
||||
TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs)
|
||||
{
|
||||
TCGOp *op = tcg_op_alloc(opc);
|
||||
TCGOp *op = tcg_op_alloc(opc, nargs);
|
||||
QTAILQ_INSERT_TAIL(&tcg_ctx->ops, op, link);
|
||||
return op;
|
||||
}
|
||||
|
||||
TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op, TCGOpcode opc)
|
||||
TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op,
|
||||
TCGOpcode opc, unsigned nargs)
|
||||
{
|
||||
TCGOp *new_op = tcg_op_alloc(opc);
|
||||
TCGOp *new_op = tcg_op_alloc(opc, nargs);
|
||||
QTAILQ_INSERT_BEFORE(old_op, new_op, link);
|
||||
return new_op;
|
||||
}
|
||||
|
||||
TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op, TCGOpcode opc)
|
||||
TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op,
|
||||
TCGOpcode opc, unsigned nargs)
|
||||
{
|
||||
TCGOp *new_op = tcg_op_alloc(opc);
|
||||
TCGOp *new_op = tcg_op_alloc(opc, nargs);
|
||||
QTAILQ_INSERT_AFTER(&s->ops, old_op, new_op, link);
|
||||
return new_op;
|
||||
}
|
||||
@ -2937,7 +2941,7 @@ static bool liveness_pass_2(TCGContext *s)
|
||||
TCGOpcode lopc = (arg_ts->type == TCG_TYPE_I32
|
||||
? INDEX_op_ld_i32
|
||||
: INDEX_op_ld_i64);
|
||||
TCGOp *lop = tcg_op_insert_before(s, op, lopc);
|
||||
TCGOp *lop = tcg_op_insert_before(s, op, lopc, 3);
|
||||
|
||||
lop->args[0] = temp_arg(dir_ts);
|
||||
lop->args[1] = temp_arg(arg_ts->mem_base);
|
||||
@ -3003,7 +3007,7 @@ static bool liveness_pass_2(TCGContext *s)
|
||||
TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
|
||||
? INDEX_op_st_i32
|
||||
: INDEX_op_st_i64);
|
||||
TCGOp *sop = tcg_op_insert_after(s, op, sopc);
|
||||
TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
|
||||
TCGTemp *out_ts = dir_ts;
|
||||
|
||||
if (IS_DEAD_ARG(0)) {
|
||||
@ -3039,7 +3043,7 @@ static bool liveness_pass_2(TCGContext *s)
|
||||
TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
|
||||
? INDEX_op_st_i32
|
||||
: INDEX_op_st_i64);
|
||||
TCGOp *sop = tcg_op_insert_after(s, op, sopc);
|
||||
TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
|
||||
|
||||
sop->args[0] = temp_arg(dir_ts);
|
||||
sop->args[1] = temp_arg(arg_ts->mem_base);
|
||||
|
Loading…
Reference in New Issue
Block a user