Argon 0.1.0
Loading...
Searching...
No Matches
lane.hpp
1#pragma once
2#include "arm_simd.hpp"
3#include "arm_simd/helpers/scalar.hpp"
4#include "arm_simd/helpers/vec64.hpp"
5#include "features.h"
6#include "helpers/argon_for.hpp"
7
8#ifdef __ARM_FEATURE_MVE
9#define simd mve
10#else
11#define simd neon
12#endif
13
14#ifdef ARGON_PLATFORM_SIMDE
15#define ace
16#elifdef __clang__
17#define ace [[gnu::always_inline]] constexpr
18#else
19#define ace [[gnu::always_inline]] inline
20#endif
21
22namespace argon {
23template <typename T>
24class Vector;
25
26#ifdef ARGON_PLATFORM_MVE
27
28// MVE does not support lane manipulators, so we use the scalar type directly
29// for the lane type.
30
31template <size_t, typename VectorType>
32using ConstLane = simd::Scalar_t<VectorType>;
33
34template <typename VectorType>
35using Lane = simd::Scalar_t<VectorType>;
36
37#else
38
45template <size_t LaneIndex, typename VectorType>
46class ConstLane {
47 using scalar_type = simd::Scalar_t<VectorType>;
49 using argon_type = helpers::ArgonFor_t<VectorType>;
50
51 public:
53 ace ConstLane(VectorType& vec) : vec_{vec} {}
55 ace operator scalar_type() const { return Get(); }
57 ace argon_type operator=(const scalar_type b) { return vec_ = Set(b); }
59 ace argon_type Load(const scalar_type* ptr) {
60#ifdef ARGON_PLATFORM_MVE
61 Set(*ptr);
62#else
63 if constexpr (simd::is_quadword_v<VectorType>) {
64 return simd::load1_lane_quad<LaneIndex>(ptr, vec_);
65 } else {
66 return simd::load1_lane<LaneIndex>(ptr, vec_);
67 }
68#endif
69 }
70
71 ace argon_type Set(const scalar_type b) { return simd::set_lane<LaneIndex>(b, vec_); }
73 ace scalar_type Get() const { return simd::get_lane<LaneIndex>(vec_); }
74
75#if __ARM_ARCH >= 8
77 ace VectorType vec() { return vec_; }
79 ace const int lane() { return LaneIndex; }
80#else
82 ace neon::Vec64_t<scalar_type> vec() {
83 if constexpr (simd::is_doubleword_v<VectorType>) {
84 return vec_;
85 } else if constexpr (simd::is_quadword_v<VectorType>) {
86 if constexpr (LaneIndex >= ArgonHalf<scalar_type>::lanes) {
87 return simd::get_high(vec_);
88 } else {
89 return simd::get_low(vec_);
90 }
91 }
92 }
93
94 ace int lane() {
95 if constexpr (simd::is_doubleword_v<VectorType>) {
96 return LaneIndex;
97 } else if constexpr (simd::is_quadword_v<VectorType>) {
98 if (LaneIndex >= ArgonHalf<scalar_type>::lanes) {
99 return (LaneIndex - ArgonHalf<scalar_type>::lanes);
100 } else {
101 return LaneIndex;
102 }
103 }
104 }
105#endif
106 private:
107 VectorType& vec_;
108};
109
115template <typename VectorType>
116class Lane {
117 using scalar_type = simd::Scalar_t<VectorType>;
118 using type = Lane<VectorType>;
119 using argon_type = helpers::ArgonFor_t<VectorType>;
120
121 public:
123 ace Lane(VectorType& vec, const int lane) : vec_{vec}, lane_{lane} {}
125 ace argon_type operator=(const scalar_type b) { return vec_ = Set(b); }
127 [[nodiscard]] ace argon_type Load(const scalar_type* ptr) {
128#ifdef ARGON_PLATFORM_MVE
129 return Set(*ptr);
130#else
131 return simd::load1_lane(vec_, lane_, ptr);
132#endif
133 }
134
135 ace argon_type Set(const scalar_type b) { return simd::set_lane(vec_, lane_, b); }
137 ace scalar_type Get() const { return simd::get_lane(vec_, lane_); }
139 ace operator scalar_type() const { return Get(); }
140
141#if __ARM_ARCH >= 8
143 ace VectorType vec() { return vec_; }
145 ace const int lane() { return lane_; }
146#else
148 ace neon::Vec64_t<scalar_type> vec() {
149 if constexpr (simd::is_doubleword_v<VectorType>) {
150 return vec_;
151 } else if constexpr (simd::is_quadword_v<VectorType>) {
152 if (lane_ >= ArgonHalf<scalar_type>::lanes) {
153 return simd::get_high(vec_);
154 } else {
155 return simd::get_low(vec_);
156 }
157 }
158 }
159
160 ace int lane() {
161 if constexpr (simd::is_doubleword_v<VectorType>) {
162 return lane_;
163 } else if constexpr (simd::is_quadword_v<VectorType>) {
164 if (lane_ >= ArgonHalf<scalar_type>::lanes) {
165 return (lane_ - ArgonHalf<scalar_type>::lanes);
166 } else {
167 return lane_;
168 }
169 }
170 }
171#endif
172
173 private:
174 VectorType& vec_;
175 int lane_;
176
177 // friend class Vector<VectorType>;
178};
179#endif
180} // namespace argon
Definition argon_half.hpp:11
Represents a single lane of a SIMD vector with the lane index known at compile time.
Definition lane.hpp:46
ace int lane()
On ARM32, return the local lane index within the 64-bit half-register returned by vec().
Definition lane.hpp:94
ace argon_type Set(const scalar_type b)
Set this lane to b and return the updated vector.
Definition lane.hpp:71
ace argon_type operator=(const scalar_type b)
Write a scalar value into this lane and return the updated vector.
Definition lane.hpp:57
ace neon::Vec64_t< scalar_type > vec()
On ARM32, return the 64-bit half-register that contains this lane.
Definition lane.hpp:82
ace ConstLane(VectorType &vec)
Construct a lane accessor bound to vec.
Definition lane.hpp:53
ace scalar_type Get() const
Get the scalar value of this lane.
Definition lane.hpp:73
ace argon_type Load(const scalar_type *ptr)
Load a scalar from ptr into this lane.
Definition lane.hpp:59
Represents a single lane of a SIMD vector with a runtime-determined index.
Definition lane.hpp:116
ace argon_type Set(const scalar_type b)
Set this lane to b and return the updated vector.
Definition lane.hpp:135
ace argon_type Load(const scalar_type *ptr)
Load a scalar from ptr into this lane and return the updated vector.
Definition lane.hpp:127
ace int lane()
Definition lane.hpp:160
ace Lane(VectorType &vec, const int lane)
Construct a lane accessor bound to vec at runtime index lane.
Definition lane.hpp:123
ace neon::Vec64_t< scalar_type > vec()
Definition lane.hpp:148
ace scalar_type Get() const
Get the scalar value of this lane.
Definition lane.hpp:137
ace argon_type operator=(const scalar_type b)
Write a scalar value into this lane and return the updated vector.
Definition lane.hpp:125
Represents a SIMD vector with various operations.
Definition vector.hpp:50
Header file for SIMD features and platform detection.
typename ArgonFor< std::remove_cv_t< T > >::type ArgonFor_t
Helper alias to get the Argon type for a given vector type.
Definition argon_for.hpp:45