00001
00002
00003 #ifndef EVAL_CONTAINER_QUAD_INT_H
00004 #define EVAL_CONTAINER_QUAD_INT_H
00005
00006 #include "osl/config.h"
00007 #include "osl/misc/carray.h"
00008 #include "osl/misc/align16New.h"
00009
00010 #ifdef __INTEL_COMPILER
00011 # include <emmintrin.h>
00012 # define __builtin_ia32_pxor128 _mm_xor_pd
00013 # define __builtin_ia32_psubd128 _mm_sub_epi32
00014 # define __builtin_ia32_paddd128 _mm_add_epi32
00015 #endif
00016
00017 #ifndef OSL_NO_SSE
00018 #if (defined __x86_64) || (defined i386)
00019 # ifndef OSL_USE_SSE
00020 # define OSL_USE_SSE 1
00021 # endif
00022 #else
00023 # warning "QuadInt without SSE"
00024 #endif
00025 #endif
00026
00027 namespace osl
00028 {
00029 namespace container
00030 {
00031 #ifdef OSL_USE_SSE
00032 # ifdef __INTEL_COMPILER
00033 typedef __v4si v4si;
00034 typedef __v2di v2di;
00035 # else
00036 typedef int v4si __attribute__ ((vector_size (16)));
00037 typedef long long v2di __attribute__ ((vector_size (16)));
00038 # endif
00039 #endif
00040 struct QuadInt : public misc::Align16New
00041 {
00042 union XMM{
00043 CArray<int,4> iv;
00044 CArray<long long,2> llv;
00045 #ifdef OSL_USE_SSE
00046 v4si v4;
00047 v2di v2;
00048 #endif
00049 } v
00050 #ifdef OSL_USE_SSE
00051 __attribute__((aligned(16)))
00052 #endif
00053 ;
00054 QuadInt(){
00055 clear();
00056 }
00057 QuadInt(QuadInt const& si){
00058 #if OSL_USE_SSE
00059 v.v4=si.v.v4;
00060 #else
00061 v.llv = si.v.llv;
00062 #endif
00063 }
00064 QuadInt& operator=(QuadInt const& si)
00065 {
00066 #if OSL_USE_SSE
00067 v.v4=si.v.v4;
00068 #else
00069 v.llv = si.v.llv;
00070 #endif
00071 return *this;
00072 }
00073 void clear()
00074 {
00075 #if OSL_USE_SSE
00076 v.v4=(v4si){ 0, 0, 0, 0 };
00077 #else
00078 v.llv[0] = v.llv[1] = 0;
00079 #endif
00080 }
00081 int& operator[](int i) {
00082 return v.iv[i];
00083 }
00084 const int& operator[](int i) const {
00085 return v.iv[i];
00086 }
00087 QuadInt operator-() const{
00088 QuadInt ret;
00089 ret -= *this;
00090 return ret;
00091 }
00092 QuadInt& operator+=(QuadInt const& si){
00093 #if OSL_USE_SSE
00094 v.v4=__builtin_ia32_paddd128(v.v4,si.v.v4);
00095 #else
00096 for(int i=0;i<4;i++) v.iv[i]+=si.v.iv[i];
00097 #endif
00098 return *this;
00099 }
00100 QuadInt& operator-=(QuadInt const& si){
00101 #if OSL_USE_SSE
00102 v.v4=__builtin_ia32_psubd128(v.v4,si.v.v4);
00103 #else
00104 for(int i=0;i<4;i++) v.iv[i]-=si.v.iv[i];
00105 #endif
00106 return *this;
00107 }
00108 QuadInt& operator*=(int scale){
00109 #if OSL_USE_SSE41
00110 XMM val;
00111 unsigned long long scalescale=(unsigned long long )((unsigned int)scale);
00112 scalescale|=scalescale<<32ull;
00113 val.v2=__builtin_ia32_vec_set_v2di(val.v2,(long long)scalescale,0);
00114 val.v2=__builtin_ia32_vec_set_v2di(val.v2,(long long)scalescale,1);
00115 v.v4=__builtin_ia32_pmulld128(v.v4,val.v4);
00116 #else
00117 for(int i=0;i<4;i++) v.iv[i]*=scale;
00118 #endif
00119 return *this;
00120 }
00121 static size_t size() { return 4; }
00122 };
00123 inline QuadInt operator+(QuadInt const& si0,QuadInt const& si1)
00124 {
00125 QuadInt ret(si0);
00126 ret+=si1;
00127 return ret;
00128 }
00129 inline QuadInt operator-(QuadInt const& si0,QuadInt const& si1)
00130 {
00131 QuadInt ret(si0);
00132 ret-=si1;
00133 return ret;
00134 }
00135 inline QuadInt operator*(QuadInt const& si0,int scale)
00136 {
00137 QuadInt ret(si0);
00138 ret*=scale;
00139 return ret;
00140 }
00141 inline bool operator==(QuadInt const& l,QuadInt const& r)
00142 {
00143 return l.v.llv[0] == r.v.llv[0] && l.v.llv[1] == r.v.llv[1];
00144 }
00145 inline bool operator<(QuadInt const& l,QuadInt const& r)
00146 {
00147 if (l.v.llv[0] != r.v.llv[0])
00148 return (l.v.llv[0] < r.v.llv[0]);
00149 return l.v.llv[1] < r.v.llv[1];
00150 }
00151
00152 class QuadIntPair
00153 {
00154 CArray<QuadInt,2> v;
00155 public:
00156 QuadIntPair() {}
00157 const QuadInt& operator[](int i) const{
00158 return v[i];
00159 }
00160 const QuadInt& operator[](Player pl) const{
00161 return v[pl];
00162 }
00163 QuadInt& operator[](int i){
00164 return v[i];
00165 }
00166 QuadInt& operator[](Player pl){
00167 return v[pl];
00168 }
00169 QuadIntPair& operator+=(QuadIntPair const& a){
00170 v[0]+=a.v[0];
00171 v[1]+=a.v[1];
00172 return *this;
00173 }
00174 QuadIntPair& operator-=(QuadIntPair const& a){
00175 v[0]-=a.v[0];
00176 v[1]-=a.v[1];
00177 return *this;
00178 }
00179 };
00180 inline QuadIntPair operator+(QuadIntPair const& si0,QuadIntPair const& si1)
00181 {
00182 QuadIntPair ret(si0);
00183 ret+=si1;
00184 return ret;
00185 }
00186 inline QuadIntPair operator-(QuadIntPair const& si0,QuadIntPair const& si1)
00187 {
00188 QuadIntPair ret(si0);
00189 ret-=si1;
00190 return ret;
00191 }
00192 }
00193
00194 using container::QuadInt;
00195 using container::QuadIntPair;
00196 }
00197 #endif // EVAL_CONTAINER_QUAD_INT_H
00198
00199
00200
00201