diff --git a/src/tenvex/expressions/core.h b/src/tenvex/expressions/core.h index c95f5f2..899e7b7 100644 --- a/src/tenvex/expressions/core.h +++ b/src/tenvex/expressions/core.h @@ -4,9 +4,10 @@ #include "defines.h" #if defined(HAS_SSE42) -#include -using vf4 = __m128; + #include + using vf4 = __m128; #else + #error "tenvex requires an SSE4.1 backend (define HAS_SSE42 and build with -msse4.1 on GCC/Clang)" #endif namespace tnvx::detail @@ -31,6 +32,13 @@ vf4 scalar(float value) noexcept return _mm_set_ps1(value); } +template +[[nodiscard]] TNVX_INLINE +float get_lane(vf4 v) noexcept +{ + return _mm_cvtss_f32(_mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, lane))); +} + [[nodiscard]] TNVX_INLINE vf4 add(vf4 l, vf4 r) noexcept { diff --git a/src/tenvex/expressions/vec4.h b/src/tenvex/expressions/vec4.h index 9b6bac9..30be4e7 100644 --- a/src/tenvex/expressions/vec4.h +++ b/src/tenvex/expressions/vec4.h @@ -20,10 +20,23 @@ struct alignas(16) vec4 : Expr TNVX_INLINE vec4(const E& e) noexcept; + [[nodiscard]] TNVX_INLINE + float x() const noexcept; + + [[nodiscard]] TNVX_INLINE + float y() const noexcept; + + [[nodiscard]] TNVX_INLINE + float z() const noexcept; + + [[nodiscard]] TNVX_INLINE + float w() const noexcept; + [[nodiscard]] TNVX_INLINE vf4 eval() const noexcept; private: + vf4 _data; }; diff --git a/src/tenvex/expressions/vec4_impl.hpp b/src/tenvex/expressions/vec4_impl.hpp index c58236d..d14b342 100644 --- a/src/tenvex/expressions/vec4_impl.hpp +++ b/src/tenvex/expressions/vec4_impl.hpp @@ -31,9 +31,33 @@ bool approx_eq(const vec4& lhs, const vec4& rhs, float eps) noexcept } TNVX_INLINE -bool tnvx::operator==(const vec4& lhs, const vec4& rhs) noexcept +bool operator==(const vec4& lhs, const vec4& rhs) noexcept { return detail::eq(lhs.eval(), rhs.eval()); } +TNVX_INLINE +float vec4::x() const noexcept +{ + return detail::get_lane<0>(_data); +} + +TNVX_INLINE +float vec4::y() const noexcept +{ + return detail::get_lane<1>(_data); +} + +TNVX_INLINE +float vec4::z() const noexcept +{ + return detail::get_lane<2>(_data); +} + +TNVX_INLINE +float vec4::w() const noexcept +{ + return detail::get_lane<3>(_data); +} + }