HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VM_BasicFunc.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: VM_BasicFunc.h ( VM Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __VM_BasicFunc__
12 #define __VM_BasicFunc__
13 
14 #include "VM_API.h"
15 #include <SYS/SYS_Types.h>
16 #include <SYS/SYS_Math.h>
17 
18 // Uncomment this define to "test" with the basic instructions. These are
19 // brain-dead slow, so they shouldn't be used in actual code.
20 //#define CPU_HAS_SIMD_INSTR 1
21 
22 class v4si;
23 
24 class v4sf {
25 public:
26  v4sf() {}
27  v4sf(float a) { f[0] = f[1] = f[2] = f[3] = a; }
28  v4sf(float a, float b, float c, float d)
29  {
30  f[0] = a;
31  f[1] = b;
32  f[2] = c;
33  f[3] = d;
34  }
35 
36  operator v4si() const;
37  fpreal32 f[4];
38 };
39 
40 class v4si {
41 public:
42  v4si() {}
43  v4si(int32 a) { i[0] = i[1] = i[2] = i[3] = a; }
45  {
46  i[0] = a;
47  i[1] = b;
48  i[2] = c;
49  i[3] = d;
50  }
51 
52  operator v4sf() const;
53  int32 i[4];
54 };
55 
56 inline
57 v4sf::operator v4si() const
58 {
59  return *(v4si *)this;
60 }
61 
62 inline
63 v4si::operator v4sf() const
64 {
65  return *(v4sf *)this;
66 }
67 
68 #define V4SF(A) (v4sf)A
69 #define V4SI(A) (v4si)A
70 
71 #define vm_BASIC_IFF(OP) \
72  v4si r; \
73  r.i[0] = a.f[0] OP b.f[0]; \
74  r.i[1] = a.f[1] OP b.f[1]; \
75  r.i[2] = a.f[2] OP b.f[2]; \
76  r.i[3] = a.f[3] OP b.f[3]; \
77  return r;
78 
79 #define vm_BASIC_CF(OP) \
80  v4si r; \
81  r.i[0] = a.f[0] OP b.f[0] ? 0xFFFFFFFF : 0; \
82  r.i[1] = a.f[1] OP b.f[1] ? 0xFFFFFFFF : 0; \
83  r.i[2] = a.f[2] OP b.f[2] ? 0xFFFFFFFF : 0; \
84  r.i[3] = a.f[3] OP b.f[3] ? 0xFFFFFFFF : 0; \
85  return r;
86 
87 #define vm_BASIC_CI(OP) \
88  v4si r; \
89  r.i[0] = a.i[0] OP b.i[0] ? 0xFFFFFFFF : 0; \
90  r.i[1] = a.i[1] OP b.i[1] ? 0xFFFFFFFF : 0; \
91  r.i[2] = a.i[2] OP b.i[2] ? 0xFFFFFFFF : 0; \
92  r.i[3] = a.i[3] OP b.i[3] ? 0xFFFFFFFF : 0; \
93  return r;
94 
95 #define vm_BASIC_III(OP) \
96  v4si r; \
97  r.i[0] = a.i[0] OP b.i[0]; \
98  r.i[1] = a.i[1] OP b.i[1]; \
99  r.i[2] = a.i[2] OP b.i[2]; \
100  r.i[3] = a.i[3] OP b.i[3]; \
101  return r;
102 
103 #define vm_BASIC_FFF(OP) \
104  v4sf r; \
105  r.f[0] = a.f[0] OP b.f[0]; \
106  r.f[1] = a.f[1] OP b.f[1]; \
107  r.f[2] = a.f[2] OP b.f[2]; \
108  r.f[3] = a.f[3] OP b.f[3]; \
109  return r;
110 
111 #define vm_BASIC_FFFF(OP1, OP2) \
112  v4sf r; \
113  r.f[0] = a.f[0] OP1 b.f[0] OP2 c.f[0]; \
114  r.f[1] = a.f[1] OP1 b.f[1] OP2 c.f[1]; \
115  r.f[2] = a.f[2] OP1 b.f[2] OP2 c.f[2]; \
116  r.f[3] = a.f[3] OP1 b.f[3] OP2 c.f[3]; \
117  return r;
118 
119 #define vm_BASIC_UFuncF(FUNC) \
120  v4sf r; \
121  r.f[0] = FUNC(a.f[0]); \
122  r.f[1] = FUNC(a.f[1]); \
123  r.f[2] = FUNC(a.f[2]); \
124  r.f[3] = FUNC(a.f[3]); \
125  return r;
126 
127 #define vm_BASIC_UFuncFF(FUNC) \
128  v4sf r; \
129  r.f[0] = FUNC(a.f[0], b.f[0]); \
130  r.f[1] = FUNC(a.f[1], b.f[1]); \
131  r.f[2] = FUNC(a.f[2], b.f[2]); \
132  r.f[3] = FUNC(a.f[3], b.f[3]); \
133  return r;
134 
135 static inline v4si vm_clt(const v4sf &a, const v4sf &b) { vm_BASIC_CF(<) }
136 static inline v4si vm_cle(const v4sf &a, const v4sf &b) { vm_BASIC_CF(<=) }
137 static inline v4si vm_cgt(const v4sf &a, const v4sf &b) { vm_BASIC_CF(>) }
138 static inline v4si vm_cge(const v4sf &a, const v4sf &b) { vm_BASIC_CF(>=) }
139 static inline v4si vm_ceq(const v4sf &a, const v4sf &b) { vm_BASIC_CF(==) }
140 static inline v4si vm_cne(const v4sf &a, const v4sf &b) { vm_BASIC_CF(!=) }
141 
142 static inline v4si vm_clt(const v4si &a, const v4si &b) { vm_BASIC_CI(<) }
143 static inline v4si vm_cle(const v4si &a, const v4si &b) { vm_BASIC_CI(<=) }
144 static inline v4si vm_cgt(const v4si &a, const v4si &b) { vm_BASIC_CI(>) }
145 static inline v4si vm_cge(const v4si &a, const v4si &b) { vm_BASIC_CI(>=) }
146 static inline v4si vm_ceq(const v4si &a, const v4si &b) { vm_BASIC_CI(==) }
147 static inline v4si vm_cne(const v4si &a, const v4si &b) { vm_BASIC_CI(!=) }
148 
149 static inline v4si vm_add(const v4si &a, const v4si &b) { vm_BASIC_III(+) }
150 static inline v4si vm_sub(const v4si &a, const v4si &b) { vm_BASIC_III(-) }
151 static inline v4si vm_mul(const v4si &a, const v4si &b) { vm_BASIC_III(*) }
152 
153 static inline v4sf vm_add(const v4sf &a, const v4sf &b) { vm_BASIC_FFF(+) }
154 static inline v4sf vm_sub(const v4sf &a, const v4sf &b) { vm_BASIC_FFF(-) }
155 static inline v4sf vm_mul(const v4sf &a, const v4sf &b) { vm_BASIC_FFF(*) }
156 static inline v4sf vm_div(const v4sf &a, const v4sf &b) { vm_BASIC_FFF(/) }
157 
158 static inline v4si vm_and(const v4si &a, const v4si &b) { vm_BASIC_III(&) }
159 static inline v4si vm_or(const v4si &a, const v4si &b) { vm_BASIC_III(|) }
160 static inline v4si vm_xor(const v4si &a, const v4si &b) { vm_BASIC_III(^) }
161 
162 static inline v4si vm_andnot(const v4si &a, const v4si &b)
163 {
164  v4si r;
165  r.i[0] = ~a.i[0] & b.i[0];
166  r.i[1] = ~a.i[1] & b.i[1];
167  r.i[2] = ~a.i[2] & b.i[2];
168  r.i[3] = ~a.i[3] & b.i[3];
169  return r;
170 }
171 
172 static inline v4sf
173 vm_min(const v4sf &a, const v4sf &b) { vm_BASIC_UFuncFF(SYSmin) }
174 static inline v4sf
175 vm_max(const v4sf &a, const v4sf &b) { vm_BASIC_UFuncFF(SYSmax) }
176 
177 static inline v4sf
178 vm_madd(const v4sf &a, const v4sf &b, const v4sf &c) { vm_BASIC_FFFF(*, +) }
179 
180 static inline v4sf vm_sqrt(const v4sf &a) { vm_BASIC_UFuncF(SYSsqrt) }
181 static inline v4sf vm_isqrt(const v4sf &a) { vm_BASIC_UFuncF(1/SYSsqrt) }
182 static inline v4sf vm_negate(const v4sf &a) { vm_BASIC_UFuncF(-) }
183 static inline v4sf vm_reciprocal(const v4sf &a) { vm_BASIC_UFuncF(1/) }
184 static inline v4sf vm_abs(const v4sf &a) { vm_BASIC_UFuncF(SYSabs) }
185 
186 static inline v4si vm_floor(const v4sf &a)
187 {
188  v4si r;
189  r.i[0] = (int)SYSfastFloor(a.f[0]);
190  r.i[1] = (int)SYSfastFloor(a.f[1]);
191  r.i[2] = (int)SYSfastFloor(a.f[2]);
192  r.i[3] = (int)SYSfastFloor(a.f[3]);
193  return r;
194 }
195 
196 static inline v4si vm_intcast(const v4sf &a)
197 {
198  v4si r;
199  r.i[0] = (int)a.f[0];
200  r.i[1] = (int)a.f[1];
201  r.i[2] = (int)a.f[2];
202  r.i[3] = (int)a.f[3];
203  return r;
204 }
205 
206 static inline v4sf vm_floatcast(const v4si &a)
207 {
208  v4sf r;
209  r.f[0] = (float)a.i[0];
210  r.f[1] = (float)a.i[1];
211  r.f[2] = (float)a.i[2];
212  r.f[3] = (float)a.i[3];
213  return r;
214 }
215 
216 static inline v4si
217 vm_splats(uint32 a)
218 {
219  return v4si(a);
220 }
221 
222 static inline v4si
223 vm_splats(int32 a)
224 {
225  return v4si(a);
226 }
227 
228 static inline v4sf
229 vm_splats(float a)
230 {
231  return v4sf(a);
232 }
233 
234 static inline v4si
235 vm_splats(uint32 a, uint32 b, uint32 c, uint32 d)
236 {
237  return v4si(a, b, c, d);
238 }
239 
240 static inline v4si
241 vm_splats(int32 a, int32 b, int32 c, int32 d)
242 {
243  return v4si(a, b, c, d);
244 }
245 
246 static inline v4sf
247 vm_splats(float a, float b, float c, float d)
248 {
249  return v4sf(a, b, c, d);
250 }
251 
252 static inline bool
253 vm_allbits(const v4si &a)
254 {
255  return (a.i[0] & a.i[1] & a.i[2] & a.i[3]) == 0xFFFFFFFF;
256 }
257 
258 static inline bool
259 vm_signbits(const v4si &a)
260 {
261  return (a.i[0] < 0 ? 1 : 0) |
262  (a.i[1] < 0 ? 2 : 0) |
263  (a.i[2] < 0 ? 4 : 0) |
264  (a.i[3] < 0 ? 8 : 0);
265 }
266 
267 static inline bool
268 vm_signbits(const v4sf &a)
269 {
270  return vm_signbits( * ((v4si *) &a) );
271 }
272 
273 template <int A, int B, int C, int D>
274 static inline v4sf
275 vm_shuffle(const v4sf &v)
276 {
277  v4sf vec;
278 
279  vec.f[0] = v.f[A];
280  vec.f[1] = v.f[B];
281  vec.f[2] = v.f[C];
282  vec.f[3] = v.f[D];
283 
284  return vec;
285 }
286 
287 static inline v4si
288 vm_load(const int32 v[4])
289 {
290  return v4si(v[0], v[1], v[2], v[3]);
291 }
292 
293 static inline v4sf
294 vm_load(const float v[4])
295 {
296  return v4sf(v[0], v[1], v[2], v[3]);
297 }
298 
299 static inline void
300 vm_store(int32 dst[4], v4si value)
301 {
302  dst[0] = value.i[0];
303  dst[1] = value.i[1];
304  dst[2] = value.i[2];
305  dst[3] = value.i[3];
306 }
307 
308 static inline void
309 vm_store(float dst[4], v4sf value)
310 {
311  dst[0] = value.f[0];
312  dst[1] = value.f[1];
313  dst[2] = value.f[2];
314  dst[3] = value.f[3];
315 }
316 
317 
318 static inline v4si
319 vm_insert(const v4si v, int32 a, int n)
320 {
321  v4si vec;
322 
323  vec = v;
324  vec.i[n] = a;
325  return vec;
326 }
327 
328 static inline v4sf
329 vm_insert(const v4sf v, float a, int n)
330 {
331  v4sf vec;
332 
333  vec = v;
334  vec.f[n] = a;
335  return vec;
336 }
337 
338 static inline int
339 vm_extract(const v4si v, int n)
340 {
341  return v.i[n];
342 }
343 
344 static inline float
345 vm_extract(const v4sf v, int n)
346 {
347  return v.f[n];
348 }
349 
350 #define VMBASIC_DEFINE_UNARY(FUN) \
351  static inline v4sf vm_##FUN(const v4sf &a) \
352  { \
353  return v4sf( \
354  SYS##FUN(a.f[0]), \
355  SYS##FUN(a.f[1]), \
356  SYS##FUN(a.f[2]), \
357  SYS##FUN(a.f[3])); \
358  }
362 #undef VMBASIC_DEFINE_UNARY
363 
364 static inline
365 void vm_sincos(const v4sf &x, v4sf *s, v4sf *c)
366 {
367  SYSsincos(x.f[0], s->f + 0, c->f + 0);
368  SYSsincos(x.f[1], s->f + 1, c->f + 1);
369  SYSsincos(x.f[2], s->f + 2, c->f + 2);
370  SYSsincos(x.f[3], s->f + 3, c->f + 3);
371 }
372 
373 static inline v4si
374 vm_shiftleft(const v4si &a, int c)
375 {
376  v4si r = a;
377  ((uint32*)r.i)[0] <<= c;
378  ((uint32*)r.i)[1] <<= c;
379  ((uint32*)r.i)[2] <<= c;
380  ((uint32*)r.i)[3] <<= c;
381  return r;
382 }
383 
384 static inline v4si
385 vm_shiftright(const v4si &a, int c)
386 {
387  v4si r = a;
388  ((uint32*)r.i)[0] >>= c;
389  ((uint32*)r.i)[1] >>= c;
390  ((uint32*)r.i)[2] >>= c;
391  ((uint32*)r.i)[3] >>= c;
392  return r;
393 }
394 
395 #define VM_EXTRACT vm_extract
396 #define VM_INSERT vm_insert
397 #define VM_SPLATS vm_splats
398 #define VM_LOAD vm_load
399 #define VM_STORE vm_store
400 
401 #define VM_CMPLT vm_clt
402 #define VM_CMPLE vm_cle
403 #define VM_CMPGT vm_cgt
404 #define VM_CMPGE vm_cge
405 #define VM_CMPEQ vm_ceq
406 #define VM_CMPNE vm_cne
407 
408 #define VM_ICMPLT vm_clt
409 #define VM_ICMPGT vm_cgt
410 #define VM_ICMPEQ vm_ceq
411 
412 #define VM_IADD vm_add
413 #define VM_ISUB vm_sub
414 #define VM_IMUL vm_mul
415 
416 #define VM_ADD vm_add
417 #define VM_SUB vm_sub
418 #define VM_MUL vm_mul
419 #define VM_DIV vm_div
420 #define VM_FDIV vm_div
421 #define VM_NEG vm_negate
422 #define VM_SQRT vm_sqrt
423 #define VM_FSQRT vm_sqrt
424 #define VM_ISQRT vm_isqrt
425 #define VM_ABS vm_abs
426 
427 #define VM_MADD vm_madd
428 #define VM_INVERT vm_reciprocal
429 
430 #define VM_MIN vm_min
431 #define VM_MAX vm_max
432 
433 #define VM_AND vm_and
434 #define VM_ANDNOT vm_andnot
435 #define VM_OR vm_or
436 #define VM_XOR vm_xor
437 
438 #define VM_ALLBITS vm_allbits
439 
440 #define VM_SHUFFLE vm_shuffle
441 
442 #define VM_P_FLOOR()
443 #define VM_FLOOR vm_floor
444 #define VM_E_FLOOR()
445 
446 #define VM_INT vm_intcast
447 
448 #define VM_IFLOAT vm_floatcast
449 
450 #define VM_SIN vm_sin
451 #define VM_COS vm_cos
452 #define VM_TAN vm_tan
453 #define VM_SINCOS vm_sincos
454 
455 // bitshifing A=v4si C=int
456 #define VM_SHIFTLEFT(A,C) vm_shiftleft(A,C)
457 #define VM_SHIFTRIGHT(A,C) vm_shiftright(A,C)
458 
459 #endif
#define SYSmax(a, b)
Definition: SYS_Math.h:1538
SYS_API double cos(double x)
Definition: SYS_FPUMath.h:69
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
__m128i v4si
Definition: VM_SSEFunc.h:34
int int32
Definition: SYS_Types.h:39
const GLdouble * v
Definition: glcorearb.h:837
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
#define SYSabs(a)
Definition: SYS_Math.h:1540
#define vm_BASIC_III(OP)
Definition: VM_BasicFunc.h:95
float fpreal32
Definition: SYS_Types.h:200
v4sf(float a)
Definition: VM_BasicFunc.h:27
fpreal32 f[4]
Definition: VM_BasicFunc.h:37
GLdouble n
Definition: glcorearb.h:2008
GLfloat f
Definition: glcorearb.h:1926
v4sf()
Definition: VM_BasicFunc.h:26
v4sf(float a, float b, float c, float d)
Definition: VM_BasicFunc.h:28
#define vm_BASIC_CF(OP)
Definition: VM_BasicFunc.h:79
__m128 v4sf
Definition: VM_SSEFunc.h:33
#define vm_BASIC_UFuncF(FUNC)
Definition: VM_BasicFunc.h:119
#define vm_BASIC_FFF(OP)
Definition: VM_BasicFunc.h:103
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
#define vm_BASIC_FFFF(OP1, OP2)
Definition: VM_BasicFunc.h:111
int32 i[4]
Definition: VM_BasicFunc.h:53
#define VMBASIC_DEFINE_UNARY(FUN)
Definition: VM_BasicFunc.h:350
SYS_API double tan(double x)
Definition: SYS_FPUMath.h:75
GLenum GLenum dst
Definition: glcorearb.h:1793
v4si(int32 a)
Definition: VM_BasicFunc.h:43
v4si()
Definition: VM_BasicFunc.h:42
unsigned int uint32
Definition: SYS_Types.h:40
v4si(int32 a, int32 b, int32 c, int32 d)
Definition: VM_BasicFunc.h:44
Definition: core.h:1131
#define vm_BASIC_UFuncFF(FUNC)
Definition: VM_BasicFunc.h:127
GLboolean r
Definition: glcorearb.h:1222
#define SYSmin(a, b)
Definition: SYS_Math.h:1539
SYS_API double sin(double x)
Definition: SYS_FPUMath.h:71
#define vm_BASIC_CI(OP)
Definition: VM_BasicFunc.h:87