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
00034 CPUID
00035 mov RegEAX, eax
00036 }
00037
00038 if (!(RegEAX & 0x80000000))
00039 return false;
00040 else
00041 _asm
00042 {
00043 mov eax, 0x80000001
00044 CPUID
00045 mov RegEDX, edx
00046 }
00047
00048 }
00049 catch(...)
00050 {
00051 return false;
00052 }
00053
00054 if (RegEDX & 0x80000000)
00055 {
00056 try
00057 {
00058
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
00071
00072
00073
00074 #ifdef USE_TASM
00075 int RegEDX=0,RegEAX=0;
00076 try
00077 {
00078 asm
00079 {
00080 mov eax, 0x80000000
00081 CPUID
00082 mov RegEAX, eax
00083 }
00084 }
00085 catch(...) { return false; }
00086
00087 if(RegEAX > 0x80000000)
00088 {
00089 asm
00090 {
00091 mov eax, 0x80000001
00092 CPUID
00093 mov RegEDX, edx
00094 }
00095 }
00096 else
00097 return false;
00098
00099 if( RegEDX & 0x80000000)
00100 {
00101 try
00102 {
00103
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"
00121 "CPUID \n"
00122 : "=a"(RegEAX));
00123 }
00124 catch(...)
00125 {
00126 return false;
00127 }
00128 if(RegEDX > 0x80000000)
00129 {
00130 asm(
00131 "mov 0x80000001, %%eax \n"
00132 "CPUID \n"
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 }