| // 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 |