CPUID命令を使用して、SSEに対応しているか調べるコード

Posted on Sat 12 September 2009 in Windows

VC++のインラインアセンブラからCPUID命令を使用してSSEに対応しているか調べるコードを書きました。

CPUID命令

EAXレジスタに値を入れてCPUID命令を呼び出すと、
各レジスタにCPUの情報が格納されます。

  • EAX=0 ベンダIDの取得
  • EAX=1 プロセッサ情報とプロセッサの機能
  • EAX=2 キャッシュとTLBディスクリプタ情報
  • EAX=3 プロッセッサ・シリアル・ナンバ
  • EAX=80000000h サポートする最大拡張機能番号の取得
  • EAX=80000001h 拡張プロセッサ情報とプロセッサの機能
  • EAX=80000002h,80000003h,80000004h プロセッサブランド文字列
  • EAX=80000006h 拡張L2キャッシュ情報
  • EAX=80000008h 仮想アドレスと物理アドレスのサイズ

今回はSSEに対応しているか調べたいのでEAXには、1を入れてCPUID命令を呼び出します。

http://www.sandpile.org/ia32/cpuid.htm
↑のページによると,
先頭をbit0として、以下のように対応情報が格納され、
対応している場合は1が格納される。

  • EDX bit23 MMX
  • EDX bit25 SSE
  • EDX bit26 SSE2
  • ECX bit0 SSE3
  • ECX bit19 SSE4.1
  • ECX bit20 SSE4.2

コード

#include <stdio.h>
#include <string.h>
int main(void)
{
    unsigned int output_ecx;
    unsigned int output_edx;
    __asm{
        mov     eax,    1;
        cpuid;
        mov     output_ecx, ecx;
        mov     output_edx, edx;
    }
    if(output_edx & 0x00800000){
        printf("support MMX\n");
    }
    if(output_edx & 0x02000000){
        printf("support SSE\n");
    }
    if(output_edx & 0x04000000){
        printf("support SSE2\n");
    }
    if(output_ecx & 0x00000001){
        printf("support SSE3\n");
    }
    if(output_ecx & 0x00080000){
        printf("support SSE4.1\n");
    }
    if(output_ecx & 0x00100000){
        printf("support SSE4.2\n");
    }
}

実行結果

Core2 Duo E8400での実行結果

support MMX
support SSE
support SSE2
support SSE3
support SSE4.1

(SSE4.2に対応してるのはCore i7かららしいです。)

Atom N280での実行結果

support MMX
support SSE
support SSE2
support SSE3

AtomSSE3まで対応らしいです。

参考URL

http://ja.wikipedia.org/wiki/CPUID
http://www.sandpile.org/ia32/cpuid.htm
http://w-farm.cocolog-nifty.com/blog/2009/02/sse42_-4a0a.html