summaryrefslogtreecommitdiff
path: root/Runtime/Math/Simd/float1.h
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Math/Simd/float1.h')
-rw-r--r--Runtime/Math/Simd/float1.h232
1 files changed, 232 insertions, 0 deletions
diff --git a/Runtime/Math/Simd/float1.h b/Runtime/Math/Simd/float1.h
new file mode 100644
index 0000000..90c17ae
--- /dev/null
+++ b/Runtime/Math/Simd/float1.h
@@ -0,0 +1,232 @@
+#ifndef SIMD_FLOAT1_H
+#define SIMD_FLOAT1_H
+
+#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h"
+
+#include "Runtime/Math/Simd/intrinsic.h"
+
+#include "Runtime/Math/Simd/bool1.h"
+
+namespace math
+{
+
+struct float1;
+
+template<typename T> struct ATTRIBUTE_ALIGN(ALIGN4F) vecexp1 : T
+{
+ typedef T value_type;
+ typedef typename T::scalar_type scalar_type;
+ typedef typename T::packed_type packed_type;
+
+ MECANIM_FORCE_INLINE vecexp1() {}
+
+ MECANIM_FORCE_INLINE vecexp1(vecexp1 const& e):value_type(e) { }
+
+ explicit MECANIM_FORCE_INLINE vecexp1(scalar_type s):value_type(s){ }
+
+ explicit MECANIM_FORCE_INLINE vecexp1(packed_type vector):value_type(vector) { }
+
+ MECANIM_FORCE_INLINE vecexp1(value_type const& r):value_type(r) { }
+
+ MECANIM_FORCE_INLINE vecexp1(scalar_type x, scalar_type y, scalar_type z, scalar_type w):value_type(x,y,z,w) { }
+
+ template<typename R> MECANIM_FORCE_INLINE vecexp1(const vecexp1<R> &e){
+ value_type::v = Vswizzle<value_type::LHS_SWZ>::lhs(value_type::v, e.eval() );
+ }
+
+ inline bool IsFinite ()const
+ {
+ return ::IsFinite(Vstoresf(value_type::v));
+ }
+
+ MECANIM_FORCE_INLINE vecexp1 &operator=(const vecexp1 &e) {
+ SIMD_ASSERT_IF(!e.IsFinite());
+ value_type::v = Vswizzle<value_type::LHS_SWZ>::lhs(value_type::v, e.eval() );
+ return *this;
+ }
+
+ template<typename R> MECANIM_FORCE_INLINE vecexp1 &operator=(const vecexp1<R> &e){
+ SIMD_ASSERT_IF(!e.IsFinite());
+ value_type::v = Vswizzle<value_type::LHS_SWZ>::lhs(value_type::v, e.eval() );
+ return *this;
+ }
+
+ MECANIM_FORCE_INLINE vecexp1 &operator=(scalar_type s) {
+ SIMD_ASSERT_IF(!::IsFinite(s));
+ value_type::operator =(s);
+ return *this; }
+
+ MECANIM_FORCE_INLINE const vecexp1 &operator+() const { return *this; }
+ MECANIM_FORCE_INLINE vecexp1 operator-() const { return vecexp1(Vneg( value_type::eval() ) ); }
+
+ template<typename R>MECANIM_FORCE_INLINE vecexp1 &operator+=(const vecexp1<R> &r) {
+ value_type::v = Vswizzle<value_type::LHS_SWZ>::lhs(value_type::v, Vadd( value_type::eval(), r.eval() )); return *this;
+ }
+
+ template<typename R> MECANIM_FORCE_INLINE vecexp1 &operator-=(const vecexp1<R> &r) {
+ value_type::v = Vswizzle<value_type::LHS_SWZ>::lhs(value_type::v, Vsub( value_type::eval(), r.eval() )); return *this;
+ }
+
+ template<typename R> MECANIM_FORCE_INLINE vecexp1 &operator*=(const vecexp1<R> &r) {
+ value_type::v = Vswizzle<value_type::LHS_SWZ>::lhs(value_type::v, Vmul(value_type::eval(), r.eval())); return *this;
+ }
+
+ template<typename R> MECANIM_FORCE_INLINE vecexp1 &operator/=(const vecexp1<R> &r) {
+ value_type::v = Vswizzle<value_type::LHS_SWZ>::lhs(value_type::v, Vdiv(value_type::eval(), r.eval())); return *this;
+ }
+};
+
+struct ATTRIBUTE_ALIGN(ALIGN4F) vec1
+{
+ typedef float scalar_type;
+ typedef vec4f packed_type;
+ typedef vec4f const& const_reference_packed_type;
+ typedef vec4f& reference_packed_type;
+
+ enum{
+ RHS_SWZ = kXYZW,
+ LHS_SWZ = kXYZW
+ };
+
+ MECANIM_FORCE_INLINE vec1() {}
+
+ MECANIM_FORCE_INLINE vec1(scalar_type scalar):v(Vloadsf(scalar)) { }
+
+ MECANIM_FORCE_INLINE vec1(packed_type vector):v(vector){ }
+
+ template<typename T> MECANIM_FORCE_INLINE vec1(const T& vector) { v = vector.eval(); }
+
+ MECANIM_FORCE_INLINE scalar_type tofloat() const { return Vstoresf( v ); }
+
+ MECANIM_FORCE_INLINE vec1 &operator=(const vec1 &l) { v = l.v; return *this; }
+
+ MECANIM_FORCE_INLINE packed_type eval()const{ return v; }
+
+protected:
+ packed_type v;
+};
+
+struct ATTRIBUTE_ALIGN(ALIGN4F) float1 : public vecexp1<vec1>
+{
+ DEFINE_GET_TYPESTRING(float1)
+
+ typedef vec1 value_type;
+ typedef vec1::scalar_type scalar_type;
+ typedef vec1::packed_type packed_type;
+
+ MECANIM_FORCE_INLINE float1() {}
+
+ MECANIM_FORCE_INLINE explicit float1(scalar_type s):vecexp1<value_type>(s) {}
+
+ MECANIM_FORCE_INLINE explicit float1(packed_type const& v):vecexp1<value_type>(v) { }
+
+ MECANIM_FORCE_INLINE float1(const float1 &f):vecexp1<value_type>(f) { }
+
+ template<typename R> MECANIM_FORCE_INLINE float1(const vecexp1<R> &e){ value_type::v = e.eval(); }
+
+ MECANIM_FORCE_INLINE float1 &operator=(const float1 &f) { value_type::v = f.eval(); return *this; }
+
+ template<typename R> MECANIM_FORCE_INLINE float1 &operator=(const vecexp1<R> &e) { value_type::v = e.eval(); return *this; }
+
+ template<typename R>MECANIM_FORCE_INLINE float1 &operator+=(const vecexp1<R> &r) {
+ value_type::v = Vadd( value_type::eval(), r.eval() ); return *this;
+ }
+
+ template<typename R> MECANIM_FORCE_INLINE float1 &operator-=(const vecexp1<R> &r) {
+ value_type::v = Vsub( value_type::eval(), r.eval() ); return *this;
+ }
+
+ template<typename R> MECANIM_FORCE_INLINE float1 &operator*=(const vecexp1<R> &r) {
+ value_type::v = Vmul(value_type::eval(), r.eval() ); return *this;
+ }
+
+ template<typename R> MECANIM_FORCE_INLINE float1 &operator/=(const vecexp1<R> &r) {
+ value_type::v = Vdiv(value_type::eval(), r.eval() ); return *this;
+ }
+
+
+ MECANIM_FORCE_INLINE float1 &operator++() { value_type::v = Vinc(value_type::v); return *this; }
+ MECANIM_FORCE_INLINE float1 operator++(int) { float1 r = *this; value_type::v = Vinc(value_type::v); return r; }
+
+ MECANIM_FORCE_INLINE float1 &operator--() { value_type::v = Vdec(value_type::v); return *this; }
+ MECANIM_FORCE_INLINE float1 operator--(int) { float1 r = *this; value_type::v = Vdec(value_type::v); return r; }
+
+ static float1 zero() {return float1(Vzero()); } // 0
+ static float1 one() {return float1(Vone());} // 1
+
+ template<class TransferFunction>
+ MECANIM_FORCE_INLINE void Transfer (TransferFunction& transfer)
+ {
+ /////@TODO: This is wrong. It will not work for SafeBinaryRead
+ /////// Probably other places in the code too!
+
+ float x;
+ if(transfer.IsReading())
+ {
+ transfer.Transfer(x, "x");
+ *this = float1(x);
+ }
+ else if(transfer.IsWriting())
+ {
+ x = tofloat();
+
+ transfer.Transfer(x, "x");
+ }
+ else
+ {
+ transfer.Transfer(x, "x");
+ }
+ }
+};
+
+// vecexp1 Arithemtic
+template<typename LHS, typename RHS> static MECANIM_FORCE_INLINE vecexp1<vec1> operator+(const vecexp1<LHS> &l, const vecexp1<RHS> &r)
+{
+ return vecexp1<vec1>( Vadd( l.eval(), r.eval() ));
+}
+
+template<typename LHS, typename RHS> static MECANIM_FORCE_INLINE vecexp1<vec1> operator-(const vecexp1<LHS> &l, const vecexp1<RHS> &r)
+{
+ return vecexp1<vec1>( Vsub( l.eval(), r.eval() ));
+}
+
+template<typename LHS, typename RHS> static MECANIM_FORCE_INLINE vecexp1<vec1> operator*(const vecexp1<LHS> &l, const vecexp1<RHS> &r)
+{
+ return vecexp1<vec1>( Vmul( l.eval(), r.eval() ));
+}
+
+template<typename LHS, typename RHS> static MECANIM_FORCE_INLINE vecexp1<vec1> operator/(const vecexp1<LHS> &l, const vecexp1<RHS> &r)
+{
+ return vecexp1<vec1>( Vdiv( l.eval(), r.eval() ));
+}
+
+// vecexp1 logic
+template <typename LHS, typename RHS> static MECANIM_FORCE_INLINE bool1 operator<(const vecexp1<LHS> &l, const vecexp1<RHS> &r)
+{
+ return bool1( Vcmplt( l.eval(), r.eval() ) );
+}
+template <typename LHS, typename RHS> static MECANIM_FORCE_INLINE bool1 operator<=(const vecexp1<LHS> &l, const vecexp1<RHS> &r)
+{
+ return bool1( Vcmple( l.eval(), r.eval() ) );
+}
+template <typename LHS, typename RHS> static MECANIM_FORCE_INLINE bool1 operator==(const vecexp1<LHS> &l, const vecexp1<RHS> &r)
+{
+ return bool1( Vcmpeq( l.eval(), r.eval() ) );
+}
+template <typename LHS, typename RHS> static MECANIM_FORCE_INLINE bool1 operator!=(const vecexp1<LHS> &l, const vecexp1<RHS> &r)
+{
+ return bool1( Vcmpneq( l.eval(), r.eval() ) );
+}
+template <typename LHS, typename RHS> static MECANIM_FORCE_INLINE bool1 operator>=(const vecexp1<LHS> &l, const vecexp1<RHS> &r)
+{
+ return bool1( Vcmpge( l.eval(), r.eval() ));
+}
+template <typename LHS, typename RHS> static MECANIM_FORCE_INLINE bool1 operator>(const vecexp1<LHS> &l, const vecexp1<RHS> &r)
+{
+ return bool1( Vcmpgt( l.eval(), r.eval() ) );
+}
+
+}
+
+
+#endif