From: Man. on 5 Apr 2010 23:39 #include "cpuid.os" // These are the bit flags set call cpuid // with register eax set to 1 #define _MMX_FEATURE_BIT 0x00800000 #define _SSE_FEATURE_BIT 0x02000000 #define _SSE2_FEATURE_BIT 0x04000000 // This bit is set when cpuid is called with // register set to 80000001h (only applicable to AMD) #define _3DNOW_FEATURE_BIT 0x80000000 int IsCPUID() { __try { _asm { xor eax, eax cpuid } } __except ( EXCEPTION_EXECUTE_HANDLER) { return 0; } return 1; } /*** * int _os_support(int feature) * - Checks if OS Supports the capablity or not * * Entry: * feature: the feature we want to check if OS supports it. * * Exit: * Returns 1 if OS support exist and 0 when OS doesn't support it. * ****************************************************************/ int _os_support(int feature) { __try { switch (feature) { case _CPU_FEATURE_SSE: __asm { xorps xmm0, xmm0 // __asm _emit 0x0f __asm _emit 0x57 __asm _emit 0xc0 // executing SSE instruction } break; case _CPU_FEATURE_SSE2: __asm { __asm _emit 0x66 __asm _emit 0x0f __asm _emit 0x57 __asm _emit 0xc0 // xorpd xmm0, xmm0 // executing WNI instruction } break; case _CPU_FEATURE_3DNOW: __asm { __asm _emit 0x0f __asm _emit 0x0f __asm _emit 0xc0 __asm _emit 0x96 // pfrcp mm0, mm0 // executing 3Dnow instruction } break; case _CPU_FEATURE_MMX: __asm { pxor mm0, mm0 // executing MMX instruction } break; } } __except (EXCEPTION_EXECUTE_HANDLER) { if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION) { return (0); } return (0); } return 1; } /*** * * void map_mname(int, int, const char *, char *) maps family and model to processor name * ****************************************************/ void map_mname( int family, int model, const char * v_name, char *m_name) { if (!strncmp("AuthenticAMD", v_name, 12)) { switch (family) // extract family code { case 4: // Am486/AM5x86 strcpy (m_name,"AMD Am486"); break; case 5: // K6 switch (model) // extract model code { case 0: case 1: case 2: case 3: strcpy (m_name,"AMD K5"); break; case 4: break; // may be assinged to more efficient processor code case 5: break; // may be assigned to more efficient processor code case 6: case 7: strcpy (m_name,"AMD K6"); break; case 8: strcpy (m_name,"AMD K6-2"); break; case 9: case 10: case 11: case 12: case 13: case 14: case 15: strcpy (m_name,"AMD K6-3"); break; default: strcpy (m_name, "MEAMI MXM"); } break; case 6: // Athlon switch(model) // Define current mode and model numbers { case 1: default: strcpy (m_name,"AMD ATHLON"); } break; } } else if ( !strncmp("GenuineIntel", v_name, 12)) { switch (family) // extract family code { case 4: switch (model) // extract model code { case 0: case 1: strcpy (m_name,"INTEL 486DX"); break; case 2: strcpy (m_name,"INTEL 486SX"); break; case 3: strcpy (m_name,"INTEL 486DX2"); break; case 4: strcpy (m_name,"INTEL 486SL"); break; case 5: strcpy (m_name,"INTEL 486SX2"); break; case 7: strcpy (m_name,"INTEL 486DX2E"); break; case 8: strcpy (m_name,"INTEL 486DX4"); break; default: strcpy (m_name, "MEAMI MXM"); } break; case 5: switch (model) // extract model code { case 1: case 2: case 3: strcpy (m_name,"INTEL Pentium"); break; case 4: strcpy (m_name,"INTEL Pentium-MMX"); break; default: strcpy (m_name, "MEAMI MXM"); } break; case 6: switch (model) // extract model code { case 1: strcpy (m_name,"INTEL Pentium-Pro"); break; case 3: strcpy (m_name,"INTEL Pentium-II"); break; case 5: strcpy (m_name,"INTEL Pentium-II"); break; // actual differentiation depends on cache settings case 6: strcpy (m_name,"INTEL Celeron"); break; case 7: strcpy (m_name,"INTEL Pentium-III"); break; // actual differentiation depends on cache settings default: strcpy (m_name, "MEAMI MXM"); } break; } } else if ( !strncmp("CyrixInstead", v_name,12)) { strcpy (m_name,"MEAMI MXM"); } else if ( !strncmp("CentaurHauls", v_name,12)) { strcpy (m_name,"MEAMI MXM"); } else { strcpy (m_name, "MEAMI MXM"); } } /*** * * int _cpuid (_p_info *pinfo) * * Entry: * * pinfo: pointer to _p_info. * * Exit: * * Returns int with capablity bit set even if pinfo = NULL * ****************************************************/ int _cpuid (_p_info *pinfo) { DWORD dwStandard = 0; DWORD dwFeature = 0; DWORD dwMax = 0; DWORD dwExt = 0; int feature = 0, os_support = 0; union { char cBuf[12+1]; struct { DWORD dw0; DWORD dw1; DWORD dw2; }; } Ident; if (!IsCPUID()) { return 0; } _asm { push ebx push ecx push edx // get the vendor string xor eax,eax cpuid mov dwMax,eax mov Ident.dw0,ebx mov Ident.dw1,edx mov Ident.dw2,ecx // get the Standard bits mov eax,1 cpuid mov dwStandard,eax mov dwFeature,edx // get AMD-specials mov eax,80000000h cpuid cmp eax,80000000h jc notamd mov eax,80000001h cpuid mov dwExt,edx notamd: pop ecx pop ebx pop edx } if (dwFeature & _MMX_FEATURE_BIT) { feature |= _CPU_FEATURE_MMX; if (_os_support(_CPU_FEATURE_MMX)) os_support |= _CPU_FEATURE_MMX; } if (dwExt & _3DNOW_FEATURE_BIT) { feature |= _CPU_FEATURE_3DNOW; if (_os_support(_CPU_FEATURE_3DNOW)) os_support |= _CPU_FEATURE_3DNOW; } if (dwFeature & _SSE_FEATURE_BIT) { feature |= _CPU_FEATURE_SSE; if (_os_support(_CPU_FEATURE_SSE)) os_support |= _CPU_FEATURE_SSE; } if (dwFeature & _SSE2_FEATURE_BIT) { feature |= _CPU_FEATURE_SSE2; if (_os_support(_CPU_FEATURE_SSE2)) os_support |= _CPU_FEATURE_SSE2; } if (pinfo) { memset(pinfo, 0, sizeof(_p_info)); pinfo->os_support = os_support; pinfo->feature = feature; pinfo->family = (dwStandard >> 8)&0xF; // retrieving family pinfo->model = (dwStandard >> 4)&0xF; // retrieving model pinfo->stepping = (dwStandard) & 0xF; // retrieving stepping Ident.cBuf[12] = 0; strcpy(pinfo->v_name, Ident.cBuf); map_mname(pinfo->family, pinfo->model, pinfo->v_name, pinfo- >model_name); pinfo->checks = _CPU_FEATURE_MMX | _CPU_FEATURE_SSE | _CPU_FEATURE_SSE2 | _CPU_FEATURE_3DNOW; } return feature; }
From: none on 6 Apr 2010 02:57 Man. wrote: > #include "cpuid.os" [snip] > return feature; > } Cool story, bro.
|
Pages: 1 Prev: The trim function and its intented purpose? Next: Faster image rotation |