github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/platform/cpuid_amd64.go (about) 1 package platform 2 3 const ( 4 // CpuFeatureSSE3 is the flag to query CpuFeatureFlags.Has for SSEv3 capabilities 5 CpuFeatureSSE3 = uint64(1) 6 // CpuFeatureSSE4_1 is the flag to query CpuFeatureFlags.Has for SSEv4.1 capabilities 7 CpuFeatureSSE4_1 = uint64(1) << 19 8 // CpuFeatureSSE4_2 is the flag to query CpuFeatureFlags.Has for SSEv4.2 capabilities 9 CpuFeatureSSE4_2 = uint64(1) << 20 10 ) 11 12 const ( 13 // CpuExtraFeatureABM is the flag to query CpuFeatureFlags.HasExtra for Advanced Bit Manipulation capabilities (e.g. LZCNT) 14 CpuExtraFeatureABM = uint64(1) << 5 15 ) 16 17 // CpuFeatures exposes the capabilities for this CPU, queried via the Has, HasExtra methods 18 var CpuFeatures CpuFeatureFlags = loadCpuFeatureFlags() 19 20 // CpuFeatureFlags exposes methods for querying CPU capabilities 21 type CpuFeatureFlags interface { 22 // Has returns true when the specified flag (represented as uint64) is supported 23 Has(cpuFeature uint64) bool 24 // HasExtra returns true when the specified extraFlag (represented as uint64) is supported 25 HasExtra(cpuFeature uint64) bool 26 } 27 28 // cpuFeatureFlags implements CpuFeatureFlags interface 29 type cpuFeatureFlags struct { 30 flags uint64 31 extraFlags uint64 32 } 33 34 // cpuid exposes the CPUID instruction to the Go layer (https://www.amd.com/system/files/TechDocs/25481.pdf) 35 // implemented in impl_amd64.s 36 func cpuid(arg1, arg2 uint32) (eax, ebx, ecx, edx uint32) 37 38 // cpuidAsBitmap combines the result of invoking cpuid to uint64 bitmap 39 func cpuidAsBitmap(arg1, arg2 uint32) uint64 { 40 _ /* eax */, _ /* ebx */, ecx, edx := cpuid(arg1, arg2) 41 return (uint64(edx) << 32) | uint64(ecx) 42 } 43 44 // loadStandardRange load flags from the standard range, panics otherwise 45 func loadStandardRange(id uint32) uint64 { 46 // ensure that the id is in the valid range, returned by cpuid(0,0) 47 maxRange, _, _, _ := cpuid(0, 0) 48 if id > maxRange { 49 panic("cannot query standard CPU flags") 50 } 51 return cpuidAsBitmap(id, 0) 52 } 53 54 // loadStandardRange load flags from the extended range, panics otherwise 55 func loadExtendedRange(id uint32) uint64 { 56 // ensure that the id is in the valid range, returned by cpuid(0x80000000,0) 57 maxRange, _, _, _ := cpuid(0x80000000, 0) 58 if id > maxRange { 59 panic("cannot query extended CPU flags") 60 } 61 return cpuidAsBitmap(id, 0) 62 } 63 64 func loadCpuFeatureFlags() CpuFeatureFlags { 65 return &cpuFeatureFlags{ 66 flags: loadStandardRange(1), 67 extraFlags: loadExtendedRange(0x80000001), 68 } 69 } 70 71 // Has implements the same method on the CpuFeatureFlags interface 72 func (f *cpuFeatureFlags) Has(cpuFeature uint64) bool { 73 return (f.flags & cpuFeature) != 0 74 } 75 76 // HasExtra implements the same method on the CpuFeatureFlags interface 77 func (f *cpuFeatureFlags) HasExtra(cpuFeature uint64) bool { 78 return (f.extraFlags & cpuFeature) != 0 79 }