summaryrefslogtreecommitdiff
path: root/src/pkg/math/dim_amd64.s
blob: 38423ef028c58082b8239e456f849ffca87852c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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 "../../cmd/ld/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