You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cpu_arm64.go 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // Copyright 2019 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package cpu
  5. import "runtime"
  6. const cacheLineSize = 64
  7. func initOptions() {
  8. options = []option{
  9. {Name: "fp", Feature: &ARM64.HasFP},
  10. {Name: "asimd", Feature: &ARM64.HasASIMD},
  11. {Name: "evstrm", Feature: &ARM64.HasEVTSTRM},
  12. {Name: "aes", Feature: &ARM64.HasAES},
  13. {Name: "fphp", Feature: &ARM64.HasFPHP},
  14. {Name: "jscvt", Feature: &ARM64.HasJSCVT},
  15. {Name: "lrcpc", Feature: &ARM64.HasLRCPC},
  16. {Name: "pmull", Feature: &ARM64.HasPMULL},
  17. {Name: "sha1", Feature: &ARM64.HasSHA1},
  18. {Name: "sha2", Feature: &ARM64.HasSHA2},
  19. {Name: "sha3", Feature: &ARM64.HasSHA3},
  20. {Name: "sha512", Feature: &ARM64.HasSHA512},
  21. {Name: "sm3", Feature: &ARM64.HasSM3},
  22. {Name: "sm4", Feature: &ARM64.HasSM4},
  23. {Name: "sve", Feature: &ARM64.HasSVE},
  24. {Name: "crc32", Feature: &ARM64.HasCRC32},
  25. {Name: "atomics", Feature: &ARM64.HasATOMICS},
  26. {Name: "asimdhp", Feature: &ARM64.HasASIMDHP},
  27. {Name: "cpuid", Feature: &ARM64.HasCPUID},
  28. {Name: "asimrdm", Feature: &ARM64.HasASIMDRDM},
  29. {Name: "fcma", Feature: &ARM64.HasFCMA},
  30. {Name: "dcpop", Feature: &ARM64.HasDCPOP},
  31. {Name: "asimddp", Feature: &ARM64.HasASIMDDP},
  32. {Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM},
  33. }
  34. }
  35. func archInit() {
  36. switch runtime.GOOS {
  37. case "android", "darwin", "netbsd":
  38. // Android and iOS don't seem to allow reading these registers.
  39. //
  40. // NetBSD:
  41. // ID_AA64ISAR0_EL1 is a privileged register and cannot be read from EL0.
  42. // It can be read via sysctl(3). Example for future implementers:
  43. // https://nxr.netbsd.org/xref/src/usr.sbin/cpuctl/arch/aarch64.c
  44. //
  45. // Fake the minimal features expected by
  46. // TestARM64minimalFeatures.
  47. ARM64.HasASIMD = true
  48. ARM64.HasFP = true
  49. case "linux":
  50. doinit()
  51. default:
  52. readARM64Registers()
  53. }
  54. }
  55. func readARM64Registers() {
  56. Initialized = true
  57. // ID_AA64ISAR0_EL1
  58. isar0 := getisar0()
  59. switch extractBits(isar0, 4, 7) {
  60. case 1:
  61. ARM64.HasAES = true
  62. case 2:
  63. ARM64.HasAES = true
  64. ARM64.HasPMULL = true
  65. }
  66. switch extractBits(isar0, 8, 11) {
  67. case 1:
  68. ARM64.HasSHA1 = true
  69. }
  70. switch extractBits(isar0, 12, 15) {
  71. case 1:
  72. ARM64.HasSHA2 = true
  73. case 2:
  74. ARM64.HasSHA2 = true
  75. ARM64.HasSHA512 = true
  76. }
  77. switch extractBits(isar0, 16, 19) {
  78. case 1:
  79. ARM64.HasCRC32 = true
  80. }
  81. switch extractBits(isar0, 20, 23) {
  82. case 2:
  83. ARM64.HasATOMICS = true
  84. }
  85. switch extractBits(isar0, 28, 31) {
  86. case 1:
  87. ARM64.HasASIMDRDM = true
  88. }
  89. switch extractBits(isar0, 32, 35) {
  90. case 1:
  91. ARM64.HasSHA3 = true
  92. }
  93. switch extractBits(isar0, 36, 39) {
  94. case 1:
  95. ARM64.HasSM3 = true
  96. }
  97. switch extractBits(isar0, 40, 43) {
  98. case 1:
  99. ARM64.HasSM4 = true
  100. }
  101. switch extractBits(isar0, 44, 47) {
  102. case 1:
  103. ARM64.HasASIMDDP = true
  104. }
  105. // ID_AA64ISAR1_EL1
  106. isar1 := getisar1()
  107. switch extractBits(isar1, 0, 3) {
  108. case 1:
  109. ARM64.HasDCPOP = true
  110. }
  111. switch extractBits(isar1, 12, 15) {
  112. case 1:
  113. ARM64.HasJSCVT = true
  114. }
  115. switch extractBits(isar1, 16, 19) {
  116. case 1:
  117. ARM64.HasFCMA = true
  118. }
  119. switch extractBits(isar1, 20, 23) {
  120. case 1:
  121. ARM64.HasLRCPC = true
  122. }
  123. // ID_AA64PFR0_EL1
  124. pfr0 := getpfr0()
  125. switch extractBits(pfr0, 16, 19) {
  126. case 0:
  127. ARM64.HasFP = true
  128. case 1:
  129. ARM64.HasFP = true
  130. ARM64.HasFPHP = true
  131. }
  132. switch extractBits(pfr0, 20, 23) {
  133. case 0:
  134. ARM64.HasASIMD = true
  135. case 1:
  136. ARM64.HasASIMD = true
  137. ARM64.HasASIMDHP = true
  138. }
  139. switch extractBits(pfr0, 32, 35) {
  140. case 1:
  141. ARM64.HasSVE = true
  142. }
  143. }
  144. func extractBits(data uint64, start, end uint) uint {
  145. return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
  146. }