Image Component Library (ICL)
SSETypes.h
Go to the documentation of this file.
1 /********************************************************************
2 ** Image Component Library (ICL) **
3 ** **
4 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld **
5 ** Neuroinformatics Group **
6 ** Website: www.iclcv.org and **
7 ** http://opensource.cit-ec.de/projects/icl **
8 ** **
9 ** File : ICLUtils/src/ICLUtils/SSETypes.h **
10 ** Module : ICLUtils **
11 ** Authors: Sergius Gaulik **
12 ** **
13 ** **
14 ** GNU LESSER GENERAL PUBLIC LICENSE **
15 ** This file may be used under the terms of the GNU Lesser General **
16 ** Public License version 3.0 as published by the **
17 ** **
18 ** Free Software Foundation and appearing in the file LICENSE.LGPL **
19 ** included in the packaging of this file. Please review the **
20 ** following information to ensure the license requirements will **
21 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt **
22 ** **
23 ** The development of this software was supported by the **
24 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. **
25 ** The Excellence Cluster EXC 277 is a grant of the Deutsche **
26 ** Forschungsgemeinschaft (DFG) in the context of the German **
27 ** Excellence Initiative. **
28 ** **
29 ********************************************************************/
30 
31 #pragma once
32 
33 #if defined ICL_USE_SSE2 && (__SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2))
34  #include "emmintrin.h"
35  #define ICL_HAVE_SSE2
36  #if defined ICL_USE_SSE3 && (__SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500))
37  #include "pmmintrin.h"
38  #define ICL_HAVE_SSE3
39  #if defined ICL_USE_SSSE3 && (__SSSE3__ || (defined _MSC_VER && _MSC_VER >= 1500))
40  #include "tmmintrin.h"
41  #define ICL_HAVE_SSSE3
42  #endif
43  #endif
44 #endif
45 
46 #include <ICLUtils/CompatMacros.h>
47 #include <ICLUtils/BasicTypes.h>
48 
49 /* This header wraps the 128 bit SSE types and defines some basic
50  functions for them. The idea is to create an easier and more intuitive
51  way to work with SSE types.
52  The type names are combinations of the basic type name and the number
53  of these basic types in the SSE type. For example: icl8ux16 is a type
54  with 16 icl8u values.
55  The following examples will show some diffrent ways to use the SSE types:
56 
57  // ++++++++++++ black and white example ++++++++++++ //
58  #include <ICLUtils/SSETypes.h>
59  #include <ICLUtils/Time.h>
60 
61  using namespace std;
62  using namespace icl;
63  using namespace icl::utils;
64 
65  #define T_SIZE 111111111
66 
67  // use a threshold to set values of an array to 0 or 255
68  void createBinaryValues(icl8u *d, icl8u *dEnd, const icl8u threshold) {
69  for (; d < dEnd; ++d) *d = (*d < threshold) ? 0 : 255;
70  }
71 
72  // use a threshold to set values of an array to 0 or 255
73  void createBinaryValuesSSE(icl8u *d, icl8u *dEnd, const icl8u threshold) {
74  // if we end up with less than 16 values at the end
75  // we have to convert them value by value to prevent memory access violation
76  icl8u *dSSEEnd = dEnd - 15;
77  // some constants
78  const icl8ux16 c128 = icl8ux16((icl8s)128);
79  const icl8ux16 cT = icl8ux16((icl8s)threshold - 129);
80 
81  // convert 16 values at the same time
82  for (; d < dSSEEnd; d += 16) {
83  // load the first 16 values
84  icl8ux16 v = icl8ux16(d);
85  // subtract 128 from every value in v
86  v -= c128;
87  // if a function for the SSE wrapper types does not exist
88  // we can mix the wrapper types with the actual SSE functions
89  v = _mm_cmpgt_epi8(v, cT);
90  // storeu stores the values from v in d
91  // (store works only with 16 aligned memory,
92  // but storeu does not have this restriction)
93  v.storeu(d);
94  }
95 
96  // convert 1 value at a time
97  for (; d < dEnd; ++d) {
98  *d = (*d < threshold) ? 0 : 255;
99  }
100  }
101 
102  int main(int n, char **ppc){
103  icl::utils::Time t;
104  icl8u *c = new icl8u[T_SIZE];
105 
106  for (unsigned int i = 0; i < T_SIZE; ++i)
107  c[i] = rand() % 256;
108 
109  t = icl::utils::Time::now();
110  createBinaryValues(c, c + T_SIZE, 123);
111  t.showAge("without SSE");
112 
113  for (unsigned int i = 0; i < T_SIZE; ++i)
114  c[i] = rand() % 256;
115 
116  t = icl::utils::Time::now();
117  createBinaryValuesSSE(c, c + T_SIZE, 123);
118  t.showAge("with SSE");
119 
120  delete c;
121 
122  return 0;
123  }
124  // ------------ black and white example ------------ //
125 
126  // ++++++++++++ rgb to gray ++++++++++++ //
127  #include <ICLUtils/SSETypes.h>
128  #include <ICLUtils/ClippedCast.h>
129  #include <ICLUtils/Time.h>
130 
131  using namespace std;
132  using namespace icl;
133  using namespace icl::utils;
134 
135  #define T_SIZE 111111111
136 
137  void RGBtoGray(const icl8u *r, const icl8u *g, const icl8u *b, icl8u *gr, icl8u *grEnd) {
138  for (; gr != grEnd; ++gr, ++r, ++g, ++b) *gr = clipped_cast<icl32f, icl8u>((*r + *g + *b) / 3.0f + 0.5f);
139  }
140  void SSERGBtoGray(const icl8u *r, const icl8u *g, const icl8u *b, icl8u *gr, icl8u *grEnd) {
141  icl8u *grSSEEnd = grEnd - 15;
142 
143  for (; gr < grSSEEnd; gr += 16, r += 16, g += 16, b += 16) {
144  // convert to icl16s for number higher than 255
145  icl16sx16 vR(r);
146  icl16sx16 vG(g);
147  icl16sx16 vB(b);
148 
149  vR += vB;
150  vR += vG;
151 
152  // convert to icl32s and then to icl32f type for floating point operations
153  icl32fx16 vRes = icl32sx16(vR);
154 
155  vRes *= icl32fx16(1.0f / 3.0f);
156  vRes.storeu(gr);
157  }
158 
159  for (; gr != grEnd; ++gr, ++r, ++g, ++b) *gr = clipped_cast<icl8u, icl8u>((*r + *g + *b) / 3.0f + 0.5f);
160  }
161 
162  int main(int n, char **ppc){
163  icl::utils::Time t;
164  icl8u *r = new icl8u[T_SIZE];
165  icl8u *g = new icl8u[T_SIZE];
166  icl8u *b = new icl8u[T_SIZE];
167  icl8u *gr = new icl8u[T_SIZE];
168 
169  for (unsigned int i = 0; i < T_SIZE; ++i) {
170  r[i] = rand() % 256;
171  g[i] = rand() % 256;
172  b[i] = rand() % 256;
173  }
174 
175  t = icl::utils::Time::now();
176  RGBtoGray(r, g, b, gr, gr + T_SIZE);
177  t.showAge("without SSE");
178 
179  t = icl::utils::Time::now();
180  SSERGBtoGray(r, g, b, gr, gr + T_SIZE);
181  t.showAge("with SSE");
182 
183  delete r;
184  delete g;
185  delete b;
186  delete gr;
187 
188  return 0;
189  }
190  // ------------ rgb to gray ------------ //
191 
192 */
193 
194 namespace icl{
195  namespace utils{
196 
197  #ifdef ICL_HAVE_SSE2
198 
199  // ++ basic SSE types ++ //
200 
201  struct Icl128 {
202  __m128 v0;
203  };
204 
205  struct Icl128i {
206  __m128i v0;
207 
208  inline Icl128i() {
209  }
210 
211  inline Icl128i(const Icl128i &v) {
212  v0 = v.v0;
213  }
214 
215  inline Icl128i(const __m128i &v) {
216  v0 = v;
217  }
218 
219  inline Icl128i(const __m128i *v) {
220  v0 = _mm_loadu_si128(v);
221  }
222 
223  inline Icl128i& operator=(const Icl128i &v) {
224  v0 = v.v0;
225  return *this;
226  }
227 
228  inline operator __m128i () const {
229  return v0;
230  }
231 
232  inline Icl128i& operator&=(const Icl128i &v) {
233  v0 = _mm_and_si128(v0, v.v0);
234  return *this;
235  }
236 
237  inline Icl128i& operator|=(const Icl128i &v) {
238  v0 = _mm_or_si128(v0, v.v0);
239  return *this;
240  }
241 
242  inline Icl128i& operator^=(const Icl128i &v) {
243  v0 = _mm_xor_si128(v0, v.v0);
244  return *this;
245  }
246 
247  inline Icl128i& andnot(const Icl128i &v) {
248  v0 = _mm_andnot_si128(v.v0, v0);
249  return *this;
250  }
251 
252  inline void store(__m128i *v) const {
253  _mm_store_si128(v, v0);
254  }
255 
256  inline void storeu(__m128i *v) const {
257  _mm_storeu_si128(v, v0);
258  }
259  };
260 
261  struct Icl128d {
262  __m128d v0;
263  };
264 
265  struct Icl256 {
266  __m128 v0; __m128 v1;
267  };
268 
269  struct Icl256i {
270  __m128i v0; __m128i v1;
271 
272  inline Icl256i() {
273  }
274 
275  inline Icl256i(const Icl256i &v) {
276  v0 = v.v0;
277  v1 = v.v1;
278  }
279 
280  inline Icl256i(const __m128i &vl, const __m128i &vh) {
281  v0 = vl;
282  v1 = vh;
283  }
284 
285  inline Icl256i(const __m128i *v) {
286  v0 = *v;
287  v1 = *(v + 1);
288  }
289 
290  inline Icl256i& operator=(const Icl256i &v) {
291  v0 = v.v0;
292  v1 = v.v1;
293  return *this;
294  }
295 
296  inline Icl256i& operator&=(const Icl256i &v) {
297  v0 = _mm_and_si128(v0, v.v0);
298  v1 = _mm_and_si128(v1, v.v1);
299  return *this;
300  }
301 
302  inline Icl256i& operator|=(const Icl256i &v) {
303  v0 = _mm_or_si128(v0, v.v0);
304  v1 = _mm_or_si128(v1, v.v1);
305  return *this;
306  }
307 
308  inline Icl256i& operator^=(const Icl256i &v) {
309  v0 = _mm_xor_si128(v0, v.v0);
310  v1 = _mm_xor_si128(v1, v.v1);
311  return *this;
312  }
313 
314  inline Icl256i& andnot(const Icl256i &v) {
315  v0 = _mm_andnot_si128(v.v0, v0);
316  v1 = _mm_andnot_si128(v.v1, v1);
317  return *this;
318  }
319 
320  inline void store(__m128i *v) const {
321  _mm_store_si128(v, v0);
322  _mm_store_si128(v + 1, v1);
323  }
324 
325  inline void storeu(__m128i *v) const {
326  _mm_storeu_si128(v, v0);
327  _mm_storeu_si128(v + 1, v1);
328  }
329  };
330 
331  struct Icl256d {
332  __m128d v0; __m128d v1;
333  };
334 
335  struct Icl512 {
336  __m128 v0; __m128 v1; __m128 v2; __m128 v3;
337  };
338 
339  struct Icl512i {
340  __m128i v0; __m128i v1; __m128i v2; __m128i v3;
341 
342  inline Icl512i() {
343  }
344 
345  inline Icl512i(const Icl512i &v) {
346  v0 = v.v0;
347  v1 = v.v1;
348  v2 = v.v2;
349  v3 = v.v3;
350  }
351 
352  inline Icl512i(const __m128i &vll, const __m128i &vlh,
353  const __m128i &vhl, const __m128i &vhh) {
354  v0 = vll;
355  v1 = vlh;
356  v2 = vhl;
357  v3 = vhh;
358  }
359 
360  inline Icl512i(const __m128i *v) {
361  v0 = *v;
362  v1 = *(v + 1);
363  v0 = *(v + 2);
364  v1 = *(v + 3);
365  }
366 
367  inline Icl512i& operator=(const Icl512i &v) {
368  v0 = v.v0;
369  v1 = v.v1;
370  v2 = v.v2;
371  v3 = v.v3;
372  return *this;
373  }
374 
375  inline Icl512i& operator&=(const Icl512i &v) {
376  v0 = _mm_and_si128(v0, v.v0);
377  v1 = _mm_and_si128(v1, v.v1);
378  v2 = _mm_and_si128(v2, v.v2);
379  v3 = _mm_and_si128(v3, v.v3);
380  return *this;
381  }
382 
383  inline Icl512i& operator|=(const Icl512i &v) {
384  v0 = _mm_or_si128(v0, v.v0);
385  v1 = _mm_or_si128(v1, v.v1);
386  v2 = _mm_or_si128(v2, v.v2);
387  v3 = _mm_or_si128(v3, v.v3);
388  return *this;
389  }
390 
391  inline Icl512i& operator^=(const Icl512i &v) {
392  v0 = _mm_xor_si128(v0, v.v0);
393  v1 = _mm_xor_si128(v1, v.v1);
394  v2 = _mm_xor_si128(v2, v.v2);
395  v3 = _mm_xor_si128(v3, v.v3);
396  return *this;
397  }
398 
399  inline Icl512i& andnot(const Icl512i &v) {
400  v0 = _mm_andnot_si128(v.v0, v0);
401  v1 = _mm_andnot_si128(v.v1, v1);
402  v2 = _mm_andnot_si128(v.v2, v2);
403  v3 = _mm_andnot_si128(v.v3, v3);
404  return *this;
405  }
406 
407  inline void store(__m128i *v) const {
408  _mm_store_si128(v, v0);
409  _mm_store_si128(v + 1, v1);
410  _mm_store_si128(v + 2, v2);
411  _mm_store_si128(v + 3, v3);
412  }
413 
414  inline void storeu(__m128i *v) const {
415  _mm_storeu_si128(v, v0);
416  _mm_storeu_si128(v + 1, v1);
417  _mm_storeu_si128(v + 2, v2);
418  _mm_storeu_si128(v + 3, v3);
419  }
420  };
421 
422  struct Icl512d {
423  __m128d v0; __m128d v1; __m128d v2; __m128d v3;
424  };
425 
426  struct Icl1024d {
427  __m128d v0; __m128d v1; __m128d v2; __m128d v3;
428  __m128d v4; __m128d v5; __m128d v6; __m128d v7;
429  };
430 
431  // -- basic SSE types -- //
432 
433 
434  // ++ advanced SSE types ++ //
435 
437  struct icl128 : Icl128 {
438  inline icl128() {
439  }
440 
441  inline icl128(const icl128 &v) {
442  v0 = v.v0;
443  }
444 
445  inline icl128(const __m128 &v) {
446  v0 = v;
447  }
448 
449  inline icl128(const icl32f *v) {
450  v0 = _mm_loadu_ps(v);
451  }
452 
453  inline icl128(const icl32f v) {
454  v0 = _mm_set1_ps(v);
455  }
456 
457  inline icl128(const Icl128 &v) {
458  v0 = v.v0;
459  }
460 
461  inline icl128(const Icl128i &v) {
462  v0 = _mm_cvtepi32_ps(v.v0);
463  }
464 /*
465  inline icl128& operator=(const __m128 &v) {
466  v0 = v;
467  return *this;
468  }
469 
470  inline icl128& operator=(const icl32f *v) {
471  v0 = _mm_loadu_ps(v);
472  return *this;
473  }
474 
475  inline icl128& operator=(const icl32f v) {
476  v0 = _mm_set1_ps(v);
477  return *this;
478  }
479 */
480  inline icl128& operator=(const icl128 &v) {
481  v0 = v.v0;
482  return *this;
483  }
484 
485  inline icl128& operator=(const Icl128 &v) {
486  v0 = v.v0;
487  return *this;
488  }
489 /*
490  inline icl128& operator=(const Icl128i &v) {
491  v0 = _mm_cvtepi32_ps(v.v0);
492  return *this;
493  }
494 */
495  inline operator __m128 () const {
496  return v0;
497  }
498 
499  inline icl128& operator+=(const Icl128 &v) {
500  v0 = _mm_add_ps(v0, v.v0);
501  return *this;
502  }
503 
504  inline icl128& operator-=(const Icl128 &v) {
505  v0 = _mm_sub_ps(v0, v.v0);
506  return *this;
507  }
508 
509  inline icl128& operator*=(const Icl128 &v) {
510  v0 = _mm_mul_ps(v0, v.v0);
511  return *this;
512  }
513 
514  inline icl128& operator/=(const Icl128 &v) {
515  v0 = _mm_div_ps(v0, v.v0);
516  return *this;
517  }
518 
519  inline icl128& operator&=(const Icl128 &v) {
520  v0 = _mm_and_ps(v0, v.v0);
521  return *this;
522  }
523 
524  inline icl128& operator|=(const Icl128 &v) {
525  v0 = _mm_or_ps(v0, v.v0);
526  return *this;
527  }
528 
529  inline icl128& operator^=(const Icl128 &v) {
530  v0 = _mm_xor_ps(v0, v.v0);
531  return *this;
532  }
533 
534  inline icl128& andnot(const Icl128 &v) {
535  v0 = _mm_andnot_ps(v.v0, v0);
536  return *this;
537  }
538 
539  inline icl128& rcp() {
540  v0 = _mm_rcp_ps(v0);
541  return *this;
542  }
543 
544  inline void store(icl32f *v) const {
545  _mm_store_ps(v, v0);
546  }
547 
548  inline void storeu(icl32f *v) const {
549  _mm_storeu_ps(v, v0);
550  }
551  };
552 
554  struct icl256 : Icl256 {
555  inline icl256() {
556  }
557 
558  inline icl256(const icl256 &v) {
559  v0 = v.v0;
560  v1 = v.v1;
561  }
562 
563  inline icl256(const __m128 &vl, const __m128 &vh) {
564  v0 = vl;
565  v1 = vh;
566  }
567 
568  inline icl256(const __m128 *v) {
569  v0 = *v;
570  v1 = *(v + 1);
571  }
572 
573  inline icl256(const icl32f v) {
574  v0 = _mm_set1_ps(v);
575  v1 = _mm_set1_ps(v);
576  }
577 
578  inline icl256(const Icl256 &v) {
579  v0 = v.v0;
580  v1 = v.v1;
581  }
582 
583  inline icl256(const Icl256i &v) {
584  v0 = _mm_cvtepi32_ps(v.v0);
585  v1 = _mm_cvtepi32_ps(v.v1);
586  }
587 /*
588  inline icl256& operator=(const __m128 *v) {
589  v0 = *v;
590  v1 = *(v + 1);
591  return *this;
592  }
593 
594  inline icl256& operator=(const icl32f v) {
595  v0 = _mm_set1_ps(v);
596  v1 = _mm_set1_ps(v);
597  return *this;
598  }
599 */
600  inline icl256& operator=(const icl256 &v) {
601  v0 = v.v0;
602  v1 = v.v1;
603  return *this;
604  }
605 
606  inline icl256& operator=(const Icl256 &v) {
607  v0 = v.v0;
608  v1 = v.v1;
609  return *this;
610  }
611 /*
612  inline icl256& operator=(const Icl256i &v) {
613  v0 = _mm_cvtepi32_ps(v.v0);
614  v1 = _mm_cvtepi32_ps(v.v1);
615  return *this;
616  }
617 */
618  inline icl256& operator+=(const Icl256 &v) {
619  v0 = _mm_add_ps(v0, v.v0);
620  v1 = _mm_add_ps(v1, v.v1);
621  return *this;
622  }
623 
624  inline icl256& operator-=(const Icl256 &v) {
625  v0 = _mm_sub_ps(v0, v.v0);
626  v1 = _mm_sub_ps(v1, v.v1);
627  return *this;
628  }
629 
630  inline icl256& operator*=(const Icl256 &v) {
631  v0 = _mm_mul_ps(v0, v.v0);
632  v1 = _mm_mul_ps(v1, v.v1);
633  return *this;
634  }
635 
636  inline icl256& operator/=(const Icl256 &v) {
637  v0 = _mm_div_ps(v0, v.v0);
638  v1 = _mm_div_ps(v1, v.v1);
639  return *this;
640  }
641 
642  inline icl256& operator&=(const Icl256 &v) {
643  v0 = _mm_and_ps(v0, v.v0);
644  v1 = _mm_and_ps(v1, v.v1);
645  return *this;
646  }
647 
648  inline icl256& operator|=(const Icl256 &v) {
649  v0 = _mm_or_ps(v0, v.v0);
650  v1 = _mm_or_ps(v1, v.v1);
651  return *this;
652  }
653 
654  inline icl256& operator^=(const Icl256 &v) {
655  v0 = _mm_xor_ps(v0, v.v0);
656  v1 = _mm_xor_ps(v1, v.v1);
657  return *this;
658  }
659 
660  inline icl256& andnot(const Icl256 &v) {
661  v0 = _mm_andnot_ps(v.v0, v0);
662  v1 = _mm_andnot_ps(v.v1, v1);
663  return *this;
664  }
665 
666  inline icl256& rcp() {
667  v0 = _mm_rcp_ps(v0);
668  v1 = _mm_rcp_ps(v1);
669  return *this;
670  }
671 
672  inline void store(icl32f *v) const {
673  _mm_store_ps(v, v0);
674  _mm_store_ps(v + 4, v1);
675  }
676 
677  inline void storeu(icl32f *v) const {
678  _mm_storeu_ps(v, v0);
679  _mm_storeu_ps(v + 4, v1);
680  }
681  };
682 
684  struct icl512 : Icl512 {
685  inline icl512() {
686  }
687 
688  inline icl512(const icl512 &v) {
689  v0 = v.v0;
690  v1 = v.v1;
691  v2 = v.v2;
692  v3 = v.v3;
693  }
694 
695  inline icl512(const __m128 &vll, const __m128 &vlh,
696  const __m128 &vhl, const __m128 &vhh) {
697  v0 = vll;
698  v1 = vlh;
699  v2 = vhl;
700  v3 = vhh;
701  }
702 
703  inline icl512(const __m128 *v) {
704  v0 = *v;
705  v1 = *(v + 1);
706  v2 = *(v + 2);
707  v3 = *(v + 3);
708  }
709 
710  inline icl512(const icl8u *v) {
711  const __m128i vk0 = _mm_setzero_si128();
712  __m128i vt0, vt1, vt2, vt3;
713 
714  vt3 = _mm_loadu_si128((__m128i*)v);
715 
716  vt1 = _mm_unpacklo_epi8(vt3, vk0);
717  vt3 = _mm_unpackhi_epi8(vt3, vk0);
718 
719  vt0 = _mm_unpacklo_epi16(vt1, vk0);
720  vt1 = _mm_unpackhi_epi16(vt1, vk0);
721  vt2 = _mm_unpacklo_epi16(vt3, vk0);
722  vt3 = _mm_unpackhi_epi16(vt3, vk0);
723 
724  v0 = _mm_cvtepi32_ps(vt0);
725  v1 = _mm_cvtepi32_ps(vt1);
726  v2 = _mm_cvtepi32_ps(vt2);
727  v3 = _mm_cvtepi32_ps(vt3);
728  }
729 
730  inline icl512(const icl32f *v) {
731  v0 = _mm_loadu_ps(v);
732  v1 = _mm_loadu_ps(v + 4);
733  v2 = _mm_loadu_ps(v + 8);
734  v3 = _mm_loadu_ps(v + 12);
735  }
736 
737  inline icl512(const Icl512 &v) {
738  v0 = v.v0;
739  v1 = v.v1;
740  v2 = v.v2;
741  v3 = v.v3;
742  }
743 
744  inline icl512(const Icl512i &v) {
745  v0 = _mm_cvtepi32_ps(v.v0);
746  v1 = _mm_cvtepi32_ps(v.v1);
747  v2 = _mm_cvtepi32_ps(v.v2);
748  v3 = _mm_cvtepi32_ps(v.v3);
749  }
750 
751  inline icl512(const icl32f v) {
752  v0 = _mm_set1_ps(v);
753  v1 = _mm_set1_ps(v);
754  v2 = _mm_set1_ps(v);
755  v3 = _mm_set1_ps(v);
756  }
757 /*
758  inline icl512& operator=(const __m128 *v) {
759  v0 = *v;
760  v1 = *(v + 1);
761  v2 = *(v + 2);
762  v3 = *(v + 3);
763  return *this;
764  }
765 
766  inline icl512& operator=(const icl32f *v) {
767  v0 = _mm_loadu_ps(v);
768  v1 = _mm_loadu_ps(v + 4);
769  v2 = _mm_loadu_ps(v + 8);
770  v3 = _mm_loadu_ps(v + 12);
771  return *this;
772  }
773 */
774  inline icl512& operator=(const icl512 &v) {
775  v0 = v.v0;
776  v1 = v.v1;
777  v2 = v.v2;
778  v3 = v.v3;
779  return *this;
780  }
781 
782  inline icl512& operator=(const Icl512 &v) {
783  v0 = v.v0;
784  v1 = v.v1;
785  v2 = v.v2;
786  v3 = v.v3;
787  return *this;
788  }
789 /*
790  inline icl512& operator=(const Icl512i &v) {
791  v0 = _mm_cvtepi32_ps(v.v0);
792  v1 = _mm_cvtepi32_ps(v.v1);
793  v2 = _mm_cvtepi32_ps(v.v2);
794  v3 = _mm_cvtepi32_ps(v.v3);
795  return *this;
796  }
797 
798  inline icl512& operator=(const icl32f v) {
799  v0 = _mm_set1_ps(v);
800  v1 = _mm_set1_ps(v);
801  v2 = _mm_set1_ps(v);
802  v3 = _mm_set1_ps(v);
803  return *this;
804  }
805 */
806  inline icl512& operator+=(const Icl512 &v) {
807  v0 = _mm_add_ps(v0, v.v0);
808  v1 = _mm_add_ps(v1, v.v1);
809  v2 = _mm_add_ps(v2, v.v2);
810  v3 = _mm_add_ps(v3, v.v3);
811  return *this;
812  }
813 
814  inline icl512& operator-=(const Icl512 &v) {
815  v0 = _mm_sub_ps(v0, v.v0);
816  v1 = _mm_sub_ps(v1, v.v1);
817  v2 = _mm_sub_ps(v2, v.v2);
818  v3 = _mm_sub_ps(v3, v.v3);
819  return *this;
820  }
821 
822  inline icl512& operator*=(const Icl512 &v) {
823  v0 = _mm_mul_ps(v0, v.v0);
824  v1 = _mm_mul_ps(v1, v.v1);
825  v2 = _mm_mul_ps(v2, v.v2);
826  v3 = _mm_mul_ps(v3, v.v3);
827  return *this;
828  }
829 
830  inline icl512& operator/=(const Icl512 &v) {
831  v0 = _mm_div_ps(v0, v.v0);
832  v1 = _mm_div_ps(v1, v.v1);
833  v2 = _mm_div_ps(v2, v.v2);
834  v3 = _mm_div_ps(v3, v.v3);
835  return *this;
836  }
837 
838  inline icl512& operator&=(const Icl512 &v) {
839  v0 = _mm_and_ps(v0, v.v0);
840  v1 = _mm_and_ps(v1, v.v1);
841  v2 = _mm_and_ps(v2, v.v2);
842  v3 = _mm_and_ps(v3, v.v3);
843  return *this;
844  }
845 
846  inline icl512& operator|=(const Icl512 &v) {
847  v0 = _mm_or_ps(v0, v.v0);
848  v1 = _mm_or_ps(v1, v.v1);
849  v2 = _mm_or_ps(v2, v.v2);
850  v3 = _mm_or_ps(v3, v.v3);
851  return *this;
852  }
853 
854  inline icl512& operator^=(const Icl512 &v) {
855  v0 = _mm_xor_ps(v0, v.v0);
856  v1 = _mm_xor_ps(v1, v.v1);
857  v2 = _mm_xor_ps(v2, v.v2);
858  v3 = _mm_xor_ps(v3, v.v3);
859  return *this;
860  }
861 
862  inline icl512& andnot(const Icl512 &v) {
863  v0 = _mm_andnot_ps(v.v0, v0);
864  v1 = _mm_andnot_ps(v.v1, v1);
865  v2 = _mm_andnot_ps(v.v2, v2);
866  v3 = _mm_andnot_ps(v.v3, v3);
867  return *this;
868  }
869 
870  inline icl512& rcp() {
871  v0 = _mm_rcp_ps(v0);
872  v1 = _mm_rcp_ps(v1);
873  v2 = _mm_rcp_ps(v2);
874  v3 = _mm_rcp_ps(v3);
875  return *this;
876  }
877 
878  inline void store(icl8u *v) const {
879  //__m128 vMin = _mm_set1_ps(-2147483520.f);
880  //__m128 vMax = _mm_set1_ps(2147483520.f);
881  //v0 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v0, vMin), vMax));
882  //v1 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v1, vMin), vMax));
883  //v2 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v2, vMin), vMax));
884  //v3 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v3, vMin), vMax));
885  __m128i vt0 = _mm_cvtps_epi32(v0);
886  __m128i vt1 = _mm_cvtps_epi32(v1);
887  __m128i vt2 = _mm_cvtps_epi32(v2);
888  __m128i vt3 = _mm_cvtps_epi32(v3);
889 
890  vt0 = _mm_packus_epi16(_mm_packs_epi32(vt0, vt1), _mm_packs_epi32(vt2, vt3));
891  _mm_store_si128((__m128i*)v, vt0);
892  }
893 
894  inline void storeu(icl8u *v) const {
895  //__m128 vMin = _mm_set1_ps(-2147483520.f);
896  //__m128 vMax = _mm_set1_ps(2147483520.f);
897  //v0 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v0, vMin), vMax));
898  //v1 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v1, vMin), vMax));
899  //v2 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v2, vMin), vMax));
900  //v3 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v3, vMin), vMax));
901  __m128i vt0 = _mm_cvtps_epi32(v0);
902  __m128i vt1 = _mm_cvtps_epi32(v1);
903  __m128i vt2 = _mm_cvtps_epi32(v2);
904  __m128i vt3 = _mm_cvtps_epi32(v3);
905 
906  vt0 = _mm_packus_epi16(_mm_packs_epi32(vt0, vt1), _mm_packs_epi32(vt2, vt3));
907  _mm_storeu_si128((__m128i*)v, vt0);
908  }
909 
910  inline void store(icl32f *v) const {
911  _mm_store_ps(v, v0);
912  _mm_store_ps(v + 4, v1);
913  _mm_store_ps(v + 8, v2);
914  _mm_store_ps(v + 12, v3);
915  }
916 
917  inline void storeu(icl32f *v) const {
918  _mm_storeu_ps(v, v0);
919  _mm_storeu_ps(v + 4, v1);
920  _mm_storeu_ps(v + 8, v2);
921  _mm_storeu_ps(v + 12, v3);
922  }
923  };
924 
926  struct icl128i8u : Icl128i {
927  inline icl128i8u() {
928  }
929 
930  inline icl128i8u(const Icl128i &v) {
931  v0 = v.v0;
932  }
933 
934  inline icl128i8u(const icl128i8u &v) {
935  v0 = v.v0;
936  }
937 
938  inline icl128i8u(const __m128i &v) {
939  v0 = v;
940  }
941 
942  inline icl128i8u(const __m128i *v) {
943  v0 = _mm_loadu_si128(v);
944  }
945 
946  inline icl128i8u(const icl8s *v) {
947  v0 = _mm_loadu_si128((__m128i*)v);
948  }
949 
950  inline icl128i8u(const icl8u *v) {
951  v0 = _mm_loadu_si128((__m128i*)v);
952  }
953 
954  inline icl128i8u(const icl8s v) {
955  v0 = _mm_set1_epi8(v);
956  }
957 
958  inline icl128i8u(const Icl256i &v) {
959  //v0 = _mm_packs_epi16(v.v0, v.v1); // for icl8s
960  v0 = _mm_packus_epi16(v.v0, v.v1);
961  }
962 
963  inline icl128i8u(const Icl512i &v) {
964  //v0 = _mm_packs_epi16(_mm_packs_epi32(v.v0, v.v1), _mm_packs_epi32(v.v2, v.v3)); // for icl8s
965  v0 = _mm_packus_epi16(_mm_packs_epi32(v.v0, v.v1), _mm_packs_epi32(v.v2, v.v3));
966  }
967 
968  inline operator Icl128i () const {
969  return *this;
970  }
971 
972  inline icl128i8u& operator=(const icl128i8u &v) {
973  v0 = v.v0;
974  return *this;
975  }
976 
977  inline icl128i8u& operator=(const Icl128i &v) {
978  v0 = v.v0;
979  return *this;
980  }
981 
982  inline icl128i8u& operator+=(const icl128i8u &v) {
983  v0 = _mm_add_epi8(v0, v.v0);
984  return *this;
985  }
986 
987  inline icl128i8u& operator-=(const icl128i8u &v) {
988  v0 = _mm_sub_epi8(v0, v.v0);
989  return *this;
990  }
991 
992  inline void store(__m128i *v) const {
993  _mm_store_si128(v, v0);
994  }
995 
996  inline void storeu(__m128i *v) const {
997  _mm_storeu_si128(v, v0);
998  }
999 
1000  inline void store(icl8s *v) const {
1001  _mm_store_si128((__m128i*)v, v0);
1002  }
1003 
1004  inline void storeu(icl8s *v) const {
1005  _mm_storeu_si128((__m128i*)v, v0);
1006  }
1007 
1008  inline void store(icl8u *v) const {
1009  _mm_store_si128((__m128i*)v, v0);
1010  }
1011 
1012  inline void storeu(icl8u *v) const {
1013  _mm_storeu_si128((__m128i*)v, v0);
1014  }
1015  };
1016 
1018  struct icl128i16s : Icl128i {
1019  inline icl128i16s() {
1020  }
1021 
1022  inline icl128i16s(const icl128i16s &v) {
1023  v0 = v.v0;
1024  }
1025 
1026  inline icl128i16s(const Icl128i &v) {
1027  v0 = v.v0;
1028  }
1029 
1030  inline icl128i16s(const __m128i &v) {
1031  v0 = v;
1032  }
1033 
1034  inline icl128i16s(const __m128i *v) {
1035  v0 = _mm_loadu_si128(v);
1036  }
1037 
1038  inline icl128i16s(const icl16s *v) {
1039  v0 = _mm_loadu_si128((__m128i*)v);
1040  }
1041 
1042  inline icl128i16s(const icl16u *v) {
1043  v0 = _mm_loadu_si128((__m128i*)v);
1044  }
1045 
1046  inline icl128i16s(const icl16s v) {
1047  v0 = _mm_set1_epi16(v);
1048  }
1049 
1050  inline icl128i16s(const Icl256i &v) {
1051  v0 = _mm_packs_epi32(v.v0, v.v1);
1052  }
1053 
1054  inline operator Icl128i () const {
1055  return *this;
1056  }
1057 
1058  inline icl128i16s& operator=(const icl128i16s &v) {
1059  v0 = v.v0;
1060  return *this;
1061  }
1062 
1063  inline icl128i16s& operator=(const Icl128i &v) {
1064  v0 = v.v0;
1065  return *this;
1066  }
1067 
1068  inline icl128i16s& operator+=(const icl128i16s &v) {
1069  v0 = _mm_add_epi16(v0, v.v0);
1070  return *this;
1071  }
1072 
1073  inline icl128i16s& operator-=(const icl128i16s &v) {
1074  v0 = _mm_sub_epi16(v0, v.v0);
1075  return *this;
1076  }
1077 
1078  inline void store(__m128i *v) const {
1079  _mm_store_si128(v, v0);
1080  }
1081 
1082  inline void storeu(__m128i *v) const {
1083  _mm_storeu_si128(v, v0);
1084  }
1085 
1086  inline void store(icl16s *v) const {
1087  _mm_store_si128((__m128i*)v, v0);
1088  }
1089 
1090  inline void storeu(icl16s *v) const {
1091  _mm_storeu_si128((__m128i*)v, v0);
1092  }
1093 
1094  inline void store(icl16u *v) const {
1095  _mm_store_si128((__m128i*)v, v0);
1096  }
1097 
1098  inline void storeu(icl16u *v) const {
1099  _mm_storeu_si128((__m128i*)v, v0);
1100  }
1101  };
1102 
1104  struct icl128i32s : Icl128i {
1105  inline icl128i32s() {
1106  }
1107 
1108  inline icl128i32s(const icl128i32s &v) {
1109  v0 = v.v0;
1110  }
1111 
1112  inline icl128i32s(const Icl128i &v) {
1113  v0 = v.v0;
1114  }
1115 
1116  inline icl128i32s(const __m128i &v) {
1117  v0 = v;
1118  }
1119 
1120  inline icl128i32s(const __m128i *v) {
1121  v0 = _mm_loadu_si128(v);
1122  }
1123 
1124  inline icl128i32s(const icl32s *v) {
1125  v0 = _mm_loadu_si128((__m128i*)v);
1126  }
1127 
1128  inline icl128i32s(const icl32u *v) {
1129  v0 = _mm_loadu_si128((__m128i*)v);
1130  }
1131 
1132  inline icl128i32s(const icl32s i0, const icl32s i1, const icl32s i2, const icl32s i3) {
1133  v0 = _mm_set_epi32(i3, i2, i1, i0);
1134  }
1135 
1136  inline icl128i32s(const icl32s v) {
1137  v0 = _mm_set1_epi32(v);
1138  }
1139 
1140  inline icl128i32s(const Icl128 &v) {
1141  //__m128 vMin = _mm_set1_ps(-2147483520.f);
1142  //__m128 vMax = _mm_set1_ps(2147483520.f);
1143  //v0 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v0, vMin), vMax));
1144  v0 = _mm_cvtps_epi32(v.v0);
1145  }
1146 
1147  inline operator Icl128i () const {
1148  return *this;
1149  }
1150 
1151 #ifndef __clang__
1152  inline icl128i32s& operator=(const icl128i32s &v) {
1153  v0 = v.v0;
1154  return *this;
1155  }
1156 
1157  inline icl128i32s& operator=(const Icl128i &v) {
1158  v0 = v.v0;
1159  return *this;
1160  }
1161 #endif
1162  inline icl128i32s& operator+=(const icl128i32s &v) {
1163  v0 = _mm_add_epi32(v0, v.v0);
1164  return *this;
1165  }
1166 
1167  inline icl128i32s& operator-=(const icl128i32s &v) {
1168  v0 = _mm_sub_epi32(v0, v.v0);
1169  return *this;
1170  }
1171 
1172  inline void store(__m128i *v) const {
1173  _mm_store_si128(v, v0);
1174  }
1175 
1176  inline void storeu(__m128i *v) const {
1177  _mm_storeu_si128(v, v0);
1178  }
1179 
1180  inline void store(icl32s *v) const {
1181  _mm_store_si128((__m128i*)v, v0);
1182  }
1183 
1184  inline void storeu(icl32s *v) const {
1185  _mm_storeu_si128((__m128i*)v, v0);
1186  }
1187 
1188  inline void store(icl32u *v) const {
1189  _mm_store_si128((__m128i*)v, v0);
1190  }
1191 
1192  inline void storeu(icl32u *v) const {
1193  _mm_storeu_si128((__m128i*)v, v0);
1194  }
1195  };
1196 
1198  struct icl256i16s : Icl256i {
1199  inline icl256i16s() {
1200  }
1201 
1202  inline icl256i16s(const icl256i16s &v) {
1203  v0 = v.v0;
1204  v1 = v.v0;
1205  }
1206 
1207  inline icl256i16s(const Icl256i &v) {
1208  v0 = v.v0;
1209  v1 = v.v0;
1210  }
1211 
1212  inline icl256i16s(const __m128i &vl, const __m128i &vh) {
1213  v0 = vl;
1214  v1 = vh;
1215  }
1216 
1217  inline icl256i16s(const __m128i *v) {
1218  v0 = *v;
1219  v1 = *(v + 1);
1220  }
1221 
1222  inline icl256i16s(const icl16s *v) {
1223  v0 = _mm_loadu_si128((__m128i*)v);
1224  v1 = _mm_loadu_si128((__m128i*)(v + 8));
1225  }
1226 
1227  inline icl256i16s(const icl16s v) {
1228  v0 = _mm_set1_epi16(v);
1229  v1 = _mm_set1_epi16(v);
1230  }
1231 
1232  inline icl256i16s(const icl128i8u &v) {
1233  const __m128i vk0 = _mm_setzero_si128();
1234  v0 = _mm_unpacklo_epi8(v.v0, vk0);
1235  v1 = _mm_unpackhi_epi8(v.v0, vk0);
1236  }
1237 
1238  inline icl256i16s(const Icl512i &v) {
1239  v0 = _mm_packs_epi32(v.v0, v.v1);
1240  v1 = _mm_packs_epi32(v.v2, v.v3);
1241  }
1242 
1243  inline operator Icl256i () const {
1244  return *this;
1245  }
1246 
1247  inline icl256i16s& operator=(const icl256i16s &v) {
1248  v0 = v.v0;
1249  v1 = v.v1;
1250  return *this;
1251  }
1252 
1253  inline icl256i16s& operator=(const Icl256i &v) {
1254  v0 = v.v0;
1255  v1 = v.v1;
1256  return *this;
1257  }
1258 
1259  inline icl256i16s& operator+=(const icl256i16s &v) {
1260  v0 = _mm_add_epi16(v0, v.v0);
1261  v1 = _mm_add_epi16(v1, v.v1);
1262  return *this;
1263  }
1264 
1265  inline icl256i16s& operator-=(const icl256i16s &v) {
1266  v0 = _mm_sub_epi16(v0, v.v0);
1267  v1 = _mm_sub_epi16(v1, v.v1);
1268  return *this;
1269  }
1270 
1271  inline void store(__m128i *v) const {
1272  _mm_store_si128(v, v0);
1273  _mm_store_si128(v + 1, v1);
1274  }
1275 
1276  inline void storeu(__m128i *v) const {
1277  _mm_storeu_si128(v, v0);
1278  _mm_storeu_si128(v + 1, v1);
1279  }
1280 
1281  inline void store(icl16s *v) const {
1282  _mm_store_si128((__m128i*)v, v0);
1283  _mm_store_si128((__m128i*)(v + 8), v1);
1284  }
1285 
1286  inline void storeu(icl16s *v) const {
1287  _mm_storeu_si128((__m128i*)v, v0);
1288  _mm_storeu_si128((__m128i*)(v + 8), v1);
1289  }
1290 
1291  inline void store(icl16u *v) const {
1292  _mm_store_si128((__m128i*)v, v0);
1293  _mm_store_si128((__m128i*)(v + 8), v1);
1294  }
1295 
1296  inline void storeu(icl16u *v) const {
1297  _mm_storeu_si128((__m128i*)v, v0);
1298  _mm_storeu_si128((__m128i*)(v + 8), v1);
1299  }
1300  };
1301 
1303  struct icl256i32s : Icl256i {
1304 
1305  inline icl256i32s() {
1306  }
1307 
1308  inline icl256i32s(const icl256i32s &v) {
1309  v0 = v.v0;
1310  v1 = v.v1;
1311  }
1312 
1313  inline icl256i32s(const Icl256i &v) {
1314  v0 = v.v0;
1315  v1 = v.v1;
1316  }
1317 
1318  inline icl256i32s(const __m128i &vl, const __m128i &vh) {
1319  v0 = vl;
1320  v1 = vh;
1321  }
1322 
1323  inline icl256i32s(const __m128i *v) {
1324  v0 = *v;
1325  v1 = *(v + 1);
1326  }
1327 
1328  inline icl256i32s(const icl32s *v) {
1329  v0 = _mm_loadu_si128((__m128i*)v);
1330  v1 = _mm_loadu_si128((__m128i*)(v + 4));
1331  }
1332 
1333  inline icl256i32s(const icl32s v) {
1334  v0 = _mm_set1_epi32(v);
1335  v1 = _mm_set1_epi32(v);
1336  }
1337 
1338  inline icl256i32s(const Icl256 &v) {
1339  //__m128 vMin = _mm_set1_ps(-2147483520.f);
1340  //__m128 vMax = _mm_set1_ps(2147483520.f);
1341  //v0 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v0, vMin), vMax));
1342  //v1 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v1, vMin), vMax));
1343  v0 = _mm_cvtps_epi32(v.v0);
1344  v1 = _mm_cvtps_epi32(v.v1);
1345  }
1346 
1347  inline icl256i32s& operator=(const icl256i32s &v) {
1348  v0 = v.v0;
1349  v1 = v.v1;
1350  return *this;
1351  }
1352 
1353  inline icl256i32s& operator=(const Icl256i &v) {
1354  v0 = v.v0;
1355  v1 = v.v1;
1356  return *this;
1357  }
1358 
1359  inline icl256i32s& operator+=(const icl256i32s &v) {
1360  v0 = _mm_add_epi16(v0, v.v0);
1361  v1 = _mm_add_epi16(v1, v.v1);
1362  return *this;
1363  }
1364 
1365  inline icl256i32s& operator-=(const icl256i32s &v) {
1366  v0 = _mm_sub_epi16(v0, v.v0);
1367  v1 = _mm_sub_epi16(v1, v.v1);
1368  return *this;
1369  }
1370 
1371  inline void store(__m128i *v) const {
1372  _mm_store_si128(v, v0);
1373  _mm_store_si128(v + 1, v1);
1374  }
1375 
1376  inline void storeu(__m128i *v) const {
1377  _mm_storeu_si128(v, v0);
1378  _mm_storeu_si128(v + 1, v1);
1379  }
1380 
1381  inline void store(icl32s *v) const {
1382  _mm_store_si128((__m128i*)v, v0);
1383  _mm_store_si128((__m128i*)(v + 4), v1);
1384  }
1385 
1386  inline void storeu(icl32s *v) const {
1387  _mm_storeu_si128((__m128i*)v, v0);
1388  _mm_storeu_si128((__m128i*)(v + 4), v1);
1389  }
1390 
1391  inline void store(icl32u *v) const {
1392  _mm_store_si128((__m128i*)v, v0);
1393  _mm_store_si128((__m128i*)(v + 4), v1);
1394  }
1395 
1396  inline void storeu(icl32u *v) const {
1397  _mm_storeu_si128((__m128i*)v, v0);
1398  _mm_storeu_si128((__m128i*)(v + 4), v1);
1399  }
1400  };
1401 
1403  struct icl512i32s : Icl512i {
1404  inline icl512i32s() {
1405  }
1406 
1407  inline icl512i32s(const icl512i32s &v) {
1408  v0 = v.v0;
1409  v1 = v.v1;
1410  v2 = v.v2;
1411  v3 = v.v3;
1412  }
1413 
1414  inline icl512i32s(const Icl512i &v) {
1415  v0 = v.v0;
1416  v1 = v.v1;
1417  v2 = v.v2;
1418  v3 = v.v3;
1419  }
1420 
1421  inline icl512i32s(const __m128i &vll, const __m128i &vlh,
1422  const __m128i &vhl, const __m128i &vhh) {
1423  v0 = vll;
1424  v1 = vlh;
1425  v2 = vhl;
1426  v3 = vhh;
1427  }
1428 
1429  inline icl512i32s(const icl32s *v) {
1430  v0 = _mm_loadu_si128((__m128i*)v);
1431  v1 = _mm_loadu_si128((__m128i*)(v + 4));
1432  v2 = _mm_loadu_si128((__m128i*)(v + 8));
1433  v3 = _mm_loadu_si128((__m128i*)(v + 12));
1434  }
1435 
1436  inline icl512i32s(const Icl256i &v) {
1437  const __m128i vk0 = _mm_setzero_si128();
1438  v0 = _mm_unpacklo_epi16(v.v0, vk0);
1439  v1 = _mm_unpackhi_epi16(v.v0, vk0);
1440  v2 = _mm_unpacklo_epi16(v.v1, vk0);
1441  v3 = _mm_unpackhi_epi16(v.v1, vk0);
1442  }
1443 
1444  inline icl512i32s(const icl32s v) {
1445  v0 = _mm_set1_epi32(v);
1446  v1 = _mm_set1_epi32(v);
1447  v2 = _mm_set1_epi32(v);
1448  v3 = _mm_set1_epi32(v);
1449  }
1450 
1451  inline icl512i32s(const Icl512 &v) {
1452  //__m128 vMin = _mm_set1_ps(-2147483520.f);
1453  //__m128 vMax = _mm_set1_ps(2147483520.f);
1454  //v0 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v0, vMin), vMax));
1455  //v1 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v1, vMin), vMax));
1456  //v2 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v2, vMin), vMax));
1457  //v3 = _mm_cvtps_epi32(_mm_min_ps(_mm_max_ps(v.v3, vMin), vMax));
1458  v0 = _mm_cvtps_epi32(v.v0);
1459  v1 = _mm_cvtps_epi32(v.v1);
1460  v2 = _mm_cvtps_epi32(v.v2);
1461  v3 = _mm_cvtps_epi32(v.v3);
1462  }
1463 
1464  inline icl512i32s& operator=(const icl512i32s &v) {
1465  v0 = v.v0;
1466  v1 = v.v1;
1467  v2 = v.v2;
1468  v3 = v.v3;
1469  return *this;
1470  }
1471 
1472  inline icl512i32s& operator=(const Icl512i &v) {
1473  v0 = v.v0;
1474  v1 = v.v1;
1475  v2 = v.v2;
1476  v3 = v.v3;
1477  return *this;
1478  }
1479 
1480  inline icl512i32s& operator+=(const icl512i32s &v) {
1481  v0 = _mm_add_epi32(v0, v.v0);
1482  v1 = _mm_add_epi32(v1, v.v1);
1483  v2 = _mm_add_epi32(v2, v.v2);
1484  v3 = _mm_add_epi32(v3, v.v3);
1485  return *this;
1486  }
1487 
1488  inline icl512i32s& operator-=(const icl512i32s &v) {
1489  v0 = _mm_sub_epi32(v0, v.v0);
1490  v1 = _mm_sub_epi32(v1, v.v1);
1491  v2 = _mm_sub_epi32(v2, v.v2);
1492  v3 = _mm_sub_epi32(v3, v.v3);
1493  return *this;
1494  }
1495 
1496  inline void store(icl32s *v) const {
1497  _mm_store_si128((__m128i*)v, v0);
1498  _mm_store_si128((__m128i*)(v + 4), v1);
1499  _mm_store_si128((__m128i*)(v + 8), v1);
1500  _mm_store_si128((__m128i*)(v + 12), v1);
1501  }
1502 
1503  inline void storeu(icl32s *v) const {
1504  _mm_storeu_si128((__m128i*)v, v0);
1505  _mm_storeu_si128((__m128i*)(v + 4), v1);
1506  _mm_storeu_si128((__m128i*)(v + 8), v1);
1507  _mm_storeu_si128((__m128i*)(v + 12), v1);
1508  }
1509 
1510  inline void store(icl32u *v) const {
1511  _mm_store_si128((__m128i*)v, v0);
1512  _mm_store_si128((__m128i*)(v + 4), v1);
1513  _mm_store_si128((__m128i*)(v + 8), v1);
1514  _mm_store_si128((__m128i*)(v + 12), v1);
1515  }
1516 
1517  inline void storeu(icl32u *v) const {
1518  _mm_storeu_si128((__m128i*)v, v0);
1519  _mm_storeu_si128((__m128i*)(v + 4), v1);
1520  _mm_storeu_si128((__m128i*)(v + 8), v1);
1521  _mm_storeu_si128((__m128i*)(v + 12), v1);
1522  }
1523  };
1524 
1526  struct icl128d : Icl128d {
1527  inline icl128d() {
1528  }
1529 
1530  inline icl128d(const __m128d &v) {
1531  v0 = v;
1532  }
1533 
1534  inline icl128d(const icl64f *v) {
1535  v0 = _mm_loadu_pd(v);
1536  }
1537 
1538  inline icl128d(const icl64f v) {
1539  v0 = _mm_set1_pd(v);
1540  }
1541 
1542  inline icl128d(const icl128d &v) {
1543  v0 = v.v0;
1544  }
1545 
1546  inline icl128d& operator=(const __m128d &v) {
1547  v0 = v;
1548  return *this;
1549  }
1550 
1551  inline icl128d& operator=(const icl64f *v) {
1552  v0 = _mm_loadu_pd(v);
1553  return *this;
1554  }
1555 
1556  inline icl128d& operator=(const icl128d &v) {
1557  v0 = v.v0;
1558  return *this;
1559  }
1560 
1561  inline operator __m128d () const {
1562  return v0;
1563  }
1564 
1565  inline icl128d& operator+=(const Icl128d &v) {
1566  v0 = _mm_add_pd(v0, v.v0);
1567  return *this;
1568  }
1569 
1570  inline icl128d& operator-=(const Icl128d &v) {
1571  v0 = _mm_sub_pd(v0, v.v0);
1572  return *this;
1573  }
1574 
1575  inline icl128d& operator*=(const Icl128d &v) {
1576  v0 = _mm_mul_pd(v0, v.v0);
1577  return *this;
1578  }
1579 
1580  inline icl128d& operator/=(const Icl128d &v) {
1581  v0 = _mm_div_pd(v0, v.v0);
1582  return *this;
1583  }
1584 
1585  inline icl128d& operator&=(const Icl128d &v) {
1586  v0 = _mm_and_pd(v0, v.v0);
1587  return *this;
1588  }
1589 
1590  inline icl128d& operator|=(const Icl128d &v) {
1591  v0 = _mm_or_pd(v0, v.v0);
1592  return *this;
1593  }
1594 
1595  inline icl128d& operator^=(const Icl128d &v) {
1596  v0 = _mm_xor_pd(v0, v.v0);
1597  return *this;
1598  }
1599 
1600  inline icl128d& andnot(const Icl128d &v) {
1601  v0 = _mm_andnot_pd(v.v0, v0);
1602  return *this;
1603  }
1604 
1605  inline void store(icl64f *v) const {
1606  _mm_store_pd(v, v0);
1607  }
1608 
1609  inline void storeu(icl64f *v) const {
1610  _mm_storeu_pd(v, v0);
1611  }
1612  };
1613 
1615  struct icl256d : Icl512d {
1616  // TODO
1617  };
1618 
1619  // type for 8 icl64f values
1620  struct icl512d : Icl512d {
1621  // TODO
1622  };
1623 
1625  struct icl1024d : Icl1024d {
1626  // TODO
1627  };
1628 
1629  // -- advanced SSE types -- //
1630 
1631 
1632  // ++ operations on SSE types ++ //
1633 
1634  // ++ arithmetic operations ++ //
1635 
1636  inline icl128 operator+(const icl128 &lv, const icl128 &rv) {
1637  icl128 ret = lv;
1638  return ret += rv;
1639  }
1640 
1641  inline icl128 operator-(const icl128 &lv, const icl128 &rv) {
1642  icl128 ret = lv;
1643  return ret -= rv;
1644  }
1645 
1646  inline icl128 operator*(const icl128 &lv, const icl128 &rv) {
1647  icl128 ret = lv;
1648  return ret *= rv;
1649  }
1650 
1651 #ifndef __clang__
1652  inline icl128 operator/(const icl128 &lv, const icl128 &rv) {
1653  icl128 ret = lv;
1654  return ret /= rv;
1655  }
1656 #endif
1657 
1658  inline icl256 operator+(const icl256 &lv, const icl256 &rv) {
1659  icl256 ret = lv;
1660  return ret += rv;
1661  }
1662 
1663  inline icl256 operator-(const icl256 &lv, const icl256 &rv) {
1664  icl256 ret = lv;
1665  return ret -= rv;
1666  }
1667 
1668  inline icl256 operator*(const icl256 &lv, const icl256 &rv) {
1669  icl256 ret = lv;
1670  return ret *= rv;
1671  }
1672 
1673  inline icl256 operator/(const icl256 &lv, const icl256 &rv) {
1674  icl256 ret = lv;
1675  return ret /= rv;
1676  }
1677 
1678  inline icl512 operator+(const icl512 &lv, const icl512 &rv) {
1679  icl512 ret = lv;
1680  return ret += rv;
1681  }
1682 
1683  inline icl512 operator-(const icl512 &lv, const icl512 &rv) {
1684  icl512 ret = lv;
1685  return ret -= rv;
1686  }
1687 
1688  inline icl512 operator*(const icl512 &lv, const icl512 &rv) {
1689  icl512 ret = lv;
1690  return ret *= rv;
1691  }
1692 
1693  inline icl512 operator/(const icl512 &lv, const icl512 &rv) {
1694  icl512 ret = lv;
1695  return ret /= rv;
1696  }
1697 
1698  // -- arithmetic operations -- //
1699 
1700  // ++ comparison operations ++ //
1701 
1702  inline icl128 operator==(const icl128 &lv, const icl128 &rv) {
1703  icl128 ret;
1704  ret.v0 = _mm_cmpeq_ps(lv.v0, rv.v0);
1705  return ret;
1706  }
1707 
1708  inline icl128 operator!=(const icl128 &lv, const icl128 &rv) {
1709  icl128 ret;
1710  ret.v0 = _mm_cmpneq_ps(lv.v0, rv.v0);
1711  return ret;
1712  }
1713 
1714  inline icl128 operator<(const icl128 &lv, const icl128 &rv) {
1715  icl128 ret;
1716  ret.v0 = _mm_cmplt_ps(lv.v0, rv.v0);
1717  return ret;
1718  }
1719 
1720  inline icl128 operator>(const icl128 &lv, const icl128 &rv) {
1721  icl128 ret;
1722  ret.v0 = _mm_cmpgt_ps(lv.v0, rv.v0);
1723  return ret;
1724  }
1725 
1726  inline icl128 operator<=(const icl128 &lv, const icl128 &rv) {
1727  icl128 ret;
1728  ret.v0 = _mm_cmple_ps(lv.v0, rv.v0);
1729  return ret;
1730  }
1731 
1732  inline icl128 operator>=(const icl128 &lv, const icl128 &rv) {
1733  icl128 ret;
1734  ret.v0 = _mm_cmpge_ps(lv.v0, rv.v0);
1735  return ret;
1736  }
1737 
1738  inline icl256 operator==(const icl256 &lv, const icl256 &rv) {
1739  icl256 ret;
1740  ret.v0 = _mm_cmpeq_ps(lv.v0, rv.v0);
1741  ret.v1 = _mm_cmpeq_ps(lv.v1, rv.v1);
1742  return ret;
1743  }
1744 
1745  inline icl256 operator!=(const icl256 &lv, const icl256 &rv) {
1746  icl256 ret;
1747  ret.v0 = _mm_cmpneq_ps(lv.v0, rv.v0);
1748  ret.v1 = _mm_cmpneq_ps(lv.v1, rv.v1);
1749  return ret;
1750  }
1751 
1752  inline icl256 operator<(const icl256 &lv, const icl256 &rv) {
1753  icl256 ret;
1754  ret.v0 = _mm_cmplt_ps(lv.v0, rv.v0);
1755  ret.v1 = _mm_cmplt_ps(lv.v1, rv.v1);
1756  return ret;
1757  }
1758 
1759  inline icl256 operator>(const icl256 &lv, const icl256 &rv) {
1760  icl256 ret;
1761  ret.v0 = _mm_cmpgt_ps(lv.v0, rv.v0);
1762  ret.v1 = _mm_cmpgt_ps(lv.v1, rv.v1);
1763  return ret;
1764  }
1765 
1766  inline icl256 operator<=(const icl256 &lv, const icl256 &rv) {
1767  icl256 ret;
1768  ret.v0 = _mm_cmple_ps(lv.v0, rv.v0);
1769  ret.v1 = _mm_cmple_ps(lv.v1, rv.v1);
1770  return ret;
1771  }
1772 
1773  inline icl256 operator>=(const icl256 &lv, const icl256 &rv) {
1774  icl256 ret;
1775  ret.v0 = _mm_cmpge_ps(lv.v0, rv.v0);
1776  ret.v1 = _mm_cmpge_ps(lv.v1, rv.v1);
1777  return ret;
1778  }
1779 
1780  inline icl512 operator==(const icl512 &lv, const icl512 &rv) {
1781  icl512 ret;
1782  ret.v0 = _mm_cmpeq_ps(lv.v0, rv.v0);
1783  ret.v1 = _mm_cmpeq_ps(lv.v1, rv.v1);
1784  ret.v2 = _mm_cmpeq_ps(lv.v2, rv.v2);
1785  ret.v3 = _mm_cmpeq_ps(lv.v3, rv.v3);
1786  return ret;
1787  }
1788 
1789  inline icl512 operator!=(const icl512 &lv, const icl512 &rv) {
1790  icl512 ret;
1791  ret.v0 = _mm_cmpneq_ps(lv.v0, rv.v0);
1792  ret.v1 = _mm_cmpneq_ps(lv.v1, rv.v1);
1793  ret.v2 = _mm_cmpneq_ps(lv.v2, rv.v2);
1794  ret.v3 = _mm_cmpneq_ps(lv.v3, rv.v3);
1795  return ret;
1796  }
1797 
1798  inline icl512 operator<(const icl512 &lv, const icl512 &rv) {
1799  icl512 ret;
1800  ret.v0 = _mm_cmplt_ps(lv.v0, rv.v0);
1801  ret.v1 = _mm_cmplt_ps(lv.v1, rv.v1);
1802  ret.v2 = _mm_cmplt_ps(lv.v2, rv.v2);
1803  ret.v3 = _mm_cmplt_ps(lv.v3, rv.v3);
1804  return ret;
1805  }
1806 
1807  inline icl512 operator>(const icl512 &lv, const icl512 &rv) {
1808  icl512 ret;
1809  ret.v0 = _mm_cmpgt_ps(lv.v0, rv.v0);
1810  ret.v1 = _mm_cmpgt_ps(lv.v1, rv.v1);
1811  ret.v2 = _mm_cmpgt_ps(lv.v2, rv.v2);
1812  ret.v3 = _mm_cmpgt_ps(lv.v3, rv.v3);
1813  return ret;
1814  }
1815 
1816  inline icl512 operator<=(const icl512 &lv, const icl512 &rv) {
1817  icl512 ret;
1818  ret.v0 = _mm_cmple_ps(lv.v0, rv.v0);
1819  ret.v1 = _mm_cmple_ps(lv.v1, rv.v1);
1820  ret.v2 = _mm_cmple_ps(lv.v2, rv.v2);
1821  ret.v3 = _mm_cmple_ps(lv.v3, rv.v3);
1822  return ret;
1823  }
1824 
1825  inline icl512 operator>=(const icl512 &lv, const icl512 &rv) {
1826  icl512 ret;
1827  ret.v0 = _mm_cmpge_ps(lv.v0, rv.v0);
1828  ret.v1 = _mm_cmpge_ps(lv.v1, rv.v1);
1829  ret.v2 = _mm_cmpge_ps(lv.v2, rv.v2);
1830  ret.v3 = _mm_cmpge_ps(lv.v3, rv.v3);
1831  return ret;
1832  }
1833 
1834  // -- comparison operations -- //
1835 
1836  // ++ logical operations ++ //
1837 
1838  inline icl128 operator&(const icl128 &lv, const icl128 &rv) {
1839  icl128 ret;
1840  ret.v0 = _mm_and_ps(lv.v0, rv.v0);
1841  return ret;
1842  }
1843 
1844  inline icl128 operator|(const icl128 &lv, const icl128 &rv) {
1845  icl128 ret;
1846  ret.v0 = _mm_or_ps(lv.v0, rv.v0);
1847  return ret;
1848  }
1849 
1850  inline icl128 operator^(const icl128 &lv, const icl128 &rv) {
1851  icl128 ret;
1852  ret.v0 = _mm_xor_ps(lv.v0, rv.v0);
1853  return ret;
1854  }
1855 
1856  inline icl128 andnot(const icl128 &lv, const icl128 &rv) {
1857  icl128 ret;
1858  ret.v0 = _mm_andnot_ps(rv.v0, lv.v0);
1859  return ret;
1860  }
1861 
1862  inline Icl128i operator&(const Icl128i &lv, const Icl128i &rv) {
1863  Icl128i ret;
1864  ret.v0 = _mm_and_si128(lv.v0, rv.v0);
1865  return ret;
1866  }
1867 
1868  inline Icl128i operator|(const Icl128i &lv, const Icl128i &rv) {
1869  Icl128i ret;
1870  ret.v0 = _mm_or_si128(lv.v0, rv.v0);
1871  return ret;
1872  }
1873 
1874  inline Icl128i operator^(const Icl128i &lv, const Icl128i &rv) {
1875  Icl128i ret;
1876  ret.v0 = _mm_xor_si128(lv.v0, rv.v0);
1877  return ret;
1878  }
1879 
1880  inline Icl128i andnot(const Icl128i &lv, const Icl128i &rv) {
1881  Icl128i ret;
1882  ret.v0 = _mm_andnot_si128(rv.v0, lv.v0);
1883  return ret;
1884  }
1885 
1886  inline icl256 operator&(const icl256 &lv, const icl256 &rv) {
1887  icl256 ret;
1888  ret.v0 = _mm_and_ps(lv.v0, rv.v0);
1889  ret.v1 = _mm_and_ps(lv.v1, rv.v1);
1890  return ret;
1891  }
1892 
1893  inline icl256 operator|(const icl256 &lv, const icl256 &rv) {
1894  icl256 ret;
1895  ret.v0 = _mm_or_ps(lv.v0, rv.v0);
1896  ret.v1 = _mm_or_ps(lv.v1, rv.v1);
1897  return ret;
1898  }
1899 
1900  inline icl256 operator^(const icl256 &lv, const icl256 &rv) {
1901  icl256 ret;
1902  ret.v0 = _mm_xor_ps(lv.v0, rv.v0);
1903  ret.v1 = _mm_xor_ps(lv.v1, rv.v1);
1904  return ret;
1905  }
1906 
1907  inline icl256 andnot(const icl256 &lv, const icl256 &rv) {
1908  icl256 ret;
1909  ret.v0 = _mm_andnot_ps(rv.v0, lv.v0);
1910  ret.v1 = _mm_andnot_ps(rv.v1, lv.v1);
1911  return ret;
1912  }
1913 
1914  inline Icl256i operator&(const Icl256i &lv, const Icl256i &rv) {
1915  Icl256i ret;
1916  ret.v0 = _mm_and_si128(lv.v0, rv.v0);
1917  ret.v1 = _mm_and_si128(lv.v1, rv.v1);
1918  return ret;
1919  }
1920 
1921  inline Icl256i operator|(const Icl256i &lv, const Icl256i &rv) {
1922  Icl256i ret;
1923  ret.v0 = _mm_or_si128(lv.v0, rv.v0);
1924  ret.v1 = _mm_or_si128(lv.v1, rv.v1);
1925  return ret;
1926  }
1927 
1928  inline Icl256i operator^(const Icl256i &lv, const Icl256i &rv) {
1929  Icl256i ret;
1930  ret.v0 = _mm_xor_si128(lv.v0, rv.v0);
1931  ret.v1 = _mm_xor_si128(lv.v1, rv.v1);
1932  return ret;
1933  }
1934 
1935  inline Icl256i andnot(const Icl256i &lv, const Icl256i &rv) {
1936  Icl256i ret;
1937  ret.v0 = _mm_andnot_si128(rv.v0, lv.v0);
1938  ret.v1 = _mm_andnot_si128(rv.v1, lv.v1);
1939  return ret;
1940  }
1941 
1942  inline icl512 operator&(const icl512 &lv, const icl512 &rv) {
1943  icl512 ret;
1944  ret.v0 = _mm_and_ps(lv.v0, rv.v0);
1945  ret.v1 = _mm_and_ps(lv.v1, rv.v1);
1946  ret.v2 = _mm_and_ps(lv.v2, rv.v2);
1947  ret.v3 = _mm_and_ps(lv.v3, rv.v3);
1948  return ret;
1949  }
1950 
1951  inline icl512 operator|(const icl512 &lv, const icl512 &rv) {
1952  icl512 ret;
1953  ret.v0 = _mm_or_ps(lv.v0, rv.v0);
1954  ret.v1 = _mm_or_ps(lv.v1, rv.v1);
1955  ret.v2 = _mm_or_ps(lv.v2, rv.v2);
1956  ret.v3 = _mm_or_ps(lv.v3, rv.v3);
1957  return ret;
1958  }
1959 
1960  inline icl512 operator^(const icl512 &lv, const icl512 &rv) {
1961  icl512 ret;
1962  ret.v0 = _mm_xor_ps(lv.v0, rv.v0);
1963  ret.v1 = _mm_xor_ps(lv.v1, rv.v1);
1964  ret.v2 = _mm_xor_ps(lv.v2, rv.v2);
1965  ret.v3 = _mm_xor_ps(lv.v3, rv.v3);
1966  return ret;
1967  }
1968 
1969  inline icl512 andnot(const icl512 &lv, const icl512 &rv) {
1970  icl512 ret;
1971  ret.v0 = _mm_andnot_ps(rv.v0, lv.v0);
1972  ret.v1 = _mm_andnot_ps(rv.v1, lv.v1);
1973  ret.v2 = _mm_andnot_ps(rv.v2, lv.v2);
1974  ret.v3 = _mm_andnot_ps(rv.v3, lv.v3);
1975  return ret;
1976  }
1977 
1978  inline Icl512i operator&(const Icl512i &lv, const Icl512i &rv) {
1979  Icl512i ret;
1980  ret.v0 = _mm_and_si128(lv.v0, rv.v0);
1981  ret.v1 = _mm_and_si128(lv.v1, rv.v1);
1982  ret.v2 = _mm_and_si128(lv.v2, rv.v2);
1983  ret.v3 = _mm_and_si128(lv.v3, rv.v3);
1984  return ret;
1985  }
1986 
1987  inline Icl512i operator|(const Icl512i &lv, const Icl512i &rv) {
1988  Icl512i ret;
1989  ret.v0 = _mm_or_si128(lv.v0, rv.v0);
1990  ret.v1 = _mm_or_si128(lv.v1, rv.v1);
1991  ret.v2 = _mm_or_si128(lv.v2, rv.v2);
1992  ret.v3 = _mm_or_si128(lv.v3, rv.v3);
1993  return ret;
1994  }
1995 
1996  inline Icl512i operator^(const Icl512i &lv, const Icl512i &rv) {
1997  Icl512i ret;
1998  ret.v0 = _mm_xor_si128(lv.v0, rv.v0);
1999  ret.v1 = _mm_xor_si128(lv.v1, rv.v1);
2000  ret.v2 = _mm_xor_si128(lv.v2, rv.v2);
2001  ret.v3 = _mm_xor_si128(lv.v3, rv.v3);
2002  return ret;
2003  }
2004 
2005  inline Icl512i andnot(const Icl512i &lv, const Icl512i &rv) {
2006  Icl512i ret;
2007  ret.v0 = _mm_andnot_si128(rv.v0, lv.v0);
2008  ret.v1 = _mm_andnot_si128(rv.v1, lv.v1);
2009  ret.v2 = _mm_andnot_si128(rv.v2, lv.v2);
2010  ret.v3 = _mm_andnot_si128(rv.v3, lv.v3);
2011  return ret;
2012  }
2013 
2014  // -- logical operations -- //
2015 
2016  // ++ shift operetions ++ //
2017 
2018  inline Icl128i& operator<<(Icl128i &v, const int i) {
2019  v.v0 = _mm_slli_epi32(v.v0, i);
2020  return v;
2021  }
2022 
2023  inline Icl128i& operator>>(Icl128i &v, const int i) {
2024  v.v0 = _mm_srai_epi32(v.v0, i);
2025  return v;
2026  }
2027 
2028  inline Icl256i& operator<<(Icl256i &v, const int i) {
2029  v.v0 = _mm_slli_epi32(v.v0, i);
2030  v.v1 = _mm_slli_epi32(v.v1, i);
2031  return v;
2032  }
2033 
2034  inline Icl256i& operator>>(Icl256i &v, const int i) {
2035  v.v0 = _mm_srai_epi32(v.v0, i);
2036  v.v1 = _mm_srai_epi32(v.v1, i);
2037  return v;
2038  }
2039 
2040  inline Icl512i& operator<<(Icl512i &v, const int i) {
2041  v.v0 = _mm_slli_epi32(v.v0, i);
2042  v.v1 = _mm_slli_epi32(v.v1, i);
2043  v.v2 = _mm_slli_epi32(v.v2, i);
2044  v.v3 = _mm_slli_epi32(v.v3, i);
2045  return v;
2046  }
2047 
2048  inline Icl512i& operator>>(Icl512i &v, const int i) {
2049  v.v0 = _mm_srai_epi32(v.v0, i);
2050  v.v1 = _mm_srai_epi32(v.v1, i);
2051  v.v2 = _mm_srai_epi32(v.v2, i);
2052  v.v3 = _mm_srai_epi32(v.v3, i);
2053  return v;
2054  }
2055 
2056  // -- shift operations -- //
2057 
2058  // ++ min-max operations ++ //
2059 
2060  inline icl128i8u min(const icl128i8u &lv, const icl128i8u &rv) {
2061  icl128i8u ret;
2062  ret.v0 = _mm_min_epu8(lv.v0, rv.v0);
2063  return ret;
2064  }
2065 
2066  inline icl128i8u max(const icl128i8u &lv, const icl128i8u &rv) {
2067  icl128i8u ret;
2068  ret.v0 = _mm_max_epu8(lv.v0, rv.v0);
2069  return ret;
2070  }
2071 
2072  inline icl128i16s min(const icl128i16s &lv, const icl128i16s &rv) {
2073  icl128i16s ret;
2074  ret.v0 = _mm_min_epi16(lv.v0, rv.v0);
2075  return ret;
2076  }
2077 
2078  inline icl128i16s max(const icl128i16s &lv, const icl128i16s &rv) {
2079  icl128i16s ret;
2080  ret.v0 = _mm_max_epi16(lv.v0, rv.v0);
2081  return ret;
2082  }
2083 
2084  inline icl256i16s min(const icl256i16s &lv, const icl256i16s &rv) {
2085  icl256i16s ret;
2086  ret.v0 = _mm_min_epi16(lv.v0, rv.v0);
2087  ret.v1 = _mm_min_epi16(lv.v1, rv.v1);
2088  return ret;
2089  }
2090 
2091  inline icl256i16s max(const icl256i16s &lv, const icl256i16s &rv) {
2092  icl256i16s ret;
2093  ret.v0 = _mm_max_epi16(lv.v0, rv.v0);
2094  ret.v1 = _mm_max_epi16(lv.v1, rv.v1);
2095  return ret;
2096  }
2097 
2098  inline icl128 min(const icl128 &lv, const icl128 &rv) {
2099  icl128 ret;
2100  ret.v0 = _mm_min_ps(lv.v0, rv.v0);
2101  return ret;
2102  }
2103 
2104  inline icl128 max(const icl128 &lv, const icl128 &rv) {
2105  icl128 ret;
2106  ret.v0 = _mm_max_ps(lv.v0, rv.v0);
2107  return ret;
2108  }
2109 
2110  inline icl256 min(const icl256 &lv, const icl256 &rv) {
2111  icl256 ret;
2112  ret.v0 = _mm_min_ps(lv.v0, rv.v0);
2113  ret.v1 = _mm_min_ps(lv.v1, rv.v1);
2114  return ret;
2115  }
2116 
2117  inline icl256 max(const icl256 &lv, const icl256 &rv) {
2118  icl256 ret;
2119  ret.v0 = _mm_max_ps(lv.v0, rv.v0);
2120  ret.v1 = _mm_max_ps(lv.v1, rv.v1);
2121  return ret;
2122  }
2123 
2124  inline icl512 min(const icl512 &lv, const icl512 &rv) {
2125  icl512 ret;
2126  ret.v0 = _mm_min_ps(lv.v0, rv.v0);
2127  ret.v1 = _mm_min_ps(lv.v1, rv.v1);
2128  ret.v2 = _mm_min_ps(lv.v2, rv.v2);
2129  ret.v3 = _mm_min_ps(lv.v3, rv.v3);
2130  return ret;
2131  }
2132 
2133  inline icl512 max(const icl512 &lv, const icl512 &rv) {
2134  icl512 ret;
2135  ret.v0 = _mm_max_ps(lv.v0, rv.v0);
2136  ret.v1 = _mm_max_ps(lv.v1, rv.v1);
2137  ret.v2 = _mm_max_ps(lv.v2, rv.v2);
2138  ret.v3 = _mm_max_ps(lv.v3, rv.v3);
2139  return ret;
2140  }
2141 
2142  // -- min-max operations -- //
2143 
2144 
2145  // ++ absosulte values ++ //
2146 
2147  #ifdef ICL_HAVE_SSE3
2148  inline icl128i8u abs(const icl128i8u &v) {
2149  icl128i8u ret;
2150  ret.v0 = _mm_abs_epi8(v.v0);
2151  return ret;
2152  }
2153 
2154  inline icl128i16s abs(const icl128i16s &v) {
2155  icl128i16s ret;
2156  ret.v0 = _mm_abs_epi16(v.v0);
2157  return ret;
2158  }
2159 
2160  inline icl128i32s abs(const icl128i32s &v) {
2161  icl128i32s ret;
2162  ret.v0 = _mm_abs_epi32(v.v0);
2163  return ret;
2164  }
2165 
2166  inline icl256i16s abs(const icl256i16s &v) {
2167  icl256i16s ret;
2168  ret.v0 = _mm_abs_epi16(v.v0);
2169  ret.v1 = _mm_abs_epi16(v.v1);
2170  return ret;
2171  }
2172 
2173  inline icl256i32s abs(const icl256i32s &v) {
2174  icl256i32s ret;
2175  ret.v0 = _mm_abs_epi32(v.v0);
2176  ret.v1 = _mm_abs_epi32(v.v1);
2177  return ret;
2178  }
2179 
2180  inline icl512i32s abs(const icl512i32s &v) {
2181  icl512i32s ret;
2182  ret.v0 = _mm_abs_epi32(v.v0);
2183  ret.v1 = _mm_abs_epi32(v.v1);
2184  ret.v2 = _mm_abs_epi32(v.v2);
2185  ret.v3 = _mm_abs_epi32(v.v3);
2186  return ret;
2187  }
2188  #else
2189  // TODO: without SSE3
2190  #endif
2191 
2192  inline icl128 abs(const icl128 &v) {
2193  icl128 ret;
2194  ret.v0 = _mm_andnot_ps(icl128(-0.0f), v.v0);
2195  return ret;
2196  }
2197 
2198  inline icl256 abs(const icl256 &v) {
2199  icl128 tmp(-0.0f);
2200  icl256 ret;
2201  ret.v0 = _mm_andnot_ps(tmp.v0, v.v0);
2202  ret.v1 = _mm_andnot_ps(tmp.v0, v.v1);
2203  return ret;
2204  }
2205 
2206  inline icl512 abs(const icl512 &v) {
2207  icl128 tmp(-0.0f);
2208  icl512 ret;
2209  ret.v0 = _mm_andnot_ps(tmp.v0, v.v0);
2210  ret.v1 = _mm_andnot_ps(tmp.v0, v.v1);
2211  ret.v2 = _mm_andnot_ps(tmp.v0, v.v2);
2212  ret.v3 = _mm_andnot_ps(tmp.v0, v.v3);
2213  return ret;
2214  }
2215 
2216  // -- absosulte values -- //
2217 
2218 
2219  // ++ squared root ++ //
2220 
2221  inline icl128 sqrt(const icl128 &v) {
2222  icl128 r;
2223  r.v0 = _mm_sqrt_ps(v.v0);
2224  return r;
2225  }
2226 
2227  inline icl256 sqrt(const icl256 &v) {
2228  icl256 r;
2229  r.v0 = _mm_sqrt_ps(v.v0);
2230  r.v1 = _mm_sqrt_ps(v.v1);
2231  return r;
2232  }
2233 
2234  inline icl512 sqrt(const icl512 &v) {
2235  icl512 r;
2236  r.v0 = _mm_sqrt_ps(v.v0);
2237  r.v1 = _mm_sqrt_ps(v.v1);
2238  r.v2 = _mm_sqrt_ps(v.v2);
2239  r.v3 = _mm_sqrt_ps(v.v3);
2240  return r;
2241  }
2242 
2243  inline icl128d sqrt(const icl128d &v) {
2244  icl128d r;
2245  r.v0 = _mm_sqrt_pd(v.v0);
2246  return r;
2247  }
2248 
2249  inline icl256d sqrt(const icl256d &v) {
2250  icl256d r;
2251  r.v0 = _mm_sqrt_pd(v.v0);
2252  r.v1 = _mm_sqrt_pd(v.v1);
2253  return r;
2254  }
2255 
2256  inline icl512d sqrt(const icl512d &v) {
2257  icl512d r;
2258  r.v0 = _mm_sqrt_pd(v.v0);
2259  r.v1 = _mm_sqrt_pd(v.v1);
2260  r.v2 = _mm_sqrt_pd(v.v2);
2261  r.v3 = _mm_sqrt_pd(v.v3);
2262  return r;
2263  }
2264 
2265  inline icl1024d sqrt(const icl1024d &v) {
2266  icl1024d r;
2267  r.v0 = _mm_sqrt_pd(v.v0);
2268  r.v1 = _mm_sqrt_pd(v.v1);
2269  r.v2 = _mm_sqrt_pd(v.v2);
2270  r.v3 = _mm_sqrt_pd(v.v3);
2271  r.v4 = _mm_sqrt_pd(v.v4);
2272  r.v5 = _mm_sqrt_pd(v.v5);
2273  r.v6 = _mm_sqrt_pd(v.v6);
2274  r.v7 = _mm_sqrt_pd(v.v7);
2275  return r;
2276  }
2277 
2278  // -- squared root -- //
2279 
2280 
2281  // ++ cube root ++ //
2282 
2283  inline icl128 cbrt(const icl128 &v) {
2284  icl128i32s tmp = icl128i32s(_mm_castps_si128(v));
2285  tmp = tmp / icl128i32s(3) + icl128i32s(709921077);
2286  icl128 a = icl128(_mm_castsi128_ps(tmp));
2287  icl128 a3 = a * a * a;
2288  return a * (a3 + v + v) * (a3 + a3 + v).rcp();
2289  }
2290 
2291  inline icl256 cbrt(const icl256 &v) {
2292  __m128i t0 = _mm_castps_si128(v.v0);
2293  __m128i t1 = _mm_castps_si128(v.v1);
2294  icl256i32s tmp = icl256i32s(t0, t1);
2295  tmp = tmp / icl256i32s(3) + icl256i32s(709921077);
2296  icl256 a = icl256(_mm_castsi128_ps(tmp.v0),
2297  _mm_castsi128_ps(tmp.v1));
2298  icl256 a3 = a * a * a;
2299  return a * (a3 + v + v) * (a3 + a3 + v).rcp();
2300  }
2301 
2302  inline icl512 cbrt(const icl512 &v) {
2303  __m128i t0 = _mm_castps_si128(v.v0);
2304  __m128i t1 = _mm_castps_si128(v.v1);
2305  __m128i t2 = _mm_castps_si128(v.v2);
2306  __m128i t3 = _mm_castps_si128(v.v3);
2307  icl512i32s tmp = icl512i32s(t0, t1, t2, t3);
2308  tmp = tmp / icl512i32s(3) + icl512i32s(709921077);
2309  icl512 a = icl512(_mm_castsi128_ps(tmp.v0),
2310  _mm_castsi128_ps(tmp.v1),
2311  _mm_castsi128_ps(tmp.v2),
2312  _mm_castsi128_ps(tmp.v3));
2313  icl512 a3 = a * a * a;
2314  return a * (a3 + v + v) * (a3 + a3 + v).rcp();
2315  }
2316 
2317  // -- cube root -- //
2318 
2319  // -- operations on SSE types -- //
2320 
2321  typedef icl128 icl32fx4;
2322  typedef icl256 icl32fx8;
2323  typedef icl512 icl32fx16;
2324  typedef icl128i8u icl8ux16;
2325  typedef icl128i16s icl16sx8;
2326  typedef icl128i32s icl32sx4;
2327  typedef icl256i16s icl16sx16;
2328  typedef icl256i32s icl32sx8;
2329  typedef icl512i32s icl32sx16;
2330  typedef icl128d icl64fx2;
2331  typedef icl256d icl64fx4;
2332  typedef icl512d icl64fx8;
2333  typedef icl1024d icl64fx16;
2334 
2335  #endif
2336 
2337  } // namespace utils
2338 }
ICLQt_API ImgQ sqrt(const ImgQ &image)
calls sqrt( each pixel)
undocument this line if you encounter any issues!
Definition: Any.h:37
Ipp8u icl8u
8Bit unsigned integer type for the ICL
Definition: BasicTypes.h:64
ICLQt_API ImgQ operator/(const ImgQ &a, const ImgQ &b)
divides two images pixel-wise
ICLQt_API ImgQ operator|(const ImgQ &a, const ImgQ &b)
channel concatenation of images
ICLQt_API ImgQ operator-(const ImgQ &a, const ImgQ &b)
subtracts two images pixel-wise
Ipp32s icl32s
32bit signed integer type for the ICL
Definition: BasicTypes.h:58
FixedMatrix< T, V_COLS, M_ROWS_AND_COLS > & operator *=(FixedMatrix< T, V_COLS, M_ROWS_AND_COLS > &v, const FixedMatrix< T, M_ROWS_AND_COLS, M_ROWS_AND_COLS > &m)
Matrix multiplication (inplace)
Definition: FixedMatrix.h:959
Ipp32f icl32f
32Bit floating point type for the ICL
Definition: BasicTypes.h:55
Ipp64f icl64f
64Bit floating point type for the ICL
Definition: BasicTypes.h:52
ICLQt_API ImgQ abs(const ImgQ &image)
calls abs ( each pixel)
ICLUtils_API std::ostream & operator<<(std::ostream &s, const ConfigFile &cf)
Default ostream operator to put a ConfigFile into a stream.
ICLUtils_API std::istream & operator>>(std::istream &s, Point &p)
istream operator
uint32_t icl32u
32bit unsigned integer type for the ICL
Definition: BasicTypes.h:88
ICLQt_API ImgQ operator *(const ImgQ &a, const ImgQ &b)
multiplies two images pixel-wise
int8_t icl8s
8bit signed integer
Definition: BasicTypes.h:85
ICLQt_API ImgQ operator+(const ImgQ &a, const ImgQ &b)
adds two images pixel-wise
uint16_t icl16u
16bit unsigned integer type for the ICL
Definition: BasicTypes.h:91
Ipp16s icl16s
16bit signed integer type for the ICL (range [-32767, 32768 ])
Definition: BasicTypes.h:61