mirror of
https://github.com/golang/go
synced 2024-11-23 08:40:08 -07:00
math: remove most 387 implementations
The Surface Pro X's 386 simulator is not completely faithful to a real 387. The most egregious problem is that it computes Log2(8) as 2.9999999999999996, but it has some other subtler problems as well. All the problems occur in routines that we don't even bother with assembly for on amd64. If the speed of Go code is OK on amd64 it should be OK on 386 too. Just remove all the 386-only assembly functions. This leaves Ceil, Floor, Trunc, Hypot, and Sqrt in 386 assembly, all of which are also in assembly on amd64 and all of which pass their tests on Surface Pro X. Compared to amd64, the 386 port omits assembly for Min, Max, and Log. It never had Min and Max, and this CL deletes Log because Log2 wasn't even correct. (None of the other architectures have assembly Log either.) Change-Id: I5eb6c61084467035269d4098a36001447b7a0601 Reviewed-on: https://go-review.googlesource.com/c/go/+/291229 Trust: Russ Cox <rsc@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
c7c6c113be
commit
474d5f4f4d
@ -1,30 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Asin(x float64) float64
|
||||
TEXT ·Asin(SB),NOSPLIT,$0
|
||||
FMOVD x+0(FP), F0 // F0=sin(x)
|
||||
FMOVD F0, F1 // F0=sin(x), F1=sin(x)
|
||||
FMULD F0, F0 // F0=sin(x)*sin(x), F1=sin(x)
|
||||
FLD1 // F0=1, F1=sin(x)*sin(x), F2=sin(x)
|
||||
FSUBRDP F0, F1 // F0=1-sin(x)*sin(x) (=cos(x)*cos(x)), F1=sin(x)
|
||||
FSQRT // F0=cos(x), F1=sin(x)
|
||||
FPATAN // F0=arcsin(sin(x))=x
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
||||
|
||||
// func Acos(x float64) float64
|
||||
TEXT ·Acos(SB),NOSPLIT,$0
|
||||
FMOVD x+0(FP), F0 // F0=cos(x)
|
||||
FMOVD F0, F1 // F0=cos(x), F1=cos(x)
|
||||
FMULD F0, F0 // F0=cos(x)*cos(x), F1=cos(x)
|
||||
FLD1 // F0=1, F1=cos(x)*cos(x), F2=cos(x)
|
||||
FSUBRDP F0, F1 // F0=1-cos(x)*cos(x) (=sin(x)*sin(x)), F1=cos(x)
|
||||
FSQRT // F0=sin(x), F1=cos(x)
|
||||
FXCHD F0, F1 // F0=cos(x), F1=sin(x)
|
||||
FPATAN // F0=arccos(cos(x))=x
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
@ -1,13 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Atan2(y, x float64) float64 // =atan(y/x)
|
||||
TEXT ·Atan2(SB),NOSPLIT,$0
|
||||
FMOVD y+0(FP), F0 // F0=y
|
||||
FMOVD x+8(FP), F0 // F0=x, F1=y
|
||||
FPATAN // F0=atan(F1/F0)
|
||||
FMOVDP F0, ret+16(FP)
|
||||
RET
|
@ -1,13 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Atan(x float64) float64
|
||||
TEXT ·Atan(SB),NOSPLIT,$0
|
||||
FMOVD x+0(FP), F0 // F0=x
|
||||
FLD1 // F0=1, F1=x
|
||||
FPATAN // F0=atan(F1/F0)
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
@ -1,40 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Exp2(x float64) float64
|
||||
TEXT ·Exp2(SB),NOSPLIT,$0
|
||||
// test bits for not-finite
|
||||
MOVL x_hi+4(FP), AX
|
||||
ANDL $0x7ff00000, AX
|
||||
CMPL AX, $0x7ff00000
|
||||
JEQ not_finite
|
||||
FMOVD x+0(FP), F0 // F0=x
|
||||
FMOVD F0, F1 // F0=x, F1=x
|
||||
FRNDINT // F0=int(x), F1=x
|
||||
FSUBD F0, F1 // F0=int(x), F1=x-int(x)
|
||||
FXCHD F0, F1 // F0=x-int(x), F1=int(x)
|
||||
F2XM1 // F0=2**(x-int(x))-1, F1=int(x)
|
||||
FLD1 // F0=1, F1=2**(x-int(x))-1, F2=int(x)
|
||||
FADDDP F0, F1 // F0=2**(x-int(x)), F1=int(x)
|
||||
FSCALE // F0=2**x, F1=int(x)
|
||||
FMOVDP F0, F1 // F0=2**x
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
||||
not_finite:
|
||||
// test bits for -Inf
|
||||
MOVL x_hi+4(FP), BX
|
||||
MOVL x_lo+0(FP), CX
|
||||
CMPL BX, $0xfff00000
|
||||
JNE not_neginf
|
||||
CMPL CX, $0
|
||||
JNE not_neginf
|
||||
MOVL $0, ret_lo+8(FP)
|
||||
MOVL $0, ret_hi+12(FP)
|
||||
RET
|
||||
not_neginf:
|
||||
MOVL CX, ret_lo+8(FP)
|
||||
MOVL BX, ret_hi+12(FP)
|
||||
RET
|
@ -1,57 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Expm1(x float64) float64
|
||||
TEXT ·Expm1(SB),NOSPLIT,$0
|
||||
FLDLN2 // F0=log(2) = 1/log2(e) ~ 0.693147
|
||||
FMOVD x+0(FP), F0 // F0=x, F1=1/log2(e)
|
||||
FABS // F0=|x|, F1=1/log2(e)
|
||||
FUCOMPP F0, F1 // compare F0 to F1
|
||||
FSTSW AX
|
||||
SAHF
|
||||
JCC use_exp // jump if F0 >= F1
|
||||
FLDL2E // F0=log2(e)
|
||||
FMULD x+0(FP), F0 // F0=x*log2(e) (-1<F0<1)
|
||||
F2XM1 // F0=e**x-1 = 2**(x*log2(e))-1
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
||||
use_exp:
|
||||
// test bits for not-finite
|
||||
MOVL x_hi+4(FP), AX
|
||||
ANDL $0x7ff00000, AX
|
||||
CMPL AX, $0x7ff00000
|
||||
JEQ not_finite
|
||||
FLDL2E // F0=log2(e)
|
||||
FMULD x+0(FP), F0 // F0=x*log2(e)
|
||||
FMOVD F0, F1 // F0=x*log2(e), F1=x*log2(e)
|
||||
FRNDINT // F0=int(x*log2(e)), F1=x*log2(e)
|
||||
FSUBD F0, F1 // F0=int(x*log2(e)), F1=x*log2(e)-int(x*log2(e))
|
||||
FXCHD F0, F1 // F0=x*log2(e)-int(x*log2(e)), F1=int(x*log2(e))
|
||||
F2XM1 // F0=2**(x*log2(e)-int(x*log2(e)))-1, F1=int(x*log2(e))
|
||||
FLD1 // F0=1, F1=2**(x*log2(e)-int(x*log2(e)))-1, F2=int(x*log2(e))
|
||||
FADDDP F0, F1 // F0=2**(x*log2(e)-int(x*log2(e))), F1=int(x*log2(e))
|
||||
FSCALE // F0=e**x, F1=int(x*log2(e))
|
||||
FMOVDP F0, F1 // F0=e**x
|
||||
FLD1 // F0=1, F1=e**x
|
||||
FSUBDP F0, F1 // F0=e**x-1
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
||||
not_finite:
|
||||
// test bits for -Inf
|
||||
MOVL x_hi+4(FP), BX
|
||||
MOVL x_lo+0(FP), CX
|
||||
CMPL BX, $0xfff00000
|
||||
JNE not_neginf
|
||||
CMPL CX, $0
|
||||
JNE not_neginf
|
||||
FLD1 // F0=1
|
||||
FCHS // F0=-1
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
||||
not_neginf:
|
||||
MOVL CX, ret_lo+8(FP)
|
||||
MOVL BX, ret_hi+12(FP)
|
||||
RET
|
@ -1,25 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Frexp(f float64) (frac float64, exp int)
|
||||
TEXT ·Frexp(SB),NOSPLIT,$0
|
||||
FMOVD f+0(FP), F0 // F0=f
|
||||
FXAM
|
||||
FSTSW AX
|
||||
SAHF
|
||||
JNP nan_zero_inf
|
||||
JCS nan_zero_inf
|
||||
FXTRACT // F0=f (0<=f<1), F1=e
|
||||
FMULD $(0.5), F0 // F0=f (0.5<=f<1), F1=e
|
||||
FMOVDP F0, frac+8(FP) // F0=e
|
||||
FLD1 // F0=1, F1=e
|
||||
FADDDP F0, F1 // F0=e+1
|
||||
FMOVLP F0, exp+16(FP) // (int=int32)
|
||||
RET
|
||||
nan_zero_inf:
|
||||
FMOVDP F0, frac+8(FP) // F0=e
|
||||
MOVL $0, exp+16(FP) // exp=0
|
||||
RET
|
@ -1,14 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Ldexp(frac float64, exp int) float64
|
||||
TEXT ·Ldexp(SB),NOSPLIT,$0
|
||||
FMOVL exp+8(FP), F0 // F0=exp
|
||||
FMOVD frac+0(FP), F0 // F0=frac, F1=e
|
||||
FSCALE // F0=x*2**e, F1=e
|
||||
FMOVDP F0, F1 // F0=x*2**e
|
||||
FMOVDP F0, ret+12(FP)
|
||||
RET
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Log10(x float64) float64
|
||||
TEXT ·Log10(SB),NOSPLIT,$0
|
||||
FLDLG2 // F0=log10(2)
|
||||
FMOVD x+0(FP), F0 // F0=x, F1=log10(2)
|
||||
FYL2X // F0=log10(x)=log2(x)*log10(2)
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
||||
|
||||
// func Log2(x float64) float64
|
||||
TEXT ·Log2(SB),NOSPLIT,$0
|
||||
FLD1 // F0=1
|
||||
FMOVD x+0(FP), F0 // F0=x, F1=1
|
||||
FYL2X // F0=log2(x)
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
@ -1,27 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Log1p(x float64) float64
|
||||
TEXT ·Log1p(SB),NOSPLIT,$0
|
||||
FMOVD $(2.928932188134524e-01), F0
|
||||
FMOVD x+0(FP), F0 // F0=x, F1=1-sqrt(2)/2 = 0.29289321881345247559915564
|
||||
FABS // F0=|x|, F1=1-sqrt(2)/2
|
||||
FUCOMPP F0, F1 // compare F0 to F1
|
||||
FSTSW AX
|
||||
FLDLN2 // F0=log(2)
|
||||
ANDW $0x0100, AX
|
||||
JEQ use_fyl2x // jump if F0 >= F1
|
||||
FMOVD x+0(FP), F0 // F0=x, F1=log(2)
|
||||
FYL2XP1 // F0=log(1+x)=log2(1+x)*log(2)
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
||||
use_fyl2x:
|
||||
FLD1 // F0=1, F2=log(2)
|
||||
FADDD x+0(FP), F0 // F0=1+x, F1=log(2)
|
||||
FYL2X // F0=log(1+x)=log2(1+x)*log(2)
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
||||
|
@ -1,13 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Log(x float64) float64
|
||||
TEXT ·Log(SB),NOSPLIT,$0
|
||||
FLDLN2 // F0=log(2)
|
||||
FMOVD x+0(FP), F0 // F0=x, F1=log(2)
|
||||
FYL2X // F0=log(x)=log2(x)*log(2)
|
||||
FMOVDP F0, ret+8(FP)
|
||||
RET
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Mod(x, y float64) float64
|
||||
TEXT ·Mod(SB),NOSPLIT,$0
|
||||
FMOVD y+8(FP), F0 // F0=y
|
||||
FMOVD x+0(FP), F0 // F0=x, F1=y
|
||||
FPREM // F0=reduced_x, F1=y
|
||||
FSTSW AX // AX=status word
|
||||
ANDW $0x0400, AX
|
||||
JNE -3(PC) // jump if reduction incomplete
|
||||
FMOVDP F0, F1 // F0=x-q*y
|
||||
FMOVDP F0, ret+16(FP)
|
||||
RET
|
@ -1,34 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Modf(f float64) (int float64, frac float64)
|
||||
TEXT ·Modf(SB),NOSPLIT,$0
|
||||
// special case for f == -0.0
|
||||
MOVL f_hi+4(FP), DX // high word
|
||||
MOVL f_lo+0(FP), AX // low word
|
||||
CMPL DX, $(1<<31) // beginning of -0.0
|
||||
JNE notNegativeZero
|
||||
CMPL AX, $0 // could be denormalized
|
||||
JNE notNegativeZero
|
||||
MOVL AX, int_lo+8(FP)
|
||||
MOVL DX, int_hi+12(FP)
|
||||
MOVL AX, frac_lo+16(FP)
|
||||
MOVL DX, frac_hi+20(FP)
|
||||
RET
|
||||
notNegativeZero:
|
||||
FMOVD f+0(FP), F0 // F0=f
|
||||
FMOVD F0, F1 // F0=f, F1=f
|
||||
FSTCW -2(SP) // save old Control Word
|
||||
MOVW -2(SP), AX
|
||||
ORW $0x0c00, AX // Rounding Control set to truncate
|
||||
MOVW AX, -4(SP) // store new Control Word
|
||||
FLDCW -4(SP) // load new Control Word
|
||||
FRNDINT // F0=trunc(f), F1=f
|
||||
FLDCW -2(SP) // load old Control Word
|
||||
FSUBD F0, F1 // F0=trunc(f), F1=f-trunc(f)
|
||||
FMOVDP F0, int+8(FP) // F0=f-trunc(f)
|
||||
FMOVDP F0, frac+16(FP)
|
||||
RET
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func Remainder(x, y float64) float64
|
||||
TEXT ·Remainder(SB),NOSPLIT,$0
|
||||
FMOVD y+8(FP), F0 // F0=y
|
||||
FMOVD x+0(FP), F0 // F0=x, F1=y
|
||||
FPREM1 // F0=reduced_x, F1=y
|
||||
FSTSW AX // AX=status word
|
||||
ANDW $0x0400, AX
|
||||
JNE -3(PC) // jump if reduction incomplete
|
||||
FMOVDP F0, F1 // F0=x-q*y
|
||||
FMOVDP F0, ret+16(FP)
|
||||
RET
|
@ -4,12 +4,24 @@
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·Acos(SB), NOSPLIT, $0
|
||||
JMP ·acos(SB)
|
||||
|
||||
TEXT ·Acosh(SB), NOSPLIT, $0
|
||||
JMP ·acosh(SB)
|
||||
|
||||
TEXT ·Asin(SB), NOSPLIT, $0
|
||||
JMP ·asin(SB)
|
||||
|
||||
TEXT ·Asinh(SB), NOSPLIT, $0
|
||||
JMP ·asinh(SB)
|
||||
|
||||
TEXT ·Atan(SB), NOSPLIT, $0
|
||||
JMP ·atan(SB)
|
||||
|
||||
TEXT ·Atan2(SB), NOSPLIT, $0
|
||||
JMP ·atan2(SB)
|
||||
|
||||
TEXT ·Atanh(SB), NOSPLIT, $0
|
||||
JMP ·atanh(SB)
|
||||
|
||||
@ -31,15 +43,48 @@ TEXT ·Erfc(SB), NOSPLIT, $0
|
||||
TEXT ·Exp(SB), NOSPLIT, $0
|
||||
JMP ·exp(SB)
|
||||
|
||||
TEXT ·Exp2(SB), NOSPLIT, $0
|
||||
JMP ·exp2(SB)
|
||||
|
||||
TEXT ·Expm1(SB), NOSPLIT, $0
|
||||
JMP ·expm1(SB)
|
||||
|
||||
TEXT ·Frexp(SB), NOSPLIT, $0
|
||||
JMP ·frexp(SB)
|
||||
|
||||
TEXT ·Ldexp(SB), NOSPLIT, $0
|
||||
JMP ·ldexp(SB)
|
||||
|
||||
TEXT ·Log10(SB), NOSPLIT, $0
|
||||
JMP ·log10(SB)
|
||||
|
||||
TEXT ·Log2(SB), NOSPLIT, $0
|
||||
JMP ·log2(SB)
|
||||
|
||||
TEXT ·Log1p(SB), NOSPLIT, $0
|
||||
JMP ·log1p(SB)
|
||||
|
||||
TEXT ·Log(SB), NOSPLIT, $0
|
||||
JMP ·log(SB)
|
||||
|
||||
TEXT ·Max(SB), NOSPLIT, $0
|
||||
JMP ·max(SB)
|
||||
|
||||
TEXT ·Min(SB), NOSPLIT, $0
|
||||
JMP ·min(SB)
|
||||
|
||||
TEXT ·Mod(SB), NOSPLIT, $0
|
||||
JMP ·mod(SB)
|
||||
|
||||
TEXT ·Modf(SB), NOSPLIT, $0
|
||||
JMP ·modf(SB)
|
||||
|
||||
TEXT ·Pow(SB), NOSPLIT, $0
|
||||
JMP ·pow(SB)
|
||||
|
||||
TEXT ·Remainder(SB), NOSPLIT, $0
|
||||
JMP ·remainder(SB)
|
||||
|
||||
TEXT ·Sin(SB), NOSPLIT, $0
|
||||
JMP ·sin(SB)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user