Bug #5093: Fix fb for non-SSE machines. (Xavier Bachelot)
This commit is contained in:
parent
ed826d563c
commit
4ec0b623b6
109
fb/fbmmx.c
109
fb/fbmmx.c
|
@ -2269,116 +2269,7 @@ fbCompositeCopyAreammx (CARD8 op,
|
||||||
width, height);
|
width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(__amd64__) && !defined(__x86_64__)
|
|
||||||
|
|
||||||
enum CPUFeatures {
|
|
||||||
NoFeatures = 0,
|
|
||||||
MMX = 0x1,
|
|
||||||
MMX_Extensions = 0x2,
|
|
||||||
SSE = 0x6,
|
|
||||||
SSE2 = 0x8,
|
|
||||||
CMOV = 0x10
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned int detectCPUFeatures(void) {
|
|
||||||
unsigned int result;
|
|
||||||
char vendor[13];
|
|
||||||
vendor[0] = 0;
|
|
||||||
vendor[12] = 0;
|
|
||||||
/* 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
|
|
||||||
* since they are special registers (%ebx is the "PIC
|
|
||||||
* register" holding an offset to global data, %esp the
|
|
||||||
* stack pointer), so we need to make sure they have their+ * original values when we access the output operands.
|
|
||||||
*/
|
|
||||||
__asm__ ("pushf\n"
|
|
||||||
"pop %%eax\n"
|
|
||||||
"mov %%eax, %%ecx\n"
|
|
||||||
"xor $0x00200000, %%eax\n"
|
|
||||||
"push %%eax\n"
|
|
||||||
"popf\n"
|
|
||||||
"pushf\n"
|
|
||||||
"pop %%eax\n"
|
|
||||||
"mov $0x0, %%edx\n"
|
|
||||||
"xor %%ecx, %%eax\n"
|
|
||||||
"jz 1\n"
|
|
||||||
|
|
||||||
"mov $0x00000000, %%eax\n"
|
|
||||||
"push %%ebx\n"
|
|
||||||
"cpuid\n"
|
|
||||||
"mov %%ebx, %%eax\n"
|
|
||||||
"pop %%ebx\n"
|
|
||||||
"mov %%eax, %1\n"
|
|
||||||
"mov %%edx, %2\n"
|
|
||||||
"mov %%ecx, %3\n"
|
|
||||||
"mov $0x00000001, %%eax\n"
|
|
||||||
"push %%ebx\n"
|
|
||||||
"cpuid\n"
|
|
||||||
"pop %%ebx\n"
|
|
||||||
"1:\n"
|
|
||||||
"mov %%edx, %0\n"
|
|
||||||
: "=r" (result),
|
|
||||||
"=m" (vendor[0]),
|
|
||||||
"=m" (vendor[4]),
|
|
||||||
"=m" (vendor[8])
|
|
||||||
:
|
|
||||||
: "%eax", "%ecx", "%edx"
|
|
||||||
);
|
|
||||||
|
|
||||||
unsigned int features = 0;
|
|
||||||
if (result) {
|
|
||||||
/* result now contains the standard feature bits */
|
|
||||||
if (result & (1 << 15))
|
|
||||||
features |= CMOV;
|
|
||||||
if (result & (1 << 23))
|
|
||||||
features |= MMX;
|
|
||||||
if (result & (1 << 25))
|
|
||||||
features |= SSE;
|
|
||||||
if (result & (1 << 26))
|
|
||||||
features |= SSE2;
|
|
||||||
if ((result & MMX) && !(result & SSE) && (strcmp(vendor, "AuthenticAMD") == 0)) {
|
|
||||||
/* check for AMD MMX extensions */
|
|
||||||
|
|
||||||
unsigned int result;
|
|
||||||
__asm__("push %%ebx\n"
|
|
||||||
"mov $0x80000000, %%eax\n"
|
|
||||||
"cpuid\n"
|
|
||||||
"xor %%edx, %%edx\n"
|
|
||||||
"cmp $0x1, %%eax\n"
|
|
||||||
"jge 2\n"
|
|
||||||
"mov $0x80000001, %%eax\n"
|
|
||||||
"cpuid\n"
|
|
||||||
"2:\n"
|
|
||||||
"pop %%ebx\n"
|
|
||||||
"mov %%edx, %0\n"
|
|
||||||
: "=r" (result)
|
|
||||||
:
|
|
||||||
: "%eax", "%ecx", "%edx"
|
|
||||||
);
|
|
||||||
if (result & (1<<22))
|
|
||||||
features |= MMX_Extensions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return features;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool
|
|
||||||
fbHaveMMX (void)
|
|
||||||
{
|
|
||||||
static Bool initialized = FALSE;
|
|
||||||
static Bool mmx_present;
|
|
||||||
|
|
||||||
if (!initialized)
|
|
||||||
{
|
|
||||||
unsigned int features = detectCPUFeatures();
|
|
||||||
mmx_present = (features & (MMX|MMX_Extensions)) == (MMX|MMX_Extensions);
|
|
||||||
initialized = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mmx_present;
|
|
||||||
}
|
|
||||||
#endif /* __amd64__ */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* RENDER */
|
#endif /* RENDER */
|
||||||
|
|
118
fb/fbpict.c
118
fb/fbpict.c
|
@ -1336,3 +1336,121 @@ fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_MMX
|
||||||
|
/* The CPU detection code needs to be in a file not compiled with
|
||||||
|
* "-mmmx -msse", as gcc would generate CMOV instructions otherwise
|
||||||
|
* that would lead to SIGILL instructions on old CPUs that don't have
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
#if !defined(__amd64__) && !defined(__x86_64__)
|
||||||
|
|
||||||
|
enum CPUFeatures {
|
||||||
|
NoFeatures = 0,
|
||||||
|
MMX = 0x1,
|
||||||
|
MMX_Extensions = 0x2,
|
||||||
|
SSE = 0x6,
|
||||||
|
SSE2 = 0x8,
|
||||||
|
CMOV = 0x10
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned int detectCPUFeatures(void) {
|
||||||
|
unsigned int result;
|
||||||
|
char vendor[13];
|
||||||
|
vendor[0] = 0;
|
||||||
|
vendor[12] = 0;
|
||||||
|
/* 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
|
||||||
|
* since they are special registers (%ebx is the "PIC
|
||||||
|
* register" holding an offset to global data, %esp the
|
||||||
|
* stack pointer), so we need to make sure they have their+ * original values when we access the output operands.
|
||||||
|
*/
|
||||||
|
__asm__ ("pushf\n"
|
||||||
|
"pop %%eax\n"
|
||||||
|
"mov %%eax, %%ecx\n"
|
||||||
|
"xor $0x00200000, %%eax\n"
|
||||||
|
"push %%eax\n"
|
||||||
|
"popf\n"
|
||||||
|
"pushf\n"
|
||||||
|
"pop %%eax\n"
|
||||||
|
"mov $0x0, %%edx\n"
|
||||||
|
"xor %%ecx, %%eax\n"
|
||||||
|
"jz 1\n"
|
||||||
|
|
||||||
|
"mov $0x00000000, %%eax\n"
|
||||||
|
"push %%ebx\n"
|
||||||
|
"cpuid\n"
|
||||||
|
"mov %%ebx, %%eax\n"
|
||||||
|
"pop %%ebx\n"
|
||||||
|
"mov %%eax, %1\n"
|
||||||
|
"mov %%edx, %2\n"
|
||||||
|
"mov %%ecx, %3\n"
|
||||||
|
"mov $0x00000001, %%eax\n"
|
||||||
|
"push %%ebx\n"
|
||||||
|
"cpuid\n"
|
||||||
|
"pop %%ebx\n"
|
||||||
|
"1:\n"
|
||||||
|
"mov %%edx, %0\n"
|
||||||
|
: "=r" (result),
|
||||||
|
"=m" (vendor[0]),
|
||||||
|
"=m" (vendor[4]),
|
||||||
|
"=m" (vendor[8])
|
||||||
|
:
|
||||||
|
: "%eax", "%ecx", "%edx"
|
||||||
|
);
|
||||||
|
|
||||||
|
unsigned int features = 0;
|
||||||
|
if (result) {
|
||||||
|
/* result now contains the standard feature bits */
|
||||||
|
if (result & (1 << 15))
|
||||||
|
features |= CMOV;
|
||||||
|
if (result & (1 << 23))
|
||||||
|
features |= MMX;
|
||||||
|
if (result & (1 << 25))
|
||||||
|
features |= SSE;
|
||||||
|
if (result & (1 << 26))
|
||||||
|
features |= SSE2;
|
||||||
|
if ((result & MMX) && !(result & SSE) && (strcmp(vendor, "AuthenticAMD") == 0)) {
|
||||||
|
/* check for AMD MMX extensions */
|
||||||
|
|
||||||
|
unsigned int result;
|
||||||
|
__asm__("push %%ebx\n"
|
||||||
|
"mov $0x80000000, %%eax\n"
|
||||||
|
"cpuid\n"
|
||||||
|
"xor %%edx, %%edx\n"
|
||||||
|
"cmp $0x1, %%eax\n"
|
||||||
|
"jge 2\n"
|
||||||
|
"mov $0x80000001, %%eax\n"
|
||||||
|
"cpuid\n"
|
||||||
|
"2:\n"
|
||||||
|
"pop %%ebx\n"
|
||||||
|
"mov %%edx, %0\n"
|
||||||
|
: "=r" (result)
|
||||||
|
:
|
||||||
|
: "%eax", "%ecx", "%edx"
|
||||||
|
);
|
||||||
|
if (result & (1<<22))
|
||||||
|
features |= MMX_Extensions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
fbHaveMMX (void)
|
||||||
|
{
|
||||||
|
static Bool initialized = FALSE;
|
||||||
|
static Bool mmx_present;
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
unsigned int features = detectCPUFeatures();
|
||||||
|
mmx_present = (features & (MMX|MMX_Extensions)) == (MMX|MMX_Extensions);
|
||||||
|
initialized = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mmx_present;
|
||||||
|
}
|
||||||
|
#endif /* __amd64__ */
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue