tcg: Convert brcond to TCGOutOpBrcond

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-01-10 11:40:06 -08:00
parent a363e1e179
commit 99ac4706b3
16 changed files with 190 additions and 125 deletions

View file

@ -1424,8 +1424,16 @@ static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)
}
}
static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
TCGArg b, bool b_const, TCGLabel *l)
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
TCGReg a, TCGReg b, TCGLabel *l)
{
tgen_cmp(s, type, c, a, b);
tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
tcg_out_insn(s, 3202, B_C, c, 0);
}
static void tgen_brcondi(TCGContext *s, TCGType ext, TCGCond c,
TCGReg a, tcg_target_long b, TCGLabel *l)
{
int tbit = -1;
bool need_cmp = true;
@ -1434,14 +1442,14 @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
case TCG_COND_EQ:
case TCG_COND_NE:
/* cmp xN,0; b.ne L -> cbnz xN,L */
if (b_const && b == 0) {
if (b == 0) {
need_cmp = false;
}
break;
case TCG_COND_LT:
case TCG_COND_GE:
/* cmp xN,0; b.mi L -> tbnz xN,63,L */
if (b_const && b == 0) {
if (b == 0) {
c = (c == TCG_COND_LT ? TCG_COND_TSTNE : TCG_COND_TSTEQ);
tbit = ext ? 63 : 31;
need_cmp = false;
@ -1450,14 +1458,14 @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
case TCG_COND_TSTEQ:
case TCG_COND_TSTNE:
/* tst xN,0xffffffff; b.ne L -> cbnz wN,L */
if (b_const && b == UINT32_MAX) {
if (b == UINT32_MAX) {
c = tcg_tst_eqne_cond(c);
ext = TCG_TYPE_I32;
need_cmp = false;
break;
}
/* tst xN,1<<B; b.ne L -> tbnz xN,B,L */
if (b_const && is_power_of_2(b)) {
if (is_power_of_2(b)) {
tbit = ctz64(b);
need_cmp = false;
}
@ -1467,7 +1475,7 @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
}
if (need_cmp) {
tcg_out_cmp(s, ext, c, a, b, b_const);
tgen_cmpi(s, ext, c, a, b);
tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
tcg_out_insn(s, 3202, B_C, c, 0);
return;
@ -1500,6 +1508,12 @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
}
}
static const TCGOutOpBrcond outop_brcond = {
.base.static_constraint = C_O0_I2(r, rC),
.out_rr = tgen_brcond,
.out_ri = tgen_brcondi,
};
static inline void tcg_out_rev(TCGContext *s, int ext, MemOp s_bits,
TCGReg rd, TCGReg rn)
{
@ -2565,13 +2579,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
tcg_out_ldst(s, I3312_STRX, a0, a1, a2, 3);
break;
case INDEX_op_brcond_i32:
a1 = (int32_t)a1;
/* FALLTHRU */
case INDEX_op_brcond_i64:
tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], arg_label(args[3]));
break;
case INDEX_op_movcond_i32:
a2 = (int32_t)a2;
/* FALLTHRU */
@ -3159,10 +3166,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st_i64:
return C_O0_I2(rz, r);
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
return C_O0_I2(r, rC);
case INDEX_op_movcond_i32:
case INDEX_op_movcond_i64:
return C_O1_I4(r, r, rC, rz, rz);

View file

@ -2181,6 +2181,26 @@ static const TCGOutOpUnary outop_not = {
.out_rr = tgen_not,
};
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
TCGReg a0, TCGReg a1, TCGLabel *l)
{
cond = tgen_cmp(s, cond, a0, a1);
tcg_out_goto_label(s, tcg_cond_to_arm_cond[cond], l);
}
static void tgen_brcondi(TCGContext *s, TCGType type, TCGCond cond,
TCGReg a0, tcg_target_long a1, TCGLabel *l)
{
cond = tgen_cmpi(s, cond, a0, a1);
tcg_out_goto_label(s, tcg_cond_to_arm_cond[cond], l);
}
static const TCGOutOpBrcond outop_brcond = {
.base.static_constraint = C_O0_I2(r, rIN),
.out_rr = tgen_brcond,
.out_ri = tgen_brcondi,
};
static void finish_setcond(TCGContext *s, TCGCond cond, TCGReg ret, bool neg)
{
tcg_out_movi32(s, tcg_cond_to_arm_cond[tcg_invert_cond(cond)], ret, 0);
@ -2317,11 +2337,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_brcond_i32:
c = tcg_out_cmp(s, args[2], args[0], args[1], const_args[1]);
tcg_out_goto_label(s, tcg_cond_to_arm_cond[c], arg_label(args[3]));
break;
case INDEX_op_brcond2_i32:
c = tcg_out_cmp2(s, args, const_args);
tcg_out_goto_label(s, tcg_cond_to_arm_cond[c], arg_label(args[5]));
@ -2421,8 +2436,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st_i32:
return C_O0_I2(r, r);
case INDEX_op_brcond_i32:
return C_O0_I2(r, rIN);
case INDEX_op_deposit_i32:
return C_O1_I2(r, 0, rZ);
case INDEX_op_extract2_i32:

View file

@ -1642,6 +1642,26 @@ static void tcg_out_brcond(TCGContext *s, int rexw, TCGCond cond,
tcg_out_jxx(s, jcc, label, small);
}
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg1, TCGReg arg2, TCGLabel *label)
{
int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW;
tcg_out_brcond(s, rexw, cond, arg1, arg2, false, label, false);
}
static void tgen_brcondi(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg1, tcg_target_long arg2, TCGLabel *label)
{
int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW;
tcg_out_brcond(s, rexw, cond, arg1, arg2, true, label, false);
}
static const TCGOutOpBrcond outop_brcond = {
.base.static_constraint = C_O0_I2(r, reT),
.out_rr = tgen_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)
@ -3124,10 +3144,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
}
break;
OP_32_64(brcond):
tcg_out_brcond(s, rexw, a2, a0, a1, const_args[1],
arg_label(args[3]), 0);
break;
OP_32_64(movcond):
tcg_out_movcond(s, rexw, args[5], a0, a1, a2, const_a2, args[3]);
break;
@ -3936,10 +3952,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st_i64:
return C_O0_I2(re, r);
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
return C_O0_I2(r, reT);
case INDEX_op_bswap16_i32:
case INDEX_op_bswap16_i64:
case INDEX_op_bswap32_i32:

View file

@ -16,7 +16,7 @@
*/
C_O0_I1(r)
C_O0_I2(rz, r)
C_O0_I2(rz, rz)
C_O0_I2(r, rz)
C_O0_I2(w, r)
C_O0_I3(r, r, r)
C_O1_I1(r, r)

View file

@ -767,8 +767,8 @@ static const struct {
[TCG_COND_GTU] = { OPC_BGTU, false }
};
static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
TCGReg arg2, TCGLabel *l)
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg1, TCGReg arg2, TCGLabel *l)
{
LoongArchInsn op = tcg_brcond_to_loongarch[cond].op;
@ -785,6 +785,11 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0));
}
static const TCGOutOpBrcond outop_brcond = {
.base.static_constraint = C_O0_I2(r, rz),
.out_rr = tgen_brcond,
};
static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
{
TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
@ -1771,11 +1776,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
tcg_out_opc_b(s, 0);
break;
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
break;
case INDEX_op_extrh_i64_i32:
tcg_out_opc_srai_d(s, a0, a1, 32);
break;
@ -2441,10 +2441,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_qemu_st_i128:
return C_O0_I3(r, r, r);
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
return C_O0_I2(rz, rz);
case INDEX_op_extu_i32_i64:
case INDEX_op_extrl_i64_i32:
case INDEX_op_extrh_i64_i32:

View file

@ -10,12 +10,10 @@
* tcg-target-con-str.h; the constraint combination is inclusive or.
*/
C_O0_I1(r)
C_O0_I2(r, rz)
C_O0_I2(rz, r)
C_O0_I2(rz, rz)
C_O0_I3(rz, r, r)
C_O0_I3(rz, rz, r)
C_O0_I4(rz, rz, rz, rz)
C_O0_I4(rz, rz, r, r)
C_O1_I1(r, r)
C_O1_I2(r, 0, rz)
C_O1_I2(r, r, r)

View file

@ -988,8 +988,8 @@ static const TCGOutOpSetcond outop_negsetcond = {
.out_rrr = tgen_negsetcond,
};
static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
TCGReg arg2, TCGLabel *l)
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg1, TCGReg arg2, TCGLabel *l)
{
static const MIPSInsn b_zero[16] = {
[TCG_COND_LT] = OPC_BLTZ,
@ -1034,6 +1034,11 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
tcg_out_nop(s);
}
static const TCGOutOpBrcond outop_brcond = {
.base.static_constraint = C_O0_I2(r, rz),
.out_rr = tgen_brcond,
};
static int tcg_out_setcond2_int(TCGContext *s, TCGCond cond, TCGReg ret,
TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh)
{
@ -2178,8 +2183,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
}
break;
case INDEX_op_br:
tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO,
arg_label(a0));
tgen_brcond(s, TCG_TYPE_I32, TCG_COND_EQ,
TCG_REG_ZERO, TCG_REG_ZERO, arg_label(a0));
break;
case INDEX_op_ld8u_i32:
@ -2283,10 +2288,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
}
break;
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
break;
case INDEX_op_brcond2_i32:
tcg_out_brcond2(s, args[4], a0, a1, a2, args[3], arg_label(args[5]));
break;
@ -2391,9 +2392,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_brcond_i32:
case INDEX_op_brcond_i64:
return C_O0_I2(rz, rz);
case INDEX_op_movcond_i32:
case INDEX_op_movcond_i64:
return (use_mips32r6_instructions

View file

@ -2124,14 +2124,26 @@ static void tcg_out_bc_lab(TCGContext *s, TCGCond cond, TCGLabel *l)
tcg_out_bc(s, cond, bd);
}
static void tcg_out_brcond(TCGContext *s, TCGCond cond,
TCGArg arg1, TCGArg arg2, int const_arg2,
TCGLabel *l, TCGType type)
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg1, TCGReg arg2, TCGLabel *l)
{
tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 0, type);
tcg_out_cmp(s, cond, arg1, arg2, false, 0, type);
tcg_out_bc_lab(s, cond, l);
}
static void tgen_brcondi(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg1, tcg_target_long arg2, TCGLabel *l)
{
tcg_out_cmp(s, cond, arg1, arg2, true, 0, type);
tcg_out_bc_lab(s, cond, l);
}
static const TCGOutOpBrcond outop_brcond = {
.base.static_constraint = C_O0_I2(r, rC),
.out_rr = tgen_brcond,
.out_ri = tgen_brcondi,
};
static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
TCGArg dest, TCGArg c1, TCGArg c2, TCGArg v1,
TCGArg v2, bool const_c2)
@ -3457,14 +3469,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_brcond_i32:
tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
arg_label(args[3]), TCG_TYPE_I32);
break;
case INDEX_op_brcond_i64:
tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
arg_label(args[3]), TCG_TYPE_I64);
break;
case INDEX_op_brcond2_i32:
tcg_out_brcond2(s, args, const_args);
break;
@ -4293,9 +4297,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st_i64:
return C_O0_I2(r, r);
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
return C_O0_I2(r, rC);
case INDEX_op_movcond_i32:
case INDEX_op_movcond_i64:
return C_O1_I4(r, r, rC, rZ, rZ);

