diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2017-01-19 13:36:21 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2017-01-19 13:36:21 +0000 |
| commit | 5e59fb10ce5ef4cb3431ffead9cf1dd48080a641 (patch) | |
| tree | 3913c59a425ce5282ad7ec15b92858eacdc5bc30 | |
| parent | ab4b92760498e097ff668f0e9c83aa87a2ec1128 (diff) | |
| parent | 39f099ec9d6d420b6fe6f7f4f8ed80ae29c65ff2 (diff) | |
| download | focaccia-qemu-5e59fb10ce5ef4cb3431ffead9cf1dd48080a641.tar.gz focaccia-qemu-5e59fb10ce5ef4cb3431ffead9cf1dd48080a641.zip | |
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>
| -rw-r--r-- | tcg/i386/tcg-target.inc.c | 45 |
1 files changed, 20 insertions, 25 deletions
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c index 01177a916d..5918008296 100644 --- a/tcg/i386/tcg-target.inc.c +++ b/tcg/i386/tcg-target.inc.c @@ -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, TCGArg arg2, bool const_a2) { - if (const_a2) { - tcg_debug_assert(have_bmi1); - tcg_debug_assert(arg2 == (rexw ? 64 : 32)); + if (have_bmi1) { 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 { - /* ??? The manual says that the output is undefined when the - 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_debug_assert(dest != arg2); 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)); } else { tcg_debug_assert(dest != arg2); - /* LZCNT sets C if the input was zero. */ tcg_out_cmov(s, TCG_COND_LTU, rexw, dest, arg2); } } else { - TCGType type = rexw ? TCG_TYPE_I64: TCG_TYPE_I32; - TCGArg rev = rexw ? 63 : 31; + tcg_debug_assert(!const_a2); + tcg_debug_assert(dest != arg1); + tcg_debug_assert(dest != arg2); - /* 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); - } + /* Recall that the output of BSR is the index not the count. */ 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: { static const TCGTargetOpDef ctz[2] = { - { .args_ct_str = { "r", "r", "0" } }, + { .args_ct_str = { "&r", "r", "r" } }, { .args_ct_str = { "&r", "r", "rW" } }, }; return &ctz[have_bmi1]; @@ -2468,7 +2463,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) case INDEX_op_clz_i64: { static const TCGTargetOpDef clz[2] = { - { .args_ct_str = { "&r", "r", "0i" } }, + { .args_ct_str = { "&r", "r", "r" } }, { .args_ct_str = { "&r", "r", "rW" } }, }; return &clz[have_lzcnt]; |