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