cpu.cpp

来自「H.263的编码程序,加了CPU指令优化,VC版.」· C++ 代码 · 共 165 行

CPP
165
字号
#include "cpu.h"
#include <excpt.h>
#include <string.h>

//;***************************************************************************/
//;*                  Copyright (c) 1998 Intel Corporation.
//;*                         All rights reserved.
//;***************************************************************************/
//;*
//;* cpu.cpp
//;*
//;* This program checks for a system's support of Streaming SIMD Extensions
//;* technology.  
//;* 
//;***************************************************************************/

#define CPUF_SUPPORTS_MMX			(0x00800000L)
#define CPUF_SUPPORTS_INTEGER_SSE	(0x02000000L)
#define CPUF_SUPPORTS_SSE2			(0x04000000L)

long lEnableFlags;
// Checking for Streaming SIMD Extensions support in the processor.


bool SIMD_fp_HWSupport()
{
	bool HWSupport = false;
	char brand[12];
	unsigned *str = (unsigned *) brand;
	__try 
	{
		_asm
		{
			mov		eax, 0			//First, check to make sure this is an Intel processor
			cpuid					//by getting the processor information string with CPUID
			mov	    str, ebx		//  ebx contains "Genu"
			mov     str+4, edx		//  edx contains "ineI"
			mov		str+8, ecx		//  ecx contains "ntel"  -- "GenuineIntel"
		}
	}
    __except(EXCEPTION_EXECUTE_HANDLER) 
	{
		if (_exception_code() == 0xc000001d) //STATUS_ILLEGAL_INSTRUCTION
		{
//			AfxMessageBox("****CPUID is not enabled****");
			return (false);
		}
		return (false); // If we get here, an unexpected exception occurred.
	}

	// Now make sure the processor is "GenuineIntel".
	if (!strncmp(brand, "GenuineIntel", 12)) 
	{
//	    AfxMessageBox("****This is not an Intel processor!****");
		return (false);
	}
	
	// And finally, check the CPUID for Streaming SIMD Extensions support.
	_asm
	{
		mov		eax, 1			// Put a "1" in eax to tell CPUID to get the feature bits
		cpuid					// Perform CPUID (puts processor feature info into EDX)
        mov lEnableFlags,edx
	/*	test	edx, 04000000h	// Test bit 25, for Streaming SIMD Extensions existence.
		jz		NotFound		// If not set, jump over the next instruction (No Streaming
		mov		[HWSupport],1	// SIMD Extensions).  Set return value to 1 to indicate,
								// that the processor does support Streaming SIMD Extensions.
	NotFound:				
	*/
	}
	
	return (true);
}	



bool SIMD_fp_OSSupport()
{
	__try
	{
		_asm  xorps xmm0, xmm0  //Execute a Streaming SIMD Extensions
								//to see if support exists.
	}
    __except(EXCEPTION_EXECUTE_HANDLER) 
	{
		unsigned long code = _exception_code();
		if (code ==  0xc000001d) //STATUS_ILLEGAL_INSTRUCTION 
		{
//		    AfxMessageBox("****OS does not support fxsave/fxrstor!****");
			return (false);
		}
		// If we get here, something else happened on your system.
//		AfxMessageBox("Something else is wrong!!!");
		return (false);
	}
	return (true);
}

bool SIMD_fp_OSException()
{
	bool SIMD_fp_OSExcept = true;
	unsigned long csr;
	float x[4] = {1.0f, 2.0f, 3.0f, 4.0f};

	__try
	{
		_asm{
			stmxcsr [csr]		//Get the MXCSR (Streaming SIMD Extensions control register)
			and     [csr], 0FFFFFDFFh // Set the divide-by-zero mask bit (bit 9) to 0 to 
			ldmxcsr [csr]		// unmask this exception, then reload the MXCSR.

			xorps   xmm0, xmm0	//Fill the denominator register with 0's
			movups  xmm1,[x]	//Do a divide by zero using Streaming SIMD Extensions
			divps	xmm1, xmm0	//  packed divide. The interrupt handler should be invoked.
		}
	}
	//
	// Catch any exception that occurs. The exception handler here needs to take different
	// actions depending on the OS.  If you have determined that your processor and OS
	// indeed support Streaming SIMD Extensions technology, an ILLEGAL_INSTRUCTION exception
	// indicates that unmasked Streaming SIMD Extensions exceptions are not supported.
	//
    __except(EXCEPTION_EXECUTE_HANDLER) 
	{
		unsigned long code = _exception_code();
		if (code ==  0xc000001d) //STATUS_ILLEGAL_INSTRUCTION
		{
//			AfxMessageBox("****OS did not handle the exception!****");
			SIMD_fp_OSExcept = false;
		}
		else 
		{ 
		//	cout << endl << "****OS handled the exception.****" << endl;
			SIMD_fp_OSExcept = true;
		    // But you would need to have special handling code here to decipher what
			// exception really occurred and why!
		}   
	}
	return (SIMD_fp_OSExcept);
}

int cputest()
{
	int InstructionFlags;
    
	SIMD_fp_HWSupport();
	if(!!(lEnableFlags & CPUF_SUPPORTS_MMX))
		InstructionFlags=1;       //MMX
	if(!!(lEnableFlags & CPUF_SUPPORTS_INTEGER_SSE))
	{
		if(SIMD_fp_OSSupport())
			if(SIMD_fp_OSException())
				InstructionFlags=2;       //SSE
	}
	if(!!(lEnableFlags & CPUF_SUPPORTS_SSE2))
	{
		if(SIMD_fp_OSSupport())
			if(SIMD_fp_OSException())
				InstructionFlags=3;       //SSE2
	}
//	InstructionFlags=2;
	return InstructionFlags;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?