blob: 4ef02eb09aaafdb55717bf84dc9ca5723fdd23f7 [file] [log] [blame]
Brad Fitzpatrick51947442016-03-01 22:57:46 +00001// Copyright 2012 The Go Authors. All rights reserved.
Russ Coxdd8dc6f2011-12-13 15:20:12 -05002// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Rob Pike8bca1482014-08-12 17:04:45 -07005#include "textflag.h"
Keith Randall1f796632013-08-12 10:25:18 -07006
Charles L. Dorian322057c2012-06-02 13:06:12 -04007#define Big 0x4330000000000000 // 2**52
8
9// func Floor(x float64) float64
Keith Randall1f796632013-08-12 10:25:18 -070010TEXT ·Floor(SB),NOSPLIT,$0
Charles L. Dorian322057c2012-06-02 13:06:12 -040011 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
Russ Cox07720b62013-03-22 12:57:55 -040025 MOVSD X0, ret+8(FP)
Charles L. Dorian322057c2012-06-02 13:06:12 -040026 RET
27isBig_floor:
Russ Cox07720b62013-03-22 12:57:55 -040028 MOVQ AX, ret+8(FP) // return x
Charles L. Dorian322057c2012-06-02 13:06:12 -040029 RET
Russ Coxdd8dc6f2011-12-13 15:20:12 -050030
Charles L. Dorian322057c2012-06-02 13:06:12 -040031// func Ceil(x float64) float64
Keith Randall1f796632013-08-12 10:25:18 -070032TEXT ·Ceil(SB),NOSPLIT,$0
Charles L. Dorian322057c2012-06-02 13:06:12 -040033 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
Russ Cox07720b62013-03-22 12:57:55 -040051 MOVSD X0, ret+8(FP)
Charles L. Dorian322057c2012-06-02 13:06:12 -040052 RET
53isBig_ceil:
Russ Cox07720b62013-03-22 12:57:55 -040054 MOVQ AX, ret+8(FP)
Charles L. Dorian322057c2012-06-02 13:06:12 -040055 RET
Russ Coxdd8dc6f2011-12-13 15:20:12 -050056
Charles L. Dorian322057c2012-06-02 13:06:12 -040057// func Trunc(x float64) float64
Keith Randall1f796632013-08-12 10:25:18 -070058TEXT ·Trunc(SB),NOSPLIT,$0
Charles L. Dorian322057c2012-06-02 13:06:12 -040059 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
Russ Cox07720b62013-03-22 12:57:55 -040072 MOVSD X0, ret+8(FP)
Charles L. Dorian322057c2012-06-02 13:06:12 -040073 RET
74isBig_trunc:
Russ Cox07720b62013-03-22 12:57:55 -040075 MOVQ AX, ret+8(FP) // return x
Charles L. Dorian322057c2012-06-02 13:06:12 -040076 RET