00001 #ifndef __LDK_SIMD_H__
00002 #define __LDK_SIMD_H__
00003
00004 #include <assert.h>
00005
00006 #ifdef __sse__
00007 #include <xmmintrin.h>
00008 #endif
00009
00010 #include "LDK/TemplateMeta.h"
00011
00012 namespace LDK
00013 {
00014
00015 #ifdef __sse__
00016 typedef __m128 v4sf;
00017
00018 class ALIGNED16 V4SF
00019 {
00020 protected:
00021 v4sf data;
00022 public:
00023 inline V4SF() {}
00024 inline V4SF(const V4SF& val) { data = val.data; }
00025 inline V4SF(const v4sf& val) { data = val; }
00026
00027 inline V4SF(float* v) { data = _mm_loadu_ps(v); }
00028 inline V4SF(float a, float b, float c, float d) { _mm_set_ps(a,b,c,d); }
00029 inline explicit V4SF(float val) { data = _mm_set_ps1(val); }
00030 inline explicit V4SF(double val) { data = _mm_set_ps1((float)val); }
00031
00032 inline V4SF& operator=(const V4SF& v) { data = v.data; }
00033 inline V4SF& operator=(const v4sf& v) { data = v; }
00034 inline V4SF& operator=(float val) { data = _mm_set_ps1(val); return *this; }
00035 inline V4SF& operator=(double val) { data = _mm_set_ps1((float)val); return *this; }
00036
00037 inline operator v4sf() const { return data; }
00038
00039 inline V4SF operator-()
00040 {
00041 V4SF rtn(0.0f);
00042 rtn -= *this;
00043 return rtn;
00044 }
00045
00046
00047
00048 friend inline V4SF operator+(const V4SF& a, const V4SF& b) { return V4SF(_mm_add_ps(a,b)); }
00049 friend inline V4SF operator-(const V4SF& a, const V4SF& b) { return V4SF(_mm_sub_ps(a,b)); }
00050 friend inline V4SF operator*(const V4SF& a, const V4SF& b) { return V4SF(_mm_mul_ps(a,b)); }
00051 friend inline V4SF operator/(const V4SF& a, const V4SF& b) { return V4SF(_mm_div_ps(a,b)); }
00052 inline V4SF& operator+=(const V4SF& v) { return *this = _mm_add_ps(data,v.data); }
00053 inline V4SF& operator-=(const V4SF& v) { return *this = _mm_sub_ps(data,v.data); }
00054 inline V4SF& operator*=(const V4SF& v) { return *this = _mm_mul_ps(data,v.data); }
00055 inline V4SF& operator/=(const V4SF& v) { return *this = _mm_div_ps(data,v.data); }
00056
00057 friend inline V4SF operator+(const V4SF& a, float b) { return V4SF(_mm_add_ps(a,_mm_set_ps1(b))); }
00058 friend inline V4SF operator-(const V4SF& a, float b) { return V4SF(_mm_sub_ps(a,_mm_set_ps1(b))); }
00059 friend inline V4SF operator*(const V4SF& a, float b) { return V4SF(_mm_mul_ps(a,_mm_set_ps1(b))); }
00060 friend inline V4SF operator/(const V4SF& a, float b) { return V4SF(_mm_div_ps(a,_mm_set_ps1(b))); }
00061 inline V4SF& operator+=(float a) { return *this = V4SF(_mm_add_ps(data,_mm_set_ps1(a))); }
00062 inline V4SF& operator-=(float a) { return *this = V4SF(_mm_sub_ps(data,_mm_set_ps1(a))); }
00063 inline V4SF& operator*=(float a) { return *this = V4SF(_mm_mul_ps(data,_mm_set_ps1(a))); }
00064 inline V4SF& operator/=(float a) { return *this = V4SF(_mm_div_ps(data,_mm_set_ps1(a))); }
00065
00066
00067 inline const float& operator[](int idx) const
00068 {
00069 assert((0 <= idx) && (idx <= 3));
00070 return *(((float*)&data)+idx);
00071 }
00072 inline float& operator[](int idx)
00073 {
00074 assert((0 <= idx) && (idx <= 3));
00075 return *(((float*)&data)+idx);
00076 }
00077
00078 friend inline V4SF recip(const V4SF& v) { return _mm_rcp_ps(v); }
00079
00080 friend inline V4SF sqrt(const V4SF& v) { return _mm_sqrt_ps(v); }
00081 friend inline V4SF recipsqrt(const V4SF& v) { return _mm_rsqrt_ps(v); }
00082 };
00083
00084 #else //emulate the VPU with the FPU.
00085 #include <math.h>
00086 struct ALIGNED16 v4sf
00087 {
00088 float f0, f1, f2, f3;
00089 v4sf() {}
00090 };
00091
00092 class ALIGNED16 V4SF
00093 {
00094 protected:
00095 v4sf data;
00096 public:
00097 V4SF() {}
00098 inline V4SF(float f0, float f1, float f2, float f3) { data.f0=f0; data.f1=f1; data.f2=f2; data.f3=f3; }
00099 inline V4SF(const v4sf& val) { data = val; }
00100 inline V4SF(float* dat) { data = (*(v4sf*)dat); }
00101 inline V4SF(float val) { *this = val; }
00102 inline V4SF& operator=(float val) { data.f0 = data.f1 = data.f2 = data.f3 = val; return *this; }
00103
00104 inline operator v4sf() const { return data; }
00105 inline V4SF operator-()
00106 {
00107 V4SF rtn(0.0f);
00108 rtn -= *this;
00109 return rtn;
00110 }
00111
00112
00113
00114
00115 friend inline V4SF operator+(const V4SF& a, const V4SF& b)
00116 {
00117 return V4SF(a.data.f0+b.data.f0, a.data.f1+b.data.f1,
00118 a.data.f2+b.data.f2, a.data.f3+b.data.f3);
00119 }
00120 friend inline V4SF operator-(const V4SF& a, const V4SF& b)
00121 {
00122 return V4SF(a.data.f0-b.data.f0, a.data.f1-b.data.f1,
00123 a.data.f2-b.data.f2, a.data.f3-b.data.f3);
00124 }
00125 friend inline V4SF operator*(const V4SF& a, const V4SF& b)
00126 {
00127 return V4SF(a.data.f0*b.data.f0, a.data.f1*b.data.f1,
00128 a.data.f2*b.data.f2, a.data.f3*b.data.f3);
00129 }
00130 friend inline V4SF operator/(const V4SF& a, const V4SF& b)
00131 {
00132 return V4SF(a.data.f0/b.data.f0, a.data.f1/b.data.f1,
00133 a.data.f2/b.data.f2, a.data.f3/b.data.f3);
00134 }
00135
00136
00137
00138 inline V4SF& operator+=(const V4SF& val)
00139 {
00140 data.f0 += val.data.f0;
00141 data.f1 += val.data.f1;
00142 data.f2 += val.data.f2;
00143 data.f3 += val.data.f3;
00144 return *this;
00145 }
00146 inline V4SF& operator-=(const V4SF& val)
00147 {
00148 data.f0 -= val.data.f0;
00149 data.f1 -= val.data.f1;
00150 data.f2 -= val.data.f2;
00151 data.f3 -= val.data.f3;
00152 return *this;
00153 }
00154 inline V4SF& operator*=(const V4SF& val)
00155 {
00156 data.f0 *= val.data.f0;
00157 data.f1 *= val.data.f1;
00158 data.f2 *= val.data.f2;
00159 data.f3 *= val.data.f3;
00160 return *this;
00161 }
00162 inline V4SF& operator/=(const V4SF& val)
00163 {
00164 data.f0 /= val.data.f0;
00165 data.f1 /= val.data.f1;
00166 data.f2 /= val.data.f2;
00167 data.f3 /= val.data.f3;
00168 return *this;
00169 }
00170
00171
00172 friend inline V4SF operator+(const V4SF& a, float b) { return V4SF(a.data.f0+b, a.data.f1+b, a.data.f2+b, a.data.f3+b); }
00173 friend inline V4SF operator-(const V4SF& a, float b) { return V4SF(a.data.f0-b, a.data.f1-b, a.data.f2-b, a.data.f3-b); }
00174 friend inline V4SF operator*(const V4SF& a, float b) { return V4SF(a.data.f0*b, a.data.f1*b, a.data.f2*b, a.data.f3*b); }
00175 friend inline V4SF operator/(const V4SF& a, float b) { return V4SF(a.data.f0/b, a.data.f1/b, a.data.f2/b, a.data.f3/b); }
00176
00177 inline V4SF& operator+=(float val)
00178 {
00179 data.f0 += val; data.f1 += val;
00180 data.f2 += val; data.f3 += val;
00181 return *this;
00182 }
00183 inline V4SF& operator-=(float val)
00184 {
00185 data.f0 -= val; data.f1 -= val;
00186 data.f2 -= val; data.f3 -= val;
00187 return *this;
00188 }
00189 inline V4SF& operator*=(float val)
00190 {
00191 data.f0 *= val; data.f1 *= val;
00192 data.f2 *= val; data.f3 *= val;
00193 return *this;
00194 }
00195 inline V4SF& operator/=(float val)
00196 {
00197 data.f0 /= val; data.f1 /= val;
00198 data.f2 /= val; data.f3 /= val;
00199 return *this;
00200 }
00201
00202 inline const float& operator[](int idx) const { return *(((float*)&data)+idx); }
00203 inline float& operator[](int idx) { return *(((float*)&data)+idx); }
00204
00205 friend inline V4SF recip(const V4SF& v) { return V4SF(1.0f/v[0], 1.0f/v[1], 1.0f/v[2], 1.0f/v[3]); }
00206
00207 friend inline V4SF sqrt(const V4SF& v) { return V4SF(sqrt(v[0]), sqrt(v[1]), sqrt(v[2]), sqrt(v[3])); }
00208 friend inline V4SF recipsqrt(const V4SF& v) { return V4SF(1.0f/sqrt(v[0]), 1.0f/sqrt(v[1]), 1.0f/sqrt(v[2]), 1.0f/sqrt(v[3])); }
00209 };
00210
00211 #endif //__sse__
00212
00213 namespace V4SFV
00214 {
00215
00216
00217 template<class A>
00218 class Expr
00219 {
00220 private:
00221 A mIter;
00222 public:
00223 Expr(const A& a)
00224 : mIter(a)
00225 { }
00226
00227 V4SF operator*() const
00228 { return *mIter; }
00229
00230 const V4SF& operator[](int i) const
00231 { return mIter[i]; }
00232
00233 void operator++()
00234 { ++mIter; }
00235 };
00236
00238
00240
00241
00242 struct ApAdd
00243 {
00244 static inline V4SF apply(const V4SF& a, const V4SF& b)
00245 { return a + b; }
00246 };
00247
00248
00249 struct ApDivide
00250 {
00251 static inline V4SF apply(const V4SF& a, const V4SF& b)
00252 { return a / b; }
00253 };
00254
00255
00256 struct ApSubtract
00257 {
00258 static inline V4SF apply(const V4SF& a, const V4SF& b)
00259 { return a - b; }
00260 };
00261
00262
00263 struct ApMultiply
00264 {
00265 static inline V4SF apply(const V4SF& a, const V4SF& b)
00266 { return a * b; }
00267 };
00268
00269
00270 struct ApAssign
00271 {
00272 static inline void apply(V4SF&a, const V4SF&b)
00273 { a = b; }
00274 };
00275
00276
00277 struct ApAddAssign
00278 {
00279 static inline void apply(V4SF&a, const V4SF&b)
00280 { a += b; }
00281 };
00282
00283
00284 struct ApSubtractAssign
00285 {
00286 static inline void apply(V4SF&a, const V4SF&b)
00287 { a -= b; }
00288 };
00289
00290
00291 struct ApMultiplyAssign
00292 {
00293 static inline void apply(V4SF&a, const V4SF&b)
00294 { a *= b; }
00295 };
00296
00297
00298 struct ApDivideAssign
00299 {
00300 static inline void apply(V4SF&a, const V4SF&b)
00301 { a /= b; }
00302 };
00303
00304
00305
00306
00307 template<class A, class B, class Op>
00308 class BinExprOp
00309 {
00310 private:
00311 A mIter1;
00312 B mIter2;
00313 public:
00314 BinExprOp(const A& a, const B& b)
00315 : mIter1(a), mIter2(b)
00316 { }
00317
00318 inline void operator++()
00319 { ++mIter1; ++mIter2; }
00320
00321 inline V4SF operator*() const
00322 { return Op::apply(*mIter1,*mIter2); }
00323
00324 inline V4SF operator[](int i) const
00325 { return Op::apply(mIter1[i], mIter2[i]); }
00326 };
00327
00328
00329 class ALIGNED16 FExprLiteral
00330 {
00331 private:
00332 V4SF mValue;
00333 public:
00334 FExprLiteral(float val) : mValue(val) {}
00335 inline void operator++() {}
00336 inline const V4SF& operator*() const { return mValue; }
00337 inline const V4SF& operator[](int idx) const { return mValue; }
00338 };
00339
00340
00341 template <int I, class A, class Op>
00342 struct AssignUnroll
00343 {
00344 static inline void loop(V4SF* a, V4SFV::Expr<A> expr)
00345 {
00346 Op::apply(*a,*expr);
00347 ++expr;
00348 AssignUnroll<I-1,A,Op>::loop(++a,expr);
00349 }
00350 };
00351
00352
00353 template <class A, class Op>
00354 struct AssignUnroll<0, A, Op>
00355 {
00356 static inline void loop(V4SF* a, V4SFV::Expr<A> expr)
00357 { Op::apply(*a,*expr); }
00358 };
00359
00360
00361 template <int Size, class A, class Op>
00362 struct AssignLoop
00363 {
00364 static inline void loop(V4SF* a, V4SFV::Expr<A> expr)
00365 {
00366 for(int i=0;i<Size;i++)
00367 {
00368 Op::apply(*a,*expr);
00369 ++a;
00370 ++expr;
00371 }
00372 }
00373 };
00374
00375 }
00376
00377
00378 template <int SizeInFloats, int Unroll=48>
00379 class V4SFVector
00380 {
00381 public:
00382 static const int SizeInF = SizeInFloats;
00383 static const int Spare = SizeInF%4;
00384 static const int SizeInV = (SizeInF/4) + (Spare ? 1 : 0);
00385 typedef V4SF* iterator;
00386 typedef const V4SF* const_iterator;
00387 typedef V4SF element;
00388 protected:
00389
00390 V4SF mData[SizeInV];
00391 public:
00392
00393 inline V4SFVector()
00394 {}
00395
00396 inline V4SFVector(const V4SFVector& rhs)
00397 {
00398 *this = rhs;
00399 }
00400
00401 inline V4SFVector(const float *array)
00402 {
00403 for(int i=0;i<SizeInFloats;i++)
00404 {
00405 ((float*)mData)[i] = array[i];
00406 }
00407 }
00408
00409 inline ~V4SFVector()
00410 {}
00411
00412 explicit inline V4SFVector(V4SFVector& b) : mData(b.mData)
00413 {}
00414
00415 inline explicit V4SFVector(float val)
00416 { *this = val; }
00417
00418 inline const_iterator begin() const { return &mData[0]; }
00419 inline const_iterator end() const { return &mData[SizeInV-1]; }
00420 inline iterator begin() { return mData; }
00421 inline iterator end() { return &mData[SizeInV-1]; }
00422
00423
00424 inline float& operator[](int idx)
00425 {
00426 assert((0 <= idx) && (idx<SizeInF+Spare));
00427 return ((float*)mData)[idx];
00428 }
00429 inline const float& operator[](int idx) const
00430 {
00431 assert((0 <= idx) && (idx<SizeInF+Spare));
00432 return ((float*)mData)[idx];
00433 }
00434 inline const V4SF& at(int idx)
00435 {
00436 assert((0 <= idx) && (idx<SizeInV));
00437 return mData[idx];
00438 }
00439 inline void at(int idx, const V4SF& v)
00440 {
00441 assert((0 <= idx) && (idx<SizeInV));
00442 mData[idx] = v;
00443 }
00444
00445 inline float interpolate(float idx)
00446 {
00447 int i = idx;
00448 assert((0 <= i) && (i<SizeInF+Spare));
00449
00450 float difference = ((float*)mData)[i+1] - ((float*)mData)[i];
00451 difference *= (idx - (float)i);
00452 return (((float*)mData)[i])+difference;
00453 }
00454
00455
00456 template<class A>
00457 inline V4SFVector& operator=(V4SFV::Expr<A> expr)
00458 {
00459 typedef typename Meta::If<(SizeInV>Unroll),V4SFV::AssignUnroll<SizeInV,A,V4SFV::ApAssign>,\
00460 V4SFV::AssignLoop<SizeInV,A,V4SFV::ApAssign> >::result AssignP;
00461 AssignP::loop(begin(),expr);
00462 return *this;
00463 }
00464 inline V4SFVector& operator=(float b)
00465 {
00466 V4SFV::FExprLiteral bLit(b);
00467 *this = V4SFV::Expr<V4SFV::FExprLiteral>(bLit);
00468 return *this;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 friend inline
00512 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,const_iterator,V4SFV::ApAdd> >
00513 operator+(const V4SFVector& a, const V4SFVector& b)
00514 {
00515 typedef V4SFV::BinExprOp<const_iterator,const_iterator,V4SFV::ApAdd> ExprT;
00516 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b.begin()));
00517 }
00518
00519 friend inline
00520 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,V4SFV::FExprLiteral,V4SFV::ApAdd> >
00521 operator+(const V4SFVector& a, float b)
00522 {
00523 typedef V4SFV::BinExprOp<const_iterator,V4SFV::FExprLiteral,V4SFV::ApAdd> ExprT;
00524 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b));
00525 }
00526
00527 template<class A> friend inline
00528 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,const_iterator,V4SFV::ApAdd> >
00529 operator+(const V4SFV::Expr<A>& a, const V4SFVector& b)
00530 {
00531 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,const_iterator,V4SFV::ApAdd> ExprT;
00532 return V4SFV::Expr<ExprT>(ExprT(a,b.begin()));
00533 }
00534
00535 template<class A> friend inline
00536 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::FExprLiteral,V4SFV::ApAdd> >
00537 operator+(const V4SFV::Expr<A>& a, float b)
00538 {
00539 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::FExprLiteral,V4SFV::ApAdd> ExprT;
00540 return V4SFV::Expr<ExprT>(ExprT(a,b));
00541 }
00542
00543 template<class A> friend inline
00544 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,V4SFV::Expr<A>,V4SFV::ApAdd> >
00545 operator+(const V4SFVector& a, const V4SFV::Expr<A>& b)
00546 {
00547 typedef V4SFV::BinExprOp<const_iterator,V4SFV::Expr<A>,V4SFV::ApAdd> ExprT;
00548 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b));
00549 }
00550
00551 template<class A, class B> friend inline
00552 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::Expr<B>,V4SFV::ApAdd> >
00553 operator+(const V4SFV::Expr<A>& a, const V4SFV::Expr<B>& b)
00554 {
00555 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::Expr<B>,V4SFV::ApAdd> ExprT;
00556 return V4SFV::Expr<ExprT>(ExprT(a,b));
00557 }
00558
00559
00560
00561 friend inline
00562 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,const_iterator,V4SFV::ApSubtract> >
00563 operator-(const V4SFVector& a, const V4SFVector& b)
00564 {
00565 typedef V4SFV::BinExprOp<const_iterator,const_iterator,V4SFV::ApSubtract> ExprT;
00566 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b.begin()));
00567 }
00568
00569 friend inline
00570 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,V4SFV::FExprLiteral,V4SFV::ApSubtract> >
00571 operator-(const V4SFVector& a, float b)
00572 {
00573 typedef V4SFV::BinExprOp<const_iterator,V4SFV::FExprLiteral,V4SFV::ApSubtract> ExprT;
00574 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b));
00575 }
00576
00577 template<class A> friend inline
00578 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,const_iterator,V4SFV::ApSubtract> >
00579 operator-(const V4SFV::Expr<A>& a, const V4SFVector& b)
00580 {
00581 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,const_iterator,V4SFV::ApSubtract> ExprT;
00582 return V4SFV::Expr<ExprT>(ExprT(a,b.begin()));
00583 }
00584
00585 template<class A> friend inline
00586 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::FExprLiteral,V4SFV::ApSubtract> >
00587 operator-(const V4SFV::Expr<A>& a, float b)
00588 {
00589 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::FExprLiteral,V4SFV::ApSubtract> ExprT;
00590 return V4SFV::Expr<ExprT>(ExprT(a,b));
00591 }
00592
00593 template<class A> friend inline
00594 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,V4SFV::Expr<A>,V4SFV::ApSubtract> >
00595 operator-(const V4SFVector& a, const V4SFV::Expr<A>& b)
00596 {
00597 typedef V4SFV::BinExprOp<const_iterator,V4SFV::Expr<A>,V4SFV::ApSubtract> ExprT;
00598 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b));
00599 }
00600
00601 template<class A, class B> friend inline
00602 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::Expr<B>,V4SFV::ApSubtract> >
00603 operator-(const V4SFV::Expr<A>& a, const V4SFV::Expr<B>& b)
00604 {
00605 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::Expr<B>,V4SFV::ApSubtract> ExprT;
00606 return V4SFV::Expr<ExprT>(ExprT(a,b));
00607 }
00608
00609
00610
00611 friend inline
00612 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,const_iterator,V4SFV::ApDivide> >
00613 operator/(const V4SFVector& a, const V4SFVector& b)
00614 {
00615 typedef V4SFV::BinExprOp<const_iterator,const_iterator,V4SFV::ApDivide> ExprT;
00616 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b.begin()));
00617 }
00618
00619 friend inline
00620 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,V4SFV::FExprLiteral,V4SFV::ApDivide> >
00621 operator/(const V4SFVector& a, float b)
00622 {
00623 typedef V4SFV::BinExprOp<const_iterator,V4SFV::FExprLiteral,V4SFV::ApDivide> ExprT;
00624 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b));
00625 }
00626
00627 template<class A> friend inline
00628 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,const_iterator,V4SFV::ApDivide> >
00629 operator/(const V4SFV::Expr<A>& a, const V4SFVector& b)
00630 {
00631 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,const_iterator,V4SFV::ApDivide> ExprT;
00632 return V4SFV::Expr<ExprT>(ExprT(a,b.begin()));
00633 }
00634
00635 template<class A> friend inline
00636 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::FExprLiteral,V4SFV::ApDivide> >
00637 operator/(const V4SFV::Expr<A>& a, float b)
00638 {
00639 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::FExprLiteral,V4SFV::ApDivide> ExprT;
00640 return V4SFV::Expr<ExprT>(ExprT(a,b));
00641 }
00642
00643 template<class A> friend inline
00644 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,V4SFV::Expr<A>,V4SFV::ApDivide> >
00645 operator/(const V4SFVector& a, const V4SFV::Expr<A>& b)
00646 {
00647 typedef V4SFV::BinExprOp<const_iterator,V4SFV::Expr<A>,V4SFV::ApDivide> ExprT;
00648 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b));
00649 }
00650
00651 template<class A, class B> friend inline
00652 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::Expr<B>,V4SFV::ApDivide> >
00653 operator/(const V4SFV::Expr<A>& a, const V4SFV::Expr<B>& b)
00654 {
00655 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::Expr<B>,V4SFV::ApDivide> ExprT;
00656 return V4SFV::Expr<ExprT>(ExprT(a,b));
00657 }
00658
00659
00660
00661 friend inline
00662 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,const_iterator,V4SFV::ApMultiply> >
00663 operator*(const V4SFVector& a, const V4SFVector& b)
00664 {
00665 typedef V4SFV::BinExprOp<const_iterator,const_iterator,V4SFV::ApMultiply> ExprT;
00666 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b.begin()));
00667 }
00668
00669 friend inline
00670 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,V4SFV::FExprLiteral,V4SFV::ApMultiply> >
00671 operator*(const V4SFVector& a, float b)
00672 {
00673 typedef V4SFV::BinExprOp<const_iterator,V4SFV::FExprLiteral,V4SFV::ApMultiply> ExprT;
00674 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b));
00675 }
00676
00677 template<class A> friend inline
00678 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,const_iterator,V4SFV::ApMultiply> >
00679 operator*(const V4SFV::Expr<A>& a, const V4SFVector& b)
00680 {
00681 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,const_iterator,V4SFV::ApMultiply> ExprT;
00682 return V4SFV::Expr<ExprT>(ExprT(a,b.begin()));
00683 }
00684
00685 template<class A> friend inline
00686 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::FExprLiteral,V4SFV::ApMultiply> >
00687 operator*(const V4SFV::Expr<A>& a, float b)
00688 {
00689 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::FExprLiteral,V4SFV::ApMultiply> ExprT;
00690 return V4SFV::Expr<ExprT>(ExprT(a,b));
00691 }
00692
00693 template<class A> friend inline
00694 V4SFV::Expr<V4SFV::BinExprOp<const_iterator,V4SFV::Expr<A>,V4SFV::ApMultiply> >
00695 operator*(const V4SFVector& a, const V4SFV::Expr<A>& b)
00696 {
00697 typedef V4SFV::BinExprOp<const_iterator,V4SFV::Expr<A>,V4SFV::ApMultiply> ExprT;
00698 return V4SFV::Expr<ExprT>(ExprT(a.begin(),b));
00699 }
00700
00701 template<class A, class B> friend inline
00702 V4SFV::Expr<V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::Expr<B>,V4SFV::ApMultiply> >
00703 operator*(const V4SFV::Expr<A>& a, const V4SFV::Expr<B>& b)
00704 {
00705 typedef V4SFV::BinExprOp<V4SFV::Expr<A>,V4SFV::Expr<B>,V4SFV::ApMultiply> ExprT;
00706 return V4SFV::Expr<ExprT>(ExprT(a,b));
00707 }
00708 };
00709
00710 }
00711
00712 #endif //__LDK_SIMD_H__