00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__VECTOR_ALIGNED__HPP
00014 #define __MMX__VECTOR_ALIGNED__HPP
00015 #include <basix/int.hpp>
00016 #include <numerix/simd.hpp>
00017
00018 namespace mmx {
00019
00020
00021
00022
00023
00024 template<typename V, typename W>
00025 struct vector_assume_aligned: public V {
00026
00027
00028
00029 typedef vector_assume_aligned<typename V::Naive,
00030 typename W::Naive> Naive;
00031 typedef vector_assume_aligned<typename V::Aligned,
00032 typename W::Aligned> Aligned;
00033 typedef vector_assume_aligned<typename V::No_simd,
00034 typename W::No_simd> No_simd;
00035 typedef vector_assume_aligned<typename V::No_thread,
00036 typename W::No_thread> No_thread;
00037 };
00038
00039 template<typename F, typename Z, typename V, typename W>
00040 struct implementation<F,Z,vector_assume_aligned<V,W> >:
00041 public implementation<F,Z,V> {};
00042
00043 template<typename V, typename W>
00044 struct vector_aligned: public V {
00045
00046 typedef vector_aligned <typename V::Naive,
00047 typename W::Naive> Naive;
00048 typedef vector_assume_aligned<typename V::Aligned,
00049 typename W::Aligned> Aligned;
00050 typedef vector_aligned <typename V::No_simd,
00051 typename W::No_simd> No_simd;
00052 typedef vector_aligned <typename V::No_thread,
00053 typename W::No_thread> No_thread;
00054 };
00055
00056 template<typename F, typename Z, typename V, typename W>
00057 struct implementation<F,Z,vector_aligned<V,W> >:
00058 public implementation<F,Z,V> {};
00059
00060
00061
00062
00063
00064 template<typename V, typename W,
00065 typename Op, typename T>
00066 struct vec_nullary_aligned_helper {
00067 typedef implementation<vector_abstractions,V> Vec;
00068 static inline void op (T* dest, nat n) {
00069 Vec::template vec_nullary<Op,T> (dest, n); } };
00070
00071 template<typename V, typename W,
00072 typename Op, typename T, typename C>
00073 struct vec_unary_aligned_helper {
00074 typedef implementation<vector_abstractions,V> Vec;
00075 static inline void op (T* dest, const C* s, nat n) {
00076 Vec::template vec_unary<Op,T,C> (dest, s, n); } };
00077
00078 template<typename V, typename W,
00079 typename Op, typename T, typename C1, typename C2>
00080 struct vec_binary_aligned_helper {
00081 typedef implementation<vector_abstractions,V> Vec;
00082 static inline void op (T* dest, const C1* s1, const C2* s2, nat n) {
00083 Vec::template vec_binary<Op,T,C1,C2> (dest, s1, s2, n); } };
00084
00085 template<typename V, typename W,
00086 typename Op, typename T, typename X>
00087 struct vec_unary_scalar_aligned_helper {
00088 typedef implementation<vector_abstractions,V> Vec;
00089 static inline void op (T* dest, const X& x, nat n) {
00090 Vec::template vec_unary_scalar<Op,T,X> (dest, x, n); } };
00091
00092 template<typename V, typename W,
00093 typename Op, typename T, typename C, typename X>
00094 struct vec_binary_scalar_aligned_helper {
00095 typedef implementation<vector_abstractions,V> Vec;
00096 static inline void op (T* dest, const C* s, const X& x, nat n) {
00097 Vec::template vec_binary_scalar<Op,T,C,X> (dest, s, x, n); } };
00098
00099 template<typename V, typename W,
00100 typename Op, typename C>
00101 struct vec_unary_test_aligned_helper {
00102 typedef implementation<vector_abstractions,V> Vec;
00103 static inline bool op (const C* s, nat n) {
00104 return Vec::template vec_unary_test (s, n); } };
00105
00106 template<typename V, typename W,
00107 typename Op, typename C1, typename C2>
00108 struct vec_binary_test_aligned_helper {
00109 typedef implementation<vector_abstractions,V> Vec;
00110 static inline bool op (const C1* s1, const C2* s2, nat n) {
00111 return Vec::template vec_binary_test<Op,C1,C2> (s1, s2, n); } };
00112
00113 template<typename V, typename W,
00114 typename Op, typename C, typename X>
00115 struct vec_binary_test_scalar_aligned_helper {
00116 typedef implementation<vector_abstractions,V> Vec;
00117 static inline bool op (const C* s, const X& x, nat n) {
00118 return Vec::template vec_binary_test_scalar<Op,C,X> (s, x, n); } };
00119
00120 template<typename V, typename W,
00121 typename Op, typename C>
00122 struct vec_unary_big_aligned_helper {
00123 typedef implementation<vector_abstractions,V> Vec;
00124 static inline C op (const C* s, nat n) {
00125 return Vec::template vec_unary_big<Op,C> (s, n); }
00126 static inline C op (const C* s, nat n, const format<C>& fm) {
00127 return Vec::template vec_unary_big<Op,C> (s, n, fm); } };
00128
00129 template<typename V, typename W,
00130 typename Op, typename C1, typename C2>
00131 struct vec_binary_big_aligned_helper {
00132 typedef implementation<vector_abstractions,V> Vec;
00133 static inline C1 op (const C1* s1, const C2* s2, nat n) {
00134 return Vec::template vec_binary_big<Op,C1,C2> (s1, s2, n); }
00135 static inline C1 op (const C1* s1, const C2* s2, nat n,
00136 const format<C1>& fm1, const format<C2>& fm2) {
00137 return Vec::template vec_binary_big<Op,C1,C2> (s1, s2, n, fm1, fm2); } };
00138
00139
00140
00141
00142
00143
00144
00145 template<typename C>
00146 struct mask_helper {
00147 static const nat m = Simd_size (C);
00148 static const nat log_m = int_bitsize_helper<nat, m>::value - 1;
00149 static const nat hi_mask_m = ((nat) -1) << log_m;
00150 static const nat lo_mask_m = m - 1;
00151 static const intptr_t len = m * sizeof (C);
00152 static const intptr_t log_len= int_bitsize_helper<nat, len>::value - 1;
00153 static const intptr_t lo_mask_len= len - 1;
00154 };
00155
00156
00157
00158
00159
00160 template<typename Z, typename V, typename W>
00161 struct implementation<vector_allocate,Z,vector_assume_aligned<V,W> >:
00162 public implementation<vector_defaults,Z>
00163 {
00164
00165 template<typename C> static inline nat
00166 vec_aligned_size (nat n) {
00167 VERIFY (mask_helper<C>::m == (((nat) 1) << mask_helper<C>::log_m),
00168 "simd size must be a power of two");
00169 return (n + mask_helper<C>::m - 1) & mask_helper<C>::hi_mask_m;
00170 }
00171
00172 template<typename C> static inline nat
00173 vec_floor_aligned_size (nat n) {
00174 return n & mask_helper<C>::hi_mask_m;
00175 }
00176
00177 template<typename C> static inline bool
00178 vec_is_aligned_size (nat n) {
00179 return (n & mask_helper<C>::lo_mask_m) == 0; }
00180
00181 template<typename C> static inline bool
00182 vec_is_aligned (const C* s) {
00183 return (mask_helper<C>::len == 16) ?
00184 (((intptr_t) s) & mask_helper<C>::lo_mask_len) == 0 : false; }
00185
00186 template<typename C> static inline intptr_t
00187 vec_ceil_shift (const C* s) {
00188 if (mask_helper<C>::len == 16) {
00189 intptr_t r= (intptr_t) s & mask_helper<C>::lo_mask_len;
00190 return (r != 0) ? mask_helper<C>::len - r : r;
00191 }
00192 return 0; }
00193
00194 };
00195
00196 template<typename Z, typename V, typename W>
00197 struct implementation<vector_abstractions,Z,vector_assume_aligned<V,W> >:
00198 public implementation<vector_allocate,Z>
00199 {
00200 typedef implementation<vector_allocate,Z> Vec;
00201
00202 template<typename Op, typename T> static inline void
00203 vec_nullary (T* dest, nat n) {
00204 VERIFY (Vec::vec_is_aligned (dest), "address must be aligned");
00205 VERIFY (Vec::template vec_is_aligned_size<T> (n), "size must be aligned");
00206 vec_nullary_aligned_helper<V,W,Op,T>::op (dest, n); }
00207
00208 template<typename Op, typename T, typename C> static inline void
00209 vec_unary (T* dest, const C* s, nat n) {
00210 VERIFY (Vec::vec_is_aligned (dest), "address must be aligned");
00211 VERIFY (Vec::vec_is_aligned (s) , "address must be aligned");
00212 VERIFY (Vec::template vec_is_aligned_size<T> (n), "size must be aligned");
00213 VERIFY (Vec::template vec_is_aligned_size<C> (n), "size must be aligned");
00214 vec_unary_aligned_helper<V,W,Op,T,C>::op (dest, s, n); }
00215
00216 template<typename Op, typename T, typename C1, typename C2> static inline void
00217 vec_binary (T* dest, const C1* s1, const C2* s2, nat n) {
00218 VERIFY (Vec::vec_is_aligned (dest) , "address must be aligned");
00219 VERIFY (Vec::vec_is_aligned (s1) , "address must be aligned");
00220 VERIFY (Vec::vec_is_aligned (s2) , "address must be aligned");
00221 VERIFY (Vec::template vec_is_aligned_size<T> (n), "size must be aligned");
00222 VERIFY (Vec::template vec_is_aligned_size<C1>(n), "size must be aligned");
00223 VERIFY (Vec::template vec_is_aligned_size<C2>(n), "size must be aligned");
00224 vec_binary_aligned_helper<V,W,Op,T,C1,C2>::op (dest, s1, s2, n); }
00225
00226 template<typename Op, typename T, typename X> static inline void
00227 vec_unary_scalar (T* dest, const X& x, nat n) {
00228 VERIFY (Vec::vec_is_aligned (dest), "address must be aligned");
00229 VERIFY (Vec::template vec_is_aligned_size<T> (n), "size must be aligned");
00230 vec_unary_scalar_aligned_helper<V,W,Op,T,X>::op (dest, x, n); }
00231
00232 template<typename Op, typename T, typename C, typename X> static inline void
00233 vec_binary_scalar (T* dest, const C* s, const X& x, nat n) {
00234 VERIFY (Vec::vec_is_aligned (dest), "address must be aligned");
00235 VERIFY (Vec::vec_is_aligned (s) , "address must be aligned");
00236 VERIFY (Vec::template vec_is_aligned_size<T> (n), "size must be aligned");
00237 VERIFY (Vec::template vec_is_aligned_size<C> (n), "size must be aligned");
00238 vec_binary_scalar_aligned_helper<V,W,Op,T,C,X>::op (dest, s, x, n); }
00239
00240 template<typename Op, typename C> static inline bool
00241 vec_unary_test (const C* s, nat n) {
00242 VERIFY (Vec::vec_is_aligned (s), "address must be aligned");
00243 VERIFY (Vec::template vec_is_aligned_size<C> (n), "size must be aligned");
00244 return vec_unary_test_aligned_helper<V,W,Op,C>::op (s, n); }
00245
00246 template<typename Op, typename C1, typename C2> static inline bool
00247 vec_binary_test (const C1* s1, const C2* s2, nat n) {
00248 VERIFY (Vec::vec_is_aligned (s1), "address must be aligned");
00249 VERIFY (Vec::vec_is_aligned (s2), "address must be aligned");
00250 VERIFY (Vec::template vec_is_aligned_size<C1> (n), "size must be aligned");
00251 VERIFY (Vec::template vec_is_aligned_size<C2> (n), "size must be aligned");
00252 return vec_binary_test_aligned_helper<V,W,Op,C1,C2>::op (s1, s2, n); }
00253
00254 template<typename Op, typename C, typename X> static inline bool
00255 vec_binary_test_scalar (const C* s, const X& x, nat n) {
00256 VERIFY (Vec::vec_is_aligned (s), "address must be aligned");
00257 VERIFY (Vec::template vec_is_aligned_size<C> (n), "size must be aligned");
00258 return vec_binary_test_scalar_aligned_helper<V,W,Op,C,X>::op (s, x, n); }
00259
00260 template<typename Op, typename C> static inline C
00261 vec_unary_big (const C* s, nat n) {
00262 VERIFY (Vec::vec_is_aligned (s), "address must be aligned");
00263 VERIFY (Vec::template vec_is_aligned_size<C> (n), "size must be aligned");
00264 return vec_unary_big_aligned_helper<V,W,Op,C>::op (s, n); }
00265
00266 template<typename Op, typename C> static inline C
00267 vec_unary_big (const C* s, nat n, const format<C>& fm) {
00268 VERIFY (Vec::vec_is_aligned (s), "address must be aligned");
00269 VERIFY (Vec::template vec_is_aligned_size<C> (n), "size must be aligned");
00270 return vec_unary_big_aligned_helper<V,W,Op,C>::op (s, n, fm); }
00271
00272 template<typename Op, typename C> static inline C
00273 vec_unary_big_dicho (const C* s, nat n) {
00274 return vec_unary_big<Op, C> (s, n); }
00275
00276 template<typename Op, typename C> static inline C
00277 vec_unary_big_dicho (const C* s, nat n, const format<C>& fm) {
00278 return vec_unary_big<Op, C> (s, n, fm); }
00279
00280 template<typename Op, typename C1, typename C2> static inline C1
00281 vec_binary_big (const C1* s1, const C2* s2, nat n) {
00282 VERIFY (Vec::vec_is_aligned (s1), "address must be aligned");
00283 VERIFY (Vec::vec_is_aligned (s2), "address must be aligned");
00284 VERIFY (Vec::template vec_is_aligned_size<C1> (n), "size must be aligned");
00285 VERIFY (Vec::template vec_is_aligned_size<C2> (n), "size must be aligned");
00286 return vec_binary_big_aligned_helper<V,W,Op,C1,C2>::op (s1, s2, n); }
00287
00288 template<typename Op, typename C1, typename C2> static inline C1
00289 vec_binary_big (const C1* s1, const C2* s2, nat n,
00290 const format<C1>& fm1, const format<C2>& fm2) {
00291 VERIFY (Vec::vec_is_aligned (s1), "address must be aligned");
00292 VERIFY (Vec::vec_is_aligned (s2), "address must be aligned");
00293 VERIFY (Vec::template vec_is_aligned_size<C1> (n), "size must be aligned");
00294 VERIFY (Vec::template vec_is_aligned_size<C2> (n), "size must be aligned");
00295 return
00296 vec_binary_big_aligned_helper<V,W,Op,C1,C2>::op (s1, s2, n, fm1, fm2); }
00297
00298 };
00299
00300
00301
00302
00303
00304 template<typename Z, typename V, typename W>
00305 struct implementation<vector_allocate,Z,vector_aligned<V,W> >:
00306 public implementation<vector_allocate,vector_assume_aligned<V,W> >
00307 {};
00308
00309 template<typename Z, typename V, typename W>
00310 struct implementation<vector_abstractions,Z,vector_aligned<V,W> >:
00311 public implementation<vector_abstractions,V>
00312 {
00313 typedef vector_assume_aligned<V,W> Aligned;
00314 typedef implementation<vector_abstractions,V> NVec;
00315 typedef implementation<vector_abstractions,Aligned> AVec;
00316
00317 template<typename C> static inline nat
00318 vec_aligned_size (nat n) {
00319 return AVec::template vec_aligned_size<C> (n);
00320 }
00321
00322 template<typename Op, typename T>
00323 static inline void
00324 vec_nullary (T* dest, nat n) {
00325 if (mask_helper<T>::len == 16) {
00326 nat r= min ((nat) AVec::vec_ceil_shift (dest), n);
00327 NVec::template vec_nullary<Op,T> (dest, r);
00328 dest += r; n -= r;
00329 r= AVec::template vec_floor_aligned_size<T> (n);
00330 AVec::template vec_nullary<Op,T> (dest, r);
00331 dest += r; n -= r;
00332 }
00333 NVec::template vec_nullary<Op,T> (dest, n);
00334 }
00335
00336 template<typename Op, typename T, typename C> static inline void
00337 vec_unary (T* dest, const C* s, nat n) {
00338 if (mask_helper<T>::len == 16 &&
00339 mask_helper<C>::len == 16) {
00340 nat rd= AVec::vec_ceil_shift (dest);
00341 nat rs= AVec::vec_ceil_shift (s);
00342 if (rd == rs) {
00343 nat r= min (rd, n);
00344 NVec::template vec_unary<Op,T,C> (dest, s, r);
00345 dest += r; s += r; n -= r;
00346 rd= AVec::template vec_floor_aligned_size<T> (n);
00347 rs= AVec::template vec_floor_aligned_size<C> (n);
00348 r= min (rd, rs);
00349 AVec::template vec_unary<Op,T,C> (dest, s, r);
00350 dest += r; s += r; n -= r;
00351 }
00352 }
00353 NVec::template vec_unary<Op,T,C> (dest, s, n);
00354 }
00355
00356 template<typename Op, typename T, typename C1, typename C2> static inline void
00357 vec_binary (T* dest, const C1* s1, const C2* s2, nat n) {
00358 if (mask_helper<T >::len == 16 &&
00359 mask_helper<C1>::len == 16 &&
00360 mask_helper<C2>::len == 16) {
00361 nat rd = AVec::vec_ceil_shift (dest);
00362 nat rs1= AVec::vec_ceil_shift (s1);
00363 nat rs2= AVec::vec_ceil_shift (s2);
00364 if (rd == rs1 && rd == rs2) {
00365 nat r= min (rd, n);
00366 NVec::template vec_binary<Op,T,C1,C2> (dest, s1, s2, r);
00367 dest += r; s1 += r; s2 += r; n -= r;
00368 rd = AVec::template vec_floor_aligned_size<T> (n);
00369 rs1= AVec::template vec_floor_aligned_size<C1> (n);
00370 rs2= AVec::template vec_floor_aligned_size<C2> (n);
00371 r= min (min (rd, rs1), rs2);
00372 AVec::template vec_binary<Op,T,C1,C2> (dest, s1, s2, r);
00373 dest += r; s1 += r; s2 += r; n -= r;
00374 }
00375 }
00376 NVec::template vec_binary<Op,T,C1,C2> (dest, s1, s2, n);
00377 }
00378
00379 template<typename Op, typename T, typename X> static inline void
00380 vec_unary_scalar (T* dest, const X& x, nat n) {
00381 if (mask_helper<T>::len == 16) {
00382 nat r= min ((nat) AVec::vec_ceil_shift (dest), n);
00383 NVec::template vec_unary_scalar<Op,T,X> (dest, x, r);
00384 dest += r; n -= r;
00385 r= AVec::template vec_floor_aligned_size<T> (n);
00386 AVec::template vec_unary_scalar<Op,T,X> (dest, x, r);
00387 dest += r; n -= r;
00388 }
00389 NVec::template vec_unary_scalar<Op,T,X> (dest, x, n);
00390 }
00391
00392 template<typename Op, typename T, typename C, typename X> static inline void
00393 vec_binary_scalar (T* dest, const C* s, const X& x, nat n) {
00394 if (mask_helper<T>::len == 16 &&
00395 mask_helper<C>::len == 16) {
00396 nat rd= AVec::vec_ceil_shift (dest);
00397 nat rs= AVec::vec_ceil_shift (s);
00398 if (rd == rs) {
00399 nat r= min (rd, n);
00400 NVec::template vec_binary_scalar<Op,T,C,X> (dest, s, x, r);
00401 dest += r; s += r; n -= r;
00402 rd= AVec::template vec_floor_aligned_size<T> (n);
00403 rs= AVec::template vec_floor_aligned_size<C> (n);
00404 r= min (rd, rs);
00405 AVec::template vec_binary_scalar<Op,T,C,X> (dest, s, x, r);
00406 dest += r; s += r; n -= r;
00407 }
00408 }
00409 NVec::template vec_binary_scalar<Op,T,C,X> (dest, s, x, n);
00410 }
00411
00412 template<typename Op, typename C> static inline bool
00413 vec_unary_test (const C* s, nat n) {
00414 if (mask_helper<C>::len == 16) {
00415 nat r= min ((nat) AVec::vec_ceil_shift (s), n);
00416 if (! NVec::template vec_unary_test<Op,C> (s, r)) return false;
00417 s += r; n -= r;
00418 r= AVec::template vec_floor_aligned_size<C> (n);
00419 if (! AVec::template vec_unary_test<Op,C> (s, r)) return false;
00420 s += r; n -= r;
00421 }
00422 return NVec::template vec_unary_test<Op,C> (s, n);
00423 }
00424
00425 template<typename Op, typename C1, typename C2> static inline bool
00426 vec_binary_test (const C1* s1, const C2* s2, nat n) {
00427 if (mask_helper<C1>::len == 16 &&
00428 mask_helper<C2>::len == 16) {
00429 nat r1= AVec::vec_ceil_shift (s1);
00430 nat r2= AVec::vec_ceil_shift (s2);
00431 if (r1 == r2) {
00432 nat r= min (r1, r2);
00433 if (! NVec::template vec_binary_test<Op,C1,C2> (s1, s2, r))
00434 return false;
00435 s1 += r; s2 += r; n -= r;
00436 r1= AVec::template vec_floor_aligned_size<C1> (n);
00437 r2= AVec::template vec_floor_aligned_size<C2> (n);
00438 r= min (r1, r2);
00439 if (! AVec::template vec_binary_test<Op,C1,C2> (s1, s2, r))
00440 return false;
00441 s1 += r; s2 += r; n -= r;
00442 }
00443 }
00444 return NVec::template vec_binary_test<Op,C1,C2> (s1, s2, n);
00445 }
00446
00447 template<typename Op, typename C, typename X> static inline bool
00448 vec_binary_test_scalar (const C* s, const X& x, nat n) {
00449 if (mask_helper<C>::len == 16) {
00450 nat r= min ((nat) AVec::vec_ceil_shift (s), n);
00451 if (! NVec::template vec_binary_test_scalar<Op,C,X> (s, x, r))
00452 return false;
00453 s += r; n -= r;
00454 r= AVec::template vec_floor_aligned_size<C> (n);
00455 if (! AVec::template vec_binary_test_scalar<Op,C,X> (s, x, r))
00456 return false;
00457 s += r; n -= r;
00458 }
00459 return NVec::template vec_binary_test_scalar<Op,C> (s, x, n);
00460 }
00461
00462 template<typename Op, typename C> static inline C
00463 vec_unary_big (const C* s, nat n) {
00464 if (mask_helper<C>::len == 16) {
00465 nat r= min ((nat) AVec::vec_ceil_shift (s), n);
00466 C c= NVec::template vec_unary_big<Op,C> (s, r);
00467 s += r; n -= r;
00468 r= AVec::template vec_floor_aligned_size<C> (n);
00469 Op::set_op (c, AVec::template vec_unary_big<Op,C> (s, r));
00470 s += r; n -= r;
00471 Op::set_op (c, NVec::template vec_unary_big<Op,C> (s, n));
00472 return c;
00473 }
00474 return NVec::template vec_unary_big<Op,C> (s, n);
00475 }
00476
00477 template<typename Op, typename C> static inline C
00478 vec_unary_big (const C* s, nat n, const format<C>& fm) {
00479 if (mask_helper<C>::len == 16) {
00480 nat r= min ((nat) AVec::vec_ceil_shift (s), n);
00481 C c= NVec::template vec_unary_big<Op,C> (s, r, fm);
00482 s += r; n -= r;
00483 r= AVec::template vec_floor_aligned_size<C> (n);
00484 Op::set_op (c, AVec::template vec_unary_big<Op,C> (s, r, fm));
00485 s += r; n -= r;
00486 Op::set_op (c, NVec::template vec_unary_big<Op,C> (s, n, fm));
00487 return c;
00488 }
00489 return NVec::template vec_unary_big<Op,C> (s, n, fm);
00490 }
00491
00492 template<typename Op, typename C> static inline C
00493 vec_unary_big_dicho (const C* s, nat n) {
00494 return NVec::template vec_unary_big<Op, C> (s, n);
00495 }
00496
00497 template<typename Op, typename C> static inline C
00498 vec_unary_big_dicho (const C* s, nat n, const format<C>& fm) {
00499 return NVec::template vec_unary_big<Op, C> (s, n, fm);
00500 }
00501
00502 template<typename Op, typename C1, typename C2> static inline C1
00503 vec_binary_big (const C1* s1, const C2* s2, nat n) {
00504 if (AVec::vec_is_aligned (s1) &&
00505 AVec::template vec_is_aligned_size<C1> (n) &&
00506 AVec::vec_is_aligned (s2) &&
00507 AVec::template vec_is_aligned_size<C2> (n))
00508 return AVec::template vec_binary_big<Op,C1,C2> (s1, s2, n);
00509 return NVec::template vec_binary_big<Op,C1,C2> (s1, s2, n);
00510 }
00511
00512 template<typename Op, typename C1, typename C2> static inline C1
00513 vec_binary_big (const C1* s1, const C2* s2, nat n,
00514 const format<C1>& fm1, const format<C2>& fm2) {
00515 if (AVec::vec_is_aligned (s1) &&
00516 AVec::template vec_is_aligned_size<C1> (n) &&
00517 AVec::vec_is_aligned (s2) &&
00518 AVec::template vec_is_aligned_size<C2> (n))
00519 return AVec::template vec_binary_big<Op,C1,C2> (s1, s2, n, fm1, fm2);
00520 return NVec::template vec_binary_big<Op,C1,C2> (s1, s2, n, fm1, fm2);
00521 }
00522
00523 };
00524
00525 }
00526 #endif // __MMX__VECTOR_ALIGNED__HPP