qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 20/37] target/i386: reimplement 0x0f 0x60-0x6f, add AVX


From: Richard Henderson
Subject: Re: [PATCH 20/37] target/i386: reimplement 0x0f 0x60-0x6f, add AVX
Date: Mon, 12 Sep 2022 12:41:35 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.11.0

On 9/12/22 00:04, Paolo Bonzini wrote:
+/*
+ * 00 = p*  Pq, Qq (if mmx not NULL; no VEX)
+ * 66 = vp* Vx, Hx, Wx
+ *
+ * These are really the same encoding, because 1) V is the same as P when VEX.V
+ * is not present 2) P and Q are the same as H and W apart from MM/XMM
+ */
+static inline void gen_binary_int_sse(DisasContext *s, CPUX86State *env, 
X86DecodedInsn *decode,
+                                      SSEFunc_0_eppp mmx, SSEFunc_0_eppp xmm, 
SSEFunc_0_eppp ymm)

No need to inline.

+{
+    assert (!!mmx == !!(decode->e.special == X86_SPECIAL_MMX));
+
+    if (mmx && (s->prefix & PREFIX_VEX) && !(s->prefix & PREFIX_DATA)) {
+        /* VEX encoding is not applicable to MMX instructions.  */
+        gen_illegal_opcode(s);
+        return;
+    }
+    if (!(s->prefix & PREFIX_DATA)) {
+        mmx(cpu_env, s->ptr0, s->ptr1, s->ptr2);
+    } else if (!s->vex_l) {
+        xmm(cpu_env, s->ptr0, s->ptr1, s->ptr2);
+    } else {
+        ymm(cpu_env, s->ptr0, s->ptr1, s->ptr2);
+    }

And a reminder from earlier patches that generating the pointers here would be better, as well as zeroing the high ymm bits for vex xmm insns.

+static void gen_MOVD_to(DisasContext *s, CPUX86State *env, X86DecodedInsn 
*decode)
+{
+    MemOp ot = decode->op[2].ot;
+    int vec_len = sse_vec_len(s, decode);
+    int lo_ofs = decode->op[0].offset
+        - xmm_offset(decode->op[0].ot)
+        + xmm_offset(ot);
+
+    tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
+
+    switch (ot) {
+    case MO_32:
+#ifdef TARGET_X86_64
+        tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
+        tcg_gen_st_i32(s->tmp3_i32, cpu_env, lo_ofs);
+        break;

Use tcg_gen_st32_tl and omit the trunc.
Alternately, zero extend in T1 and fall through...

+    case MO_64:
+#endif
+        tcg_gen_st_tl(s->T1, cpu_env, lo_ofs);

This could also be

    tcg_gen_gvec_dup_i64(MO_64, offset, 8, sse_vec_max_len, s->T1);

to do the store and clear in one call.



r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]