PageRenderTime 35ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llmath/llsimdtypes.inl

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 157 lines | 104 code | 25 blank | 28 comment | 0 complexity | d36bb1192999d4450acd1ceef4d4cbad MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsimdtypes.inl
  3. * @brief Inlined definitions of basic SIMD math related types
  4. *
  5. * $LicenseInfo:firstyear=2010&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. //////////////////
  27. // LLSimdScalar
  28. //////////////////
  29. inline LLSimdScalar operator+(const LLSimdScalar& a, const LLSimdScalar& b)
  30. {
  31. LLSimdScalar t(a);
  32. t += b;
  33. return t;
  34. }
  35. inline LLSimdScalar operator-(const LLSimdScalar& a, const LLSimdScalar& b)
  36. {
  37. LLSimdScalar t(a);
  38. t -= b;
  39. return t;
  40. }
  41. inline LLSimdScalar operator*(const LLSimdScalar& a, const LLSimdScalar& b)
  42. {
  43. LLSimdScalar t(a);
  44. t *= b;
  45. return t;
  46. }
  47. inline LLSimdScalar operator/(const LLSimdScalar& a, const LLSimdScalar& b)
  48. {
  49. LLSimdScalar t(a);
  50. t /= b;
  51. return t;
  52. }
  53. inline LLSimdScalar operator-(const LLSimdScalar& a)
  54. {
  55. static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 };
  56. return _mm_xor_ps(*reinterpret_cast<const LLQuad*>(signMask), a);
  57. }
  58. inline LLBool32 operator==(const LLSimdScalar& a, const LLSimdScalar& b)
  59. {
  60. return _mm_comieq_ss(a, b);
  61. }
  62. inline LLBool32 operator!=(const LLSimdScalar& a, const LLSimdScalar& b)
  63. {
  64. return _mm_comineq_ss(a, b);
  65. }
  66. inline LLBool32 operator<(const LLSimdScalar& a, const LLSimdScalar& b)
  67. {
  68. return _mm_comilt_ss(a, b);
  69. }
  70. inline LLBool32 operator<=(const LLSimdScalar& a, const LLSimdScalar& b)
  71. {
  72. return _mm_comile_ss(a, b);
  73. }
  74. inline LLBool32 operator>(const LLSimdScalar& a, const LLSimdScalar& b)
  75. {
  76. return _mm_comigt_ss(a, b);
  77. }
  78. inline LLBool32 operator>=(const LLSimdScalar& a, const LLSimdScalar& b)
  79. {
  80. return _mm_comige_ss(a, b);
  81. }
  82. inline LLBool32 LLSimdScalar::isApproximatelyEqual(const LLSimdScalar& rhs, F32 tolerance /* = F_APPROXIMATELY_ZERO */) const
  83. {
  84. const LLSimdScalar tol( tolerance );
  85. const LLSimdScalar diff = _mm_sub_ss( mQ, rhs.mQ );
  86. const LLSimdScalar absDiff = diff.getAbs();
  87. return absDiff <= tol;
  88. }
  89. inline void LLSimdScalar::setMax( const LLSimdScalar& a, const LLSimdScalar& b )
  90. {
  91. mQ = _mm_max_ss( a, b );
  92. }
  93. inline void LLSimdScalar::setMin( const LLSimdScalar& a, const LLSimdScalar& b )
  94. {
  95. mQ = _mm_min_ss( a, b );
  96. }
  97. inline LLSimdScalar& LLSimdScalar::operator=(F32 rhs)
  98. {
  99. mQ = _mm_set_ss(rhs);
  100. return *this;
  101. }
  102. inline LLSimdScalar& LLSimdScalar::operator+=(const LLSimdScalar& rhs)
  103. {
  104. mQ = _mm_add_ss( mQ, rhs );
  105. return *this;
  106. }
  107. inline LLSimdScalar& LLSimdScalar::operator-=(const LLSimdScalar& rhs)
  108. {
  109. mQ = _mm_sub_ss( mQ, rhs );
  110. return *this;
  111. }
  112. inline LLSimdScalar& LLSimdScalar::operator*=(const LLSimdScalar& rhs)
  113. {
  114. mQ = _mm_mul_ss( mQ, rhs );
  115. return *this;
  116. }
  117. inline LLSimdScalar& LLSimdScalar::operator/=(const LLSimdScalar& rhs)
  118. {
  119. mQ = _mm_div_ss( mQ, rhs );
  120. return *this;
  121. }
  122. inline LLSimdScalar LLSimdScalar::getAbs() const
  123. {
  124. static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
  125. return _mm_and_ps( mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A));
  126. }
  127. inline F32 LLSimdScalar::getF32() const
  128. {
  129. F32 ret;
  130. _mm_store_ss(&ret, mQ);
  131. return ret;
  132. }