News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Rewritten CPUID algo for testing instruction sets.

Started by hutch--, May 01, 2010, 02:04:38 PM

Previous topic - Next topic

hutch--

I am tired of this stuff as well but I was after an easy to use algo to test if you can use the later instruction sets so I have kept dabbling to make it easier to use. This one is coded with BT to make it easier to read and has the eflags test on board so it won't crash on an old timer even if you can get win32 to run on it. I felt cheated in that the first version in the rewrite used CMOVC with no jumps but then it dawned that there may be something that will run win32 that did not have the CMOVxx family of instructions so I had to do it again.


IF 0  ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                      Build this template with "CONSOLE ASSEMBLE AND LINK"
ENDIF ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include\masm32rt.inc

    .686p

    testi PROTO :DWORD

    X86ST STRUCT
      sse42 dd ?
      sse41 dd ?
      ssse3 dd ?
      sse3  dd ?
      sse2  dd ?
      sse   dd ?
      mmx   dd ?
    X86ST ENDS

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    LOCAL x86   :X86ST

    invoke testi,ADDR x86

    print str$(x86.sse42),13,10
    print str$(x86.sse41),13,10
    print str$(x86.ssse3),13,10
    print str$(x86.sse3),13,10

    print str$(x86.sse2),13,10
    print str$(x86.sse),13,10
    print str$(x86.mmx),13,10

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

testi proc pStruct:DWORD

  ; returns 0 if no CPUID, 1 if it is supported.
  ; if supported tests from MMX to SSE4.2 and
  ; writes results to structure

  ; -------------------------------------------------
  ; test for CPUID so it does not crash on old timers
  ; -------------------------------------------------
    pushfd
    pop eax

    mov ecx, eax
    xor eax, 00000000001000000000000000000000b          ; set bit 21 of eflags
    push eax
    popfd
    pushfd
    pop eax

    xor eax, ecx            ; test if its changed
    jnz exists              ; if changed then CPUID
    xor eax, eax            ; returns 0 if no CPUID
    ret
  ; -------------------------------------------------

  exists:

    push esi

    mov esi, pStruct

    mov eax, 1
    cpuid

    mov (X86ST PTR [esi]).sse42, 0
    bt ecx, 20                                      ; sse4.2
    jnc @F
    mov (X86ST PTR [esi]).sse42, 1
  @@:

    mov (X86ST PTR [esi]).sse41, 0
    bt ecx, 19                                      ; sse4.1
    jnc @F
    mov (X86ST PTR [esi]).sse41, 1
  @@:

    mov (X86ST PTR [esi]).ssse3, 0
    bt ecx, 9                                       ; ssse3
    jnc @F
    mov (X86ST PTR [esi]).ssse3, 1
  @@:

    mov (X86ST PTR [esi]).sse3, 0
    bt ecx, 0                                       ; sse3
    jnc @F
    mov (X86ST PTR [esi]).sse3, 1
  @@:

    mov (X86ST PTR [esi]).sse2, 0
    bt edx, 26                                      ; sse2
    jnc @F
    mov (X86ST PTR [esi]).sse2, 1
  @@:

    mov (X86ST PTR [esi]).sse, 0
    bt edx, 25                                      ; sse
    jnc @F
    mov (X86ST PTR [esi]).sse, 1
  @@:

    mov (X86ST PTR [esi]).mmx, 0
    bt edx, 23                                      ; mmx
    jnc @F
    mov (X86ST PTR [esi]).mmx, 1
  @@:

    pop esi

    mov eax, 1

    ret

testi endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

you have to watch register addressing modes and conditional branch distances, as well   :P
once you get to the part where you know you have a pentium, you can breath a little

hutch--

 :bg

I doubt that win32 will run on an 8086. Win32 capable processors have no problems with either. Further there is no branch that exceeds signed byte range in this algo. Having written code for the original i486 (still own it) the original DX 33 meg version could do both and I vaguely remember a young guy running win95 OEM on a 486SX.

The algo only tests instruction sets, its not trying to be CPU-Z. Anything old enough to be a problem does not run win32 or from the testing by other members it already runs on PIII, PII and I think the earliest non MMX pentiums. I seem to have missed the drift of your post.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

sinsi

Since this is in the lab

    mov (X86ST PTR [esi]).sse42, 0
    bt ecx, 20                                      ; sse4.2
    jnc @F
    mov (X86ST PTR [esi]).sse42, 1
  @@:



    sub eax,eax

    mov (X86ST PTR [esi]).sse42, eax
    bt ecx, 20                                      ; sse4.2
    adc (X86ST PTR [esi]).sse42, eax

Or zero the struc then just bt and adc.

>I vaguely remember a young guy running win95 OEM on a 486SX.
Hey, that was me! but it was osr2...back in the summer of 69 96
Light travels faster than sound, that's why some people seem bright until you hear them.

clive

TRUE/FALSE, no initialization, one write, no branch

    bt ecx, 20                                      ; sse4.2
    sbb eax,eax
    mov (X86ST PTR [esi]).sse42, eax
It could be a random act of randomness. Those happen a lot as well.

