qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: paul@nowt.org, richard.henderson@linaro.org
Subject: [PATCH 25/35] target/i386: Use tcg gvec ops for pmovmskb
Date: Thu, 13 Oct 2022 23:46:41 +0200	[thread overview]
Message-ID: <20221013214651.672114-26-pbonzini@redhat.com> (raw)
In-Reply-To: <20221013214651.672114-1-pbonzini@redhat.com>

From: Richard Henderson <richard.henderson@linaro.org>

As pmovmskb is used by strlen et al, this is the third
highest overhead sse operation at %0.8.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
[Reorganize to generate code for any vector size. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/tcg/emit.c.inc | 88 +++++++++++++++++++++++++++++++++++---
 1 file changed, 83 insertions(+), 5 deletions(-)

diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index 062c92e45a..ad93094ca8 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -1191,14 +1191,92 @@ static void gen_PINSR(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
     gen_pinsr(s, env, decode, decode->op[2].ot);
 }
 
+static void gen_pmovmskb_i64(TCGv_i64 d, TCGv_i64 s)
+{
+    TCGv_i64 t = tcg_temp_new_i64();
+
+    tcg_gen_andi_i64(d, s, 0x8080808080808080ull);
+
+    /*
+     * After each shift+or pair:
+     * 0:  a.......b.......c.......d.......e.......f.......g.......h.......
+     * 7:  ab......bc......cd......de......ef......fg......gh......h.......
+     * 14: abcd....bcde....cdef....defg....efgh....fgh.....gh......h.......
+     * 28: abcdefghbcdefgh.cdefgh..defgh...efgh....fgh.....gh......h.......
+     * The result is left in the high bits of the word.
+     */
+    tcg_gen_shli_i64(t, d, 7);
+    tcg_gen_or_i64(d, d, t);
+    tcg_gen_shli_i64(t, d, 14);
+    tcg_gen_or_i64(d, d, t);
+    tcg_gen_shli_i64(t, d, 28);
+    tcg_gen_or_i64(d, d, t);
+}
+
+static void gen_pmovmskb_vec(unsigned vece, TCGv_vec d, TCGv_vec s)
+{
+    TCGv_vec t = tcg_temp_new_vec_matching(d);
+    TCGv_vec m = tcg_constant_vec_matching(d, MO_8, 0x80);
+
+    /* See above */
+    tcg_gen_and_vec(vece, d, s, m);
+    tcg_gen_shli_vec(vece, t, d, 7);
+    tcg_gen_or_vec(vece, d, d, t);
+    tcg_gen_shli_vec(vece, t, d, 14);
+    tcg_gen_or_vec(vece, d, d, t);
+    tcg_gen_shli_vec(vece, t, d, 28);
+    tcg_gen_or_vec(vece, d, d, t);
+}
+
+#ifdef TARGET_X86_64
+#define TCG_TARGET_HAS_extract2_tl TCG_TARGET_HAS_extract2_i64
+#else
+#define TCG_TARGET_HAS_extract2_tl TCG_TARGET_HAS_extract2_i32
+#endif
+
 static void gen_PMOVMSKB(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
 {
-    if (s->prefix & PREFIX_DATA) {
-        gen_helper_pmovmskb_xmm(s->tmp2_i32, cpu_env, OP_PTR2);
-    } else {
-        gen_helper_pmovmskb_mmx(s->tmp2_i32, cpu_env, OP_PTR2);
+    static const TCGOpcode vecop_list[] = { INDEX_op_shli_vec, 0 };
+    static const GVecGen2 g = {
+        .fni8 = gen_pmovmskb_i64,
+        .fniv = gen_pmovmskb_vec,
+        .opt_opc = vecop_list,
+        .vece = MO_64,
+        .prefer_i64 = TCG_TARGET_REG_BITS == 64
+    };
+    MemOp ot = decode->op[2].ot;
+    int vec_len = vector_len(s, decode);
+    TCGv t = tcg_temp_new();
+
+    tcg_gen_gvec_2(offsetof(CPUX86State, xmm_t0) + xmm_offset(ot), decode->op[2].offset,
+                   vec_len, vec_len, &g);
+    tcg_gen_ld8u_tl(s->T0, cpu_env, offsetof(CPUX86State, xmm_t0.ZMM_B(vec_len - 1)));
+    while (vec_len > 8) {
+        vec_len -= 8;
+        if (TCG_TARGET_HAS_extract2_tl) {
+            /*
+             * Load the next byte of the result into the high byte of T.
+             * TCG does a similar expansion of deposit to shl+extract2; by
+             * loading the whole word, the shift left is avoided.
+             */
+#ifdef TARGET_X86_64
+            tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, xmm_t0.ZMM_Q((vec_len - 1) / 8)));
+#else
+            tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, xmm_t0.ZMM_L((vec_len - 1) / 4)));
+#endif
+
+            tcg_gen_extract2_tl(s->T0, t, s->T0, TARGET_LONG_BITS - 8);
+        } else {
+            /*
+             * The _previous_ value is deposited into bits 8 and higher of t.  Because
+             * those bits are known to be zero after ld8u, this becomes a shift+or
+             * if deposit is not available.
+             */
+            tcg_gen_ld8u_tl(t, cpu_env, offsetof(CPUX86State, xmm_t0.ZMM_B(vec_len - 1)));
+            tcg_gen_deposit_tl(s->T0, t, s->T0, 8, TARGET_LONG_BITS - 8);
+        }
     }
