github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/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 hasSSE4() bool
    10  // returns whether SSE4.1 is supported
    11  TEXT ·hasSSE4(SB),NOSPLIT,$0
    12  	XORQ AX, AX
    13  	INCL AX
    14  	CPUID
    15  	SHRQ $19, CX
    16  	ANDQ $1, CX
    17  	MOVB CX, ret+0(FP)
    18  	RET
    19  
    20  // func Floor(x float64) float64
    21  TEXT ·Floor(SB),NOSPLIT,$0
    22  	CMPB    math·useSSE4(SB), $1
    23  	JNE     nosse4
    24  	ROUNDSD $1, x+0(FP), X0
    25  	MOVQ X0, ret+8(FP)
    26  	RET
    27  nosse4:
    28  	MOVQ	x+0(FP), AX
    29  	MOVQ	$~(1<<63), DX // sign bit mask
    30  	ANDQ	AX,DX // DX = |x|
    31  	SUBQ	$1,DX
    32  	MOVQ    $(Big - 1), CX // if |x| >= 2**52-1 or IsNaN(x) or |x| == 0, return x
    33  	CMPQ	DX,CX
    34  	JAE     isBig_floor
    35  	MOVQ	AX, X0 // X0 = x
    36  	CVTTSD2SQ	X0, AX
    37  	CVTSQ2SD	AX, X1 // X1 = float(int(x))
    38  	CMPSD	X1, X0, 1 // compare LT; X0 = 0xffffffffffffffff or 0
    39  	MOVSD	$(-1.0), X2
    40  	ANDPD	X2, X0 // if x < float(int(x)) {X0 = -1} else {X0 = 0}
    41  	ADDSD	X1, X0
    42  	MOVSD	X0, ret+8(FP)
    43  	RET
    44  isBig_floor:
    45  	MOVQ    AX, ret+8(FP) // return x
    46  	RET
    47  
    48  // func Ceil(x float64) float64
    49  TEXT ·Ceil(SB),NOSPLIT,$0
    50  	CMPB    math·useSSE4(SB), $1
    51  	JNE     nosse4
    52  	ROUNDSD $2, x+0(FP), X0
    53  	MOVQ X0, ret+8(FP)
    54  	RET
    55  nosse4:
    56  	MOVQ	x+0(FP), AX
    57  	MOVQ	$~(1<<63), DX // sign bit mask
    58  	MOVQ	AX, BX // BX = copy of x
    59  	ANDQ    DX, BX // BX = |x|
    60  	MOVQ    $Big, CX // if |x| >= 2**52 or IsNaN(x), return x
    61  	CMPQ    BX, CX
    62  	JAE     isBig_ceil
    63  	MOVQ	AX, X0 // X0 = x
    64  	MOVQ	DX, X2 // X2 = sign bit mask
    65  	CVTTSD2SQ	X0, AX
    66  	ANDNPD	X0, X2 // X2 = sign
    67  	CVTSQ2SD	AX, X1	// X1 = float(int(x))
    68  	CMPSD	X1, X0, 2 // compare LE; X0 = 0xffffffffffffffff or 0
    69  	ORPD	X2, X1 // if X1 = 0.0, incorporate sign
    70  	MOVSD	$1.0, X3
    71  	ANDNPD	X3, X0
    72  	ORPD	X2, X0 // if float(int(x)) <= x {X0 = 1} else {X0 = -0}
    73  	ADDSD	X1, X0
    74  	MOVSD	X0, ret+8(FP)
    75  	RET
    76  isBig_ceil:
    77  	MOVQ	AX, ret+8(FP)
    78  	RET
    79  
    80  // func Trunc(x float64) float64
    81  TEXT ·Trunc(SB),NOSPLIT,$0
    82  	MOVQ	x+0(FP), AX
    83  	MOVQ	$~(1<<63), DX // sign bit mask
    84  	MOVQ	AX, BX // BX = copy of x
    85  	ANDQ    DX, BX // BX = |x|
    86  	MOVQ    $Big, CX // if |x| >= 2**52 or IsNaN(x), return x
    87  	CMPQ    BX, CX
    88  	JAE     isBig_trunc
    89  	MOVQ	AX, X0
    90  	MOVQ	DX, X2 // X2 = sign bit mask
    91  	CVTTSD2SQ	X0, AX
    92  	ANDNPD	X0, X2 // X2 = sign
    93  	CVTSQ2SD	AX, X0 // X0 = float(int(x))
    94  	ORPD	X2, X0 // if X0 = 0.0, incorporate sign
    95  	MOVSD	X0, ret+8(FP)
    96  	RET
    97  isBig_trunc:
    98  	MOVQ    AX, ret+8(FP) // return x
    99  	RET