Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

detect_3dnow.cpp

Go to the documentation of this file.
00001 
00002 #include "Core/precomp.h"
00003 #include "API/Core/System/system.h"
00004 #include "API/Core/System/cl_assert.h"
00005 
00006 static bool do_3dnow_test();
00007 
00008 bool CL_System::detect_3dnow()
00009 {
00010         static bool has_3dnow = false;
00011         static bool first_time = true;
00012         
00013         if (first_time)
00014         {
00015                 first_time = false;
00016                 has_3dnow = do_3dnow_test();
00017         }
00018         
00019         return has_3dnow;
00020 }
00021 
00022 static bool do_3dnow_test()
00023 {
00024 #ifdef USE_I386_ASSEMBLER
00025 #ifdef __MSC__
00026         unsigned long RegEDX = 0;
00027         unsigned long RegEAX = 0;
00028 
00029         try 
00030         {
00031                 _asm
00032                 {
00033                         mov             eax, 0x80000000         // set up CPUID to return processor extended functions
00034                         CPUID                                           // code bytes = 0fh,  0a2h
00035                         mov             RegEAX, eax
00036                 }
00037 
00038                 if (!(RegEAX & 0x80000000))             // no functions > 0x80000000 ?
00039                         return false;                           //we don't have any extended features, quit
00040                 else
00041                         _asm
00042                         {
00043                                 mov     eax, 0x80000001         // CPUID ext. function 0x80000001
00044                                 CPUID                       // EDX contains extended feature flags
00045                                 mov             RegEDX, edx                     // extended features returned in edx
00046                         }
00047 
00048         }
00049         catch(...)                                      // catch everything
00050         {
00051                 return false;
00052         }
00053 
00054         if (RegEDX & 0x80000000)        // bit 31 indicates presence of 3DNow! technology
00055         {
00056                 try
00057                 {
00058                         //DB 0Fh, 0Eh                   // try executing the 3DNow! instruction "femms"
00059                         _asm _emit 0x0f;
00060                         _asm _emit 0x0e;
00061                 }
00062                 catch(...) { return false; }
00063         }
00064         else
00065                 return false;
00066 
00067         return true;
00068 #elif __BORLANDC__
00069 
00070 //This is for detecting assembly when using the Borland compilers
00071 //If you do not have TASM then this will not compile
00072 //If you do have TASM then uncomment the code below, otherwise ignore it
00073 
00074         #ifdef USE_TASM
00075         int RegEDX=0,RegEAX=0;
00076   try
00077   {
00078         asm
00079     {
00080         mov             eax, 0x80000000         // set up CPUID to return processor extended functions
00081         CPUID                                           // code bytes = 0fh,  0a2h
00082         mov             RegEAX, eax
00083     }
00084   }
00085   catch(...) { return false; }
00086 
00087   if(RegEAX > 0x80000000)
00088   {
00089         asm
00090     {
00091                         mov     eax, 0x80000001         // CPUID ext. function 0x80000001
00092         CPUID                       // EDX contains extended feature flags
00093         mov             RegEDX, edx                     // extended features returned in edx
00094     }
00095   }
00096   else
00097         return false;
00098 
00099   if( RegEDX & 0x80000000)
00100   {
00101         try
00102                 {
00103                         //DB 0Fh, 0Eh                   // try executing the 3DNow! instruction "femms"
00104       __emit__(0x0f,0x0e);
00105                 }
00106                 catch(...) { return false; }
00107   }
00108   return true;
00109   #else
00110 
00111         std::cout<<"3DNow not supported by this version of library.  Please check source(detect_3dnow.cpp)."<<std::endl;
00112   return false;
00113         #endif
00114 #elif __GNUC__
00115 
00116         unsigned int RegEDX=0,RegEAX=0;
00117         try
00118         {
00119                 asm(
00120                 "mov 0x80000000, %%eax \n" //Get ready for extended functions
00121                 "CPUID \n" //Access CPUID
00122                 : "=a"(RegEAX));
00123         }
00124         catch(...) 
00125         {
00126                 return false;
00127         }
00128         if(RegEDX > 0x80000000) 
00129         {
00130                 asm(
00131                                 "mov 0x80000001, %%eax \n" //Access extended features
00132                                 "CPUID \n"  //Query CPU
00133                                 : "=d"(RegEDX));
00134         }
00135         else 
00136         {
00137                 return false;
00138         }
00139 
00140         if(!(RegEDX & 0x80000000))
00141         {
00142                 return false;
00143         }
00144         try
00145         {
00146                 asm("femms");
00147         }
00148         catch(...)
00149         {
00150                 return false;
00151         }
00152         return true;
00153 
00154 #endif
00155 #else
00156         static bool warning = true;
00157         if (warning)
00158         {
00159                 cl_info(0, "CL_System::detect_3dnow() not implemented under unix yet.");
00160                 warning = false;
00161         }
00162         return false;
00163 #endif //Endif USE_I386_ASSEMBLER
00164 }

Generated at Wed Apr 4 19:53:59 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001