cpu_arm64.go (3767B)
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 5 package cpu 6 7 import "runtime" 8 9 // cacheLineSize is used to prevent false sharing of cache lines. 10 // We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size. 11 // It doesn't cost much and is much more future-proof. 12 const cacheLineSize = 128 13 14 func initOptions() { 15 options = []option{ 16 {Name: "fp", Feature: &ARM64.HasFP}, 17 {Name: "asimd", Feature: &ARM64.HasASIMD}, 18 {Name: "evstrm", Feature: &ARM64.HasEVTSTRM}, 19 {Name: "aes", Feature: &ARM64.HasAES}, 20 {Name: "fphp", Feature: &ARM64.HasFPHP}, 21 {Name: "jscvt", Feature: &ARM64.HasJSCVT}, 22 {Name: "lrcpc", Feature: &ARM64.HasLRCPC}, 23 {Name: "pmull", Feature: &ARM64.HasPMULL}, 24 {Name: "sha1", Feature: &ARM64.HasSHA1}, 25 {Name: "sha2", Feature: &ARM64.HasSHA2}, 26 {Name: "sha3", Feature: &ARM64.HasSHA3}, 27 {Name: "sha512", Feature: &ARM64.HasSHA512}, 28 {Name: "sm3", Feature: &ARM64.HasSM3}, 29 {Name: "sm4", Feature: &ARM64.HasSM4}, 30 {Name: "sve", Feature: &ARM64.HasSVE}, 31 {Name: "crc32", Feature: &ARM64.HasCRC32}, 32 {Name: "atomics", Feature: &ARM64.HasATOMICS}, 33 {Name: "asimdhp", Feature: &ARM64.HasASIMDHP}, 34 {Name: "cpuid", Feature: &ARM64.HasCPUID}, 35 {Name: "asimrdm", Feature: &ARM64.HasASIMDRDM}, 36 {Name: "fcma", Feature: &ARM64.HasFCMA}, 37 {Name: "dcpop", Feature: &ARM64.HasDCPOP}, 38 {Name: "asimddp", Feature: &ARM64.HasASIMDDP}, 39 {Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM}, 40 } 41 } 42 43 func archInit() { 44 switch runtime.GOOS { 45 case "freebsd": 46 readARM64Registers() 47 case "linux", "netbsd", "openbsd": 48 doinit() 49 default: 50 // Many platforms don't seem to allow reading these registers. 51 setMinimalFeatures() 52 } 53 } 54 55 // setMinimalFeatures fakes the minimal ARM64 features expected by 56 // TestARM64minimalFeatures. 57 func setMinimalFeatures() { 58 ARM64.HasASIMD = true 59 ARM64.HasFP = true 60 } 61 62 func readARM64Registers() { 63 Initialized = true 64 65 parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0()) 66 } 67 68 func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { 69 // ID_AA64ISAR0_EL1 70 switch extractBits(isar0, 4, 7) { 71 case 1: 72 ARM64.HasAES = true 73 case 2: 74 ARM64.HasAES = true 75 ARM64.HasPMULL = true 76 } 77 78 switch extractBits(isar0, 8, 11) { 79 case 1: 80 ARM64.HasSHA1 = true 81 } 82 83 switch extractBits(isar0, 12, 15) { 84 case 1: 85 ARM64.HasSHA2 = true 86 case 2: 87 ARM64.HasSHA2 = true 88 ARM64.HasSHA512 = true 89 } 90 91 switch extractBits(isar0, 16, 19) { 92 case 1: 93 ARM64.HasCRC32 = true 94 } 95 96 switch extractBits(isar0, 20, 23) { 97 case 2: 98 ARM64.HasATOMICS = true 99 } 100 101 switch extractBits(isar0, 28, 31) { 102 case 1: 103 ARM64.HasASIMDRDM = true 104 } 105 106 switch extractBits(isar0, 32, 35) { 107 case 1: 108 ARM64.HasSHA3 = true 109 } 110 111 switch extractBits(isar0, 36, 39) { 112 case 1: 113 ARM64.HasSM3 = true 114 } 115 116 switch extractBits(isar0, 40, 43) { 117 case 1: 118 ARM64.HasSM4 = true 119 } 120 121 switch extractBits(isar0, 44, 47) { 122 case 1: 123 ARM64.HasASIMDDP = true 124 } 125 126 // ID_AA64ISAR1_EL1 127 switch extractBits(isar1, 0, 3) { 128 case 1: 129 ARM64.HasDCPOP = true 130 } 131 132 switch extractBits(isar1, 12, 15) { 133 case 1: 134 ARM64.HasJSCVT = true 135 } 136 137 switch extractBits(isar1, 16, 19) { 138 case 1: 139 ARM64.HasFCMA = true 140 } 141 142 switch extractBits(isar1, 20, 23) { 143 case 1: 144 ARM64.HasLRCPC = true 145 } 146 147 // ID_AA64PFR0_EL1 148 switch extractBits(pfr0, 16, 19) { 149 case 0: 150 ARM64.HasFP = true 151 case 1: 152 ARM64.HasFP = true 153 ARM64.HasFPHP = true 154 } 155 156 switch extractBits(pfr0, 20, 23) { 157 case 0: 158 ARM64.HasASIMD = true 159 case 1: 160 ARM64.HasASIMD = true 161 ARM64.HasASIMDHP = true 162 } 163 164 switch extractBits(pfr0, 32, 35) { 165 case 1: 166 ARM64.HasSVE = true 167 } 168 } 169 170 func extractBits(data uint64, start, end uint) uint { 171 return (uint)(data>>start) & ((1 << (end - start + 1)) - 1) 172 }