_ CacheLinePad
}
+var ARM arm
+
+// The booleans in arm contain the correspondingly named cpu feature bit.
+// The struct is padded to avoid false sharing.
+type arm struct {
+ _ CacheLinePad
+ HasIDIVA bool
+ _ CacheLinePad
+}
+
var ARM64 arm64
// The booleans in arm64 contain the correspondingly named cpu feature bit.
package cpu
const CacheLineSize = 32
+
+// arm doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2.
+// These are linknamed in runtime/os_(linux|freebsd)_arm.go and are
+// initialized by archauxv().
+// These should not be changed after they are initialized.
+var HWCap uint
+var HWCap2 uint
+
+// HWCAP/HWCAP2 bits. These are exposed by Linux and FreeBSD.
+const (
+ hwcap_IDIVA = 1 << 17
+)
+
+func doinit() {
+ options = []option{
+ {"idiva", &ARM.HasIDIVA},
+ }
+
+ // HWCAP feature bits
+ ARM.HasIDIVA = isSet(HWCap, hwcap_IDIVA)
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}
// +build !386
// +build !amd64
// +build !amd64p32
+// +build !arm
// +build !arm64
// +build !ppc64
// +build !ppc64le
offset_x86_HasAVX2 = unsafe.Offsetof(cpu.X86.HasAVX2)
offset_x86_HasERMS = unsafe.Offsetof(cpu.X86.HasERMS)
offset_x86_HasSSE2 = unsafe.Offsetof(cpu.X86.HasSSE2)
+
+ offset_arm_HasIDIVA = unsafe.Offsetof(cpu.ARM.HasIDIVA)
)
package runtime
-var hardDiv bool // TODO: set if a hardware divider is available
-
func checkgoarm() {
// TODO(minux): FP checks like in os_linux_arm.go.
_AT_PAGESZ = 6 // Page size in bytes
_AT_TIMEKEEP = 22 // Pointer to timehands.
_AT_HWCAP = 25 // CPU feature flags
+ _AT_HWCAP2 = 26 // CPU feature flags 2
)
func sysauxv(auxv []uintptr) {
package runtime
+import "internal/cpu"
+
const (
_HWCAP_VFP = 1 << 6
_HWCAP_VFPv3 = 1 << 13
- _HWCAP_IDIVA = 1 << 17
)
-var hwcap = ^uint32(0) // set by archauxv
-var hardDiv bool // set if a hardware divider is available
+// AT_HWCAP is not available on FreeBSD-11.1-RELEASE or earlier.
+// Default to mandatory VFP hardware support for arm being available.
+// If AT_HWCAP is available goarmHWCap will be updated in archauxv.
+// TODO(moehrmann) remove once all go supported FreeBSD versions support _AT_HWCAP.
+var goarmHWCap uint = (_HWCAP_VFP | _HWCAP_VFPv3)
func checkgoarm() {
- if goarm > 5 && hwcap&_HWCAP_VFP == 0 {
+ // Update cpu.HWCap to match goarmHWCap in case they were not updated in archauxv.
+ cpu.HWCap = goarmHWCap
+
+ if goarm > 5 && cpu.HWCap&_HWCAP_VFP == 0 {
print("runtime: this CPU has no floating point hardware, so it cannot run\n")
print("this GOARM=", goarm, " binary. Recompile using GOARM=5.\n")
exit(1)
}
- if goarm > 6 && hwcap&_HWCAP_VFPv3 == 0 {
+ if goarm > 6 && cpu.HWCap&_HWCAP_VFPv3 == 0 {
print("runtime: this CPU has no VFPv3 floating point hardware, so it cannot run\n")
print("this GOARM=", goarm, " binary. Recompile using GOARM=5 or GOARM=6.\n")
exit(1)
func archauxv(tag, val uintptr) {
switch tag {
- case _AT_HWCAP: // CPU capability bit flags
- hwcap = uint32(val)
- hardDiv = (hwcap & _HWCAP_IDIVA) != 0
+ case _AT_HWCAP:
+ cpu.HWCap = uint(val)
+ goarmHWCap = cpu.HWCap
+ case _AT_HWCAP2:
+ cpu.HWCap2 = uint(val)
}
}
package runtime
-import "unsafe"
+import (
+ "internal/cpu"
+ "unsafe"
+)
const (
_AT_PLATFORM = 15 // introduced in at least 2.6.11
_HWCAP_VFP = 1 << 6 // introduced in at least 2.6.11
_HWCAP_VFPv3 = 1 << 13 // introduced in 2.6.30
- _HWCAP_IDIVA = 1 << 17
)
var randomNumber uint32
var armArch uint8 = 6 // we default to ARMv6
-var hwcap uint32 // set by archauxv
-var hardDiv bool // set if a hardware divider is available
func checkgoarm() {
// On Android, /proc/self/auxv might be unreadable and hwcap won't
if GOOS == "android" {
return
}
- if goarm > 5 && hwcap&_HWCAP_VFP == 0 {
+ if goarm > 5 && cpu.HWCap&_HWCAP_VFP == 0 {
print("runtime: this CPU has no floating point hardware, so it cannot run\n")
print("this GOARM=", goarm, " binary. Recompile using GOARM=5.\n")
exit(1)
}
- if goarm > 6 && hwcap&_HWCAP_VFPv3 == 0 {
+ if goarm > 6 && cpu.HWCap&_HWCAP_VFPv3 == 0 {
print("runtime: this CPU has no VFPv3 floating point hardware, so it cannot run\n")
print("this GOARM=", goarm, " binary. Recompile using GOARM=5 or GOARM=6.\n")
exit(1)
armArch = t - '0'
}
- case _AT_HWCAP: // CPU capability bit flags
- hwcap = uint32(val)
- hardDiv = (hwcap & _HWCAP_IDIVA) != 0
+ case _AT_HWCAP:
+ cpu.HWCap = uint(val)
+ case _AT_HWCAP2:
+ cpu.HWCap2 = uint(val)
}
}
package runtime
-var hardDiv bool // TODO: set if a hardware divider is available
-
func checkgoarm() {
// TODO(minux): FP checks like in os_linux_arm.go.
import "unsafe"
-var hardDiv bool // TODO: set if a hardware divider is available
-
func lwp_mcontext_init(mc *mcontextt, stk unsafe.Pointer, mp *m, gp *g, fn uintptr) {
// Machine dependent mcontext initialisation for LWP.
mc.__gregs[_REG_R15] = uint32(funcPC(lwp_tramp))
package runtime
-var hardDiv bool // TODO: set if a hardware divider is available
-
func checkgoarm() {
// TODO(minux): FP checks like in os_linux_arm.go.
package runtime
-var hardDiv bool // TODO: set if a hardware divider is available
-
func checkgoarm() {
return // TODO(minux)
}
// the RET instruction will clobber R12 on nacl, and the compiler's register
// allocator needs to know.
TEXT runtime·udiv(SB),NOSPLIT|NOFRAME,$0
- MOVBU runtime·hardDiv(SB), Ra
+ MOVBU internal∕cpu·ARM+const_offset_arm_HasIDIVA(SB), Ra
CMP $0, Ra
BNE udiv_hardware