Go to the documentation of this file.00001
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
00221
00222
00223