Argon 0.1.0
Loading...
Searching...
No Matches
duplicate_lane.hpp
1#pragma once
2#include <utility>
3#include "argon/features.h"
4#include "arm_simd.hpp"
5#include "concepts.hpp"
6#include "scalar.hpp"
7#include "vec64.hpp"
8
9#ifdef __ARM_FEATURE_MVE
10#define simd mve
11#else
12#define simd neon
13#endif
14
15#ifdef ARGON_PLATFORM_SIMDE
16#define nce
17#elifdef __clang__
18#define nce [[gnu::always_inline]] constexpr
19#else
20#define nce [[gnu::always_inline]] inline
21#endif
22
23namespace simd {
24#ifndef ARGON_PLATFORM_MVE
25template <typename VectorType>
26nce VectorType duplicate_lane(Vec64_t<Scalar_t<VectorType>> vec, const int i) {
27 constexpr int lanes = sizeof(VectorType) / sizeof(Scalar_t<VectorType>);
28 constexpr bool is_quadword = is_quadword_v<VectorType>;
29 if constexpr (is_quadword) {
30 if constexpr (lanes == 2) {
31 switch (i) {
32 case 0:
33 return simd::duplicate_lane_quad<0>(vec);
34 case 1:
35 return simd::duplicate_lane_quad<1>(vec);
36 default:
37 std::unreachable();
38 }
39 } else if constexpr (lanes == 4) {
40 switch (i) {
41 case 0:
42 return simd::duplicate_lane_quad<0>(vec);
43 case 1:
44 return simd::duplicate_lane_quad<1>(vec);
45 case 2:
46 return simd::duplicate_lane_quad<2>(vec);
47 case 3:
48 return simd::duplicate_lane_quad<3>(vec);
49 default:
50 std::unreachable();
51 }
52 } else if constexpr (lanes == 8) {
53 switch (i) {
54 case 0:
55 return simd::duplicate_lane_quad<0>(vec);
56 case 1:
57 return simd::duplicate_lane_quad<1>(vec);
58 case 2:
59 return simd::duplicate_lane_quad<2>(vec);
60 case 3:
61 return simd::duplicate_lane_quad<3>(vec);
62 case 4:
63 return simd::duplicate_lane_quad<4>(vec);
64 case 5:
65 return simd::duplicate_lane_quad<5>(vec);
66 case 6:
67 return simd::duplicate_lane_quad<6>(vec);
68 case 7:
69 return simd::duplicate_lane_quad<7>(vec);
70 default:
71 std::unreachable();
72 }
73 } else {
74 std::unreachable();
75 }
76
77 } else {
78 if constexpr (lanes == 2) {
79 switch (i) {
80 case 0:
81 return simd::duplicate_lane<0>(vec);
82 case 1:
83 return simd::duplicate_lane<1>(vec);
84 default:
85 std::unreachable();
86 }
87 } else if constexpr (lanes == 4) {
88 switch (i) {
89 case 0:
90 return simd::duplicate_lane<0>(vec);
91 case 1:
92 return simd::duplicate_lane<1>(vec);
93 case 2:
94 return simd::duplicate_lane<2>(vec);
95 case 3:
96 return simd::duplicate_lane<3>(vec);
97 default:
98 std::unreachable();
99 }
100 } else if constexpr (lanes == 8) {
101 switch (i) {
102 case 0:
103 return simd::duplicate_lane<0>(vec);
104 case 1:
105 return simd::duplicate_lane<1>(vec);
106 case 2:
107 return simd::duplicate_lane<2>(vec);
108 case 3:
109 return simd::duplicate_lane<3>(vec);
110 case 4:
111 return simd::duplicate_lane<4>(vec);
112 case 5:
113 return simd::duplicate_lane<5>(vec);
114 case 6:
115 return simd::duplicate_lane<6>(vec);
116 case 7:
117 return simd::duplicate_lane<7>(vec);
118 default:
119 std::unreachable();
120 }
121 } else {
122 std::unreachable();
123 }
124 }
125}
126#endif
127} // namespace simd
128#undef simd
129#undef nce
Concept to check if a type is a quad-word SIMD vector type.
Definition concepts.hpp:57
Header file for SIMD features and platform detection.