algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : vector_aligned.hpp 00004 * DESCRIPTION: vectors aligned in memory 00005 * COPYRIGHT : (C) 2008 Joris van der Hoeven and Gregoire Lecerf 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 * Variants for memory alignment of vectors 00022 ******************************************************************************/ 00023 00024 template<typename V, typename W> 00025 struct vector_assume_aligned: public V { 00026 // These vectors are assumed to be always aligned 00027 // V is the variant to be used on base types 00028 // W is the variant to be used on simd types (see vector_sse.hpp) 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 // These vectors are not necessarily aligned in memory 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 * Helpers to be specialized on aligned hardware data 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 * Mask helper 00141 ******************************************************************************/ 00142 00143 // Alignment 'len' of C is determined from its corresponding simd type. 00144 // So far memory alignment is only suported for multiples of 16 bytes. 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 * Low level routines on vectors which are assumed to be aligned in memory 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 }; // implementation<vector_allocate,Z,vector_assume_aligned<V,W> > 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 }; // implementation<vector_abstractions,Z,vector_assume_aligned<V,W> > 00299 00300 /****************************************************************************** 00301 * Abstract low level routines on vectors not necessarily aligned in memory 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 {}; // implementation<vector_allocate,Z,vector_aligned<V,W> > 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 }; // implementation<vector_abstractions,Z,vector_aligned<V,W> > 00524 00525 } // namespace mmx 00526 #endif // __MMX__VECTOR_ALIGNED__HPP