os_darwin_arm64.go 4.0 KB

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