cpu_arm64.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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 "freebsd":
  38. readARM64Registers()
  39. case "linux", "netbsd":
  40. doinit()
  41. default:
  42. // Most platforms don't seem to allow reading these registers.
  43. //
  44. // OpenBSD:
  45. // See https://golang.org/issue/31746
  46. setMinimalFeatures()
  47. }
  48. }
  49. // setMinimalFeatures fakes the minimal ARM64 features expected by
  50. // TestARM64minimalFeatures.
  51. func setMinimalFeatures() {
  52. ARM64.HasASIMD = true
  53. ARM64.HasFP = true
  54. }
  55. func readARM64Registers() {
  56. Initialized = true
  57. parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0())
  58. }
  59. func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {
  60. // ID_AA64ISAR0_EL1
  61. switch extractBits(isar0, 4, 7) {
  62. case 1:
  63. ARM64.HasAES = true
  64. case 2:
  65. ARM64.HasAES = true
  66. ARM64.HasPMULL = true
  67. }
  68. switch extractBits(isar0, 8, 11) {
  69. case 1:
  70. ARM64.HasSHA1 = true
  71. }
  72. switch extractBits(isar0, 12, 15) {
  73. case 1:
  74. ARM64.HasSHA2 = true
  75. case 2:
  76. ARM64.HasSHA2 = true
  77. ARM64.HasSHA512 = true
  78. }
  79. switch extractBits(isar0, 16, 19) {
  80. case 1:
  81. ARM64.HasCRC32 = true
  82. }
  83. switch extractBits(isar0, 20, 23) {
  84. case 2:
  85. ARM64.HasATOMICS = true
  86. }
  87. switch extractBits(isar0, 28, 31) {
  88. case 1:
  89. ARM64.HasASIMDRDM = true
  90. }
  91. switch extractBits(isar0, 32, 35) {
  92. case 1:
  93. ARM64.HasSHA3 = true
  94. }
  95. switch extractBits(isar0, 36, 39) {
  96. case 1:
  97. ARM64.HasSM3 = true
  98. }
  99. switch extractBits(isar0, 40, 43) {
  100. case 1:
  101. ARM64.HasSM4 = true
  102. }
  103. switch extractBits(isar0, 44, 47) {
  104. case 1:
  105. ARM64.HasASIMDDP = true
  106. }
  107. // ID_AA64ISAR1_EL1
  108. switch extractBits(isar1, 0, 3) {
  109. case 1:
  110. ARM64.HasDCPOP = true
  111. }
  112. switch extractBits(isar1, 12, 15) {
  113. case 1:
  114. ARM64.HasJSCVT = true
  115. }
  116. switch extractBits(isar1, 16, 19) {
  117. case 1:
  118. ARM64.HasFCMA = true
  119. }
  120. switch extractBits(isar1, 20, 23) {
  121. case 1:
  122. ARM64.HasLRCPC = true
  123. }
  124. // ID_AA64PFR0_EL1
  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. }