在使用汇编实现 cosf 时(参考math-neon library),遇到:调用cosf_neon,得到的值与sinf_neon的值一致。例如:
假设参数为0.366519,C math 得到的正确的值为 cos(0.366519)=0.933580,sin(0.366519)=0.358368,而sinf_neon与cosf_neon 都是0.358367。如下
贴出cosf_neon的代码。请问大家有无遇到这种类似的问题?谢谢。
float sinf_neon_hfp(float x)\n{\n#ifdef __MATH_NEON\nasm volatile (\n\n&quot;vld1.32 d3, [%0] \\n\\t&quot; //d3 = {invrange, range}\n&quot;vdup.f32 d0, d0[0] \\n\\t&quot; //d0 = {x, x}\n&quot;vabs.f32 d1, d0 \\n\\t&quot; //d1 = {ax, ax}\n\n&quot;vmul.f32 d2, d1, d3[0] \\n\\t&quot; //d2 = d1 * d3[0] \n&quot;vcvt.u32.f32 d2, d2 \\n\\t&quot; //d2 = (int) d2\n&quot;vmov.i32 d5, #1 \\n\\t&quot; //d5 = 1 \n&quot;vcvt.f32.u32 d4, d2 \\n\\t&quot; //d4 = (float) d2 \n&quot;vshr.u32 d7, d2, #1 \\n\\t&quot; //d7 = d2 >> 1\n&quot;vmls.f32 d1, d4, d3[1] \\n\\t&quot; //d1 = d1 - d4 * d3[1]\n\n&quot;vand.i32 d5, d2, d5 \\n\\t&quot; //d5 = d2 & d5\n&quot;vclt.f32 d18, d0, #0 \\n\\t&quot; //d18 = (d0 < 0.0)\n&quot;vcvt.f32.u32 d6, d5 \\n\\t&quot; //d6 = (float) d5\n&quot;vmls.f32 d1, d6, d3[1] \\n\\t&quot; //d1 = d1 - d6 * d3[1]\n&quot;veor.i32 d5, d5, d7 \\n\\t&quot; //d5 = d5 ^ d7 \n&quot;vmul.f32 d2, d1, d1 \\n\\t&quot; //d2 = d1*d1 = {x^2, x^2} \n\n&quot;vld1.32 {d16, d17}, [%1] \\n\\t&quot; //q8 = {p7, p3, p5, p1}\n&quot;veor.i32 d5, d5, d18 \\n\\t&quot; //d5 = d5 ^ d18 \n&quot;vshl.i32 d5, d5, #31 \\n\\t&quot; //d5 = d5 << 31\n&quot;veor.i32 d1, d1, d5 \\n\\t&quot; //d1 = d1 ^ d5\n\n&quot;vmul.f32 d3, d2, d2 \\n\\t&quot; //d3 = d2*d2 = {x^4, x^4} \n&quot;vmul.f32 q0, q8, d1[0] \\n\\t&quot; //q0 = q8 * d1[0] = {p7x, p3x, p5x, p1x}\n&quot;vmla.f32 d1, d0, d2[0] \\n\\t&quot; //d1 = d1 + d0*d2 = {p5x + p7x^3, p1x + p3x^3} \n&quot;vmla.f32 d1, d3, d1[0] \\n\\t&quot; //d1 = d1 + d3*d0 = {...., p1x + p3x^3 + p5x^5 + p7x^7} \n\n&quot;vmov.f32 s0, s3 \\n\\t&quot; //s0 = s3\n: \n: &quot;r&quot;(__sinf_rng), &quot;r&quot;(__sinf_lut) \n: &quot;q0&quot;, &quot;q1&quot;, &quot;q2&quot;, &quot;q3&quot;, &quot;q8&quot;, &quot;q9&quot;\n);\n#endif\n}\n\nfloat cosf_neon_hfp(float x)\n{\n#ifdef __MATH_NEON\n float xx = x + M_PI_2;\nreturn sinf_neon_hfp(xx);\n#endif\n}\n\nfloat cosf_neon_sfp(float x)\n{\n#ifdef __MATH_NEON\nasm volatile (&quot;vdup.f32 d0, r0 \\n\\t&quot;);\ncosf_neon_hfp(x);\nasm volatile (&quot;vmov.f32 r0, s0 \\n\\t&quot;);\n#else\n return cosf_c(x);\n#endif\n}; |