View file

@ -11,7 +11,7 @@
*/
C_O0_I1(r)
C_O0_I2(rz, r)
C_O0_I2(rz, rz)
C_O0_I2(r, rz)
C_O1_I1(r, r)
C_O1_I2(r, r, r)
C_O1_I2(r, r, ri)

View file

@ -1184,8 +1184,8 @@ static const struct {
[TCG_COND_GTU] = { OPC_BLTU, true }
};
static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
TCGReg arg2, TCGLabel *l)
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg1, TCGReg arg2, TCGLabel *l)
{
RISCVInsn op = tcg_brcond_to_riscv[cond].op;
@ -1201,6 +1201,11 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
tcg_out_opc_branch(s, op, arg1, arg2, 0);
}
static const TCGOutOpBrcond outop_brcond = {
.base.static_constraint = C_O0_I2(r, rz),
.out_rr = tgen_brcond,
};
#define SETCOND_INV TCG_TARGET_NB_REGS
#define SETCOND_NEZ (SETCOND_INV << 1)
#define SETCOND_FLAGS (SETCOND_INV | SETCOND_NEZ)
@ -2516,11 +2521,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const_args[4], const_args[5], true, false);
break;
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
break;
case INDEX_op_movcond_i32:
case INDEX_op_movcond_i64:
tcg_out_movcond(s, args[5], a0, a1, a2, c2,
@ -2863,10 +2863,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st_i64:
return C_O0_I2(rz, r);
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
return C_O0_I2(rz, rz);
case INDEX_op_movcond_i32:
case INDEX_op_movcond_i64:
return C_O1_I4(r, r, rI, rM, rM);

View file

@ -1693,6 +1693,24 @@ static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
tgen_branch(s, cc, l);
}
static void tgen_brcondr(TCGContext *s, TCGType type, TCGCond c,
TCGReg a0, TCGReg a1, TCGLabel *l)
{
tgen_brcond(s, type, c, a0, a1, false, l);
}
static void tgen_brcondi(TCGContext *s, TCGType type, TCGCond c,
TCGReg a0, tcg_target_long a1, TCGLabel *l)
{
tgen_brcond(s, type, c, a0, a1, true, l);
}
static const TCGOutOpBrcond outop_brcond = {
.base.static_constraint = C_O0_I2(r, rC),
.out_rr = tgen_brcondr,
.out_ri = tgen_brcondi,
};
static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *dest)
{
ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
@ -2857,10 +2875,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
tgen_branch(s, S390_CC_ALWAYS, arg_label(args[0]));
break;
case INDEX_op_brcond_i32:
tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
args[1], const_args[1], arg_label(args[3]));
break;
case INDEX_op_movcond_i32:
tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1],
args[2], const_args[2], args[3], const_args[3], args[4]);
@ -2934,10 +2948,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
tcg_out_insn(s, RRE, SLBGR, args[1], args[5]);
break;
case INDEX_op_brcond_i64:
tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
args[1], const_args[1], arg_label(args[3]));
break;
case INDEX_op_movcond_i64:
tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1],
args[2], const_args[2], args[3], const_args[3], args[4]);
@ -3454,11 +3464,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st_i64:
return C_O0_I2(r, r);
case INDEX_op_brcond_i32:
return C_O0_I2(r, ri);
case INDEX_op_brcond_i64:
return C_O0_I2(r, rC);
case INDEX_op_bswap16_i32:
case INDEX_op_bswap16_i64:
case INDEX_op_bswap32_i32:

View file

@ -11,7 +11,7 @@
*/
C_O0_I1(r)
C_O0_I2(rz, r)
C_O0_I2(rz, rJ)
C_O0_I2(r, rJ)
C_O1_I1(r, r)
C_O1_I2(r, r, r)
C_O1_I2(r, r, rJ)

View file

@ -822,6 +822,35 @@ static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
}
}
static void tcg_out_brcond(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg1, TCGArg arg2, bool const_arg2,
TCGLabel *l)
{
if (type == TCG_TYPE_I32) {
tcg_out_brcond_i32(s, cond, arg1, arg2, const_arg2, l);
} else {
tcg_out_brcond_i64(s, cond, arg1, arg2, const_arg2, l);
}
}
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg1, TCGReg arg2, TCGLabel *l)
{
tcg_out_brcond(s, type, cond, arg1, arg2, false, l);
}
static void tgen_brcondi(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg1, tcg_target_long arg2, TCGLabel *l)
{
tcg_out_brcond(s, type, cond, arg1, arg2, true, l);
}
static const TCGOutOpBrcond outop_brcond = {
.base.static_constraint = C_O0_I2(r, rJ),
.out_rr = tgen_brcond,
.out_ri = tgen_brcondi,
};
static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
TCGReg ret, TCGReg c1,
TCGArg c2, bool c2const, bool neg)
@ -1755,9 +1784,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
tcg_out_ldst(s, a0, a1, a2, STW);
break;
case INDEX_op_brcond_i32:
tcg_out_brcond_i32(s, a2, a0, a1, const_args[1], arg_label(args[3]));
break;
case INDEX_op_movcond_i32:
tcg_out_movcond_i32(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
break;
@ -1796,9 +1822,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
tcg_out_ldst(s, a0, a1, a2, STX);
break;
case INDEX_op_brcond_i64:
tcg_out_brcond_i64(s, a2, a0, a1, const_args[1], arg_label(args[3]));
break;
case INDEX_op_movcond_i64:
tcg_out_movcond_i64(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
break;
@ -1872,9 +1895,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_qemu_st_i64:
return C_O0_I2(rz, r);
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
return C_O0_I2(rz, rJ);
case INDEX_op_movcond_i32:
case INDEX_op_movcond_i64:
return C_O1_I4(r, rz, rJ, rI, 0);

View file

@ -986,6 +986,14 @@ typedef struct TCGOutOpBinary {
TCGReg a0, TCGReg a1, tcg_target_long a2);
} TCGOutOpBinary;
typedef struct TCGOutOpBrcond {
TCGOutOp base;
void (*out_rr)(TCGContext *s, TCGType type, TCGCond cond,
TCGReg a1, TCGReg a2, TCGLabel *label);
void (*out_ri)(TCGContext *s, TCGType type, TCGCond cond,
TCGReg a1, tcg_target_long a2, TCGLabel *label);
} TCGOutOpBrcond;
typedef struct TCGOutOpDivRem {
TCGOutOp base;
void (*out_rr01r)(TCGContext *s, TCGType type,
@ -1040,6 +1048,8 @@ static const TCGOutOp * const all_outop[NB_OPS] = {
OUTOP(INDEX_op_add, TCGOutOpBinary, outop_add),
OUTOP(INDEX_op_and, TCGOutOpBinary, outop_and),
OUTOP(INDEX_op_andc, TCGOutOpBinary, outop_andc),
OUTOP(INDEX_op_brcond_i32, TCGOutOpBrcond, outop_brcond),
OUTOP(INDEX_op_brcond_i64, TCGOutOpBrcond, outop_brcond),
OUTOP(INDEX_op_clz, TCGOutOpBinary, outop_clz),
OUTOP(INDEX_op_ctpop, TCGOutOpUnary, outop_ctpop),
OUTOP(INDEX_op_ctz, TCGOutOpBinary, outop_ctz),
@ -5486,6 +5496,22 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
}
break;
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
{
const TCGOutOpBrcond *out = &outop_brcond;
TCGCond cond = new_args[2];
TCGLabel *label = arg_label(new_args[3]);
tcg_debug_assert(!const_args[0]);
if (const_args[1]) {
out->out_ri(s, type, cond, new_args[0], new_args[1], label);
} else {
out->out_rr(s, type, cond, new_args[0], new_args[1], label);
}
}
break;
case INDEX_op_setcond:
case INDEX_op_negsetcond:
{

View file

@ -665,8 +665,9 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
regs[r0] = sextract32(regs[r1], pos, len);
break;
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
tci_args_rl(insn, tb_ptr, &r0, &ptr);
if ((uint32_t)regs[r0]) {
if (regs[r0]) {
tb_ptr = ptr;
}
break;
@ -784,12 +785,6 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrbb(insn, &r0, &r1, &pos, &len);
regs[r0] = sextract64(regs[r1], pos, len);
break;
case INDEX_op_brcond_i64:
tci_args_rl(insn, tb_ptr, &r0, &ptr);
if (regs[r0]) {
tb_ptr = ptr;
}
break;
case INDEX_op_ext_i32_i64:
tci_args_rr(insn, &r0, &r1);
regs[r0] = (int32_t)regs[r1];

View file

@ -81,10 +81,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_deposit_i64:
return C_O1_I2(r, r, r);
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
return C_O0_I2(r, r);
case INDEX_op_add2_i32:
case INDEX_op_add2_i64:
case INDEX_op_sub2_i32:
@ -964,6 +960,17 @@ static const TCGOutOpSetcond outop_negsetcond = {
.out_rrr = tgen_negsetcond,
};
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
TCGReg arg0, TCGReg arg1, TCGLabel *l)
{
tgen_setcond(s, type, cond, TCG_REG_TMP, arg0, arg1);
tcg_out_op_rl(s, INDEX_op_brcond_i32, TCG_REG_TMP, l);
}
static const TCGOutOpBrcond outop_brcond = {
.base.static_constraint = C_O0_I2(r, r),
.out_rr = tgen_brcond,
};
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
@ -1011,11 +1018,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
tcg_out_op_rrbb(s, opc, args[0], args[1], args[2], args[3]);
break;
CASE_32_64(brcond)
tgen_setcond(s, type, args[2], TCG_REG_TMP, args[0], args[1]);
tcg_out_op_rl(s, opc, TCG_REG_TMP, arg_label(args[3]));
break;
case INDEX_op_bswap32_i32: /* Optional (TCG_TARGET_HAS_bswap32_i32). */
case INDEX_op_bswap64_i64: /* Optional (TCG_TARGET_HAS_bswap64_i64). */
tcg_out_op_rr(s, opc, args[0], args[1]);