-    tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
+    tcg_temp_free(t);
 }
 
 static void gen_PSHUFW(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
-- 
2.37.3



  parent reply	other threads:[~2022-10-13 22:12 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-13 21:46 [PATCH v3 00/35] target/i386: new decoder + AVX implementation Paolo Bonzini
2022-10-13 21:46 ` [PATCH 01/35] target/i386: Define XMMReg and access macros, align ZMM registers Paolo Bonzini
2022-10-13 21:46 ` [PATCH 02/35] target/i386: make ldo/sto operations consistent with ldq Paolo Bonzini
2022-10-13 21:46 ` [PATCH 03/35] target/i386: add core of new i386 decoder Paolo Bonzini
2022-10-13 21:46 ` [PATCH 04/35] target/i386: add ALU load/writeback core Paolo Bonzini
2022-10-13 21:46 ` [PATCH 05/35] target/i386: add CPUID[EAX=7, ECX=0].ECX to DisasContext Paolo Bonzini
2022-10-13 21:46 ` [PATCH 06/35] target/i386: add CPUID feature checks to new decoder Paolo Bonzini
2022-10-13 21:46 ` [PATCH 07/35] target/i386: add AVX_EN hflag Paolo Bonzini
2022-10-13 21:46 ` [PATCH 08/35] target/i386: validate VEX prefixes via the instructions' exception classes Paolo Bonzini
2022-10-13 21:46 ` [PATCH 09/35] target/i386: validate SSE prefixes directly in the decoding table Paolo Bonzini
2022-10-13 21:46 ` [PATCH 10/35] target/i386: move scalar 0F 38 and 0F 3A instruction to new decoder Paolo Bonzini
2022-10-13 21:46 ` [PATCH 11/35] target/i386: Prepare ops_sse_header.h for 256 bit AVX Paolo Bonzini
2022-10-13 21:46 ` [PATCH 12/35] target/i386: extend helpers to support VEX.V 3- and 4- operand encodings Paolo Bonzini
2022-10-13 21:46 ` [PATCH 13/35] target/i386: support operand merging in binary scalar helpers Paolo Bonzini
2022-10-13 21:46 ` [PATCH 14/35] target/i386: provide 3-operand versions of unary " Paolo Bonzini
2022-10-13 21:46 ` [PATCH 15/35] target/i386: implement additional AVX comparison operators Paolo Bonzini
2022-10-13 21:46 ` [PATCH 16/35] target/i386: Introduce 256-bit vector helpers Paolo Bonzini
2022-10-13 21:46 ` [PATCH 17/35] target/i386: reimplement 0x0f 0x60-0x6f, add AVX Paolo Bonzini
2022-10-13 21:46 ` [PATCH 18/35] target/i386: reimplement 0x0f 0xd8-0xdf, 0xe8-0xef, 0xf8-0xff, " Paolo Bonzini
2022-10-13 21:46 ` [PATCH 19/35] target/i386: reimplement 0x0f 0x50-0x5f, " Paolo Bonzini
2022-10-13 21:46 ` [PATCH 20/35] target/i386: reimplement 0x0f 0x78-0x7f, " Paolo Bonzini
2022-10-13 21:46 ` [PATCH 21/35] target/i386: reimplement 0x0f 0x70-0x77, " Paolo Bonzini
2022-10-13 21:46 ` [PATCH 22/35] target/i386: reimplement 0x0f 0xd0-0xd7, 0xe0-0xe7, 0xf0-0xf7, " Paolo Bonzini
2022-10-13 21:46 ` [PATCH 23/35] target/i386: clarify (un)signedness of immediates from 0F3Ah opcodes Paolo Bonzini
2022-10-13 21:46 ` [PATCH 24/35] target/i386: reimplement 0x0f 0x3a, add AVX Paolo Bonzini
2022-10-13 21:46 ` Paolo Bonzini [this message]
2022-10-13 21:46 ` [PATCH 26/35] target/i386: reimplement 0x0f 0x38, " Paolo Bonzini
2022-10-13 21:46 ` [PATCH 27/35] target/i386: reimplement 0x0f 0xc2, 0xc4-0xc6, " Paolo Bonzini
2022-10-13 21:46 ` [PATCH 28/35] target/i386: reimplement 0x0f 0x10-0x17, " Paolo Bonzini
2022-10-13 21:46 ` [PATCH 29/35] target/i386: reimplement 0x0f 0x28-0x2f, " Paolo Bonzini
2022-10-13 21:46 ` [PATCH 30/35] target/i386: implement XSAVE and XRSTOR of AVX registers Paolo Bonzini
2022-10-13 21:46 ` [PATCH 31/35] target/i386: implement VLDMXCSR/VSTMXCSR Paolo Bonzini
2022-10-13 21:46 ` [PATCH 32/35] target/i386: Enable AVX cpuid bits when using TCG Paolo Bonzini
2022-10-13 21:46 ` [PATCH 33/35] tests/tcg: extend SSE tests to AVX Paolo Bonzini
2022-10-13 21:46 ` [PATCH 34/35] target/i386: move 3DNow to the new decoder Paolo Bonzini
2022-10-13 21:46 ` [PATCH 35/35] target/i386: remove old SSE decoder Paolo Bonzini

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=20221013214651.672114-26-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=paul@nowt.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.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).