new X86 CPU detection code (Petr Sebor)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $Id: common_x86.c,v 1.20 2002/11/13 15:03:31 brianp Exp $ */
|
||||
/* $Id: common_x86.c,v 1.21 2003/01/21 16:13:55 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -52,8 +52,14 @@ int _mesa_x86_cpu_features = 0;
|
||||
|
||||
/* No reason for this to be public.
|
||||
*/
|
||||
extern int _mesa_identify_x86_cpu_features( void );
|
||||
extern int _mesa_identify_x86_cpu_features(void);
|
||||
|
||||
extern GLuint _mesa_x86_has_cpuid(void);
|
||||
extern void _mesa_x86_cpuid(GLuint op, GLuint *reg_eax, GLuint *reg_ebx, GLuint *reg_ecx, GLuint *reg_edx);
|
||||
extern GLuint _mesa_x86_cpuid_eax(GLuint op);
|
||||
extern GLuint _mesa_x86_cpuid_ebx(GLuint op);
|
||||
extern GLuint _mesa_x86_cpuid_ecx(GLuint op);
|
||||
extern GLuint _mesa_x86_cpuid_edx(GLuint op);
|
||||
|
||||
static void message( const char *msg )
|
||||
{
|
||||
@@ -240,8 +246,84 @@ void _mesa_init_all_x86_transform_asm( void )
|
||||
{
|
||||
(void) message; /* silence warning */
|
||||
#ifdef USE_X86_ASM
|
||||
_mesa_x86_cpu_features = _mesa_identify_x86_cpu_features();
|
||||
_mesa_x86_cpu_features = 0;
|
||||
|
||||
if (!_mesa_x86_has_cpuid()) {
|
||||
message("CPUID not detected");
|
||||
}
|
||||
else {
|
||||
GLuint cpu_features;
|
||||
GLuint cpu_ext_features;
|
||||
GLuint cpu_ext_info;
|
||||
char cpu_vendor[13];
|
||||
GLuint result;
|
||||
|
||||
/* get vendor name */
|
||||
_mesa_x86_cpuid(0, &result, (GLuint *)(cpu_vendor + 0), (GLuint *)(cpu_vendor + 8), (GLuint *)(cpu_vendor + 4));
|
||||
cpu_vendor[12] = '\0';
|
||||
|
||||
message("cpu vendor: ");
|
||||
message(cpu_vendor);
|
||||
message("\n");
|
||||
|
||||
/* get cpu features */
|
||||
cpu_features = _mesa_x86_cpuid_edx(1);
|
||||
|
||||
if (cpu_features & X86_CPU_FPU)
|
||||
_mesa_x86_cpu_features |= X86_FEATURE_FPU;
|
||||
if (cpu_features & X86_CPU_CMOV)
|
||||
_mesa_x86_cpu_features |= X86_FEATURE_CMOV;
|
||||
|
||||
#ifdef USE_MMX_ASM
|
||||
if (cpu_features & X86_CPU_MMX)
|
||||
_mesa_x86_cpu_features |= X86_FEATURE_MMX;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSE_ASM
|
||||
if (cpu_features & X86_CPU_XMM)
|
||||
_mesa_x86_cpu_features |= X86_FEATURE_XMM;
|
||||
if (cpu_features & X86_CPU_XMM2)
|
||||
_mesa_x86_cpu_features |= X86_FEATURE_XMM2;
|
||||
#endif
|
||||
|
||||
/* query extended cpu features */
|
||||
if ((cpu_ext_info = _mesa_x86_cpuid_eax(0x80000000)) > 0x80000000) {
|
||||
if (cpu_ext_info >= 0x80000001) {
|
||||
|
||||
cpu_ext_features = _mesa_x86_cpuid_edx(0x80000001);
|
||||
|
||||
if (cpu_features & X86_CPU_MMX) {
|
||||
|
||||
#ifdef USE_3DNOW_ASM
|
||||
if (cpu_ext_features & X86_CPUEXT_3DNOW)
|
||||
_mesa_x86_cpu_features |= X86_FEATURE_3DNOW;
|
||||
if (cpu_ext_features & X86_CPUEXT_3DNOW_EXT)
|
||||
_mesa_x86_cpu_features |= X86_FEATURE_3DNOWEXT;
|
||||
#endif
|
||||
|
||||
#ifdef USE_MMX_ASM
|
||||
if (cpu_ext_features & X86_CPUEXT_MMX_EXT)
|
||||
_mesa_x86_cpu_features |= X86_FEATURE_MMXEXT;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* query cpu name */
|
||||
if (cpu_ext_info >= 0x80000002) {
|
||||
GLuint ofs;
|
||||
char cpu_name[49];
|
||||
for (ofs = 0; ofs < 3; ofs++)
|
||||
_mesa_x86_cpuid(0x80000002+ofs, (GLuint *)(cpu_name + (16*ofs)+0), (GLuint *)(cpu_name + (16*ofs)+4), (GLuint *)(cpu_name + (16*ofs)+8), (GLuint *)(cpu_name + (16*ofs)+12));
|
||||
cpu_name[48] = '\0'; /* the name should be NULL terminated, but just to be sure */
|
||||
|
||||
message("cpu name: ");
|
||||
message(cpu_name);
|
||||
message("\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( getenv( "MESA_NO_ASM" ) ) {
|
||||
_mesa_x86_cpu_features = 0;
|
||||
}
|
||||
|
||||
+89
-123
@@ -1,4 +1,4 @@
|
||||
/* $Id: common_x86_asm.S,v 1.16 2003/01/09 23:43:02 brianp Exp $ */
|
||||
/* $Id: common_x86_asm.S,v 1.17 2003/01/21 16:13:58 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -32,6 +32,7 @@
|
||||
* Written by Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
|
||||
*
|
||||
* Cleaned up and simplified by Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -43,141 +44,105 @@
|
||||
#include "matypes.h"
|
||||
#include "common_x86_features.h"
|
||||
|
||||
|
||||
/* Intel vendor string
|
||||
*/
|
||||
#define GENU 0x756e6547 /* "Genu" */
|
||||
#define INEI 0x49656e69 /* "ineI" */
|
||||
#define NTEL 0x6c65746e /* "ntel" */
|
||||
|
||||
/* AMD vendor string
|
||||
*/
|
||||
#define AUTH 0x68747541 /* "Auth" */
|
||||
#define ENTI 0x69746e65 /* "enti" */
|
||||
#define CAMD 0x444d4163 /* "cAMD" */
|
||||
|
||||
|
||||
SEG_DATA
|
||||
|
||||
/* We might want to print out some useful messages.
|
||||
*/
|
||||
GLNAME( found_intel ): STRING( "Genuine Intel processor found\n\0" )
|
||||
GLNAME( found_amd ): STRING( "Authentic AMD processor found\n\0" )
|
||||
|
||||
|
||||
SEG_TEXT
|
||||
|
||||
ALIGNTEXT4
|
||||
GLOBL GLNAME( _mesa_identify_x86_cpu_features )
|
||||
GLNAME( _mesa_identify_x86_cpu_features ):
|
||||
|
||||
PUSH_L ( EBX )
|
||||
PUSH_L ( ESI )
|
||||
GLOBL GLNAME(_mesa_x86_has_cpuid)
|
||||
GLNAME(_mesa_x86_has_cpuid):
|
||||
|
||||
/* Test for the CPUID command. If the ID Flag bit in EFLAGS
|
||||
* (bit 21) is writable, the CPUID command is present.
|
||||
*/
|
||||
* (bit 21) is writable, the CPUID command is present */
|
||||
PUSHF_L
|
||||
POP_L ( EAX )
|
||||
MOV_L ( EAX, ECX )
|
||||
XOR_L ( CONST(0x00200000), EAX )
|
||||
PUSH_L ( EAX )
|
||||
POP_L (EAX)
|
||||
MOV_L (EAX, ECX)
|
||||
XOR_L (CONST(0x00200000), EAX)
|
||||
PUSH_L (EAX)
|
||||
POPF_L
|
||||
PUSHF_L
|
||||
POP_L ( EAX )
|
||||
POP_L (EAX)
|
||||
|
||||
/* Verify the ID Flag bit has been written.
|
||||
*/
|
||||
CMP_L ( ECX, EAX )
|
||||
JZ ( LLBL (cpuid_done) )
|
||||
/* Verify the ID Flag bit has been written. */
|
||||
CMP_L (ECX, EAX)
|
||||
SETNE (AL)
|
||||
XOR_L (CONST(0xff), EAX)
|
||||
|
||||
/* Get the CPU vendor info.
|
||||
*/
|
||||
XOR_L ( EAX, EAX )
|
||||
CPUID
|
||||
|
||||
/* Test for Intel processors. We must look for the
|
||||
* "GenuineIntel" string in EBX, ECX and EDX.
|
||||
*/
|
||||
CMP_L ( CONST(GENU), EBX )
|
||||
JNE ( LLBL(cpuid_amd) )
|
||||
CMP_L ( CONST(INEI), EDX )
|
||||
JNE ( LLBL(cpuid_amd) )
|
||||
CMP_L ( CONST(NTEL), ECX )
|
||||
JNE ( LLBL(cpuid_amd) )
|
||||
|
||||
/* We have an Intel processor, so we can get the feature
|
||||
* information with an CPUID input value of 1.
|
||||
*/
|
||||
MOV_L ( CONST(0x1), EAX )
|
||||
CPUID
|
||||
MOV_L ( EDX, EAX )
|
||||
|
||||
/* Mask out highest bit, which is used by AMD for 3dnow
|
||||
* Newer Intel have this bit set, but do not support 3dnow
|
||||
*/
|
||||
AND_L ( CONST(0X7FFFFFFF), EAX)
|
||||
JMP ( LLBL(cpuid_done) )
|
||||
|
||||
LLBL(cpuid_amd):
|
||||
|
||||
/* Test for AMD processors. We must look for the
|
||||
* "AuthenticAMD" string in EBX, ECX and EDX.
|
||||
*/
|
||||
CMP_L ( CONST(AUTH), EBX )
|
||||
JNE ( LLBL(cpuid_other) )
|
||||
CMP_L ( CONST(ENTI), EDX )
|
||||
JNE ( LLBL(cpuid_other) )
|
||||
CMP_L ( CONST(CAMD), ECX )
|
||||
JNE ( LLBL(cpuid_other) )
|
||||
|
||||
/* We have an AMD processor, so we can get the feature
|
||||
* information after we verify that the extended functions are
|
||||
* supported.
|
||||
*/
|
||||
/* The features we need are almost all in the extended set. The
|
||||
* exception is SSE enable, which is in the standard set (0x1).
|
||||
*/
|
||||
MOV_L ( CONST(0x1), EAX )
|
||||
CPUID
|
||||
TEST_L ( EAX, EAX )
|
||||
JZ ( LLBL (cpuid_failed) )
|
||||
MOV_L ( EDX, ESI )
|
||||
|
||||
MOV_L ( CONST(0x80000000), EAX )
|
||||
CPUID
|
||||
TEST_L ( EAX, EAX )
|
||||
JZ ( LLBL (cpuid_failed) )
|
||||
|
||||
MOV_L ( CONST(0x80000001), EAX )
|
||||
CPUID
|
||||
MOV_L ( EDX, EAX )
|
||||
|
||||
AND_L ( CONST(0x02000000), ESI ) /* OR in the SSE bit */
|
||||
OR_L ( ESI, EAX )
|
||||
|
||||
JMP ( LLBL (cpuid_done) )
|
||||
|
||||
LLBL(cpuid_other):
|
||||
|
||||
/* Test for other processors here when required.
|
||||
*/
|
||||
|
||||
LLBL(cpuid_failed):
|
||||
|
||||
/* If we can't determine the feature information, we must
|
||||
* return zero to indicate that no platform-specific
|
||||
* optimizations can be used.
|
||||
*/
|
||||
MOV_L ( CONST(0), EAX )
|
||||
|
||||
LLBL (cpuid_done):
|
||||
|
||||
POP_L ( ESI )
|
||||
POP_L ( EBX )
|
||||
RET
|
||||
|
||||
|
||||
ALIGNTEXT4
|
||||
GLOBL GLNAME(_mesa_x86_cpuid)
|
||||
GLNAME(_mesa_x86_cpuid):
|
||||
|
||||
MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */
|
||||
PUSH_L (EDI)
|
||||
PUSH_L (EBX)
|
||||
|
||||
CPUID
|
||||
|
||||
MOV_L (REGOFF(16, ESP), EDI) /* *eax */
|
||||
MOV_L (EAX, REGIND(EDI))
|
||||
MOV_L (REGOFF(20, ESP), EDI) /* *ebx */
|
||||
MOV_L (EBX, REGIND(EDI))
|
||||
MOV_L (REGOFF(24, ESP), EDI) /* *ecx */
|
||||
MOV_L (ECX, REGIND(EDI))
|
||||
MOV_L (REGOFF(28, ESP), EDI) /* *edx */
|
||||
MOV_L (EDX, REGIND(EDI))
|
||||
|
||||
POP_L (EBX)
|
||||
POP_L (EDI)
|
||||
RET
|
||||
|
||||
ALIGNTEXT4
|
||||
GLOBL GLNAME(_mesa_x86_cpuid_eax)
|
||||
GLNAME(_mesa_x86_cpuid_eax):
|
||||
|
||||
MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */
|
||||
PUSH_L (EBX)
|
||||
|
||||
CPUID
|
||||
|
||||
POP_L (EBX)
|
||||
RET
|
||||
|
||||
ALIGNTEXT4
|
||||
GLOBL GLNAME(_mesa_x86_cpuid_ebx)
|
||||
GLNAME(_mesa_x86_cpuid_ebx):
|
||||
|
||||
MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */
|
||||
PUSH_L (EBX)
|
||||
|
||||
CPUID
|
||||
MOV_L (EBX, EAX) /* return EBX */
|
||||
|
||||
POP_L (EBX)
|
||||
RET
|
||||
|
||||
ALIGNTEXT4
|
||||
GLOBL GLNAME(_mesa_x86_cpuid_ecx)
|
||||
GLNAME(_mesa_x86_cpuid_ecx):
|
||||
|
||||
MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */
|
||||
PUSH_L (EBX)
|
||||
|
||||
CPUID
|
||||
MOV_L (ECX, EAX) /* return ECX */
|
||||
|
||||
POP_L (EBX)
|
||||
RET
|
||||
|
||||
ALIGNTEXT4
|
||||
GLOBL GLNAME(_mesa_x86_cpuid_edx)
|
||||
GLNAME(_mesa_x86_cpuid_edx):
|
||||
|
||||
MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */
|
||||
PUSH_L (EBX)
|
||||
|
||||
CPUID
|
||||
MOV_L (EDX, EAX) /* return EDX */
|
||||
|
||||
POP_L (EBX)
|
||||
RET
|
||||
|
||||
#ifdef USE_SSE_ASM
|
||||
/* Execute an SSE instruction to see if the operating system correctly
|
||||
* supports SSE. A signal handler for SIGILL should have been set
|
||||
@@ -235,3 +200,4 @@ GLNAME( _mesa_test_os_sse_exception_support ):
|
||||
RET
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* $Id: common_x86_features.h,v 1.5 2002/10/29 20:28:57 brianp Exp $ */
|
||||
/* $Id: common_x86_features.h,v 1.6 2003/01/21 16:14:00 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.5
|
||||
* Version: 5.1
|
||||
*
|
||||
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
|
||||
*
|
||||
@@ -35,40 +35,27 @@
|
||||
#ifndef __COMMON_X86_FEATURES_H__
|
||||
#define __COMMON_X86_FEATURES_H__
|
||||
|
||||
/* Capabilities of CPUs
|
||||
*/
|
||||
#define X86_FEATURE_FPU 0x00000001
|
||||
#define X86_FEATURE_VME 0x00000002
|
||||
#define X86_FEATURE_DE 0x00000004
|
||||
#define X86_FEATURE_PSE 0x00000008
|
||||
#define X86_FEATURE_TSC 0x00000010
|
||||
#define X86_FEATURE_MSR 0x00000020
|
||||
#define X86_FEATURE_PAE 0x00000040
|
||||
#define X86_FEATURE_MCE 0x00000080
|
||||
#define X86_FEATURE_CX8 0x00000100
|
||||
#define X86_FEATURE_APIC 0x00000200
|
||||
#define X86_FEATURE_10 0x00000400
|
||||
#define X86_FEATURE_SEP 0x00000800
|
||||
#define X86_FEATURE_MTRR 0x00001000
|
||||
#define X86_FEATURE_PGE 0x00002000
|
||||
#define X86_FEATURE_MCA 0x00004000
|
||||
#define X86_FEATURE_CMOV 0x00008000
|
||||
#define X86_FEATURE_PAT 0x00010000
|
||||
#define X86_FEATURE_PSE36 0x00020000
|
||||
#define X86_FEATURE_18 0x00040000
|
||||
#define X86_FEATURE_19 0x00080000
|
||||
#define X86_FEATURE_20 0x00100000
|
||||
#define X86_FEATURE_21 0x00200000
|
||||
#define X86_FEATURE_MMXEXT 0x00400000
|
||||
#define X86_FEATURE_MMX 0x00800000
|
||||
#define X86_FEATURE_FXSR 0x01000000
|
||||
#define X86_FEATURE_XMM 0x02000000
|
||||
#define X86_FEATURE_XMM2 0x04000000
|
||||
#define X86_FEATURE_27 0x08000000
|
||||
#define X86_FEATURE_28 0x10000000
|
||||
#define X86_FEATURE_29 0x20000000
|
||||
#define X86_FEATURE_3DNOWEXT 0x40000000
|
||||
#define X86_FEATURE_3DNOW 0x80000000
|
||||
#define X86_FEATURE_FPU (1<<0)
|
||||
#define X86_FEATURE_CMOV (1<<1)
|
||||
#define X86_FEATURE_MMXEXT (1<<2)
|
||||
#define X86_FEATURE_MMX (1<<3)
|
||||
#define X86_FEATURE_FXSR (1<<4)
|
||||
#define X86_FEATURE_XMM (1<<5)
|
||||
#define X86_FEATURE_XMM2 (1<<6)
|
||||
#define X86_FEATURE_3DNOWEXT (1<<7)
|
||||
#define X86_FEATURE_3DNOW (1<<8)
|
||||
|
||||
/* standard X86 CPU features */
|
||||
#define X86_CPU_FPU (1<<0)
|
||||
#define X86_CPU_CMOV (1<<15)
|
||||
#define X86_CPU_MMX (1<<23)
|
||||
#define X86_CPU_XMM (1<<25)
|
||||
#define X86_CPU_XMM2 (1<<26)
|
||||
|
||||
/* extended X86 CPU features */
|
||||
#define X86_CPUEXT_MMX_EXT (1<<22)
|
||||
#define X86_CPUEXT_3DNOW_EXT (1<<30)
|
||||
#define X86_CPUEXT_3DNOW (1<<31)
|
||||
|
||||
#define cpu_has_mmx (_mesa_x86_cpu_features & X86_FEATURE_MMX)
|
||||
#define cpu_has_mmxext (_mesa_x86_cpu_features & X86_FEATURE_MMXEXT)
|
||||
@@ -78,3 +65,4 @@
|
||||
#define cpu_has_3dnowext (_mesa_x86_cpu_features & X86_FEATURE_3DNOWEXT)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user