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
|
// 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.
// func Hypot(x, y float64) float64
TEXT ·Hypot(SB),7,$0
// test bits for not-finite
MOVL xh+4(FP), AX // high word x
ANDL $0x7ff00000, AX
CMPL AX, $0x7ff00000
JEQ not_finite
MOVL yh+12(FP), AX // high word y
ANDL $0x7ff00000, AX
CMPL AX, $0x7ff00000
JEQ not_finite
FMOVD x+0(FP), F0 // F0=x
FABS // F0=|x|
FMOVD y+8(FP), F0 // F0=y, F1=|x|
FABS // F0=|y|, F1=|x|
FUCOMI F0, F1 // compare F0 to F1
JCC 2(PC) // jump if F0 >= F1
FXCHD F0, F1 // F0=|x| (larger), F1=|y| (smaller)
FTST // compare F0 to 0
FSTSW AX
ANDW $0x4000, AX
JNE 10(PC) // jump if F0 = 0
FXCHD F0, F1 // F0=y (smaller), F1=x (larger)
FDIVD F1, F0 // F0=y(=y/x), F1=x
FMULD F0, F0 // F0=y*y, F1=x
FLD1 // F0=1, F1=y*y, F2=x
FADDDP F0, F1 // F0=1+y*y, F1=x
FSQRT // F0=sqrt(1+y*y), F1=x
FMULDP F0, F1 // F0=x*sqrt(1+y*y)
FMOVDP F0, r+16(FP)
RET
FMOVDP F0, F1 // F0=0
FMOVDP F0, r+16(FP)
RET
not_finite:
// test bits for -Inf or +Inf
MOVL xh+4(FP), AX // high word x
ORL xl+0(FP), AX // low word x
ANDL $0x7fffffff, AX
CMPL AX, $0x7ff00000
JEQ is_inf
MOVL yh+12(FP), AX // high word y
ORL yl+8(FP), AX // low word y
ANDL $0x7fffffff, AX
CMPL AX, $0x7ff00000
JEQ is_inf
MOVL $0x7ff00000, rh+20(FP) // return NaN = 0x7FF0000000000001
MOVL $0x00000001, rl+16(FP)
RET
is_inf:
MOVL AX, rh+20(FP) // return +Inf = 0x7FF0000000000000
MOVL $0x00000000, rl+16(FP)
RET
|