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:
parent
e11632ee00
commit
1707a9977f
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user