Port MSVC++ CPU detection code from pixman. (Vladimir Vukicevic).

This commit is contained in:
Soren Sandmann Pedersen 2007-04-25 13:21:47 -04:00
parent c19ece1d8c
commit c056ce95d8

View File

@ -1509,7 +1509,6 @@ fbComposite (CARD8 op,
pMask->pDrawable->width == 1 && pMask->pDrawable->width == 1 &&
pMask->pDrawable->height == 1) pMask->pDrawable->height == 1)
maskTransform = FALSE; maskTransform = FALSE;
} }
if (pSrc->pDrawable && (!pMask || pMask->pDrawable) if (pSrc->pDrawable && (!pMask || pMask->pDrawable)
@ -2116,7 +2115,7 @@ enum CPUFeatures {
static unsigned int detectCPUFeatures(void) { static unsigned int detectCPUFeatures(void) {
unsigned int features = 0; unsigned int features = 0;
unsigned int result; unsigned int result = 0;
#ifdef HAVE_GETISAX #ifdef HAVE_GETISAX
if (getisax(&result, 1)) { if (getisax(&result, 1)) {
@ -2133,8 +2132,13 @@ static unsigned int detectCPUFeatures(void) {
} }
#else #else
char vendor[13]; char vendor[13];
#ifdef _MSC_VER
int vendor0 = 0, vendor1, vendor2;
#endif
vendor[0] = 0; vendor[0] = 0;
vendor[12] = 0; vendor[12] = 0;
#ifdef __GNUC__
/* see p. 118 of amd64 instruction set manual Vol3 */ /* see p. 118 of amd64 instruction set manual Vol3 */
/* We need to be careful about the handling of %ebx and /* We need to be careful about the handling of %ebx and
* %esp here. We can't declare either one as clobbered * %esp here. We can't declare either one as clobbered
@ -2153,7 +2157,7 @@ static unsigned int detectCPUFeatures(void) {
"pop %%eax\n" "pop %%eax\n"
"mov $0x0, %%edx\n" "mov $0x0, %%edx\n"
"xor %%ecx, %%eax\n" "xor %%ecx, %%eax\n"
"jz 1\n" "jz 1f\n"
"mov $0x00000000, %%eax\n" "mov $0x00000000, %%eax\n"
"push %%ebx\n" "push %%ebx\n"
@ -2177,6 +2181,45 @@ static unsigned int detectCPUFeatures(void) {
: "%eax", "%ecx", "%edx" : "%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) { if (result) {
/* result now contains the standard feature bits */ /* result now contains the standard feature bits */
if (result & (1 << 15)) if (result & (1 << 15))
@ -2191,14 +2234,13 @@ static unsigned int detectCPUFeatures(void) {
(strcmp(vendor, "AuthenticAMD") == 0 || (strcmp(vendor, "AuthenticAMD") == 0 ||
strcmp(vendor, "Geode by NSC") == 0)) { strcmp(vendor, "Geode by NSC") == 0)) {
/* check for AMD MMX extensions */ /* check for AMD MMX extensions */
#ifdef __GNUC__
unsigned int result;
__asm__("push %%ebx\n" __asm__("push %%ebx\n"
"mov $0x80000000, %%eax\n" "mov $0x80000000, %%eax\n"
"cpuid\n" "cpuid\n"
"xor %%edx, %%edx\n" "xor %%edx, %%edx\n"
"cmp $0x1, %%eax\n" "cmp $0x1, %%eax\n"
"jge 2\n" "jge 2f\n"
"mov $0x80000001, %%eax\n" "mov $0x80000001, %%eax\n"
"cpuid\n" "cpuid\n"
"2:\n" "2:\n"
@ -2208,11 +2250,27 @@ static unsigned int detectCPUFeatures(void) {
: :
: "%eax", "%ecx", "%edx" : "%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)) if (result & (1<<22))
features |= MMX_Extensions; features |= MMX_Extensions;
} }
} }
#endif /* HAVE_GETISAX */ #endif /* HAVE_GETISAX */
return features; return features;
} }