//-------------------------------------------------------------------------- // Rob Wyatt for Game Developer/Gamasutra April 1999 //-------------------------------------------------------------------------- #include "Windows.h" #include "Detect.h" #include "KNI.h" //-------------------------------------------------------------------------- CDetect::CDetect ( ) : SIMDPresent(false),OSSupport(false),OSExceptions(false),DetectStatus(true), SerialPresent(false) //--------------------------- { // // First detect the presence of the new SIMD instructions // __try { SIMDPresent = DetectFeatureBit(25); } __except(EXCEPTION_EXECUTE_HANDLER) { DetectStatus = false; } // We do not have SIMD so there is no point in continuing. if (!SIMDPresent) return; // // Check for OS support // __try { _asm { //Execute a Streaming SIMD instruction and see if an //exception occurs. If the exception is an unknown //op-code then SIMD is not supported by the OS. ADDPS(_XMM0,_XMM1) } OSSupport = true; } __except(EXCEPTION_EXECUTE_HANDLER) { if (_exception_code() != STATUS_ILLEGAL_INSTRUCTION) { DetectStatus = false; } } // // Detect the exception support // OSExceptions = DetectExceptionSupport(); // // Check if a serial number is present // __try { SerialPresent = DetectFeatureBit(18); } __except(EXCEPTION_EXECUTE_HANDLER) { DetectStatus = false; } // // Now if the serial number bit is set then try to read it // but trap any possible exceptions just in case // if (SerialPresent) { __try { ReadSerialNumber(SerialNumber); } __except(EXCEPTION_EXECUTE_HANDLER) { DetectStatus = false; SerialPresent = false; } } } //-------------------------------------------------------------------------- bool CDetect::DetectExceptionSupport ( ) //--------------------------- { bool exception_support = true; float test_val[4] = {1.0f, 1.0f, 1.0f, 1.0f}; DWORD control; DWORD control_original; __try { _asm { // Enable divide by zero exceptions by clearing // bit 9 in the SIMD control register. push ebp lea ebp,control STMXCSR mov eax, DWORD PTR [ebp] and DWORD PTR [ebp], 0fffffdffh LDMXCSR pop ebp mov control_original, eax // clear XMM0, all bits being 0 is 0.0 in floating point lea eax,test_val XORPS (_XMM0,_XMM0) MOVUPS (_XMM1,EAX_PTR) DIVPS (_XMM1,_XMM0) } } __except(EXCEPTION_EXECUTE_HANDLER) { // The divide by zero above has caused an illegal instruction // exception so the OS must not support SIMD exceptions. if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION) { exception_support = false; } } // // Put the original SIMD register back // _asm { push ebp lea ebp,control_original LDMXCSR pop ebp } return exception_support; } //-------------------------------------------------------------------------- bool CDetect::DetectFeatureBit ( DWORD bit ) //--------------------------- { bool found; DWORD test_bit = 1<