Cycles: Make all #include statements relative to cycles source directory
[blender.git] / intern / cycles / util / util_simd.h
1 /*
2  * Copyright 2011-2013 Intel Corporation
3  * Modifications Copyright 2014, Blender Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0(the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #ifndef __UTIL_SIMD_TYPES_H__
19 #define __UTIL_SIMD_TYPES_H__
20
21 #include <limits>
22
23 #include "util/util_debug.h"
24 #include "util/util_types.h"
25
26 CCL_NAMESPACE_BEGIN
27
28 #ifdef __KERNEL_SSE2__
29
30 struct sseb;
31 struct ssei;
32 struct ssef;
33
34 extern const __m128 _mm_lookupmask_ps[16];
35
36 /* Special Types */
37
38 static struct TrueTy {
39 __forceinline operator bool( ) const { return true; }
40 } True ccl_maybe_unused;
41
42 static struct FalseTy {
43 __forceinline operator bool( ) const { return false; }
44 } False ccl_maybe_unused;
45
46 static struct NegInfTy
47 {
48 __forceinline operator          float    ( ) const { return -std::numeric_limits<float>::infinity(); }
49 __forceinline operator          int      ( ) const { return std::numeric_limits<int>::min(); }
50 } neg_inf ccl_maybe_unused;
51
52 static struct PosInfTy
53 {
54 __forceinline operator          float    ( ) const { return std::numeric_limits<float>::infinity(); }
55 __forceinline operator          int      ( ) const { return std::numeric_limits<int>::max(); }
56 } inf ccl_maybe_unused, pos_inf ccl_maybe_unused;
57
58 /* Intrinsics Functions */
59
60 #if defined(__BMI__) && defined(__GNUC__)
61 #  ifndef _tzcnt_u32
62 #    define _tzcnt_u32 __tzcnt_u32
63 #  endif
64 #  ifndef _tzcnt_u64
65 #    define _tzcnt_u64 __tzcnt_u64
66 #  endif
67 #endif
68
69 #if defined(__LZCNT__)
70 #define _lzcnt_u32 __lzcnt32
71 #define _lzcnt_u64 __lzcnt64
72 #endif
73
74 #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__clang__)
75
76 __forceinline int __popcnt(int in) {
77   return _mm_popcnt_u32(in);
78 }
79
80 #if !defined(_MSC_VER)
81 __forceinline unsigned int __popcnt(unsigned int in) {
82   return _mm_popcnt_u32(in);
83 }
84 #endif
85
86 #if defined(__KERNEL_64_BIT__)
87 __forceinline long long __popcnt(long long in) {
88   return _mm_popcnt_u64(in);
89 }
90 __forceinline size_t __popcnt(size_t in) {
91   return _mm_popcnt_u64(in);
92 }
93 #endif
94
95 __forceinline int __bsf(int v) {
96 #if defined(__KERNEL_AVX2__) 
97   return _tzcnt_u32(v);
98 #else
99   unsigned long r = 0; _BitScanForward(&r,v); return r;
100 #endif
101 }
102
103 __forceinline unsigned int __bsf(unsigned int v) {
104 #if defined(__KERNEL_AVX2__) 
105   return _tzcnt_u32(v);
106 #else
107   unsigned long r = 0; _BitScanForward(&r,v); return r;
108 #endif
109 }
110
111 __forceinline int __bsr(int v) {
112   unsigned long r = 0; _BitScanReverse(&r,v); return r;
113 }
114
115 __forceinline int __btc(int v, int i) {
116   long r = v; _bittestandcomplement(&r,i); return r;
117 }
118
119 __forceinline int __bts(int v, int i) {
120   long r = v; _bittestandset(&r,i); return r;
121 }
122
123 __forceinline int __btr(int v, int i) {
124   long r = v; _bittestandreset(&r,i); return r;
125 }
126
127 __forceinline int bitscan(int v) {
128 #if defined(__KERNEL_AVX2__) 
129   return _tzcnt_u32(v);
130 #else
131   return __bsf(v);
132 #endif
133 }
134
135 __forceinline int clz(const int x)
136 {
137 #if defined(__KERNEL_AVX2__)
138   return _lzcnt_u32(x);
139 #else
140   if(UNLIKELY(x == 0)) return 32;
141   return 31 - __bsr(x);    
142 #endif
143 }
144
145 __forceinline int __bscf(int& v) 
146 {
147   int i = __bsf(v);
148   v &= v-1;
149   return i;
150 }
151
152 __forceinline unsigned int __bscf(unsigned int& v) 
153 {
154   unsigned int i = __bsf(v);
155   v &= v-1;
156   return i;
157 }
158
159 #if defined(__KERNEL_64_BIT__)
160
161 __forceinline size_t __bsf(size_t v) {
162 #if defined(__KERNEL_AVX2__) 
163   return _tzcnt_u64(v);
164 #else
165   unsigned long r = 0; _BitScanForward64(&r,v); return r;
166 #endif
167 }
168
169 __forceinline size_t __bsr(size_t v) {
170   unsigned long r = 0; _BitScanReverse64(&r,v); return r;
171 }
172
173 __forceinline size_t __btc(size_t v, size_t i) {
174   size_t r = v; _bittestandcomplement64((__int64*)&r,i); return r;
175 }
176
177 __forceinline size_t __bts(size_t v, size_t i) {
178   __int64 r = v; _bittestandset64(&r,i); return r;
179 }
180
181 __forceinline size_t __btr(size_t v, size_t i) {
182   __int64 r = v; _bittestandreset64(&r,i); return r;
183 }
184
185 __forceinline size_t bitscan(size_t v) {
186 #if defined(__KERNEL_AVX2__)
187 #if defined(__KERNEL_64_BIT__)
188   return _tzcnt_u64(v);
189 #else
190   return _tzcnt_u32(v);
191 #endif
192 #else
193   return __bsf(v);
194 #endif
195 }
196
197 __forceinline size_t __bscf(size_t& v) 
198 {
199   size_t i = __bsf(v);
200   v &= v-1;
201   return i;
202 }
203
204 #endif /* __KERNEL_64_BIT__ */
205
206 #else /* _WIN32 */
207
208 __forceinline unsigned int __popcnt(unsigned int in) {
209   int r = 0; asm ("popcnt %1,%0" : "=r"(r) : "r"(in)); return r;
210 }
211
212 __forceinline int __bsf(int v) {
213   int r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r;
214 }
215
216 __forceinline int __bsr(int v) {
217   int r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r;
218 }
219
220 __forceinline int __btc(int v, int i) {
221   int r = 0; asm ("btc %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags" ); return r;
222 }
223
224 __forceinline int __bts(int v, int i) {
225   int r = 0; asm ("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r;
226 }
227
228 __forceinline int __btr(int v, int i) {
229   int r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r;
230 }
231
232 #if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__))
233 __forceinline size_t __bsf(size_t v) {
234   size_t r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r;
235 }
236 #endif
237
238 __forceinline unsigned int __bsf(unsigned int v) {
239   unsigned int r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r;
240 }
241
242 __forceinline size_t __bsr(size_t v) {
243   size_t r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r;
244 }
245
246 __forceinline size_t __btc(size_t v, size_t i) {
247   size_t r = 0; asm ("btc %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags" ); return r;
248 }
249
250 __forceinline size_t __bts(size_t v, size_t i) {
251   size_t r = 0; asm ("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r;
252 }
253
254 __forceinline size_t __btr(size_t v, size_t i) {
255   size_t r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r;
256 }
257
258 __forceinline int bitscan(int v) {
259 #if defined(__KERNEL_AVX2__) 
260   return _tzcnt_u32(v);
261 #else
262   return __bsf(v);
263 #endif
264 }
265
266 __forceinline unsigned int bitscan(unsigned int v) {
267 #if defined(__KERNEL_AVX2__) 
268   return _tzcnt_u32(v);
269 #else
270   return __bsf(v);
271 #endif
272 }
273
274 #if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__))
275 __forceinline size_t bitscan(size_t v) {
276 #if defined(__KERNEL_AVX2__)
277 #if defined(__KERNEL_64_BIT__)
278   return _tzcnt_u64(v);
279 #else
280   return _tzcnt_u32(v);
281 #endif
282 #else
283   return __bsf(v);
284 #endif
285 }
286 #endif
287
288 __forceinline int clz(const int x)
289 {
290 #if defined(__KERNEL_AVX2__)
291   return _lzcnt_u32(x);
292 #else
293   if(UNLIKELY(x == 0)) return 32;
294   return 31 - __bsr(x);    
295 #endif
296 }
297
298 __forceinline int __bscf(int& v) 
299 {
300   int i = bitscan(v);
301 #if defined(__KERNEL_AVX2__)
302   v &= v-1;
303 #else
304   v = __btc(v,i);
305 #endif
306   return i;
307 }
308
309 __forceinline unsigned int __bscf(unsigned int& v) 
310 {
311   unsigned int i = bitscan(v);
312   v &= v-1;
313   return i;
314 }
315
316 #if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__))
317 __forceinline size_t __bscf(size_t& v) 
318 {
319   size_t i = bitscan(v);
320 #if defined(__KERNEL_AVX2__)
321   v &= v-1;
322 #else
323   v = __btc(v,i);
324 #endif
325   return i;
326 }
327 #endif
328
329 #endif /* _WIN32 */
330
331 static const unsigned int BITSCAN_NO_BIT_SET_32 = 32;
332 static const size_t       BITSCAN_NO_BIT_SET_64 = 64;
333
334 /* Emulation of SSE4 functions with SSE3 */
335
336 #if defined(__KERNEL_SSE3) && !defined(__KERNEL_SSE4__)
337
338 #define _MM_FROUND_TO_NEAREST_INT    0x00
339 #define _MM_FROUND_TO_NEG_INF        0x01
340 #define _MM_FROUND_TO_POS_INF        0x02
341 #define _MM_FROUND_TO_ZERO           0x03
342 #define _MM_FROUND_CUR_DIRECTION     0x04
343
344 #define _mm_blendv_ps __emu_mm_blendv_ps
345 __forceinline __m128 _mm_blendv_ps( __m128 value, __m128 input, __m128 mask ) { 
346     return _mm_or_ps(_mm_and_ps(mask, input), _mm_andnot_ps(mask, value)); 
347 }
348
349 #define _mm_blend_ps __emu_mm_blend_ps
350 __forceinline __m128 _mm_blend_ps( __m128 value, __m128 input, const int mask ) { 
351     assert(mask < 0x10); return _mm_blendv_ps(value, input, _mm_lookupmask_ps[mask]); 
352 }
353
354 #define _mm_blendv_epi8 __emu_mm_blendv_epi8
355 __forceinline __m128i _mm_blendv_epi8( __m128i value, __m128i input, __m128i mask ) { 
356     return _mm_or_si128(_mm_and_si128(mask, input), _mm_andnot_si128(mask, value)); 
357 }
358
359 #define _mm_mullo_epi32 __emu_mm_mullo_epi32
360 __forceinline __m128i _mm_mullo_epi32( __m128i value, __m128i input ) {
361   __m128i rvalue;
362   char* _r = (char*)(&rvalue + 1);
363   char* _v = (char*)(& value + 1);
364   char* _i = (char*)(& input + 1);
365   for( ssize_t i = -16 ; i != 0 ; i += 4 ) *((int32*)(_r + i)) = *((int32*)(_v + i))*  *((int32*)(_i + i));
366   return rvalue;
367 }
368
369
370 #define _mm_min_epi32 __emu_mm_min_epi32
371 __forceinline __m128i _mm_min_epi32( __m128i value, __m128i input ) { 
372     return _mm_blendv_epi8(input, value, _mm_cmplt_epi32(value, input)); 
373 }
374
375 #define _mm_max_epi32 __emu_mm_max_epi32
376 __forceinline __m128i _mm_max_epi32( __m128i value, __m128i input ) { 
377     return _mm_blendv_epi8(value, input, _mm_cmplt_epi32(value, input)); 
378 }
379
380 #define _mm_extract_epi32 __emu_mm_extract_epi32
381 __forceinline int _mm_extract_epi32( __m128i input, const int index ) {
382   switch ( index ) {
383   case 0: return _mm_cvtsi128_si32(input);
384   case 1: return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(1, 1, 1, 1)));
385   case 2: return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(2, 2, 2, 2)));
386   case 3: return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(3, 3, 3, 3)));
387   default: assert(false); return 0;
388   }
389 }
390
391 #define _mm_insert_epi32 __emu_mm_insert_epi32
392 __forceinline __m128i _mm_insert_epi32( __m128i value, int input, const int index ) { 
393     assert(index >= 0 && index < 4); ((int*)&value)[index] = input; return value; 
394 }
395
396 #define _mm_extract_ps __emu_mm_extract_ps
397 __forceinline int _mm_extract_ps( __m128 input, const int index ) {
398   int32* ptr = (int32*)&input; return ptr[index];
399 }
400
401 #define _mm_insert_ps __emu_mm_insert_ps
402 __forceinline __m128 _mm_insert_ps( __m128 value, __m128 input, const int index )
403 { assert(index < 0x100); ((float*)&value)[(index >> 4)&0x3] = ((float*)&input)[index >> 6]; return _mm_andnot_ps(_mm_lookupmask_ps[index&0xf], value); }
404
405 #define _mm_round_ps __emu_mm_round_ps
406 __forceinline __m128 _mm_round_ps( __m128 value, const int flags )
407 {
408   switch ( flags )
409   {
410   case _MM_FROUND_TO_NEAREST_INT: return _mm_cvtepi32_ps(_mm_cvtps_epi32(value));
411   case _MM_FROUND_TO_NEG_INF    : return _mm_cvtepi32_ps(_mm_cvtps_epi32(_mm_add_ps(value, _mm_set1_ps(-0.5f))));
412   case _MM_FROUND_TO_POS_INF    : return _mm_cvtepi32_ps(_mm_cvtps_epi32(_mm_add_ps(value, _mm_set1_ps( 0.5f))));
413   case _MM_FROUND_TO_ZERO       : return _mm_cvtepi32_ps(_mm_cvttps_epi32(value));
414   }
415   return value;
416 }
417
418 #ifdef _M_X64
419 #define _mm_insert_epi64 __emu_mm_insert_epi64
420 __forceinline __m128i _mm_insert_epi64( __m128i value, __int64 input, const int index ) { 
421     assert(size_t(index) < 4); ((__int64*)&value)[index] = input; return value; 
422 }
423
424 #define _mm_extract_epi64 __emu_mm_extract_epi64
425 __forceinline __int64 _mm_extract_epi64( __m128i input, const int index ) { 
426     assert(size_t(index) < 2); 
427     return index == 0 ? _mm_cvtsi128_si64x(input) : _mm_cvtsi128_si64x(_mm_unpackhi_epi64(input, input)); 
428 }
429 #endif
430
431 #endif
432
433 #else  /* __KERNEL_SSE2__ */
434
435 /* This section is for utility functions which operates on non-register data
436  * which might be used from a non-vectorized code.
437  */
438
439 ccl_device_inline int bitscan(int value)
440 {
441         assert(value != 0);
442         int bit = 0;
443         while(value >>= 1) {
444                 ++bit;
445         }
446         return bit;
447 }
448
449
450 #endif /* __KERNEL_SSE2__ */
451
452 CCL_NAMESPACE_END
453
454 #include "util/util_math.h"
455 #include "util/util_sseb.h"
456 #include "util/util_ssei.h"
457 #include "util/util_ssef.h"
458 #include "util/util_avxf.h"
459
460 #endif /* __UTIL_SIMD_TYPES_H__ */
461