2 * Copyright
(c) 2014 Advanced Micro Devices
, Inc.
4 * Permission is hereby granted
, free of charge
, to any person obtaining a copy
5 * of this software and associated documentation files
(the "Software"), to deal
6 * in the Software without restriction
, including without limitation the rights
7 * to use
, copy
, modify
, merge
, publish
, distribute
, sublicense
, and
/or sell
8 * copies of the Software
, and to permit persons to whom the Software is
9 * furnished to do so
, subject to the following conditions
:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED
"AS IS", WITHOUT WARRANTY OF ANY KIND
, EXPRESS OR
15 * IMPLIED
, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM
, DAMAGES OR OTHER
18 * LIABILITY
, WHETHER IN AN ACTION OF CONTRACT
, TORT OR OTHERWISE
, ARISING FROM
,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 #pragma OPENCL EXTENSION cl_khr_fp64
: enable
32 #define LN0
8.33333333333317923934e-02
33 #define LN1
1.25000000037717509602e-02
34 #define LN2
2.23213998791944806202e-03
35 #define LN3
4.34887777707614552256e-04
37 #define LF0
8.33333333333333593622e-02
38 #define LF1
1.24999999978138668903e-02
39 #define LF2
2.23219810758559851206e-03
41 _CLC_DEF void __clc_ep_log
(double x
, int
*xexp
, double
*r1
, double
*r2
)
43 // Computes natural log
(x). Algorithm based on
:
44 // Ping-Tak Peter Tang
45 // "Table-driven implementation of the logarithm function in IEEE
46 // floating-point arithmetic"
47 // ACM Transactions on Mathematical Software
(TOMS)
48 // Volume
16, Issue
4 (December 1990)
49 int near_one
= x
>= 0x1.e0faap-1
& x
<= 0x1.1082cp
+0;
51 ulong ux
= as_ulong
(x);
52 ulong uxs
= as_ulong
(as_double(0x03d0000000000000UL | ux
) -
0x1.0p-962
);
53 int c
= ux
< IMPBIT_DP64
;
55 int expadjust
= c ?
60 : 0;
57 // Store the exponent of x in xexp and put f into the range
[0.5,1)
58 int xexp1
= ((as_int2(ux).hi
>> 20) & 0x7ff) - EXPBIAS_DP64 - expadjust
;
59 double f
= as_double
(HALFEXPBITS_DP64 |
(ux & MANTBITS_DP64
));
60 *xexp
= near_one ?
0 : xexp1
;
63 double u1
= MATH_DIVIDE
(r, 2.0 + r
);
67 int index
= as_int2
(ux).hi
>> 13;
68 index
= ((0x80 |
(index & 0x7e)) >> 1) + (index & 0x1);
70 double f1
= index
* 0x1.0p-7
;
72 double u2
= MATH_DIVIDE
(f2, fma
(0.5
, f2
, f1
));
74 double2 tv
= USE_TABLE
(ln_tbl, (index -
64));
78 z1
= near_one ? r
: z1
;
79 q
= near_one ?
0.0 : q
;
80 double u
= near_one ? u1
: u2
;
83 double cc
= near_one ? ru1
: u2
;
85 double z21
= fma
(v, fma
(v, fma
(v, LN3
, LN2
), LN1
), LN0
);
86 double z22
= fma
(v, fma
(v, LF2
, LF1
), LF0
);
87 double z2
= near_one ? z21
: z22
;
88 z2
= fma
(u*v
, z2
, cc
) + q
;