00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CS_PROCESSORCAP_H__
00020 #define __CS_PROCESSORCAP_H__
00021
00022
00027 class csProcessorCapability
00028 {
00029 public:
00030
00034 csProcessorCapability ()
00035 {
00036 }
00037
00041 ~csProcessorCapability ()
00042 {
00043 }
00044
00048 static inline void Initialize ()
00049 {
00050 if (isInitialized)
00051 return;
00052
00053 #ifdef PROC_X86
00054 CheckX86Processor ();
00055 #else
00056 mmxSupported = false;
00057 sseSupported = false;
00058 #endif
00059 }
00060
00061 static inline bool HasMMX ()
00062 {
00063 Initialize ();
00064
00065 return mmxSupported;
00066 }
00067
00068 private:
00069
00071 static bool isInitialized;
00072
00074 static bool mmxSupported;
00075
00077 static bool sseSupported;
00078
00080 static bool AMD3dnowSupported;
00081
00082 #ifdef PROC_X86
00083
00087 static inline void csProcessorCapability::CheckX86Processor ()
00088 {
00089 int32 capFlags;
00090 int CPUnum;
00091 int maxEax = 0;
00092
00093 bool have_cpuid;
00094 char *processorName = new char [14];
00095
00096 #if defined(COMP_VC)
00097 __asm
00098 {
00099
00100 push eax
00101 push ebx
00102 push esi
00103
00104
00105 pushfd
00106 pop eax
00107 mov ebx, eax
00108 xor eax, 40000h
00109 push eax
00110 popfd
00111 pushfd
00112 pop eax
00113 xor eax, ebx
00114 mov CPUnum, 386
00115 je end_detect
00116 push ebx
00117 popfd
00118
00119
00120 pushfd
00121 pop eax
00122 mov ecx, eax
00123 xor eax, 200000h
00124 push eax
00125 popfd
00126 pushfd
00127 pop eax
00128 xor eax, ecx
00129 mov CPUnum, 486
00130 jz end_detect
00131 mov CPUnum, 586
00132
00133 mov have_cpuid, 1
00134
00135
00136 mov eax, 0
00137 cpuid
00138 mov maxEax, eax
00139
00140
00141 mov esi, processorName
00142 mov [esi+0], ebx
00143 mov [esi+4], edx
00144 mov [esi+8], ecx
00145 mov [esi+12], 0
00146
00147 test maxEax, 1
00148 jz end_detect
00149
00150
00151 mov eax, 1
00152 cpuid
00153 mov capFlags, edx
00154
00155 end_detect:
00156
00157 pop esi
00158 pop ebx
00159 pop eax
00160 }
00161 #elif defined(COMP_GCC)
00162 __asm__(
00163
00164 " pushfl \n"
00165 " popl %%eax \n"
00166 " movl %%eax, %%ebx \n"
00167 " xorl $0x40000, %%eax \n"
00168 " pushl %%eax \n"
00169 " popfl \n"
00170 " pushfl \n"
00171 " popl %%eax \n"
00172 " xorl %%ebx, %%eax \n"
00173 " movl $386,%0 \n"
00174 " je 1f \n"
00175 " pushl %%ebx \n"
00176 " popfl \n"
00177
00178 " pushfl \n"
00179 " popl %%eax \n"
00180 " movl %%eax, %%ecx \n"
00181 " xorl $0x200000,%%eax \n"
00182 " pushl %%eax \n"
00183 " popfl \n"
00184 " pushfl \n"
00185 " popl %%eax \n"
00186 " xorl %%eax, %%ecx \n"
00187 " movl $486,%0 \n"
00188 " jz 1f \n"
00189 " movl $586,%0 \n"
00190 " movl $1,%1 \n"
00191
00192 " xorl %%eax,%%eax \n"
00193 " cpuid \n"
00194 " movl %%eax,%2 \n"
00195
00196 " movl %4,%%esi \n"
00197 " movl %%ebx,0(%%esi) \n"
00198 " movl %%edx,4(%%esi) \n"
00199 " movl %%ecx,8(%%esi) \n"
00200 " movl $0,12(%%esi) \n"
00201 " testl $1,%2 \n"
00202 " jz 1f \n"
00203
00204 " movl $1,%%eax \n"
00205 " cpuid \n"
00206 " movl %%edx,%3 \n"
00207 "1: \n"
00208 : "=g" (CPUnum), "=g" (have_cpuid), "=g" (maxEax), "=g" (capFlags)
00209 : "g" (processorName), "2" (maxEax)
00210 : "eax", "ebx", "ecx", "edx", "esi");
00211
00212 #endif //COMP_
00213 mmxSupported = capFlags & (1<<23);
00214 sseSupported = capFlags & (1<<25);
00215
00216 }
00217 #else //PROC_X86
00218 void csProcessorCapability::CheckX86Processor () {}
00219 #endif //PROC_X86
00220
00221 };
00222
00223 #endif //__CS_PROCESSORCAP_H__