mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
tcg: Convert brcond2_i32 to TCGOutOpBrcond2
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
c1e84acb7a
commit
f408df587a
7 changed files with 118 additions and 70 deletions
|
@ -2253,6 +2253,19 @@ static const TCGOutOpMovcond outop_movcond = {
|
|||
.out = tgen_movcond,
|
||||
};
|
||||
|
||||
static void tgen_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
|
||||
TCGArg bl, bool const_bl, TCGArg bh, bool const_bh,
|
||||
TCGLabel *l)
|
||||
{
|
||||
cond = tcg_out_cmp2(s, cond, al, ah, bl, const_bl, bh, const_bh);
|
||||
tcg_out_goto_label(s, tcg_cond_to_arm_cond[cond], l);
|
||||
}
|
||||
|
||||
static const TCGOutOpBrcond2 outop_brcond2 = {
|
||||
.base.static_constraint = C_O0_I4(r, r, rI, rI),
|
||||
.out = tgen_brcond2,
|
||||
};
|
||||
|
||||
|
||||
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||
|
@ -2335,11 +2348,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
tcg_out_mov_reg(s, COND_AL, args[0], a0);
|
||||
break;
|
||||
|
||||
case INDEX_op_brcond2_i32:
|
||||
c = tcg_out_cmp2(s, args[4], args[0], args[1], args[2], const_args[2],
|
||||
args[3], const_args[3]);
|
||||
tcg_out_goto_label(s, tcg_cond_to_arm_cond[c], arg_label(args[5]));
|
||||
break;
|
||||
case INDEX_op_setcond2_i32:
|
||||
c = tcg_out_cmp2(s, args[5], args[1], args[2], args[3], const_args[3],
|
||||
args[4], const_args[4]);
|
||||
|
@ -2444,8 +2452,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
return C_O2_I4(r, r, r, r, rIN, rIK);
|
||||
case INDEX_op_sub2_i32:
|
||||
return C_O2_I4(r, r, rI, rI, rIN, rIK);
|
||||
case INDEX_op_brcond2_i32:
|
||||
return C_O0_I4(r, r, rI, rI);
|
||||
case INDEX_op_setcond2_i32:
|
||||
return C_O1_I4(r, r, r, rI, rI);
|
||||
|
||||
|
|
|
@ -1662,42 +1662,52 @@ static const TCGOutOpBrcond outop_brcond = {
|
|||
.out_ri = tgen_brcondi,
|
||||
};
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
|
||||
const int *const_args, bool small)
|
||||
static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al,
|
||||
TCGReg ah, TCGArg bl, bool blconst,
|
||||
TCGArg bh, bool bhconst,
|
||||
TCGLabel *label_this, bool small)
|
||||
{
|
||||
TCGLabel *label_next = gen_new_label();
|
||||
TCGLabel *label_this = arg_label(args[5]);
|
||||
TCGCond cond = args[4];
|
||||
|
||||
switch (cond) {
|
||||
case TCG_COND_EQ:
|
||||
case TCG_COND_TSTEQ:
|
||||
tcg_out_brcond(s, 0, tcg_invert_cond(cond),
|
||||
args[0], args[2], const_args[2], label_next, 1);
|
||||
tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
|
||||
label_this, small);
|
||||
al, bl, blconst, label_next, true);
|
||||
tcg_out_brcond(s, 0, cond, ah, bh, bhconst, label_this, small);
|
||||
break;
|
||||
|
||||
case TCG_COND_NE:
|
||||
case TCG_COND_TSTNE:
|
||||
tcg_out_brcond(s, 0, cond, args[0], args[2], const_args[2],
|
||||
label_this, small);
|
||||
tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
|
||||
label_this, small);
|
||||
tcg_out_brcond(s, 0, cond, al, bl, blconst, label_this, small);
|
||||
tcg_out_brcond(s, 0, cond, ah, bh, bhconst, label_this, small);
|
||||
break;
|
||||
|
||||
default:
|
||||
tcg_out_brcond(s, 0, tcg_high_cond(cond), args[1],
|
||||
args[3], const_args[3], label_this, small);
|
||||
tcg_out_brcond(s, 0, tcg_high_cond(cond),
|
||||
ah, bh, bhconst, label_this, small);
|
||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
||||
tcg_out_brcond(s, 0, tcg_unsigned_cond(cond), args[0],
|
||||
args[2], const_args[2], label_this, small);
|
||||
tcg_out_brcond(s, 0, tcg_unsigned_cond(cond),
|
||||
al, bl, blconst, label_this, small);
|
||||
break;
|
||||
}
|
||||
tcg_out_label(s, label_next);
|
||||
}
|
||||
|
||||
static void tgen_brcond2(TCGContext *s, TCGCond cond, TCGReg al,
|
||||
TCGReg ah, TCGArg bl, bool blconst,
|
||||
TCGArg bh, bool bhconst, TCGLabel *l)
|
||||
{
|
||||
tcg_out_brcond2(s, cond, al, ah, bl, blconst, bh, bhconst, l, false);
|
||||
}
|
||||
|
||||
#if TCG_TARGET_REG_BITS != 32
|
||||
__attribute__((unused))
|
||||
#endif
|
||||
static const TCGOutOpBrcond2 outop_brcond2 = {
|
||||
.base.static_constraint = C_O0_I4(r, r, ri, ri),
|
||||
.out = tgen_brcond2,
|
||||
};
|
||||
|
||||
static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGArg arg2,
|
||||
|
@ -1854,11 +1864,8 @@ static const TCGOutOpSetcond outop_negsetcond = {
|
|||
static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
|
||||
const int *const_args)
|
||||
{
|
||||
TCGArg new_args[6];
|
||||
TCGLabel *label_true, *label_over;
|
||||
|
||||
memcpy(new_args, args+1, 5*sizeof(TCGArg));
|
||||
|
||||
if (args[0] == args[1] || args[0] == args[2]
|
||||
|| (!const_args[3] && args[0] == args[3])
|
||||
|| (!const_args[4] && args[0] == args[4])) {
|
||||
|
@ -1867,8 +1874,8 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
|
|||
label_true = gen_new_label();
|
||||
label_over = gen_new_label();
|
||||
|
||||
new_args[5] = label_arg(label_true);
|
||||
tcg_out_brcond2(s, new_args, const_args+1, 1);
|
||||
tcg_out_brcond2(s, args[5], args[1], args[2], args[3], const_args[3],
|
||||
args[4], const_args[4], label_true, true);
|
||||
|
||||
tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
|
||||
tcg_out_jxx(s, JCC_JMP, label_over, 1);
|
||||
|
@ -1884,9 +1891,10 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
|
|||
tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
|
||||
|
||||
label_over = gen_new_label();
|
||||
new_args[4] = tcg_invert_cond(new_args[4]);
|
||||
new_args[5] = label_arg(label_over);
|
||||
tcg_out_brcond2(s, new_args, const_args+1, 1);
|
||||
tcg_out_brcond2(s, tcg_invert_cond(args[5]), args[1], args[2],
|
||||
args[3], const_args[3],
|
||||
args[4], const_args[4], label_over, true);
|
||||
|
||||
|
||||
tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
|
||||
tcg_out_label(s, label_over);
|
||||
|
@ -3233,9 +3241,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
break;
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
case INDEX_op_brcond2_i32:
|
||||
tcg_out_brcond2(s, args, const_args, 0);
|
||||
break;
|
||||
case INDEX_op_setcond2_i32:
|
||||
tcg_out_setcond2(s, args, const_args);
|
||||
break;
|
||||
|
@ -4007,9 +4012,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
||||
return C_O0_I3(L, L, L);
|
||||
|
||||
case INDEX_op_brcond2_i32:
|
||||
return C_O0_I4(r, r, ri, ri);
|
||||
|
||||
case INDEX_op_setcond2_i32:
|
||||
return C_O1_I4(r, r, r, ri, ri);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ C_O0_I1(r)
|
|||
C_O0_I2(r, rz)
|
||||
C_O0_I2(rz, r)
|
||||
C_O0_I3(rz, rz, r)
|
||||
C_O0_I4(rz, rz, rz, rz)
|
||||
C_O0_I4(r, r, rz, rz)
|
||||
C_O1_I1(r, r)
|
||||
C_O1_I2(r, 0, rz)
|
||||
C_O1_I2(r, r, r)
|
||||
|
|
|
@ -1074,8 +1074,9 @@ static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
|
|||
tcg_out_setcond_end(s, ret, tmpflags);
|
||||
}
|
||||
|
||||
static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
|
||||
TCGReg bl, TCGReg bh, TCGLabel *l)
|
||||
static void tgen_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
|
||||
TCGArg bl, bool const_bl,
|
||||
TCGArg bh, bool const_bh, TCGLabel *l)
|
||||
{
|
||||
int tmpflags = tcg_out_setcond2_int(s, cond, TCG_TMP0, al, ah, bl, bh);
|
||||
TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
|
||||
|
@ -1086,6 +1087,14 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
|
|||
tcg_out_nop(s);
|
||||
}
|
||||
|
||||
#if TCG_TARGET_REG_BITS != 32
|
||||
__attribute__((unused))
|
||||
#endif
|
||||
static const TCGOutOpBrcond2 outop_brcond2 = {
|
||||
.base.static_constraint = C_O0_I4(r, r, rz, rz),
|
||||
.out = tgen_brcond2,
|
||||
};
|
||||
|
||||
static void tgen_movcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg ret, TCGReg c1, TCGArg c2, bool const_c2,
|
||||
TCGArg v1, bool const_v1, TCGArg v2, bool const_v2)
|
||||
|
@ -2297,10 +2306,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
}
|
||||
break;
|
||||
|
||||
case INDEX_op_brcond2_i32:
|
||||
tcg_out_brcond2(s, args[4], a0, a1, a2, args[3], arg_label(args[5]));
|
||||
break;
|
||||
|
||||
case INDEX_op_setcond2_i32:
|
||||
tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
|
||||
break;
|
||||
|
@ -2401,8 +2406,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
return C_O2_I4(r, r, rz, rz, rN, rN);
|
||||
case INDEX_op_setcond2_i32:
|
||||
return C_O1_I4(r, rz, rz, rz, rz);
|
||||
case INDEX_op_brcond2_i32:
|
||||
return C_O0_I4(rz, rz, rz, rz);
|
||||
|
||||
case INDEX_op_qemu_ld_i32:
|
||||
return C_O1_I1(r, r);
|
||||
|
|
|
@ -2283,14 +2283,23 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
|
|||
tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, CR_EQ + 0*4 + 1, 31, 31);
|
||||
}
|
||||
|
||||
static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
|
||||
const int *const_args)
|
||||
static void tgen_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
|
||||
TCGArg bl, bool const_bl,
|
||||
TCGArg bh, bool const_bh, TCGLabel *l)
|
||||
{
|
||||
tcg_out_cmp2(s, args[4], args[0], args[1], args[2], const_args[2],
|
||||
args[3], const_args[3]);
|
||||
tcg_out_bc_lab(s, TCG_COND_EQ, arg_label(args[5]));
|
||||
assert(TCG_TARGET_REG_BITS == 32);
|
||||
tcg_out_cmp2(s, cond, al, ah, bl, const_bl, bh, const_bh);
|
||||
tcg_out_bc_lab(s, TCG_COND_EQ, l);
|
||||
}
|
||||
|
||||
#if TCG_TARGET_REG_BITS != 32
|
||||
__attribute__((unused))
|
||||
#endif
|
||||
static const TCGOutOpBrcond2 outop_brcond2 = {
|
||||
.base.static_constraint = C_O0_I4(r, r, rU, rC),
|
||||
.out = tgen_brcond2,
|
||||
};
|
||||
|
||||
static void tcg_out_mb(TCGContext *s, TCGArg a0)
|
||||
{
|
||||
uint32_t insn;
|
||||
|
@ -3450,10 +3459,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
tcg_out_mem_long(s, STD, STDX, args[0], args[1], args[2]);
|
||||
break;
|
||||
|
||||
case INDEX_op_brcond2_i32:
|
||||
tcg_out_brcond2(s, args, const_args);
|
||||
break;
|
||||
|
||||
case INDEX_op_qemu_ld_i32:
|
||||
tcg_out_qemu_ld(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
|
||||
break;
|
||||
|
@ -4272,8 +4277,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_deposit_i32:
|
||||
case INDEX_op_deposit_i64:
|
||||
return C_O1_I2(r, 0, rZ);
|
||||
case INDEX_op_brcond2_i32:
|
||||
return C_O0_I4(r, r, rU, rC);
|
||||
case INDEX_op_setcond2_i32:
|
||||
return C_O1_I4(r, r, r, rU, rC);
|
||||
case INDEX_op_add2_i64:
|
||||
|
|
30
tcg/tcg.c
30
tcg/tcg.c
|
@ -994,6 +994,13 @@ typedef struct TCGOutOpBrcond {
|
|||
TCGReg a1, tcg_target_long a2, TCGLabel *label);
|
||||
} TCGOutOpBrcond;
|
||||
|
||||
typedef struct TCGOutOpBrcond2 {
|
||||
TCGOutOp base;
|
||||
void (*out)(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
|
||||
TCGArg bl, bool const_bl,
|
||||
TCGArg bh, bool const_bh, TCGLabel *l);
|
||||
} TCGOutOpBrcond2;
|
||||
|
||||
typedef struct TCGOutOpDivRem {
|
||||
TCGOutOp base;
|
||||
void (*out_rr01r)(TCGContext *s, TCGType type,
|
||||
|
@ -1087,6 +1094,10 @@ static const TCGOutOp * const all_outop[NB_OPS] = {
|
|||
OUTOP(INDEX_op_shr, TCGOutOpBinary, outop_shr),
|
||||
OUTOP(INDEX_op_sub, TCGOutOpSubtract, outop_sub),
|
||||
OUTOP(INDEX_op_xor, TCGOutOpBinary, outop_xor),
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
OUTOP(INDEX_op_brcond2_i32, TCGOutOpBrcond2, outop_brcond2),
|
||||
#endif
|
||||
};
|
||||
|
||||
#undef OUTOP
|
||||
|
@ -5540,6 +5551,25 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
|
|||
}
|
||||
break;
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
case INDEX_op_brcond2_i32:
|
||||
{
|
||||
const TCGOutOpBrcond2 *out = &outop_brcond2;
|
||||
TCGCond cond = new_args[4];
|
||||
TCGLabel *label = arg_label(new_args[5]);
|
||||
|
||||
tcg_debug_assert(!const_args[0]);
|
||||
tcg_debug_assert(!const_args[1]);
|
||||
out->out(s, cond, new_args[0], new_args[1],
|
||||
new_args[2], const_args[2],
|
||||
new_args[3], const_args[3], label);
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case INDEX_op_brcond2_i32:
|
||||
g_assert_not_reached();
|
||||
#endif
|
||||
|
||||
default:
|
||||
if (def->flags & TCG_OPF_VECTOR) {
|
||||
tcg_out_vec_op(s, op->opc, type - TCG_TYPE_V64,
|
||||
|
|
|
@ -87,11 +87,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_sub2_i64:
|
||||
return C_O2_I4(r, r, r, r, r, r);
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
case INDEX_op_brcond2_i32:
|
||||
return C_O0_I4(r, r, r, r);
|
||||
#endif
|
||||
|
||||
case INDEX_op_setcond2_i32:
|
||||
return C_O1_I4(r, r, r, r, r);
|
||||
|
||||
|
@ -985,6 +980,23 @@ static const TCGOutOpMovcond outop_movcond = {
|
|||
.out = tgen_movcond,
|
||||
};
|
||||
|
||||
static void tgen_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
|
||||
TCGArg bl, bool const_bl,
|
||||
TCGArg bh, bool const_bh, TCGLabel *l)
|
||||
{
|
||||
tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, TCG_REG_TMP,
|
||||
al, ah, bl, bh, cond);
|
||||
tcg_out_op_rl(s, INDEX_op_brcond, TCG_REG_TMP, l);
|
||||
}
|
||||
|
||||
#if TCG_TARGET_REG_BITS != 32
|
||||
__attribute__((unused))
|
||||
#endif
|
||||
static const TCGOutOpBrcond2 outop_brcond2 = {
|
||||
.base.static_constraint = C_O0_I4(r, r, r, r),
|
||||
.out = tgen_brcond2,
|
||||
};
|
||||
|
||||
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||
const int const_args[TCG_MAX_OP_ARGS])
|
||||
|
@ -1055,14 +1067,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
args[3], args[4], args[5]);
|
||||
break;
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
case INDEX_op_brcond2_i32:
|
||||
tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, TCG_REG_TMP,
|
||||
args[0], args[1], args[2], args[3], args[4]);
|
||||
tcg_out_op_rl(s, INDEX_op_brcond, TCG_REG_TMP, arg_label(args[5]));
|
||||
break;
|
||||
#endif
|
||||
|
||||
case INDEX_op_qemu_ld_i64:
|
||||
case INDEX_op_qemu_st_i64:
|
||||
if (TCG_TARGET_REG_BITS == 32) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue