/* This isn't entirely correct, CPUID should depend on the VEX
capabilities, not on the underlying CPU. See bug #324882. */
- if ((archinfo->hwcaps & VEX_HWCAPS_AMD64_SSE3) &&
+ if ((archinfo->hwcaps & VEX_HWCAPS_AMD64_SSSE3) &&
(archinfo->hwcaps & VEX_HWCAPS_AMD64_CX16) &&
(archinfo->hwcaps & VEX_HWCAPS_AMD64_AVX2)) {
fName = "amd64g_dirtyhelper_CPUID_avx2";
fAddr = &amd64g_dirtyhelper_CPUID_avx2;
/* This is a Core-i7-4910-like machine */
}
- else if ((archinfo->hwcaps & VEX_HWCAPS_AMD64_SSE3) &&
+ else if ((archinfo->hwcaps & VEX_HWCAPS_AMD64_SSSE3) &&
(archinfo->hwcaps & VEX_HWCAPS_AMD64_CX16) &&
(archinfo->hwcaps & VEX_HWCAPS_AMD64_AVX)) {
fName = "amd64g_dirtyhelper_CPUID_avx_and_cx16";
fAddr = &amd64g_dirtyhelper_CPUID_avx_and_cx16;
/* This is a Core-i5-2300-like machine */
}
- else if ((archinfo->hwcaps & VEX_HWCAPS_AMD64_SSE3) &&
+ else if ((archinfo->hwcaps & VEX_HWCAPS_AMD64_SSSE3) &&
(archinfo->hwcaps & VEX_HWCAPS_AMD64_CX16)) {
fName = "amd64g_dirtyhelper_CPUID_sse42_and_cx16";
fAddr = &amd64g_dirtyhelper_CPUID_sse42_and_cx16;
vassert(arch_host == VexArchAMD64);
vassert(0 == (hwcaps_host
& ~(VEX_HWCAPS_AMD64_SSE3
+ | VEX_HWCAPS_AMD64_SSSE3
| VEX_HWCAPS_AMD64_CX16
| VEX_HWCAPS_AMD64_LZCNT
| VEX_HWCAPS_AMD64_AVX
{ VEX_HWCAPS_AMD64_LZCNT, "lzcnt" },
{ VEX_HWCAPS_AMD64_RDTSCP, "rdtscp" },
{ VEX_HWCAPS_AMD64_SSE3, "sse3" },
+ { VEX_HWCAPS_AMD64_SSSE3, "ssse3" },
{ VEX_HWCAPS_AMD64_AVX, "avx" },
{ VEX_HWCAPS_AMD64_AVX2, "avx2" },
{ VEX_HWCAPS_AMD64_BMI, "bmi" },
orthogonal. */
/* Throw out obviously stupid cases: */
- Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
- Bool have_avx = (hwcaps & VEX_HWCAPS_AMD64_AVX) != 0;
- Bool have_bmi = (hwcaps & VEX_HWCAPS_AMD64_BMI) != 0;
- Bool have_avx2 = (hwcaps & VEX_HWCAPS_AMD64_AVX2) != 0;
-
- /* AVX without SSE3 */
- if (have_avx && !have_sse3)
+ Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
+ Bool have_ssse3 = (hwcaps & VEX_HWCAPS_AMD64_SSSE3) != 0;
+ Bool have_avx = (hwcaps & VEX_HWCAPS_AMD64_AVX) != 0;
+ Bool have_bmi = (hwcaps & VEX_HWCAPS_AMD64_BMI) != 0;
+ Bool have_avx2 = (hwcaps & VEX_HWCAPS_AMD64_AVX2) != 0;
+
+ /* SSSE3 without SSE3 */
+ if (have_ssse3 && !have_sse3)
+ invalid_hwcaps(arch, hwcaps,
+ "Support for SSSE3 requires SSE3 capabilities\n");
+ /* AVX without SSSE3 */
+ if (have_avx && !have_ssse3)
invalid_hwcaps(arch, hwcaps,
- "Support for AVX requires SSE3 capabilities\n");
+ "Support for AVX requires SSSE3 capabilities\n");
/* AVX2 or BMI without AVX */
if (have_avx2 && !have_avx)
invalid_hwcaps(arch, hwcaps,
/* amd64: baseline capability is SSE2, with cmpxchg8b but not
cmpxchg16b. */
#define VEX_HWCAPS_AMD64_SSE3 (1<<5) /* SSE3 support */
+#define VEX_HWCAPS_AMD64_SSSE3 (1<<12) /* Supplemental SSE3 support */
#define VEX_HWCAPS_AMD64_CX16 (1<<6) /* cmpxchg16b support */
#define VEX_HWCAPS_AMD64_LZCNT (1<<7) /* SSE4a LZCNT insn */
#define VEX_HWCAPS_AMD64_AVX (1<<8) /* AVX instructions */
}
#elif defined(VGA_amd64)
- { Bool have_sse3, have_cx8, have_cx16;
+ { Bool have_sse3, have_ssse3, have_cx8, have_cx16;
Bool have_lzcnt, have_avx, have_bmi, have_avx2;
Bool have_rdtscp;
UInt eax, ebx, ecx, edx, max_basic, max_extended;
HChar vstr[13];
vstr[0] = 0;
+ have_sse3 = have_ssse3 = have_cx8 = have_cx16
+ = have_lzcnt = have_avx = have_bmi = have_avx2
+ = have_rdtscp = False;
+
+ eax = ebx = ecx = edx = max_basic = max_extended = 0;
+
if (!VG_(has_cpuid)())
/* we can't do cpuid at all. Give up. */
return False;
VG_(cpuid)(1, 0, &eax, &ebx, &ecx, &edx);
// we assume that SSE1 and SSE2 are available by default
- have_sse3 = (ecx & (1<<0)) != 0; /* True => have sse3 insns */
- // ssse3 is ecx:9
+ have_sse3 = (ecx & (1<<0)) != 0; /* True => have sse3 insns */
+ have_ssse3 = (ecx & (1<<9)) != 0; /* True => have Sup SSE3 insns */
// sse41 is ecx:19
// sse42 is ecx:20
va = VexArchAMD64;
vai.endness = VexEndnessLE;
vai.hwcaps = (have_sse3 ? VEX_HWCAPS_AMD64_SSE3 : 0)
+ | (have_ssse3 ? VEX_HWCAPS_AMD64_SSSE3 : 0)
| (have_cx16 ? VEX_HWCAPS_AMD64_CX16 : 0)
| (have_lzcnt ? VEX_HWCAPS_AMD64_LZCNT : 0)
| (have_avx ? VEX_HWCAPS_AMD64_AVX : 0)