12b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This file is part of Eigen, a lightweight C++ template library 22b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// for linear algebra. 32b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// 42b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This Source Code Form is subject to the terms of the Mozilla 52b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Public License v. 2.0. If a copy of the MPL was not distributed 62b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 72b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 82b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/* The sin, cos, exp, and log functions of this file come from 92b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ 102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifndef EIGEN_MATH_FUNCTIONS_NEON_H 132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define EIGEN_MATH_FUNCTIONS_NEON_H 142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace Eigen { 162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal { 182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED 202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangPacket4f pexp<Packet4f>(const Packet4f& _x) 212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Packet4f x = _x; 232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Packet4f tmp, fx; 242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); 262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f); 272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f); 282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(exp_hi, 88.3762626647950f); 292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(exp_lo, -88.3762626647949f); 302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(cephes_LOG2EF, 1.44269504088896341f); 312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_C1, 0.693359375f); 322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_C2, -2.12194440e-4f); 332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p0, 1.9875691500E-4f); 342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p1, 1.3981999507E-3f); 352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p2, 8.3334519073E-3f); 362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p3, 4.1665795894E-2f); 372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p4, 1.6666665459E-1f); 382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p5, 5.0000001201E-1f); 392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang x = vminq_f32(x, p4f_exp_hi); 412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang x = vmaxq_f32(x, p4f_exp_lo); 422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /* express exp(x) as exp(g + n*log(2)) */ 442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang fx = vmlaq_f32(p4f_half, x, p4f_cephes_LOG2EF); 452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /* perform a floorf */ 472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang tmp = vcvtq_f32_s32(vcvtq_s32_f32(fx)); 482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /* if greater, substract 1 */ 502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Packet4ui mask = vcgtq_f32(tmp, fx); 512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang mask = vandq_u32(mask, vreinterpretq_u32_f32(p4f_1)); 522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang fx = vsubq_f32(tmp, vreinterpretq_f32_u32(mask)); 542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang tmp = vmulq_f32(fx, p4f_cephes_exp_C1); 562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Packet4f z = vmulq_f32(fx, p4f_cephes_exp_C2); 572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang x = vsubq_f32(x, tmp); 582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang x = vsubq_f32(x, z); 592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Packet4f y = vmulq_f32(p4f_cephes_exp_p0, x); 612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang z = vmulq_f32(x, x); 622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vaddq_f32(y, p4f_cephes_exp_p1); 632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vmulq_f32(y, x); 642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vaddq_f32(y, p4f_cephes_exp_p2); 652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vmulq_f32(y, x); 662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vaddq_f32(y, p4f_cephes_exp_p3); 672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vmulq_f32(y, x); 682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vaddq_f32(y, p4f_cephes_exp_p4); 692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vmulq_f32(y, x); 702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vaddq_f32(y, p4f_cephes_exp_p5); 712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vmulq_f32(y, z); 732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vaddq_f32(y, x); 742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vaddq_f32(y, p4f_1); 752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /* build 2^n */ 772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang int32x4_t mm; 782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang mm = vcvtq_s32_f32(fx); 792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang mm = vaddq_s32(mm, p4i_0x7f); 802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang mm = vshlq_n_s32(mm, 23); 812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Packet4f pow2n = vreinterpretq_f32_s32(mm); 822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang y = vmulq_f32(y, pow2n); 842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return y; 852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace internal 882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace Eigen 902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif // EIGEN_MATH_FUNCTIONS_NEON_H 92