os_darwin_arm64.go (3805B)
1 // Copyright (c) 2020 Klaus Post, released under MIT License. See LICENSE file. 2 3 package cpuid 4 5 import ( 6 "runtime" 7 "strings" 8 9 "golang.org/x/sys/unix" 10 ) 11 12 func detectOS(c *CPUInfo) bool { 13 if runtime.GOOS != "ios" { 14 tryToFillCPUInfoFomSysctl(c) 15 } 16 // There are no hw.optional sysctl values for the below features on Mac OS 11.0 17 // to detect their supported state dynamically. Assume the CPU features that 18 // Apple Silicon M1 supports to be available as a minimal set of features 19 // to all Go programs running on darwin/arm64. 20 // TODO: Add more if we know them. 21 c.featureSet.setIf(runtime.GOOS != "ios", AESARM, PMULL, SHA1, SHA2) 22 23 return true 24 } 25 26 func sysctlGetBool(name string) bool { 27 value, err := unix.SysctlUint32(name) 28 if err != nil { 29 return false 30 } 31 return value != 0 32 } 33 34 func sysctlGetString(name string) string { 35 value, err := unix.Sysctl(name) 36 if err != nil { 37 return "" 38 } 39 return value 40 } 41 42 func sysctlGetInt(unknown int, names ...string) int { 43 for _, name := range names { 44 value, err := unix.SysctlUint32(name) 45 if err != nil { 46 continue 47 } 48 if value != 0 { 49 return int(value) 50 } 51 } 52 return unknown 53 } 54 55 func sysctlGetInt64(unknown int, names ...string) int { 56 for _, name := range names { 57 value64, err := unix.SysctlUint64(name) 58 if err != nil { 59 continue 60 } 61 if int(value64) != unknown { 62 return int(value64) 63 } 64 } 65 return unknown 66 } 67 68 func setFeature(c *CPUInfo, name string, feature FeatureID) { 69 c.featureSet.setIf(sysctlGetBool(name), feature) 70 } 71 func tryToFillCPUInfoFomSysctl(c *CPUInfo) { 72 c.BrandName = sysctlGetString("machdep.cpu.brand_string") 73 74 if len(c.BrandName) != 0 { 75 c.VendorString = strings.Fields(c.BrandName)[0] 76 } 77 78 c.PhysicalCores = sysctlGetInt(runtime.NumCPU(), "hw.physicalcpu") 79 c.ThreadsPerCore = sysctlGetInt(1, "machdep.cpu.thread_count", "kern.num_threads") / 80 sysctlGetInt(1, "hw.physicalcpu") 81 c.LogicalCores = sysctlGetInt(runtime.NumCPU(), "machdep.cpu.core_count") 82 c.Family = sysctlGetInt(0, "machdep.cpu.family", "hw.cpufamily") 83 c.Model = sysctlGetInt(0, "machdep.cpu.model") 84 c.CacheLine = sysctlGetInt64(0, "hw.cachelinesize") 85 c.Cache.L1I = sysctlGetInt64(-1, "hw.l1icachesize") 86 c.Cache.L1D = sysctlGetInt64(-1, "hw.l1dcachesize") 87 c.Cache.L2 = sysctlGetInt64(-1, "hw.l2cachesize") 88 c.Cache.L3 = sysctlGetInt64(-1, "hw.l3cachesize") 89 90 // from https://developer.arm.com/downloads/-/exploration-tools/feature-names-for-a-profile 91 setFeature(c, "hw.optional.arm.FEAT_AES", AESARM) 92 setFeature(c, "hw.optional.AdvSIMD", ASIMD) 93 setFeature(c, "hw.optional.arm.FEAT_DotProd", ASIMDDP) 94 setFeature(c, "hw.optional.arm.FEAT_RDM", ASIMDRDM) 95 setFeature(c, "hw.optional.FEAT_CRC32", CRC32) 96 setFeature(c, "hw.optional.arm.FEAT_DPB", DCPOP) 97 // setFeature(c, "", EVTSTRM) 98 setFeature(c, "hw.optional.arm.FEAT_FCMA", FCMA) 99 setFeature(c, "hw.optional.arm.FEAT_FP", FP) 100 setFeature(c, "hw.optional.arm.FEAT_FP16", FPHP) 101 setFeature(c, "hw.optional.arm.FEAT_PAuth", GPA) 102 setFeature(c, "hw.optional.arm.FEAT_JSCVT", JSCVT) 103 setFeature(c, "hw.optional.arm.FEAT_LRCPC", LRCPC) 104 setFeature(c, "hw.optional.arm.FEAT_PMULL", PMULL) 105 setFeature(c, "hw.optional.arm.FEAT_SHA1", SHA1) 106 setFeature(c, "hw.optional.arm.FEAT_SHA256", SHA2) 107 setFeature(c, "hw.optional.arm.FEAT_SHA3", SHA3) 108 setFeature(c, "hw.optional.arm.FEAT_SHA512", SHA512) 109 // setFeature(c, "", SM3) 110 // setFeature(c, "", SM4) 111 setFeature(c, "hw.optional.arm.FEAT_SVE", SVE) 112 113 // from empirical observation 114 setFeature(c, "hw.optional.AdvSIMD_HPFPCvt", ASIMDHP) 115 setFeature(c, "hw.optional.armv8_1_atomics", ATOMICS) 116 setFeature(c, "hw.optional.floatingpoint", FP) 117 setFeature(c, "hw.optional.armv8_2_sha3", SHA3) 118 setFeature(c, "hw.optional.armv8_2_sha512", SHA512) 119 setFeature(c, "hw.optional.armv8_3_compnum", FCMA) 120 setFeature(c, "hw.optional.armv8_crc32", CRC32) 121 }