]> git.uio.no Git - u/mrichter/AliRoot.git/blob - Vc/include/Vc/avx/mask.tcc
update to Vc 0.7.3-dev
[u/mrichter/AliRoot.git] / Vc / include / Vc / avx / mask.tcc
1 /*  This file is part of the Vc library.
2
3     Copyright (C) 2011-2012 Matthias Kretz <kretz@kde.org>
4
5     Vc is free software: you can redistribute it and/or modify
6     it under the terms of the GNU Lesser General Public License as
7     published by the Free Software Foundation, either version 3 of
8     the License, or (at your option) any later version.
9
10     Vc is distributed in the hope that it will be useful, but
11     WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with Vc.  If not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20 namespace AliRoot {
21 namespace Vc
22 {
23 namespace AVX
24 {
25
26 template<> Vc_ALWAYS_INLINE Mask<4, 32>::Mask(const Mask<8, 32> &m)
27     : k(concat(_mm_unpacklo_ps(lo128(m.data()), lo128(m.data())),
28                 _mm_unpackhi_ps(lo128(m.data()), lo128(m.data()))))
29 {
30 }
31
32 template<> Vc_ALWAYS_INLINE Mask<8, 32>::Mask(const Mask<4, 32> &m)
33     // aabb ccdd -> abcd 0000
34     : k(concat(Mem::shuffle<X0, X2, Y0, Y2>(lo128(m.data()), hi128(m.data())),
35                 _mm_setzero_ps()))
36 {
37 }
38
39 template<unsigned int Size> Vc_ALWAYS_INLINE Vc_PURE int Mask<Size, 32u>::shiftMask() const
40 {
41     return _mm256_movemask_epi8(dataI());
42 }
43 template<unsigned int Size> Vc_ALWAYS_INLINE Vc_PURE int Mask<Size, 16u>::shiftMask() const
44 {
45     return _mm_movemask_epi8(dataI());
46 }
47
48 template<> Vc_ALWAYS_INLINE Vc_PURE int Mask< 4, 32>::toInt() const { return _mm256_movemask_pd(dataD()); }
49 template<> Vc_ALWAYS_INLINE Vc_PURE int Mask< 8, 32>::toInt() const { return _mm256_movemask_ps(data ()); }
50 template<> Vc_ALWAYS_INLINE Vc_PURE int Mask< 8, 16>::toInt() const { return _mm_movemask_epi8(_mm_packs_epi16(dataI(), _mm_setzero_si128())); }
51 template<> Vc_ALWAYS_INLINE Vc_PURE int Mask<16, 16>::toInt() const { return _mm_movemask_epi8(dataI()); }
52
53 template<> Vc_ALWAYS_INLINE Vc_PURE bool Mask< 4, 32>::operator[](int index) const { return toInt() & (1 << index); }
54 template<> Vc_ALWAYS_INLINE Vc_PURE bool Mask< 8, 32>::operator[](int index) const { return toInt() & (1 << index); }
55 template<> Vc_ALWAYS_INLINE Vc_PURE bool Mask< 8, 16>::operator[](int index) const { return shiftMask() & (1 << 2 * index); }
56 template<> Vc_ALWAYS_INLINE Vc_PURE bool Mask<16, 16>::operator[](int index) const { return toInt() & (1 << index); }
57
58 #ifndef VC_IMPL_POPCNT
59 static Vc_ALWAYS_INLINE Vc_CONST unsigned int _mm_popcnt_u32(unsigned int n) {
60     n = (n & 0x55555555U) + ((n >> 1) & 0x55555555U);
61     n = (n & 0x33333333U) + ((n >> 2) & 0x33333333U);
62     n = (n & 0x0f0f0f0fU) + ((n >> 4) & 0x0f0f0f0fU);
63     //n = (n & 0x00ff00ffU) + ((n >> 8) & 0x00ff00ffU);
64     //n = (n & 0x0000ffffU) + ((n >>16) & 0x0000ffffU);
65     return n;
66 }
67 #endif
68 template<unsigned int Size> Vc_ALWAYS_INLINE Vc_PURE int Mask<Size, 32u>::count() const { return _mm_popcnt_u32(toInt()); }
69 template<unsigned int Size> Vc_ALWAYS_INLINE Vc_PURE int Mask<Size, 16u>::count() const { return _mm_popcnt_u32(toInt()); }
70 template<unsigned int Size> Vc_ALWAYS_INLINE Vc_PURE int Mask<Size, 32u>::firstOne() const { return _bit_scan_forward(toInt()); }
71 template<unsigned int Size> Vc_ALWAYS_INLINE Vc_PURE int Mask<Size, 16u>::firstOne() const { return _bit_scan_forward(toInt()); }
72
73 } // namespace AVX
74 } // namespace Vc
75 } // namespace AliRoot