github.com/eun/go@v0.0.0-20170811110501-92cfd07a6cfd/src/math/floor_amd64.s (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  #include "textflag.h"
     6  
     7  #define Big		0x4330000000000000 // 2**52
     8  
     9  // func Floor(x float64) float64
    10  TEXT ·Floor(SB),NOSPLIT,$0
    11  	CMPB    ·useSSE41(SB), $1
    12  	JNE     nosse4
    13  	ROUNDSD $1, x+0(FP), X0
    14  	MOVQ X0, ret+8(FP)
    15  	RET
    16  nosse4:
    17  	MOVQ	x+0(FP), AX
    18  	MOVQ	$~(1<<63), DX // sign bit mask
    19  	ANDQ	AX,DX // DX = |x|
    20  	SUBQ	$1,DX
    21  	MOVQ    $(Big - 1), CX // if |x| >= 2**52-1 or IsNaN(x) or |x| == 0, return x
    22  	CMPQ	DX,CX
    23  	JAE     isBig_floor
    24  	MOVQ	AX, X0 // X0 = x
    25  	CVTTSD2SQ	X0, AX
    26  	CVTSQ2SD	AX, X1 // X1 = float(int(x))
    27  	CMPSD	X1, X0, 1 // compare LT; X0 = 0xffffffffffffffff or 0
    28  	MOVSD	$(-1.0), X2
    29  	ANDPD	X2, X0 // if x < float(int(x)) {X0 = -1} else {X0 = 0}
    30  	ADDSD	X1, X0
    31  	MOVSD	X0, ret+8(FP)
    32  	RET
    33  isBig_floor:
    34  	MOVQ    AX, ret+8(FP) // return x
    35  	RET
    36  
    37  // func Ceil(x float64) float64
    38  TEXT ·Ceil(SB),NOSPLIT,$0
    39  	CMPB    ·useSSE41(SB), $1
    40  	JNE     nosse4
    41  	ROUNDSD $2, x+0(FP), X0
    42  	MOVQ X0, ret+8(FP)
    43  	RET
    44  nosse4:
    45  	MOVQ	x+0(FP), AX
    46  	MOVQ	$~(1<<63), DX // sign bit mask
    47  	MOVQ	AX, BX // BX = copy of x
    48  	ANDQ    DX, BX // BX = |x|
    49  	MOVQ    $Big, CX // if |x| >= 2**52 or IsNaN(x), return x
    50  	CMPQ    BX, CX
    51  	JAE     isBig_ceil
    52  	MOVQ	AX, X0 // X0 = x
    53  	MOVQ	DX, X2 // X2 = sign bit mask
    54  	CVTTSD2SQ	X0, AX
    55  	ANDNPD	X0, X2 // X2 = sign
    56  	CVTSQ2SD	AX, X1	// X1 = float(int(x))
    57  	CMPSD	X1, X0, 2 // compare LE; X0 = 0xffffffffffffffff or 0
    58  	ORPD	X2, X1 // if X1 = 0.0, incorporate sign
    59  	MOVSD	$1.0, X3
    60  	ANDNPD	X3, X0
    61  	ORPD	X2, X0 // if float(int(x)) <= x {X0 = 1} else {X0 = -0}
    62  	ADDSD	X1, X0
    63  	MOVSD	X0, ret+8(FP)
    64  	RET
    65  isBig_ceil:
    66  	MOVQ	AX, ret+8(FP)
    67  	RET
    68  
    69  // func Trunc(x float64) float64
    70  TEXT ·Trunc(SB),NOSPLIT,$0
    71  	MOVQ	x+0(FP), AX
    72  	MOVQ	$~(1<<63), DX // sign bit mask
    73  	MOVQ	AX, BX // BX = copy of x
    74  	ANDQ    DX, BX // BX = |x|
    75  	MOVQ    $Big, CX // if |x| >= 2**52 or IsNaN(x), return x
    76  	CMPQ    BX, CX
    77  	JAE     isBig_trunc
    78  	MOVQ	AX, X0
    79  	MOVQ	DX, X2 // X2 = sign bit mask
    80  	CVTTSD2SQ	X0, AX
    81  	ANDNPD	X0, X2 // X2 = sign
    82  	CVTSQ2SD	AX, X0 // X0 = float(int(x))
    83  	ORPD	X2, X0 // if X0 = 0.0, incorporate sign
    84  	MOVSD	X0, ret+8(FP)
    85  	RET
    86  isBig_trunc:
    87  	MOVQ    AX, ret+8(FP) // return x
    88  	RET