summaryrefslogtreecommitdiffstats
path: root/src/math/hypot_386.s
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/math/hypot_386.s59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/math/hypot_386.s b/src/math/hypot_386.s
new file mode 100644
index 0000000..80a8fd3
--- /dev/null
+++ b/src/math/hypot_386.s
@@ -0,0 +1,59 @@
+// 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 archHypot(p, q float64) float64
+TEXT ·archHypot(SB),NOSPLIT,$0
+// test bits for not-finite
+ MOVL p_hi+4(FP), AX // high word p
+ ANDL $0x7ff00000, AX
+ CMPL AX, $0x7ff00000
+ JEQ not_finite
+ MOVL q_hi+12(FP), AX // high word q
+ ANDL $0x7ff00000, AX
+ CMPL AX, $0x7ff00000
+ JEQ not_finite
+ FMOVD p+0(FP), F0 // F0=p
+ FABS // F0=|p|
+ FMOVD q+8(FP), F0 // F0=q, F1=|p|
+ FABS // F0=|q|, F1=|p|
+ FUCOMI F0, F1 // compare F0 to F1
+ JCC 2(PC) // jump if F0 >= F1
+ FXCHD F0, F1 // F0=|p| (larger), F1=|q| (smaller)
+ FTST // compare F0 to 0
+ FSTSW AX
+ ANDW $0x4000, AX
+ JNE 10(PC) // jump if F0 = 0
+ FXCHD F0, F1 // F0=q (smaller), F1=p (larger)
+ FDIVD F1, F0 // F0=q(=q/p), F1=p
+ FMULD F0, F0 // F0=q*q, F1=p
+ FLD1 // F0=1, F1=q*q, F2=p
+ FADDDP F0, F1 // F0=1+q*q, F1=p
+ FSQRT // F0=sqrt(1+q*q), F1=p
+ FMULDP F0, F1 // F0=p*sqrt(1+q*q)
+ FMOVDP F0, ret+16(FP)
+ RET
+ FMOVDP F0, F1 // F0=0
+ FMOVDP F0, ret+16(FP)
+ RET
+not_finite:
+// test bits for -Inf or +Inf
+ MOVL p_hi+4(FP), AX // high word p
+ ORL p_lo+0(FP), AX // low word p
+ ANDL $0x7fffffff, AX
+ CMPL AX, $0x7ff00000
+ JEQ is_inf
+ MOVL q_hi+12(FP), AX // high word q
+ ORL q_lo+8(FP), AX // low word q
+ ANDL $0x7fffffff, AX
+ CMPL AX, $0x7ff00000
+ JEQ is_inf
+ MOVL $0x7ff80000, ret_hi+20(FP) // return NaN = 0x7FF8000000000001
+ MOVL $0x00000001, ret_lo+16(FP)
+ RET
+is_inf:
+ MOVL AX, ret_hi+20(FP) // return +Inf = 0x7FF0000000000000
+ MOVL $0x00000000, ret_lo+16(FP)
+ RET