github.com/mattn/go@v0.0.0-20171011075504-07f7db3ea99f/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