diff options
Diffstat (limited to 'Eigen/src/Core/arch/SSE/MathFunctions.h')
-rw-r--r-- | Eigen/src/Core/arch/SSE/MathFunctions.h | 226 |
1 files changed, 115 insertions, 111 deletions
diff --git a/Eigen/src/Core/arch/SSE/MathFunctions.h b/Eigen/src/Core/arch/SSE/MathFunctions.h index cb73fd205..9d56d8218 100644 --- a/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -30,8 +30,10 @@ #ifndef EIGEN_MATH_FUNCTIONS_SSE_H #define EIGEN_MATH_FUNCTIONS_SSE_H +namespace internal { + template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet4f ei_plog<Packet4f>(const Packet4f& _x) +Packet4f plog<Packet4f>(const Packet4f& _x) { Packet4f x = _x; _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); @@ -64,15 +66,15 @@ Packet4f ei_plog<Packet4f>(const Packet4f& _x) Packet4f invalid_mask = _mm_cmple_ps(x, _mm_setzero_ps()); - x = ei_pmax(x, ei_p4f_min_norm_pos); /* cut off denormalized stuff */ + x = pmax(x, p4f_min_norm_pos); /* cut off denormalized stuff */ emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23); /* keep only the fractional part */ - x = _mm_and_ps(x, ei_p4f_inv_mant_mask); - x = _mm_or_ps(x, ei_p4f_half); + x = _mm_and_ps(x, p4f_inv_mant_mask); + x = _mm_or_ps(x, p4f_half); - emm0 = _mm_sub_epi32(emm0, ei_p4i_0x7f); - Packet4f e = ei_padd(_mm_cvtepi32_ps(emm0), ei_p4f_1); + emm0 = _mm_sub_epi32(emm0, p4i_0x7f); + Packet4f e = padd(_mm_cvtepi32_ps(emm0), p4f_1); /* part2: if( x < SQRTHF ) { @@ -80,38 +82,38 @@ Packet4f ei_plog<Packet4f>(const Packet4f& _x) x = x + x - 1.0; } else { x = x - 1.0; } */ - Packet4f mask = _mm_cmplt_ps(x, ei_p4f_cephes_SQRTHF); + Packet4f mask = _mm_cmplt_ps(x, p4f_cephes_SQRTHF); Packet4f tmp = _mm_and_ps(x, mask); - x = ei_psub(x, ei_p4f_1); - e = ei_psub(e, _mm_and_ps(ei_p4f_1, mask)); - x = ei_padd(x, tmp); + x = psub(x, p4f_1); + e = psub(e, _mm_and_ps(p4f_1, mask)); + x = padd(x, tmp); - Packet4f x2 = ei_pmul(x,x); - Packet4f x3 = ei_pmul(x2,x); + Packet4f x2 = pmul(x,x); + Packet4f x3 = pmul(x2,x); Packet4f y, y1, y2; - y = ei_pmadd(ei_p4f_cephes_log_p0, x, ei_p4f_cephes_log_p1); - y1 = ei_pmadd(ei_p4f_cephes_log_p3, x, ei_p4f_cephes_log_p4); - y2 = ei_pmadd(ei_p4f_cephes_log_p6, x, ei_p4f_cephes_log_p7); - y = ei_pmadd(y , x, ei_p4f_cephes_log_p2); - y1 = ei_pmadd(y1, x, ei_p4f_cephes_log_p5); - y2 = ei_pmadd(y2, x, ei_p4f_cephes_log_p8); - y = ei_pmadd(y, x3, y1); - y = ei_pmadd(y, x3, y2); - y = ei_pmul(y, x3); - - y1 = ei_pmul(e, ei_p4f_cephes_log_q1); - tmp = ei_pmul(x2, ei_p4f_half); - y = ei_padd(y, y1); - x = ei_psub(x, tmp); - y2 = ei_pmul(e, ei_p4f_cephes_log_q2); - x = ei_padd(x, y); - x = ei_padd(x, y2); + y = pmadd(p4f_cephes_log_p0, x, p4f_cephes_log_p1); + y1 = pmadd(p4f_cephes_log_p3, x, p4f_cephes_log_p4); + y2 = pmadd(p4f_cephes_log_p6, x, p4f_cephes_log_p7); + y = pmadd(y , x, p4f_cephes_log_p2); + y1 = pmadd(y1, x, p4f_cephes_log_p5); + y2 = pmadd(y2, x, p4f_cephes_log_p8); + y = pmadd(y, x3, y1); + y = pmadd(y, x3, y2); + y = pmul(y, x3); + + y1 = pmul(e, p4f_cephes_log_q1); + tmp = pmul(x2, p4f_half); + y = padd(y, y1); + x = psub(x, tmp); + y2 = pmul(e, p4f_cephes_log_q2); + x = padd(x, y); + x = padd(x, y2); return _mm_or_ps(x, invalid_mask); // negative arg will be NAN } template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet4f ei_pexp<Packet4f>(const Packet4f& _x) +Packet4f pexp<Packet4f>(const Packet4f& _x) { Packet4f x = _x; _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); @@ -137,40 +139,40 @@ Packet4f ei_pexp<Packet4f>(const Packet4f& _x) Packet4i emm0; // clamp x - x = ei_pmax(ei_pmin(x, ei_p4f_exp_hi), ei_p4f_exp_lo); + x = pmax(pmin(x, p4f_exp_hi), p4f_exp_lo); /* express exp(x) as exp(g + n*log(2)) */ - fx = ei_pmadd(x, ei_p4f_cephes_LOG2EF, ei_p4f_half); + fx = pmadd(x, p4f_cephes_LOG2EF, p4f_half); /* how to perform a floorf with SSE: just below */ emm0 = _mm_cvttps_epi32(fx); tmp = _mm_cvtepi32_ps(emm0); /* if greater, substract 1 */ Packet4f mask = _mm_cmpgt_ps(tmp, fx); - mask = _mm_and_ps(mask, ei_p4f_1); - fx = ei_psub(tmp, mask); + mask = _mm_and_ps(mask, p4f_1); + fx = psub(tmp, mask); - tmp = ei_pmul(fx, ei_p4f_cephes_exp_C1); - Packet4f z = ei_pmul(fx, ei_p4f_cephes_exp_C2); - x = ei_psub(x, tmp); - x = ei_psub(x, z); + tmp = pmul(fx, p4f_cephes_exp_C1); + Packet4f z = pmul(fx, p4f_cephes_exp_C2); + x = psub(x, tmp); + x = psub(x, z); - z = ei_pmul(x,x); + z = pmul(x,x); - Packet4f y = ei_p4f_cephes_exp_p0; - y = ei_pmadd(y, x, ei_p4f_cephes_exp_p1); - y = ei_pmadd(y, x, ei_p4f_cephes_exp_p2); - y = ei_pmadd(y, x, ei_p4f_cephes_exp_p3); - y = ei_pmadd(y, x, ei_p4f_cephes_exp_p4); - y = ei_pmadd(y, x, ei_p4f_cephes_exp_p5); - y = ei_pmadd(y, z, x); - y = ei_padd(y, ei_p4f_1); + Packet4f y = p4f_cephes_exp_p0; + y = pmadd(y, x, p4f_cephes_exp_p1); + y = pmadd(y, x, p4f_cephes_exp_p2); + y = pmadd(y, x, p4f_cephes_exp_p3); + y = pmadd(y, x, p4f_cephes_exp_p4); + y = pmadd(y, x, p4f_cephes_exp_p5); + y = pmadd(y, z, x); + y = padd(y, p4f_1); /* build 2^n */ emm0 = _mm_cvttps_epi32(fx); - emm0 = _mm_add_epi32(emm0, ei_p4i_0x7f); + emm0 = _mm_add_epi32(emm0, p4i_0x7f); emm0 = _mm_slli_epi32(emm0, 23); - return ei_pmul(y, _mm_castsi128_ps(emm0)); + return pmul(y, _mm_castsi128_ps(emm0)); } /* evaluation of 4 sines at onces, using SSE2 intrinsics. @@ -186,7 +188,7 @@ Packet4f ei_pexp<Packet4f>(const Packet4f& _x) */ template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet4f ei_psin<Packet4f>(const Packet4f& _x) +Packet4f psin<Packet4f>(const Packet4f& _x) { Packet4f x = _x; _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); @@ -215,24 +217,24 @@ Packet4f ei_psin<Packet4f>(const Packet4f& _x) Packet4i emm0, emm2; sign_bit = x; /* take the absolute value */ - x = ei_pabs(x); + x = pabs(x); /* take the modulo */ /* extract the sign bit (upper one) */ - sign_bit = _mm_and_ps(sign_bit, ei_p4f_sign_mask); + sign_bit = _mm_and_ps(sign_bit, p4f_sign_mask); /* scale by 4/Pi */ - y = ei_pmul(x, ei_p4f_cephes_FOPI); + y = pmul(x, p4f_cephes_FOPI); /* store the integer part of y in mm0 */ emm2 = _mm_cvttps_epi32(y); /* j=(j+1) & (~1) (see the cephes sources) */ - emm2 = _mm_add_epi32(emm2, ei_p4i_1); - emm2 = _mm_and_si128(emm2, ei_p4i_not1); + emm2 = _mm_add_epi32(emm2, p4i_1); + emm2 = _mm_and_si128(emm2, p4i_not1); y = _mm_cvtepi32_ps(emm2); /* get the swap sign flag */ - emm0 = _mm_and_si128(emm2, ei_p4i_4); + emm0 = _mm_and_si128(emm2, p4i_4); emm0 = _mm_slli_epi32(emm0, 29); /* get the polynom selection mask there is one polynom for 0 <= x <= Pi/4 @@ -240,7 +242,7 @@ Packet4f ei_psin<Packet4f>(const Packet4f& _x) Both branches will be computed. */ - emm2 = _mm_and_si128(emm2, ei_p4i_2); + emm2 = _mm_and_si128(emm2, p4i_2); emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128()); Packet4f swap_sign_bit = _mm_castsi128_ps(emm0); @@ -249,33 +251,33 @@ Packet4f ei_psin<Packet4f>(const Packet4f& _x) /* The magic pass: "Extended precision modular arithmetic" x = ((x - y * DP1) - y * DP2) - y * DP3; */ - xmm1 = ei_pmul(y, ei_p4f_minus_cephes_DP1); - xmm2 = ei_pmul(y, ei_p4f_minus_cephes_DP2); - xmm3 = ei_pmul(y, ei_p4f_minus_cephes_DP3); - x = ei_padd(x, xmm1); - x = ei_padd(x, xmm2); - x = ei_padd(x, xmm3); + xmm1 = pmul(y, p4f_minus_cephes_DP1); + xmm2 = pmul(y, p4f_minus_cephes_DP2); + xmm3 = pmul(y, p4f_minus_cephes_DP3); + x = padd(x, xmm1); + x = padd(x, xmm2); + x = padd(x, xmm3); /* Evaluate the first polynom (0 <= x <= Pi/4) */ - y = ei_p4f_coscof_p0; + y = p4f_coscof_p0; Packet4f z = _mm_mul_ps(x,x); - y = ei_pmadd(y, z, ei_p4f_coscof_p1); - y = ei_pmadd(y, z, ei_p4f_coscof_p2); - y = ei_pmul(y, z); - y = ei_pmul(y, z); - Packet4f tmp = ei_pmul(z, ei_p4f_half); - y = ei_psub(y, tmp); - y = ei_padd(y, ei_p4f_1); + y = pmadd(y, z, p4f_coscof_p1); + y = pmadd(y, z, p4f_coscof_p2); + y = pmul(y, z); + y = pmul(y, z); + Packet4f tmp = pmul(z, p4f_half); + y = psub(y, tmp); + y = padd(y, p4f_1); /* Evaluate the second polynom (Pi/4 <= x <= 0) */ - Packet4f y2 = ei_p4f_sincof_p0; - y2 = ei_pmadd(y2, z, ei_p4f_sincof_p1); - y2 = ei_pmadd(y2, z, ei_p4f_sincof_p2); - y2 = ei_pmul(y2, z); - y2 = ei_pmul(y2, x); - y2 = ei_padd(y2, x); + Packet4f y2 = p4f_sincof_p0; + y2 = pmadd(y2, z, p4f_sincof_p1); + y2 = pmadd(y2, z, p4f_sincof_p2); + y2 = pmul(y2, z); + y2 = pmul(y2, x); + y2 = padd(y2, x); /* select the correct result from the two polynoms */ y2 = _mm_and_ps(poly_mask, y2); @@ -285,9 +287,9 @@ Packet4f ei_psin<Packet4f>(const Packet4f& _x) return _mm_xor_ps(y, sign_bit); } -/* almost the same as ei_psin */ +/* almost the same as psin */ template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet4f ei_pcos<Packet4f>(const Packet4f& _x) +Packet4f pcos<Packet4f>(const Packet4f& _x) { Packet4f x = _x; _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); @@ -312,25 +314,25 @@ Packet4f ei_pcos<Packet4f>(const Packet4f& _x) Packet4f xmm1, xmm2 = _mm_setzero_ps(), xmm3, y; Packet4i emm0, emm2; - x = ei_pabs(x); + x = pabs(x); /* scale by 4/Pi */ - y = ei_pmul(x, ei_p4f_cephes_FOPI); + y = pmul(x, p4f_cephes_FOPI); /* get the integer part of y */ emm2 = _mm_cvttps_epi32(y); /* j=(j+1) & (~1) (see the cephes sources) */ - emm2 = _mm_add_epi32(emm2, ei_p4i_1); - emm2 = _mm_and_si128(emm2, ei_p4i_not1); + emm2 = _mm_add_epi32(emm2, p4i_1); + emm2 = _mm_and_si128(emm2, p4i_not1); y = _mm_cvtepi32_ps(emm2); - emm2 = _mm_sub_epi32(emm2, ei_p4i_2); + emm2 = _mm_sub_epi32(emm2, p4i_2); /* get the swap sign flag */ - emm0 = _mm_andnot_si128(emm2, ei_p4i_4); + emm0 = _mm_andnot_si128(emm2, p4i_4); emm0 = _mm_slli_epi32(emm0, 29); /* get the polynom selection mask */ - emm2 = _mm_and_si128(emm2, ei_p4i_2); + emm2 = _mm_and_si128(emm2, p4i_2); emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128()); Packet4f sign_bit = _mm_castsi128_ps(emm0); @@ -338,31 +340,31 @@ Packet4f ei_pcos<Packet4f>(const Packet4f& _x) /* The magic pass: "Extended precision modular arithmetic" x = ((x - y * DP1) - y * DP2) - y * DP3; */ - xmm1 = ei_pmul(y, ei_p4f_minus_cephes_DP1); - xmm2 = ei_pmul(y, ei_p4f_minus_cephes_DP2); - xmm3 = ei_pmul(y, ei_p4f_minus_cephes_DP3); - x = ei_padd(x, xmm1); - x = ei_padd(x, xmm2); - x = ei_padd(x, xmm3); + xmm1 = pmul(y, p4f_minus_cephes_DP1); + xmm2 = pmul(y, p4f_minus_cephes_DP2); + xmm3 = pmul(y, p4f_minus_cephes_DP3); + x = padd(x, xmm1); + x = padd(x, xmm2); + x = padd(x, xmm3); /* Evaluate the first polynom (0 <= x <= Pi/4) */ - y = ei_p4f_coscof_p0; - Packet4f z = ei_pmul(x,x); + y = p4f_coscof_p0; + Packet4f z = pmul(x,x); - y = ei_pmadd(y,z,ei_p4f_coscof_p1); - y = ei_pmadd(y,z,ei_p4f_coscof_p2); - y = ei_pmul(y, z); - y = ei_pmul(y, z); - Packet4f tmp = _mm_mul_ps(z, ei_p4f_half); - y = ei_psub(y, tmp); - y = ei_padd(y, ei_p4f_1); + y = pmadd(y,z,p4f_coscof_p1); + y = pmadd(y,z,p4f_coscof_p2); + y = pmul(y, z); + y = pmul(y, z); + Packet4f tmp = _mm_mul_ps(z, p4f_half); + y = psub(y, tmp); + y = padd(y, p4f_1); /* Evaluate the second polynom (Pi/4 <= x <= 0) */ - Packet4f y2 = ei_p4f_sincof_p0; - y2 = ei_pmadd(y2, z, ei_p4f_sincof_p1); - y2 = ei_pmadd(y2, z, ei_p4f_sincof_p2); - y2 = ei_pmul(y2, z); - y2 = ei_pmadd(y2, x, x); + Packet4f y2 = p4f_sincof_p0; + y2 = pmadd(y2, z, p4f_sincof_p1); + y2 = pmadd(y2, z, p4f_sincof_p2); + y2 = pmul(y2, z); + y2 = pmadd(y2, x, x); /* select the correct result from the two polynoms */ y2 = _mm_and_ps(poly_mask, y2); @@ -376,16 +378,18 @@ Packet4f ei_pcos<Packet4f>(const Packet4f& _x) // This is based on Quake3's fast inverse square root. // For detail see here: http://www.beyond3d.com/content/articles/8/ template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED -Packet4f ei_psqrt<Packet4f>(const Packet4f& _x) +Packet4f psqrt<Packet4f>(const Packet4f& _x) { - Packet4f half = ei_pmul(_x, ei_pset1<Packet4f>(.5f)); + Packet4f half = pmul(_x, pset1<Packet4f>(.5f)); /* select only the inverse sqrt of non-zero inputs */ - Packet4f non_zero_mask = _mm_cmpgt_ps(_x, ei_pset1<Packet4f>(std::numeric_limits<float>::epsilon())); + Packet4f non_zero_mask = _mm_cmpgt_ps(_x, pset1<Packet4f>(std::numeric_limits<float>::epsilon())); Packet4f x = _mm_and_ps(non_zero_mask, _mm_rsqrt_ps(_x)); - x = ei_pmul(x, ei_psub(ei_pset1<Packet4f>(1.5f), ei_pmul(half, ei_pmul(x,x)))); - return ei_pmul(_x,x); + x = pmul(x, psub(pset1<Packet4f>(1.5f), pmul(half, pmul(x,x)))); + return pmul(_x,x); } +} // end namespace internal + #endif // EIGEN_MATH_FUNCTIONS_SSE_H |