Setting GOARM automatically on linux/arm

113 views
Skip to first unread message

Dave Cheney

unread,
Aug 9, 2012, 5:39:46 AM8/9/12
to golang-dev
Hello,

I would like to propose two changes for linux/arm that remove the
requirement to set GOARM to match the architecture of their host.

http://codereview.appspot.com/6446105/ gives the go command the
ability to set the correct GOARM value based on the cpu features
advertised in /proc/cpuinfo.

http://codereview.appspot.com/6458104/ always builds the bootstrap
version of go in soft float mode, which then leverages 6446105 to
provide the correct GOARM setting for the main build.

With both of these CLs in place, I can do a complete ./all.bash on an
ARMv5 host without supplying GOARM manually.

Cheers

Dave

Russ Cox

unread,
Aug 9, 2012, 4:09:58 PM8/9/12
to Dave Cheney, golang-dev
Making the go command adjust magically is something I'd like to avoid.
I also don't want to make the bootstrap process more complex, at least
not in this way.

I propose the following instead.

First, make the runtime print a message when a binary has been
compiled with too high a GOARM for the current system. That will
replace the 'illegal instruction' exceptions with a nice message. The
information should be in the auxv array, so it should be very easy to
do. If it requires grubbing around in files, maybe it makes more sense
to put in a signal handler for illegal instruction. Either way, we
have to fix this first.

Once that is done, then I think it would be reasonable to infer and
hard-code GOARM the same way we infer and hard-code GOOS and GOARCH.
That is:
* in cmd/dist, compute the right GOARM if it is not set on startup and GOOS=arm
* in cmd/dist, print the GOARM variable in 'go tool dist env'. ("" for non-arm)
* in cmd/dist/build.c's special case for lib9's goos.c, pass -DGOARM
like the others (probably easiest as a string)
* in lib9 add a getgoarm like getgoos.
* in 5l add a -V flag that takes a numeric argument (goarm =
atoi(EARGF(usage()))), and make -F an alias for goarm = 5, with the
default setting being goarm = atoi(getgoarm())

Once that is done then I think we can go back to discussing settings
of goarm other than 5 and not-5.

I realize this is similar to what you ended up with, but there is a
critical difference, namely that the go command does not change
behavior when you move it from one machine to the next. We already
have behavior that saves all.bash-time state, and if we're going to do
state detection I'd like to keep it all there.

Thanks.
Russ

Dave Cheney

unread,
Aug 9, 2012, 7:13:06 PM8/9/12
to Russ Cox, golang-dev
Thank you for your detailed reply Russ.

minux

unread,
Aug 10, 2012, 6:28:10 AM8/10/12
to Russ Cox, Dave Cheney, golang-dev
On Fri, Aug 10, 2012 at 4:09 AM, Russ Cox <r...@golang.org> wrote:
First, make the runtime print a message when a binary has been
compiled with too high a GOARM for the current system. That will
replace the 'illegal instruction' exceptions with a nice message. The
information should be in the auxv array, so it should be very easy to
do. If it requires grubbing around in files, maybe it makes more sense
to put in a signal handler for illegal instruction. Either way, we
have to fix this first.
this needs a way to embed link-time $GOARM into the binary, or
we need to guess/detect $GOARM at run-time.

Once that is done, then I think it would be reasonable to infer and
hard-code GOARM the same way we infer and hard-code GOOS and GOARCH.
That is:
 * in cmd/dist, compute the right GOARM if it is not set on startup and GOOS=arm 
what's the default GOARM value? (for example, when cross compiling) 
 * in cmd/dist, print the GOARM variable in 'go tool dist env'. ("" for non-arm)
 * in cmd/dist/build.c's special case for lib9's goos.c, pass -DGOARM
like the others (probably easiest as a string)
 * in lib9 add a getgoarm like getgoos.
 * in 5l add a -V flag that takes a numeric argument (goarm =
atoi(EARGF(usage()))), and make -F an alias for goarm = 5, with the
default setting being goarm = atoi(getgoarm())
5l -V is used, meaning show version string. why we need to add a flag for it?
do we want to deprecate manual setting of $GOARM?

minux

unread,
Aug 10, 2012, 9:45:35 AM8/10/12
to Russ Cox, Dave Cheney, golang-dev
On Fri, Aug 10, 2012 at 4:09 AM, Russ Cox <r...@golang.org> wrote:
 * in cmd/dist, compute the right GOARM if it is not set on startup and GOOS=arm
 * in cmd/dist, print the GOARM variable in 'go tool dist env'. ("" for non-arm)
 * in cmd/dist/build.c's special case for lib9's goos.c, pass -DGOARM
like the others (probably easiest as a string)
 * in lib9 add a getgoarm like getgoos.
 * in 5l add a -V flag that takes a numeric argument (goarm =
atoi(EARGF(usage()))), and make -F an alias for goarm = 5, with the
default setting being goarm = atoi(getgoarm())
there are some difficulties for this approach.

the bigest (and fundamental) one is:
our GOARM is somewhat misnamed, probably it should be named GOVFP.
that is, arm architecture version and whether it has vfp or not is orthogonal.

for example, the NXP LPC32x0 series SoC combines ARM926EJ-S (ARMv5)
with a VFP9 (VFPv1), and we do support VFPv1 (after disabling generation
of "vmov (imm)" instruction).

i can't think of a good backward-compatible solution to this problem; vfp really
should be a feature of a ARM core, and not tied to the architecture version of
the core.

minux

unread,
Aug 10, 2012, 10:02:17 AM8/10/12
to Russ Cox, Dave Cheney, golang-dev
some facts:
1. integer code generated by 5c and 5g only requires ARMv5, so in theory, a go
program that doesn't use floating point should be runnable on any ARMv5+
processors.
2. fp code generated by 5c and 5g requires VFPv3 (or VFPv1 if we disable one
type of instruction [vmov (imm)]).
3. our runtime and all the low-level packages are portable across ARMv5+
processors.

my conclusion: we only need to test at runtime the existence and version of VFP
(runtime.hwcap has this kind of information), and we only need two (or three) type
of binaries (soft-fp, VFPv1/VFPv2, and perhaps VFPv3&NEON); if we want to relieve
the burden on the user, we can automatically detect whether there is a VFP and
always use first two types; advanced user can select the last type manually if he
is aware of the problem.

Reply all
Reply to author
Forward
0 new messages