00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef _MSC_VER
00024 # pragma once
00025 # pragma warning( push )
00026 # pragma warning( disable : 4324 4702 4714 )
00027 #endif // _MSC_VER
00028
00029 namespace exmat {
00030
00031
00032 #if (HAVE_TT_PARAMETER)
00033 template<class Exp, class newL, class newR> struct RefillBinExp;
00034 template<template<class,class,class> class Exp, class L, class R, class SpecTag, class newL, class newR>
00035 struct RefillBinExp< exmat::SIMD::SSCon<Exp<L,R,SpecTag> >, newL, newR> {
00036 typedef Exp<newL, newR, SpecTag> RET;
00037 };
00038 #endif // HAVE_TT_PARAMETER
00039
00040
00041 #if HAVE_PARTIAL_SPECIALIZATION && EXMAT_ENABLE_SIMD
00042 using namespace exmat::SIMD;
00043
00045
00046 template<typename T, int ROWS, int COLS, class Left, class Right>
00047 struct GetBinExpTmpType<T,ROWS,COLS,SSCon<Left>,SSCon<Right> > {
00048 typedef Mat<SSCon<SCon<ROWS,COLS,T> >, EmptyErrorChecker> RET;
00049 };
00050 template<typename T, int ROWS, int COLS, class Left, class Right>
00051 struct GetBinExpTmpType<T,ROWS,COLS,SSCon<Left>,ScalarCon<Right> > {
00052 typedef Mat<SSCon<SCon<ROWS,COLS,T> >, EmptyErrorChecker> RET;
00053 };
00054 template<typename T, int ROWS, int COLS, class Left, class Right>
00055 struct GetBinExpTmpType<T,ROWS,COLS,ScalarCon<Left>,SSCon<Right> > {
00056 typedef Mat<SSCon<SCon<ROWS,COLS,T> >, EmptyErrorChecker> RET;
00057 };
00059
00060
00061
00062
00063
00064
00065 #define COMMON_SIMDEXP_TYPEDEFS(LOrR) \
00066 typedef SSCon<self_type> rep_type; \
00067 typedef const ExpRow<self_type> const_row_type; \
00068 typedef typename super_type::index_type index_type; \
00069 typedef typename LOrR::SIMD_unit_type SIMD_unit_type; \
00070 typedef typename super_type::value_type value_type; \
00071 enum { ROWS = super_type::ROWS, \
00072 COLS = super_type::COLS }; \
00073 typedef Left left_type; \
00074 typedef Right right_type; \
00075 using super_type::leftOp; \
00076 using super_type::rightOp; \
00077 typedef typename GetBinExpTmpType<value_type,ROWS,COLS,Left,Right>::RET temp_type;
00078
00079
00081
00082
00083
00084 template<class Left_, class Right_>
00085 class AddExp<SSCon<Left_>, SSCon<Right_> > :
00086 public AddExp<Left_, Right_>,
00087 public SIMDTag
00088 {
00089 typedef SSCon<Left_> Left;
00090 typedef SSCon<Right_> Right;
00091 typedef AddExp<Left_, Right_> super_type;
00092 typedef AddExp<Left, Right> self_type;
00093 public:
00094
00095 COMMON_SIMDEXP_TYPEDEFS(Left);
00096
00097 EXMAT_INLINE2 AddExp(const self_type& self)
00098 : super_type(self) {}
00099 EXMAT_INLINE2 AddExp(const Left& l, const Right& r)
00100 : super_type(l, r) {}
00101
00102
00103
00104 EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00105 return Intrinsics::add_p(leftOp.getUnitAt(i), rightOp.getUnitAt(i));
00106 }
00107 };
00108
00110 template<class Left_, typename Right_>
00111 class AddExp<SSCon<Left_>, ScalarCon<Right_> > :
00112 public AddExp<Left_, ScalarCon<Right_> >,
00113 public SIMDTag
00114 {
00115 typedef SSCon<Left_> Left;
00116 typedef ScalarCon<Right_> Right;
00117 typedef AddExp<Left_, Right> super_type;
00118 typedef AddExp<Left, Right> self_type;
00119 public:
00120
00121 COMMON_SIMDEXP_TYPEDEFS(Left);
00122
00123 EXMAT_INLINE2 AddExp(const self_type& self)
00124 : super_type(self), unitData(self.unitData)
00125 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00126 EXMAT_INLINE2 AddExp(const Left& l, const Right& r)
00127 : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&r.scalar))
00128 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00129
00130
00131
00132 EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00133 return Intrinsics::add_p(leftOp.getUnitAt(i), unitData);
00134 }
00135 protected:
00136 SIMD_unit_type unitData;
00137 };
00138
00140 template<class Left_, typename Right_>
00141 class AddExp<ScalarCon<Left_>, SSCon<Right_> > :
00142 public AddExp<ScalarCon<Left_>, Right_>,
00143 public SIMDTag
00144 {
00145 typedef ScalarCon<Left_> Left;
00146 typedef SSCon<Right_> Right;
00147 typedef AddExp<Left, Right_> super_type;
00148 typedef AddExp<Left, Right> self_type;
00149 public:
00150
00151 COMMON_SIMDEXP_TYPEDEFS(Right);
00152
00153 EXMAT_INLINE2 AddExp(const self_type& self)
00154 : super_type(self), unitData(self.unitData)
00155 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00156 EXMAT_INLINE2 AddExp(const Left& l, const Right& r)
00157 : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&l.scalar))
00158 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00159
00160
00161
00162 EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00163 return Intrinsics::add_p(unitData, rightOp.getUnitAt(i));
00164 }
00165 protected:
00166 SIMD_unit_type unitData;
00167 };
00169
00170
00172
00173 template<class Left_, class Right_>
00174 class SubExp<SSCon<Left_>, SSCon<Right_> > :
00175 public SubExp<Left_, Right_>,
00176 public SIMDTag
00177 {
00178 typedef SSCon<Left_> Left;
00179 typedef SSCon<Right_> Right;
00180 typedef SubExp<Left_, Right_> super_type;
00181 typedef SubExp<Left, Right> self_type;
00182 public:
00183
00184 COMMON_SIMDEXP_TYPEDEFS(Left);
00185
00186 EXMAT_INLINE2 SubExp(const self_type& self)
00187 : super_type(self) {}
00188 EXMAT_INLINE2 SubExp(const Left& l, const Right& r)
00189 : super_type(l, r) {}
00190
00191
00192
00193 EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00194 return Intrinsics::sub_p(leftOp.getUnitAt(i), rightOp.getUnitAt(i));
00195 }
00196 };
00197
00199 template<class Left_, typename Right_>
00200 class SubExp<SSCon<Left_>, ScalarCon<Right_> > :
00201 public SubExp<Left_, ScalarCon<Right_> >,
00202 public SIMDTag
00203 {
00204 typedef SSCon<Left_> Left;
00205 typedef ScalarCon<Right_> Right;
00206 typedef SubExp<Left_, Right> super_type;
00207 typedef SubExp<Left, Right> self_type;
00208 public:
00209
00210 COMMON_SIMDEXP_TYPEDEFS(Left);
00211
00212 EXMAT_INLINE2 SubExp(const self_type& self)
00213 : super_type(self), unitData(self.unitData)
00214 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00215 EXMAT_INLINE2 SubExp(const Left& l, const Right& r)
00216 : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&r.scalar))
00217 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00218
00219
00220
00221 EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00222 return Intrinsics::sub_p(leftOp.getUnitAt(i), unitData);
00223 }
00224 protected:
00225 SIMD_unit_type unitData;
00226 };
00227
00229 template<class Left_, typename Right_>
00230 class SubExp<ScalarCon<Left_>, SSCon<Right_> > :
00231 public SubExp<ScalarCon<Left_>, Right_>,
00232 public SIMDTag
00233 {
00234 typedef ScalarCon<Left_> Left;
00235 typedef SSCon<Right_> Right;
00236 typedef SubExp<Left, Right_> super_type;
00237 typedef SubExp<Left, Right> self_type;
00238 public:
00239
00240 COMMON_SIMDEXP_TYPEDEFS(Right);
00241
00242 EXMAT_INLINE2 SubExp(const self_type& self)
00243 : super_type(self), unitData(self.unitData)
00244 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00245 EXMAT_INLINE2 SubExp(const Left& l, const Right& r)
00246 : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&l.scalar))
00247 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00248
00249
00250
00251 EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00252 return Intrinsics::sub_p(unitData, rightOp.getUnitAt(i));
00253 }
00254 protected:
00255 SIMD_unit_type unitData;
00256 };
00258
00259
00261
00262 template<class Left_, class Right_>
00263 class MulExp<SSCon<Left_>, SSCon<Right_> > :
00264 public MulExp<Left_, Right_>,
00265 public SIMDTag
00266 {
00267 typedef SSCon<Left_> Left;
00268 typedef SSCon<Right_> Right;
00269 typedef MulExp<Left_, Right_> super_type;
00270 typedef MulExp<Left, Right> self_type;
00271 public:
00272
00273 COMMON_SIMDEXP_TYPEDEFS(Left);
00274
00275 EXMAT_INLINE2 MulExp(const self_type& self)
00276 : super_type(self) {}
00277 EXMAT_INLINE2 MulExp(const Left& l, const Right& r)
00278 : super_type(l, r) {}
00279
00281
00282 EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00283 THROWMSG(false, InternalErrMsg, __FILE__);
00284 return leftOp.getUnitAt(i);
00285 }
00287 };
00288
00290 template<class Left_, class Right_>
00291 class ScalarMulExp<SSCon<Left_>, ScalarCon<Right_> > :
00292 public ScalarMulExp<Left_, ScalarCon<Right_> >,
00293 public SIMDTag
00294 {
00295 typedef SSCon<Left_> Left;
00296 typedef ScalarCon<Right_> Right;
00297 typedef ScalarMulExp<Left_, Right> super_type;
00298 typedef ScalarMulExp<Left, Right> self_type;
00299 public:
00300
00301 COMMON_SIMDEXP_TYPEDEFS(Left);
00302
00303 EXMAT_INLINE2 ScalarMulExp(const self_type& self)
00304 : super_type(self), unitData(self.unitData)
00305 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00306 EXMAT_INLINE2 ScalarMulExp(const Left& l, const Right& r)
00307 : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&r.scalar))
00308 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00309
00310
00311
00312 EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00313 return Intrinsics::mul_p(leftOp.getUnitAt(i), unitData);
00314 }
00315 protected:
00316 SIMD_unit_type unitData;
00317 };
00318
00320 template<class Left_, class Right_>
00321 class ScalarMulExp<ScalarCon<Left_>, SSCon<Right_> > :
00322 public ScalarMulExp<ScalarCon<Left_>, Right_>,
00323 public SIMDTag
00324 {
00325 typedef ScalarCon<Left_> Left;
00326 typedef SSCon<Right_> Right;
00327 typedef ScalarMulExp<Left, Right_> super_type;
00328 typedef ScalarMulExp<Left, Right> self_type;
00329 public:
00330
00331 COMMON_SIMDEXP_TYPEDEFS(Right);
00332
00333 EXMAT_INLINE2 ScalarMulExp(const self_type& self)
00334 : super_type(self), unitData(self.unitData)
00335 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00336 EXMAT_INLINE2 ScalarMulExp(const Left& l, const Right& r)
00337 : super_type(l, r), unitData(SIMD::Intrinsics::load1_p(&l.scalar))
00338 { ALIGNMENT_CHECK(sizeof(SIMD_unit_type)); }
00339
00340
00341
00342 EXMAT_INLINE2 SIMD_unit_type getUnitAt(const index_type i) const {
00343 return Intrinsics::mul_p(unitData, rightOp.getUnitAt(i));
00344 }
00345 protected:
00346 SIMD_unit_type unitData;
00347 };
00349
00350
00351 #undef COMMON_SIMDEXP_TYPEDEFS
00352
00353
00354 #endif // HAVE_PARTIAL_SPECIALIZATION
00355
00356
00357 };
00358
00359 #ifdef _MSC_VER
00360 # pragma warning( pop )
00361 #endif // _MSC_VER