Cleanup: trailing space
[blender.git] / intern / cycles / util / util_avxf.h
1 /*
2  * Copyright 2016 Intel Corporation
3  *
4  * Licensed under the Apache License, Version 2.0(the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __UTIL_AVXF_H__
18 #define __UTIL_AVXF_H__
19
20 CCL_NAMESPACE_BEGIN
21
22 struct avxb;
23
24 struct avxf
25 {
26         typedef avxf Float;
27
28         enum { size = 8 };  /* Number of SIMD elements. */
29
30         union {
31                 __m256 m256;
32                 float f[8];
33                 int i[8];
34         };
35
36         __forceinline avxf           () {}
37         __forceinline avxf           (const avxf& other) { m256 = other.m256; }
38         __forceinline avxf& operator=(const avxf& other) { m256 = other.m256; return *this; }
39
40         __forceinline avxf(const __m256 a) : m256(a) {}
41         __forceinline avxf(const __m256i a) : m256(_mm256_castsi256_ps (a)) {}
42
43         __forceinline operator const __m256&(void) const { return m256; }
44         __forceinline operator       __m256&(void)       { return m256; }
45
46         __forceinline avxf          (float a) : m256(_mm256_set1_ps(a)) {}
47
48         __forceinline avxf(float high32x4, float low32x4) :
49            m256(_mm256_set_ps(high32x4, high32x4, high32x4, high32x4, low32x4, low32x4, low32x4, low32x4)) {}
50
51         __forceinline avxf(float a3, float a2, float a1, float a0) :
52            m256(_mm256_set_ps(a3, a2, a1, a0, a3, a2, a1, a0)) {}
53
54         __forceinline avxf(float a7, float a6, float a5, float a4, float a3, float a2, float a1, float a0) :
55                 m256(_mm256_set_ps(a7, a6, a5, a4, a3, a2, a1, a0)) {}
56
57         __forceinline avxf(float3 a) :
58                 m256(_mm256_set_ps(a.w, a.z, a.y, a.x, a.w, a.z, a.y, a.x)) {}
59
60
61         __forceinline avxf(int a3, int a2, int a1, int a0)
62         {
63                 const __m256i foo = _mm256_set_epi32(a3, a2, a1, a0, a3, a2, a1, a0);
64                 m256 = _mm256_castsi256_ps(foo);
65         }
66
67
68         __forceinline avxf(int a7, int a6, int a5, int a4, int a3, int a2, int a1, int a0)
69         {
70                 const __m256i foo = _mm256_set_epi32(a7, a6, a5, a4, a3, a2, a1, a0);
71                 m256 = _mm256_castsi256_ps(foo);
72         }
73
74         __forceinline avxf(__m128 a, __m128 b)
75         {
76                 const __m256 foo = _mm256_castps128_ps256(a);
77                 m256 = _mm256_insertf128_ps(foo, b, 1);
78         }
79
80         __forceinline const float& operator [](const size_t i) const { assert(i < 8); return f[i]; }
81         __forceinline       float& operator [](const size_t i) { assert(i < 8); return f[i]; }
82 };
83
84 __forceinline avxf cross(const avxf& a, const avxf& b)
85 {
86         avxf r(0.0, a[4]*b[5] - a[5]*b[4], a[6]*b[4] - a[4]*b[6], a[5]*b[6] - a[6]*b[5],
87                    0.0, a[0]*b[1] - a[1]*b[0], a[2]*b[0] - a[0]*b[2], a[1]*b[2] - a[2]*b[1]);
88         return r;
89 }
90
91 __forceinline void dot3(const avxf& a, const avxf& b, float &den, float &den2)
92 {
93         const avxf t = _mm256_mul_ps(a.m256, b.m256);
94         den = ((float*)&t)[0] + ((float*)&t)[1] + ((float*)&t)[2];
95         den2 = ((float*)&t)[4] + ((float*)&t)[5] + ((float*)&t)[6];
96 }
97
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Unary Operators
100 ////////////////////////////////////////////////////////////////////////////////
101
102 __forceinline const avxf mm256_sqrt(const avxf& a) { return _mm256_sqrt_ps(a.m256); }
103
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Binary Operators
106 ////////////////////////////////////////////////////////////////////////////////
107
108 __forceinline const avxf operator +(const avxf& a, const avxf& b) { return _mm256_add_ps(a.m256, b.m256); }
109 __forceinline const avxf operator +(const avxf& a, const float& b) { return a + avxf(b); }
110 __forceinline const avxf operator +(const float& a, const avxf& b) { return avxf(a) + b; }
111
112 __forceinline const avxf operator -(const avxf& a, const avxf& b) { return _mm256_sub_ps(a.m256, b.m256); }
113 __forceinline const avxf operator -(const avxf& a, const float& b) { return a - avxf(b); }
114 __forceinline const avxf operator -(const float& a, const avxf& b) { return avxf(a) - b; }
115
116 __forceinline const avxf operator *(const avxf& a, const avxf& b) { return _mm256_mul_ps(a.m256, b.m256); }
117 __forceinline const avxf operator *(const avxf& a, const float& b) { return a * avxf(b); }
118 __forceinline const avxf operator *(const float& a, const avxf& b) { return avxf(a) * b; }
119
120 __forceinline const avxf operator /(const avxf& a, const avxf& b) { return _mm256_div_ps(a.m256,b.m256); }
121 __forceinline const avxf operator /(const avxf& a, const float& b) { return a/avxf(b); }
122 __forceinline const avxf operator /(const float& a, const avxf& b) { return avxf(a)/b; }
123
124 __forceinline const avxf operator|(const avxf& a, const avxf& b) { return _mm256_or_ps(a.m256,b.m256); }
125
126 __forceinline const avxf operator^(const avxf& a, const avxf& b) { return _mm256_xor_ps(a.m256,b.m256); }
127
128 __forceinline const avxf operator&(const avxf& a, const avxf& b) { return _mm256_and_ps(a.m256,b.m256); }
129
130 __forceinline const avxf max(const avxf& a, const avxf& b) { return _mm256_max_ps(a.m256, b.m256); }
131 __forceinline const avxf min(const avxf& a, const avxf& b) { return _mm256_min_ps(a.m256, b.m256); }
132
133 ////////////////////////////////////////////////////////////////////////////////
134 /// Movement/Shifting/Shuffling Functions
135 ////////////////////////////////////////////////////////////////////////////////
136
137 __forceinline const avxf shuffle(const avxf& a, const __m256i &shuf) {
138         return _mm256_permutevar_ps(a, shuf);
139 }
140
141 template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7> __forceinline const avxf shuffle(const avxf& a) {
142         return _mm256_permutevar_ps(a, _mm256_set_epi32( i7,i6,i5,i4 ,i3,i2,i1,i0));
143 }
144
145 template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const avxf shuffle(const avxf& a, const avxf& b) {
146         return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
147 }
148 template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const avxf shuffle(const avxf& a) {
149         return shuffle<i0,i1,i2,i3>(a,a);
150 }
151 template<size_t i0> __forceinline const avxf shuffle(const avxf& a, const avxf& b) {
152         return shuffle<i0,i0,i0,i0>(a, b);
153 }
154 template<size_t i0> __forceinline const avxf shuffle(const avxf& a) {
155         return shuffle<i0>(a,a);
156 }
157
158 template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7> __forceinline const avxf permute(const avxf& a) {
159 #ifdef __KERNEL_AVX2__
160         return  _mm256_permutevar8x32_ps(a,_mm256_set_epi32( i7,i6,i5,i4 ,i3,i2,i1,i0));
161 #else
162         float temp[8];
163         _mm256_storeu_ps((float*)&temp, a);
164         return avxf(temp[i7], temp[i6], temp[i5], temp[i4], temp[i3], temp[i2], temp[i1], temp[i0]);
165 #endif
166 }
167
168 template<int S0, int S1, int S2, int S3,int S4,int S5,int S6, int S7>
169 ccl_device_inline const avxf set_sign_bit(const avxf &a)
170 {
171         return a ^ avxf(S7 << 31, S6 << 31, S5 << 31, S4 << 31, S3 << 31,S2 << 31,S1 << 31,S0 << 31);
172 }
173
174 template<size_t S0, size_t S1, size_t S2, size_t S3,size_t S4,size_t S5,size_t S6, size_t S7>
175 ccl_device_inline const avxf blend(const avxf &a, const avxf &b)
176 {
177         return _mm256_blend_ps(a,b,S7 << 0 | S6 << 1 | S5 << 2 | S4 << 3 | S3 << 4 | S2 << 5 | S1 << 6 | S0 << 7);
178 }
179
180 template<size_t S0, size_t S1, size_t S2, size_t S3 >
181 ccl_device_inline const avxf blend(const avxf &a, const avxf &b)
182 {
183         return blend<S0,S1,S2,S3,S0,S1,S2,S3>(a,b);
184 }
185
186 //#if defined(__KERNEL_SSE41__)
187 __forceinline avxf maxi(const avxf& a, const avxf& b) {
188         const avxf ci = _mm256_max_ps(a, b);
189         return ci;
190 }
191
192 __forceinline avxf mini(const avxf& a, const avxf& b) {
193         const avxf ci = _mm256_min_ps(a, b);
194         return ci;
195 }
196 //#endif
197
198 ////////////////////////////////////////////////////////////////////////////////
199 /// Ternary Operators
200 ////////////////////////////////////////////////////////////////////////////////
201 __forceinline const avxf madd (const avxf& a, const avxf& b, const avxf& c) {
202 #ifdef __KERNEL_AVX2__
203         return _mm256_fmadd_ps(a,b,c);
204 #else
205         return c+(a*b);
206 #endif
207 }
208
209 __forceinline const avxf nmadd(const avxf& a, const avxf& b, const avxf& c) {
210 #ifdef __KERNEL_AVX2__
211         return _mm256_fnmadd_ps(a, b, c);
212 #else
213         return c-(a*b);
214 #endif
215 }
216 __forceinline const avxf msub(const avxf& a, const avxf& b, const avxf& c) {
217         return _mm256_fmsub_ps(a, b, c);
218 }
219
220 ////////////////////////////////////////////////////////////////////////////////
221 /// Comparison Operators
222 ////////////////////////////////////////////////////////////////////////////////
223 #ifdef __KERNEL_AVX2__
224 __forceinline const avxb operator <=(const avxf& a, const avxf& b) {
225         return _mm256_cmp_ps(a.m256, b.m256, _CMP_LE_OS);
226 }
227 #endif
228
229 #endif
230
231 #ifndef _mm256_set_m128
232 #  define _mm256_set_m128(/* __m128 */ hi, /* __m128 */ lo) \
233     _mm256_insertf128_ps(_mm256_castps128_ps256(lo), (hi), 0x1)
234 #endif
235
236 #define _mm256_loadu2_m128(/* float const* */ hiaddr, /* float const* */ loaddr) \
237     _mm256_set_m128(_mm_loadu_ps(hiaddr), _mm_loadu_ps(loaddr))
238
239 CCL_NAMESPACE_END