nlib
SimdVector4.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_SIMD_SIMDVECTOR4_H_
17 #define INCLUDE_NN_NLIB_SIMD_SIMDVECTOR4_H_
18 
19 #include "nn/nlib/simd/SimdFloat.h"
20 
21 NLIB_NAMESPACE_BEGIN
22 namespace simd {
23 
25  public:
26  template<typename MyVector4>
27  static SimdVector __vectorcall LoadFloat4(const MyVector4* p) NLIB_NOEXCEPT;
28  template<typename MyVector4>
29  static void __vectorcall StoreFloat4(MyVector4* p, SimdVectorArg vec) NLIB_NOEXCEPT;
30  static bool __vectorcall CmpEq(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
31  return F128::IsAllMaskTrue(F128::CmpEq(vec1, vec2));
32  }
33  static bool __vectorcall CmpLt(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
34  return F128::IsAllMaskTrue(F128::CmpLt(vec1, vec2));
35  }
36  static bool __vectorcall CmpLe(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
37  return F128::IsAllMaskTrue(F128::CmpLe(vec1, vec2));
38  }
39  static bool __vectorcall CmpGt(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
40  return F128::IsAllMaskTrue(F128::CmpGt(vec1, vec2));
41  }
42  static bool __vectorcall CmpGe(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
43  return F128::IsAllMaskTrue(F128::CmpGe(vec1, vec2));
44  }
45  static bool __vectorcall CmpNe(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
46  return F128::IsAllMaskTrue(F128::CmpNe(vec1, vec2));
47  }
48  static bool __vectorcall CmpNearEq(SimdVectorArg vec1, SimdVectorArg vec2,
50  return F128::IsAllMaskTrue(F128::CmpNearEq(vec1, vec2, eps));
51  }
52  static bool __vectorcall IsNaN(SimdVectorArg vec) NLIB_NOEXCEPT {
53  return !F128::IsAllMaskFalse(F128::IsNaN(vec));
54  }
55  static bool __vectorcall IsInfinite(SimdVectorArg vec) NLIB_NOEXCEPT {
56  return !F128::IsAllMaskFalse(F128::IsInfinite(vec));
57  }
58  static bool __vectorcall InBound(SimdVectorArg vec, SimdVectorArg bounds) NLIB_NOEXCEPT {
59  return F128::IsAllMaskTrue(F128::InBound(vec, bounds));
60  }
61 
62  static f128 __vectorcall Dot(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
63  template<bool SetLane0, bool SetLane1, bool SetLane2, bool SetLane3>
64  static f128 __vectorcall DotEx(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT;
65  static f128 __vectorcall Dot2(SimdVectorArg a, SimdVectorArg b0,
67  static f128 __vectorcall Dot3(SimdVectorArg a, SimdVectorArg b0, SimdVectorArg b1,
69  static f128 __vectorcall Dot4(SimdVectorArg a, SimdVectorArg b0, SimdVectorArg b1,
71  static SimdVector __vectorcall Normalize(SimdVectorArg vec) NLIB_NOEXCEPT;
72  static SimdVector __vectorcall NormalizeEst(SimdVectorArg vec) NLIB_NOEXCEPT;
73  static f128 __vectorcall LengthSq(SimdVectorArg vec) NLIB_NOEXCEPT;
74  static f128 __vectorcall Length(SimdVectorArg vec) NLIB_NOEXCEPT;
75  static f128 __vectorcall LengthEst(SimdVectorArg vec) NLIB_NOEXCEPT;
76  static f128 __vectorcall RecpLength(SimdVectorArg vec) NLIB_NOEXCEPT;
77  static f128 __vectorcall RecpLengthEst(SimdVectorArg vec) NLIB_NOEXCEPT;
78  static f128 __vectorcall GetAngle(SimdVectorArg vec1_normalized,
79  SimdVectorArg vec2_normalized) NLIB_NOEXCEPT;
80  static SimdVector __vectorcall Reflect(SimdVectorArg vec, SimdVectorArg normal) NLIB_NOEXCEPT;
81  // static SimdVector __vectorcall Transform(SimdMatrixArg m, SimdVectorArg vec) NLIB_NOEXCEPT;
82  static SimdVector __vectorcall Transform(SimdVectorArg vec, SimdMatrixArg m) NLIB_NOEXCEPT;
83 
84  // TransformSequence(....)
85  // Refract, Ortho
86 
87  private:
88  Vector4(); // forbidden
89 };
90 
91 #ifndef NLIB_DOXYGEN
92 
93 #define NLIB_M(tp) inline tp __vectorcall
94 #define NLIB_MH(tp) inline tp __vectorcall
95 
96 template<typename MyVector4>
97 // MyVector is a structure like 'struct MyVector4 { float x, y, z, w; };'
98 // nlib_ns::simd::Float4, DirectX::XMFLOAT3, DirectX::XMFLOAT3A for example
99 NLIB_MH(SimdVector) Vector4::LoadFloat4(const MyVector4* p) NLIB_NOEXCEPT {
100  NLIB_STATIC_ASSERT(sizeof(p->x) == 4);
101  NLIB_STATIC_ASSERT(sizeof(p->y) == 4);
102  NLIB_STATIC_ASSERT(sizeof(p->z) == 4);
103  NLIB_STATIC_ASSERT(sizeof(p->w) == 4);
104  return F128::LoadA4(reinterpret_cast<const float*>(&p->x));
105 }
106 
107 template<typename MyVector4>
108 // MyVector is a structure like 'struct MyVector4 { float x, y, z, w; };'
109 // nlib_ns::simd::Float4, DirectX::XMFLOAT3, DirectX::XMFLOAT3A for example
110 NLIB_MH(void) Vector4::StoreFloat4(MyVector4* p, SimdVectorArg vec) NLIB_NOEXCEPT {
111  NLIB_STATIC_ASSERT(sizeof(p->x) == 4);
112  NLIB_STATIC_ASSERT(sizeof(p->y) == 4);
113  NLIB_STATIC_ASSERT(sizeof(p->z) == 4);
114  NLIB_STATIC_ASSERT(sizeof(p->w) == 4);
115  F128::StoreA4(reinterpret_cast<float*>(&p->x), vec);
116 }
117 
118 // r = { dot, dot, dot, dot }
119 NLIB_M(f128) Vector4::Dot(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
120 #ifdef NLIB_F128_SIMD_NOUSE
121  f128 ret;
122  ret.vec.v[0] = ret.vec.v[1] = ret.vec.v[2] = ret.vec.v[3] =
123  vec1.vec.v[0] * vec2.vec.v[0] + vec1.vec.v[1] * vec2.vec.v[1] +
124  vec1.vec.v[2] * vec2.vec.v[2] + vec1.vec.v[3] * vec2.vec.v[3];
125  return ret;
126 #elif defined(NLIB_SSE41)
127  return _mm_dp_ps(vec1, vec2, 0xFF);
128 #elif defined(NLIB_NEON)
129 #ifdef __aarch64__
130  float32x4_t tmp = vmulq_f32(vec1, vec2);
131  tmp = vpaddq_f32(tmp, tmp);
132  tmp = vpaddq_f32(tmp, tmp);
133  return tmp;
134 #else
135  float32x4_t tmp = vmulq_f32(vec1, vec2);
136  float32x2_t v1 = vget_low_f32(tmp);
137  float32x2_t v2 = vget_high_f32(tmp);
138  v1 = vpadd_f32(v1, v1);
139  v2 = vpadd_f32(v2, v2);
140  v1 = vadd_f32(v1, v2);
141  return vcombine_f32(v1, v1);
142 #endif
143 #elif defined(CAFE)
144  f128 tmp = F128::Mult(vec1, vec2);
145  f32x2 val = __PS_ADD(tmp.vec.ps[0], tmp.vec.ps[1]);
146  val = __PS_SUM0(val, val, val);
147  f128 ret;
148  ret.vec.ps[0] = ret.vec.ps[1] = __PS_FDUP(val[0]);
149  return ret;
150 #endif
151 }
152 
153 template<bool SetLane0, bool SetLane1, bool SetLane2, bool SetLane3>
154 // r[i] = SetLane[i] ? dot : 0.f
155 NLIB_MH(f128) Vector4::DotEx(SimdVectorArg vec1, SimdVectorArg vec2) NLIB_NOEXCEPT {
156 #if !defined(NLIB_F128_SIMD_NOUSE) && defined(NLIB_SSE41)
157  return _mm_dp_ps(
158  vec1, vec2,
159  (0xF0 | (SetLane0 ? 1 : 0) | (SetLane1 ? 2 : 0) | (SetLane2 ? 4 : 0) | (SetLane3 ? 8 : 0)));
160 #else
161  return F128::Splat<SetLane0, SetLane1, SetLane2, SetLane3>(F128::SetZero(), Dot(vec1, vec2));
162 #endif
163 }
164 
165 // r = { dot(a, b0), dot(a, b1), 0.f, 0.f }
166 NLIB_M(f128) Vector4::Dot2(SimdVectorArg a, SimdVectorArg b0, SimdVectorArg b1) NLIB_NOEXCEPT {
167 #if !defined(NLIB_F128_SIMD_NOUSE) && defined(NLIB_NEON)
168 #ifdef __aarch64__
169  float32x4_t zero = vdupq_n_f32(0);
170  float32x4_t tmp0 = vmulq_f32(a, b0);
171  float32x4_t tmp1 = vmulq_f32(a, b1);
172  tmp0 = vpaddq_f32(tmp0, tmp1);
173  tmp0 = vpaddq_f32(tmp0, zero);
174  return tmp0;
175 #else
176  float32x4x2_t trn = vtrnq_f32(b0, b1);
177  float32x2_t lo = vget_low_f32(a);
178  float32x2_t hi = vget_high_f32(a);
179  float32x4_t xxzz = vcombine_f32(vdup_lane_f32(lo, 0), vdup_lane_f32(hi, 0));
180  float32x4_t yyww = vcombine_f32(vdup_lane_f32(lo, 1), vdup_lane_f32(hi, 1));
181  float32x4_t tmp = vmulq_f32(trn.val[0], xxzz);
182  tmp = vmlaq_f32(tmp, yyww, trn.val[1]);
183  float32x2_t result = vadd_f32(vget_low_f32(tmp), vget_high_f32(tmp));
184  return vcombine_f32(result, vdup_n_f32(0.f));
185 #endif
186 #else
187  f128 t0 = Vector4::DotEx<true, false, false, false>(a, b0);
188  f128 t1 = Vector4::DotEx<false, true, false, false>(a, b1);
189  return F128::Or(t0, t1);
190 #endif
191 }
192 
193 // r = { dot(a, b0), dot(a, b1), dot(a, b2), 0.f }
194 NLIB_M(f128)
196 #if !defined(NLIB_F128_SIMD_NOUSE) && defined(NLIB_NEON)
197 #ifdef __aarch64__
198  float32x4_t zero = vdupq_n_f32(0);
199  float32x4_t tmp0 = vmulq_f32(a, b0);
200  float32x4_t tmp1 = vmulq_f32(a, b1);
201  float32x4_t tmp2 = vmulq_f32(a, b2);
202  tmp0 = vpaddq_f32(tmp0, tmp1);
203  tmp2 = vpaddq_f32(tmp2, zero);
204  tmp0 = vpaddq_f32(tmp0, tmp2);
205  return tmp0;
206 #else
207  f128 row0, row1, row2, row3;
208  float32x4x2_t trn_f0_ = vtrnq_f32(b0, b1);
209  float32x4x2_t trn_f1_ = vtrnq_f32(b2, vdupq_n_f32(0.f));
210  row0 = vcombine_f32(vget_low_f32(trn_f0_.val[0]), vget_low_f32(trn_f1_.val[0]));
211  row1 = vcombine_f32(vget_low_f32(trn_f0_.val[1]), vget_low_f32(trn_f1_.val[1]));
212  row2 = vcombine_f32(vget_high_f32(trn_f0_.val[0]), vget_high_f32(trn_f1_.val[0]));
213  row3 = vcombine_f32(vget_high_f32(trn_f0_.val[1]), vget_high_f32(trn_f1_.val[1]));
214  f128 ret = F128::Mult<0>(a, row0, each_select32);
215  ret = F128::MultAdd<1>(a, row1, ret, each_select32);
216  ret = F128::MultAdd<2>(a, row2, ret, each_select32);
217  return F128::MultAdd<3>(a, row3, ret, each_select32);
218 #endif
219 #else
220  f128 t0 = Vector4::DotEx<true, false, false, false>(a, b0);
221  f128 t1 = Vector4::DotEx<false, true, false, false>(a, b1);
222  f128 t2 = Vector4::DotEx<false, false, true, false>(a, b2);
223  return F128::Or(F128::Or(t0, t1), t2);
224 #endif
225 }
226 
227 // r = { dot(a, b0), dot(a, b1), dot(a, b2), dot(a, b3) }
228 NLIB_M(f128)
229 Vector4::Dot4(SimdVectorArg a, SimdVectorArg b0, SimdVectorArg b1, SimdVectorArg b2,
231 #if !defined(NLIB_F128_SIMD_NOUSE) && defined(NLIB_NEON)
232 #ifdef __aarch64__
233  float32x4_t tmp0 = vmulq_f32(a, b0);
234  float32x4_t tmp1 = vmulq_f32(a, b1);
235  float32x4_t tmp2 = vmulq_f32(a, b2);
236  float32x4_t tmp3 = vmulq_f32(a, b3);
237  tmp0 = vpaddq_f32(tmp0, tmp1);
238  tmp2 = vpaddq_f32(tmp2, tmp3);
239  tmp0 = vpaddq_f32(tmp0, tmp2);
240  return tmp0;
241 #else
242  f128 row0, row1, row2, row3;
243  float32x4x2_t trn_f0_ = vtrnq_f32(b0, b1);
244  float32x4x2_t trn_f1_ = vtrnq_f32(b2, b3);
245  row0 = vcombine_f32(vget_low_f32(trn_f0_.val[0]), vget_low_f32(trn_f1_.val[0]));
246  row1 = vcombine_f32(vget_low_f32(trn_f0_.val[1]), vget_low_f32(trn_f1_.val[1]));
247  row2 = vcombine_f32(vget_high_f32(trn_f0_.val[0]), vget_high_f32(trn_f1_.val[0]));
248  row3 = vcombine_f32(vget_high_f32(trn_f0_.val[1]), vget_high_f32(trn_f1_.val[1]));
249  f128 ret = F128::Mult<0>(a, row0, each_select32);
250  ret = F128::MultAdd<1>(a, row1, ret, each_select32);
251  ret = F128::MultAdd<2>(a, row2, ret, each_select32);
252  return F128::MultAdd<3>(a, row3, ret, each_select32);
253 #endif
254 #else
255  f128 t0 = Vector4::DotEx<true, false, false, false>(a, b0);
256  f128 t1 = Vector4::DotEx<false, true, false, false>(a, b1);
257  f128 t2 = Vector4::DotEx<false, false, true, false>(a, b2);
258  f128 t3 = Vector4::DotEx<false, false, false, true>(a, b3);
259  return F128::Or(F128::Or(t0, t1), F128::Or(t2, t3));
260 #endif
261 }
262 
263 // nan if |vec| is too big, 0 if |vec| = 0
264 NLIB_M(SimdVector) Vector4::Normalize(SimdVectorArg vec) NLIB_NOEXCEPT {
265  f128 dot = Vector4::Dot(vec, vec);
266 #if defined(NLIB_NEON) && !defined(NLIB_F128_SIMD_NOUSE)
267  float32x4_t x;
268  x = vrsqrteq_f32(dot);
269  x = vmulq_f32(x, vrsqrtsq_f32(dot, vmulq_f32(x, x)));
270  f128 rsqrt = vmulq_f32(x, vrsqrtsq_f32(dot, vmulq_f32(x, x)));
271 #else
272  f128 rsqrt = F128::RecpSqrt(dot);
273 #endif
274  f128 inf = F128::SetInfinity();
275  f128 eqzero = F128::CmpEqZero(dot);
276  f128 eqinf = F128::CmpEq(dot, inf);
277  SimdVector ret = F128::Mult(vec, rsqrt);
278  f128 nan = F128::SetNaN();
279  ret = F128::AndNot(eqzero, ret);
280  ret = F128::Select(eqinf, nan, ret);
281  return ret;
282 }
283 
284 // r = { lensq, lensq, lensq, lensq }
285 NLIB_M(f128) Vector4::LengthSq(SimdVectorArg vec) NLIB_NOEXCEPT {
286  return Dot(vec, vec);
287 }
288 
289 // r = { len, len, len, len }
290 NLIB_M(f128) Vector4::Length(SimdVectorArg vec) NLIB_NOEXCEPT {
291  return F128::Sqrt(Dot(vec, vec));
292 }
293 
294 // r = { len, len, len, len }
295 NLIB_M(f128) Vector4::LengthEst(SimdVectorArg vec) NLIB_NOEXCEPT {
296  return F128::SqrtEst(Dot(vec, vec));
297 }
298 
299 // r = { recpLen, recpLen, recpLen, recpLen }
300 NLIB_M(f128) Vector4::RecpLength(SimdVectorArg vec) NLIB_NOEXCEPT {
301  return F128::RecpSqrt(Dot(vec, vec));
302 }
303 
304 // r = { recpLen, recpLen, recpLen, recpLen }
305 NLIB_M(f128) Vector4::RecpLengthEst(SimdVectorArg vec) NLIB_NOEXCEPT {
306  return F128::RecpSqrtEst(Dot(vec, vec));
307 }
308 
309 NLIB_M(SimdVector) Vector4::NormalizeEst(SimdVectorArg vec) NLIB_NOEXCEPT {
310  return F128::Mult(vec, RecpLengthEst(vec));
311 }
312 
313 // { radian, radian, radian, radian }
314 NLIB_M(f128)
315 Vector4::GetAngle(SimdVectorArg vec1_normalized, SimdVectorArg vec2_normalized) NLIB_NOEXCEPT {
316  f128 ret = Dot(vec1_normalized, vec2_normalized);
317  ret = F128::Clamp(ret, F128::SetNegativeOne(), F128::SetOne());
318  return F128::ArcCos(ret);
319 }
320 
321 NLIB_M(SimdVector) Vector4::Reflect(SimdVectorArg vec, SimdVectorArg normal) NLIB_NOEXCEPT {
322  f128 s = Dot(vec, normal);
323  s = F128::Add(s, s);
324  return F128::MultSub(s, normal, vec);
325 }
326 
327 /*
328 // r = m * vec
329 NLIB_M(SimdVector) Vector4::Transform(SimdMatrixArg m, SimdVectorArg vec) NLIB_NOEXCEPT {
330 #ifdef NLIB_F128_SIMD_NOUSE
331  f128 ret;
332  ret.vec.v[0] = m.r[0].vec.v[0] * vec.vec.v[0] + m.r[0].vec.v[1] * vec.vec.v[1] +
333  m.r[0].vec.v[2] * vec.vec.v[2] + m.r[0].vec.v[3] * vec.vec.v[3];
334  ret.vec.v[1] = m.r[1].vec.v[0] * vec.vec.v[0] + m.r[1].vec.v[1] * vec.vec.v[1] +
335  m.r[1].vec.v[2] * vec.vec.v[2] + m.r[1].vec.v[3] * vec.vec.v[3];
336  ret.vec.v[2] = m.r[2].vec.v[0] * vec.vec.v[0] + m.r[2].vec.v[1] * vec.vec.v[1] +
337  m.r[2].vec.v[2] * vec.vec.v[2] + m.r[2].vec.v[3] * vec.vec.v[3];
338  ret.vec.v[3] = m.r[3].vec.v[0] * vec.vec.v[0] + m.r[3].vec.v[1] * vec.vec.v[1] +
339  m.r[3].vec.v[2] * vec.vec.v[2] + m.r[3].vec.v[3] * vec.vec.v[3];
340  return ret;
341 #elif defined(NLIB_SSE41)
342  f128 tmp, ret;
343  ret = _mm_dp_ps(m.r[0], vec, 0xF1);
344  tmp = _mm_dp_ps(m.r[1], vec, 0xF2);
345  ret = _mm_or_ps(ret, tmp);
346  tmp = _mm_dp_ps(m.r[2], vec, 0xF4);
347  ret = _mm_or_ps(ret, tmp);
348  tmp = _mm_dp_ps(m.r[3], vec, 0xF8);
349  ret = _mm_or_ps(ret, tmp);
350  return ret;
351 #elif defined(NLIB_NEON)
352  float32x4_t r0, r1;
353  float32x2_t lo, hi, tmp;
354 
355  r0 = vmulq_f32(m.r[0], vec);
356  r1 = vmulq_f32(m.r[1], vec);
357  lo = vpadd_f32(vget_low_f32(r0), vget_high_f32(r0));
358  tmp = vpadd_f32(vget_low_f32(r1), vget_high_f32(r1));
359  lo = vpadd_f32(lo, tmp);
360 
361  r0 = vmulq_f32(m.r[2], vec);
362  r1 = vmulq_f32(m.r[3], vec);
363  hi = vpadd_f32(vget_low_f32(r0), vget_high_f32(r0));
364  tmp = vpadd_f32(vget_low_f32(r1), vget_high_f32(r1));
365  hi = vpadd_f32(hi, tmp);
366 
367  return vcombine_f32(lo, hi);
368 #endif
369 }
370 */
371 
372 // r = vec * m
373 NLIB_M(SimdVector) Vector4::Transform(SimdVectorArg vec, SimdMatrixArg m) NLIB_NOEXCEPT {
374  f128 ret = F128::Mult<0>(vec, m.r[0], each_select32);
375  ret = F128::MultAdd<1>(vec, m.r[1], ret, each_select32);
376  ret = F128::MultAdd<2>(vec, m.r[2], ret, each_select32);
377  return F128::MultAdd<3>(vec, m.r[3], ret, each_select32);
378 }
379 
380 #undef NLIB_M
381 #undef NLIB_MH
382 
383 #endif // NLIB_DOXYGEN
384 
385 } // namespace simd
386 NLIB_NAMESPACE_END
387 
388 #endif // INCLUDE_NN_NLIB_SIMD_SIMDVECTOR4_H_
static bool InBound(SimdVectorArg vec, SimdVectorArg bounds) noexcept
Evaluates whether the elements of vec are inside the bounds of bounds.
Definition: SimdVector4.h:58
static bool CmpNearEq(SimdVectorArg vec1, SimdVectorArg vec2, SimdVectorArg eps) noexcept
Compares vec1 and vec2 to see whether they are nearly equal.
Definition: SimdVector4.h:48
f128arg SimdVectorArg
f128arg is defined using typedef.
Definition: SimdFloat.h:4157
static bool IsNaN(SimdVectorArg vec) noexcept
Evaluates whether any of the elements of vec are NaN.
Definition: SimdVector4.h:52
#define NLIB_VIS_HIDDEN
Symbols for functions and classes are not made available outside of the library.
Definition: Platform_unix.h:86
static bool CmpGe(SimdVectorArg vec1, SimdVectorArg vec2) noexcept
Checks to see whether all of the elements of vec1 are equal or greater than the corresponding element...
Definition: SimdVector4.h:42
static bool CmpGt(SimdVectorArg vec1, SimdVectorArg vec2) noexcept
Checks to see whether all of the elements of vec1 are larger than the corresponding elements of vec2...
Definition: SimdVector4.h:39
The structure for keeping a 4x4 matrix.
Definition: SimdFloat.h:4168
static bool CmpNe(SimdVectorArg vec1, SimdVectorArg vec2) noexcept
Compares vec1 and vec2 to see whether they are unequal.
Definition: SimdVector4.h:45
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Config.h:109
The class with the collection of functions that perform calculations on four-dimensional vectors...
Definition: SimdVector4.h:24
Defines the class and functions for SIMD computations on single-precision floating-point numbers...
constexpr const each_select32_tag each_select32
The tag for representing the selection of a 32-bit lane with an each_select32_tag-type constant objec...
Definition: SimdInt.h:63
static bool CmpEq(SimdVectorArg vec1, SimdVectorArg vec2) noexcept
Compares two four-dimensional vectors to see if they are equal.
Definition: SimdVector4.h:30
nlib_f128_t f128
nlib_f128_t is defined using typedef.
Definition: SimdFloat.h:77
static bool CmpLt(SimdVectorArg vec1, SimdVectorArg vec2) noexcept
Checks to see whether all of the elements of vec1 are smaller than the corresponding elements of vec2...
Definition: SimdVector4.h:33
#define NLIB_STATIC_ASSERT(exp)
Defines a static assertion. Uses static_assert if it is available for use.
Definition: Config.h:174
static bool IsInfinite(SimdVectorArg vec) noexcept
Evaluates whether any of the elements of vec are positive infinity or negative infinity.
Definition: SimdVector4.h:55
static bool CmpLe(SimdVectorArg vec1, SimdVectorArg vec2) noexcept
Checks to see whether all of the elements of vec1 are equal or less than the corresponding elements o...
Definition: SimdVector4.h:36
f128 SimdVector
f128 is defined using typedef. Used when handling three-dimensional or four-dimensional vectors...
Definition: SimdFloat.h:4156