PandaRoot
P4_F32vec4.h
Go to the documentation of this file.
1 #ifndef L1Algo_F32vec4P4_H
2 #define L1Algo_F32vec4P4_H
3 
4 #include <iostream>
5 #include <cmath>
6 #include "xmmintrin.h"
7 #include "vec_arithmetic.h"
8 
9 /**********************************
10  *
11  * Vector of four single floats
12  *
13  **********************************/
14 
15 //#pragma pack(push,16)/* Must ensure class & union 16-B aligned */
16 
17 // typedef __m128 VectorFloat __attribute__ ((aligned(16)));
18 
19 const union {
20  float f;
21  unsigned int i;
22 } __f_one = {1.f};
23 
24 const union {
25  unsigned int i[4];
26  __m128 m;
27 } __f32vec4_abs_mask_cheat = {{0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}}, __f32vec4_sgn_mask_cheat = {{0x80000000, 0x80000000, 0x80000000, 0x80000000}},
29  __f32vec4_true_cheat = {{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}}, __f32vec4_false_cheat = {{0x00000000, 0x00000000, 0x00000000, 0x00000000}};
30 
31 #define _f32vec4_abs_mask (static_cast<F32vec4>(__f32vec4_abs_mask_cheat.m))
32 #define _f32vec4_sgn_mask (static_cast<F32vec4>(__f32vec4_sgn_mask_cheat.m))
33 #define _f32vec4_zero (static_cast<F32vec4>(__f32vec4_zero_cheat.m))
34 #define _f32vec4_one (static_cast<F32vec4>(__f32vec4_one_cheat.m))
35 #define _f32vec4_true (static_cast<F32vec4>(__f32vec4_true_cheat.m))
36 #define _f32vec4_false (static_cast<F32vec4>(__f32vec4_false_cheat.m))
37 
38 class F32vec4 {
39  public:
40  __m128 v;
41 
42  float &operator[](int i) { return (reinterpret_cast<float *>(&v))[i]; }
43  float operator[](int i) const { return (reinterpret_cast<const float *>(&v))[i]; }
44 
45  F32vec4() : v(_mm_set_ps1(0)) {}
46  F32vec4(const __m128 &a) : v(a) {}
47  F32vec4(const float &a) : v(_mm_set_ps1(a)) {}
48 
49  F32vec4(const float &f0, const float &f1, const float &f2, const float &f3) : v(_mm_set_ps(f3, f2, f1, f0)) {}
50 
51  /* Conversion function */
52  operator __m128() const { return v; } /* Convert to __m128 */
53 
54  /* Arithmetic Operators */
55  friend F32vec4 operator+(const F32vec4 &a, const F32vec4 &b) { return _mm_add_ps(a, b); }
56  friend F32vec4 operator-(const F32vec4 &a, const F32vec4 &b) { return _mm_sub_ps(a, b); }
57  friend F32vec4 operator*(const F32vec4 &a, const F32vec4 &b) { return _mm_mul_ps(a, b); }
58  friend F32vec4 operator/(const F32vec4 &a, const F32vec4 &b) { return _mm_div_ps(a, b); }
59 
60  /* Functions */
61  friend F32vec4 min(const F32vec4 &a, const F32vec4 &b) { return _mm_min_ps(a, b); }
62  friend F32vec4 max(const F32vec4 &a, const F32vec4 &b) { return _mm_max_ps(a, b); }
63 
64  /* Square Root */
65  friend F32vec4 sqrt(const F32vec4 &a) { return _mm_sqrt_ps(a); }
66 
67  /* Reciprocal( inverse) Square Root */
68  friend F32vec4 rsqrt(const F32vec4 &a) { return _mm_rsqrt_ps(a); }
69 
70  /* Reciprocal (inversion) */
71  // friend F32vec4 rcp ( const F32vec4 &a ){ return _mm_rcp_ps (a); }
72  /* Reciprocal (inversion) */
73  // friend F32vec4 rcp ( const F32vec4 &a ){ return 1. / a; }
74  /* NewtonRaphson Reciprocal
75  [2 * rcpps(x) - (x * rcpps(x) * rcpps(x))] */
76  friend F32vec4 rcp(const F32vec4 &a)
77  {
78  F32vec4 Ra0 = _mm_rcp_ps(a);
79  return _mm_sub_ps(_mm_add_ps(Ra0, Ra0), _mm_mul_ps(_mm_mul_ps(Ra0, a), Ra0));
80  }
81 
82  /* Absolute value */
83  friend F32vec4 fabs(const F32vec4 &a) { return _mm_and_ps(a, _f32vec4_abs_mask); }
84 
85  /* Sign */
86  friend F32vec4 sgn(const F32vec4 &a) { return _mm_or_ps(_mm_and_ps(a, _f32vec4_sgn_mask), _f32vec4_one); }
87  friend F32vec4 asgnb(const F32vec4 &a, const F32vec4 &b) { return _mm_or_ps(_mm_and_ps(b, _f32vec4_sgn_mask), a); }
88 
89  /* Logical */
90 
91  friend F32vec4 operator&(const F32vec4 &a, const F32vec4 &b)
92  { // mask returned
93  return _mm_and_ps(a, b);
94  }
95  friend F32vec4 operator|(const F32vec4 &a, const F32vec4 &b)
96  { // mask returned
97  return _mm_or_ps(a, b);
98  }
99  friend F32vec4 operator^(const F32vec4 &a, const F32vec4 &b)
100  { // mask returned
101  return _mm_xor_ps(a, b);
102  }
103  friend F32vec4 operator!(const F32vec4 &a)
104  { // mask returned
105  return _mm_xor_ps(a, _f32vec4_true);
106  }
107  // friend F32vec4 operator||( const F32vec4 &a, const F32vec4 &b ){ // mask returned
108  // return _mm_or_ps(a, b);
109  // }
110 
111  /* Comparison */
112 
113  friend F32vec4 operator<(const F32vec4 &a, const F32vec4 &b)
114  { // mask returned
115  return _mm_cmplt_ps(a, b);
116  }
117  friend F32vec4 operator<=(const F32vec4 &a, const F32vec4 &b)
118  { // mask returned
119  return _mm_cmple_ps(a, b);
120  }
121  friend F32vec4 operator>(const F32vec4 &a, const F32vec4 &b)
122  { // mask returned
123  return _mm_cmpgt_ps(a, b);
124  }
125  friend F32vec4 operator>=(const F32vec4 &a, const F32vec4 &b)
126  { // mask returned
127  return _mm_cmpge_ps(a, b);
128  }
129  friend F32vec4 operator==(const F32vec4 &a, const F32vec4 &b)
130  { // mask returned
131  return _mm_cmpeq_ps(a, b);
132  }
133 
134 #define if3(a, b, c) ((a) & (b)) | ((!(a)) & (c)) // analog (a) ? b : c
135 
136 #define NotEmpty(a) bool((a)[0]) | bool((a)[1]) | bool((a)[2]) | bool((a)[3])
137 #define Empty(a) !(bool((a)[0]) | bool((a)[1]) | bool((a)[2]) | bool((a)[3]))
138  // bool NotEmpty(const F32vec4 &a) { return a[0]||a[1]||a[2]||a[3]; }
139  // bool Empty(const F32vec4 &a) { return !(a[0]||a[1]||a[2]||a[3]); } // optimize
140  friend F32vec4 bool2int(const F32vec4 &a)
141  { // mask returned
142  return if3(a, 1, 0);
143  }
144 
145  /* Define all operators for consistensy */
146 
147  vec_arithmetic(F32vec4, float);
148 
149  /* Non intrinsic functions */
150 
151 #define _f1(A, F) F32vec4(F(A[0]), F(A[1]), F(A[2]), F(A[3]))
152 
153  friend F32vec4 exp(const F32vec4 &a) { return _f1(a, exp); }
154  friend F32vec4 log(const F32vec4 &a) { return _f1(a, log); }
155  friend F32vec4 sin(const F32vec4 &a) { return _f1(a, sin); }
156  friend F32vec4 cos(const F32vec4 &a) { return _f1(a, cos); }
157  friend F32vec4 acos(const F32vec4 &a) { return _f1(a, acos); }
158 
159 #undef _f1
160 
161  friend F32vec4 atan2(const F32vec4 &y, const F32vec4 &x)
162  {
163  const F32vec4 pi(3.1415926535897932);
164  const F32vec4 pi_2 = pi / 2;
165  const F32vec4 zero(0);
166 
167  const F32vec4 &xZero = F32vec4(x == zero);
168  const F32vec4 &yZero = F32vec4(y == zero);
169  const F32vec4 &xNeg = F32vec4(x < zero);
170  const F32vec4 &yNeg = F32vec4(y < zero);
171 
172  const F32vec4 &absX = fabs(x);
173  const F32vec4 &absY = fabs(y);
174 
175  F32vec4 a = absY / absX;
176  const F32vec4 pi_4 = pi / 4;
177  const F32vec4 &gt_tan_3pi_8 = F32vec4(a > F32vec4(2.414213562373095));
178  const F32vec4 &gt_tan_pi_8 = F32vec4(a > F32vec4(0.4142135623730950)) & F32vec4(!gt_tan_3pi_8);
179  const F32vec4 minusOne(-1);
180  F32vec4 b(zero);
181  b = (pi_2 & gt_tan_3pi_8) + (F32vec4(!gt_tan_3pi_8) & b);
182  b = (pi_4 & gt_tan_pi_8) + (F32vec4(!gt_tan_pi_8) & b);
183  a = (gt_tan_3pi_8 & (minusOne / a)) + (F32vec4(!gt_tan_3pi_8) & a);
184  a = (gt_tan_pi_8 & ((absY - absX) / (absY + absX))) + (F32vec4(!gt_tan_pi_8) & a);
185  const F32vec4 &a2 = a * a;
186  b += (((8.05374449538e-2 * a2 - 1.38776856032E-1) * a2 + 1.99777106478E-1) * a2 - 3.33329491539E-1) * a2 * a + a;
187  F32vec4 xyNeg = F32vec4(xNeg ^ yNeg);
188  b = (xyNeg & (-b)) + (F32vec4(!xyNeg) & b);
189  xyNeg = F32vec4(xNeg & !yNeg);
190  b = (xyNeg & (b + pi)) + (F32vec4(!xyNeg) & b);
191  xyNeg = F32vec4(xNeg & yNeg);
192  b = (xyNeg & (b - pi)) + (F32vec4(!xyNeg) & b);
193  xyNeg = F32vec4(xZero & yZero);
194  b = (xyNeg & zero) + (F32vec4(!xyNeg) & b);
195  xyNeg = F32vec4(xZero & yNeg);
196  b = (xyNeg & (-pi_2)) + (F32vec4(!xyNeg) & b);
197  return b;
198  }
199 
200  friend std::ostream &operator<<(std::ostream &strm, const F32vec4 &a)
201  {
202  strm << "[" << a[0] << " " << a[1] << " " << a[2] << " " << a[3] << "]";
203  return strm;
204  }
205 
206  friend std::istream &operator>>(std::istream &strm, F32vec4 &a)
207  {
208  float tmp;
209  strm >> tmp;
210  a = tmp;
211  return strm;
212  }
213 
214 } __attribute__((aligned(16)));
215 
216 typedef F32vec4 fvec;
217 typedef float fscal;
218 const int fvecLen = 4;
219 //#define fvec_true _f32vec4_true
220 //#define fvec_false _f32vec4_false
221 #define _fvecalignment __attribute__((aligned(16)))
222 
223 #include "std_alloc.h"
224 
225 #endif
const union @48 __f32vec4_true_cheat
double pi
Definition: f_Init.h:29
friend F32vec4 operator!(const F32vec4 &a)
Definition: P4_F32vec4.h:103
friend F32vec4 log(const F32vec4 &a)
Definition: P4_F32vec4.h:154
const union @47 __f_one
const union @48 __f32vec4_false_cheat
friend F32vec4 operator==(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:129
const union @48 __f32vec4_one_cheat
__m128 m
Definition: P4_F32vec4.h:26
F32vec4(const float &a)
Definition: P4_F32vec4.h:47
const union @48 __f32vec4_zero_cheat
friend F32vec4 max(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:62
#define _f32vec4_one
Definition: P4_F32vec4.h:34
friend F32vec4 rsqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:68
friend F32vec4 acos(const F32vec4 &a)
Definition: P4_F32vec4.h:157
friend std::ostream & operator<<(std::ostream &strm, const F32vec4 &a)
Definition: P4_F32vec4.h:200
#define _f1(A, F)
Definition: P4_F32vec4.h:114
unsigned int i
Definition: P4_F32vec4.h:21
vec_arithmetic(F32vec4, float)
friend F32vec4 operator>(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:121
friend F32vec4 operator+(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:55
friend F32vec4 exp(const F32vec4 &a)
Definition: P4_F32vec4.h:153
#define _f32vec4_true
Definition: P4_F32vec4.h:35
friend F32vec4 rcp(const F32vec4 &a)
Definition: P4_F32vec4.h:76
#define _f32vec4_sgn_mask
Definition: P4_F32vec4.h:32
friend F32vec4 operator/(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:58
friend F32vec4 asgnb(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:87
#define _f32vec4_abs_mask
Definition: P4_F32vec4.h:31
friend F32vec4 operator|(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:95
friend F32vec4 if3(const F32vec4 &a, const F32vec4 &b, const F32vec4 &c)
const union @48 __f32vec4_sgn_mask_cheat
friend F32vec4 atan2(const F32vec4 &y, const F32vec4 &x)
Definition: P4_F32vec4.h:161
friend F32vec4 operator<(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:113
float operator[](int i) const
Definition: P4_F32vec4.h:43
friend F32vec4 bool2int(const F32vec4 &a)
Definition: P4_F32vec4.h:140
F32vec4 fvec
Definition: P4_F32vec4.h:216
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:156
friend F32vec4 operator<=(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:117
float & operator[](int i)
Definition: P4_F32vec4.h:42
class F32vec4 __attribute__((aligned(16)))
friend F32vec4 operator &(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:91
friend F32vec4 operator^(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:99
const int fvecLen
Definition: P4_F32vec4.h:218
F32vec4()
Definition: P4_F32vec4.h:45
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:83
const union @48 __f32vec4_abs_mask_cheat
float f
Definition: P4_F32vec4.h:20
friend F32vec4 operator-(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:56
friend F32vec4 sgn(const F32vec4 &a)
Definition: P4_F32vec4.h:86
friend F32vec4 min(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:61
friend F32vec4 operator>=(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:125
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:65
float fscal
Definition: P4_F32vec4.h:217
friend std::istream & operator>>(std::istream &strm, F32vec4 &a)
Definition: P4_F32vec4.h:206
friend F32vec4 operator*(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:57
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:155
__m128 v
Definition: P4_F32vec4.h:40