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_MAKE_UINT_H
9#define LIBSIMDPP_SIMDPP_CORE_MAKE_UINT_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/make_const.h>
17
18namespace simdpp {
19namespace SIMDPP_ARCH_NAMESPACE {
20
21/** Creates a vector from unsigned integer values known at compile-time.
22 The result of this function may be assigned or converted to a vector of any
23 type: standard conversions are used to convert the arguments. All
24 conversions and other overhead is performed at compile-time thus even if the
25 minimal optimization level is selected, the function results in a simple
26 load from memory.
27
28 The function is not guaranteed to have adequate performance if the
29 arguments are not known at compile-time.
30
31 If the vector has fewer elements than the number of the parameters this
32 function accepts then the extra values are discarded.
33
34 Note that per C++ rules negative values are sign-extended to fill entire
35 element before being converted to unsigned type thus e.g. it's safe to use
36 -1 to fill element with ones.
37
38 @par 1 parameter version
39 @code
40 | 0 1 2 3 ... n |
41 r = [ v0 v0 v0 v0 ... v0 ]
42 @endcode
43
44 @par 2 parameters version
45 @code
46 | 0 1 2 3 ... n |
47 r = [ v0 v1 v0 v1 ... v1 ]
48 @endcode
49
50 @par 4 parameters version
51 @code
52 | 0 1 2 3 ... n |
53 r = [ v0 v1 v2 v3 ... v3 ]
54 @endcode
55
56 @par 8 parameters version
57 @code
58 | 0 1 .. 7 8 ... n |
59 r = [ v0 v1 .. v7 v0 ... v7 ]
60 @endcode
61*/
62// FIXME: return empty expr
63SIMDPP_INL expr_vec_make_const<uint64_t,1> make_uint(uint64_t v0)
64{
65 expr_vec_make_const<uint64_t,1> a;
66 a.a[0] = v0;
67 return a;
68}
69
70static SIMDPP_INL
71expr_vec_make_const<uint64_t,2> make_uint(uint64_t v0, uint64_t v1)
72{
73 expr_vec_make_const<uint64_t,2> a;
74 a.a[0] = v0; a.a[1] = v1;
75 return a;
76}
77
78static SIMDPP_INL
79expr_vec_make_const<uint64_t,4>
80 make_uint(uint64_t v0, uint64_t v1, uint64_t v2, uint64_t v3)
81{
82 expr_vec_make_const<uint64_t,4> a;
83 a.a[0] = v0; a.a[1] = v1; a.a[2] = v2; a.a[3] = v3;
84 return a;
85}
86
87static SIMDPP_INL
88expr_vec_make_const<uint64_t,8>
89 make_uint(uint64_t v0, uint64_t v1, uint64_t v2, uint64_t v3,
90 uint64_t v4, uint64_t v5, uint64_t v6, uint64_t v7)
91{
92 expr_vec_make_const<uint64_t,8> a;
93 a.a[0] = v0; a.a[1] = v1; a.a[2] = v2; a.a[3] = v3;
94 a.a[4] = v4; a.a[5] = v5; a.a[6] = v6; a.a[7] = v7;
95 return a;
96}
97
98static SIMDPP_INL
99expr_vec_make_const<uint64_t,16>
100 make_uint(uint64_t v0, uint64_t v1, uint64_t v2, uint64_t v3,
101 uint64_t v4, uint64_t v5, uint64_t v6, uint64_t v7,
102 uint64_t v8, uint64_t v9, uint64_t v10, uint64_t v11,
103 uint64_t v12, uint64_t v13, uint64_t v14, uint64_t v15)
104{
105 expr_vec_make_const<uint64_t,16> a;
106 a.a[0] = v0; a.a[1] = v1; a.a[2] = v2; a.a[3] = v3;
107 a.a[4] = v4; a.a[5] = v5; a.a[6] = v6; a.a[7] = v7;
108 a.a[8] = v8; a.a[9] = v9; a.a[10] = v10; a.a[11] = v11;
109 a.a[12] = v12; a.a[13] = v13; a.a[14] = v14; a.a[15] = v15;
110 return a;
111}
112
113template<class V> SIMDPP_INL
114V make_uint(uint64_t v0)
115{
116 static_assert(is_vector<V>::value && !is_mask<V>::value,
117 "V must be a non-mask vector");
118 expr_vec_make_const<uint64_t,1> a;
119 a.a[0] = v0;
120 return detail::insn::i_make_const_any<V>(a);
121}
122
123template<class V> SIMDPP_INL
124V make_uint(uint64_t v0, uint64_t v1)
125{
126 static_assert(is_vector<V>::value && !is_mask<V>::value,
127 "V must be a non-mask vector");
128 expr_vec_make_const<uint64_t,2> a;
129 a.a[0] = v0; a.a[1] = v1;
130 return detail::insn::i_make_const_any<V>(a);
131}
132
133template<class V> SIMDPP_INL
134V make_uint(uint64_t v0, uint64_t v1, uint64_t v2, uint64_t v3)
135{
136 static_assert(is_vector<V>::value && !is_mask<V>::value,
137 "V must be a non-mask vector");
138 expr_vec_make_const<uint64_t,4> a;
139 a.a[0] = v0; a.a[1] = v1; a.a[2] = v2; a.a[3] = v3;
140 return detail::insn::i_make_const_any<V>(a);
141}
142
143template<class V> SIMDPP_INL
144V make_uint(uint64_t v0, uint64_t v1, uint64_t v2, uint64_t v3,
145 uint64_t v4, uint64_t v5, uint64_t v6, uint64_t v7)
146{
147 static_assert(is_vector<V>::value && !is_mask<V>::value,
148 "V must be a non-mask vector");
149 expr_vec_make_const<uint64_t,8> a;
150 a.a[0] = v0; a.a[1] = v1; a.a[2] = v2; a.a[3] = v3;
151 a.a[4] = v4; a.a[5] = v5; a.a[6] = v6; a.a[7] = v7;
152 return detail::insn::i_make_const_any<V>(a);
153}
154
155template<class V> SIMDPP_INL
156V make_uint(uint64_t v0, uint64_t v1, uint64_t v2, uint64_t v3,
157 uint64_t v4, uint64_t v5, uint64_t v6, uint64_t v7,
158 uint64_t v8, uint64_t v9, uint64_t v10, uint64_t v11,
159 uint64_t v12, uint64_t v13, uint64_t v14, uint64_t v15)
160{
161 static_assert(is_vector<V>::value && !is_mask<V>::value,
162 "V must be a non-mask vector");
163 expr_vec_make_const<uint64_t,16> a;
164 a.a[0] = v0; a.a[1] = v1; a.a[2] = v2; a.a[3] = v3;
165 a.a[4] = v4; a.a[5] = v5; a.a[6] = v6; a.a[7] = v7;
166 a.a[8] = v8; a.a[9] = v9; a.a[10] = v10; a.a[11] = v11;
167 a.a[12] = v12; a.a[13] = v13; a.a[14] = v14; a.a[15] = v15;
168 return detail::insn::i_make_const_any<V>(a);
169}
170
171/// Creates a vector initialized to zero
172SIMDPP_INL expr_vec_make_const<uint64_t,1> make_zero()
173{
174 return make_uint(0);
175}
176
177template<class V> SIMDPP_INL
178V make_zero()
179{
180 return make_uint<V>(0);
181}
182
183/// Creates a vector initialized to ones
184SIMDPP_INL expr_vec_make_ones make_ones()
185{
186 return expr_vec_make_ones();
187}
188
189template<class V> SIMDPP_INL
190V make_ones()
191{
192 return (V) make_ones();
193}
194
195} // namespace SIMDPP_ARCH_NAMESPACE
196} // namespace simdpp
197
198#endif
199
200