]> xenbits.xensource.com Git - xen.git/commitdiff
x86emul: extend MASKMOV{Q,DQU} tests
authorJan Beulich <jbeulich@suse.com>
Tue, 4 Sep 2018 09:29:22 +0000 (11:29 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 4 Sep 2018 09:29:22 +0000 (11:29 +0200)
While deriving the first AVX512 pieces from existing code I've got the
(in the end wrong) impression that the emulation of these insns would be
broken. Besides testing that the instructions act as no-ops when the
controlling mask bits are all zero, add ones to also check that the data
merging actually works.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
tools/tests/x86_emulator/test_x86_emulator.c

index ad9a5e72b78a041ec099532a9d0a5b0f6346418b..4458a6537b29bc04c34b00602b5cd97e14109e16 100644 (file)
@@ -2626,7 +2626,7 @@ int main(int argc, char **argv)
         printf("skipped\n");
 #endif
 
-    printf("%-40s", "Testing maskmovq (zero mask)...");
+    printf("%-40s", "Testing maskmovq %mm4,%mm4...");
     if ( stack_exec && cpu_has_sse )
     {
         decl_insn(maskmovq);
@@ -2639,12 +2639,25 @@ int main(int argc, char **argv)
         rc = x86_emulate(&ctxt, &emulops);
         if ( rc != X86EMUL_OKAY || !check_eip(maskmovq) )
             goto fail;
+
+        asm volatile ( "pcmpeqb %mm3, %mm3\n\t"
+                       "punpcklbw %mm3, %mm4\n" );
+        memset(res, 0x55, 24);
+
+        set_insn(maskmovq);
+        regs.edi = (unsigned long)(res + 2);
+        rc = x86_emulate(&ctxt, &emulops);
+        if ( rc != X86EMUL_OKAY || !check_eip(maskmovq) ||
+             memcmp(res, res + 4, 8) ||
+             res[2] != 0xff55ff55 || res[3] != 0xff55ff55 )
+            goto fail;
+
         printf("okay\n");
     }
     else
         printf("skipped\n");
 
-    printf("%-40s", "Testing maskmovdqu (zero mask)...");
+    printf("%-40s", "Testing maskmovdqu %xmm3,%xmm3...");
     if ( stack_exec && cpu_has_sse2 )
     {
         decl_insn(maskmovdqu);
@@ -2653,9 +2666,24 @@ int main(int argc, char **argv)
                        put_insn(maskmovdqu, "maskmovdqu %xmm3, %xmm3") );
 
         set_insn(maskmovdqu);
+        regs.edi = 0;
         rc = x86_emulate(&ctxt, &emulops);
         if ( rc != X86EMUL_OKAY || !check_eip(maskmovdqu) )
             goto fail;
+
+        asm volatile ( "pcmpeqb %xmm4, %xmm4\n\t"
+                       "punpcklbw %xmm4, %xmm3\n" );
+        memset(res, 0x55, 48);
+
+        set_insn(maskmovdqu);
+        regs.edi = (unsigned long)(res + 4);
+        rc = x86_emulate(&ctxt, &emulops);
+        if ( rc != X86EMUL_OKAY || !check_eip(maskmovdqu) ||
+             memcmp(res, res + 8, 16) ||
+             res[4] != 0xff55ff55 || res[5] != 0xff55ff55 ||
+             res[6] != 0xff55ff55 || res[7] != 0xff55ff55 )
+            goto fail;
+
         printf("okay\n");
     }
     else