00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __VM_BasicFunc__
00019 #define __VM_BasicFunc__
00020
00021 #include "VM_API.h"
00022 #include <SYS/SYS_Types.h>
00023
00024
00025
00026
00027
00028 class v4si;
00029
00030 class v4sf {
00031 public:
00032 operator v4si() const;
00033 fpreal32 f[4];
00034 };
00035
00036 class v4si {
00037 public:
00038 operator v4sf() const;
00039 int32 i[4];
00040 };
00041
00042 inline
00043 v4sf::operator v4si() const
00044 {
00045 return *(v4si *)this;
00046 }
00047
00048 inline
00049 v4si::operator v4sf() const
00050 {
00051 return *(v4sf *)this;
00052 }
00053
00054 #define V4SF(A) (v4sf)A
00055 #define V4SI(A) (v4si)A
00056
00057 #define vm_BASIC_IFF(OP) \
00058 v4si r; \
00059 r.i[0] = a.f[0] OP b.f[0]; \
00060 r.i[1] = a.f[1] OP b.f[1]; \
00061 r.i[2] = a.f[2] OP b.f[2]; \
00062 r.i[3] = a.f[3] OP b.f[3]; \
00063 return r;
00064
00065 #define vm_BASIC_CF(OP) \
00066 v4si r; \
00067 r.i[0] = a.f[0] OP b.f[0] ? 0xFFFFFFFF : 0; \
00068 r.i[1] = a.f[1] OP b.f[1] ? 0xFFFFFFFF : 0; \
00069 r.i[2] = a.f[2] OP b.f[2] ? 0xFFFFFFFF : 0; \
00070 r.i[3] = a.f[3] OP b.f[3] ? 0xFFFFFFFF : 0; \
00071 return r;
00072
00073 #define vm_BASIC_CI(OP) \
00074 v4si r; \
00075 r.i[0] = a.i[0] OP b.i[0] ? 0xFFFFFFFF : 0; \
00076 r.i[1] = a.i[1] OP b.i[1] ? 0xFFFFFFFF : 0; \
00077 r.i[2] = a.i[2] OP b.i[2] ? 0xFFFFFFFF : 0; \
00078 r.i[3] = a.i[3] OP b.i[3] ? 0xFFFFFFFF : 0; \
00079 return r;
00080
00081 #define vm_BASIC_III(OP) \
00082 v4si r; \
00083 r.i[0] = a.i[0] OP b.i[0]; \
00084 r.i[1] = a.i[1] OP b.i[1]; \
00085 r.i[2] = a.i[2] OP b.i[2]; \
00086 r.i[3] = a.i[3] OP b.i[3]; \
00087 return r;
00088
00089 #define vm_BASIC_FFF(OP) \
00090 v4sf r; \
00091 r.f[0] = a.f[0] OP b.f[0]; \
00092 r.f[1] = a.f[1] OP b.f[1]; \
00093 r.f[2] = a.f[2] OP b.f[2]; \
00094 r.f[3] = a.f[3] OP b.f[3]; \
00095 return r;
00096
00097 #define vm_BASIC_FFFF(OP1, OP2) \
00098 v4sf r; \
00099 r.f[0] = a.f[0] OP1 b.f[0] OP2 c.f[0]; \
00100 r.f[1] = a.f[1] OP1 b.f[1] OP2 c.f[1]; \
00101 r.f[2] = a.f[2] OP1 b.f[2] OP2 c.f[2]; \
00102 r.f[3] = a.f[3] OP1 b.f[3] OP2 c.f[3]; \
00103 return r;
00104
00105 #define vm_BASIC_UFuncF(FUNC) \
00106 v4sf r; \
00107 r.f[0] = FUNC(a.f[0]); \
00108 r.f[1] = FUNC(a.f[1]); \
00109 r.f[2] = FUNC(a.f[2]); \
00110 r.f[3] = FUNC(a.f[3]); \
00111 return r;
00112
00113 #define vm_BASIC_UFuncFF(FUNC) \
00114 v4sf r; \
00115 r.f[0] = FUNC(a.f[0], b.f[0]); \
00116 r.f[1] = FUNC(a.f[1], b.f[1]); \
00117 r.f[2] = FUNC(a.f[2], b.f[2]); \
00118 r.f[3] = FUNC(a.f[3], b.f[3]); \
00119 return r;
00120
00121 static inline v4si vm_clt(const v4sf &a, const v4sf &b) { vm_BASIC_CF(<) }
00122 static inline v4si vm_cle(const v4sf &a, const v4sf &b) { vm_BASIC_CF(<=) }
00123 static inline v4si vm_cgt(const v4sf &a, const v4sf &b) { vm_BASIC_CF(>) }
00124 static inline v4si vm_cge(const v4sf &a, const v4sf &b) { vm_BASIC_CF(>=) }
00125 static inline v4si vm_ceq(const v4sf &a, const v4sf &b) { vm_BASIC_CF(==) }
00126 static inline v4si vm_cne(const v4sf &a, const v4sf &b) { vm_BASIC_CF(!=) }
00127
00128 static inline v4si vm_clt(const v4si &a, const v4si &b) { vm_BASIC_CI(<) }
00129 static inline v4si vm_cle(const v4si &a, const v4si &b) { vm_BASIC_CI(<=) }
00130 static inline v4si vm_cgt(const v4si &a, const v4si &b) { vm_BASIC_CI(>) }
00131 static inline v4si vm_cge(const v4si &a, const v4si &b) { vm_BASIC_CI(>=) }
00132 static inline v4si vm_ceq(const v4si &a, const v4si &b) { vm_BASIC_CI(==) }
00133 static inline v4si vm_cne(const v4si &a, const v4si &b) { vm_BASIC_CI(!=) }
00134
00135 static inline v4si vm_add(const v4si &a, const v4si &b) { vm_BASIC_III(+) }
00136 static inline v4si vm_sub(const v4si &a, const v4si &b) { vm_BASIC_III(-) }
00137
00138 static inline v4sf vm_add(const v4sf &a, const v4sf &b) { vm_BASIC_FFF(+) }
00139 static inline v4sf vm_sub(const v4sf &a, const v4sf &b) { vm_BASIC_FFF(-) }
00140 static inline v4sf vm_mul(const v4sf &a, const v4sf &b) { vm_BASIC_FFF(*) }
00141 static inline v4sf vm_div(const v4sf &a, const v4sf &b) { vm_BASIC_FFF(/) }
00142
00143 static inline v4si vm_and(const v4si &a, const v4si &b) { vm_BASIC_III(&) }
00144 static inline v4si vm_or(const v4si &a, const v4si &b) { vm_BASIC_III(|) }
00145 static inline v4si vm_xor(const v4si &a, const v4si &b) { vm_BASIC_III(^) }
00146
00147 static inline v4si vm_andnot(const v4si &a, const v4si &b)
00148 {
00149 v4si r;
00150 r.i[0] = ~a.i[0] & b.i[0];
00151 r.i[1] = ~a.i[1] & b.i[1];
00152 r.i[2] = ~a.i[2] & b.i[2];
00153 r.i[3] = ~a.i[3] & b.i[3];
00154 return r;
00155 }
00156
00157 static inline v4sf
00158 vm_min(const v4sf &a, const v4sf &b) { vm_BASIC_UFuncFF(SYSmin) }
00159 static inline v4sf
00160 vm_max(const v4sf &a, const v4sf &b) { vm_BASIC_UFuncFF(SYSmax) }
00161
00162 static inline v4sf
00163 vm_madd(const v4sf &a, const v4sf &b, const v4sf &c) { vm_BASIC_FFFF(*, +) }
00164
00165 static inline v4sf vm_sqrt(const v4sf &a) { vm_BASIC_UFuncF(SYSsqrt) }
00166 static inline v4sf vm_isqrt(const v4sf &a) { vm_BASIC_UFuncF(1/SYSsqrt) }
00167 static inline v4sf vm_negate(const v4sf &a) { vm_BASIC_UFuncF(-) }
00168 static inline v4sf vm_reciprocal(const v4sf &a) { vm_BASIC_UFuncF(1/) }
00169 static inline v4sf vm_abs(const v4sf &a) { vm_BASIC_UFuncF(SYSabs) }
00170
00171 static inline v4si vm_floor(const v4sf &a)
00172 {
00173 v4si r;
00174 r.i[0] = (int)SYSfastFloor(a.f[0]);
00175 r.i[1] = (int)SYSfastFloor(a.f[1]);
00176 r.i[2] = (int)SYSfastFloor(a.f[2]);
00177 r.i[3] = (int)SYSfastFloor(a.f[3]);
00178 return r;
00179 }
00180
00181 static inline v4si vm_intcast(const v4sf &a)
00182 {
00183 v4si r;
00184 r.i[0] = (int)a.f[0];
00185 r.i[1] = (int)a.f[1];
00186 r.i[2] = (int)a.f[2];
00187 r.i[3] = (int)a.f[3];
00188 return r;
00189 }
00190
00191 static inline v4sf vm_floatcast(const v4si &a)
00192 {
00193 v4sf r;
00194 r.f[0] = (float)a.i[0];
00195 r.f[1] = (float)a.i[1];
00196 r.f[2] = (float)a.i[2];
00197 r.f[3] = (float)a.i[3];
00198 return r;
00199 }
00200
00201 static inline void
00202 vm_splats(v4si &v, uint32 a)
00203 {
00204 v.i[0] = v.i[1] = v.i[2] = v.i[3] = a;
00205 }
00206
00207 static inline void
00208 vm_splats(v4sf &v, float a)
00209 {
00210 v.f[0] = v.f[1] = v.f[2] = v.f[3] = a;
00211 }
00212
00213 static inline void
00214 vm_splats(v4si &v, uint32 a, uint32 b, uint32 c, uint32 d)
00215 {
00216 v.i[0] = a;
00217 v.i[1] = b;
00218 v.i[2] = c;
00219 v.i[3] = d;
00220 }
00221
00222 static inline void
00223 vm_splats(v4sf &v, float a, float b, float c, float d)
00224 {
00225 v.f[0] = a;
00226 v.f[1] = b;
00227 v.f[2] = c;
00228 v.f[3] = d;
00229 }
00230
00231 static inline bool
00232 vm_allbits(const v4si &a)
00233 {
00234 return (a.i[0] & a.i[1] & a.i[2] & a.i[3]) == 0xFFFFFFFF;
00235 }
00236
00237 template <int A, int B, int C, int D>
00238 static inline v4sf
00239 vm_shuffle(const v4sf &v)
00240 {
00241 v4sf vec;
00242
00243 vec.f[0] = v.f[A];
00244 vec.f[1] = v.f[B];
00245 vec.f[2] = v.f[C];
00246 vec.f[3] = v.f[D];
00247
00248 return vec;
00249 }
00250
00251 #define VM_SPLATS vm_splats
00252
00253 #define VM_CMPLT vm_clt
00254 #define VM_CMPLE vm_cle
00255 #define VM_CMPGT vm_cgt
00256 #define VM_CMPGE vm_cge
00257 #define VM_CMPEQ vm_ceq
00258 #define VM_CMPNE vm_cne
00259
00260 #define VM_ICMPLT vm_clt
00261 #define VM_ICMPGT vm_cgt
00262 #define VM_ICMPEQ vm_ceq
00263
00264 #define VM_IADD vm_add
00265 #define VM_ISUB vm_sub
00266
00267 #define VM_ADD vm_add
00268 #define VM_SUB vm_sub
00269 #define VM_MUL vm_mul
00270 #define VM_DIV vm_div
00271 #define VM_FDIV vm_div
00272 #define VM_NEG vm_negate
00273 #define VM_SQRT vm_sqrt
00274 #define VM_FSQRT vm_sqrt
00275 #define VM_ISQRT vm_isqrt
00276 #define VM_ABS vm_abs
00277
00278 #define VM_MADD vm_madd
00279 #define VM_INVERT vm_reciprocal
00280
00281 #define VM_MIN vm_min
00282 #define VM_MAX vm_max
00283
00284 #define VM_AND vm_and
00285 #define VM_ANDNOT vm_andnot
00286 #define VM_OR vm_or
00287 #define VM_XOR vm_xor
00288
00289 #define VM_ALLBITS vm_allbits
00290
00291 #define VM_SHUFFLE vm_shuffle
00292
00293 #define VM_P_FLOOR()
00294 #define VM_FLOOR vm_floor
00295 #define VM_E_FLOOR()
00296
00297 #define VM_P_INT()
00298 #define VM_INT vm_intcast
00299 #define VM_E_INT()
00300
00301 #define VM_IFLOAT vm_floatcast
00302
00303 #endif