cpu support code

类别:编程语言 点击:0 评论:0 推荐:

#ifndef CPU_SUPPORT_H
#define CPU_SUPPORT_H

#define CPU_SUPPORTS_CPUID       (0x00000001L)
#define CPU_SUPPORTS_FPU            (0x00000002L)
#define CPU_SUPPORTS_MMX            (0x00000004L)
#define CPU_SUPPORTS_INTEGER_SSE    (0x00000008L)
#define CPU_SUPPORTS_SSE            (0x00000010L)
#define CPU_SUPPORTS_SSE2           (0x00000020L)
#define CPU_SUPPORTS_3DNOW          (0x00000040L)
#define CPU_SUPPORTS_3DNOW_EXT      (0x00000080L)

long CPUGetSupportedExtensions();

#endif

--------------------------------------------------------------------------------------------------------------
#include <wtypes.h>
#include <winnt.h>
#include "cpusupport.h"

static long g_lCPUExtensionsAvailable;

// This is ridiculous ???

static long CPUCheckForSSESupport() {
 __try
  {
//  __asm andps xmm0,xmm0

  __asm _emit 0x0f
  __asm _emit 0x54
  __asm _emit 0xc0

 }
  __except(EXCEPTION_EXECUTE_HANDLER)
  {
    // The operating system does not recognize andps. Reset them.
  if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
   g_lCPUExtensionsAvailable &= ~(CPU_SUPPORTS_SSE|CPU_SUPPORTS_SSE2);
 }

 return g_lCPUExtensionsAvailable;
}

long __declspec(naked) CPUGetSupportedExtensions() {
 __asm {
  push ebp
  push edi
  push esi
  push ebx

  xor  ebp,ebp   ;cpu flags - if we don't have CPUID, we probably
              ;won't want to try FPU optimizations.

  ;check for CPUID.

  pushfd     ;flags -> EAX
  pop  eax
  or  eax,00200000h ;set the ID bit
  push eax    ;EAX -> flags
  popfd
  pushfd     ;flags -> EAX
  pop  eax
  and  eax,00200000h ;ID bit set?
  jz  done   ;nope...

  ;CPUID exists, check for features register.

  mov  ebp,00000003h
  xor  eax,eax
  cpuid
  or  eax,eax
  jz  done   ;no features register?!?

  ;features register exists, look for MMX, SSE, SSE2.

  mov  eax,1
  cpuid
  mov  ebx,edx
  and  ebx,00800000h ;MMX is bit 23
  shr  ebx,21
  or  ebp,ebx   ;set bit 2 if MMX exists

  mov  ebx,edx
  and  edx,02000000h ;SSE is bit 25
  shr  edx,25
  neg  edx
  and  edx,00000018h ;set bits 3 and 4 if SSE exists
  or  ebp,edx

  and  ebx,04000000h ;SSE2 is bit 26
  shr  ebx,21
  and  ebx,00000020h ;set bit 5
  or  ebp,ebx

  ;check for vendor feature register (K6/Athlon).

  mov  eax,80000000h
  cpuid
  mov  ecx,80000001h
  cmp  eax,ecx
  jb  done

  ;vendor feature register exists, look for 3DNow! and Athlon extensions

  mov  eax,ecx
  cpuid

  mov  eax,edx
  and  edx,80000000h ;3DNow! is bit 31
  shr  edx,25
  or  ebp,edx   ;set bit 6

  mov  edx,eax
  and  eax,40000000h ;3DNow!2 is bit 30
  shr  eax,23
  or  ebp,eax   ;set bit 7

  and  edx,00400000h ;AMD MMX extensions (integer SSE) is bit 22
  shr  edx,19
  or  ebp,edx

done:
  mov  eax,ebp
  mov  g_lCPUExtensionsAvailable, ebp

  ;Full SSE and SSE-2 require OS support for the xmm* registers.

  test eax,00000030h
  jz  nocheck
  call CPUCheckForSSESupport
nocheck:
  pop  ebx
  pop  esi
  pop  edi
  pop  ebp
  ret
 }
}

本文地址:http://com.8s8s.com/it/it24401.htm