mirror of https://github.com/proxmox/mirror_qemu
tcg/i386 fixes
-----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJYfqF8AAoJEK0ScMxN0Ceb694H/ih/nSzpKSGzYi/Qr8Xv3GaU rFIGinYNMeja+BiVtqvlvjs+Syc8Mf7S3TJCcfrD2w1C9NywhDF2/SOrONCuAp7Z NpjrVX2YFdXwnXnnhiZV/MxYxvaxOQ10LnyAQTxJLW7MKh1Z2kjJ/uw7EHCag2MR B4FMjAPVrMZfW8VRuWUaugdl+oJcPJg+uAdiIpV3fYg75VOzSwb7sO5NLOfIJYqI ACSyJtdb+L3oWorToLmyezZSs4xXVeuaEFZ/UIpIA3iztzdIjAc6BzBPx6wuoKLN KJpip7kdwTCCINRTi7BaK5jYLdoTfD0Yh2bW1G1uZS7k8GaBn/iXSA1jHweVCJk= =Wmg7 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20170117' into staging tcg/i386 fixes # gpg: Signature made Tue 17 Jan 2017 22:58:04 GMT # gpg: using RSA key 0xAD1270CC4DD0279B # gpg: Good signature from "Richard Henderson <rth7680@gmail.com>" # gpg: aka "Richard Henderson <rth@redhat.com>" # gpg: aka "Richard Henderson <rth@twiddle.net>" # Primary key fingerprint: 9CB1 8DDA F8E8 49AD 2AFC 16A4 AD12 70CC 4DD0 279B * remotes/rth/tags/pull-tcg-20170117: tcg/i386: Always use TZCNT when available Revert "tcg/i386: Rely on undefined/undocumented behaviour of BSF/BSR" Signed-off-by: Peter Maydell <peter.maydell@linaro.org>master
commit
5e59fb10ce
|
@ -1143,17 +1143,18 @@ static void tcg_out_movcond64(TCGContext *s, TCGCond cond, TCGReg dest,
|
||||||
static void tcg_out_ctz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
|
static void tcg_out_ctz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
|
||||||
TCGArg arg2, bool const_a2)
|
TCGArg arg2, bool const_a2)
|
||||||
{
|
{
|
||||||
if (const_a2) {
|
if (have_bmi1) {
|
||||||
tcg_debug_assert(have_bmi1);
|
|
||||||
tcg_debug_assert(arg2 == (rexw ? 64 : 32));
|
|
||||||
tcg_out_modrm(s, OPC_TZCNT + rexw, dest, arg1);
|
tcg_out_modrm(s, OPC_TZCNT + rexw, dest, arg1);
|
||||||
|
if (const_a2) {
|
||||||
|
tcg_debug_assert(arg2 == (rexw ? 64 : 32));
|
||||||
|
} else {
|
||||||
|
tcg_debug_assert(dest != arg2);
|
||||||
|
tcg_out_cmov(s, TCG_COND_LTU, rexw, dest, arg2);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* ??? The manual says that the output is undefined when the
|
tcg_debug_assert(dest != arg2);
|
||||||
input is zero, but real hardware leaves it unchanged. As
|
|
||||||
noted in target-i386/translate.c, real programs depend on
|
|
||||||
this -- now we are one more of those. */
|
|
||||||
tcg_debug_assert(dest == arg2);
|
|
||||||
tcg_out_modrm(s, OPC_BSF + rexw, dest, arg1);
|
tcg_out_modrm(s, OPC_BSF + rexw, dest, arg1);
|
||||||
|
tcg_out_cmov(s, TCG_COND_EQ, rexw, dest, arg2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1166,26 +1167,20 @@ static void tcg_out_clz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
|
||||||
tcg_debug_assert(arg2 == (rexw ? 64 : 32));
|
tcg_debug_assert(arg2 == (rexw ? 64 : 32));
|
||||||
} else {
|
} else {
|
||||||
tcg_debug_assert(dest != arg2);
|
tcg_debug_assert(dest != arg2);
|
||||||
/* LZCNT sets C if the input was zero. */
|
|
||||||
tcg_out_cmov(s, TCG_COND_LTU, rexw, dest, arg2);
|
tcg_out_cmov(s, TCG_COND_LTU, rexw, dest, arg2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TCGType type = rexw ? TCG_TYPE_I64: TCG_TYPE_I32;
|
tcg_debug_assert(!const_a2);
|
||||||
TCGArg rev = rexw ? 63 : 31;
|
tcg_debug_assert(dest != arg1);
|
||||||
|
tcg_debug_assert(dest != arg2);
|
||||||
|
|
||||||
/* Recall that the output of BSR is the index not the count.
|
/* Recall that the output of BSR is the index not the count. */
|
||||||
Therefore we must adjust the result by ^ (SIZE-1). In some
|
|
||||||
cases below, we prefer an extra XOR to a JMP. */
|
|
||||||
/* ??? See the comment in tcg_out_ctz re BSF. */
|
|
||||||
if (const_a2) {
|
|
||||||
tcg_debug_assert(dest != arg1);
|
|
||||||
tcg_out_movi(s, type, dest, arg2 ^ rev);
|
|
||||||
} else {
|
|
||||||
tcg_debug_assert(dest == arg2);
|
|
||||||
tgen_arithi(s, ARITH_XOR + rexw, dest, rev, 0);
|
|
||||||
}
|
|
||||||
tcg_out_modrm(s, OPC_BSR + rexw, dest, arg1);
|
tcg_out_modrm(s, OPC_BSR + rexw, dest, arg1);
|
||||||
tgen_arithi(s, ARITH_XOR + rexw, dest, rev, 0);
|
tgen_arithi(s, ARITH_XOR + rexw, dest, rexw ? 63 : 31, 0);
|
||||||
|
|
||||||
|
/* Since we have destroyed the flags from BSR, we have to re-test. */
|
||||||
|
tcg_out_cmp(s, arg1, 0, 1, rexw);
|
||||||
|
tcg_out_cmov(s, TCG_COND_EQ, rexw, dest, arg2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2459,7 +2454,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
|
||||||
case INDEX_op_ctz_i64:
|
case INDEX_op_ctz_i64:
|
||||||
{
|
{
|
||||||
static const TCGTargetOpDef ctz[2] = {
|
static const TCGTargetOpDef ctz[2] = {
|
||||||
{ .args_ct_str = { "r", "r", "0" } },
|
{ .args_ct_str = { "&r", "r", "r" } },
|
||||||
{ .args_ct_str = { "&r", "r", "rW" } },
|
{ .args_ct_str = { "&r", "r", "rW" } },
|
||||||
};
|
};
|
||||||
return &ctz[have_bmi1];
|
return &ctz[have_bmi1];
|
||||||
|
@ -2468,7 +2463,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
|
||||||
case INDEX_op_clz_i64:
|
case INDEX_op_clz_i64:
|
||||||
{
|
{
|
||||||
static const TCGTargetOpDef clz[2] = {
|
static const TCGTargetOpDef clz[2] = {
|
||||||
{ .args_ct_str = { "&r", "r", "0i" } },
|
{ .args_ct_str = { "&r", "r", "r" } },
|
||||||
{ .args_ct_str = { "&r", "r", "rW" } },
|
{ .args_ct_str = { "&r", "r", "rW" } },
|
||||||
};
|
};
|
||||||
return &clz[have_lzcnt];
|
return &clz[have_lzcnt];
|
||||||
|
|
Loading…
Reference in New Issue