00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #ifndef __MMX__POLYNOMIAL_BALANCED__HPP
00014 #define __MMX__POLYNOMIAL_BALANCED__HPP
00015 
00016 namespace mmx {
00017 #define TMPL template<typename C>
00018 
00019 
00020 
00021 
00022 
00023 template<typename V>
00024 struct polynomial_balanced: public V {
00025   typedef typename V::Vec Vec;
00026   typedef typename V::Naive Naive;
00027   typedef polynomial_balanced<typename V::Positive> Positive;
00028   typedef polynomial_balanced<typename V::No_simd> No_simd;
00029   typedef polynomial_balanced<typename V::No_thread> No_thread;
00030   typedef polynomial_balanced<typename V::No_scaled> No_scaled;
00031 };
00032 
00033 template<typename F, typename V, typename W>
00034 struct implementation<F,V,polynomial_balanced<W> >:
00035   public implementation<F,V,W> {};
00036 
00037 
00038 
00039 
00040 
00041 template<typename V, typename W>
00042 struct implementation<polynomial_multiply,V,polynomial_balanced<W> >:
00043   public implementation<polynomial_linear,V>
00044 {
00045   typedef implementation<vector_linear,V> Vec;
00046   typedef implementation<polynomial_linear,W> Pol;
00047   typedef implementation<polynomial_multiply,W> Fallback;
00048 
00049 TMPL static inline void
00050 mul (C* dest, const C* s1, const C* s2, nat n1, nat n2) {
00051   if (n1 == 0 && n2 == 0)
00052     return;
00053   if (n1 == 0 || n2 == 0) {
00054     Pol::clear (dest, n1+n2-1);
00055     return;
00056   }
00057   if (n1 == n2) {
00058     Fallback::mul (dest, s1, s2, n1, n2);
00059     return;
00060   }
00061   nat n= n1+n2-1;
00062   Pol::clear (dest, n);
00063   if (n1 < n2) {
00064     nat l= aligned_size<C,V> (2*n1-1);
00065     C* temp= mmx_new<C> (l);
00066     while (n2 > 0) {
00067       nat n3= min (n1, n2);
00068       mul (temp, s1, s2, n1, n3);
00069       Vec::add (dest, temp, n1+n3-1);
00070       n2 -= n3; s2 += n3; dest += n3;
00071     }
00072     mmx_delete<C> (temp, l);
00073   }
00074   else {
00075     nat l= aligned_size<C,V> (2*n2-1);
00076     C* temp= mmx_new<C> (l);
00077     while (n1 > 0) {
00078       nat n3= min (n1, n2);
00079       mul (temp, s1, s2, n3, n2);
00080       Vec::add (dest, temp, n2+n3-1);
00081       n1 -= n3; s1 += n3; dest += n3;
00082     }
00083     mmx_delete<C> (temp, l);
00084   }
00085 }
00086 
00087 TMPL static inline void
00088 square (C* dest, const C* s, nat n) {
00089   Fallback::square (dest, s, n);
00090 }
00091 
00092 }; 
00093 
00094 #undef TMPL
00095 } 
00096 #endif //__MMX__POLYNOMIAL_BALANCED__HPP