github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/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