VCV Rack API v2
Loading...
Searching...
No Matches
functions.hpp
Go to the documentation of this file.
1#pragma once
2#include <simd/Vector.hpp>
4#include <common.hpp>
5#include <math.hpp>
6
7
8namespace rack {
9namespace simd {
10
11
12// Functions based on instructions
13
16 return float_4(_mm_andnot_ps(a.v, b.v));
17}
18
22inline int movemask(float_4 a) {
23 return _mm_movemask_ps(a.v);
24}
25
29inline int movemask(int32_4 a) {
30 return _mm_movemask_ps(_mm_castsi128_ps(a.v));
31}
32
37 return float_4(_mm_rsqrt_ps(x.v));
38}
39
43inline float_4 rcp(float_4 x) {
44 return float_4(_mm_rcp_ps(x.v));
45}
46
47
48// Nonstandard convenience functions
49
50inline float ifelse(bool cond, float a, float b) {
51 return cond ? a : b;
52}
53
55inline float_4 ifelse(float_4 mask, float_4 a, float_4 b) {
56 return (a & mask) | andnot(mask, b);
57}
58
61template <typename T>
63
64template <>
66 // Pick out N'th bit of `a` and check if it's 1.
67 int32_4 mask1234 = int32_4(1, 2, 4, 8);
68 return (mask1234 & int32_4(a)) == mask1234;
69}
70
71template <>
74}
75
76
77// Standard math functions from std::
78
79/* Import std:: math functions into the simd namespace so you can use `sin(T)` etc in templated functions and get both the scalar and vector versions.
80
81Example:
82
83 template <typename T>
84 T sin_plus_cos(T x) {
85 return simd::sin(x) + simd::cos(x);
86 }
87*/
88
89using std::fmax;
90
92 return float_4(_mm_max_ps(x.v, b.v));
93}
94
95using std::fmin;
96
98 return float_4(_mm_min_ps(x.v, b.v));
99}
100
101using std::sqrt;
102
104 return float_4(_mm_sqrt_ps(x.v));
105}
106
107using std::log;
108
109inline float_4 log(float_4 x) {
110 return float_4(sse_mathfun_log_ps(x.v));
111}
112
113using std::log10;
114
116 return float_4(sse_mathfun_log_ps(x.v)) / std::log(10.f);
117}
118
119using std::log2;
120
122 return float_4(sse_mathfun_log_ps(x.v)) / std::log(2.f);
123}
124
125using std::exp;
126
127inline float_4 exp(float_4 x) {
128 return float_4(sse_mathfun_exp_ps(x.v));
129}
130
131using std::sin;
132
133inline float_4 sin(float_4 x) {
134 return float_4(sse_mathfun_sin_ps(x.v));
135}
136
137using std::cos;
138
139inline float_4 cos(float_4 x) {
140 return float_4(sse_mathfun_cos_ps(x.v));
141}
142
143using std::tan;
144
145inline float_4 tan(float_4 x) {
146 return float_4(sse_mathfun_tan_ps(x.v));
147}
148
149using std::atan;
150
152 return float_4(sse_mathfun_atan_ps(x.v));
153}
154
155using std::atan2;
156
158 return float_4(sse_mathfun_atan2_ps(x.v, y.v));
159}
160
161using std::trunc;
162
163// SIMDe defines _MM_FROUND_NO_EXC with a prefix
164#ifndef _MM_FROUND_NO_EXC
165 #define _MM_FROUND_NO_EXC SIMDE_MM_FROUND_NO_EXC
166#endif
167
169 return float_4(_mm_round_ps(a.v, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC));
170}
171
172using std::floor;
173
175 return float_4(_mm_round_ps(a.v, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC));
176}
177
178using std::ceil;
179
181 return float_4(_mm_round_ps(a.v, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC));
182}
183
184using std::round;
185
187 return float_4(_mm_round_ps(a.v, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
188}
189
190using std::fmod;
191
193 return a - floor(a / b) * b;
194}
195
196using std::hypot;
197
199 return sqrt(a * a + b * b);
200}
201
202using std::fabs;
203
205 // Sign bit
206 int32_4 mask = ~0x80000000;
207 return a & float_4::cast(mask);
208}
209
210using std::abs;
211
212inline float_4 abs(float_4 a) {
213 return fabs(a);
214}
215
216inline float_4 abs(std::complex<float_4> a) {
217 return hypot(a.real(), a.imag());
218}
219
220using std::arg;
221
222inline float_4 arg(std::complex<float_4> a) {
223 return atan2(a.imag(), a.real());
224}
225
226using std::pow;
227
229 return exp(b * log(a));
230}
231
232inline float_4 pow(float a, float_4 b) {
233 return exp(b * std::log(a));
234}
235
236template <typename T>
237T pow(T a, int b) {
238 // Optimal with `-O3 -funsafe-math-optimizations` when b is known at compile-time
239 T p = 1;
240 for (int i = 1; i <= b; i *= 2) {
241 if (i & b)
242 p *= a;
243 a *= a;
244 }
245 return p;
246}
247
248// From math.hpp
249
250using math::clamp;
251
252inline float_4 clamp(float_4 x, float_4 a = 0.f, float_4 b = 1.f) {
253 return fmin(fmax(x, a), b);
254}
255
256using math::rescale;
257
258inline float_4 rescale(float_4 x, float_4 xMin, float_4 xMax, float_4 yMin, float_4 yMax) {
259 return yMin + (x - xMin) / (xMax - xMin) * (yMax - yMin);
260}
261
262using math::crossfade;
263
265 return a + (b - a) * p;
266}
267
268using math::sgn;
269
270inline float_4 sgn(float_4 x) {
271 float_4 signbit = x & -0.f;
272 float_4 nonzero = (x != 0.f);
273 return signbit | (nonzero & 1.f);
274}
275
276
277} // namespace simd
278} // namespace rack
#define _MM_FROUND_NO_EXC
Definition functions.hpp:165
int clamp(int x, int a, int b)
Limits x between a and b.
Definition math.hpp:32
float rescale(float x, float xMin, float xMax, float yMin, float yMax)
Rescales x from the range [xMin, xMax] to [yMin, yMax].
Definition math.hpp:151
float crossfade(float a, float b, float p)
Linearly interpolates between a and b, from p = 0 to p = 1.
Definition math.hpp:157
int log2(int n)
Returns floor(log_2(n)), or 0 if n == 1.
Definition math.hpp:77
T sgn(T x)
Returns 1 for positive numbers, -1 for negative numbers, and 0 for zero.
Definition math.hpp:95
float_4 andnot(float_4 a, float_4 b)
~a & b
Definition functions.hpp:15
float_4 arg(std::complex< float_4 > a)
Definition functions.hpp:222
float_4 abs(float_4 a)
Definition functions.hpp:212
float_4 fmax(float_4 x, float_4 b)
Definition functions.hpp:91
float_4 atan2(float_4 x, float_4 y)
Definition functions.hpp:157
float_4 fmin(float_4 x, float_4 b)
Definition functions.hpp:97
float_4 hypot(float_4 a, float_4 b)
Definition functions.hpp:198
float_4 cos(float_4 x)
Definition functions.hpp:139
float_4 pow(float_4 a, float_4 b)
Definition functions.hpp:228
int32_4 movemaskInverse< int32_4 >(int a)
Definition functions.hpp:65
float_4 sqrt(float_4 x)
Definition functions.hpp:103
float_4 tan(float_4 x)
Definition functions.hpp:145
float_4 movemaskInverse< float_4 >(int a)
Definition functions.hpp:72
Vector< int32_t, 4 > int32_4
Definition Vector.hpp:340
float_4 ceil(float_4 a)
Definition functions.hpp:180
float_4 floor(float_4 a)
Definition functions.hpp:174
T movemaskInverse(int a)
Returns a vector where element N is all 1's if the N'th bit of a is 1, or all 0's if the N'th bit of ...
float_4 rsqrt(float_4 x)
Returns the approximate reciprocal square root.
Definition functions.hpp:36
int movemask(float_4 a)
Returns an integer with each bit corresponding to the most significant bit of each element.
Definition functions.hpp:22
float_4 fabs(float_4 a)
Definition functions.hpp:204
float_4 rcp(float_4 x)
Returns the approximate reciprocal.
Definition functions.hpp:43
float_4 log10(float_4 x)
Definition functions.hpp:115
Vector< float, 4 > float_4
Definition Vector.hpp:339
float_4 trunc(float_4 a)
Definition functions.hpp:168
float_4 exp(float_4 x)
Definition functions.hpp:127
float_4 atan(float_4 x)
Definition functions.hpp:151
float_4 round(float_4 a)
Definition functions.hpp:186
float ifelse(bool cond, float a, float b)
Definition functions.hpp:50
float_4 log(float_4 x)
Definition functions.hpp:109
float_4 sin(float_4 x)
Definition functions.hpp:133
float_4 fmod(float_4 a, float_4 b)
Definition functions.hpp:192
Root namespace for the Rack API.
Definition AudioDisplay.hpp:9
__m128 sse_mathfun_cos_ps(__m128 x)
Definition sse_mathfun.h:297
__m128 sse_mathfun_log_ps(__m128 x)
Definition sse_mathfun.h:58
__m128 sse_mathfun_exp_ps(__m128 x)
Definition sse_mathfun.h:129
__m128 sse_mathfun_sin_ps(__m128 x)
Definition sse_mathfun.h:209
__m128 sse_mathfun_atan_ps(__m128 x)
Definition sse_mathfun_extension.h:176
__m128 sse_mathfun_tan_ps(__m128 x)
Definition sse_mathfun_extension.h:167
__m128 sse_mathfun_atan2_ps(__m128 y, __m128 x)
Definition sse_mathfun_extension.h:247
Wrapper for __m128 representing an aligned vector of 4 single-precision float values.
Definition Vector.hpp:33
static Vector cast(Vector< int32_t, 4 > a)
Definition Vector.hpp:162
__m128 v
Definition Vector.hpp:38
Definition Vector.hpp:107
__m128i v
Definition Vector.hpp:112