]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Support mmxext (integer sse) subset on i386 (athlon). Bug #323713
authorMark Wielaard <mark@klomp.org>
Tue, 27 Aug 2013 10:23:23 +0000 (10:23 +0000)
committerMark Wielaard <mark@klomp.org>
Tue, 27 Aug 2013 10:23:23 +0000 (10:23 +0000)
Some processors like the AMD Athlon "Classic" support mmxext,
a sse1 subset. This subset is not properly detected by VEX.
The subset uses the same encoding as the sse1 instructions.

The subset is described at:
  http://support.amd.com/us/Embedded_TechDocs/22466.pdf
  https://en.wikipedia.org/wiki/3DNow!#3DNow.21_extensions

Detects mmxext subset from cpuid information (and enables it
when full sse1 is found). Also fixes the prereq of
none/tests/x86/insn_mmxext.vgtest so that it also runs when
full sse1 (and not just the mmxext subset) is found.
It already passed on such configurations. With the VEX patch
(r2745) it also passes with just the mmxext subset.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13515

coregrind/m_machine.c
none/tests/x86/insn_mmxext.vgtest

index 353c05b1bd91b0a4c5844b32a94e45cf581c0a91..2fd5f07ffb3062dd62ce3a3471cd7a657a4ce536 100644 (file)
@@ -701,7 +701,7 @@ Bool VG_(machine_get_hwcaps)( void )
    LibVEX_default_VexArchInfo(&vai);
 
 #if defined(VGA_x86)
-   { Bool have_sse1, have_sse2, have_cx8, have_lzcnt;
+   { Bool have_sse1, have_sse2, have_cx8, have_lzcnt, have_mmxext;
      UInt eax, ebx, ecx, edx, max_extended;
      HChar vstr[13];
      vstr[0] = 0;
@@ -738,24 +738,38 @@ Bool VG_(machine_get_hwcaps)( void )
      if (!have_cx8)
         return False;
 
-     /* Figure out if this is an AMD that can do LZCNT. */
+     /* Figure out if this is an AMD that can do mmxext and/or LZCNT. */
+     have_mmxext = False;
      have_lzcnt = False;
      if (0 == VG_(strcmp)(vstr, "AuthenticAMD")
          && max_extended >= 0x80000001) {
         VG_(cpuid)(0x80000001, 0, &eax, &ebx, &ecx, &edx);
         have_lzcnt = (ecx & (1<<5)) != 0; /* True => have LZCNT */
+
+        /* Some older AMD processors support a sse1 subset (Integer SSE). */
+        have_mmxext = !have_sse1 && ((edx & (1<<22)) != 0);
      }
 
+     /* Intel processors don't define the mmxext extension, but since it
+        is just a sse1 subset always define it when we have sse1. */
+     if (have_sse1)
+        have_mmxext = True;
+
      va = VexArchX86;
-     if (have_sse2 && have_sse1) {
-        vai.hwcaps  = VEX_HWCAPS_X86_SSE1;
+     if (have_sse2 && have_sse1 && have_mmxext) {
+        vai.hwcaps  = VEX_HWCAPS_X86_MMXEXT;
+        vai.hwcaps |= VEX_HWCAPS_X86_SSE1;
         vai.hwcaps |= VEX_HWCAPS_X86_SSE2;
         if (have_lzcnt)
            vai.hwcaps |= VEX_HWCAPS_X86_LZCNT;
         VG_(machine_x86_have_mxcsr) = 1;
-     } else if (have_sse1) {
-        vai.hwcaps  = VEX_HWCAPS_X86_SSE1;
+     } else if (have_sse1 && have_mmxext) {
+        vai.hwcaps  = VEX_HWCAPS_X86_MMXEXT;
+        vai.hwcaps |= VEX_HWCAPS_X86_SSE1;
         VG_(machine_x86_have_mxcsr) = 1;
+     } else if (have_mmxext) {
+        vai.hwcaps  = VEX_HWCAPS_X86_MMXEXT; /*integer only sse1 subset*/
+        VG_(machine_x86_have_mxcsr) = 0;
      } else {
        vai.hwcaps = 0; /*baseline - no sse at all*/
        VG_(machine_x86_have_mxcsr) = 0;
index ad48b6e7142c6ef35103d0184e7619a8420789b1..e3627d623bcc092e9719804c0206bd6ecfecd267 100644 (file)
@@ -1,3 +1,4 @@
 prog: ../../../none/tests/x86/insn_mmxext
-prereq: ../../../tests/x86_amd64_features x86-mmxext
+# mmxext is an old AMD subset of sse1, so either will do.
+prereq: ../../../tests/x86_amd64_features x86-mmxext || ../../../tests/x86_amd64_features x86-sse
 vgopts: -q