VCTR
Loading...
Searching...
No Matches
NeonRegister.h
1/*
2 ==============================================================================
3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5 Copyright 2022- by sonible GmbH.
6
7 This file is part of VCTR - Versatile Container Templates Reconceptualized.
8
9 VCTR is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License version 3
11 only, as published by the Free Software Foundation.
12
13 VCTR is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License version 3 for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 version 3 along with VCTR. If not, see <https://www.gnu.org/licenses/>.
20 ==============================================================================
21*/
22
23namespace vctr
24{
25
26template <class T>
28{
29 static NeonRegister broadcast (const T&) { return {}; }
30};
31
32#if VCTR_ARM
33
34template <>
35struct NeonRegister<float>
36{
37 static constexpr size_t numElements = 4;
38
39 using NativeType = float32x4_t;
40 float32x4_t value;
41
42 //==============================================================================
43 // Loading
44 // clang-format off
45 static NeonRegister load (const float* d) { return { vld1q_f32 (d) }; }
46 static NeonRegister broadcast (float x) { return { vdupq_n_f32 (x) }; }
47
48 //==============================================================================
49 // Storing
50 void store (float* d) const { vst1q_f32 (d, value); }
51
52 //==============================================================================
53 // Bit Operations
54 static NeonRegister andNot (NeonRegister a, NeonRegister b) { return { vreinterpretq_f32_u32 (vandq_u32 (vreinterpretq_u32_f32 (a.value), vreinterpretq_u32_f32 (b.value))) }; }
55
56 //==============================================================================
57 // Math
58 static NeonRegister abs (NeonRegister x) { return { vabsq_f32 (x.value) }; }
59 static NeonRegister mul (NeonRegister a, NeonRegister b) { return { vmulq_f32 (a.value, b.value) }; }
60 static NeonRegister add (NeonRegister a, NeonRegister b) { return { vaddq_f32 (a.value, b.value) }; }
61 static NeonRegister sub (NeonRegister a, NeonRegister b) { return { vsubq_f32 (a.value, b.value) }; }
62 static NeonRegister max (NeonRegister a, NeonRegister b) { return { vmaxq_f32 (a.value, b.value) }; }
63 static NeonRegister min (NeonRegister a, NeonRegister b) { return { vminq_f32 (a.value, b.value) }; }
64 // clang-format on
65};
66
67template <>
68struct NeonRegister<double>
69{
70 static constexpr size_t numElements = 2;
71
72 using NativeType = float64x2_t;
73 float64x2_t value;
74
75 //==============================================================================
76 // Loading
77 // clang-format off
78 static NeonRegister load (const double* d) { return { vld1q_f64 (d) }; }
79 static NeonRegister broadcast (double x) { return { vdupq_n_f64 (x) }; }
80
81 //==============================================================================
82 // Storing
83 void store (double* d) const { vst1q_f64 (d, value); }
84
85 //==============================================================================
86 // Bit Operations
87 static NeonRegister andNot (NeonRegister a, NeonRegister b) { return { vreinterpretq_f64_u64 (vandq_u64 (vreinterpretq_u64_f64 (a.value), vreinterpretq_u64_f64 (b.value))) }; }
88
89 //==============================================================================
90 // Math
91 static NeonRegister abs (NeonRegister x) { return { vabsq_f64 (x.value) }; }
92 static NeonRegister mul (NeonRegister a, NeonRegister b) { return { vmulq_f64 (a.value, b.value) }; }
93 static NeonRegister add (NeonRegister a, NeonRegister b) { return { vaddq_f64 (a.value, b.value) }; }
94 static NeonRegister sub (NeonRegister a, NeonRegister b) { return { vsubq_f64 (a.value, b.value) }; }
95 static NeonRegister max (NeonRegister a, NeonRegister b) { return { vmaxq_f64 (a.value, b.value) }; }
96 static NeonRegister min (NeonRegister a, NeonRegister b) { return { vminq_f64 (a.value, b.value) }; }
97 // clang-format on
98};
99
100template <>
101struct NeonRegister<int32_t>
102{
103 static constexpr size_t numElements = 4;
104
105 using NativeType = int32x4_t;
106 int32x4_t value;
107
108 //==============================================================================
109 // Loading
110 // clang-format off
111 static NeonRegister load (const int32_t* d) { return { vld1q_s32 (d) }; }
112 static NeonRegister broadcast (int32_t x) { return { vdupq_n_s32 (x) }; }
113
114 //==============================================================================
115 // Storing
116 void store (int32_t* d) const { vst1q_s32 (d, value); }
117
118 //==============================================================================
119 // Bit Operations
120
121 //==============================================================================
122 // Math
123 static NeonRegister abs (NeonRegister x) { return { vabsq_s32 (x.value) }; }
124 static NeonRegister mul (NeonRegister a, NeonRegister b) { return { vmulq_s32 (a.value, b.value) }; }
125 static NeonRegister add (NeonRegister a, NeonRegister b) { return { vaddq_s32 (a.value, b.value) }; }
126 static NeonRegister sub (NeonRegister a, NeonRegister b) { return { vsubq_s32 (a.value, b.value) }; }
127 static NeonRegister max (NeonRegister a, NeonRegister b) { return { vmaxq_s32 (a.value, b.value) }; }
128 static NeonRegister min (NeonRegister a, NeonRegister b) { return { vminq_s32 (a.value, b.value) }; }
129 // clang-format on
130};
131
132template <>
133struct NeonRegister<uint32_t>
134{
135 static constexpr size_t numElements = 4;
136
137 using NativeType = uint32x4_t;
138 uint32x4_t value;
139
140 //==============================================================================
141 // Loading
142 // clang-format off
143 static NeonRegister load (const uint32_t* d) { return { vld1q_u32 (d) }; }
144 static NeonRegister broadcast (uint32_t x) { return { vdupq_n_u32 (x) }; }
145
146 //==============================================================================
147 // Storing
148 void store (uint32_t* d) const { vst1q_u32 (d, value); }
149
150 //==============================================================================
151 // Bit Operations
152
153 //==============================================================================
154 // Math
155 static NeonRegister mul (NeonRegister a, NeonRegister b) { return { vmulq_u32 (a.value, b.value) }; }
156 static NeonRegister add (NeonRegister a, NeonRegister b) { return { vaddq_u32 (a.value, b.value) }; }
157 static NeonRegister sub (NeonRegister a, NeonRegister b) { return { vsubq_u32 (a.value, b.value) }; }
158 static NeonRegister max (NeonRegister a, NeonRegister b) { return { vmaxq_u32 (a.value, b.value) }; }
159 static NeonRegister min (NeonRegister a, NeonRegister b) { return { vminq_u32 (a.value, b.value) }; }
160 // clang-format on
161};
162
163template <>
164struct NeonRegister<int64_t>
165{
166 static constexpr size_t numElements = 2;
167
168 using NativeType = int64x2_t;
169 int64x2_t value;
170
171 //==============================================================================
172 // Loading
173 // clang-format off
174 static NeonRegister load (const int64_t* d) { return { vld1q_s64 (d) }; }
175 static NeonRegister broadcast (int64_t x) { return { vdupq_n_s64 (x) }; }
176
177 //==============================================================================
178 // Storing
179 void store (int64_t* d) const { vst1q_s64 (d, value); }
180
181 //==============================================================================
182 // Bit Operations
183
184 //==============================================================================
185 // Math
186 static NeonRegister abs (NeonRegister x) { return { vabsq_s64 (x.value) }; }
187 static NeonRegister add (NeonRegister a, NeonRegister b) { return { vaddq_s64 (a.value, b.value) }; }
188 static NeonRegister sub (NeonRegister a, NeonRegister b) { return { vsubq_s64 (a.value, b.value) }; }
189 // clang-format on
190};
191
192template <>
193struct NeonRegister<uint64_t>
194{
195 static constexpr size_t numElements = 2;
196
197 using NativeType = uint64x2_t;
198 uint64x2_t value;
199
200 //==============================================================================
201 // Loading
202 // clang-format off
203 static NeonRegister load (const uint64_t* d) { return { vld1q_u64 (d) }; }
204 static NeonRegister broadcast (uint64_t x) { return { vdupq_n_u64 (x) }; }
205
206 //==============================================================================
207 // Storing
208 void store (uint64_t* d) const { vst1q_u64 (d, value); }
209
210 //==============================================================================
211 // Bit Operations
212
213 //==============================================================================
214 // Math
215 static NeonRegister add (NeonRegister a, NeonRegister b) { return { vaddq_u64 (a.value, b.value) }; }
216 static NeonRegister sub (NeonRegister a, NeonRegister b) { return { vsubq_u64 (a.value, b.value) }; }
217 // clang-format on
218};
219
220#endif
221
222} // namespace vctr
constexpr ExpressionChainBuilder< expressions::Max > max
Computes the maximum value of the source values.
Definition: Max.h:194
constexpr ExpressionChainBuilder< expressions::Abs > abs
Computes the absolute value of the source values.
Definition: Abs.h:133
constexpr ExpressionChainBuilder< expressions::Min > min
Computes the minimum value of the source values.
Definition: Min.h:194
The main namespace of the VCTR project.
Definition: Array.h:24
Definition: NeonRegister.h:28