Commit ec92af65 authored by Charlie Dorian's avatar Charlie Dorian Committed by Minux Ma

math: Dim, Max, Min - allow more bit patterns for NaN

Fixes #9919

Change-Id: Ib443c762f727d4986ca7f8a404362f92b0e91aff
Reviewed-on: https://go-review.googlesource.com/5553Reviewed-by: default avatarMinux Ma <minux@golang.org>
parent b986f3e3
...@@ -991,6 +991,24 @@ var vffdimSC = [][2]float64{ ...@@ -991,6 +991,24 @@ var vffdimSC = [][2]float64{
{NaN(), Inf(1)}, {NaN(), Inf(1)},
{NaN(), NaN()}, {NaN(), NaN()},
} }
var nan = Float64frombits(0xFFF8000000000000) // SSE2 DIVSD 0/0
var vffdim2SC = [][2]float64{
{Inf(-1), Inf(-1)},
{Inf(-1), Inf(1)},
{Inf(-1), nan},
{Copysign(0, -1), Copysign(0, -1)},
{Copysign(0, -1), 0},
{0, Copysign(0, -1)},
{0, 0},
{Inf(1), Inf(-1)},
{Inf(1), Inf(1)},
{Inf(1), nan},
{nan, Inf(-1)},
{nan, Copysign(0, -1)},
{nan, 0},
{nan, Inf(1)},
{nan, nan},
}
var fdimSC = []float64{ var fdimSC = []float64{
NaN(), NaN(),
0, 0,
...@@ -2015,6 +2033,11 @@ func TestDim(t *testing.T) { ...@@ -2015,6 +2033,11 @@ func TestDim(t *testing.T) {
t.Errorf("Dim(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fdimSC[i]) t.Errorf("Dim(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fdimSC[i])
} }
} }
for i := 0; i < len(vffdim2SC); i++ {
if f := Dim(vffdim2SC[i][0], vffdim2SC[i][1]); !alike(fdimSC[i], f) {
t.Errorf("Dim(%g, %g) = %g, want %g", vffdim2SC[i][0], vffdim2SC[i][1], f, fdimSC[i])
}
}
} }
func TestFloor(t *testing.T) { func TestFloor(t *testing.T) {
...@@ -2041,6 +2064,11 @@ func TestMax(t *testing.T) { ...@@ -2041,6 +2064,11 @@ func TestMax(t *testing.T) {
t.Errorf("Max(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fmaxSC[i]) t.Errorf("Max(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fmaxSC[i])
} }
} }
for i := 0; i < len(vffdim2SC); i++ {
if f := Max(vffdim2SC[i][0], vffdim2SC[i][1]); !alike(fmaxSC[i], f) {
t.Errorf("Max(%g, %g) = %g, want %g", vffdim2SC[i][0], vffdim2SC[i][1], f, fmaxSC[i])
}
}
} }
func TestMin(t *testing.T) { func TestMin(t *testing.T) {
...@@ -2054,6 +2082,11 @@ func TestMin(t *testing.T) { ...@@ -2054,6 +2082,11 @@ func TestMin(t *testing.T) {
t.Errorf("Min(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fminSC[i]) t.Errorf("Min(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fminSC[i])
} }
} }
for i := 0; i < len(vffdim2SC); i++ {
if f := Min(vffdim2SC[i][0], vffdim2SC[i][1]); !alike(fminSC[i], f) {
t.Errorf("Min(%g, %g) = %g, want %g", vffdim2SC[i][0], vffdim2SC[i][1], f, fminSC[i])
}
}
} }
func TestMod(t *testing.T) { func TestMod(t *testing.T) {
......
...@@ -26,13 +26,13 @@ dim2: // (-Inf, -Inf) special case ...@@ -26,13 +26,13 @@ dim2: // (-Inf, -Inf) special case
JEQ bothInf JEQ bothInf
dim3: // (NaN, x) or (x, NaN) dim3: // (NaN, x) or (x, NaN)
MOVQ $~(1<<63), DX MOVQ $~(1<<63), DX
MOVQ $NaN, AX MOVQ $PosInf, AX
ANDQ DX, BX // x = |x| ANDQ DX, BX // x = |x|
CMPQ AX, BX CMPQ AX, BX
JLE isDimNaN JLT isDimNaN
ANDQ DX, CX // y = |y| ANDQ DX, CX // y = |y|
CMPQ AX, CX CMPQ AX, CX
JLE isDimNaN JLT isDimNaN
MOVSD x+0(FP), X0 MOVSD x+0(FP), X0
SUBSD y+8(FP), X0 SUBSD y+8(FP), X0
...@@ -41,8 +41,8 @@ dim3: // (NaN, x) or (x, NaN) ...@@ -41,8 +41,8 @@ dim3: // (NaN, x) or (x, NaN)
MOVSD X0, ret+16(FP) MOVSD X0, ret+16(FP)
RET RET
bothInf: // Dim(-Inf, -Inf) or Dim(+Inf, +Inf) bothInf: // Dim(-Inf, -Inf) or Dim(+Inf, +Inf)
MOVQ $NaN, AX
isDimNaN: isDimNaN:
MOVQ $NaN, AX
MOVQ AX, ret+16(FP) MOVQ AX, ret+16(FP)
RET RET
...@@ -58,15 +58,15 @@ TEXT ·Max(SB),NOSPLIT,$0 ...@@ -58,15 +58,15 @@ TEXT ·Max(SB),NOSPLIT,$0
JEQ isPosInf JEQ isPosInf
// NaN special cases // NaN special cases
MOVQ $~(1<<63), DX // bit mask MOVQ $~(1<<63), DX // bit mask
MOVQ $NaN, AX MOVQ $PosInf, AX
MOVQ R8, BX MOVQ R8, BX
ANDQ DX, BX // x = |x| ANDQ DX, BX // x = |x|
CMPQ AX, BX CMPQ AX, BX
JLE isMaxNaN JLT isMaxNaN
MOVQ R9, CX MOVQ R9, CX
ANDQ DX, CX // y = |y| ANDQ DX, CX // y = |y|
CMPQ AX, CX CMPQ AX, CX
JLE isMaxNaN JLT isMaxNaN
// ±0 special cases // ±0 special cases
ORQ CX, BX ORQ CX, BX
JEQ isMaxZero JEQ isMaxZero
...@@ -77,6 +77,7 @@ TEXT ·Max(SB),NOSPLIT,$0 ...@@ -77,6 +77,7 @@ TEXT ·Max(SB),NOSPLIT,$0
MOVSD X0, ret+16(FP) MOVSD X0, ret+16(FP)
RET RET
isMaxNaN: // return NaN isMaxNaN: // return NaN
MOVQ $NaN, AX
isPosInf: // return +Inf isPosInf: // return +Inf
MOVQ AX, ret+16(FP) MOVQ AX, ret+16(FP)
RET RET
...@@ -89,16 +90,6 @@ isMaxZero: ...@@ -89,16 +90,6 @@ isMaxZero:
MOVQ R9, ret+16(FP) // return other 0 MOVQ R9, ret+16(FP) // return other 0
RET RET
/*
MOVQ $0, AX
CMPQ AX, R8
JNE +3(PC)
MOVQ R8, ret+16(FP) // return 0
RET
MOVQ R9, ret+16(FP) // return other 0
RET
*/
// func Min(x, y float64) float64 // func Min(x, y float64) float64
TEXT ·Min(SB),NOSPLIT,$0 TEXT ·Min(SB),NOSPLIT,$0
// -Inf special cases // -Inf special cases
...@@ -111,15 +102,15 @@ TEXT ·Min(SB),NOSPLIT,$0 ...@@ -111,15 +102,15 @@ TEXT ·Min(SB),NOSPLIT,$0
JEQ isNegInf JEQ isNegInf
// NaN special cases // NaN special cases
MOVQ $~(1<<63), DX MOVQ $~(1<<63), DX
MOVQ $NaN, AX MOVQ $PosInf, AX
MOVQ R8, BX MOVQ R8, BX
ANDQ DX, BX // x = |x| ANDQ DX, BX // x = |x|
CMPQ AX, BX CMPQ AX, BX
JLE isMinNaN JLT isMinNaN
MOVQ R9, CX MOVQ R9, CX
ANDQ DX, CX // y = |y| ANDQ DX, CX // y = |y|
CMPQ AX, CX CMPQ AX, CX
JLE isMinNaN JLT isMinNaN
// ±0 special cases // ±0 special cases
ORQ CX, BX ORQ CX, BX
JEQ isMinZero JEQ isMinZero
...@@ -130,6 +121,7 @@ TEXT ·Min(SB),NOSPLIT,$0 ...@@ -130,6 +121,7 @@ TEXT ·Min(SB),NOSPLIT,$0
MOVSD X0, ret+16(FP) MOVSD X0, ret+16(FP)
RET RET
isMinNaN: // return NaN isMinNaN: // return NaN
MOVQ $NaN, AX
isNegInf: // return -Inf isNegInf: // return -Inf
MOVQ AX, ret+16(FP) MOVQ AX, ret+16(FP)
RET RET
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment