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_MOVE_L_H
9#define LIBSIMDPP_SIMDPP_CORE_MOVE_L_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/move_l.h>
17
18namespace simdpp {
19namespace SIMDPP_ARCH_NAMESPACE {
20
21/** Moves the elements in an int8x16 vector to the left by @a shift positions.
22
23 @code
24 shift: pos:| 0 1 . 14 15 |
25 0 r = [ a0 a1 . a14 a15 ]
26 1 r = [ a1 a2 . a15 0 ]
27 2 r = [ a2 a3 . 0 0 ]
28 ... .. .. .. ... .. .. ..
29 14 r = [ a15 0 . 0 0 ]
30 15 r = [ 0 0 . 0 0 ]
31 16 r = [ 0 0 . 0 0 ]
32 @endcode
33
34 @par 256-bit version:
35 The lower and higher 128-bit halves are processed as if 128-bit instruction
36 was applied to each of them separately.
37
38 @icost{SSE2-AVX, NEON, ALTIVEC, 2}
39*/
40template<unsigned shift, unsigned N, class V> SIMDPP_INL
41typename detail::get_expr_nomask<V>::empty
42 move16_l(const any_vec8<N,V>& a)
43{
44 static_assert(shift <= 16, "Shift out of bounds");
45 typename detail::get_expr_nomask_nosign<V>::type ra;
46 ra = a.wrapped().eval();
47 return detail::insn::i_move16_l_wrapper<shift>::run(ra);
48}
49
50/** Moves the 16-bit elements in a vector to the left by @a shift positions.
51
52 @code
53 shift: pos:| 0 1 . 6 7 |
54 0 r = [ a0 a1 . a6 a7 ]
55 1 r = [ a1 a2 . a7 0 ]
56 2 r = [ a2 a3 . 0 0 ]
57 ... .. .. .. ... .. ..
58 6 r = [ a6 a7 . 0 0 ]
59 7 r = [ a7 0 . 0 0 ]
60 8 r = [ 0 0 . 0 0 ]
61 @endcode
62
63 @par 256-bit version:
64 The lower and higher 128-bit halves are processed as if 128-bit instruction
65 was applied to each of them separately.
66
67 @icost{SSE2-AVX, NEON, ALTIVEC, 2}
68*/
69template<unsigned shift, unsigned N, class V> SIMDPP_INL
70typename detail::get_expr_nomask<V>::empty
71 move8_l(const any_vec16<N,V>& a)
72{
73 static_assert(shift <= 8, "Shift out of bounds");
74
75 typename detail::get_expr_nomask_nosign<V>::type ra;
76 ra = a.wrapped().eval();
77 return detail::insn::i_move8_l_wrapper<shift>::run(ra);
78}
79
80/** Moves the 32-bit elements in a vector to the left by @a shift positions.
81
82 @code
83 shift: pos:| 0 1 2 3 |
84 0 r = [ a0 a1 a2 a3 ]
85 1 r = [ a1 a2 a3 0 ]
86 2 r = [ a2 a3 0 0 ]
87 3 r = [ a3 0 0 0 ]
88 4 r = [ 0 0 0 0 ]
89 @endcode
90
91 @par 256-bit version:
92 The lower and higher 128-bit halves are processed as if 128-bit instruction
93 was applied to each of them separately.
94
95 @icost{SSE2-AVX, NEON, ALTIVEC, 2}
96*/
97template<unsigned shift, unsigned N, class V> SIMDPP_INL
98typename detail::get_expr_nomask<V>::empty
99 move4_l(const any_vec32<N,V>& a)
100{
101 static_assert(shift <= 4, "Shift out of bounds");
102
103 typename detail::get_expr_nomask_nosign<V>::type ra;
104 ra = a.wrapped().eval();
105 return detail::insn::i_move4_l_wrapper<shift>::run(ra);
106}
107
108
109/** Moves the 64-bit elements in a vector to the left by @a shift positions.
110
111 @code
112 shift: pos:| 0 1 |
113 0 r = [ a0 a1 ]
114 1 r = [ a1 0 ]
115 2 r = [ 0 0 ]
116 @endcode
117
118 @par 256-bit version:
119 The lower and higher 128-bit halves are processed as if 128-bit instruction
120 was applied to each of them separately.
121
122 @icost{SSE2-AVX, NEON, ALTIVEC, 2}
123*/
124template<unsigned shift, unsigned N, class V> SIMDPP_INL
125typename detail::get_expr_nomask<V>::empty
126 move2_l(const any_vec64<N,V>& a)
127{
128 static_assert(shift <= 2, "Shift out of bounds");
129
130 typename detail::get_expr_nomask_nosign<V>::type ra;
131 ra = a.wrapped().eval();
132 return detail::insn::i_move2_l_wrapper<shift>::run(ra);
133}
134
135} // namespace SIMDPP_ARCH_NAMESPACE
136} // namespace simdpp
137
138#endif
139
140