|  | // Copyright 2016 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. | 
|  |  | 
|  | // Based on dim_amd64.s | 
|  |  | 
|  | #include "textflag.h" | 
|  |  | 
|  | #define PosInf 0x7FF0000000000000 | 
|  | #define NaN    0x7FF8000000000001 | 
|  | #define NegInf 0xFFF0000000000000 | 
|  |  | 
|  | // func Dim(x, y float64) float64 | 
|  | TEXT ·Dim(SB),NOSPLIT,$0 | 
|  | // (+Inf, +Inf) special case | 
|  | MOVD    x+0(FP), R2 | 
|  | MOVD    y+8(FP), R3 | 
|  | MOVD    $PosInf, R4 | 
|  | CMPUBNE R4, R2, dim2 | 
|  | CMPUBEQ R4, R3, bothInf | 
|  | dim2:	// (-Inf, -Inf) special case | 
|  | MOVD    $NegInf, R4 | 
|  | CMPUBNE R4, R2, dim3 | 
|  | CMPUBEQ R4, R3, bothInf | 
|  | dim3:	// (NaN, x) or (x, NaN) | 
|  | MOVD    $~(1<<63), R5 | 
|  | MOVD    $PosInf, R4 | 
|  | AND     R5, R2 // x = |x| | 
|  | CMPUBLT R4, R2, isDimNaN | 
|  | AND     R5, R3 // y = |y| | 
|  | CMPUBLT R4, R3, isDimNaN | 
|  |  | 
|  | FMOVD   x+0(FP), F1 | 
|  | FMOVD   y+8(FP), F2 | 
|  | FSUB    F2, F1 | 
|  | FMOVD   $(0.0), F2 | 
|  | FCMPU   F2, F1 | 
|  | BGE     +3(PC) | 
|  | FMOVD   F1, ret+16(FP) | 
|  | RET | 
|  | FMOVD   F2, ret+16(FP) | 
|  | RET | 
|  | bothInf: // Dim(-Inf, -Inf) or Dim(+Inf, +Inf) | 
|  | isDimNaN: | 
|  | MOVD    $NaN, R4 | 
|  | MOVD    R4, ret+16(FP) | 
|  | RET | 
|  |  | 
|  | // func ·Max(x, y float64) float64 | 
|  | TEXT ·Max(SB),NOSPLIT,$0 | 
|  | // +Inf special cases | 
|  | MOVD    $PosInf, R4 | 
|  | MOVD    x+0(FP), R8 | 
|  | CMPUBEQ R4, R8, isPosInf | 
|  | MOVD    y+8(FP), R9 | 
|  | CMPUBEQ R4, R9, isPosInf | 
|  | // NaN special cases | 
|  | MOVD    $~(1<<63), R5 // bit mask | 
|  | MOVD    $PosInf, R4 | 
|  | MOVD    R8, R2 | 
|  | AND     R5, R2 // x = |x| | 
|  | CMPUBLT R4, R2, isMaxNaN | 
|  | MOVD    R9, R3 | 
|  | AND     R5, R3 // y = |y| | 
|  | CMPUBLT R4, R3, isMaxNaN | 
|  | // ±0 special cases | 
|  | OR      R3, R2 | 
|  | BEQ     isMaxZero | 
|  |  | 
|  | FMOVD   x+0(FP), F1 | 
|  | FMOVD   y+8(FP), F2 | 
|  | FCMPU   F2, F1 | 
|  | BGT     +3(PC) | 
|  | FMOVD   F1, ret+16(FP) | 
|  | RET | 
|  | FMOVD   F2, ret+16(FP) | 
|  | RET | 
|  | isMaxNaN: // return NaN | 
|  | MOVD	$NaN, R4 | 
|  | isPosInf: // return +Inf | 
|  | MOVD    R4, ret+16(FP) | 
|  | RET | 
|  | isMaxZero: | 
|  | MOVD    $(1<<63), R4 // -0.0 | 
|  | CMPUBEQ R4, R8, +3(PC) | 
|  | MOVD    R8, ret+16(FP) // return 0 | 
|  | RET | 
|  | MOVD    R9, ret+16(FP) // return other 0 | 
|  | RET | 
|  |  | 
|  | // func Min(x, y float64) float64 | 
|  | TEXT ·Min(SB),NOSPLIT,$0 | 
|  | // -Inf special cases | 
|  | MOVD    $NegInf, R4 | 
|  | MOVD    x+0(FP), R8 | 
|  | CMPUBEQ R4, R8, isNegInf | 
|  | MOVD    y+8(FP), R9 | 
|  | CMPUBEQ R4, R9, isNegInf | 
|  | // NaN special cases | 
|  | MOVD    $~(1<<63), R5 | 
|  | MOVD    $PosInf, R4 | 
|  | MOVD    R8, R2 | 
|  | AND     R5, R2 // x = |x| | 
|  | CMPUBLT R4, R2, isMinNaN | 
|  | MOVD    R9, R3 | 
|  | AND     R5, R3 // y = |y| | 
|  | CMPUBLT R4, R3, isMinNaN | 
|  | // ±0 special cases | 
|  | OR      R3, R2 | 
|  | BEQ     isMinZero | 
|  |  | 
|  | FMOVD   x+0(FP), F1 | 
|  | FMOVD   y+8(FP), F2 | 
|  | FCMPU   F2, F1 | 
|  | BLT     +3(PC) | 
|  | FMOVD   F1, ret+16(FP) | 
|  | RET | 
|  | FMOVD   F2, ret+16(FP) | 
|  | RET | 
|  | isMinNaN: // return NaN | 
|  | MOVD	$NaN, R4 | 
|  | isNegInf: // return -Inf | 
|  | MOVD    R4, ret+16(FP) | 
|  | RET | 
|  | isMinZero: | 
|  | MOVD    $(1<<63), R4 // -0.0 | 
|  | CMPUBEQ R4, R8, +3(PC) | 
|  | MOVD    R9, ret+16(FP) // return other 0 | 
|  | RET | 
|  | MOVD    R8, ret+16(FP) // return -0 | 
|  | RET | 
|  |  |