liyujie
2025-08-28 d9927380ed7c8366f762049be9f3fee225860833
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
#include "textflag.h"
 
#define Big        0x4330000000000000 // 2**52
 
// func Floor(x float64) float64
TEXT ·Floor(SB),NOSPLIT,$0
   MOVQ    x+0(FP), AX
   MOVQ    $~(1<<63), DX // sign bit mask
   ANDQ    AX,DX // DX = |x|
   SUBQ    $1,DX
   MOVQ    $(Big - 1), CX // if |x| >= 2**52-1 or IsNaN(x) or |x| == 0, return x
   CMPQ    DX,CX
   JAE     isBig_floor
   MOVQ    AX, X0 // X0 = x
   CVTTSD2SQ    X0, AX
   CVTSQ2SD    AX, X1 // X1 = float(int(x))
   CMPSD    X1, X0, 1 // compare LT; X0 = 0xffffffffffffffff or 0
   MOVSD    $(-1.0), X2
   ANDPD    X2, X0 // if x < float(int(x)) {X0 = -1} else {X0 = 0}
   ADDSD    X1, X0
   MOVSD    X0, ret+8(FP)
   RET
isBig_floor:
   MOVQ    AX, ret+8(FP) // return x
   RET
 
// func Ceil(x float64) float64
TEXT ·Ceil(SB),NOSPLIT,$0
   MOVQ    x+0(FP), AX
   MOVQ    $~(1<<63), DX // sign bit mask
   MOVQ    AX, BX // BX = copy of x
   ANDQ    DX, BX // BX = |x|
   MOVQ    $Big, CX // if |x| >= 2**52 or IsNaN(x), return x
   CMPQ    BX, CX
   JAE     isBig_ceil
   MOVQ    AX, X0 // X0 = x
   MOVQ    DX, X2 // X2 = sign bit mask
   CVTTSD2SQ    X0, AX
   ANDNPD    X0, X2 // X2 = sign
   CVTSQ2SD    AX, X1    // X1 = float(int(x))
   CMPSD    X1, X0, 2 // compare LE; X0 = 0xffffffffffffffff or 0
   ORPD    X2, X1 // if X1 = 0.0, incorporate sign
   MOVSD    $1.0, X3
   ANDNPD    X3, X0
   ORPD    X2, X0 // if float(int(x)) <= x {X0 = 1} else {X0 = -0}
   ADDSD    X1, X0
   MOVSD    X0, ret+8(FP)
   RET
isBig_ceil:
   MOVQ    AX, ret+8(FP)
   RET
 
// func Trunc(x float64) float64
TEXT ·Trunc(SB),NOSPLIT,$0
   MOVQ    x+0(FP), AX
   MOVQ    $~(1<<63), DX // sign bit mask
   MOVQ    AX, BX // BX = copy of x
   ANDQ    DX, BX // BX = |x|
   MOVQ    $Big, CX // if |x| >= 2**52 or IsNaN(x), return x
   CMPQ    BX, CX
   JAE     isBig_trunc
   MOVQ    AX, X0
   MOVQ    DX, X2 // X2 = sign bit mask
   CVTTSD2SQ    X0, AX
   ANDNPD    X0, X2 // X2 = sign
   CVTSQ2SD    AX, X0 // X0 = float(int(x))
   ORPD    X2, X0 // if X0 = 0.0, incorporate sign
   MOVSD    X0, ret+8(FP)
   RET
isBig_trunc:
   MOVQ    AX, ret+8(FP) // return x
   RET