mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 18:23:57 -06:00
tcg: Convert add to TCGOutOpBinary
Drop all backend support for an immediate as the first operand. This should never happen in any case, as we swap commutative operands to place immediates as the second operand. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
b5701261da
commit
662cdbcf00
12 changed files with 302 additions and 195 deletions
41
tcg/tcg.c
41
tcg/tcg.c
|
@ -978,6 +978,14 @@ typedef struct TCGOutOp {
|
|||
TCGConstraintSetIndex (*dynamic_constraint)(TCGType type, unsigned flags);
|
||||
} TCGOutOp;
|
||||
|
||||
typedef struct TCGOutOpBinary {
|
||||
TCGOutOp base;
|
||||
void (*out_rrr)(TCGContext *s, TCGType type,
|
||||
TCGReg a0, TCGReg a1, TCGReg a2);
|
||||
void (*out_rri)(TCGContext *s, TCGType type,
|
||||
TCGReg a0, TCGReg a1, tcg_target_long a2);
|
||||
} TCGOutOpBinary;
|
||||
|
||||
#include "tcg-target.c.inc"
|
||||
|
||||
#ifndef CONFIG_TCG_INTERPRETER
|
||||
|
@ -987,10 +995,21 @@ QEMU_BUILD_BUG_ON((int)(offsetof(CPUNegativeOffsetState, tlb.f[0]) -
|
|||
< MIN_TLB_MASK_TABLE_OFS);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Register V as the TCGOutOp for O.
|
||||
* This verifies that V is of type T, otherwise give a nice compiler error.
|
||||
* This prevents trivial mistakes within each arch/tcg-target.c.inc.
|
||||
*/
|
||||
#define OUTOP(O, T, V) [O] = _Generic(V, T: &V.base)
|
||||
|
||||
/* Register allocation descriptions for every TCGOpcode. */
|
||||
static const TCGOutOp * const all_outop[NB_OPS] = {
|
||||
OUTOP(INDEX_op_add_i32, TCGOutOpBinary, outop_add),
|
||||
OUTOP(INDEX_op_add_i64, TCGOutOpBinary, outop_add),
|
||||
};
|
||||
|
||||
#undef OUTOP
|
||||
|
||||
/*
|
||||
* All TCG threads except the parent (i.e. the one that called tcg_context_init
|
||||
* and registered the target's TCG globals) must register with this function
|
||||
|
@ -5414,6 +5433,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
|
|||
}
|
||||
|
||||
/* emit instruction */
|
||||
TCGType type = TCGOP_TYPE(op);
|
||||
switch (op->opc) {
|
||||
case INDEX_op_ext_i32_i64:
|
||||
tcg_out_exts_i32_i64(s, new_args[0], new_args[1]);
|
||||
|
@ -5424,12 +5444,29 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
|
|||
case INDEX_op_extrl_i64_i32:
|
||||
tcg_out_extrl_i64_i32(s, new_args[0], new_args[1]);
|
||||
break;
|
||||
|
||||
case INDEX_op_add_i32:
|
||||
case INDEX_op_add_i64:
|
||||
{
|
||||
const TCGOutOpBinary *out =
|
||||
container_of(all_outop[op->opc], TCGOutOpBinary, base);
|
||||
|
||||
/* Constants should never appear in the first source operand. */
|
||||
tcg_debug_assert(!const_args[1]);
|
||||
if (const_args[2]) {
|
||||
out->out_rri(s, type, new_args[0], new_args[1], new_args[2]);
|
||||
} else {
|
||||
out->out_rrr(s, type, new_args[0], new_args[1], new_args[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (def->flags & TCG_OPF_VECTOR) {
|
||||
tcg_out_vec_op(s, op->opc, TCGOP_TYPE(op) - TCG_TYPE_V64,
|
||||
tcg_out_vec_op(s, op->opc, type - TCG_TYPE_V64,
|
||||
TCGOP_VECE(op), new_args, const_args);
|
||||
} else {
|
||||
tcg_out_op(s, op->opc, TCGOP_TYPE(op), new_args, const_args);
|
||||
tcg_out_op(s, op->opc, type, new_args, const_args);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue