Features

kinzo 25.06.09 13:34

Testaa Streaming SIMD Extension tuen.

 Tekstiversio  Arvo: 4 (4 ääntä)  Äänestä: +  -
/*
Kinzo 2009

Ohjelman tarkoitus on demonstoida cpuid käskyä.
Ohjelma testaa prosessorin Streaming Simd tuen
ja tulostaa tuotetut sse versiot.
Ohjelma käyttää standardi c-kirjastoa.
Alusta on Linux x86-64.

Kääntää voit komennolla: gcc -o features features.s
*/
.section .data
str_cpuid:
        .string "CPUID support...   "
str_sse:
        .string "SSE support...     "
str_sse2:
        .string "SSE2 support...    "
str_sse3:
        .string "SSE3 support...    "
str_ssse3:
        .string "SSSE3 support...   "
str_sse41:
        .string "SSE4.1 support...  "
str_sse42:
        .string "SSE4.2 support...  "
str_yes:
        .string "YES!\n"
str_no:
        .string "NO!\n"
.section .text
.global main
.type main, @function
/*
 Palauttaa 0.
*/
main:
        pushq       %rbp
        movq        %rsp, %rbp
/*
        Tulostaa str_cpuid
*/
        xorq        %rax, %rax            /* %rax rekisterissä ilmoitetaan käytetyt %xmm rekisterit */
        movq        $str_cpuid, %rdi      /* Lisää infoa funktioiden kutsumisesta x86-64 Linuxilla */
        call        printf                /* vaikkapa: http://www.cs.cmu.edu/~fp/courses/15213-s06/misc/asm64-handout.pdf */
/*
        Testaa CPUID tuki ja tulosta vastaus.
        jos ei tukea poistu.
*/
        pushfq                            /* Tallenna liput- */
        popq        %rax                  /* akkuun. */
        xorq        $0x200000, %rax       /* Pakotetaan bitti 21 */
        pushq       %rax                  /* Ladataan muunneltu rFLAG- */
        popfq                             /* takaisin. */
        pushfq
        testq       $0x200000, (%rsp)     /* Jos bitti 21 on alhaalla- */
        jnz         CPUIDYES              /* ei cpu tue CPUID käskyä. */
        call        no                    /* Sinulla on siis onneton suoritin. */
        jmp         EXIT
CPUIDYES:
        call        yes
/*
        Tulosta str_sse.
*/
        xorq        %rax, %rax
        movq        $str_sse, %rdi
        call        printf
/*
        Kysytään featteja.
*/
        movq        $1, %rax              /* Saa aikaan sen että CPUID kertoo */
        cpuid                             /* prosessorin ominaisuudet %ecx ja %edx rekistereihin. */
        pushq       %rcx                  /* Otetaan featit talteen jotta ei tarvitsisi */
        pushq       %rdx                  /* koko ajan käskeä. */
/*
        Testaa SSE tuki.
*/
        testq       $0x2000000, (%rsp)    /* Bitti #25 %edx rekisterissä. */
        jnz         SSEYES
        call        no
        jmp         SSEEND
SSEYES:
        call        yes
SSEEND:
/*
        Tulosta str_sse2.
*/
        xorq        %rax, %rax
        movq        $str_sse2, %rdi
        call        printf
/*
        Testaa SSE2 tuki.
*/
        testq       $0x400000,(%rsp)      /* Bitti #26 %edx rekisterissä. */
        jnz         SSE2YES
        call        no
        jmp         SSE2END
SSE2YES:
        call        yes
SSE2END:
/*
        Tulosta str_sse3
*/
        xorq        %rax, %rax
        movq        $str_sse3, %rdi
        call        printf
/*
        Testaa SSE3 tuki.
*/
        testq       $0x1, 8(%rsp)         /* Bitti #0 %ecx rekisterissä. */
        jnz         SSE3YES
        call        no
        jmp         SSE3END
SSE3YES:
        call        yes
SSE3END:
/*
        Tulosta str_ssse3.
*/
        xorq        %rax, %rax
        movq        $str_ssse3, %rdi
        call        printf
/*
        Testaa SSSE3 tuki.
*/
        testq       $0x200, 8(%rsp)       /* Bitti #19 %ecx rekisterissä */
        jnz         SSSE3YES
        call        no
        jmp         SSSE3END
SSSE3YES:
        call        yes
SSSE3END:
/*
        Tulostaa str_sse41.
*/
        xorq        %rax, %rax
        movq        $str_sse41, %rdi
        call        printf
/*
        Testaa SSE4.1 tuen.
*/
        testq       $0x80000, 8(%rsp)
        jnz         SSE41YES
        call        no
        jmp         SSE41END
SSE41YES:
        call        yes
SSE41END:
/*
        Tulostaa str_sse42.
*/
        xorq        %rax, %rax
        movq        $str_sse42, %rdi
        call        printf
/*
        Testaa SSE4.2 tuen.
*/
        testq       $0x100000, 8(%rsp)
        jnz         SSE42YES
        call        no
        jmp         SSE42END
SSE42YES:
        call        yes
SSE42END:
       
EXIT:
        xorq        %rax, %rax        /* Palauttaa 0 käyttikselle */
        movq        %rbp, %rsp        /* Voit toki käskeä: mov $0, %rax */
        popq        %rbp              /* Mutta tämä taitaa olla suosituin tapa. Miksi? */
        ret
/*
 Tulostaa YES!
*/
.type yes, @function
yes:
        pushq       %rbp
        movq        %rsp, %rbp
        movq        $str_yes, %rdi
        xorq        %rax, %rax
        call        printf
        movq        %rbp, %rsp
        popq        %rbp
        ret
/*
 Tulostaa NO!
*/
.type no, @function
no:
        pushq       %rbp
        movq        %rsp, %rbp
        movq        $str_no, %rdi
        xorq        %rax, %rax
        call        printf
        movq        %rbp, %rsp
        popq        %rbp
        ret
 

kinzo 13:55 25.6.09 
Käskyvinkkejä sekä neuvoja koodin kirjoituksesta otetaan vastaan.

Features tulostaa minulla:
CPUID support... YES!
SSE support... YES!
SSE2 support... YES!
SSE3 support... YES!
SSSE3 support... YES!
SSE4.1 support... YES!
SSE4.2 support... NO!
kinzo 13:57 25.6.09 
Unohtui mainita että CPU on core 2 duo t8300 (penryn muistaakseni).
Grez 15:59 26.6.09 
kinzo kirjoitti:
xorq ... /* Mutta tämä taitaa olla suosituin tapa. Miksi? *

(Premature) optimization. "Root of all evil", sanotaan. Toisaalta suosittua varsinkin assemblykoodareiden keskuudessa.

Funktionaalisestihan noissa on sen verran eroa, että mov ei muuta lippujen tilaa kun taas xor asettaa liput tuloksen mukaan. Esimerkissä sillä ei pitäisi olla käytännön merkitystä.