tripleInt.h
Go to the documentation of this file.
00001 /* tripleInt.h
00002  */
00003 #ifndef EVAL_CONTAINER_TRIPLE_INT_H
00004 #define EVAL_CONTAINER_TRIPLE_INT_H
00005 #include "osl/misc/carray.h"
00006 #include "osl/misc/align16New.h"
00007 #include "osl/misc/cstdint.h"
00008 #include "osl/config.h"
00009 #include <iosfwd>
00010 
00011 #if (defined __INTEL_COMPILER || defined __clang__)
00012 #  include <emmintrin.h>
00013 #  define __builtin_ia32_pxor128 _mm_xor_si128
00014 #  define __builtin_ia32_psubd128 _mm_sub_epi32
00015 #  define __builtin_ia32_paddd128 _mm_add_epi32
00016 #endif
00017 
00018 #ifndef OSL_NO_SSE
00019 #if (defined __x86_64__) || (defined __i386__)
00020 #  ifndef OSL_USE_SSE
00021 #    define OSL_USE_SSE 1
00022 #  endif
00023 #else
00024 #  warning "TripleInt without SSE"
00025 #endif
00026 #endif
00027 
00028 namespace osl
00029 {
00030   namespace container
00031   {
00032 #ifndef OSL_USE_SSE
00033     typedef CArray<int32_t,4> v4si;
00034     typedef CArray<int64_t,2> v2di;
00035 #elif defined __INTEL_COMPILER
00036     typedef __v4si v4si;
00037     typedef __v2di v2di;
00038 #else
00039     typedef int v4si __attribute__ ((vector_size (16)));
00040     typedef long long v2di __attribute__ ((vector_size (16)));
00041 #endif
00042     struct TripleInt : public misc::Align16New
00043     {
00044       union XMM{
00045         CArray<int,4> iv;
00046         v4si v4;
00047         v2di v2;
00048       } v
00049 #ifdef __GNUC__
00050       __attribute__((aligned(16)))
00051 #endif
00052         ;
00053       TripleInt(){
00054 #if OSL_USE_SSE
00055         assert(reinterpret_cast<size_t>(this) % 16 == 0);
00056 #endif
00057         clear();
00058       }
00059       TripleInt(TripleInt const& si){
00060 #if OSL_USE_SSE
00061         assert(reinterpret_cast<size_t>(this) % 16 == 0);
00062         v.v4=si.v.v4;
00063 #else
00064         for(int i=0;i<3;i++) v.iv[i]=si.v.iv[i];
00065 #endif
00066       }
00067       TripleInt(int a, int b, int c){
00068 #if OSL_USE_SSE
00069         assert(reinterpret_cast<size_t>(this) % 16 == 0);
00070         v.v4 = (v4si){a, b, c, 0};      
00071 #elif __GNUC__
00072         v.iv = (CArray<int,4>){{a, b, c, 0}};
00073 #else
00074         v.iv[0] = a, v.iv[1] = b, v.iv[2] = c;
00075 #endif
00076       }
00077       void clear()
00078       {
00079 #if OSL_USE_SSE
00080         v.v4=(v4si){ 0, 0, 0, 0 };
00081 #else
00082         for(int i=0;i<3;i++) v.iv[i]=0;
00083 #endif
00084       }
00085       int& operator[](int i) { 
00086         return v.iv[i]; 
00087       }
00088       const int& operator[](int i) const { 
00089         return v.iv[i]; 
00090       }
00091       TripleInt operator-() const{
00092         TripleInt ret;
00093 #if OSL_USE_SSE
00094         ret.v.v4=__builtin_ia32_psubd128(ret.v.v4,v.v4);
00095 #else
00096         for(int i=0;i<3;i++) ret.v.iv[i]= -v.iv[i];
00097 #endif    
00098         return ret;
00099       }
00100       TripleInt& operator+=(TripleInt const& si){
00101 #if OSL_USE_SSE
00102         v.v4=__builtin_ia32_paddd128(v.v4,si.v.v4);
00103 #else
00104         for(int i=0;i<3;i++) v.iv[i]+=si.v.iv[i];
00105 #endif    
00106         return *this;
00107       }
00108       TripleInt& operator-=(TripleInt const& si){
00109 #if OSL_USE_SSE
00110         v.v4=__builtin_ia32_psubd128(v.v4,si.v.v4);
00111 #else
00112         for(int i=0;i<3;i++) v.iv[i]-=si.v.iv[i];
00113 #endif    
00114         return *this;
00115       }
00116       TripleInt& operator*=(int scale){
00117 #if OSL_USE_SSE41
00118         XMM val;
00119         unsigned long long scalescale=(unsigned long long )((unsigned int)scale);
00120         scalescale|=scalescale<<32ull;
00121         val.v2=__builtin_ia32_vec_set_v2di(val.v2,(long long)scalescale,0);
00122         val.v2=__builtin_ia32_vec_set_v2di(val.v2,(long long)scalescale,1);
00123         v.v4=__builtin_ia32_pmulld128(v.v4,val.v4);
00124 #else
00125         for(int i=0;i<3;i++) v.iv[i]*=scale;
00126 #endif
00127         return *this;
00128       }
00129       TripleInt& operator/=(int div)
00130       {
00131         for(int i=0;i<3;i++) v.iv[i] /= div;
00132         return *this;
00133       }
00134       TripleInt& operator>>=(int shift)
00135       {
00136 #if OSL_USE_SSE
00137         v.v4= __builtin_ia32_psradi128 (v.v4, shift);
00138 #else
00139         for(int i=0;i<3;i++) v.iv[i] >>= shift;
00140 #endif    
00141         return *this;
00142       }
00143       static size_t size() { return 3; }
00144     };
00145     inline TripleInt operator+(TripleInt const& si0,TripleInt const& si1)
00146     {
00147       TripleInt ret(si0);
00148       ret+=si1;
00149       return ret;
00150     }
00151     inline TripleInt operator-(TripleInt const& si0,TripleInt const& si1)
00152     {
00153       TripleInt ret(si0);
00154       ret-=si1;
00155       return ret;
00156     }
00157     inline TripleInt operator*(TripleInt const& si0,int scale)
00158     {
00159       TripleInt ret(si0);
00160       ret*=scale;
00161       return ret;
00162     }
00163     inline bool operator==(TripleInt const& l,TripleInt const& r)
00164     {
00165       for(int i=0;i<3;i++) 
00166         if (l[i] != r[i])
00167           return false;
00168       return true;
00169     }
00170     
00171     class TripleIntPair{
00172       CArray<TripleInt,2> v;
00173     public:
00174       TripleIntPair() {}
00175       const TripleInt& operator[](int i) const{
00176         return v[i];
00177       }
00178       const TripleInt& operator[](Player pl) const{
00179         return v[pl];
00180       }
00181       TripleInt& operator[](int i){
00182         return v[i];
00183       }
00184       TripleInt& operator[](Player pl){
00185         return v[pl];
00186       }
00187       TripleIntPair& operator+=(TripleIntPair const& a){
00188         v[0]+=a.v[0];
00189         v[1]+=a.v[1];
00190         return *this;
00191       }
00192       TripleIntPair& operator-=(TripleIntPair const& a){
00193         v[0]-=a.v[0];
00194         v[1]-=a.v[1];
00195         return *this;
00196       }
00197     };
00198     inline TripleIntPair operator+(TripleIntPair const& si0,TripleIntPair const& si1)
00199     {
00200       TripleIntPair ret(si0);
00201       ret+=si1;
00202       return ret;
00203     }
00204     inline TripleIntPair operator-(TripleIntPair const& si0,TripleIntPair const& si1)
00205     {
00206       TripleIntPair ret(si0);
00207       ret-=si1;
00208       return ret;
00209     }
00210     inline bool operator==(TripleIntPair const& l,TripleIntPair const& r)
00211     {
00212       return l[0] == r[0] && l[1] == r[1];
00213     }
00214     std::ostream& operator<<(std::ostream& os,TripleInt const& ti);
00215   }
00216   using container::TripleInt;
00217   using container::TripleIntPair;
00218 }
00219 #endif // EVAL_CONTAINER_TRIPLE_INT_H
00220 // ;;; Local Variables:
00221 // ;;; mode:c++
00222 // ;;; c-basic-offset:2
00223 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines