1 | /* Copyright (C) 2013-2014 Povilas Kanapickas <povilas@radix.lt> |
2 | |
3 | Distributed under the Boost Software License, Version 1.0. |
4 | (See accompanying file LICENSE_1_0.txt or copy at |
5 | http://www.boost.org/LICENSE_1_0.txt) |
6 | */ |
7 | |
8 | #ifndef LIBSIMDPP_SIMDPP_CORE_SHUFFLE4x2_H |
9 | #define LIBSIMDPP_SIMDPP_CORE_SHUFFLE4x2_H |
10 | |
11 | #ifndef LIBSIMDPP_SIMD_H |
12 | #error "This file must be included through simd.h" |
13 | #endif |
14 | |
15 | #include <simdpp/types.h> |
16 | #include <simdpp/detail/insn/shuffle4x2.h> |
17 | |
18 | namespace simdpp { |
19 | namespace SIMDPP_ARCH_NAMESPACE { |
20 | |
21 | /** Selects 32-bit values from two vectors. |
22 | The selector values must be in range [0; 7]. |
23 | |
24 | @code |
25 | For each 128-bit segment: |
26 | ab = [ a..b ] |
27 | r0 = ab[s0] |
28 | r1 = ab[s1] |
29 | r2 = ab[s2] |
30 | r3 = ab[s3] |
31 | @endcode |
32 | */ |
33 | template<unsigned s0, unsigned s1, unsigned s2, unsigned s3, unsigned N, |
34 | class V1, class V2> SIMDPP_INL |
35 | typename detail::get_expr2_nomask<V1, V2>::empty |
36 | shuffle4x2(const any_vec32<N,V1>& a, const any_vec32<N,V2>& b) |
37 | { |
38 | #if SIMDPP_USE_NULL || SIMDPP_USE_SSE2 || SIMDPP_USE_NEON |
39 | static_assert(s0 < 8 && s1 < 8 && s2 < 8 && s3 < 8, "Selector out of range" ); |
40 | typename detail::get_expr2_nomask_nosign<V1,V2,void>::type a0 = a.wrapped().eval(), |
41 | b0 = b.wrapped().eval(); |
42 | return detail::insn::i_shuffle4x2<s0,s1,s2,s3>(a0, b0); |
43 | #else |
44 | return SIMDPP_NOT_IMPLEMENTED_TEMPLATE2(V1, a, b); |
45 | #endif |
46 | } |
47 | |
48 | /** Selects 64-bit values from two vectors. |
49 | The selector values must be in range [0; 7]. |
50 | |
51 | @code |
52 | For each 256-bit segment: |
53 | ab = [ a..b ] |
54 | r0 = ab[s0] |
55 | r1 = ab[s1] |
56 | r2 = ab[s2] |
57 | r3 = ab[s3] |
58 | @endcode |
59 | */ |
60 | template<unsigned s0, unsigned s1, unsigned s2, unsigned s3, unsigned N, |
61 | class V1, class V2> SIMDPP_INL |
62 | typename detail::get_expr2_nomask<V1, V2>::empty |
63 | shuffle4x2(const any_vec64<N,V1>& a, const any_vec64<N,V2>& b) |
64 | { |
65 | #if SIMDPP_USE_NULL || SIMDPP_USE_SSE2 || SIMDPP_USE_NEON |
66 | static_assert(s0 < 8 && s1 < 8 && s2 < 8 && s3 < 8, "Selector out of range" ); |
67 | typename detail::get_expr2_nomask_nosign<V1,V2,void>::type a0 = a.wrapped().eval(), |
68 | b0 = b.wrapped().eval(); |
69 | return detail::insn::i_shuffle4x2<s0,s1,s2,s3>(a0, b0); |
70 | #else |
71 | return SIMDPP_NOT_IMPLEMENTED_TEMPLATE2(V1, a, b); |
72 | #endif |
73 | } |
74 | |
75 | } // namespace SIMDPP_ARCH_NAMESPACE |
76 | } // namespace simdpp |
77 | |
78 | #endif |
79 | |
80 | |