/** * @file llsimdtypes.h * @brief Declaration of basic SIMD math related types * * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #ifndef LL_SIMD_TYPES_H #define LL_SIMD_TYPES_H #ifndef LL_SIMD_MATH_H #error "Please include llmath.h before this file." #endif typedef __m128 LLQuad; #if LL_WINDOWS #pragma warning(push) #pragma warning( disable : 4800 3 ) // Disable warning about casting int to bool for this class. #if defined(_MSC_VER) && (_MSC_VER < 1500) // VC++ 2005 is missing these intrinsics // __forceinline is MSVC specific and attempts to override compiler inlining judgment. This is so // even in debug builds this call is a NOP. __forceinline const __m128 _mm_castsi128_ps( const __m128i a ) { return reinterpret_cast(a); } __forceinline const __m128i _mm_castps_si128( const __m128 a ) { return reinterpret_cast(a); } #endif // _MSC_VER #endif // LL_WINDOWS class LLBool32 { public: inline LLBool32() {} inline LLBool32(int rhs) : m_bool(rhs) {} inline LLBool32(unsigned int rhs) : m_bool(rhs) {} inline LLBool32(bool rhs) { m_bool = static_cast(rhs); } inline LLBool32& operator= (bool rhs) { m_bool = (int)rhs; return *this; } inline bool operator== (bool rhs) const { return static_cast(m_bool) == rhs; } inline bool operator!= (bool rhs) const { return !operator==(rhs); } inline operator bool() const { return static_cast(m_bool); } private: int m_bool{ 0 }; }; #if LL_WINDOWS #pragma warning(pop) #endif class LLSimdScalar { public: inline LLSimdScalar() {} inline LLSimdScalar(LLQuad q) { mQ = q; } inline LLSimdScalar(F32 f) { mQ = _mm_set_ss(f); } static inline const LLSimdScalar& getZero() { extern const LLQuad F_ZERO_4A; return reinterpret_cast(F_ZERO_4A); } inline F32 getF32() const; inline LLBool32 isApproximatelyEqual(const LLSimdScalar& rhs, F32 tolerance = F_APPROXIMATELY_ZERO) const; inline LLSimdScalar getAbs() const; inline void setMax( const LLSimdScalar& a, const LLSimdScalar& b ); inline void setMin( const LLSimdScalar& a, const LLSimdScalar& b ); inline LLSimdScalar& operator=(F32 rhs); inline LLSimdScalar& operator+=(const LLSimdScalar& rhs); inline LLSimdScalar& operator-=(const LLSimdScalar& rhs); inline LLSimdScalar& operator*=(const LLSimdScalar& rhs); inline LLSimdScalar& operator/=(const LLSimdScalar& rhs); inline operator LLQuad() const { return mQ; } inline const LLQuad& getQuad() const { return mQ; } private: LLQuad mQ{}; }; #endif //LL_SIMD_TYPES_H