Browse Source

Add simd.hpp

tags/v1.0.0
Andrew Belt 6 years ago
parent
commit
14292f8e65
1 changed files with 105 additions and 0 deletions
  1. +105
    -0
      include/simd.hpp

+ 105
- 0
include/simd.hpp View File

@@ -0,0 +1,105 @@
#include <x86intrin.h>


#define ALIGN(n) __attribute__((aligned(n)))


namespace simd {


template <int N>
struct f32;


/** Wrapper for `__m128` representing a vector of 4 single-precision float values. */
template <>
struct f32<4> {
__m128 v;

f32<4>() {}
f32<4>(__m128 v) : v(v) {}
template <typename T>
f32<4>(T x) {
v = _mm_set_ps1((float) x);
}
/** Reads an array of 4 values */
f32<4>(const float *x) {
v = _mm_loadu_ps(x);
}
/** Writes an array of 4 values */
void store(float *x) {
_mm_storeu_ps(x, v);
}
};


// Operator overloads

#define DECLARE_F32_4_OPERATOR_INFIX(operator, func) \
inline f32<4> operator(f32<4> a, f32<4> b) { \
return f32<4>(func(a.v, b.v)); \
} \
template <typename T> \
f32<4> operator(T a, f32<4> b) { \
return operator(f32<4>(a), b); \
} \
template <typename T> \
f32<4> operator(f32<4> a, T b) { \
return operator(a, f32<4>(b)); \
}

DECLARE_F32_4_OPERATOR_INFIX(operator+, _mm_add_ps)
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)
DECLARE_F32_4_OPERATOR_INFIX(operator==, _mm_cmpeq_ps)
DECLARE_F32_4_OPERATOR_INFIX(operator>=, _mm_cmpge_ps)
DECLARE_F32_4_OPERATOR_INFIX(operator>, _mm_cmpgt_ps)
DECLARE_F32_4_OPERATOR_INFIX(operator<=, _mm_cmple_ps)
DECLARE_F32_4_OPERATOR_INFIX(operator<, _mm_cmplt_ps)
DECLARE_F32_4_OPERATOR_INFIX(operator!=, _mm_cmpneq_ps)

#define DECLARE_F32_4_OPERATOR_INCREMENT(operator, func) \
inline f32<4> &operator(f32<4> &a, f32<4> b) { \
a.v = func(a.v, b.v); \
return a; \
} \
template <typename T> \
f32<4> &operator(f32<4> &a, T b) { \
return operator(a, f32<4>(b)); \
}

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);


inline f32<4> rsqrt(f32<4> a) {
return f32<4>(_mm_rsqrt_ps(a.v));
}

inline f32<4> rcp(f32<4> a) {
return f32<4>(_mm_rcp_ps(a.v));
}


} // namespace simd


namespace std {

inline simd::f32<4> max(simd::f32<4> a, simd::f32<4> b) {
return simd::f32<4>(_mm_max_ps(a.v, b.v));
}

inline simd::f32<4> min(simd::f32<4> a, simd::f32<4> b) {
return simd::f32<4>(_mm_min_ps(a.v, b.v));
}

inline simd::f32<4> sqrt(simd::f32<4> a) {
return simd::f32<4>(_mm_sqrt_ps(a.v));
}

} // namespace std


Loading…
Cancel
Save