diff options
Diffstat (limited to 'src/math/hypot_386.s')
-rw-r--r-- | src/math/hypot_386.s | 59 |
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..a89cdf7 --- /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 Hypot(p, q float64) float64 +TEXT ·Hypot(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 |