Skip to content

Commit b08ba36

Browse files
committed
1 parent cbd0879 commit b08ba36

File tree

3 files changed

+164
-1
lines changed

3 files changed

+164
-1
lines changed

src/runtime/asm_arm64.s

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,3 +1312,28 @@ TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
13121312
MOVD R0, x+0(FP)
13131313
MOVD R1, y+8(FP)
13141314
JMP runtime·goPanicSlice3CU(SB)
1315+
1316+
// func getisar0() uint64
1317+
TEXT runtime·getisar0(SB),NOSPLIT,$0
1318+
// get Instruction Set Attributes 0 into x0
1319+
// mrs x0, ID_AA64ISAR0_EL1 = d5380600
1320+
WORD $0xd5380600
1321+
MOVD R0, ret+0(FP)
1322+
RET
1323+
1324+
// func getisar1() uint64
1325+
TEXT runtime·getisar1(SB),NOSPLIT,$0
1326+
// get Instruction Set Attributes 1 into x0
1327+
// mrs x0, ID_AA64ISAR1_EL1 = d5380620
1328+
WORD $0xd5380620
1329+
MOVD R0, ret+0(FP)
1330+
RET
1331+
1332+
// func getpfr0() uint64
1333+
TEXT runtime·getpfr0(SB),NOSPLIT,$0
1334+
// get Processor Feature Register 0 into x0
1335+
// mrs x0, ID_AA64PFR0_EL1 = d5380400
1336+
WORD $0xd5380400
1337+
MOVD R0, ret+0(FP)
1338+
RET
1339+

src/runtime/os_freebsd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ const (
394394
)
395395

396396
func sysauxv(auxv []uintptr) {
397+
archauxv(_AT_HWCAP, 0)
397398
for i := 0; auxv[i] != _AT_NULL; i += 2 {
398399
tag, val := auxv[i], auxv[i+1]
399400
switch tag {

src/runtime/os_freebsd_arm64.go

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,154 @@ package runtime
88

99
import "internal/cpu"
1010

11+
func getisar0() uint64
12+
func getisar1() uint64
13+
func getpfr0() uint64
14+
15+
const (
16+
hwcap_FP = 1 << 0
17+
hwcap_ASIMD = 1 << 1
18+
hwcap_EVTSTRM = 1 << 2
19+
hwcap_AES = 1 << 3
20+
hwcap_PMULL = 1 << 4
21+
hwcap_SHA1 = 1 << 5
22+
hwcap_SHA2 = 1 << 6
23+
hwcap_CRC32 = 1 << 7
24+
hwcap_ATOMICS = 1 << 8
25+
hwcap_FPHP = 1 << 9
26+
hwcap_ASIMDHP = 1 << 10
27+
hwcap_CPUID = 1 << 11
28+
hwcap_ASIMDRDM = 1 << 12
29+
hwcap_JSCVT = 1 << 13
30+
hwcap_FCMA = 1 << 14
31+
hwcap_LRCPC = 1 << 15
32+
hwcap_DCPOP = 1 << 16
33+
hwcap_SHA3 = 1 << 17
34+
hwcap_SM3 = 1 << 18
35+
hwcap_SM4 = 1 << 19
36+
hwcap_ASIMDDP = 1 << 20
37+
hwcap_SHA512 = 1 << 21
38+
hwcap_SVE = 1 << 22
39+
hwcap_ASIMDFHM = 1 << 23
40+
)
41+
1142
func archauxv(tag, val uintptr) {
1243
switch tag {
1344
case _AT_HWCAP:
1445
// arm64 doesn't have a 'cpuid' instruction equivalent and relies on
1546
// HWCAP/HWCAP2 bits for hardware capabilities.
16-
cpu.HWCap = uint(val)
47+
// detection. See issue #31746.
48+
var isar0, isar1, pfr0 uint64
49+
50+
isar0 = getisar0()
51+
isar1 = getisar1()
52+
pfr0 = getpfr0()
53+
54+
// ID_AA64ISAR0_EL1
55+
switch extract_bits(isar0, 4, 7) {
56+
case 1:
57+
cpu.HWCap |= hwcap_AES
58+
case 2:
59+
cpu.HWCap |= hwcap_PMULL | hwcap_AES
60+
}
61+
62+
switch extract_bits(isar0, 8, 11) {
63+
case 1:
64+
cpu.HWCap |= hwcap_SHA1
65+
}
66+
67+
switch extract_bits(isar0, 12, 15) {
68+
case 1:
69+
cpu.HWCap |= hwcap_SHA2
70+
case 2:
71+
cpu.HWCap |= hwcap_SHA2 | hwcap_SHA512
72+
}
73+
74+
switch extract_bits(isar0, 16, 19) {
75+
case 1:
76+
cpu.HWCap |= hwcap_CRC32
77+
}
78+
79+
switch extract_bits(isar0, 20, 23) {
80+
case 2:
81+
cpu.HWCap |= hwcap_ATOMICS
82+
}
83+
84+
switch extract_bits(isar0, 28, 31) {
85+
case 1:
86+
cpu.HWCap |= hwcap_ASIMDRDM
87+
}
88+
89+
switch extract_bits(isar0, 32, 35) {
90+
case 1:
91+
cpu.HWCap |= hwcap_SHA3
92+
}
93+
94+
switch extract_bits(isar0, 36, 39) {
95+
case 1:
96+
cpu.HWCap |= hwcap_SM3
97+
}
98+
99+
switch extract_bits(isar0, 40, 43) {
100+
case 1:
101+
cpu.HWCap |= hwcap_SM4
102+
}
103+
104+
switch extract_bits(isar0, 44, 47) {
105+
case 1:
106+
cpu.HWCap |= hwcap_ASIMDDP
107+
}
108+
109+
// ID_AA64ISAR1_EL1
110+
switch extract_bits(isar1, 0, 3) {
111+
case 1:
112+
cpu.HWCap |= hwcap_DCPOP
113+
}
114+
115+
switch extract_bits(isar1, 12, 15) {
116+
case 1:
117+
cpu.HWCap |= hwcap_JSCVT
118+
}
119+
120+
switch extract_bits(isar1, 16, 19) {
121+
case 1:
122+
cpu.HWCap |= hwcap_FCMA
123+
}
124+
125+
switch extract_bits(isar1, 20, 23) {
126+
case 1:
127+
cpu.HWCap |= hwcap_LRCPC
128+
}
129+
130+
// ID_AA64PFR0_EL1
131+
switch extract_bits(pfr0, 16, 19) {
132+
case 0:
133+
cpu.HWCap |= hwcap_FP
134+
case 1:
135+
cpu.HWCap |= hwcap_FP | hwcap_FPHP
136+
}
137+
138+
switch extract_bits(pfr0, 20, 23) {
139+
case 0:
140+
cpu.HWCap |= hwcap_ASIMD
141+
case 1:
142+
cpu.HWCap |= hwcap_ASIMD | hwcap_ASIMDHP
143+
}
144+
145+
switch extract_bits(pfr0, 32, 35) {
146+
case 1:
147+
cpu.HWCap |= hwcap_SVE
148+
}
149+
17150
case _AT_HWCAP2:
18151
cpu.HWCap2 = uint(val)
19152
}
20153
}
21154

155+
func extract_bits(data uint64, start, end uint) uint {
156+
return (uint)(data >> start) & ((1 << (end - start + 1)) - 1)
157+
}
158+
22159
//go:nosplit
23160
func cputicks() int64 {
24161
// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand().

0 commit comments

Comments
 (0)