7#ifdef __ARM_FEATURE_MVE
13#ifdef ARGON_PLATFORM_SIMDE
16#define nce [[gnu::always_inline]] constexpr
18#define nce [[gnu::always_inline]] inline
21#define make_lane_helper_dword_1arg(lane_func) \
22 template <is_vector_type T, is_doubleword U> \
23 requires std::is_same_v<Scalar_t<T>, Scalar_t<U>> \
24 nce T lane_func(T a, U vec, const int lane) { \
25 constexpr int lanes = sizeof(U) / sizeof(Scalar_t<U>); \
26 if constexpr (lanes == 2) { \
29 return lane_func<0>(a, vec); \
31 return lane_func<1>(a, vec); \
35 } else if constexpr (lanes == 4) { \
38 return lane_func<0>(a, vec); \
40 return lane_func<1>(a, vec); \
42 return lane_func<2>(a, vec); \
44 return lane_func<3>(a, vec); \
48 } else if constexpr (lanes == 8) { \
51 return lane_func<0>(a, vec); \
53 return lane_func<1>(a, vec); \
55 return lane_func<2>(a, vec); \
57 return lane_func<3>(a, vec); \
59 return lane_func<4>(a, vec); \
61 return lane_func<5>(a, vec); \
63 return lane_func<6>(a, vec); \
65 return lane_func<7>(a, vec); \
72#define make_lane_helper_dword_2arg(lane_func) \
73 template <is_vector_type T, is_doubleword U> \
74 requires std::is_same_v<Scalar_t<T>, Scalar_t<U>> \
75 nce T lane_func(T a, T b, U vec, const int lane) { \
76 constexpr int lanes = sizeof(U) / sizeof(Scalar_t<U>); \
77 if constexpr (lanes == 2) { \
80 return lane_func<0>(a, b, vec); \
82 return lane_func<1>(a, b, vec); \
86 } else if constexpr (lanes == 4) { \
89 return lane_func<0>(a, b, vec); \
91 return lane_func<1>(a, b, vec); \
93 return lane_func<2>(a, b, vec); \
95 return lane_func<3>(a, b, vec); \
99 } else if constexpr (lanes == 8) { \
102 return lane_func<0>(a, b, vec); \
104 return lane_func<1>(a, b, vec); \
106 return lane_func<2>(a, b, vec); \
108 return lane_func<3>(a, b, vec); \
110 return lane_func<4>(a, b, vec); \
112 return lane_func<5>(a, b, vec); \
114 return lane_func<6>(a, b, vec); \
116 return lane_func<7>(a, b, vec); \
118 std::unreachable(); \
123#define make_lane_helper_qword_1arg(lane_func) \
124 template <is_vector_type T, is_vector_type U> \
125 requires std::is_same_v<Scalar_t<T>, Scalar_t<U>> \
126 nce T lane_func(T a, U vec, const int lane) { \
127 constexpr int lanes = sizeof(U) / sizeof(Scalar_t<U>); \
128 if constexpr (lanes == 2) { \
131 return lane_func<0>(a, vec); \
133 return lane_func<1>(a, vec); \
135 std::unreachable(); \
137 } else if constexpr (lanes == 4) { \
140 return lane_func<0>(a, vec); \
142 return lane_func<1>(a, vec); \
144 return lane_func<2>(a, vec); \
146 return lane_func<3>(a, vec); \
148 std::unreachable(); \
150 } else if constexpr (lanes == 8) { \
153 return lane_func<0>(a, vec); \
155 return lane_func<1>(a, vec); \
157 return lane_func<2>(a, vec); \
159 return lane_func<3>(a, vec); \
161 return lane_func<4>(a, vec); \
163 return lane_func<5>(a, vec); \
165 return lane_func<6>(a, vec); \
167 return lane_func<7>(a, vec); \
169 std::unreachable(); \
171 } else if constexpr (lanes == 16) { \
174 return lane_func<0>(a, vec); \
176 return lane_func<1>(a, vec); \
178 return lane_func<2>(a, vec); \
180 return lane_func<3>(a, vec); \
182 return lane_func<4>(a, vec); \
184 return lane_func<5>(a, vec); \
186 return lane_func<6>(a, vec); \
188 return lane_func<7>(a, vec); \
190 return lane_func<8>(a, vec); \
192 return lane_func<9>(a, vec); \
194 return lane_func<10>(a, vec); \
196 return lane_func<11>(a, vec); \
198 return lane_func<12>(a, vec); \
200 return lane_func<13>(a, vec); \
202 return lane_func<14>(a, vec); \
204 return lane_func<15>(a, vec); \
206 std::unreachable(); \
211#define make_lane_helper_qword_2arg(lane_func) \
212 template <is_vector_type T, is_vector_type U> \
213 requires std::is_same_v<Scalar_t<T>, Scalar_t<U>> \
214 nce T lane_func(T a, T b, U vec, const int lane) { \
215 constexpr int lanes = sizeof(U) / sizeof(Scalar_t<U>); \
216 if constexpr (lanes == 2) { \
219 return lane_func<0>(a, b, vec); \
221 return lane_func<1>(a, b, vec); \
223 std::unreachable(); \
225 } else if constexpr (lanes == 4) { \
228 return lane_func<0>(a, b, vec); \
230 return lane_func<1>(a, b, vec); \
232 return lane_func<2>(a, b, vec); \
234 return lane_func<3>(a, b, vec); \
236 std::unreachable(); \
238 } else if constexpr (lanes == 8) { \
241 return lane_func<0>(a, b, vec); \
243 return lane_func<1>(a, b, vec); \
245 return lane_func<2>(a, b, vec); \
247 return lane_func<3>(a, b, vec); \
249 return lane_func<4>(a, b, vec); \
251 return lane_func<5>(a, b, vec); \
253 return lane_func<6>(a, b, vec); \
255 return lane_func<7>(a, b, vec); \
257 std::unreachable(); \
259 } else if constexpr (lanes == 16) { \
262 return lane_func<0>(a, b, vec); \
264 return lane_func<1>(a, b, vec); \
266 return lane_func<2>(a, b, vec); \
268 return lane_func<3>(a, b, vec); \
270 return lane_func<4>(a, b, vec); \
272 return lane_func<5>(a, b, vec); \
274 return lane_func<6>(a, b, vec); \
276 return lane_func<7>(a, b, vec); \
278 return lane_func<8>(a, b, vec); \
280 return lane_func<9>(a, b, vec); \
282 return lane_func<10>(a, b, vec); \
284 return lane_func<11>(a, b, vec); \
286 return lane_func<12>(a, b, vec); \
288 return lane_func<13>(a, b, vec); \
290 return lane_func<14>(a, b, vec); \
292 return lane_func<15>(a, b, vec); \
294 std::unreachable(); \
300#ifndef ARGON_PLATFORM_MVE
301make_lane_helper_dword_1arg(multiply_lane);
302make_lane_helper_dword_1arg(multiply_long_lane);
303make_lane_helper_dword_1arg(multiply_double_saturate_long_lane);
304make_lane_helper_dword_1arg(multiply_double_saturate_high_lane);
305make_lane_helper_dword_1arg(multiply_double_round_saturate_high_lane);
306make_lane_helper_dword_2arg(multiply_add_lane);
307make_lane_helper_dword_2arg(multiply_subtract_lane);
308make_lane_helper_dword_2arg(multiply_add_long_lane);
309make_lane_helper_dword_2arg(multiply_subtract_long_lane);
310make_lane_helper_dword_2arg(multiply_double_add_saturate_long_lane);
311make_lane_helper_dword_2arg(multiply_double_subtract_saturate_long_lane);
315make_lane_helper_qword_1arg(multiply_lane);
316make_lane_helper_qword_1arg(multiply_long_lane);
317make_lane_helper_qword_1arg(multiply_double_saturate_long_lane);
318make_lane_helper_qword_1arg(multiply_double_saturate_high_lane);
319make_lane_helper_qword_1arg(multiply_double_round_saturate_high_lane);
320make_lane_helper_qword_2arg(multiply_add_lane);
321make_lane_helper_qword_2arg(multiply_subtract_lane);
322make_lane_helper_qword_2arg(multiply_add_long_lane);
323make_lane_helper_qword_2arg(multiply_subtract_long_lane);
324make_lane_helper_qword_2arg(multiply_double_add_saturate_long_lane);
325make_lane_helper_qword_2arg(multiply_double_subtract_saturate_long_lane);
331#undef make_lane_helper_dword_1arg
332#undef make_lane_helper_qword_1arg
333#undef make_lane_helper_dword_2arg
334#undef make_lane_helper_qword_2arg
Header file for SIMD features and platform detection.