diff options
author | Soren Sandmann Pedersen <ssp@dhcp83-218.boston.redhat.com> | 2007-04-25 13:21:47 -0400 |
---|---|---|
committer | Soren Sandmann Pedersen <ssp@dhcp83-218.boston.redhat.com> | 2007-04-25 22:22:22 -0400 |
commit | c056ce95d89ef1df57edf47149fc34cd3925496e (patch) | |
tree | 9c773e8cffc964ae37d29230f5425bb59146424e /fb | |
parent | c19ece1d8c32dc81740a4036a642661f54064e75 (diff) |
Port MSVC++ CPU detection code from pixman. (Vladimir Vukicevic).
Diffstat (limited to 'fb')
-rw-r--r-- | fb/fbpict.c | 70 |
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; } |