diff options
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/x86/common_x86.c | 88 | ||||
| -rw-r--r-- | src/mesa/x86/common_x86_asm.S | 182 | ||||
| -rw-r--r-- | src/mesa/x86/common_x86_features.h | 60 | 
3 files changed, 183 insertions, 147 deletions
| diff --git a/src/mesa/x86/common_x86.c b/src/mesa/x86/common_x86.c index b680cb7..f22cd18 100644 --- a/src/mesa/x86/common_x86.c +++ b/src/mesa/x86/common_x86.c @@ -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;     } diff --git a/src/mesa/x86/common_x86_asm.S b/src/mesa/x86/common_x86_asm.S index 0bd55e7..9deceea 100644 --- a/src/mesa/x86/common_x86_asm.S +++ b/src/mesa/x86/common_x86_asm.S @@ -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,140 +44,104 @@  #include "matypes.h"  #include "common_x86_features.h" +	SEG_TEXT -/* Intel vendor string - */ -#define GENU	0x756e6547	/* "Genu" */ -#define INEI	0x49656e69	/* "ineI" */ -#define NTEL	0x6c65746e	/* "ntel" */ +ALIGNTEXT4 +GLOBL GLNAME(_mesa_x86_has_cpuid) +GLNAME(_mesa_x86_has_cpuid): -/* AMD vendor string - */ -#define AUTH	0x68747541	/* "Auth" */ -#define ENTI	0x69746e65	/* "enti" */ -#define CAMD	0x444d4163	/* "cAMD" */ +	/* Test for the CPUID command.  If the ID Flag bit in EFLAGS +	 * (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) +	POPF_L +	PUSHF_L +	POP_L	(EAX) +	/* Verify the ID Flag bit has been written. */ +	CMP_L	(ECX, EAX) +	SETNE	(AL) +	XOR_L	(CONST(0xff), EAX) -	SEG_DATA +	RET -/* 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" ) +ALIGNTEXT4 +GLOBL GLNAME(_mesa_x86_cpuid) +GLNAME(_mesa_x86_cpuid): -	SEG_TEXT +	MOV_L	(REGOFF(4, ESP), EAX)		/* cpuid op */ +	PUSH_L	(EDI) +	PUSH_L	(EBX) -ALIGNTEXT4 -GLOBL GLNAME( _mesa_identify_x86_cpu_features ) -GLNAME( _mesa_identify_x86_cpu_features ): +	CPUID -	PUSH_L	( EBX ) -	PUSH_L	( ESI ) +	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 -	/* Test for the CPUID command.  If the ID Flag bit in EFLAGS -	 * (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 ) -	POPF_L -	PUSHF_L -	POP_L	( EAX ) +ALIGNTEXT4 +GLOBL GLNAME(_mesa_x86_cpuid_eax) +GLNAME(_mesa_x86_cpuid_eax): -	/* Verify the ID Flag bit has been written. -	 */ -	CMP_L	( ECX, EAX ) -	JZ	( LLBL (cpuid_done) ) +	MOV_L	(REGOFF(4, ESP), EAX)		/* cpuid op */ +	PUSH_L	(EBX) -	/* 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 ) +	POP_L	(EBX) +	RET -	/* 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) ) +ALIGNTEXT4 +GLOBL GLNAME(_mesa_x86_cpuid_ebx) +GLNAME(_mesa_x86_cpuid_ebx): -LLBL(cpuid_amd): +	MOV_L	(REGOFF(4, ESP), EAX)		/* cpuid op */ +	PUSH_L	(EBX) -	/* 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	(EBX, EAX)			/* return EBX */ -	MOV_L	( CONST(0x80000000), EAX ) -	CPUID -	TEST_L	( EAX, EAX ) -	JZ	( LLBL (cpuid_failed) ) +	POP_L	(EBX) +	RET -	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) ) +ALIGNTEXT4 +GLOBL GLNAME(_mesa_x86_cpuid_ecx) +GLNAME(_mesa_x86_cpuid_ecx): -LLBL(cpuid_other): +	MOV_L	(REGOFF(4, ESP), EAX)		/* cpuid op */ +	PUSH_L	(EBX) -	/* Test for other processors here when required. -	 */ +	CPUID +	MOV_L	(ECX, EAX)			/* return ECX */ -LLBL(cpuid_failed): +	POP_L	(EBX) +	RET -	/* 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 ) +ALIGNTEXT4 +GLOBL GLNAME(_mesa_x86_cpuid_edx) +GLNAME(_mesa_x86_cpuid_edx): -LLBL (cpuid_done): +	MOV_L	(REGOFF(4, ESP), EAX)		/* cpuid op */ +	PUSH_L	(EBX) -	POP_L	( ESI ) -	POP_L	( EBX ) -	RET +	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 @@ -235,3 +200,4 @@ GLNAME( _mesa_test_os_sse_exception_support ):  	RET  #endif + diff --git a/src/mesa/x86/common_x86_features.h b/src/mesa/x86/common_x86_features.h index 258f389..9050977 100644 --- a/src/mesa/x86/common_x86_features.h +++ b/src/mesa/x86/common_x86_features.h @@ -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 + | 
