csutil/csprocessorcap.h
Go to the documentation of this file.
00001 /* 00002 Copyright (C) 2002 by Marten Svanfeldt 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public 00015 License along with this library; if not, write to the Free 00016 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00017 */ 00018 00019 #ifndef __CS_PROCESSORCAP_H__ 00020 #define __CS_PROCESSORCAP_H__ 00021 00026 #include "csextern.h" 00027 00028 #include "csutil/deprecated_warn_off.h" 00029 00036 class CS_CRYSTALSPACE_EXPORT 00037 CS_DEPRECATED_TYPE_MSG("csProcessorCapability is deprecated. " 00038 "Please use CS::Platform::ProcessorSpecDetection instead.") 00039 csProcessorCapability 00040 { 00041 public: 00042 00046 csProcessorCapability () 00047 { 00048 } 00049 00053 ~csProcessorCapability () 00054 { 00055 } 00056 00060 static inline void Initialize () 00061 { 00062 if (isInitialized) 00063 return; 00064 00065 #ifdef CS_PROCESSOR_X86 00066 CheckX86Processor (); 00067 #else 00068 mmxSupported = false; 00069 sseSupported = false; 00070 processorName[0] = 0; 00071 #endif 00072 } 00073 00074 static inline bool HasMMX () 00075 { 00076 Initialize (); 00077 00078 return mmxSupported; 00079 } 00080 00081 static inline bool HasSSE () 00082 { 00083 Initialize (); 00084 00085 return sseSupported; 00086 } 00087 00088 static inline const char* GetProcessorName () 00089 { 00090 Initialize (); 00091 00092 return processorName; 00093 } 00094 00095 private: 00096 00098 static bool isInitialized; 00099 00101 static bool mmxSupported; 00102 00104 static bool sseSupported; 00105 00107 static bool AMD3dnowSupported; 00108 00110 static char processorName[16]; 00111 00112 #if defined(CS_PROCESSOR_X86) && (CS_PROCESSOR_SIZE == 32) 00113 00117 static inline void CheckX86Processor () 00118 { 00119 int32 capFlags = 0; 00120 int CPUnum; 00121 int maxEax = 0; 00122 const char* procName = processorName; 00123 00124 bool have_cpuid; 00125 00126 #if defined(CS_COMPILER_MSVC) 00127 __asm 00128 { 00129 // save vars 00130 push eax 00131 push ebx 00132 push esi 00133 00134 //detect 386/486 00135 pushfd 00136 pop eax //get EFLAGS 00137 mov ebx, eax //save original EFLAGS 00138 xor eax, 40000h //toggle AC bit 00139 push eax //copy to stack 00140 popfd //copy to EFLAGS 00141 pushfd 00142 pop eax //get EFLAGS again 00143 xor eax, ebx //check AC bit 00144 mov CPUnum, 386 //386 00145 je end_detect //is a 386, stop detection 00146 push ebx //restore EFLAGS 00147 popfd 00148 00149 //detect 486/pentium+ 00150 pushfd //get EFLAGS 00151 pop eax 00152 mov ecx, eax 00153 xor eax, 200000h //toggle ID bit in EFLAGS 00154 push eax //save new EFLAGS value on stack 00155 popfd //replace current EFLAGS value 00156 pushfd //get new EFLAGS 00157 pop eax //store new EFLAGS in EAX 00158 xor eax, ecx //can not toggle ID bit, 00159 mov CPUnum, 486 00160 jz end_detect //processor=80486 00161 mov CPUnum, 586 //586+ 00162 00163 mov have_cpuid, 1 //we have cpuid 00164 00165 //check number of cpuid instructions 00166 mov eax, 0 00167 cpuid 00168 mov maxEax, eax //save the maximum eax for cpuid 00169 00170 //save MFT string 00171 mov esi, procName 00172 mov [esi+0], ebx 00173 mov [esi+4], edx 00174 mov [esi+8], ecx 00175 mov [esi+12], 0 00176 00177 test maxEax, 1 00178 jz end_detect 00179 00180 //get flagstring 00181 mov eax, 1 00182 cpuid 00183 mov capFlags, edx 00184 00185 end_detect: 00186 00187 pop esi 00188 pop ebx 00189 pop eax 00190 } 00191 #elif defined(CS_COMPILER_GCC) 00192 __asm__( 00193 //detect 386/486 00194 " pushfl \n" 00195 " popl %%eax \n" //get EFLAGS 00196 " movl %%eax, %%ebx \n" //save original EFLAGS 00197 " xorl $0x40000, %%eax \n" //toggle AC bit 00198 " pushl %%eax \n" //copy to stack 00199 " popfl \n" //copy to EFLAGS 00200 " pushfl \n" 00201 " popl %%eax \n" //get EFLAGS again 00202 " xorl %%ebx, %%eax \n" //check AC bit 00203 " movl $386,%0 \n" //386 00204 " je 1f \n" //is a 386, stop detection 00205 " pushl %%ebx \n" //restore EFLAGS 00206 " popfl \n" 00207 //detect 486/pentium+ 00208 " pushfl \n" //get EFLAGS 00209 " popl %%eax \n" 00210 " movl %%eax, %%ecx \n" 00211 " xorl $0x200000,%%eax \n" //toggle ID bit in EFLAGS 00212 " pushl %%eax \n" //save new EFLAGS value on stack 00213 " popfl \n" //replace current EFLAGS value 00214 " pushfl \n" //get new EFLAGS 00215 " popl %%eax \n" //store new EFLAGS in EAX 00216 " xorl %%eax, %%ecx \n" //can not toggle ID bit, 00217 " movl $486,%0 \n" 00218 " jz 1f \n" //processor=80486 00219 " movl $586,%0 \n" //586+ 00220 " movl $1,%1 \n" //we have cpuid 00221 //check number of cpuid instructions 00222 " xorl %%eax,%%eax \n" // thebolt: this was a movl $0,%eax 00223 " cpuid \n" 00224 " movl %%eax,%2 \n" //save the maximum eax for cpuid 00225 //save MFT string 00226 " movl %4,%%esi \n" 00227 " movl %%ebx,0(%%esi) \n" 00228 " movl %%edx,4(%%esi) \n" 00229 " movl %%ecx,8(%%esi) \n" 00230 " movl $0,12(%%esi) \n" 00231 " testl $1,%2 \n" 00232 " jz 1f \n" 00233 //get flagstring 00234 " movl $1,%%eax \n" 00235 " cpuid \n" 00236 " movl %%edx,%3 \n" 00237 "1: \n" 00238 : "=g" (CPUnum), "=g" (have_cpuid), "=g" (maxEax), "=g" (capFlags) 00239 : "g" (procName), "2" (maxEax) 00240 : "eax", "ebx", "ecx", "edx", "esi"); 00241 00242 #endif //CS_COMPILER_MSVC/GCC 00243 mmxSupported = (capFlags & (1<<23)) != 0; 00244 sseSupported = (capFlags & (1<<25)) != 0; 00245 //AMD3dnowSupported = capFlags & (1<<31); 00246 } 00247 #else //CS_PROCESSOR_X86 00248 static inline void CheckX86Processor() {} 00249 #endif //CS_PROCESSOR_X86 00250 }; 00251 00252 #include "csutil/deprecated_warn_on.h" 00253 00254 #endif //__CS_PROCESSORCAP_H__
Generated for Crystal Space 1.4.1 by doxygen 1.7.1