CPUID - Check what instructions are supported by your CPU

Post your working scripts, libraries and tools for AHK v1.1 and older
iseahound
Posts: 1434
Joined: 13 Aug 2016, 21:04
Contact:

CPUID - Check what instructions are supported by your CPU

Post by iseahound » 12 May 2022, 18:54

image.png
image.png (93.91 KiB) Viewed 578 times
Sample code

Code: Select all

if (cpuid().ECX[28] == True)
    MsgBox % "Advanced Vector Extensions are supported"

if (cpuid().edx[26] == True)
    MsgBox % "SSE2 instructions are supported"
AutoHotkey v1

Code: Select all

      CPUID() {
         static cpuid := 0

         if not cpuid {
            ; C source code - https://godbolt.org/z/1YPd6jz61
            code := (A_PtrSize == 4)
               ? "VYnlV4t9EFaLdQhTiw+LBg+iiQaLRQyJGItFFIkPiRBbXl9dww=="
               : "U4sBSYnKSYnTQYsID6JBiQJBiRtBiQhBiRFbww=="
            size := StrLen(RTrim(code, "=")) * 3 // 4
            bin := DllCall("GlobalAlloc", "uint", 0, "uptr", size, "ptr")
            DllCall("VirtualProtect", "ptr", bin, "ptr", size, "uint", 0x40, "uint*", old:=0)
            DllCall("crypt32\CryptStringToBinary", "str", code, "uint", 0, "uint", 0x1, "ptr", bin, "uint*", size, "ptr", 0, "ptr", 0)

            ; Set eax flag to 1 to retrieve supported CPU features.
            ; See this for CPU features: https://wiki.osdev.org/CPUID
            ; Also see: Appendix D.2 - CPUID Feature Flags Related to Instruction Support
            ; On page 1861 - https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/40332.pdf
            DllCall(bin, "uint*", a := 1, "uint*", b := 0, "uint*", c := 0, "uint*", d := 0)

            ; Free memory.
            DllCall("GlobalFree", "ptr", bin)

            ; To check for SSE2 use the following code example:
            ; if cpuid().edx[26] == True
            eax := {0: a & 1}
            ebx := {0: b & 1}
            ecx := {0: c & 1}
            edx := {0: d & 1}
            loop 31 {
               eax[A_Index] := !!(1 << A_Index & a)
               ebx[A_Index] := !!(1 << A_Index & b)
               ecx[A_Index] := !!(1 << A_Index & c)
               edx[A_Index] := !!(1 << A_Index & d)
            }
            cpuid := {eax: eax, ebx: ebx, ecx: ecx, edx: edx}
         }

         return cpuid
      }
AutoHotkey v2 compatible

Code: Select all

      CPUID() {
         static cpuid := 0

         if not cpuid {
            ; C source code - https://godbolt.org/z/1YPd6jz61
            code := (A_PtrSize == 4)
               ? "VYnlV4t9EFaLdQhTiw+LBg+iiQaLRQyJGItFFIkPiRBbXl9dww=="
               : "U4sBSYnKSYnTQYsID6JBiQJBiRtBiQhBiRFbww=="
            size := StrLen(RTrim(code, "=")) * 3 // 4
            bin := DllCall("GlobalAlloc", "uint", 0, "uptr", size, "ptr")
            DllCall("VirtualProtect", "ptr", bin, "ptr", size, "uint", 0x40, "uint*", &old:=0)
            DllCall("crypt32\CryptStringToBinary", "str", code, "uint", 0, "uint", 0x1, "ptr", bin, "uint*", size, "ptr", 0, "ptr", 0)

            ; Set eax flag to 1 to retrieve supported CPU features.
            ; See this for CPU features: https://wiki.osdev.org/CPUID
            ; Also see: Appendix D.2 - CPUID Feature Flags Related to Instruction Support
            ; On page 1861 - https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/40332.pdf
            DllCall(bin, "uint*", &a := 1, "uint*", &b := 0, "uint*", &c := 0, "uint*", &d := 0)

            ; Free memory.
            DllCall("GlobalFree", "ptr", bin)

            ; To check for SSE2 use the following code example:
            ; if cpuid().edx[26] == True
            eax := Map(0, a & 1)
            ebx := Map(0, b & 1)
            ecx := Map(0, c & 1)
            edx := Map(0, d & 1)
            loop 31 {
               eax[A_Index] := !!(1 << A_Index & a)
               ebx[A_Index] := !!(1 << A_Index & b)
               ecx[A_Index] := !!(1 << A_Index & c)
               edx[A_Index] := !!(1 << A_Index & d)
            }
            cpuid := {eax: eax, ebx: ebx, ecx: ecx, edx: edx}
         }

         return cpuid
      }

I'm not sure what this would be useful for...

iseahound
Posts: 1434
Joined: 13 Aug 2016, 21:04
Contact:

Re: CPUID - Check what instructions are supported by your CPU

Post by iseahound » 15 Sep 2023, 10:03

It's come to my attention that gcc has builtin methods of doing this properly. The problem with CPUID is that it only returns whether the processor supports the instruction set (and it's not obvious how to text for AVX512), and not whether the OS supports the instruction set.

https://godbolt.org/z/5167jsE17

not that the built-in gcc functions work in AutoHotkey hmm....

Post Reply

Return to “Scripts and Functions (v1)”