github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/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 archFloor(x float64) float64 10 TEXT ·archFloor(SB),NOSPLIT,$0 11 MOVQ x+0(FP), AX 12 MOVQ $~(1<<63), DX // sign bit mask 13 ANDQ AX,DX // DX = |x| 14 SUBQ $1,DX 15 MOVQ $(Big - 1), CX // if |x| >= 2**52-1 or IsNaN(x) or |x| == 0, return x 16 CMPQ DX,CX 17 JAE isBig_floor 18 MOVQ AX, X0 // X0 = x 19 CVTTSD2SQ X0, AX 20 CVTSQ2SD AX, X1 // X1 = float(int(x)) 21 CMPSD X1, X0, 1 // compare LT; X0 = 0xffffffffffffffff or 0 22 MOVSD $(-1.0), X2 23 ANDPD X2, X0 // if x < float(int(x)) {X0 = -1} else {X0 = 0} 24 ADDSD X1, X0 25 MOVSD X0, ret+8(FP) 26 RET 27 isBig_floor: 28 MOVQ AX, ret+8(FP) // return x 29 RET 30 31 // func archCeil(x float64) float64 32 TEXT ·archCeil(SB),NOSPLIT,$0 33 MOVQ x+0(FP), AX 34 MOVQ $~(1<<63), DX // sign bit mask 35 MOVQ AX, BX // BX = copy of x 36 ANDQ DX, BX // BX = |x| 37 MOVQ $Big, CX // if |x| >= 2**52 or IsNaN(x), return x 38 CMPQ BX, CX 39 JAE isBig_ceil 40 MOVQ AX, X0 // X0 = x 41 MOVQ DX, X2 // X2 = sign bit mask 42 CVTTSD2SQ X0, AX 43 ANDNPD X0, X2 // X2 = sign 44 CVTSQ2SD AX, X1 // X1 = float(int(x)) 45 CMPSD X1, X0, 2 // compare LE; X0 = 0xffffffffffffffff or 0 46 ORPD X2, X1 // if X1 = 0.0, incorporate sign 47 MOVSD $1.0, X3 48 ANDNPD X3, X0 49 ORPD X2, X0 // if float(int(x)) <= x {X0 = 1} else {X0 = -0} 50 ADDSD X1, X0 51 MOVSD X0, ret+8(FP) 52 RET 53 isBig_ceil: 54 MOVQ AX, ret+8(FP) 55 RET 56 57 // func archTrunc(x float64) float64 58 TEXT ·archTrunc(SB),NOSPLIT,$0 59 MOVQ x+0(FP), AX 60 MOVQ $~(1<<63), DX // sign bit mask 61 MOVQ AX, BX // BX = copy of x 62 ANDQ DX, BX // BX = |x| 63 MOVQ $Big, CX // if |x| >= 2**52 or IsNaN(x), return x 64 CMPQ BX, CX 65 JAE isBig_trunc 66 MOVQ AX, X0 67 MOVQ DX, X2 // X2 = sign bit mask 68 CVTTSD2SQ X0, AX 69 ANDNPD X0, X2 // X2 = sign 70 CVTSQ2SD AX, X0 // X0 = float(int(x)) 71 ORPD X2, X0 // if X0 = 0.0, incorporate sign 72 MOVSD X0, ret+8(FP) 73 RET 74 isBig_trunc: 75 MOVQ AX, ret+8(FP) // return x 76 RET