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
26 #include
<clc
/clcmacro.h
>
27 #include
<clc
/relational
/clc_isinf.h
>
28 #include
<clc
/relational
/clc_isnan.h
>
29 #include
<clc
/shared
/clc_clamp.h
>
31 _CLC_DEF _CLC_OVERLOAD float __clc_ldexp
(float x
, int n
) {
33 if
(!__clc_fp32_subnormals_supported
()) {
35 // This treats subnormals as zeros
37 int e
= (i >> 23) & 0xff;
38 int m
= i
& 0x007fffff;
39 int s
= i
& 0x80000000;
40 int v
= add_sat
(e, n
);
41 v
= __clc_clamp
(v, 0, 0xff);
42 int mr
= e
== 0 | v
== 0 | v
== 0xff ?
0 : m
;
47 return as_float
(s |
(er << 23) | mr
);
50 /* supports denormal values
*/
51 const int multiplier
= 24;
57 sign
= val_ui
& 0x80000000;
58 val_ui
= val_ui
& 0x7fffffff; /* remove the sign bit */
61 exponent
= val_ui
>> 23; /* get the exponent */
64 /* denormal support
*/
66 127 -
(as_uint((float)(as_float(val_ui |
0x3f800000) -
1.0f
)) >> 23);
67 int dexponent
= 25 - fbh
;
68 uint dval_ui
= (((val_ui << fbh
) & 0x007fffff) |
(dexponent << 23));
69 int ex
= dexponent
+ n - multiplier
;
71 uint val
= sign |
(ex << 23) |
(dval_ui & 0x007fffff);
72 int ex1
= dexponent
+ multiplier
;
74 dval_ui
= (((dval_ui & 0x007fffff) |
0x800000) >> ex1
);
75 dval_ui
= dexponent
> 0 ? val
: dval_ui
;
76 dval_ui
= dexponent
> 254 ?
0x7f800000 : dval_ui
; /*overflow*/
77 dval_ui
= dexponent
< -multiplier ?
0 : dval_ui
; /*underflow*/
78 dval_ui
= dval_ui | sign
;
79 val_f
= as_float
(dval_ui);
83 val
= sign |
(exponent << 23) |
(val_ui & 0x007fffff);
84 ex1
= exponent
+ multiplier
;
86 val_ui
= (((val_ui & 0x007fffff) |
0x800000) >> ex1
);
87 val_ui
= exponent
> 0 ? val
: val_ui
;
88 val_ui
= exponent
> 254 ?
0x7f800000 : val_ui
; /*overflow*/
89 val_ui
= exponent
< -multiplier ?
0 : val_ui
; /*underflow*/
90 val_ui
= val_ui | sign
;
92 val_ui
= dexp
== 0 ? dval_ui
: val_ui
;
93 val_f
= as_float
(val_ui);
95 val_f
= __clc_isnan
(x) | __clc_isinf
(x) | val_x
== 0 ? x
: val_f
;
101 #pragma OPENCL EXTENSION cl_khr_fp64
: enable
103 _CLC_DEF _CLC_OVERLOAD double __clc_ldexp
(double x
, int n
) {
104 long l
= as_ulong
(x);
105 int e
= (l >> 52) & 0x7ff;
106 long s
= l
& 0x8000000000000000;
108 ulong ux
= as_ulong
(x * 0x1.0p
+53);
109 int de
= ((int)(ux >> 52) & 0x7ff) -
53;
116 v
= __clc_clamp
(v, -
0x7ff, 0x7ff);
120 double mr
= as_double
(ux |
((ulong)(v + 53) << 52));
123 mr
= v
> 0 ? as_double
(ux |
((ulong)v
<< 52)) : mr
;
125 mr
= v
== 0x7ff ? as_double
(s | PINFBITPATT_DP64
) : mr
;
126 mr
= v
< -
53 ? as_double
(s) : mr
;
128 mr
= ((n == 0) | __clc_isinf
(x) |
(x == 0)) ? x
: mr
;
136 #pragma OPENCL EXTENSION cl_khr_fp16
: enable
138 _CLC_OVERLOAD _CLC_DEF half __clc_ldexp
(half x
, int n
) {
139 return
(half)__clc_ldexp
((float)x
, n
);
142 _CLC_BINARY_VECTORIZE
(_CLC_OVERLOAD _CLC_DEF
, half
, __clc_ldexp
, half
, int
);