hutch--

 :bg

Thanks folks, novel approach, branchless without CMOVxx.  :U
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

hutch--

I actually found a use for SETC.


;; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

; "mmi" Multi media Instructions

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

mmi proc pStruct:DWORD

  ; returns 0 if no CPUID, 1 if it is supported.
  ; if supported tests from MMX to SSE4.2 and
  ; writes results to structure

  ; -------------------------------------------------
  ; test for CPUID so it does not crash on old timers
  ; -------------------------------------------------
    pushfd
    pop eax

    mov ecx, eax
    xor eax, 00000000001000000000000000000000b          ; set bit 21 of eflags
    push eax
    popfd
    pushfd
    pop eax

    xor eax, ecx            ; test if its changed
    jnz exists              ; if changed then CPUID
    xor eax, eax            ; returns 0 if no CPUID
    ret 4
  ; -------------------------------------------------

  exists:
  ; -------------------
  ; zero fill structure
  ; -------------------
    mov ecx, SIZEOF X86ST
    shr ecx, 2
    mov eax, [esp+4]        ; pStruct
  @@:
    mov DWORD PTR [eax], 0
    add eax, 4
    sub ecx, 1
    jnz @B

    mov eax, 1
    cpuid

    mov eax, [esp+4]        ; pStruct

    bt ecx, 20                                      ; sse4.2
    setc BYTE PTR (X86ST PTR [eax]).sse42

    bt ecx, 19                                      ; sse4.1
    setc BYTE PTR (X86ST PTR [eax]).sse41

    bt ecx, 9                                       ; ssse3
    setc BYTE PTR (X86ST PTR [eax]).ssse3

    bt ecx, 0                                       ; sse3
    setc BYTE PTR (X86ST PTR [eax]).sse3

    bt edx, 26                                      ; sse2
    setc BYTE PTR (X86ST PTR [eax]).sse2

    bt edx, 25                                      ; sse
    setc BYTE PTR (X86ST PTR [eax]).sse

    bt edx, 23                                      ; mmx
    setc BYTE PTR (X86ST PTR [eax]).mmx

    mov eax, 1
    ret 4

mmi endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

clive

Pity it only works on bytes, and you have to init the table.

Instead of
    mov ecx, SIZEOF X86ST
    shr ecx, 2


you could use this for a fixed size structure
    mov ecx, SIZEOF X86ST SHR 2

Wouldn't it make more sense for the new feature to be at the end of the table so when it expands the rest of the table remains the same?
It could be a random act of randomness. Those happen a lot as well.

hutch--

 :bg

> mov ecx, SIZEOF X86ST SHR 2

Saves the SHR in code which makes sense.

> Wouldn't it make more sense for the new feature to be at the end of the table so when it expands the rest of the table remains the same?

I have missed something here, by passing the structure adress you are selecting the member to write to by its name so you can routinely add extra members to the structure.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

clive

It was more of a backward compatibility thought.. Although you really want the user to keep all the code/versions synchronized

    X86ST STRUCT
      mmx   dd ?
      sse   dd ?
      sse2  dd ?
      sse3  dd ?
      ssse3 dd ?
      sse41 dd ?
      sse42 dd ?

; New features added here expanding the structure

    X86ST ENDS


The other thing Microsoft typically does is add a size field as the first record.
It could be a random act of randomness. Those happen a lot as well.

hutch--

This does make sense in a context where the information was being pulled out of the operating system but in the context where the information is being taken directly from the processor there is nothing that is going to change it except hardware change that breaks the existing reference material. If for example it was an external structure in the OS, if it was changed out of the published order, it would break code that was written using it but where the structure is handled internally only then with a built binary nothing external to the binary will change the information.

I confess I shot the structure together in decending order because the Intel reference material had it written that way in the table and an order inversion or random shuffle would not change anything as each structure member is addressed in code by its name.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Ficko

Thanks Hutch!

This is a very usefull code :U
What missing is the subdivision for "Extended MMX" - SSE Primer -

Like AMD "Athlon" and "Duron" are capable of executing MMX integer extentions but not SSE.
3DNow! subdivision would be a nice add-in as well. :wink

hutch--

Ficko,

I know what they are but I don't have an AMD box to test on and its almost impossible to get a reliable result without being able to test it. You can determine if the box is an AMD from the Vendor string "AuthenticAMD" but it needs tests for the two 3DNow sets and extended MMX and sse4a.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

Hutch - you might be able to use this thread as a reference book
you can see the code - then, you can see how it ran on a hundred different machines
http://www.masm32.com/board/index.php?topic=13044.msg101030#msg101030

hutch--

Ficko,

I added to the test piece the values I know for AMD but I have no way of testing them.

I get these returns on an Intel Quad.


-----
INTEL
-----
0 sse4.2
1 sse4.1
1 ssse3
1 sse3
1 sse2
1 sse
1 mmx

---
AMD
---
0 sse4a
0 mmx_ex
0 3DNow
0 3DNow_ex

Press any key to continue ...


Could I impose on you to run this code on an AMD, anything late like an Athlon or Phenom ii.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php