glm/wip/simd/sse.cpp

1379 lines
34 KiB
C++
Raw Normal View History

2010-04-14 12:27:44 +00:00
#include "precompiled.h"
#include "sse.h"
//namespace sse
//{
// // some defines first
// union ieee754_QNAN
// {
// const float f;
// struct
// {
// const unsigned int mantissa:23, exp:8, sign:1;
// };
//
// ieee754_QNAN() : f(0.0), mantissa(0x7FFFFF), exp(0xFF), sign(0x0) {}
// };
//
// namespace detail
// {
// union ieee754
// {
// ieee754() :
// f(0.0f)
// {}
//
// ieee754(float f) :
// f(f)
// {}
//
// ieee754(unsigned int mantissa, unsigned int exp, unsigned int sign) :
// mantissa(mantissa), exp(exp), sign(sign)
// {}
//
// float f;
// struct
// {
// unsigned int mantissa:23, exp:8, sign:1;
// };
// };
//
// _MM_ALIGN16 const ieee754 qnan(0x7FFFFF, 0xFF, 0x0);
// }
//
// float load(unsigned int mantissa, unsigned int exp, unsigned int sign)
// {
// sse::detail::ieee754 value(mantissa, exp, sign);
// return value.f;
// }
//
// _MM_ALIGN16 const sse::detail::ieee754 qnan(0x7FFFFF, 0xFF, 0x0);
//
// _MM_ALIGN16 const ieee754_QNAN absMask;
// //static const __m128 abs4Mask = _mm_load1_ps( &absMask.f);
// static const __m128 abs4Mask = _mm_set_ps1(absMask.f);
//
// __m128 _mm_neg_ps(__m128 v)
// {
// return _mm_sub_ps(_mm_setzero_ps(), v);
// }
//
// __m128 fast_pow(__m128 base, __m128 exponent)
// {
// __m128 denom = _mm_mul_ps( exponent, base);
// denom = _mm_sub_ps( exponent, denom);
// denom = _mm_add_ps( base, denom);
// return _mm_mul_ps( base, _mm_rcp_ps(denom));
// }
//
// static const __m128 zero = _mm_setzero_ps();
// static const __m128 one = _mm_set_ps1(1.0f);
// static const __m128 two = _mm_set_ps1(2.0f);
// static const __m128 pi = _mm_set_ps1(3.1415926535897932384626433832795f);
// static const __m128 hundred_eighty = _mm_set_ps1(180.f);
// static const __m128 pi_over_hundred_eighty = _mm_set_ps1(0.017453292519943295769236907684886f);
// static const __m128 hundred_eighty_over_pi = _mm_set_ps1(57.295779513082320876798154814105f);
//
// //vec4 radians(vec4 degrees)
// //{
// // const float pi = float(3.1415926535897932384626433832795);
// // return degrees * (pi / 180.f);
// //}
// __m128 radians(__m128 degrees)
// {
// return _mm_mul_ps(degrees, pi_over_hundred_eighty);
// }
//
// __m128 _mm_rad_ss(__m128 degrees)
// {
// return _mm_mul_ss(degrees, pi_over_hundred_eighty);
// }
//
// __m128 _mm_rad_ps(__m128 degrees)
// {
// return _mm_mul_ps(degrees, pi_over_hundred_eighty);
// }
//
// //vec4 degrees(vec4 radians)
// //{
// // const float pi = float(3.1415926535897932384626433832795);
// // return radians * (180.f / pi);
// //}
// __m128 degrees(__m128 radians)
// {
// return _mm_mul_ps(radians, hundred_eighty_over_pi);
// }
//
// __m128 _mm_deg_ss(__m128 radians)
// {
// return _mm_mul_ss(radians, hundred_eighty_over_pi);
// }
//
// __m128 _mm_deg_ps(__m128 radians)
// {
// return _mm_mul_ps(radians, hundred_eighty_over_pi);
// }
//
// //vec4 sqrt(vec4 v)
// //{
// // return vec4(sqrt(v.x), sqrt(v.y), sqrt(v.z), sqrt(v.w));
// //}
// __m128 sqrt(__m128 v)
// {
// return _mm_sqrt_ps(v);
// }
//
// //vec4 inversesqrt(vec4 x)
// //{
// // return vec4(1.0f) / sqrt(x);
// //}
// __m128 inversesqrt(__m128 v)
// {
// return _mm_rsqrt_ps(v);
// }
//
// //vec4 abs(vec4 x)
// //{
// // return x >= T(0) ? x : -x;
// //}
// __m128 abs(__m128 x)
// {
// return _mm_and_ps(abs4Mask, x);
// }
//
// //__m128 _mm_abs_ss(__m128 x)
// //{
// // return _mm_and_ss(abs4Mask, x);
// //}
//
// __m128 _mm_abs_ps(__m128 x)
// {
// return _mm_and_ps(abs4Mask, x);
// }
//
// //vec4 sign(vec4 x)
// //{
// // vec4 result;
// // if(x > vec4(0))
// // result = vec4(1);
// // else if(x < T(0))
// // result = vec4(-1);
// // else
// // result = vec4(0);
// // return result;
// //}
// __m128 sign(__m128 x)
// {
// __m128 result;
// __m128 cmp0 = _mm_cmpeq_ps(x, zero);
// if(_mm_movemask_ps(cmp0) == 0)
// result = zero;
// else
// {
// __m128 cmp1 = _mm_cmpge_ps(x, zero);
// //__m128 cmp2 = _mm_cmple_ps(x, zero);
// if(_mm_movemask_ps(cmp1) > 0)
// result = one;
// else //if(_mm_movemask_ps(cmp2) > 0)
// result = minus_one;
// }
// return result;
// }
//
// __m128 _mm_sgn_ss(__m128 x)
// {
// __m128 result;
// __m128 cmp0 = _mm_cmpeq_ss(x, zero);
// if(_mm_movemask_ss(cmp0) == 0)
// result = zero;
// else
// {
// __m128 cmp1 = _mm_cmpge_ss(x, zero);
// //__m128 cmp2 = _mm_cmple_ss(x, zero);
// if(_mm_movemask_ss(cmp1) > 0)
// result = one;
// else //if(_mm_movemask_ss(cmp2) > 0)
// result = minus_one;
// }
// return result;
// }
//
// __m128 _mm_sgn_ps(__m128 x)
// {
// __m128 cmp0 = _mm_cmpeq_ps(x, zero);
// __m128 cmp1 = _mm_cmple_ps(x, zero);
// __m128 cmp2 = _mm_cmpge_ps(x, zero)
//
// __m128 result;
// __m128 cmp0 = _mm_cmpeq_ps(x, zero);
// if(_mm_movemask_ps(cmp0) == 0)
// result = zero;
// else
// {
// __m128 cmp1 = _mm_cmpge_ps(x, zero);
// //__m128 cmp2 = _mm_cmple_ps(x, zero);
// if(_mm_movemask_ps(cmp1) > 0)
// result = one;
// else //if(_mm_movemask_ps(cmp2) > 0)
// result = minus_one;
// }
// return result;
// }
//
// //vec4 floor(vec4 x)
// //{
// // return ::std::floor(x);
// //}
//
// __m128 floor(__m128 v)
// {
//
// }
//
// __m128 _mm_flr_ss(__m128 v)
// {
//
// }
//
// __m128 _mm_flr_ps(__m128 v)
// {
//
// }
//
// //vec4 ceil(vec4 x)
// //{
// // return ::std::ceil(vec4);
// //}
//
//
//
// //vec4 fract(vec4 x)
// //{
// // return x - floor(x);
// //}
// __m128 fract(__m128 x)
// {
// __m128 flr0 = floor(x);
// __m128 sub0 = _mm_sub_ps(x, flr0);
// return sub0;
// }
//
// __m128 _mm_frc_ss(__m128 x)
// {
// __m128 flr0 = _mm_flr_ss(x);
// __m128 sub0 = _mm_sub_ss(x, flr0);
// return sub0;
// }
//
// __m128 _mm_frc_ps(__m128 x)
// {
// __m128 flr0 = _mm_flr_ps(x);
// __m128 sub0 = _mm_sub_ps(x, flr0);
// return sub0;
// }
//
// //vec4 mod(vec4 x, vec4 y)
// //{
// // return x - y * floor(x / y);
// //}
// __m128 mod(__m128 x, __m128 y)
// {
// __m128 div0 = _mm_div_ps(x, y);
// __m128 flr0 = _mm_flr_ps(div0);
// __m128 mul0 = _mm_mul_ps(y, flr0);
// __m128 sub0 = _mm_sub_ps(x, mul0);
// return sub0;
// }
//
// __m128 _mm_mod_ss(__m128 x, __m128 y)
// {
// __m128 div0 = _mm_div_ss(x, y);
// __m128 flr0 = _mm_flr_ss(div0);
// __m128 mul0 = _mm_mul_ss(y, flr0);
// __m128 sub0 = _mm_sub_ss(x, mul0);
// return sub0;
// }
//
// __m128 _mm_mod_ps(__m128 x, __m128 y)
// {
// __m128 div0 = _mm_div_ps(x, y);
// __m128 flr0 = _mm_flr_ps(div0);
// __m128 mul0 = _mm_mul_ps(y, flr0);
// __m128 sub0 = _mm_sub_ps(x, mul0);
// return sub0;
// }
//
// //vec4 min(vec4 x, vec4 y)
// //{
// // return x < y ? x : y;
// //}
// __m128 min(__m128 v1, __m128 v2)
// {
// return _mm_min_ps(v1, v2);
// }
//
// //vec4 max(vec4 x, vec4 y)
// //{
// // return x > y ? x : y;
// //}
// __m128 max(__m128 v1, __m128 v2)
// {
// return _mm_max_ps(v1, v2);
// }
//
// //vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal)
// //{
// // return max(min(v, maxVal), minVal);
// //}
// __m128 clamp(__m128 v, __m128 minVal, __m128 maxVal)
// {
// return _mm_max_ps(_mm_min_ps(v, maxVal), minVal);
// }
//
// __m128 _mm_clp_ss(__m128 v, __m128 minVal, __m128 maxVal)
// {
// __m128 min0 = _mm_min_ss(v, maxVal);
// __m128 max0 = _mm_max_ss(min0, minVal);
// return max0;
// }
//
// __m128 _mm_clp_ps(__m128 v, __m128 minVal, __m128 maxVal)
// {
// __m128 min0 = _mm_min_ps(v, maxVal);
// __m128 max0 = _mm_max_ps(min0, minVal);
// return max0;
// }
//
// //vec4 mix(vec4 x, vec4 y, vec4 a)
// //{
// // return x * (vec4(1) - a) + y * a;
// //}
// __m128 mix(__m128 v1, __m128 v2, __m128 a)
// {
// __m128 sub0 = _mm_sub_ps(one, a);
// __m128 mul0 = _mm_mul_ps(v1, sub0);
// __m128 mul1 = _mm_mul_ps(v2, a);
// __m128 add0 = _mm_add_ps(mul0, mul1);
// return add0;
// }
//
// __m128 _mm_lerp_ss(__m128 v1, __m128 v2, __m128 a)
// {
// __m128 sub0 = _mm_sub_ss(one, a);
// __m128 mul0 = _mm_mul_ss(v1, sub0);
// __m128 mul1 = _mm_mul_ss(v2, a);
// __m128 add0 = _mm_add_ss(mul0, mul1);
// return add0;
// }
//
// __m128 _mm_lerp_ps(__m128 v1, __m128 v2, __m128 a)
// {
// __m128 sub0 = _mm_sub_ps(one, a);
// __m128 mul0 = _mm_mul_ps(v1, sub0);
// __m128 mul1 = _mm_mul_ps(v2, a);
// __m128 add0 = _mm_add_ps(mul0, mul1);
// return add0;
// }
//
// //vec4 step(vec4 edge, vec4 x)
// //{
// // return x <= edge ? vec4(0) : vec4(1);
// //}
// __m128 step(__m128 edge, __m128 x)
// {
// __m128 cmp = _mm_cmple_ps(x, edge);
// if(_mm_movemask_ps(cmp) == 0)
// return one;
// else
// return zero;
// }
//
// __m128 _mm_step_ss(__m128 edge, __m128 x)
// {
// __m128 cmp = _mm_cmple_ss(x, edge);
// if(_mm_movemask_ss(cmp) == 0)
// return one;
// else
// return zero;
// }
//
// __m128 _mm_step_ps(__m128 edge, __m128 x)
// {
// __m128 cmp = _mm_cmple_ps(x, edge);
// if(_mm_movemask_ps(cmp) == 0)
// return one;
// else
// return zero;
// }
//
// //vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x)
// //{
// // vec4 tmp = clamp((x - edge0) / (edge1 - edge0), vec4(0), vec4(1));
// // return tmp * tmp * (vec4(3) - vec4(2) * tmp);
// //}
// __m128 smoothstep(__m128 edge0, __m128 edge1, __m128 x)
// {
// __m128 sub0 = _mm_sub_ps(x, edge0);
// __m128 sub1 = _mm_sub_ps(edge1, edge0);
// __m128 div0 = _mm_sub_ps(sub0, sub1);
// __m128 clp0 = _mm_clp_ps(div0, zero, one);
// __m128 mul0 = _mm_mul_ps(two, clp0);
// __m128 sub2 = _mm_sub_ps(three, mul0);
// __m128 mul1 = _mm_mul_ps(clp0, clp0);
// __m128 mul2 = _mm_mul_ps(mul1, sub2);
// return mul2;
// }
//
// __m128 _mm_ssp_ss(__m128 edge0, __m128 edge1, __m128 x)
// {
// __m128 sub0 = _mm_sub_ss(x, edge0);
// __m128 sub1 = _mm_sub_ss(edge1, edge0);
// __m128 div0 = _mm_sub_ss(sub0, sub1);
// __m128 clp0 = _mm_clp_ss(div0, zero, one);
// __m128 mul0 = _mm_mul_ss(two, clp0);
// __m128 sub2 = _mm_sub_ss(three, mul0);
// __m128 mul1 = _mm_mul_ss(clp0, clp0);
// __m128 mul2 = _mm_mul_ss(mul1, sub2);
// return mul2;
// }
//
// __m128 _mm_ssp_ps(__m128 edge0, __m128 edge1, __m128 x)
// {
// __m128 sub0 = _mm_sub_ps(x, edge0);
// __m128 sub1 = _mm_sub_ps(edge1, edge0);
// __m128 div0 = _mm_sub_ps(sub0, sub1);
// __m128 clp0 = _mm_clp_ps(div0, zero, one);
// __m128 mul0 = _mm_mul_ps(two, clp0);
// __m128 sub2 = _mm_sub_ps(three, mul0);
// __m128 mul1 = _mm_mul_ps(clp0, clp0);
// __m128 mul2 = _mm_mul_ps(mul1, sub2);
// return mul2;
// }
//
// //float length(vec4 x)
// //{
// // float sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
// // return sqrt(sqr);
// //}
// __m128 length(__m128 x)
// {
// __m128 dot0 = dot(x, x);
// __m128 sqt0 = _mm_sqrt_ps(dot0);
// return sqt0;
// }
//
// __m128 _mm_len_ss(__m128 x)
// {
// __m128 dot0 = _mm_dot_ss(x, x);
// __m128 sqt0 = _mm_sqrt_ss(dot0);
// return sqt0;
// }
//
// __m128 _mm_len_ps(__m128 x)
// {
// __m128 dot0 = _mm_dot_ps(x, x);
// __m128 sqt0 = _mm_sqrt_ps(dot0);
// return sqt0;
// }
//
// //float distance(vec4 p0, vec4 p1)
// //{
// // return length(p1 - p0);
// //}
// __m128 distance(__m128 p0, __m128 p1)
// {
// __m128 sub0 = _mm_sub_ps(p0, p1);
// __m128 len0 = _mm_len_ps(sub0);
// return len0;
// }
//
// __m128 _mm_dst_ss(__m128 p0, __m128 p1)
// {
// __m128 sub0 = _mm_sub_ps(p0, p1);
// __m128 len0 = _mm_len_ps(sub0);
// return len0;
// }
//
// __m128 _mm_dst_ps(__m128 p0, __m128 p1)
// {
// __m128 sub0 = _mm_sub_ps(p0, p1);
// __m128 len0 = _mm_len_ps(sub0);
// return len0;
// }
//
// //vec4 dot(vec4 x, vec4 y)
// //{
// // return vec4(x.x * y.x + x.y * y.y + x.z * y.z + x.w * y.w);
// //}
// __m128 dot(__m128 v1, __m128 v2)
// {
// __m128 mul0 = _mm_mul_ps(v1, v2);
// __m128 swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1));
// __m128 add0 = _mm_add_ps(mul0, swp0);
// __m128 swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3));
// __m128 add1 = _mm_add_ps(add0, swp1);
// return add1;
// }
//
// __m128 _mm_dot_ss(__m128 v1, __m128 v2)
// {
// __m128 mul0 = _mm_mul_ps(v1, v2);
// __m128 swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1));
// __m128 add0 = _mm_add_ps(mul0, swp0);
// __m128 swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3));
// __m128 add1 = _mm_add_ps(add0, swp1);
// return add1;
// }
//
// __m128 _mm_dot_ps(__m128 v1, __m128 v2)
// {
// __m128 mul0 = _mm_mul_ps(v1, v2);
// __m128 swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1));
// __m128 add0 = _mm_add_ps(mul0, swp0);
// __m128 swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3));
// __m128 add1 = _mm_add_ps(add0, swp1);
// return add1;
// }
//
// //vec3 cross(vec3 x, vec3 y)
// //{
// // return vec3(
// // x.y * y.z - y.y * x.z,
// // x.z * y.x - y.z * x.x,
// // x.x * y.y - y.x * x.y);
// //}
// __m128 cross(__m128 v1, __m128 v2)
// {
// __m128 swp0 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 0, 2, 1));
// __m128 swp1 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 1, 0, 2));
// __m128 swp2 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 0, 2, 1));
// __m128 swp3 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 1, 0, 2));
// __m128 mul0 = _mm_mul_ps(swp0, swp3);
// __m128 mul1 = _mm_mul_ps(swp1, swp2);
// __m128 sub0 = _mm_sub_ps(mul0, mul1);
// return sub0;
// }
//
// __m128 _mm_xpd_ps(__m128 v1, __m128 v2)
// {
// __m128 swp0 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 0, 2, 1));
// __m128 swp1 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 1, 0, 2));
// __m128 swp2 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 0, 2, 1));
// __m128 swp3 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 1, 0, 2));
// __m128 mul0 = _mm_mul_ps(swp0, swp3);
// __m128 mul1 = _mm_mul_ps(swp1, swp2);
// __m128 sub0 = _mm_sub_ps(mul0, mul1);
// return sub0;
// }
//
// //vec4 normalize(vec4 x)
// //{
// // float sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
// // return x * inversesqrt(sqr);
// //}
// __m128 normalize(__m128 v)
// {
// __m128 dot0 = dot(v, v);
// __m128 isr0 = _mm_rsqrt_ps(dot0);
// __m128 mul0 = _mm_mul_ps(v, isr0);
// return mul0;
// }
//
// __m128 _mm_nrm_ps(__m128 v)
// {
// __m128 dot0 = dot(v, v);
// __m128 isr0 = _mm_rsqrt_ps(dot0);
// __m128 mul0 = _mm_mul_ps(v, isr0);
// return mul0;
// }
//
// __m128 rcp(__m128 v)
// {
// return _mm_rcp_ps(v);
// }
//
// //vec4 mad(vec4 v0, vec4 v1, vec4 v2)
// //{
// // return v0 * v1 + v2;
// //}
// __m128 mad(__m128 v0, __m128 v1, __m128 v2)
// {
// __m128 mul0 = _mm_mul_ps(v0, v1);
// __m128 add0 = _mm_add_ps(mul0, v2);
// return add0;
// }
//
// __m128 _mm_mad_ss(__m128 v0, __m128 v1, __m128 v2)
// {
// __m128 mul0 = _mm_mul_ss(v0, v1);
// __m128 add0 = _mm_add_ss(mul0, v2);
// return add0;
// }
//
// __m128 _mm_mad_ps(__m128 v0, __m128 v1, __m128 v2)
// {
// __m128 mul0 = _mm_mul_ps(v0, v1);
// __m128 add0 = _mm_add_ps(mul0, v2);
// return add0;
// }
//
// //vec4 reflect(vec4 I, vec4 N)
// //{
// // return I - N * dot(N, I) * 2.0f;
// //}
// __m128 reflect(__m128 I, __m128 N)
// {
// __m128 dot0 = dot(N, I);
// __m128 mul0 = _mm_mul_ps(N, I);
// __m128 mul1 = _mm_mul_ps(mul0, two);
// __m128 sub0 = _mm_sub_ps(I, mul1);
// return sub0;
// }
//
// __m128 _mm_rfe_ps(__m128 I, __m128 N)
// {
// __m128 dot0 = dot(N, I);
// __m128 mul0 = _mm_mul_ps(N, I);
// __m128 mul1 = _mm_mul_ps(mul0, two);
// __m128 sub0 = _mm_sub_ps(I, mul1);
// return sub0;
// }
//
// //vec4 refract(vec4 I, vec4 N, T eta)
// //{
// // float dotValue = dot(N, I);
// // float k = 1.0f - eta * eta * (1.0f - dotValue * dotValue);
// // if(k < 0.0f)
// // return vec4(0.0f);
// // return eta * I - (eta * dotValue + sqrt(k)) * N;
// //}
// __m128 refract(__m128 I, __m128 N, __m128 eta)
// {
// __m128 dot0 = dot(N, I);
// __m128 mul0 = _mm_mul_ps(eta, eta);
// __m128 mul1 = _mm_mul_ps(dot0, dot0);
// __m128 sub0 = _mm_sub_ps(one, mul0);
// __m128 sub1 = _mm_sub_ps(one, mul1);
// __m128 mul2 = _mm_mul_ps(sub0, sub1);
//
// if(_mm_movemask_ps(_mm_cmplt_ss(mul2, zero)) == 0)
// return zero;
//
// __m128 sqt0 = _mm_sqrt_ps(mul2);
// __m128 mul3 = _mm_mul_ps(eta, dot0);
// __m128 add0 = _mm_add_ps(mul3, sqt0);
// __m128 mul4 = _mm_mul_ps(add0, N);
// __m128 mul5 = _mm_mul_ps(eta, I);
// __m128 sub2 = _mm_sub_ps(mul5, mul4);
//
// return sub2;
// }
//
// __m128 _mm_rfa_ps(__m128 I, __m128 N, __m128 eta)
// {
// __m128 dot0 = dot(N, I);
// __m128 mul0 = _mm_mul_ps(eta, eta);
// __m128 mul1 = _mm_mul_ps(dot0, dot0);
// __m128 sub0 = _mm_sub_ps(one, mul0);
// __m128 sub1 = _mm_sub_ps(one, mul1);
// __m128 mul2 = _mm_mul_ps(sub0, sub1);
//
// if(_mm_movemask_ps(_mm_cmplt_ss(mul2, zero)) == 0)
// return zero;
//
// __m128 sqt0 = _mm_sqrt_ps(mul2);
// __m128 mul3 = _mm_mul_ps(eta, dot0);
// __m128 add0 = _mm_add_ps(mul3, sqt0);
// __m128 mul4 = _mm_mul_ps(add0, N);
// __m128 mul5 = _mm_mul_ps(eta, I);
// __m128 sub2 = _mm_sub_ps(mul5, mul4);
//
// return sub2;
// }
//
//
// struct vec4;
// typedef const vec4& vec4_param;
//
// template <int N>
// class comp
// {
// public:
// comp(int i) :
// index(i)
// {
// assert(i < N && i >= 0);
// }
//
// operator const int() const{return index;}
//
// private:
// int index;
// };
//
// typedef comp<4> comp4_t;
//
// struct vec4
// {
// vec4();
// vec4(float s);
// vec4(float x, float y, float z, float w);
// vec4(float v[4]);
//
// explicit vec4(__m128 data);
//
// vec4& operator= (vec4_param v);
// vec4& operator+=(float s);
// vec4& operator+=(vec4_param v);
// vec4& operator-=(float s);
// vec4& operator-=(vec4_param v);
// vec4& operator*=(float s);
// vec4& operator*=(vec4_param v);
// vec4& operator/=(float s);
// vec4& operator/=(vec4_param v);
// vec4& operator++();
// vec4& operator--();
//
// union
// {
// __m128 data;
// struct{float x, y, z, w;};
// float array[4];
// };
// };
//
// vec4::vec4() :
// data(_mm_setzero_ps())
// {}
//
// vec4::vec4(float s) :
// data(_mm_load_ps1(&s))
//// data(_mm_set_ps1(s))
// {}
//
// vec4::vec4(float v[4]) :
// data(_mm_load_ps(v))
// {}
//
// vec4::vec4(float x, float y, float z, float w) :
//// data(_mm_setr_ps(x, y, z, w))
// data(_mm_set_ps(w, z, y, x))
// {}
//
// vec4::vec4(__m128 data) :
// data(data)
// {}
//
// vec4& vec4::operator= (vec4_param v)
// {
// this->data = v.data;
// return *this;
// }
//
// vec4& vec4::operator+=(float s)
// {
// vec4 tmp(s);
// this->data = _mm_add_ps(this->data , tmp.data);
// return *this;
// }
//
// vec4& vec4::operator+=(vec4_param v)
// {
// this->data = _mm_add_ps(this->data , v.data);
// return *this;
// }
//
// vec4& vec4::operator-=(float s)
// {
// vec4 tmp(s);
// this->data = _mm_sub_ps(this->data , tmp.data);
// return *this;
// }
//
// vec4& vec4::operator-=(vec4_param v)
// {
// this->data = _mm_sub_ps(this->data , v.data);
// return *this;
// }
//
// vec4& vec4::operator*=(float s)
// {
// vec4 tmp(s);
// this->data = _mm_mul_ps(this->data , tmp.data);
// return *this;
// }
//
// vec4& vec4::operator*=(vec4_param v)
// {
// this->data = _mm_mul_ps(this->data , v.data);
// return *this;
// }
//
// vec4& vec4::operator/=(float s)
// {
// vec4 tmp(s);
// this->data = _mm_div_ps(this->data , tmp.data);
// return *this;
// }
//
// vec4& vec4::operator/=(vec4_param v)
// {
// this->data = _mm_div_ps(this->data , v.data);
// return *this;
// }
//
// vec4& vec4::operator++()
// {
// static __m128 inc = _mm_set_ps1(1.0f);
// this->data = _mm_add_ps(this->data , inc);
// return *this;
// }
//
// vec4& vec4::operator--()
// {
// static __m128 inc = _mm_set_ps1(1.0f);
// this->data = _mm_sub_ps(this->data , inc);
// return *this;
// }
//
// vec4 operator+ (const vec4& v1, const vec4& v2)
// {
// return vec4(_mm_add_ps(v1.data , v2.data));
// }
//
// vec4 operator+ (const vec4& v1, const float s)
// {
// vec4 v2(s);
// return vec4(_mm_add_ps(v1.data , v2.data));
// }
//
// vec4 operator+ (const float s, const vec4& v2)
// {
// vec4 v1(s);
// return vec4(_mm_add_ps(v1.data , v2.data));
// }
//
// vec4 operator- (const vec4& v1, const vec4& v2)
// {
// return vec4(_mm_sub_ps(v1.data , v2.data));
// }
//
// vec4 operator- (const vec4& v1, const float s)
// {
// vec4 v2(s);
// return vec4(_mm_sub_ps(v1.data , v2.data));
// }
//
// vec4 operator- (const float s, const vec4& v2)
// {
// vec4 v1(s);
// return vec4(_mm_sub_ps(v1.data , v2.data));
// }
//
// vec4 operator* (const vec4& v1, const vec4& v2)
// {
// return vec4(_mm_mul_ps(v1.data , v2.data));
// }
//
// vec4 operator* (const vec4& v1, const float s)
// {
// vec4 v2(s);
// return vec4(_mm_mul_ps(v1.data , v2.data));
// }
//
// vec4 operator* (const float s, const vec4& v2)
// {
// vec4 v1(s);
// return vec4(_mm_mul_ps(v1.data , v2.data));
// }
//
// vec4 operator/ (const vec4& v1, const vec4& v2)
// {
// return vec4(_mm_div_ps(v1.data , v2.data));
// }
//
// vec4 operator/ (const vec4& v1, const float s)
// {
// vec4 v2(s);
// return vec4(_mm_div_ps(v1.data , v2.data));
// }
//
// vec4 operator/ (const float s, const vec4& v2)
// {
// vec4 v1(s);
// return vec4(_mm_div_ps(v1.data , v2.data));
// }
//
// vec4 load(const vec4& v, const comp4_t component)
// {
// switch(component)
// {
// default:
// case 3:
// return vec4(_mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(0, 0, 0, 0)));
// case 2:
// return vec4(_mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(1, 1, 1, 1)));
// case 1:
// return vec4(_mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(2, 2, 2, 2)));
// case 0:
// return vec4(_mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 3, 3, 3)));
// }
// }
//
// vec4 rcp(vec4_param v)
// {
// return vec4(_mm_rcp_ps(v.data));
// }
//
// vec4 sqrt(vec4_param v)
// {
// return vec4(_mm_sqrt_ps(v.data));
// }
//
// vec4 inversesqrt(vec4_param v)
// {
// return vec4(_mm_rsqrt_ps(v.data));
// }
//
// vec4 min(vec4_param v1, vec4_param v2)
// {
// return vec4(_mm_min_ps(v1.data, v2.data));
// }
//
// vec4 max(vec4_param v1, vec4_param v2)
// {
// return vec4(_mm_max_ps(v1.data, v2.data));
// }
//
// vec4 clamp(vec4_param v, float minVal, float maxVal)
// {
// vec4 v1(minVal);
// vec4 v2(maxVal);
// return vec4(_mm_min_ps(_mm_max_ps(v.data, v2.data), v1.data));
// }
//
// vec4 clamp(vec4_param v, vec4_param minVal, vec4_param maxVal)
// {
// return vec4(_mm_min_ps(_mm_max_ps(v.data, maxVal.data), minVal.data));
// }
//
// vec4 mix(vec4_param x, vec4_param y, vec4_param a)
// {
// __m128 one = _mm_set_ps1(1.0f);
// __m128 b = _mm_sub_ps(one, a.data);
// __m128 mul1 = _mm_mul_ps(x.data, b);
// __m128 mul2 = _mm_mul_ps(y.data, a.data);
// __m128 addFinal = _mm_add_ps(mul1, mul2);
// return vec4(addFinal);
//
//
//// __m128 b = _mm_sub_ps(_mm_set_ps1(1.0f), a.data);
//// return vec4(_mm_add_ps(_mm_mul_ps(x.data, b), _mm_mul_ps(y.data, a.data)));
// }
//
// float dot(vec4_param x, vec4_param y)
// {
// float result = 0.0f;
// _mm_store_ss(&result, dot(x.data, y.data));
// return result;
// }
//
// vec4 reflect(vec4_param I, vec4_param N)
// {
// __m128 Normal = N.data;
// __m128 Inc = I.data;
// __m128 Two = _mm_set_ps1(2.0f);
// __m128 Mul = _mm_mul_ps(Normal, dot(Normal, Inc));
// return vec4(_mm_sub_ps(Inc, _mm_mul_ps(Mul, Two)));
// }
//
// vec4 refract(vec4_param I, vec4_param N, float eta)
// {
// __m128 zero = _mm_set_ps1(0.0f);
// __m128 eta1 = _mm_set_ps1(eta);
// __m128 eta2 = _mm_mul_ps(eta1, eta1);
// __m128 one = _mm_set_ps1(1.0f);
// __m128 dotValue = dot(I.data, N.data);
// __m128 dotValue2 = _mm_mul_ps(dotValue, dotValue);
// __m128 k = _mm_sub_ps(one, _mm_mul_ps(eta2, _mm_sub_ps(one, dotValue2)));
// __m128 isnull = _mm_cmplt_ss(k, zero);
// if(_mm_movemask_ps(isnull) == 0)
// return vec4(zero);
// else
// {
// __m128 temp0 = _mm_add_ps(_mm_mul_ps(eta1, dotValue), sqrt(k));
// __m128 temp1 = _mm_shuffle_ps(temp0, temp0, _MM_SHUFFLE(0, 0, 0, 0));
// __m128 temp2 = _mm_mul_ps(temp1, N.data);
// __m128 temp3 = _mm_mul_ps(eta1, I.data);
// return vec4(_mm_sub_ps(temp3, temp2));
// }
// }
//
//
//};
//
//namespace glm
//{
// glm::vec4 rcp(const glm::vec4& v)
// {
// return 1.0f / v;
// }
//}
//
//namespace cpu
//{
// void sincos(float a, float &s, float &c)
// {
// _asm
// {
// fld a
// fsincos
// mov ecx, c
// mov edx, s
// fstp dword ptr [ecx]
// fstp dword ptr [edx]
// }
// }
//
// void sincos(double a, double& s, double& c)
// {
// _asm
// {
// fld a
// fsincos
// mov ecx, c
// mov edx, s
// fstp qword ptr [ecx]
// fstp qword ptr [edx]
// }
// }
//
// float sin(float s)
// {
// float result = 0.0f;
// float* p = &result;
// _asm
// {
// fld s
// fsin
// mov ecx, p
// fstp dword ptr [ecx]
// }
// return result;
//
// //float result = 0.0f;
// //_asm
// //{
// // fld s
// // fsin
// // mov ecx, result
// // fstp dword ptr [ecx]
// //}
// //return result;
// }
//
// float abs(float s)
// {
// float result = 0.0f;
// float* p = &result;
// _asm
// {
// fld s
// fabs
// mov ecx, p
// fstp dword ptr [ecx]
// }
// return result;
//
// //float result = 0.0f;
// //_asm
// //{
// // fld s
// // fsin
// // mov ecx, result
// // fstp dword ptr [ecx]
// //}
// //return result;
// }
//
// float add(float s1, float s2)
// {
// float result = 0.0f;
// float* p = &result;
// _asm
// {
// fld s1
// fld s2
// fadd
// mov ecx, p
// fstp dword ptr [ecx]
// }
// return result;
// }
//
// float sub(float s1, float s2)
// {
// float result = 0.0f;
// float* p = &result;
// _asm
// {
// fld s1
// fld s2
// fsub
// mov ecx, p
// fstp dword ptr [ecx]
// }
// return result;
// }
//
// float mul(float s1, float s2)
// {
// float result = 0.0f;
// float* p = &result;
// _asm
// {
// fld s1
// fld s2
// fmul
// mov ecx, p
// fstp dword ptr [ecx]
// }
// return result;
// }
//
// float div(float s1, float s2)
// {
// float result = 0.0f;
// float* p = &result;
// _asm
// {
// fld s1
// fld s2
// fdiv
// mov ecx, p
// fstp dword ptr [ecx]
// }
// return result;
// }
//}
//
//void test_asm()
//{
// float sin0 = cpu::sin(1.0f);
// float sin1 = glm::sin(1.0f);
// float add0 = cpu::add(1.0f, 2.0f);
// float sub0 = cpu::sub(1.0f, 2.0f);
//
//
// float end = 1.0f;
//}
//
//void test_clamp()
//{
// sse::vec4 v(0.5f, 0.5f, 9.5f, 9.5f);
// sse::vec4 minVal(1.0f, 2.0f, 3.0f, 4.0f);
// sse::vec4 maxVal(5.0f, 6.0f, 7.0f, 8.0f);
//
// __m128 clamp0 = sse::clamp(
// v.data,
// minVal.data,
// maxVal.data);
//
// glm::vec4 clamp1 = glm::clamp(
// glm::vec4(0.5f, 0.5f, 9.5f, 9.5f),
// glm::vec4(1.0f, 2.0f, 3.0f, 4.0f),
// glm::vec4(5.0f, 6.0f, 7.0f, 8.0f));
//
// __m128 end = _mm_setzero_ps();
//}
//
//#define DECLARE_EPI32_CONST(name) \
// extern const _MM_ALIGN16 int _epi32_##name[4];
//#define IMPLEMENT_EPI32_CONST(name,x) \
// const _MM_ALIGN16 int _epi32_##name[4]={x,x,x,x};
//#define IMPLEMENT_EPI32_CONST4(name,x,y,z,w) \
// const _MM_ALIGN16 int _epi32_##name[4]={w,z,y,x};
//
//#define DECLARE_PS_CONST(name) \
// extern const _MM_ALIGN16 float _ps_##name[4];
//#define IMPLEMENT_PS_CONST(name,x) \
// const _MM_ALIGN16 float _ps_##name[4]={x,x,x,x};
//#define IMPLEMENT_PS_CONST4(name,x,y,z,w) \
// const _MM_ALIGN16 float _ps_##name[4]={w,z,y,x};
//
////IMPLEMENT_PS_CONST(sincos_p0, 0.15707963267948963959e1f)
////IMPLEMENT_PS_CONST(sincos_p1, -0.64596409750621907082e0f)
////IMPLEMENT_PS_CONST(sincos_p2, 0.7969262624561800806e-1f)
////IMPLEMENT_PS_CONST(sincos_p3, -0.468175413106023168e-2f)
//
//IMPLEMENT_EPI32_CONST(sign_mask,0x80000000)
//IMPLEMENT_EPI32_CONST(inv_sign_mask,0x7FFFFFFF)
//IMPLEMENT_EPI32_CONST(mant_mask,0x7F800000)
//IMPLEMENT_EPI32_CONST(inv_mant_mask,0x807FFFFF)
//IMPLEMENT_EPI32_CONST(min_norm_pos,0x00800000)
//IMPLEMENT_EPI32_CONST(1,1)
//IMPLEMENT_EPI32_CONST(2,2)
//IMPLEMENT_EPI32_CONST(7,7)
//IMPLEMENT_EPI32_CONST(127,127)
//IMPLEMENT_EPI32_CONST(ninf,0xFF800000)
//IMPLEMENT_EPI32_CONST(pinf,0x7F800000)
//
//IMPLEMENT_PS_CONST(1_3,0.33333333333333333333333333333333f)
//IMPLEMENT_PS_CONST(0p5,0.5f)
//IMPLEMENT_PS_CONST(1,1.0f)
//IMPLEMENT_PS_CONST(m1,-1.0f)
//IMPLEMENT_PS_CONST(2,2.0f)
//IMPLEMENT_PS_CONST(3,3.0f)
//IMPLEMENT_PS_CONST(127,127.0f)
//IMPLEMENT_PS_CONST(255,255.0f)
//IMPLEMENT_PS_CONST(2pow23,8388608.0f)
//
//IMPLEMENT_PS_CONST4(1_0_0_0,1.0f,0.0f,0.0f,0.0f)
//IMPLEMENT_PS_CONST4(0_1_0_0,0.0f,1.0f,0.0f,0.0f)
//IMPLEMENT_PS_CONST4(0_0_1_0,0.0f,0.0f,1.0f,0.0f)
//IMPLEMENT_PS_CONST4(0_0_0_1,0.0f,0.0f,0.0f,1.0f)
//
//IMPLEMENT_PS_CONST(pi, 3.1415926535897932384626433832795f)
//IMPLEMENT_PS_CONST(pi2, 6.283185307179586476925286766560f)
//IMPLEMENT_PS_CONST(2_pi, 0.63661977236758134307553505349006f)
//IMPLEMENT_PS_CONST(pi_2, 1.5707963267948966192313216916398f)
//IMPLEMENT_PS_CONST(4_pi, 1.2732395447351626861510701069801f)
//IMPLEMENT_PS_CONST(pi_4, 0.78539816339744830961566084581988f)
//
//IMPLEMENT_PS_CONST(sincos_p0, 0.15707963267948963959e1f)
//IMPLEMENT_PS_CONST(sincos_p1, -0.64596409750621907082e0f)
//IMPLEMENT_PS_CONST(sincos_p2, 0.7969262624561800806e-1f)
//IMPLEMENT_PS_CONST(sincos_p3, -0.468175413106023168e-2f)
//IMPLEMENT_PS_CONST(tan_p0, -1.79565251976484877988e7f)
//IMPLEMENT_PS_CONST(tan_p1, 1.15351664838587416140e6f)
//IMPLEMENT_PS_CONST(tan_p2, -1.30936939181383777646e4f)
//IMPLEMENT_PS_CONST(tan_q0, -5.38695755929454629881e7f)
//IMPLEMENT_PS_CONST(tan_q1, 2.50083801823357915839e7f)
//IMPLEMENT_PS_CONST(tan_q2, -1.32089234440210967447e6f)
//IMPLEMENT_PS_CONST(tan_q3, 1.36812963470692954678e4f)
//IMPLEMENT_PS_CONST(tan_poleval,3.68935e19f)
//IMPLEMENT_PS_CONST(atan_t0, -0.91646118527267623468e-1f)
//IMPLEMENT_PS_CONST(atan_t1, -0.13956945682312098640e1f)
//IMPLEMENT_PS_CONST(atan_t2, -0.94393926122725531747e2f)
//IMPLEMENT_PS_CONST(atan_t3, 0.12888383034157279340e2f)
//IMPLEMENT_PS_CONST(atan_s0, 0.12797564625607904396e1f)
//IMPLEMENT_PS_CONST(atan_s1, 0.21972168858277355914e1f)
//IMPLEMENT_PS_CONST(atan_s2, 0.68193064729268275701e1f)
//IMPLEMENT_PS_CONST(atan_s3, 0.28205206687035841409e2f)
//
//IMPLEMENT_PS_CONST(exp_hi, 88.3762626647949f)
//IMPLEMENT_PS_CONST(exp_lo, -88.3762626647949f)
//IMPLEMENT_PS_CONST(exp_rln2, 1.4426950408889634073599f)
//IMPLEMENT_PS_CONST(exp_p0, 1.26177193074810590878e-4f)
//IMPLEMENT_PS_CONST(exp_p1, 3.02994407707441961300e-2f)
//IMPLEMENT_PS_CONST(exp_q0, 3.00198505138664455042e-6f)
//IMPLEMENT_PS_CONST(exp_q1, 2.52448340349684104192e-3f)
//IMPLEMENT_PS_CONST(exp_q2, 2.27265548208155028766e-1f)
//IMPLEMENT_PS_CONST(exp_q3, 2.00000000000000000009e0f)
//IMPLEMENT_PS_CONST(exp_c1, 6.93145751953125e-1f)
//IMPLEMENT_PS_CONST(exp_c2, 1.42860682030941723212e-6f)
//IMPLEMENT_PS_CONST(exp2_hi, 127.4999961853f)
//IMPLEMENT_PS_CONST(exp2_lo, -127.4999961853f)
//IMPLEMENT_PS_CONST(exp2_p0, 2.30933477057345225087e-2f)
//IMPLEMENT_PS_CONST(exp2_p1, 2.02020656693165307700e1f)
//IMPLEMENT_PS_CONST(exp2_p2, 1.51390680115615096133e3f)
//IMPLEMENT_PS_CONST(exp2_q0, 2.33184211722314911771e2f)
//IMPLEMENT_PS_CONST(exp2_q1, 4.36821166879210612817e3f)
//IMPLEMENT_PS_CONST(log_p0, -7.89580278884799154124e-1f)
//IMPLEMENT_PS_CONST(log_p1, 1.63866645699558079767e1f)
//IMPLEMENT_PS_CONST(log_p2, -6.41409952958715622951e1f)
//IMPLEMENT_PS_CONST(log_q0, -3.56722798256324312549e1f)
//IMPLEMENT_PS_CONST(log_q1, 3.12093766372244180303e2f)
//IMPLEMENT_PS_CONST(log_q2, -7.69691943550460008604e2f)
//IMPLEMENT_PS_CONST(log_c0, 0.693147180559945f)
//IMPLEMENT_PS_CONST(log2_c0, 1.44269504088896340735992f)
//
//#define GLM_NAKED __declspec(naked) __cdecl
//
//__m128 GLM_NAKED _mm_cos_ps(__m128 x)
//{
// __asm
// {
// andps xmm0, _epi32_inv_sign_mask
// addps xmm0, _ps_pi_2
// mulps xmm0, _ps_2_pi
// pxor xmm3, xmm3
// movdqa xmm5, _epi32_1
// movaps xmm4, _ps_1
// cvttps2dq xmm2, xmm0
// pand xmm5, xmm2
// pcmpeqd xmm5, xmm3
// cvtdq2ps xmm6, xmm2
// pand xmm2, _epi32_2
// pslld xmm2, 30
// subps xmm0, xmm6
// minps xmm0, xmm4
// subps xmm4, xmm0
// andps xmm0, xmm5
// andnps xmm5, xmm4
// orps xmm0, xmm5
// movaps xmm1, xmm0
// mulps xmm0, xmm0
// orps xmm1, xmm2
// movaps xmm7, xmm0
// mulps xmm0, _ps_sincos_p3
// addps xmm0, _ps_sincos_p2
// mulps xmm0, xmm7
// addps xmm0, _ps_sincos_p1
// mulps xmm0, xmm7
// addps xmm0, _ps_sincos_p0
// mulps xmm0, xmm1
// ret
// }
//}
//
//void test_sse()
//{
// sse::vec4 v1(1.0f, 2.0f, 3.0f, 4.0f);
// sse::vec4 v2(5.0f, 6.0f, 7.0f, 8.0f);
// sse::vec4 v3(9.0f);
// sse::vec4 v4(0.5f, 0.5f, 0.5f, 0.5f);
// __m128 v5 = sse::mix(v1.data, v2.data, v4.data);
// __m128 dot0 = sse::dot(v1.data, v2.data);
// float dot1 = sse::dot(v1, v2);
// __m128 rcp0 = sse::rcp(v1.data);
// glm::vec4 rcp1 = rcp(glm::vec4(1.0f, 2.0f, 3.0f, 4.0f));
//
// // cross
// {
// sse::vec4 v1(4.0f, 2.0f, 2.0f, 0.0f);
// sse::vec4 v2(1.0f, 2.0f, 3.0f, 0.0f);
// __m128 crs0 = sse::cross(v1.data, v2.data);
//
// glm::vec3 v3(4.0f, 2.0f, 2.0f);
// glm::vec3 v4(1.0f, 2.0f, 3.0f);
// glm::vec3 crs1 = glm::cross(v3, v4);
//
// __m128 end = _mm_set_ps1(1.0f);
// }
//
// // ieee754
// {
// sse::detail::ieee754 one(1.f);
// float f = sse::load(one.mantissa, one.exp, one.sign);
//
// __m128 end = _mm_set_ps1(1.0f);
// }
//
// test_clamp();
// test_asm();
//
// __m128 cos0 = _mm_cos_ps(_mm_set_ps1(1.0f));
// glm::vec4 cos1 = glm::cos(glm::vec4(1.0f));
//
// float f = glm::dot(glm::vec4(1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(5.0f, 6.0f, 7.0f, 8.0f));
// sse::vec4 end(9.0f);
//
// //sse::vec4 vComp = sse::load(sse::vec4(1.0f, 2.0f, 3.0f, 4.0f), 1);
// //vComp += sse::vec4(1.0f);
// //--vComp;
// //sse::vec4 vMixed = sse::mix(vComp, sse::vec4(-0.5f), sse::vec4(0.5f));
// //float sDot = sse::dot(sse::vec4(1.0f), sse::vec4(2.0f));
// //float cDot = glm::dot(glm::vec4(1.0f), glm::vec4(2.0f));
//}