From: Mark Wielaard Date: Tue, 27 Aug 2013 10:23:23 +0000 (+0000) Subject: Support mmxext (integer sse) subset on i386 (athlon). Bug #323713 X-Git-Tag: svn/VALGRIND_3_9_0~176 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=acbf92d9755eee21ba62f62e55f8a1509d476de4;p=thirdparty%2Fvalgrind.git Support mmxext (integer sse) subset on i386 (athlon). Bug #323713 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 --- diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c index 353c05b1bd..2fd5f07ffb 100644 --- a/coregrind/m_machine.c +++ b/coregrind/m_machine.c @@ -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; diff --git a/none/tests/x86/insn_mmxext.vgtest b/none/tests/x86/insn_mmxext.vgtest index ad48b6e714..e3627d623b 100644 --- a/none/tests/x86/insn_mmxext.vgtest +++ b/none/tests/x86/insn_mmxext.vgtest @@ -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