summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSoren Sandmann Pedersen <ssp@dhcp83-218.boston.redhat.com>2007-04-25 13:21:47 -0400
committerSoren Sandmann Pedersen <ssp@dhcp83-218.boston.redhat.com>2007-04-25 22:22:22 -0400
commitc056ce95d89ef1df57edf47149fc34cd3925496e (patch)
tree9c773e8cffc964ae37d29230f5425bb59146424e
parentc19ece1d8c32dc81740a4036a642661f54064e75 (diff)
Port MSVC++ CPU detection code from pixman. (Vladimir Vukicevic).
-rw-r--r--fb/fbpict.c70
1 files changed, 64 insertions, 6 deletions
diff --git a/fb/fbpict.c b/fb/fbpict.c
index b4cddd767..f9f536863 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -1509,7 +1509,6 @@ fbComposite (CARD8 op,
pMask->pDrawable->width == 1 &&
pMask->pDrawable->height == 1)
maskTransform = FALSE;
-
}
if (pSrc->pDrawable && (!pMask || pMask->pDrawable)
@@ -2116,7 +2115,7 @@ enum CPUFeatures {
static unsigned int detectCPUFeatures(void) {
unsigned int features = 0;
- unsigned int result;
+ unsigned int result = 0;
#ifdef HAVE_GETISAX
if (getisax(&result, 1)) {
@@ -2133,8 +2132,13 @@ static unsigned int detectCPUFeatures(void) {
}
#else
char vendor[13];
+#ifdef _MSC_VER
+ int vendor0 = 0, vendor1, vendor2;
+#endif
vendor[0] = 0;
vendor[12] = 0;
+
+#ifdef __GNUC__
/* see p. 118 of amd64 instruction set manual Vol3 */
/* We need to be careful about the handling of %ebx and
* %esp here. We can't declare either one as clobbered
@@ -2153,7 +2157,7 @@ static unsigned int detectCPUFeatures(void) {
"pop %%eax\n"
"mov $0x0, %%edx\n"
"xor %%ecx, %%eax\n"
- "jz 1\n"
+ "jz 1f\n"
"mov $0x00000000, %%eax\n"
"push %%ebx\n"
@@ -2177,6 +2181,45 @@ static unsigned int detectCPUFeatures(void) {
: "%eax", "%ecx", "%edx"
);
+#elif defined (_MSC_VER)
+
+ _asm {
+ pushfd
+ pop eax
+ mov ecx, eax
+ xor eax, 00200000h
+ push eax
+ popfd
+ pushfd
+ pop eax
+ mov edx, 0
+ xor eax, ecx
+ jz nocpuid
+
+ mov eax, 0
+ push ebx
+ cpuid
+ mov eax, ebx
+ pop ebx
+ mov vendor0, eax
+ mov vendor1, edx
+ mov vendor2, ecx
+ mov eax, 1
+ push ebx
+ cpuid
+ pop ebx
+ nocpuid:
+ mov result, edx
+ }
+ memmove (vendor+0, &vendor0, 4);
+ memmove (vendor+4, &vendor1, 4);
+ memmove (vendor+8, &vendor2, 4);
+
+#else
+# error unsupported compiler
+#endif
+
+ features = 0;
if (result) {
/* result now contains the standard feature bits */
if (result & (1 << 15))
@@ -2191,14 +2234,13 @@ static unsigned int detectCPUFeatures(void) {
(strcmp(vendor, "AuthenticAMD") == 0 ||
strcmp(vendor, "Geode by NSC") == 0)) {
/* check for AMD MMX extensions */
-
- unsigned int result;
+#ifdef __GNUC__
__asm__("push %%ebx\n"
"mov $0x80000000, %%eax\n"
"cpuid\n"
"xor %%edx, %%edx\n"
"cmp $0x1, %%eax\n"
- "jge 2\n"
+ "jge 2f\n"
"mov $0x80000001, %%eax\n"
"cpuid\n"
"2:\n"
@@ -2208,11 +2250,27 @@ static unsigned int detectCPUFeatures(void) {
:
: "%eax", "%ecx", "%edx"
);
+#elif defined _MSC_VER
+ _asm {
+ push ebx
+ mov eax, 80000000h
+ cpuid
+ xor edx, edx
+ cmp eax, 1
+ jge notamd
+ mov eax, 80000001h
+ cpuid
+ notamd:
+ pop ebx
+ mov result, edx
+ }
+#endif
if (result & (1<<22))
features |= MMX_Extensions;
}
}
#endif /* HAVE_GETISAX */
+
return features;
}