1/* Copyright (C) 2011-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_TYPES_INT32X4_H
9#define LIBSIMDPP_SIMDPP_TYPES_INT32X4_H
10
11#ifndef LIBSIMDPP_SIMD_H
12 #error "This file must be included through simd.h"
13#endif
14
15#include <simdpp/setup_arch.h>
16#include <simdpp/types/fwd.h>
17#include <simdpp/types/any.h>
18#include <simdpp/core/cast.h>
19#include <simdpp/detail/construct_eval.h>
20#include <simdpp/detail/array.h>
21#include <simdpp/detail/null/mask.h>
22#include <cstdint>
23
24namespace simdpp {
25namespace SIMDPP_ARCH_NAMESPACE {
26
27/** Class representing 4x 32-bit signed integer vector
28*/
29template<>
30class int32<4, void> : public any_int32<4, int32<4,void>> {
31public:
32 static const unsigned type_tag = SIMDPP_TAG_INT;
33 using element_type = int32_t;
34 using base_vector_type = int32<4,void>;
35 using expr_type = void;
36
37#if SIMDPP_USE_SSE2
38 using native_type = __m128i;
39#elif SIMDPP_USE_NEON
40 using native_type = int32x4_t;
41#elif SIMDPP_USE_ALTIVEC
42 using native_type = __vector int32_t;
43#elif SIMDPP_USE_MSA
44 using native_type = v4i32;
45#else
46 using native_type = detail::vararray<int32_t,4>;
47#endif
48
49 SIMDPP_INL int32<4>() = default;
50 SIMDPP_INL int32<4>(const int32<4> &) = default;
51 SIMDPP_INL int32<4> &operator=(const int32<4> &) = default;
52
53 template<class E> SIMDPP_INL int32<4>(const int32<4,E>& d) { *this = d.eval(); }
54 template<class E> SIMDPP_INL int32<4>(const uint32<4,E>& d) { *this = d.eval(); }
55 template<class V> SIMDPP_INL explicit int32<4>(const any_vec<16,V>& d)
56 {
57 *this = bit_cast<int32<4>>(d.wrapped().eval());
58 }
59 template<class V> SIMDPP_INL int32<4>& operator=(const any_vec<16,V>& d)
60 {
61 *this = bit_cast<int32<4>>(d.wrapped().eval()); return *this;
62 }
63
64 /// Construct from the underlying vector type
65 SIMDPP_INL int32<4>(const native_type& d) : d_(d) {}
66 SIMDPP_INL int32<4>& operator=(const native_type& d) { d_ = d; return *this; }
67
68 /// Convert to the underlying vector type
69#if !SIMDPP_DISABLE_DEPRECATED_CONVERSION_OPERATOR_TO_NATIVE_TYPES
70 SIMDPP_INL operator native_type() const SIMDPP_IMPLICIT_CONVERSION_DEPRECATION_MSG
71 { return d_; }
72#endif
73 SIMDPP_INL native_type native() const { return d_; }
74
75 template<class E> SIMDPP_INL int32<4>(const expr_vec_construct<E>& e)
76 {
77 detail::construct_eval_wrapper(*this, e.expr());
78 }
79 template<class E> SIMDPP_INL int32<4>& operator=(const expr_vec_construct<E>& e)
80 {
81 detail::construct_eval_wrapper(*this, e.expr()); return *this;
82 }
83
84 /// Access base vectors
85 SIMDPP_INL const int32<4>& vec(unsigned) const { return *this; }
86 SIMDPP_INL int32<4>& vec(unsigned) { return *this; }
87
88 SIMDPP_INL int32<4> eval() const { return *this; }
89
90#if SIMDPP_USE_NULL
91 /// For internal use only
92 SIMDPP_INL const int32_t& el(unsigned i) const { return d_[i]; }
93 SIMDPP_INL int32_t& el(unsigned i) { return d_[i]; }
94#endif
95
96private:
97 native_type d_;
98};
99
100/** Class representing 4x 32-bit unsigned integer vector
101*/
102template<>
103class uint32<4, void> : public any_int32<4, uint32<4,void>> {
104public:
105 static const unsigned type_tag = SIMDPP_TAG_UINT;
106 using element_type = uint32_t;
107 using base_vector_type = uint32<4,void>;
108 using expr_type = void;
109
110#if SIMDPP_USE_SSE2
111 using native_type = __m128i;
112#elif SIMDPP_USE_NEON
113 using native_type = uint32x4_t;
114#elif SIMDPP_USE_ALTIVEC
115 using native_type = __vector uint32_t;
116#elif SIMDPP_USE_MSA
117 using native_type = v4u32;
118#else
119 using native_type = detail::vararray<uint32_t,4>;
120#endif
121
122 SIMDPP_INL uint32<4>() = default;
123 SIMDPP_INL uint32<4>(const uint32<4> &) = default;
124 SIMDPP_INL uint32<4> &operator=(const uint32<4> &) = default;
125
126 template<class E> SIMDPP_INL uint32<4>(const uint32<4,E>& d) { *this = d.eval(); }
127 template<class E> SIMDPP_INL uint32<4>(const int32<4,E>& d) { *this = d.eval(); }
128 template<class V> SIMDPP_INL explicit uint32<4>(const any_vec<16,V>& d)
129 {
130 *this = bit_cast<uint32<4>>(d.wrapped().eval());
131 }
132 template<class V> SIMDPP_INL uint32<4>& operator=(const any_vec<16,V>& d)
133 {
134 *this = bit_cast<uint32<4>>(d.wrapped().eval()); return *this;
135 }
136
137 /// Construct from the underlying vector type
138 SIMDPP_INL uint32<4>(const native_type& d) : d_(d) {}
139 SIMDPP_INL uint32<4>& operator=(const native_type& d) { d_ = d; return *this; }
140
141 /// Convert to the underlying vector type
142#if !SIMDPP_DISABLE_DEPRECATED_CONVERSION_OPERATOR_TO_NATIVE_TYPES
143 SIMDPP_INL operator native_type() const SIMDPP_IMPLICIT_CONVERSION_DEPRECATION_MSG
144 { return d_; }
145#endif
146 SIMDPP_INL native_type native() const { return d_; }
147
148 template<class E> SIMDPP_INL uint32<4>(const expr_vec_construct<E>& e)
149 {
150 detail::construct_eval_wrapper(*this, e.expr());
151 }
152 template<class E> SIMDPP_INL uint32<4>& operator=(const expr_vec_construct<E>& e)
153 {
154 detail::construct_eval_wrapper(*this, e.expr()); return *this;
155 }
156
157 /// Access base vectors
158 SIMDPP_INL const uint32<4>& vec(unsigned) const { return *this; }
159 SIMDPP_INL uint32<4>& vec(unsigned) { return *this; }
160
161 SIMDPP_INL uint32<4> eval() const { return *this; }
162
163#if SIMDPP_USE_NULL
164 /// For uinternal use only
165 SIMDPP_INL const uint32_t& el(unsigned i) const { return d_[i]; }
166 SIMDPP_INL uint32_t& el(unsigned i) { return d_[i]; }
167#endif
168
169private:
170 native_type d_;
171};
172
173/// Class representing possibly optimized mask data for 4x 32-bit integer
174/// vector
175template<>
176class mask_int32<4, void> : public any_int32<4, mask_int32<4,void>> {
177public:
178 static const unsigned type_tag = SIMDPP_TAG_MASK_INT;
179 using base_vector_type = mask_int32<4,void>;
180 using expr_type = void;
181
182#if SIMDPP_USE_AVX512VL
183 using native_type = __mmask8;
184#elif SIMDPP_USE_SSE2
185 using native_type = __m128i;
186#elif SIMDPP_USE_NEON
187 using native_type = uint32x4_t;
188#elif SIMDPP_USE_ALTIVEC
189 using native_type = __vector uint32_t;
190#elif SIMDPP_USE_MSA
191 using native_type = v4u32;
192#else
193 using native_type = detail::vararray<uint8_t,4>;
194#endif
195
196 SIMDPP_INL mask_int32<4>() = default;
197 SIMDPP_INL mask_int32<4>(const mask_int32<4> &) = default;
198 SIMDPP_INL mask_int32<4> &operator=(const mask_int32<4> &) = default;
199
200 SIMDPP_INL mask_int32<4>(const native_type& d) : d_(d) {}
201
202#if SIMDPP_USE_ALTIVEC
203 SIMDPP_INL mask_int32<4>(const __vector __bool int& d) : d_((__vector uint32_t)d) {}
204#endif
205
206#if (SIMDPP_USE_SSE2 && !SIMDPP_USE_AVX512VL) || SIMDPP_USE_NEON || SIMDPP_USE_ALTIVEC
207 SIMDPP_INL mask_int32<4>(const uint32<4>& d) : d_(d.native()) {}
208#endif
209
210 template<class E> SIMDPP_INL explicit mask_int32<4>(const mask_float32<4,E>& d)
211 {
212 *this = bit_cast<mask_int32<4>>(d.eval());
213 }
214 template<class E> SIMDPP_INL mask_int32<4>& operator=(const mask_float32<4,E>& d)
215 {
216 *this = bit_cast<mask_int32<4>>(d.eval()); return *this;
217 }
218
219 /// Convert to the underlying vector type
220#if !SIMDPP_DISABLE_DEPRECATED_CONVERSION_OPERATOR_TO_NATIVE_TYPES
221 SIMDPP_INL operator native_type() const SIMDPP_IMPLICIT_CONVERSION_DEPRECATION_MSG
222 { return d_; }
223#endif
224 SIMDPP_INL native_type native() const { return d_; }
225
226 /// Access the underlying type
227 SIMDPP_INL uint32<4> unmask() const
228 {
229#if SIMDPP_USE_NULL
230 return detail::null::unmask_mask<uint32<4>>(*this);
231#elif SIMDPP_USE_AVX512VL
232 return _mm_movm_epi32(d_);
233#else
234 return uint32<4>(d_);
235#endif
236 }
237
238#if SIMDPP_USE_NULL
239 SIMDPP_INL uint8_t& el(unsigned id) { return d_[id]; }
240 SIMDPP_INL const uint8_t& el(unsigned id) const { return d_[id]; }
241#endif
242
243 SIMDPP_INL const mask_int32<4>& vec(unsigned) const { return *this; }
244 SIMDPP_INL mask_int32<4>& vec(unsigned) { return *this; }
245
246 SIMDPP_INL mask_int32<4> eval() const { return *this; }
247
248private:
249 native_type d_;
250};
251
252} // namespace SIMDPP_ARCH_NAMESPACE
253} // namespace simdpp
254
255#endif
256