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
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))
"-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;
// 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;
}