サポートしているSIMD拡張を調べるプログラム

Intel AVX について勉強しているが、使っているCPUがどのSIMD拡張をサポートしているのかを知りたくなった。なので色々調べてインラインアセンブラを使ったコードを書いてみた。Sandy Bridge (Core i7 2600K)でAVXが使えることは確認できた。

// sup_ext.c
#include <stdio.h>

int main()
{
    int REG_edx, REG_ecx, REG_eax=-1;
    __asm__("mov eax, 1\n\t"
            "cpuid\n\t"
            "mov %0, edx\n\t"
            "mov %1, ecx\n\t"
            : "=r" (REG_edx), "=r" (REG_ecx)
           );
    if(REG_edx && 0x800000) printf("MMX ");         // EDX bit 23
    if(REG_edx && 0x2000000) printf("SSE ");        // EDX bit 25
    if(REG_edx && 0x4000000) printf("SSE2 ");       // EDX bit 26
    if(REG_ecx && 0x00000001) printf("SSE3 ");      // ECX bit 0
    if(REG_ecx && 0x00000200) printf("SSSE3 ");     // ECX bit 9
    if(REG_ecx && 0x00080000) printf("SSE4.1 ");    // ECX bit 19
    if(REG_ecx && 0x00100000) printf("SSE4.2 ");    // ECX bit 20
    if(REG_ecx && 0x00200000) printf("AESNI ");     // ECX bit 25
    if(REG_ecx && 0x00000002) printf("PCLMULQDQ "); // ECX bit 1

    __asm__("mov eax, 1\n\t"
            "cpuid\n\t"
            "and ecx, 402653184\n\t" // 0x01800000 = 402653184
            "cmp ecx, 402653184\n\t"
            "jne not_supported\n\t"
            "mov ecx, 0\n\t"
            "xgetbv\n\t"
            "and eax, 6\n\t"
            "cmp eax, 6\n\t"
            "mov %0, eax\n"
            "not_supported:\n\t"
            : "=r" (REG_eax)
           );
    if (REG_eax == 0x6)
        printf("AVX "); // EAX bit 1&2
    printf("\n");

    return 0;
}
コンパイル・コマンド

gcc -masm=intel sup_ext.c