1 | /* Copyright (C) 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_SHUFFLE2x2_H |
9 | #define LIBSIMDPP_SIMDPP_CORE_SHUFFLE2x2_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; 3]. |
23 | |
24 | @code |
25 | For each 64-bit segment: |
26 | ab = [ a..b ] |
27 | r0 = ab[s0] |
28 | r1 = ab[s1] |
29 | @endcode |
30 | */ |
31 | template<unsigned s0, unsigned s1, unsigned N, |
32 | class V1, class V2> SIMDPP_INL |
33 | typename detail::get_expr2_nomask<V1, V2>::empty |
34 | shuffle2x2(const any_vec32<N,V1>& a, const any_vec32<N,V2>& b) |
35 | { |
36 | #if SIMDPP_USE_NULL || SIMDPP_USE_SSE2 || SIMDPP_USE_NEON |
37 | static_assert(s0 < 4 && s1 < 4, "Selector out of range" ); |
38 | typename detail::get_expr2_nomask_nosign<V1,V2,void>::type a0 = a.wrapped().eval(), |
39 | b0 = b.wrapped().eval(); |
40 | return detail::insn::i_shuffle2x2<s0,s1>(a0, b0); |
41 | #else |
42 | return SIMDPP_NOT_IMPLEMENTED_TEMPLATE2(V1, a, b); |
43 | #endif |
44 | } |
45 | |
46 | /** Selects 64-bit values from two vectors. |
47 | The selector values must be in range [0; 3]. |
48 | |
49 | @code |
50 | For each 128-bit segment: |
51 | ab = [ a..b ] |
52 | r0 = ab[s0] |
53 | r1 = ab[s1] |
54 | @endcode |
55 | */ |
56 | template<unsigned s0, unsigned s1, unsigned N, |
57 | class V1, class V2> SIMDPP_INL |
58 | typename detail::get_expr2_nomask<V1, V2>::empty |
59 | shuffle2x2(const any_vec64<N,V1>& a, const any_vec64<N,V2>& b) |
60 | { |
61 | #if SIMDPP_USE_NULL || SIMDPP_USE_SSE2 || SIMDPP_USE_NEON |
62 | static_assert(s0 < 4 && s1 < 4, "Selector out of range" ); |
63 | typename detail::get_expr2_nomask_nosign<V1,V2,void>::type a0 = a.wrapped().eval(), |
64 | b0 = b.wrapped().eval(); |
65 | return detail::insn::i_shuffle2x2<s0,s1>(a0, b0); |
66 | #else |
67 | return SIMDPP_NOT_IMPLEMENTED_TEMPLATE2(V1, a, b); |
68 | #endif |
69 | } |
70 | |
71 | } // namespace SIMDPP_ARCH_NAMESPACE |
72 | } // namespace simdpp |
73 | |
74 | #endif |
75 | |
76 | |