summaryrefslogtreecommitdiff
path: root/src/math/dim_amd64.s
diff options
context:
space:
mode:
authorTianon Gravi <admwiggin@gmail.com>2015-01-15 12:50:40 -0700
committerTianon Gravi <admwiggin@gmail.com>2015-01-15 12:50:40 -0700
commit2a0db60599fdd75b1bc3e297180fbe1282763759 (patch)
tree68d43c3e30d9ab961ddf6b7365201ca6b675b253 /src/math/dim_amd64.s
parentef33cba3c8de6c431df56503df51fcd3a473c89e (diff)
parentf154da9e12608589e8d5f0508f908a0c3e88a1bb (diff)
downloadgolang-2a0db60599fdd75b1bc3e297180fbe1282763759.tar.gz
Merge tag 'upstream/1.4' into debian-experimental
* tag 'upstream/1.4': Imported Upstream version 1.4
Diffstat (limited to 'src/math/dim_amd64.s')
-rw-r--r--src/math/dim_amd64.s144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/math/dim_amd64.s b/src/math/dim_amd64.s
new file mode 100644
index 000000000..622cc3fba
--- /dev/null
+++ b/src/math/dim_amd64.s
@@ -0,0 +1,144 @@
+// 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"
+
+#define PosInf 0x7FF0000000000000
+#define NaN 0x7FF8000000000001
+#define NegInf 0xFFF0000000000000
+
+// func Dim(x, y float64) float64
+TEXT ·Dim(SB),NOSPLIT,$0
+ // (+Inf, +Inf) special case
+ MOVQ x+0(FP), BX
+ MOVQ y+8(FP), CX
+ MOVQ $PosInf, AX
+ CMPQ AX, BX
+ JNE dim2
+ CMPQ AX, CX
+ JEQ bothInf
+dim2: // (-Inf, -Inf) special case
+ MOVQ $NegInf, AX
+ CMPQ AX, BX
+ JNE dim3
+ CMPQ AX, CX
+ JEQ bothInf
+dim3: // (NaN, x) or (x, NaN)
+ MOVQ $~(1<<63), DX
+ MOVQ $NaN, AX
+ ANDQ DX, BX // x = |x|
+ CMPQ AX, BX
+ JLE isDimNaN
+ ANDQ DX, CX // y = |y|
+ CMPQ AX, CX
+ JLE isDimNaN
+
+ MOVSD x+0(FP), X0
+ SUBSD y+8(FP), X0
+ MOVSD $(0.0), X1
+ MAXSD X1, X0
+ MOVSD X0, ret+16(FP)
+ RET
+bothInf: // Dim(-Inf, -Inf) or Dim(+Inf, +Inf)
+ MOVQ $NaN, AX
+isDimNaN:
+ MOVQ AX, ret+16(FP)
+ RET
+
+// func ·Max(x, y float64) float64
+TEXT ·Max(SB),NOSPLIT,$0
+ // +Inf special cases
+ MOVQ $PosInf, AX
+ MOVQ x+0(FP), R8
+ CMPQ AX, R8
+ JEQ isPosInf
+ MOVQ y+8(FP), R9
+ CMPQ AX, R9
+ JEQ isPosInf
+ // NaN special cases
+ MOVQ $~(1<<63), DX // bit mask
+ MOVQ $NaN, AX
+ MOVQ R8, BX
+ ANDQ DX, BX // x = |x|
+ CMPQ AX, BX
+ JLE isMaxNaN
+ MOVQ R9, CX
+ ANDQ DX, CX // y = |y|
+ CMPQ AX, CX
+ JLE isMaxNaN
+ // ±0 special cases
+ ORQ CX, BX
+ JEQ isMaxZero
+
+ MOVQ R8, X0
+ MOVQ R9, X1
+ MAXSD X1, X0
+ MOVSD X0, ret+16(FP)
+ RET
+isMaxNaN: // return NaN
+isPosInf: // return +Inf
+ MOVQ AX, ret+16(FP)
+ RET
+isMaxZero:
+ MOVQ $(1<<63), AX // -0.0
+ CMPQ AX, R8
+ JEQ +3(PC)
+ MOVQ R8, ret+16(FP) // return 0
+ RET
+ MOVQ R9, ret+16(FP) // return other 0
+ 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
+TEXT ·Min(SB),NOSPLIT,$0
+ // -Inf special cases
+ MOVQ $NegInf, AX
+ MOVQ x+0(FP), R8
+ CMPQ AX, R8
+ JEQ isNegInf
+ MOVQ y+8(FP), R9
+ CMPQ AX, R9
+ JEQ isNegInf
+ // NaN special cases
+ MOVQ $~(1<<63), DX
+ MOVQ $NaN, AX
+ MOVQ R8, BX
+ ANDQ DX, BX // x = |x|
+ CMPQ AX, BX
+ JLE isMinNaN
+ MOVQ R9, CX
+ ANDQ DX, CX // y = |y|
+ CMPQ AX, CX
+ JLE isMinNaN
+ // ±0 special cases
+ ORQ CX, BX
+ JEQ isMinZero
+
+ MOVQ R8, X0
+ MOVQ R9, X1
+ MINSD X1, X0
+ MOVSD X0, ret+16(FP)
+ RET
+isMinNaN: // return NaN
+isNegInf: // return -Inf
+ MOVQ AX, ret+16(FP)
+ RET
+isMinZero:
+ MOVQ $(1<<63), AX // -0.0
+ CMPQ AX, R8
+ JEQ +3(PC)
+ MOVQ R9, ret+16(FP) // return other 0
+ RET
+ MOVQ R8, ret+16(FP) // return -0
+ RET
+