1 /* This file is part of the Vc library.
3 Copyright (C) 2011-2012 Matthias Kretz <kretz@kde.org>
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.
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.
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/>.
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()))))
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())),
39 template<unsigned int Size> Vc_ALWAYS_INLINE Vc_PURE int Mask<Size, 32u>::shiftMask() const
41 return _mm256_movemask_epi8(dataI());
43 template<unsigned int Size> Vc_ALWAYS_INLINE Vc_PURE int Mask<Size, 16u>::shiftMask() const
45 return _mm_movemask_epi8(dataI());
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()); }
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); }
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);
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()); }
75 } // namespace AliRoot