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