From 1707a9977f2272333b86853c2ac09a3bdba9915e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 14 Feb 2012 01:23:15 -0500 Subject: [PATCH] runtime: on 386, fix FP control word on all threads, not just initial thread It is possible that Linux and Windows copy the FP control word from the parent thread when creating a new thread. Empirically, Darwin does not. Reset the FP control world in all cases. Enable the floating-point strconv test. Fixes #2917 (again). R=golang-dev, r, iant CC=golang-dev https://golang.org/cl/5660047 --- src/pkg/runtime/asm_386.s | 18 ++++++++++-------- src/pkg/runtime/asm_amd64.s | 4 ++++ src/pkg/runtime/asm_arm.s | 4 ++++ src/pkg/runtime/proc.c | 1 + src/pkg/runtime/runtime.h | 1 + src/pkg/strconv/atof_test.go | 11 +++++------ 6 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/pkg/runtime/asm_386.s b/src/pkg/runtime/asm_386.s index a4f94601dc..6bbec30638 100644 --- a/src/pkg/runtime/asm_386.s +++ b/src/pkg/runtime/asm_386.s @@ -5,14 +5,6 @@ #include "zasm_GOOS_GOARCH.h" TEXT _rt0_386(SB),7,$0 - // Linux, Windows start the FPU in extended double precision. - // Other operating systems use double precision. - // Change to double precision to match them, - // and to match other hardware that only has double. - PUSHL $0x27F - FLDCW 0(SP) - POPL AX - // copy arguments forward on an even stack MOVL 0(SP), AX // argc LEAL 4(SP), BX // argv @@ -99,6 +91,16 @@ TEXT runtime·breakpoint(SB),7,$0 INT $3 RET +TEXT runtime·asminit(SB),7,$0 + // Linux, Windows start the FPU in extended double precision. + // Other operating systems use double precision. + // Change to double precision to match them, + // and to match other hardware that only has double. + PUSHL $0x27F + FLDCW 0(SP) + POPL AX + RET + /* * go-routine */ diff --git a/src/pkg/runtime/asm_amd64.s b/src/pkg/runtime/asm_amd64.s index 9a660b5b73..2ea87a779f 100644 --- a/src/pkg/runtime/asm_amd64.s +++ b/src/pkg/runtime/asm_amd64.s @@ -80,6 +80,10 @@ TEXT runtime·breakpoint(SB),7,$0 BYTE $0xcc RET +TEXT runtime·asminit(SB),7,$0 + // No per-thread init. + RET + /* * go-routine */ diff --git a/src/pkg/runtime/asm_arm.s b/src/pkg/runtime/asm_arm.s index 58b18626fe..3d9a7a73ee 100644 --- a/src/pkg/runtime/asm_arm.s +++ b/src/pkg/runtime/asm_arm.s @@ -74,6 +74,10 @@ TEXT runtime·breakpoint(SB),7,$0 // no breakpoint yet; let program exit RET +TEXT runtime·asminit(SB),7,$0 + // No per-thread init. + RET + /* * go-routine */ diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index e008be9677..9a4d205901 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -720,6 +720,7 @@ runtime·mstart(void) runtime·gosave(&m->g0->sched); m->g0->sched.pc = (void*)-1; // make sure it is never used + runtime·asminit(); runtime·minit(); schedule(nil); } diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index d39b4bd693..48f6b3e34b 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -525,6 +525,7 @@ int32 runtime·atoi(byte*); void runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)); void runtime·signalstack(byte*, int32); G* runtime·malg(int32); +void runtime·asminit(void); void runtime·minit(void); Func* runtime·findfunc(uintptr); int32 runtime·funcline(Func*, uintptr); diff --git a/src/pkg/strconv/atof_test.go b/src/pkg/strconv/atof_test.go index 04bf336f45..5995023823 100644 --- a/src/pkg/strconv/atof_test.go +++ b/src/pkg/strconv/atof_test.go @@ -8,7 +8,6 @@ import ( "math" "math/rand" "reflect" - "runtime" . "strconv" "strings" "testing" @@ -232,16 +231,16 @@ var roundTripCases = []struct { s string }{ // Issue 2917. - // A Darwin/386 builder failed on AtofRandom with this case. + // This test will break the optimized conversion if the + // FPU is using 80-bit registers instead of 64-bit registers, + // usually because the operating system initialized the + // thread with 80-bit precision and the Go runtime didn't + // fix the FP control word. {8865794286000691 << 39, "4.87402195346389e+27"}, {8865794286000692 << 39, "4.8740219534638903e+27"}, } func TestRoundTrip(t *testing.T) { - if runtime.GOOS == "darwin" && runtime.GOARCH == "386" { - t.Logf("skipping round-trip test on darwin/386 - known failure, issue 2917") - return - } for _, tt := range roundTripCases { old := SetOptimize(false) s := FormatFloat(tt.f, 'g', -1, 64) -- 2.50.0