Home | History | Annotate | Download | only in math
      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 	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 Ceil(x float64) float64
     32 TEXT Ceil(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 Trunc(x float64) float64
     58 TEXT Trunc(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
     77