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