# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

cpu_info.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "stdmisc.h"
00027 
00028 #include "nel/misc/cpu_info.h"
00029 
00030 
00031 namespace NLMISC 
00032 {
00033 
00034 static bool DetectMMX(void)
00035 {               
00036         #ifdef NL_OS_WINDOWS            
00037                 if (!CCpuInfo___::hasCPUID()) return false; // cpuid not supported ...
00038 
00039                 uint32 result = 0;
00040                 __asm
00041                 {
00042                          mov  eax,1
00043                          cpuid
00044                          test edx,0x800000  // bit 23 = MMX instruction set
00045                          je   noMMX
00046                          mov result, 1  
00047                         noMMX:
00048                 }
00049 
00050                 return result == 1;
00051  
00052                 // printf("mmx detected\n");
00053 
00054         #else
00055                 return false;
00056         #endif
00057 }
00058 
00059 
00060 static bool DetectSSE(void)
00061 {       
00062         #ifdef NL_OS_WINDOWS
00063                 if (!CCpuInfo___::hasCPUID()) return false; // cpuid not supported ...
00064 
00065                 uint32 result = 0;
00066                 __asm
00067                 {                       
00068                         mov eax, 1   // request for feature flags
00069                         cpuid                                                   
00070                         test EDX, 002000000h   // bit 25 in feature flags equal to 1
00071                         je noSSE
00072                         mov result, 1  // sse detected
00073                 noSSE:
00074                 }
00075 
00076 
00077                 if (result)
00078                 {
00079                         // check OS support for SSE
00080                         try 
00081                         {
00082                                 __asm
00083                                 {
00084                                         xorps xmm0, xmm0  // Streaming SIMD Extension
00085                                 }
00086                         }
00087                         catch(...)
00088                         {
00089                                 return false;
00090                         }
00091                 
00092                         // printf("sse detected\n");
00093 
00094                         return true;
00095                 }
00096                 else
00097                 {
00098                         return false;
00099                 }
00100         #else
00101                 return false;
00102         #endif
00103 }
00104 
00105 bool HasMMX = DetectMMX();
00106 bool HasSSE = DetectSSE();
00107 
00108 bool CCpuInfo___::hasCPUID(void)
00109 {
00110         #ifdef NL_OS_WINDOWS
00111                  uint32 result;
00112                  __asm
00113                  {
00114                          pushad
00115                          pushfd                                         
00116                          //      If ID bit of EFLAGS can change, then cpuid is available
00117                          pushfd
00118                          pop  eax                                       // Get EFLAG
00119                          mov  ecx,eax
00120                          xor  eax,0x200000                      // Flip ID bit
00121                          push eax
00122                          popfd                                          // Write EFLAGS
00123                          pushfd      
00124                          pop  eax                                       // read back EFLAG
00125                          xor  eax,ecx                           
00126                          je   noCpuid                           // no flip -> no CPUID instr.
00127                          
00128                          popfd                                          // restore state
00129                          popad
00130                          mov  result, 1
00131                          jmp  CPUIDPresent
00132                 
00133                         noCpuid:
00134                          popfd                                      // restore state
00135                          popad
00136                          mov result, 0
00137                         CPUIDPresent:    
00138                  }
00139                  return result == 1;
00140         #else
00141                  return false;
00142         #endif
00143 }
00144 bool CCpuInfo___::hasMMX(void) { return HasMMX; }
00145 bool CCpuInfo___::hasSSE(void) { return HasSSE; }
00146 
00147 } // NLMISC