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 + -
显示快捷键?