1
0
mirror of https://github.com/golang/go synced 2024-11-24 23:07:56 -07:00

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
This commit is contained in:
Russ Cox 2012-02-14 01:23:15 -05:00
parent e11632ee00
commit 1707a9977f
6 changed files with 25 additions and 14 deletions

View File

@ -5,14 +5,6 @@
#include "zasm_GOOS_GOARCH.h" #include "zasm_GOOS_GOARCH.h"
TEXT _rt0_386(SB),7,$0 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 // copy arguments forward on an even stack
MOVL 0(SP), AX // argc MOVL 0(SP), AX // argc
LEAL 4(SP), BX // argv LEAL 4(SP), BX // argv
@ -99,6 +91,16 @@ TEXT runtime·breakpoint(SB),7,$0
INT $3 INT $3
RET 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 * go-routine
*/ */

View File

@ -80,6 +80,10 @@ TEXT runtime·breakpoint(SB),7,$0
BYTE $0xcc BYTE $0xcc
RET RET
TEXT runtime·asminit(SB),7,$0
// No per-thread init.
RET
/* /*
* go-routine * go-routine
*/ */

View File

@ -74,6 +74,10 @@ TEXT runtime·breakpoint(SB),7,$0
// no breakpoint yet; let program exit // no breakpoint yet; let program exit
RET RET
TEXT runtime·asminit(SB),7,$0
// No per-thread init.
RET
/* /*
* go-routine * go-routine
*/ */

View File

@ -720,6 +720,7 @@ runtime·mstart(void)
runtime·gosave(&m->g0->sched); runtime·gosave(&m->g0->sched);
m->g0->sched.pc = (void*)-1; // make sure it is never used m->g0->sched.pc = (void*)-1; // make sure it is never used
runtime·asminit();
runtime·minit(); runtime·minit();
schedule(nil); schedule(nil);
} }

View File

@ -525,6 +525,7 @@ int32 runtime·atoi(byte*);
void runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)); void runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void));
void runtime·signalstack(byte*, int32); void runtime·signalstack(byte*, int32);
G* runtime·malg(int32); G* runtime·malg(int32);
void runtime·asminit(void);
void runtime·minit(void); void runtime·minit(void);
Func* runtime·findfunc(uintptr); Func* runtime·findfunc(uintptr);
int32 runtime·funcline(Func*, uintptr); int32 runtime·funcline(Func*, uintptr);

View File

@ -8,7 +8,6 @@ import (
"math" "math"
"math/rand" "math/rand"
"reflect" "reflect"
"runtime"
. "strconv" . "strconv"
"strings" "strings"
"testing" "testing"
@ -232,16 +231,16 @@ var roundTripCases = []struct {
s string s string
}{ }{
// Issue 2917. // 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"}, {8865794286000691 << 39, "4.87402195346389e+27"},
{8865794286000692 << 39, "4.8740219534638903e+27"}, {8865794286000692 << 39, "4.8740219534638903e+27"},
} }
func TestRoundTrip(t *testing.T) { 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 { for _, tt := range roundTripCases {
old := SetOptimize(false) old := SetOptimize(false)
s := FormatFloat(tt.f, 'g', -1, 64) s := FormatFloat(tt.f, 'g', -1, 64)