All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
tripleInt.h
Go to the documentation of this file.
1 /* tripleInt.h
2  */
3 #ifndef EVAL_CONTAINER_TRIPLE_INT_H
4 #define EVAL_CONTAINER_TRIPLE_INT_H
5 #include "osl/misc/carray.h"
6 #include "osl/misc/align16New.h"
7 #include "osl/misc/cstdint.h"
8 #include "osl/config.h"
9 #include <iosfwd>
10 
11 #if (defined __INTEL_COMPILER || defined __clang__)
12 # include <emmintrin.h>
13 # define __builtin_ia32_pxor128 _mm_xor_si128
14 # define __builtin_ia32_psubd128 _mm_sub_epi32
15 # define __builtin_ia32_paddd128 _mm_add_epi32
16 #endif
17 
18 #ifndef OSL_NO_SSE
19 #if (defined __x86_64__) || (defined __i386__)
20 # ifndef OSL_USE_SSE
21 # define OSL_USE_SSE 1
22 # endif
23 #else
24 # warning "TripleInt without SSE"
25 #endif
26 #endif
27 
28 namespace osl
29 {
30  namespace container
31  {
32 #ifndef OSL_USE_SSE
33  typedef CArray<int32_t,4> v4si;
34  typedef CArray<int64_t,2> v2di;
35 #elif defined __INTEL_COMPILER
36  typedef __v4si v4si;
37  typedef __v2di v2di;
38 #else
39  typedef int v4si __attribute__ ((vector_size (16)));
40  typedef long long v2di __attribute__ ((vector_size (16)));
41 #endif
42  struct TripleInt : public misc::Align16New
43  {
44  union XMM{
45  CArray<int,4> iv;
48  } v
49 #ifdef __GNUC__
50  __attribute__((aligned(16)))
51 #endif
52  ;
54 #if OSL_USE_SSE
55  assert(reinterpret_cast<size_t>(this) % 16 == 0);
56 #endif
57  clear();
58  }
59  TripleInt(TripleInt const& si){
60 #if OSL_USE_SSE
61  assert(reinterpret_cast<size_t>(this) % 16 == 0);
62  v.v4=si.v.v4;
63 #else
64  for(int i=0;i<3;i++) v.iv[i]=si.v.iv[i];
65 #endif
66  }
67  TripleInt(int a, int b, int c){
68 #if OSL_USE_SSE
69  assert(reinterpret_cast<size_t>(this) % 16 == 0);
70  v.v4 = (v4si){a, b, c, 0};
71 #elif __GNUC__
72  v.iv = (CArray<int,4>){{a, b, c, 0}};
73 #else
74  v.iv[0] = a, v.iv[1] = b, v.iv[2] = c;
75 #endif
76  }
77  void clear()
78  {
79 #if OSL_USE_SSE
80  v.v4=(v4si){ 0, 0, 0, 0 };
81 #else
82  for(int i=0;i<3;i++) v.iv[i]=0;
83 #endif
84  }
85  int& operator[](int i) {
86  return v.iv[i];
87  }
88  const int& operator[](int i) const {
89  return v.iv[i];
90  }
92  TripleInt ret;
93 #if OSL_USE_SSE
94  ret.v.v4=__builtin_ia32_psubd128(ret.v.v4,v.v4);
95 #else
96  for(int i=0;i<3;i++) ret.v.iv[i]= -v.iv[i];
97 #endif
98  return ret;
99  }
101 #if OSL_USE_SSE
102  v.v4=__builtin_ia32_paddd128(v.v4,si.v.v4);
103 #else
104  for(int i=0;i<3;i++) v.iv[i]+=si.v.iv[i];
105 #endif
106  return *this;
107  }
109 #if OSL_USE_SSE
110  v.v4=__builtin_ia32_psubd128(v.v4,si.v.v4);
111 #else
112  for(int i=0;i<3;i++) v.iv[i]-=si.v.iv[i];
113 #endif
114  return *this;
115  }
116  TripleInt& operator*=(int scale){
117 #if OSL_USE_SSE41
118  XMM val;
119  unsigned long long scalescale=(unsigned long long )((unsigned int)scale);
120  scalescale|=scalescale<<32ull;
121  val.v2=__builtin_ia32_vec_set_v2di(val.v2,(long long)scalescale,0);
122  val.v2=__builtin_ia32_vec_set_v2di(val.v2,(long long)scalescale,1);
123  v.v4=__builtin_ia32_pmulld128(v.v4,val.v4);
124 #else
125  for(int i=0;i<3;i++) v.iv[i]*=scale;
126 #endif
127  return *this;
128  }
130  {
131  for(int i=0;i<3;i++) v.iv[i] /= div;
132  return *this;
133  }
134  TripleInt& operator>>=(int shift)
135  {
136 #if OSL_USE_SSE
137  v.v4= __builtin_ia32_psradi128 (v.v4, shift);
138 #else
139  for(int i=0;i<3;i++) v.iv[i] >>= shift;
140 #endif
141  return *this;
142  }
143  static size_t size() { return 3; }
144  };
145  inline TripleInt operator+(TripleInt const& si0,TripleInt const& si1)
146  {
147  TripleInt ret(si0);
148  ret+=si1;
149  return ret;
150  }
151  inline TripleInt operator-(TripleInt const& si0,TripleInt const& si1)
152  {
153  TripleInt ret(si0);
154  ret-=si1;
155  return ret;
156  }
157  inline TripleInt operator*(TripleInt const& si0,int scale)
158  {
159  TripleInt ret(si0);
160  ret*=scale;
161  return ret;
162  }
163  inline bool operator==(TripleInt const& l,TripleInt const& r)
164  {
165  for(int i=0;i<3;i++)
166  if (l[i] != r[i])
167  return false;
168  return true;
169  }
170 
172  CArray<TripleInt,2> v;
173  public:
175  const TripleInt& operator[](int i) const{
176  return v[i];
177  }
178  const TripleInt& operator[](Player pl) const{
179  return v[pl];
180  }
182  return v[i];
183  }
185  return v[pl];
186  }
188  v[0]+=a.v[0];
189  v[1]+=a.v[1];
190  return *this;
191  }
193  v[0]-=a.v[0];
194  v[1]-=a.v[1];
195  return *this;
196  }
197  };
198  inline TripleIntPair operator+(TripleIntPair const& si0,TripleIntPair const& si1)
199  {
200  TripleIntPair ret(si0);
201  ret+=si1;
202  return ret;
203  }
204  inline TripleIntPair operator-(TripleIntPair const& si0,TripleIntPair const& si1)
205  {
206  TripleIntPair ret(si0);
207  ret-=si1;
208  return ret;
209  }
210  inline bool operator==(TripleIntPair const& l,TripleIntPair const& r)
211  {
212  return l[0] == r[0] && l[1] == r[1];
213  }
214  std::ostream& operator<<(std::ostream& os,TripleInt const& ti);
215  }
216  using container::TripleInt;
217  using container::TripleIntPair;
218 }
219 #endif // EVAL_CONTAINER_TRIPLE_INT_H
220 // ;;; Local Variables:
221 // ;;; mode:c++
222 // ;;; c-basic-offset:2
223 // ;;; End: