1
// Copyright (c) 2020 Klaus Post, released under MIT License. See LICENSE file.
3
// Copyright 2018 The Go Authors. All rights reserved.
4
// Use of this source code is governed by a BSD-style
5
// license that can be found in the LICENSE file located
6
// here https://github.com/golang/sys/blob/master/LICENSE
20
hwcap_EVTSTRM = 1 << 2
26
hwcap_ATOMICS = 1 << 8
28
hwcap_ASIMDHP = 1 << 10
30
hwcap_ASIMDRDM = 1 << 12
38
hwcap_ASIMDDP = 1 << 20
39
hwcap_SHA512 = 1 << 21
41
hwcap_ASIMDFHM = 1 << 23
44
func detectOS(c *CPUInfo) bool {
45
// For now assuming no hyperthreading is reasonable.
46
c.LogicalCores = runtime.NumCPU()
47
c.PhysicalCores = c.LogicalCores
50
// We did not get values from the runtime.
51
// Try reading /proc/self/auxv
53
// From https://github.com/golang/sys
58
uintSize = int(32 << (^uint(0) >> 63))
61
buf, err := ioutil.ReadFile("/proc/self/auxv")
63
// e.g. on android /proc/self/auxv is not accessible, so silently
64
// ignore the error and leave Initialized = false. On some
65
// architectures (e.g. arm64) doinit() implements a fallback
66
// readout and will set Initialized = true again.
69
bo := binary.LittleEndian
70
for len(buf) >= 2*(uintSize/8) {
74
tag = uint(bo.Uint32(buf[0:]))
75
val = uint(bo.Uint32(buf[4:]))
78
tag = uint(bo.Uint64(buf[0:]))
79
val = uint(bo.Uint64(buf[8:]))
94
// HWCap was populated by the runtime from the auxiliary vector.
95
// Use HWCap information since reading aarch64 system registers
96
// is not supported in user space on older linux kernels.
97
c.featureSet.setIf(isSet(hwcap, hwcap_AES), AESARM)
98
c.featureSet.setIf(isSet(hwcap, hwcap_ASIMD), ASIMD)
99
c.featureSet.setIf(isSet(hwcap, hwcap_ASIMDDP), ASIMDDP)
100
c.featureSet.setIf(isSet(hwcap, hwcap_ASIMDHP), ASIMDHP)
101
c.featureSet.setIf(isSet(hwcap, hwcap_ASIMDRDM), ASIMDRDM)
102
c.featureSet.setIf(isSet(hwcap, hwcap_CPUID), ARMCPUID)
103
c.featureSet.setIf(isSet(hwcap, hwcap_CRC32), CRC32)
104
c.featureSet.setIf(isSet(hwcap, hwcap_DCPOP), DCPOP)
105
c.featureSet.setIf(isSet(hwcap, hwcap_EVTSTRM), EVTSTRM)
106
c.featureSet.setIf(isSet(hwcap, hwcap_FCMA), FCMA)
107
c.featureSet.setIf(isSet(hwcap, hwcap_FP), FP)
108
c.featureSet.setIf(isSet(hwcap, hwcap_FPHP), FPHP)
109
c.featureSet.setIf(isSet(hwcap, hwcap_JSCVT), JSCVT)
110
c.featureSet.setIf(isSet(hwcap, hwcap_LRCPC), LRCPC)
111
c.featureSet.setIf(isSet(hwcap, hwcap_PMULL), PMULL)
112
c.featureSet.setIf(isSet(hwcap, hwcap_SHA1), SHA1)
113
c.featureSet.setIf(isSet(hwcap, hwcap_SHA2), SHA2)
114
c.featureSet.setIf(isSet(hwcap, hwcap_SHA3), SHA3)
115
c.featureSet.setIf(isSet(hwcap, hwcap_SHA512), SHA512)
116
c.featureSet.setIf(isSet(hwcap, hwcap_SM3), SM3)
117
c.featureSet.setIf(isSet(hwcap, hwcap_SM4), SM4)
118
c.featureSet.setIf(isSet(hwcap, hwcap_SVE), SVE)
120
// The Samsung S9+ kernel reports support for atomics, but not all cores
121
// actually support them, resulting in SIGILL. See issue #28431.
122
// TODO(elias.naur): Only disable the optimization on bad chipsets on android.
123
c.featureSet.setIf(isSet(hwcap, hwcap_ATOMICS) && runtime.GOOS != "android", ATOMICS)
128
func isSet(hwc uint, value uint) bool {
129
return hwc&value != 0