|
From: <sv...@va...> - 2009-05-21 22:06:17
|
Author: sewardj
Date: 2009-05-21 23:06:09 +0100 (Thu, 21 May 2009)
New Revision: 10078
Log:
At startup, check processor capabilities a bit more carefully:
amd64:
- make cmpxchg8b support be a minimum requirement
- detect and note presence/absence of cmpxchg16b support
- detect and note presence/absence of SSE3 support
x86:
- make cmpxchg8b support be a minimum requirement
Modified:
branches/DCAS/coregrind/m_machine.c
Modified: branches/DCAS/coregrind/m_machine.c
===================================================================
--- branches/DCAS/coregrind/m_machine.c 2009-05-21 19:37:04 UTC (rev 10077)
+++ branches/DCAS/coregrind/m_machine.c 2009-05-21 22:06:09 UTC (rev 10078)
@@ -154,7 +154,7 @@
static void apply_to_GPs_of_tid(VexGuestArchState* vex, void (*f)(Addr))
{
-#if defined(VGA_x86)
+# if defined(VGA_x86)
(*f)(vex->guest_EAX);
(*f)(vex->guest_ECX);
(*f)(vex->guest_EDX);
@@ -163,7 +163,7 @@
(*f)(vex->guest_EDI);
(*f)(vex->guest_ESP);
(*f)(vex->guest_EBP);
-#elif defined(VGA_amd64)
+# elif defined(VGA_amd64)
(*f)(vex->guest_RAX);
(*f)(vex->guest_RCX);
(*f)(vex->guest_RDX);
@@ -180,7 +180,7 @@
(*f)(vex->guest_R13);
(*f)(vex->guest_R14);
(*f)(vex->guest_R15);
-#elif defined(VGA_ppc32) || defined(VGA_ppc64)
+# elif defined(VGA_ppc32) || defined(VGA_ppc64)
/* XXX ask tool about validity? */
(*f)(vex->guest_GPR0);
(*f)(vex->guest_GPR1);
@@ -217,9 +217,9 @@
(*f)(vex->guest_CTR);
(*f)(vex->guest_LR);
-#else
-# error Unknown arch
-#endif
+# else
+# error "Unknown arch"
+# endif
}
@@ -347,7 +347,7 @@
LibVEX_default_VexArchInfo(&vai);
#if defined(VGA_x86)
- { Bool have_sse1, have_sse2;
+ { Bool have_sse1, have_sse2, have_cx8;
UInt eax, ebx, ecx, edx;
if (!VG_(has_cpuid)())
@@ -365,6 +365,13 @@
have_sse1 = (edx & (1<<25)) != 0; /* True => have sse insns */
have_sse2 = (edx & (1<<26)) != 0; /* True => have sse2 insns */
+ /* cmpxchg8b is a minimum requirement now; if we don't have it we
+ must simply give up. But all CPUs since Pentium-I have it, so
+ that doesn't seem like much of a restriction. */
+ have_cx8 = (edx & (1<<8)) != 0; /* True => have cmpxchg8b */
+ if (!have_cx8)
+ return False;
+
if (have_sse2 && have_sse1) {
va = VexArchX86;
vai.hwcaps = VEX_HWCAPS_X86_SSE1;
@@ -387,11 +394,41 @@
}
#elif defined(VGA_amd64)
- vg_assert(VG_(has_cpuid)());
- va = VexArchAMD64;
- vai.hwcaps = 0; /*baseline - SSE2 */
- return True;
+ { Bool have_sse1, have_sse2, have_sse3, have_cx8, have_cx16;
+ UInt eax, ebx, ecx, edx;
+ if (!VG_(has_cpuid)())
+ /* we can't do cpuid at all. Give up. */
+ return False;
+
+ VG_(cpuid)(0, &eax, &ebx, &ecx, &edx);
+ if (eax < 1)
+ /* we can't ask for cpuid(x) for x > 0. Give up. */
+ return False;
+
+ /* get capabilities bits into edx */
+ VG_(cpuid)(1, &eax, &ebx, &ecx, &edx);
+
+ have_sse1 = (edx & (1<<25)) != 0; /* True => have sse insns */
+ have_sse2 = (edx & (1<<26)) != 0; /* True => have sse2 insns */
+ have_sse3 = (ecx & (1<<9)) != 0; /* True => have sse3 insns */
+
+ /* cmpxchg8b is a minimum requirement now; if we don't have it we
+ must simply give up. But all CPUs since Pentium-I have it, so
+ that doesn't seem like much of a restriction. */
+ have_cx8 = (edx & (1<<8)) != 0; /* True => have cmpxchg8b */
+ if (!have_cx8)
+ return False;
+
+ /* on amd64 we tolerate older cpus, which don't have cmpxchg16b */
+ have_cx16 = (ecx & (1<<13)) != 0; /* True => have cmpxchg16b */
+
+ va = VexArchAMD64;
+ vai.hwcaps = (have_sse3 ? VEX_HWCAPS_AMD64_SSE3 : 0)
+ | (have_cx16 ? VEX_HWCAPS_AMD64_CX16 : 0);
+ return True;
+ }
+
#elif defined(VGA_ppc32)
{
/* Find out which subset of the ppc32 instruction set is supported by
|