| @@ -1,3 +1,4 @@ | |||
| #include "common.hpp" | |||
| #include "sse_mathfun.h" | |||
| #include <emmintrin.h> | |||
| @@ -6,24 +7,51 @@ namespace rack { | |||
| namespace dsp { | |||
| inline float cast_i32_f32(int i) { | |||
| float f; | |||
| std::memcpy(&f, &i, sizeof(f)); | |||
| return f; | |||
| } | |||
| inline int cast_f32_i32(float f) { | |||
| float i; | |||
| std::memcpy(&i, &f, sizeof(i)); | |||
| return i; | |||
| } | |||
| template <int N> | |||
| struct f32; | |||
| /** Wrapper for `__m128` representing an aligned vector of 4 single-precision float values. */ | |||
| /** Wrapper for `__m128` representing an aligned vector of 4 single-precision float values. | |||
| */ | |||
| template <> | |||
| struct f32<4> { | |||
| __m128 v; | |||
| /** Constructs an uninitialized vector. */ | |||
| f32<4>() {} | |||
| /** Constructs a vector from a native `__m128` type. */ | |||
| f32<4>(__m128 v) : v(v) {} | |||
| /** Constructs a vector with all elements set to `x`. */ | |||
| f32<4>(float x) { | |||
| v = _mm_set_ps1(x); | |||
| } | |||
| /** Reads an array of 4 values. */ | |||
| static f32<4> load(const float *x) { | |||
| return f32<4>(_mm_loadu_ps(x)); | |||
| } | |||
| /** Returns a vector initialized to zero. */ | |||
| static f32<4> zero() { | |||
| return f32<4>(_mm_setzero_ps()); | |||
| } | |||
| /** Writes an array of 4 values. */ | |||
| void store(float *x) { | |||
| _mm_storeu_ps(x, v); | |||
| @@ -52,9 +80,9 @@ typedef f32<4> f32_4; | |||
| } | |||
| /** `a operator b` */ | |||
| #define DECLARE_F32_4_OPERATOR_INCREMENT(operator, func) \ | |||
| #define DECLARE_F32_4_OPERATOR_INCREMENT(operator, opfunc) \ | |||
| inline f32_4 &operator(f32_4 &a, const f32_4 &b) { \ | |||
| a.v = func(a.v, b.v); \ | |||
| a = opfunc(a, b); \ | |||
| return a; \ | |||
| } \ | |||
| template <typename T> \ | |||
| @@ -67,6 +95,25 @@ DECLARE_F32_4_OPERATOR_INFIX(operator-, _mm_sub_ps) | |||
| DECLARE_F32_4_OPERATOR_INFIX(operator*, _mm_mul_ps) | |||
| DECLARE_F32_4_OPERATOR_INFIX(operator/, _mm_div_ps) | |||
| /** Boolean operators on vectors give 0x00000000 for false and 0xffffffff for true, for each vector element. | |||
| Use these to apply logic, bit masks, and conditions to elements. | |||
| Examples: | |||
| Subtract 1 from value if greater than or equal to 1. | |||
| x -= (x >= 1.f) & 1.f; | |||
| */ | |||
| DECLARE_F32_4_OPERATOR_INFIX(operator^, _mm_xor_ps) | |||
| DECLARE_F32_4_OPERATOR_INFIX(operator&, _mm_and_ps) | |||
| DECLARE_F32_4_OPERATOR_INFIX(operator|, _mm_mul_ps) | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator+=, operator+); | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator-=, operator-); | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator*=, operator*); | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator/=, operator/); | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator^=, operator^); | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator&=, operator&); | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator|=, operator|); | |||
| /** `+a` */ | |||
| inline f32_4 operator+(const f32_4 &a) { | |||
| return a; | |||
| @@ -77,11 +124,6 @@ inline f32_4 operator-(const f32_4 &a) { | |||
| return 0.f - a; | |||
| } | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator+=, _mm_add_ps); | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator-=, _mm_sub_ps); | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator*=, _mm_mul_ps); | |||
| DECLARE_F32_4_OPERATOR_INCREMENT(operator/=, _mm_div_ps); | |||
| /** `++a` */ | |||
| inline f32_4 &operator++(f32_4 &a) { | |||
| a += 1.f; | |||
| @@ -108,10 +150,6 @@ inline f32_4 operator--(f32_4 &a, int) { | |||
| return b; | |||
| } | |||
| DECLARE_F32_4_OPERATOR_INFIX(operator^, _mm_xor_ps) | |||
| DECLARE_F32_4_OPERATOR_INFIX(operator&, _mm_and_ps) | |||
| DECLARE_F32_4_OPERATOR_INFIX(operator|, _mm_mul_ps) | |||
| /** `~a` */ | |||
| inline f32_4 operator~(const f32_4 &a) { | |||
| return f32_4(_mm_xor_ps(a.v, _mm_cmpeq_ps(a.v, a.v))); | |||
| @@ -125,7 +163,6 @@ DECLARE_F32_4_OPERATOR_INFIX(operator<, _mm_cmplt_ps) | |||
| DECLARE_F32_4_OPERATOR_INFIX(operator!=, _mm_cmpneq_ps) | |||
| // Math functions | |||