github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/src/math/exp_amd64.s (about) 1 // Copyright 2010 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 // The method is based on a paper by Naoki Shibata: "Efficient evaluation 8 // methods of elementary functions suitable for SIMD computation", Proc. 9 // of International Supercomputing Conference 2010 (ISC'10), pp. 25 -- 32 10 // (May 2010). The paper is available at 11 // http://www.springerlink.com/content/340228x165742104/ 12 // 13 // The original code and the constants below are from the author's 14 // implementation available at http://freshmeat.net/projects/sleef. 15 // The README file says, "The software is in public domain. 16 // You can use the software without any obligation." 17 // 18 // This code is a simplified version of the original. 19 20 #define LN2 0.6931471805599453094172321214581766 // log_e(2) 21 #define LOG2E 1.4426950408889634073599246810018920 // 1/LN2 22 #define LN2U 0.69314718055966295651160180568695068359375 // upper half LN2 23 #define LN2L 0.28235290563031577122588448175013436025525412068e-12 // lower half LN2 24 #define T0 1.0 25 #define T1 0.5 26 #define T2 1.6666666666666666667e-1 27 #define T3 4.1666666666666666667e-2 28 #define T4 8.3333333333333333333e-3 29 #define T5 1.3888888888888888889e-3 30 #define T6 1.9841269841269841270e-4 31 #define T7 2.4801587301587301587e-5 32 #define PosInf 0x7FF0000000000000 33 #define NegInf 0xFFF0000000000000 34 #define Overflow 7.09782712893384e+02 35 36 // func Exp(x float64) float64 37 TEXT ·Exp(SB),NOSPLIT,$0 38 // test bits for not-finite 39 MOVQ x+0(FP), BX 40 MOVQ $~(1<<63), AX // sign bit mask 41 MOVQ BX, DX 42 ANDQ AX, DX 43 MOVQ $PosInf, AX 44 CMPQ AX, DX 45 JLE notFinite 46 // check if argument will overflow 47 MOVQ BX, X0 48 MOVSD $Overflow, X1 49 COMISD X1, X0 50 JA overflow 51 MOVSD $LOG2E, X1 52 MULSD X0, X1 53 CVTSD2SL X1, BX // BX = exponent 54 CVTSL2SD BX, X1 55 MOVSD $LN2U, X2 56 MULSD X1, X2 57 SUBSD X2, X0 58 MOVSD $LN2L, X2 59 MULSD X1, X2 60 SUBSD X2, X0 61 // reduce argument 62 MULSD $0.0625, X0 63 // Taylor series evaluation 64 MOVSD $T7, X1 65 MULSD X0, X1 66 ADDSD $T6, X1 67 MULSD X0, X1 68 ADDSD $T5, X1 69 MULSD X0, X1 70 ADDSD $T4, X1 71 MULSD X0, X1 72 ADDSD $T3, X1 73 MULSD X0, X1 74 ADDSD $T2, X1 75 MULSD X0, X1 76 ADDSD $T1, X1 77 MULSD X0, X1 78 ADDSD $T0, X1 79 MULSD X1, X0 80 MOVSD $2.0, X1 81 ADDSD X0, X1 82 MULSD X1, X0 83 MOVSD $2.0, X1 84 ADDSD X0, X1 85 MULSD X1, X0 86 MOVSD $2.0, X1 87 ADDSD X0, X1 88 MULSD X1, X0 89 MOVSD $2.0, X1 90 ADDSD X0, X1 91 MULSD X1, X0 92 ADDSD $1.0, X0 93 // return fr * 2**exponent 94 MOVL $0x3FF, AX // bias 95 ADDL AX, BX 96 JLE underflow 97 CMPL BX, $0x7FF 98 JGE overflow 99 MOVL $52, CX 100 SHLQ CX, BX 101 MOVQ BX, X1 102 MULSD X1, X0 103 MOVSD X0, ret+8(FP) 104 RET 105 notFinite: 106 // test bits for -Inf 107 MOVQ $NegInf, AX 108 CMPQ AX, BX 109 JNE notNegInf 110 // -Inf, return 0 111 underflow: // return 0 112 MOVQ $0, AX 113 MOVQ AX, ret+8(FP) 114 RET 115 overflow: // return +Inf 116 MOVQ $PosInf, BX 117 notNegInf: // NaN or +Inf, return x 118 MOVQ BX, ret+8(FP) 119 RET