Commit 3d50aaf4 authored by Shenghou Ma's avatar Shenghou Ma

cmd/dist: support for NetBSD/ARM

1. when executing a unsupported VFP instruction, the NetBSD kernel somehow
doesn't report SIGILL, and instead just spin and spin, we add a alarm(2)
to detect this case (albeit this is a kernel bug).
2. NetBSD/ARM's VFP11 support is not complete, so temporarily disable it.
3. The default gcc shipped with NetBSD-current mis-optimizes our code
at -O2, so lower the optimization level to -O1 on NetBSD/ARM.

R=dave, rsc
CC=golang-dev
https://golang.org/cl/7286044
parent a17b7b94
......@@ -17,6 +17,18 @@ static void useVFPv1(void);
char *
xgetgoarm(void)
{
#if defined(__NetBSD__) || defined(__FreeBSD__)
// NetBSD has buggy support for VFPv2 (incorrect inexact,
// denormial, and NaN handling). When GOARM=6, some of our
// math tests fails on Raspberry Pi.
// Thus we return "5" here for safety, the user is free
// to override.
// Note: using GOARM=6 with cgo can trigger a kernel assertion
// failure and crash NetBSD/evbarm kernel.
// FreeBSD also have broken VFP support, so disable VFP also
// on FreeBSD.
return "5";
#endif
if(xtryexecfunc(useVFPv3))
return "7";
else if(xtryexecfunc(useVFPv1))
......
......@@ -411,7 +411,13 @@ static char *proto_gccargs[] = {
"-fno-common",
"-ggdb",
"-pipe",
#if defined(__NetBSD__) && defined(__arm__)
// GCC 4.5.4 (NetBSD nb1 20120916) on ARM is known to mis-optimize gc/mparith3.c
// Fix available at http://patchwork.ozlabs.org/patch/64562/.
"-O1",
#else
"-O2",
#endif
};
static Vec gccargs;
......
......@@ -745,17 +745,24 @@ static void sigillhand(int);
// xtryexecfunc tries to execute function f, if any illegal instruction
// signal received in the course of executing that function, it will
// return 0, otherwise it will return 1.
// Some systems (notably NetBSD) will spin and spin when executing VFPv3
// instructions on VFPv2 system (e.g. Raspberry Pi) without ever triggering
// SIGILL, so we set a 1-second alarm to catch that case.
int
xtryexecfunc(void (*f)(void))
{
int r;
r = 0;
signal(SIGILL, sigillhand);
signal(SIGALRM, sigillhand);
alarm(1);
if(sigsetjmp(sigill_jmpbuf, 1) == 0) {
f();
r = 1;
}
signal(SIGILL, SIG_DFL);
alarm(0);
signal(SIGALRM, SIG_DFL);
return r;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment