qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org
Subject: [Qemu-devel] [PULL 1/2] Revert "tcg/i386: Rely on undefined/undocumented behaviour of BSF/BSR"
Date: Tue, 17 Jan 2017 15:03:31 -0800	[thread overview]
Message-ID: <20170117230332.16279-2-rth@twiddle.net> (raw)
In-Reply-To: <20170117230332.16279-1-rth@twiddle.net>

This reverts commit 4ac76910734209dab83ddd3795f08fc7889ef463.

This fixes
  http://lists.nongnu.org/archive/html/qemu-devel/2017-01/msg03062.html

While I think we could get away with relying on the undocumented
behaviour, the tcg constraint system isn't powerful enough to
properly describe the required (non-)overlap conditions.

Reported-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/i386/tcg-target.inc.c | 35 +++++++++++++----------------------
 1 file changed, 13 insertions(+), 22 deletions(-)

diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 01177a9..6489b73 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -1148,12 +1148,9 @@ static void tcg_out_ctz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
         tcg_debug_assert(arg2 == (rexw ? 64 : 32));
         tcg_out_modrm(s, OPC_TZCNT + rexw, dest, arg1);
     } 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 +1163,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 +2450,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 +2459,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];
-- 
2.9.3

  reply	other threads:[~2017-01-17 23:03 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-17 23:03 [Qemu-devel] [PULL 0/2] Fixes for x86 host Richard Henderson
2017-01-17 23:03 ` Richard Henderson [this message]
2017-01-17 23:03 ` [Qemu-devel] [PULL 2/2] tcg/i386: Always use TZCNT when available Richard Henderson
2017-01-19 17:44 ` [Qemu-devel] [PULL 0/2] Fixes for x86 host Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170117230332.16279-2-rth@twiddle.net \
    --to=rth@twiddle.net \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).