mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
tcg: Convert setcond, negsetcond to TCGOutOpSetcond
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
f791458932
commit
5a7b38c8ca
13 changed files with 477 additions and 237 deletions
|
@ -1356,25 +1356,37 @@ static inline void tcg_out_dep(TCGContext *s, TCGType ext, TCGReg rd,
|
|||
tcg_out_bfm(s, ext, rd, rn, a, b);
|
||||
}
|
||||
|
||||
static void tgen_cmp(TCGContext *s, TCGType ext, TCGCond cond,
|
||||
TCGReg a, TCGReg b)
|
||||
{
|
||||
if (is_tst_cond(cond)) {
|
||||
tcg_out_insn(s, 3510, ANDS, ext, TCG_REG_XZR, a, b);
|
||||
} else {
|
||||
tcg_out_insn(s, 3502, SUBS, ext, TCG_REG_XZR, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
static void tgen_cmpi(TCGContext *s, TCGType ext, TCGCond cond,
|
||||
TCGReg a, tcg_target_long b)
|
||||
{
|
||||
if (is_tst_cond(cond)) {
|
||||
tcg_out_logicali(s, I3404_ANDSI, ext, TCG_REG_XZR, a, b);
|
||||
} else if (b >= 0) {
|
||||
tcg_debug_assert(is_aimm(b));
|
||||
tcg_out_insn(s, 3401, SUBSI, ext, TCG_REG_XZR, a, b);
|
||||
} else {
|
||||
tcg_debug_assert(is_aimm(-b));
|
||||
tcg_out_insn(s, 3401, ADDSI, ext, TCG_REG_XZR, a, -b);
|
||||
}
|
||||
}
|
||||
|
||||
static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGCond cond, TCGReg a,
|
||||
tcg_target_long b, bool const_b)
|
||||
{
|
||||
if (is_tst_cond(cond)) {
|
||||
if (!const_b) {
|
||||
tcg_out_insn(s, 3510, ANDS, ext, TCG_REG_XZR, a, b);
|
||||
} else {
|
||||
tcg_out_logicali(s, I3404_ANDSI, ext, TCG_REG_XZR, a, b);
|
||||
}
|
||||
if (const_b) {
|
||||
tgen_cmpi(s, ext, cond, a, b);
|
||||
} else {
|
||||
if (!const_b) {
|
||||
tcg_out_insn(s, 3502, SUBS, ext, TCG_REG_XZR, a, b);
|
||||
} else if (b >= 0) {
|
||||
tcg_debug_assert(is_aimm(b));
|
||||
tcg_out_insn(s, 3401, SUBSI, ext, TCG_REG_XZR, a, b);
|
||||
} else {
|
||||
tcg_debug_assert(is_aimm(-b));
|
||||
tcg_out_insn(s, 3401, ADDSI, ext, TCG_REG_XZR, a, -b);
|
||||
}
|
||||
tgen_cmp(s, ext, cond, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2433,6 +2445,59 @@ static const TCGOutOpUnary outop_not = {
|
|||
.out_rr = tgen_not,
|
||||
};
|
||||
|
||||
static void tgen_cset(TCGContext *s, TCGCond cond, TCGReg ret)
|
||||
{
|
||||
/* Use CSET alias of CSINC Wd, WZR, WZR, invert(cond). */
|
||||
tcg_out_insn(s, 3506, CSINC, TCG_TYPE_I32, ret, TCG_REG_XZR,
|
||||
TCG_REG_XZR, tcg_invert_cond(cond));
|
||||
}
|
||||
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg a0, TCGReg a1, TCGReg a2)
|
||||
{
|
||||
tgen_cmp(s, type, cond, a1, a2);
|
||||
tgen_cset(s, cond, a0);
|
||||
}
|
||||
|
||||
static void tgen_setcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg a0, TCGReg a1, tcg_target_long a2)
|
||||
{
|
||||
tgen_cmpi(s, type, cond, a1, a2);
|
||||
tgen_cset(s, cond, a0);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_setcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rC),
|
||||
.out_rrr = tgen_setcond,
|
||||
.out_rri = tgen_setcondi,
|
||||
};
|
||||
|
||||
static void tgen_csetm(TCGContext *s, TCGType ext, TCGCond cond, TCGReg ret)
|
||||
{
|
||||
/* Use CSETM alias of CSINV Wd, WZR, WZR, invert(cond). */
|
||||
tcg_out_insn(s, 3506, CSINV, ext, ret, TCG_REG_XZR,
|
||||
TCG_REG_XZR, tcg_invert_cond(cond));
|
||||
}
|
||||
|
||||
static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg a0, TCGReg a1, TCGReg a2)
|
||||
{
|
||||
tgen_cmp(s, type, cond, a1, a2);
|
||||
tgen_csetm(s, type, cond, a0);
|
||||
}
|
||||
|
||||
static void tgen_negsetcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg a0, TCGReg a1, tcg_target_long a2)
|
||||
{
|
||||
tgen_cmpi(s, type, cond, a1, a2);
|
||||
tgen_csetm(s, type, cond, a0);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_negsetcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rC),
|
||||
.out_rrr = tgen_negsetcond,
|
||||
.out_rri = tgen_negsetcondi,
|
||||
};
|
||||
|
||||
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
|
||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||
|
@ -2507,26 +2572,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
|
|||
tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], arg_label(args[3]));
|
||||
break;
|
||||
|
||||
case INDEX_op_setcond_i32:
|
||||
a2 = (int32_t)a2;
|
||||
/* FALLTHRU */
|
||||
case INDEX_op_setcond_i64:
|
||||
tcg_out_cmp(s, ext, args[3], a1, a2, c2);
|
||||
/* Use CSET alias of CSINC Wd, WZR, WZR, invert(cond). */
|
||||
tcg_out_insn(s, 3506, CSINC, TCG_TYPE_I32, a0, TCG_REG_XZR,
|
||||
TCG_REG_XZR, tcg_invert_cond(args[3]));
|
||||
break;
|
||||
|
||||
case INDEX_op_negsetcond_i32:
|
||||
a2 = (int32_t)a2;
|
||||
/* FALLTHRU */
|
||||
case INDEX_op_negsetcond_i64:
|
||||
tcg_out_cmp(s, ext, args[3], a1, a2, c2);
|
||||
/* Use CSETM alias of CSINV Wd, WZR, WZR, invert(cond). */
|
||||
tcg_out_insn(s, 3506, CSINV, ext, a0, TCG_REG_XZR,
|
||||
TCG_REG_XZR, tcg_invert_cond(args[3]));
|
||||
break;
|
||||
|
||||
case INDEX_op_movcond_i32:
|
||||
a2 = (int32_t)a2;
|
||||
/* FALLTHRU */
|
||||
|
@ -3114,12 +3159,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_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
return C_O1_I2(r, r, rC);
|
||||
|
||||
case INDEX_op_brcond_i32:
|
||||
case INDEX_op_brcond_i64:
|
||||
return C_O0_I2(r, rC);
|
||||
|
|
|
@ -1210,31 +1210,48 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
|
|||
}
|
||||
}
|
||||
|
||||
static TCGCond tcg_out_cmp(TCGContext *s, TCGCond cond, TCGReg a,
|
||||
TCGArg b, int b_const)
|
||||
static TCGCond tgen_cmp(TCGContext *s, TCGCond cond, TCGReg a, TCGReg b)
|
||||
{
|
||||
if (is_tst_cond(cond)) {
|
||||
tcg_out_dat_reg(s, COND_AL, ARITH_TST, 0, a, b, SHIFT_IMM_LSL(0));
|
||||
return tcg_tst_eqne_cond(cond);
|
||||
}
|
||||
tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, a, b, SHIFT_IMM_LSL(0));
|
||||
return cond;
|
||||
}
|
||||
|
||||
static TCGCond tgen_cmpi(TCGContext *s, TCGCond cond, TCGReg a, TCGArg b)
|
||||
{
|
||||
int imm12;
|
||||
|
||||
if (!is_tst_cond(cond)) {
|
||||
tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b, b_const);
|
||||
tcg_out_dat_IN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b);
|
||||
return cond;
|
||||
}
|
||||
|
||||
cond = tcg_tst_eqne_cond(cond);
|
||||
if (b_const) {
|
||||
int imm12 = encode_imm(b);
|
||||
|
||||
/*
|
||||
* The compare constraints allow rIN, but TST does not support N.
|
||||
* Be prepared to load the constant into a scratch register.
|
||||
*/
|
||||
if (imm12 >= 0) {
|
||||
tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, a, imm12);
|
||||
return cond;
|
||||
}
|
||||
/*
|
||||
* The compare constraints allow rIN, but TST does not support N.
|
||||
* Be prepared to load the constant into a scratch register.
|
||||
*/
|
||||
imm12 = encode_imm(b);
|
||||
if (imm12 >= 0) {
|
||||
tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, a, imm12);
|
||||
} else {
|
||||
tcg_out_movi32(s, COND_AL, TCG_REG_TMP, b);
|
||||
b = TCG_REG_TMP;
|
||||
tcg_out_dat_reg(s, COND_AL, ARITH_TST, 0,
|
||||
a, TCG_REG_TMP, SHIFT_IMM_LSL(0));
|
||||
}
|
||||
return tcg_tst_eqne_cond(cond);
|
||||
}
|
||||
|
||||
static TCGCond tcg_out_cmp(TCGContext *s, TCGCond cond, TCGReg a,
|
||||
TCGArg b, int b_const)
|
||||
{
|
||||
if (b_const) {
|
||||
return tgen_cmpi(s, cond, a, b);
|
||||
} else {
|
||||
return tgen_cmp(s, cond, a, b);
|
||||
}
|
||||
tcg_out_dat_reg(s, COND_AL, ARITH_TST, 0, a, b, SHIFT_IMM_LSL(0));
|
||||
return cond;
|
||||
}
|
||||
|
||||
static TCGCond tcg_out_cmp2(TCGContext *s, const TCGArg *args,
|
||||
|
@ -2164,6 +2181,52 @@ static const TCGOutOpUnary outop_not = {
|
|||
.out_rr = tgen_not,
|
||||
};
|
||||
|
||||
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);
|
||||
tcg_out_movi32(s, tcg_cond_to_arm_cond[cond], ret, neg ? -1 : 1);
|
||||
}
|
||||
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg a0, TCGReg a1, TCGReg a2)
|
||||
{
|
||||
cond = tgen_cmp(s, cond, a1, a2);
|
||||
finish_setcond(s, cond, a0, false);
|
||||
}
|
||||
|
||||
static void tgen_setcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg a0, TCGReg a1, tcg_target_long a2)
|
||||
{
|
||||
cond = tgen_cmpi(s, cond, a1, a2);
|
||||
finish_setcond(s, cond, a0, false);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_setcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rIN),
|
||||
.out_rrr = tgen_setcond,
|
||||
.out_rri = tgen_setcondi,
|
||||
};
|
||||
|
||||
static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg a0, TCGReg a1, TCGReg a2)
|
||||
{
|
||||
cond = tgen_cmp(s, cond, a1, a2);
|
||||
finish_setcond(s, cond, a0, true);
|
||||
}
|
||||
|
||||
static void tgen_negsetcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg a0, TCGReg a1, tcg_target_long a2)
|
||||
{
|
||||
cond = tgen_cmpi(s, cond, a1, a2);
|
||||
finish_setcond(s, cond, a0, true);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_negsetcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rIN),
|
||||
.out_rrr = tgen_negsetcond,
|
||||
.out_rri = tgen_negsetcondi,
|
||||
};
|
||||
|
||||
|
||||
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||
|
@ -2258,20 +2321,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
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_setcond_i32:
|
||||
c = tcg_out_cmp(s, args[3], args[1], args[2], const_args[2]);
|
||||
tcg_out_dat_imm(s, tcg_cond_to_arm_cond[c],
|
||||
ARITH_MOV, args[0], 0, 1);
|
||||
tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(c)],
|
||||
ARITH_MOV, args[0], 0, 0);
|
||||
break;
|
||||
case INDEX_op_negsetcond_i32:
|
||||
c = tcg_out_cmp(s, args[3], args[1], args[2], const_args[2]);
|
||||
tcg_out_dat_imm(s, tcg_cond_to_arm_cond[c],
|
||||
ARITH_MVN, args[0], 0, 0);
|
||||
tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(c)],
|
||||
ARITH_MOV, args[0], 0, 0);
|
||||
break;
|
||||
|
||||
case INDEX_op_brcond2_i32:
|
||||
c = tcg_out_cmp2(s, args, const_args);
|
||||
|
@ -2372,10 +2421,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_setcond_i32:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
return C_O1_I2(r, r, rIN);
|
||||
|
||||
case INDEX_op_brcond_i32:
|
||||
return C_O0_I2(r, rIN);
|
||||
case INDEX_op_deposit_i32:
|
||||
|
|
|
@ -1679,10 +1679,11 @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
|
|||
}
|
||||
#endif
|
||||
|
||||
static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond,
|
||||
TCGArg dest, TCGArg arg1, TCGArg arg2,
|
||||
int const_arg2, bool neg)
|
||||
static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGArg arg2,
|
||||
bool const_arg2, bool neg)
|
||||
{
|
||||
int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW;
|
||||
int cmp_rexw = rexw;
|
||||
bool inv = false;
|
||||
bool cleared;
|
||||
|
@ -1757,7 +1758,7 @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond,
|
|||
case TCG_COND_LT:
|
||||
/* If arg2 is 0, extract the sign bit. */
|
||||
if (const_arg2 && arg2 == 0) {
|
||||
tcg_out_mov(s, rexw ? TCG_TYPE_I64 : TCG_TYPE_I32, dest, arg1);
|
||||
tcg_out_mov(s, type, dest, arg1);
|
||||
if (inv) {
|
||||
tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, dest);
|
||||
}
|
||||
|
@ -1793,6 +1794,42 @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond,
|
|||
}
|
||||
}
|
||||
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, false, false);
|
||||
}
|
||||
|
||||
static void tgen_setcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, true, false);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_setcond = {
|
||||
.base.static_constraint = C_O1_I2(q, r, reT),
|
||||
.out_rrr = tgen_setcond,
|
||||
.out_rri = tgen_setcondi,
|
||||
};
|
||||
|
||||
static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, false, true);
|
||||
}
|
||||
|
||||
static void tgen_negsetcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, true, true);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_negsetcond = {
|
||||
.base.static_constraint = C_O1_I2(q, r, reT),
|
||||
.out_rrr = tgen_negsetcond,
|
||||
.out_rri = tgen_negsetcondi,
|
||||
};
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
|
||||
const int *const_args)
|
||||
|
@ -3091,12 +3128,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
tcg_out_brcond(s, rexw, a2, a0, a1, const_args[1],
|
||||
arg_label(args[3]), 0);
|
||||
break;
|
||||
OP_32_64(setcond):
|
||||
tcg_out_setcond(s, rexw, args[3], a0, a1, a2, const_a2, false);
|
||||
break;
|
||||
OP_32_64(negsetcond):
|
||||
tcg_out_setcond(s, rexw, args[3], a0, a1, a2, const_a2, true);
|
||||
break;
|
||||
OP_32_64(movcond):
|
||||
tcg_out_movcond(s, rexw, args[5], a0, a1, a2, const_a2, args[3]);
|
||||
break;
|
||||
|
@ -3934,12 +3965,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_deposit_i64:
|
||||
return C_O1_I2(q, 0, qi);
|
||||
|
||||
case INDEX_op_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
return C_O1_I2(q, r, reT);
|
||||
|
||||
case INDEX_op_movcond_i32:
|
||||
case INDEX_op_movcond_i64:
|
||||
return C_O1_I4(r, r, reT, r, 0);
|
||||
|
|
|
@ -687,6 +687,42 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
|||
}
|
||||
}
|
||||
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tcg_out_setcond(s, cond, dest, arg1, arg2, false, false);
|
||||
}
|
||||
|
||||
static void tgen_setcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tcg_out_setcond(s, cond, dest, arg1, arg2, true, false);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_setcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rJ),
|
||||
.out_rrr = tgen_setcond,
|
||||
.out_rri = tgen_setcondi,
|
||||
};
|
||||
|
||||
static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tcg_out_setcond(s, cond, dest, arg1, arg2, false, true);
|
||||
}
|
||||
|
||||
static void tgen_negsetcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tcg_out_setcond(s, cond, dest, arg1, arg2, true, true);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_negsetcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rJ),
|
||||
.out_rrr = tgen_negsetcond,
|
||||
.out_rri = tgen_negsetcondi,
|
||||
};
|
||||
|
||||
static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||
TCGReg c1, tcg_target_long c2, bool const2,
|
||||
TCGReg v1, TCGReg v2)
|
||||
|
@ -1813,15 +1849,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
tcg_out_opc_revb_d(s, a0, a1);
|
||||
break;
|
||||
|
||||
case INDEX_op_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
tcg_out_setcond(s, args[3], a0, a1, a2, c2, false);
|
||||
break;
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
tcg_out_setcond(s, args[3], a0, a1, a2, c2, true);
|
||||
break;
|
||||
|
||||
case INDEX_op_movcond_i32:
|
||||
case INDEX_op_movcond_i64:
|
||||
tcg_out_movcond(s, args[5], a0, a1, a2, c2, args[3], args[4]);
|
||||
|
@ -2452,12 +2479,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
/* Must deposit into the same register as input */
|
||||
return C_O1_I2(r, 0, rz);
|
||||
|
||||
case INDEX_op_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
return C_O1_I2(r, r, rJ);
|
||||
|
||||
case INDEX_op_movcond_i32:
|
||||
case INDEX_op_movcond_i64:
|
||||
return C_O1_I4(r, rz, rJ, rz, rz);
|
||||
|
|
|
@ -23,8 +23,8 @@ C_O1_I2(r, r, ri)
|
|||
C_O1_I2(r, r, rI)
|
||||
C_O1_I2(r, r, rIK)
|
||||
C_O1_I2(r, r, rJ)
|
||||
C_O1_I2(r, r, rz)
|
||||
C_O1_I2(r, r, rzW)
|
||||
C_O1_I2(r, rz, rz)
|
||||
C_O1_I4(r, rz, rz, rz, 0)
|
||||
C_O1_I4(r, rz, rz, rz, rz)
|
||||
C_O2_I1(r, r, r)
|
||||
|
|
|
@ -952,15 +952,20 @@ static void tcg_out_setcond_end(TCGContext *s, TCGReg ret, int tmpflags)
|
|||
}
|
||||
}
|
||||
|
||||
static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||
TCGReg arg1, TCGReg arg2)
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg ret, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2);
|
||||
tcg_out_setcond_end(s, ret, tmpflags);
|
||||
}
|
||||
|
||||
static void tcg_out_negsetcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||
TCGReg arg1, TCGReg arg2)
|
||||
static const TCGOutOpSetcond outop_setcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rz),
|
||||
.out_rrr = tgen_setcond,
|
||||
};
|
||||
|
||||
static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg ret, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2);
|
||||
TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
|
||||
|
@ -978,6 +983,11 @@ static void tcg_out_negsetcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
|||
}
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_negsetcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rz),
|
||||
.out_rrr = tgen_negsetcond,
|
||||
};
|
||||
|
||||
static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
|
||||
TCGReg arg2, TCGLabel *l)
|
||||
{
|
||||
|
@ -1041,10 +1051,11 @@ static int tcg_out_setcond2_int(TCGContext *s, TCGCond cond, TCGReg ret,
|
|||
break;
|
||||
|
||||
default:
|
||||
tcg_out_setcond(s, TCG_COND_EQ, TCG_TMP0, ah, bh);
|
||||
tcg_out_setcond(s, tcg_unsigned_cond(cond), TCG_TMP1, al, bl);
|
||||
tgen_setcond(s, TCG_TYPE_I32, TCG_COND_EQ, TCG_TMP0, ah, bh);
|
||||
tgen_setcond(s, TCG_TYPE_I32, tcg_unsigned_cond(cond),
|
||||
TCG_TMP1, al, bl);
|
||||
tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, TCG_TMP0);
|
||||
tcg_out_setcond(s, tcg_high_cond(cond), TCG_TMP0, ah, bh);
|
||||
tgen_setcond(s, TCG_TYPE_I32, tcg_high_cond(cond), TCG_TMP0, ah, bh);
|
||||
tcg_out_opc_reg(s, OPC_OR, ret, TCG_TMP0, TCG_TMP1);
|
||||
break;
|
||||
}
|
||||
|
@ -2285,14 +2296,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
tcg_out_movcond(s, args[5], a0, a1, a2, args[3], args[4]);
|
||||
break;
|
||||
|
||||
case INDEX_op_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
tcg_out_setcond(s, args[3], a0, a1, a2);
|
||||
break;
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
tcg_out_negsetcond(s, args[3], a0, a1, a2);
|
||||
break;
|
||||
case INDEX_op_setcond2_i32:
|
||||
tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
|
||||
break;
|
||||
|
@ -2385,12 +2388,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_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
return C_O1_I2(r, rz, rz);
|
||||
|
||||
case INDEX_op_deposit_i32:
|
||||
case INDEX_op_deposit_i64:
|
||||
return C_O1_I2(r, 0, rz);
|
||||
|
|
|
@ -1926,8 +1926,8 @@ static TCGReg tcg_gen_setcond_xor(TCGContext *s, TCGReg arg1, TCGArg arg2,
|
|||
}
|
||||
|
||||
static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGArg arg0, TCGArg arg1, TCGArg arg2,
|
||||
int const_arg2, bool neg)
|
||||
TCGReg arg0, TCGReg arg1, TCGArg arg2,
|
||||
bool const_arg2, bool neg)
|
||||
{
|
||||
int sh;
|
||||
bool inv;
|
||||
|
@ -2072,6 +2072,42 @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
|||
}
|
||||
}
|
||||
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, false, false);
|
||||
}
|
||||
|
||||
static void tgen_setcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, true, false);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_setcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rC),
|
||||
.out_rrr = tgen_setcond,
|
||||
.out_rri = tgen_setcondi,
|
||||
};
|
||||
|
||||
static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, false, true);
|
||||
}
|
||||
|
||||
static void tgen_negsetcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, true, true);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_negsetcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rC),
|
||||
.out_rrr = tgen_negsetcond,
|
||||
.out_rri = tgen_negsetcondi,
|
||||
};
|
||||
|
||||
static void tcg_out_bc(TCGContext *s, TCGCond cond, int bd)
|
||||
{
|
||||
tcg_out32(s, tcg_to_bc[cond] | bd);
|
||||
|
@ -3465,22 +3501,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], false);
|
||||
break;
|
||||
|
||||
case INDEX_op_setcond_i32:
|
||||
tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
|
||||
const_args[2], false);
|
||||
break;
|
||||
case INDEX_op_setcond_i64:
|
||||
tcg_out_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
|
||||
const_args[2], false);
|
||||
break;
|
||||
case INDEX_op_negsetcond_i32:
|
||||
tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
|
||||
const_args[2], true);
|
||||
break;
|
||||
case INDEX_op_negsetcond_i64:
|
||||
tcg_out_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
|
||||
const_args[2], true);
|
||||
break;
|
||||
case INDEX_op_setcond2_i32:
|
||||
tcg_out_setcond2(s, args, const_args);
|
||||
break;
|
||||
|
@ -4276,11 +4296,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_brcond_i32:
|
||||
case INDEX_op_brcond_i64:
|
||||
return C_O0_I2(r, rC);
|
||||
case INDEX_op_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
return C_O1_I2(r, r, rC);
|
||||
case INDEX_op_movcond_i32:
|
||||
case INDEX_op_movcond_i64:
|
||||
return C_O1_I4(r, r, rC, rZ, rZ);
|
||||
|
|
|
@ -1325,6 +1325,24 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
|||
}
|
||||
}
|
||||
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tcg_out_setcond(s, cond, dest, arg1, arg2, false);
|
||||
}
|
||||
|
||||
static void tgen_setcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tcg_out_setcond(s, cond, dest, arg1, arg2, true);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_setcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rI),
|
||||
.out_rrr = tgen_setcond,
|
||||
.out_rri = tgen_setcondi,
|
||||
};
|
||||
|
||||
static void tcg_out_negsetcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||
TCGReg arg1, tcg_target_long arg2, bool c2)
|
||||
{
|
||||
|
@ -1363,6 +1381,24 @@ static void tcg_out_negsetcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
|||
}
|
||||
}
|
||||
|
||||
static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tcg_out_negsetcond(s, cond, dest, arg1, arg2, false);
|
||||
}
|
||||
|
||||
static void tgen_negsetcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tcg_out_negsetcond(s, cond, dest, arg1, arg2, true);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_negsetcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rI),
|
||||
.out_rrr = tgen_negsetcond,
|
||||
.out_rri = tgen_negsetcondi,
|
||||
};
|
||||
|
||||
static void tcg_out_movcond_zicond(TCGContext *s, TCGReg ret, TCGReg test_ne,
|
||||
int val1, bool c_val1,
|
||||
int val2, bool c_val2)
|
||||
|
@ -2485,16 +2521,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
|
||||
break;
|
||||
|
||||
case INDEX_op_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
tcg_out_setcond(s, args[3], a0, a1, a2, c2);
|
||||
break;
|
||||
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
tcg_out_negsetcond(s, args[3], a0, a1, a2, c2);
|
||||
break;
|
||||
|
||||
case INDEX_op_movcond_i32:
|
||||
case INDEX_op_movcond_i64:
|
||||
tcg_out_movcond(s, args[5], a0, a1, a2, c2,
|
||||
|
@ -2837,12 +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_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
return C_O1_I2(r, r, rI);
|
||||
|
||||
case INDEX_op_brcond_i32:
|
||||
case INDEX_op_brcond_i64:
|
||||
return C_O0_I2(rz, rz);
|
||||
|
|
|
@ -1370,9 +1370,9 @@ static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
|
|||
return tgen_cmp2(s, type, c, r1, c2, c2const, need_carry, &inv_cc);
|
||||
}
|
||||
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg c1, TCGArg c2,
|
||||
bool c2const, bool neg)
|
||||
static void tgen_setcond_int(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg c1, TCGArg c2,
|
||||
bool c2const, bool neg)
|
||||
{
|
||||
int cc;
|
||||
|
||||
|
@ -1464,6 +1464,42 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
|||
tcg_out_insn(s, RRFc, LOCGR, dest, TCG_TMP0, cc);
|
||||
}
|
||||
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tgen_setcond_int(s, type, cond, dest, arg1, arg2, false, false);
|
||||
}
|
||||
|
||||
static void tgen_setcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tgen_setcond_int(s, type, cond, dest, arg1, arg2, true, false);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_setcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rC),
|
||||
.out_rrr = tgen_setcond,
|
||||
.out_rri = tgen_setcondi,
|
||||
};
|
||||
|
||||
static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tgen_setcond_int(s, type, cond, dest, arg1, arg2, false, true);
|
||||
}
|
||||
|
||||
static void tgen_negsetcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tgen_setcond_int(s, type, cond, dest, arg1, arg2, true, true);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_negsetcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rC),
|
||||
.out_rrr = tgen_negsetcond,
|
||||
.out_rri = tgen_negsetcondi,
|
||||
};
|
||||
|
||||
static void tgen_movcond_int(TCGContext *s, TCGType type, TCGReg dest,
|
||||
TCGArg v3, int v3const, TCGReg v4,
|
||||
int cc, int inv_cc)
|
||||
|
@ -2825,14 +2861,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
|
||||
args[1], const_args[1], arg_label(args[3]));
|
||||
break;
|
||||
case INDEX_op_setcond_i32:
|
||||
tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
|
||||
args[2], const_args[2], false);
|
||||
break;
|
||||
case INDEX_op_negsetcond_i32:
|
||||
tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
|
||||
args[2], const_args[2], true);
|
||||
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]);
|
||||
|
@ -2910,14 +2938,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
|
||||
args[1], const_args[1], arg_label(args[3]));
|
||||
break;
|
||||
case INDEX_op_setcond_i64:
|
||||
tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
|
||||
args[2], const_args[2], false);
|
||||
break;
|
||||
case INDEX_op_negsetcond_i64:
|
||||
tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
|
||||
args[2], const_args[2], true);
|
||||
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]);
|
||||
|
@ -3434,12 +3454,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_setcond_i32:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
return C_O1_I2(r, r, rC);
|
||||
|
||||
case INDEX_op_brcond_i32:
|
||||
return C_O0_I2(r, ri);
|
||||
case INDEX_op_brcond_i64:
|
||||
|
|
|
@ -15,7 +15,6 @@ C_O0_I2(rz, rJ)
|
|||
C_O1_I1(r, r)
|
||||
C_O1_I2(r, r, r)
|
||||
C_O1_I2(r, r, rJ)
|
||||
C_O1_I2(r, rz, rJ)
|
||||
C_O1_I4(r, rz, rJ, rI, 0)
|
||||
C_O2_I2(r, r, r, r)
|
||||
C_O2_I4(r, r, rz, rz, rJ, rJ)
|
||||
|
|
|
@ -714,7 +714,7 @@ static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
|
|||
}
|
||||
|
||||
static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||
TCGReg c1, int32_t c2, int c2const, bool neg)
|
||||
TCGReg c1, int32_t c2, bool c2const, bool neg)
|
||||
{
|
||||
/* For 32-bit comparisons, we can play games with ADDC/SUBC. */
|
||||
switch (cond) {
|
||||
|
@ -788,7 +788,7 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
|
|||
}
|
||||
|
||||
static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||
TCGReg c1, int32_t c2, int c2const, bool neg)
|
||||
TCGReg c1, int32_t c2, bool c2const, bool neg)
|
||||
{
|
||||
int rcond;
|
||||
|
||||
|
@ -822,6 +822,53 @@ static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
|
|||
}
|
||||
}
|
||||
|
||||
static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg ret, TCGReg c1,
|
||||
TCGArg c2, bool c2const, bool neg)
|
||||
{
|
||||
if (type == TCG_TYPE_I32) {
|
||||
tcg_out_setcond_i32(s, cond, ret, c1, c2, c2const, neg);
|
||||
} else {
|
||||
tcg_out_setcond_i64(s, cond, ret, c1, c2, c2const, neg);
|
||||
}
|
||||
}
|
||||
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, false, false);
|
||||
}
|
||||
|
||||
static void tgen_setcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, true, false);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_setcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rJ),
|
||||
.out_rrr = tgen_setcond,
|
||||
.out_rri = tgen_setcondi,
|
||||
};
|
||||
|
||||
static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, false, true);
|
||||
}
|
||||
|
||||
static void tgen_negsetcondi(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
tcg_out_setcond(s, type, cond, dest, arg1, arg2, true, true);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_negsetcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, rJ),
|
||||
.out_rrr = tgen_negsetcond,
|
||||
.out_rri = tgen_negsetcondi,
|
||||
};
|
||||
|
||||
static void tcg_out_addsub2_i32(TCGContext *s, TCGReg rl, TCGReg rh,
|
||||
TCGReg al, TCGReg ah, int32_t bl, int blconst,
|
||||
int32_t bh, int bhconst, int opl, int oph)
|
||||
|
@ -1711,12 +1758,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_brcond_i32:
|
||||
tcg_out_brcond_i32(s, a2, a0, a1, const_args[1], arg_label(args[3]));
|
||||
break;
|
||||
case INDEX_op_setcond_i32:
|
||||
tcg_out_setcond_i32(s, args[3], a0, a1, a2, c2, false);
|
||||
break;
|
||||
case INDEX_op_negsetcond_i32:
|
||||
tcg_out_setcond_i32(s, args[3], a0, a1, a2, c2, true);
|
||||
break;
|
||||
case INDEX_op_movcond_i32:
|
||||
tcg_out_movcond_i32(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
|
||||
break;
|
||||
|
@ -1758,12 +1799,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_brcond_i64:
|
||||
tcg_out_brcond_i64(s, a2, a0, a1, const_args[1], arg_label(args[3]));
|
||||
break;
|
||||
case INDEX_op_setcond_i64:
|
||||
tcg_out_setcond_i64(s, args[3], a0, a1, a2, c2, false);
|
||||
break;
|
||||
case INDEX_op_negsetcond_i64:
|
||||
tcg_out_setcond_i64(s, args[3], a0, a1, a2, c2, true);
|
||||
break;
|
||||
case INDEX_op_movcond_i64:
|
||||
tcg_out_movcond_i64(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
|
||||
break;
|
||||
|
@ -1837,12 +1872,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_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
return C_O1_I2(r, rz, rJ);
|
||||
|
||||
case INDEX_op_brcond_i32:
|
||||
case INDEX_op_brcond_i64:
|
||||
return C_O0_I2(rz, rJ);
|
||||
|
|
31
tcg/tcg.c
31
tcg/tcg.c
|
@ -1003,6 +1003,14 @@ typedef struct TCGOutOpUnary {
|
|||
void (*out_rr)(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1);
|
||||
} TCGOutOpUnary;
|
||||
|
||||
typedef struct TCGOutOpSetcond {
|
||||
TCGOutOp base;
|
||||
void (*out_rrr)(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg ret, TCGReg a1, TCGReg a2);
|
||||
void (*out_rri)(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg ret, TCGReg a1, tcg_target_long a2);
|
||||
} TCGOutOpSetcond;
|
||||
|
||||
typedef struct TCGOutOpSubtract {
|
||||
TCGOutOp base;
|
||||
void (*out_rrr)(TCGContext *s, TCGType type,
|
||||
|
@ -1047,6 +1055,8 @@ static const TCGOutOp * const all_outop[NB_OPS] = {
|
|||
OUTOP(INDEX_op_muluh, TCGOutOpBinary, outop_muluh),
|
||||
OUTOP(INDEX_op_nand, TCGOutOpBinary, outop_nand),
|
||||
OUTOP(INDEX_op_neg, TCGOutOpUnary, outop_neg),
|
||||
OUTOP(INDEX_op_negsetcond_i32, TCGOutOpSetcond, outop_negsetcond),
|
||||
OUTOP(INDEX_op_negsetcond_i64, TCGOutOpSetcond, outop_negsetcond),
|
||||
OUTOP(INDEX_op_nor, TCGOutOpBinary, outop_nor),
|
||||
OUTOP(INDEX_op_not, TCGOutOpUnary, outop_not),
|
||||
OUTOP(INDEX_op_or, TCGOutOpBinary, outop_or),
|
||||
|
@ -1056,6 +1066,8 @@ static const TCGOutOp * const all_outop[NB_OPS] = {
|
|||
OUTOP(INDEX_op_rotl, TCGOutOpBinary, outop_rotl),
|
||||
OUTOP(INDEX_op_rotr, TCGOutOpBinary, outop_rotr),
|
||||
OUTOP(INDEX_op_sar, TCGOutOpBinary, outop_sar),
|
||||
OUTOP(INDEX_op_setcond_i32, TCGOutOpSetcond, outop_setcond),
|
||||
OUTOP(INDEX_op_setcond_i64, TCGOutOpSetcond, outop_setcond),
|
||||
OUTOP(INDEX_op_shl, TCGOutOpBinary, outop_shl),
|
||||
OUTOP(INDEX_op_shr, TCGOutOpBinary, outop_shr),
|
||||
OUTOP(INDEX_op_sub, TCGOutOpSubtract, outop_sub),
|
||||
|
@ -5482,6 +5494,25 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
|
|||
}
|
||||
break;
|
||||
|
||||
case INDEX_op_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
{
|
||||
const TCGOutOpSetcond *out =
|
||||
container_of(all_outop[op->opc], TCGOutOpSetcond, base);
|
||||
TCGCond cond = new_args[3];
|
||||
|
||||
tcg_debug_assert(!const_args[1]);
|
||||
if (const_args[2]) {
|
||||
out->out_rri(s, type, cond,
|
||||
new_args[0], new_args[1], new_args[2]);
|
||||
} else {
|
||||
out->out_rrr(s, type, cond,
|
||||
new_args[0], new_args[1], new_args[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (def->flags & TCG_OPF_VECTOR) {
|
||||
|
|
|
@ -77,10 +77,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_setcond_i32:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_negsetcond_i32:
|
||||
case INDEX_op_negsetcond_i64:
|
||||
case INDEX_op_deposit_i32:
|
||||
case INDEX_op_deposit_i64:
|
||||
return C_O1_I2(r, r, r);
|
||||
|
@ -942,6 +938,32 @@ static const TCGOutOpUnary outop_not = {
|
|||
.out_rr = tgen_not,
|
||||
};
|
||||
|
||||
static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
TCGOpcode opc = (type == TCG_TYPE_I32
|
||||
? INDEX_op_setcond_i32
|
||||
: INDEX_op_setcond_i64);
|
||||
tcg_out_op_rrrc(s, opc, dest, arg1, arg2, cond);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_setcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, r),
|
||||
.out_rrr = tgen_setcond,
|
||||
};
|
||||
|
||||
static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||
TCGReg dest, TCGReg arg1, TCGReg arg2)
|
||||
{
|
||||
tgen_setcond(s, type, cond, dest, arg1, arg2);
|
||||
tgen_neg(s, type, dest, dest);
|
||||
}
|
||||
|
||||
static const TCGOutOpSetcond outop_negsetcond = {
|
||||
.base.static_constraint = C_O1_I2(r, r, r),
|
||||
.out_rrr = tgen_negsetcond,
|
||||
};
|
||||
|
||||
|
||||
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||
|
@ -958,27 +980,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
tcg_out_op_l(s, opc, arg_label(args[0]));
|
||||
break;
|
||||
|
||||
CASE_32_64(setcond)
|
||||
tcg_out_op_rrrc(s, opc, args[0], args[1], args[2], args[3]);
|
||||
break;
|
||||
|
||||
CASE_32_64(movcond)
|
||||
case INDEX_op_setcond2_i32:
|
||||
tcg_out_op_rrrrrc(s, opc, args[0], args[1], args[2],
|
||||
args[3], args[4], args[5]);
|
||||
break;
|
||||
|
||||
case INDEX_op_negsetcond_i32:
|
||||
tcg_out_op_rrrc(s, INDEX_op_setcond_i32,
|
||||
args[0], args[1], args[2], args[3]);
|
||||
tcg_out_op_rr(s, INDEX_op_neg, args[0], args[0]);
|
||||
break;
|
||||
case INDEX_op_negsetcond_i64:
|
||||
tcg_out_op_rrrc(s, INDEX_op_setcond_i64,
|
||||
args[0], args[1], args[2], args[3]);
|
||||
tcg_out_op_rr(s, INDEX_op_neg, args[0], args[0]);
|
||||
break;
|
||||
|
||||
CASE_32_64(ld8u)
|
||||
CASE_32_64(ld8s)
|
||||
CASE_32_64(ld16u)
|
||||
|
@ -1005,9 +1012,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
break;
|
||||
|
||||
CASE_32_64(brcond)
|
||||
tcg_out_op_rrrc(s, (opc == INDEX_op_brcond_i32
|
||||
? INDEX_op_setcond_i32 : INDEX_op_setcond_i64),
|
||||
TCG_REG_TMP, args[0], args[1], args[2]);
|
||||
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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue