algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/vector_aligned.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines