00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef FVEC4_H
00021 #define FVEC4_H
00022
00023 #include <math.h>
00024 #include <algorithm>
00025 #include <xmmintrin.h>
00026 #include <emmintrin.h>
00027
00029 struct vec4_32i {
00030 __m128i data;
00031
00032 vec4_32i(){}
00033 vec4_32i(__m128i a) { data=a; }
00034 vec4_32i(int a) { _mm_set1_epi32(a); }
00035 vec4_32i(int a, int b, int c, int d) { _mm_set_epi32(a,b,c,d); }
00036 };
00037
00039 struct fvec4 {
00040 __m128 data;
00041 static const int size = 4;
00042
00043 fvec4() {}
00044 fvec4(__m128 a) {data=a;}
00045 fvec4(const fvec4 &a) {data=a.data;}
00046 fvec4(float a) {data = _mm_set_ps1(a);}
00047 fvec4(float a, float b, float c, float d) { data = _mm_set_ps(a,b,c,d); }
00048
00049 fvec4 operator = (const fvec4 &a) { data = a.data; return *this; }
00050 fvec4 operator = (const __m128 a) { data = a; return *this; }
00051 fvec4 operator = (float a) { data = _mm_set_ps1(a); return *this; }
00052
00053 fvec4 operator += (const fvec4 &a) { return *this = _mm_add_ps(data,a.data); }
00054 fvec4 operator -= (const fvec4 &a) { return *this = _mm_sub_ps(data,a.data); }
00055 fvec4 operator *= (const fvec4 &a) { return *this = _mm_mul_ps(data,a.data); }
00056 fvec4 operator /= (const fvec4 &a) { return *this = _mm_div_ps(data,a.data); }
00057 float &operator [] (int i) { return ((float *) &data)[i]; }
00058 const float &operator [] (int i) const { return ((const float *) &data)[i]; }
00059
00060 operator vec4_32i() { return vec4_32i(_mm_cvttps_epi32(data)); }
00061
00062 float horizontal_max() {
00063 return std::max(
00064 std::max( (*this)[0], (*this)[1] ),
00065 std::max( (*this)[2], (*this)[3] ));
00066 }
00067 int horizontal_max_index() {
00068 int best=0;
00069 float val = (*this)[0];
00070 for (int i=1; i<3; i++) {
00071 if (val < (*this)[i]) {
00072 val = (*this)[i];
00073 best = i;
00074 }
00075 }
00076 return best;
00077 }
00078 };
00079
00080 inline fvec4 operator + (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_add_ps(a.data, b.data)); }
00081 inline fvec4 operator - (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_sub_ps(a.data, b.data)); }
00082 inline fvec4 operator - (const fvec4 &a) { return fvec4(0) - a; }
00083 inline fvec4 operator * (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_mul_ps(a.data, b.data)); }
00084 inline fvec4 operator / (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_div_ps(a.data, b.data)); }
00085 inline fvec4 rcp(fvec4 &a) { return fvec4(_mm_rcp_ps(a.data)); }
00086 inline fvec4 operator < (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_cmplt_ps(a.data, b.data)); }
00087 inline fvec4 operator > (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_cmpgt_ps(a.data, b.data)); }
00088 inline fvec4 operator <= (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_cmpngt_ps(a.data, b.data)); }
00089 inline fvec4 operator >= (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_cmpnlt_ps(a.data, b.data)); }
00090 inline fvec4 operator == (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_cmpeq_ps(a.data, b.data)); }
00091
00092 inline fvec4 operator & (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_and_ps(a.data, b.data)); }
00093 inline fvec4 operator | (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_or_ps(a.data, b.data)); }
00094 inline fvec4 operator ^ (const fvec4 &a, const fvec4 &b) { return fvec4(_mm_xor_ps(a.data, b.data)); }
00095 inline fvec4 min(const fvec4 &a, const fvec4 &b) { return fvec4(_mm_min_ps(a.data, b.data)); }
00096 inline fvec4 max(const fvec4 &a, const fvec4 &b) { return fvec4(_mm_max_ps(a.data, b.data)); }
00097
00098 #endif