Skip to content

Commit

Permalink
cmd/dist: re-enable GOARM auto-detection
Browse files Browse the repository at this point in the history
cmd/dist will re-exec itself to detect VFP support at run-time.

Fixes golang#9732, golang#12548.

Change-Id: I9ad0c5c7fa3e97bd79a32da372e1a962565bb3af
Reviewed-on: https://go-review.googlesource.com/3973
Reviewed-by: Brad Fitzpatrick <[email protected]>
  • Loading branch information
minux committed Sep 10, 2015
1 parent a370fba commit 3f2baa3
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 31 deletions.
51 changes: 20 additions & 31 deletions src/cmd/dist/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,14 @@ func main() {
}
}

if len(os.Args) > 1 && os.Args[1] == "-check-goarm" {
useVFPv1() // might fail with SIGILL
println("VFPv1 OK.")
useVFPv3() // might fail with SIGILL
println("VFPv3 OK.")
os.Exit(0)
}

xinit()
xmain()
xexit(0)
Expand Down Expand Up @@ -515,40 +523,21 @@ func xgetgoarm() string {
// OpenBSD currently only supports softfloat.
return "5"
}
if goos != "linux" {
// All other arm platforms that we support
// require ARMv7.

// Try to exec ourselves in a mode to detect VFP support.
// Seeing how far it gets determines which instructions failed.
// The test is OS-agnostic.
out := run("", 0, os.Args[0], "-check-goarm")
v1ok := strings.Contains(out, "VFPv1 OK.")
v3ok := strings.Contains(out, "VFPv3 OK.")

if v1ok && v3ok {
return "7"
}
cpuinfo := readfile("/proc/cpuinfo")
goarm := "5"
for _, line := range splitlines(cpuinfo) {
line := strings.SplitN(line, ":", 2)
if len(line) < 2 {
continue
}
if strings.TrimSpace(line[0]) != "Features" {
continue
}
features := splitfields(line[1])
sort.Strings(features) // so vfpv3 sorts after vfp

// Infer GOARM value from the vfp features available
// on this host. Values of GOARM detected are:
// 5: no vfp support was found
// 6: vfp (v1) support was detected, but no higher
// 7: vfpv3 support was detected.
// This matches the assertions in runtime.checkarm.
for _, f := range features {
switch f {
case "vfp":
goarm = "6"
case "vfpv3":
goarm = "7"
}
}
if v1ok {
return "6"
}
return goarm
return "5"
}

func min(a, b int) int {
Expand Down
8 changes: 8 additions & 0 deletions src/cmd/dist/util_gc.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ func cansse2() bool {
cpuid(&info, 1)
return info[3]&(1<<26) != 0 // SSE2
}

// useVFPv1 tries to execute one VFPv1 instruction on ARM.
// It will crash the current process if VFPv1 is missing.
func useVFPv1()

// useVFPv3 tries to execute one VFPv3 instruction on ARM.
// It will crash the current process if VFPv3 is missing.
func useVFPv3()
4 changes: 4 additions & 0 deletions src/cmd/dist/util_gccgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ int supports_sse2() {
import "C"

func cansse2() bool { return C.supports_sse2() != 0 }

func useVFPv1() {}

func useVFPv3() {}
17 changes: 17 additions & 0 deletions src/cmd/dist/vfp_arm.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build gc,arm

#include "textflag.h"

// try to run "vmov.f64 d0, d0" instruction
TEXT ·useVFPv1(SB),NOSPLIT,$0
WORD $0xeeb00b40 // vmov.f64 d0, d0
RET

// try to run VFPv3-only "vmov.f64 d0, #112" instruction
TEXT ·useVFPv3(SB),NOSPLIT,$0
WORD $0xeeb70b00 // vmov.f64 d0, #112
RET
13 changes: 13 additions & 0 deletions src/cmd/dist/vfp_default.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !arm,gc

#include "textflag.h"

TEXT ·useVFPv1(SB),NOSPLIT,$0
RET

TEXT ·useVFPv3(SB),NOSPLIT,$0
RET

0 comments on commit 3f2baa3

Please sign in to comment.