21,458
社区成员
发帖
与我相关
我的任务
分享
float cosf_neon_hfp(float x)
{
asm volatile (
"vdup.f32 d0, r0 \n\t"
"vld1.f32 d3, [%0] \n\t" //d3 = {invrange, range}
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x}
"vabs.f32 d1, d0 \n\t" //d1 = {ax, ax}
"vmul.f32 d2, d1, d3[0] \n\t" //d2 = d1 * d3[0]
"vcvt.u32.f32 d2, d2 \n\t" //d2 = (int) d2
"vmov.i32 d5, #1 \n\t" //d5 = 1
"vcvt.f32.u32 d4, d2 \n\t" //d4 = (float) d2
"vshr.u32 d7, d2, #1 \n\t" //d7 = d2 >> 1
"vmls.f32 d1, d4, d3[1] \n\t" //d1 = d1 - d4 * d3[1]
"vand.i32 d5, d2, d5 \n\t" //d5 = d2 & d5
"vclt.f32 d18, d0, #0 \n\t" //d18 = (d0 < 0.0)
"vcvt.f32.u32 d6, d5 \n\t" //d6 = (float) d5
"vmls.f32 d1, d6, d3[1] \n\t" //d1 = d1 - d6 * d3[1]
"veor.i32 d5, d5, d7 \n\t" //d5 = d5 ^ d7
"vmul.f32 d2, d1, d1 \n\t" //d2 = d1*d1 = {x^2, x^2}
"vld1.32 {d16, d17}, [%1] \n\t" //q8 = {p7, p3, p5, p1}
"veor.i32 d5, d5, d18 \n\t" //d5 = d5 ^ d18
"vshl.i32 d5, d5, #31 \n\t" //d5 = d5 << 31
"veor.i32 d1, d1, d5 \n\t" //d1 = d1 ^ d5
"vmul.f32 d3, d2, d2 \n\t" //d3 = d2*d2 = {x^4, x^4}
"vmul.f32 q0, q8, d1[0] \n\t" //q0 = q8 * d1[0] = {p7x, p3x, p5x, p1x}
"vmla.f32 d1, d0, d2[0] \n\t" //d1 = d1 + d0*d2 = {p5x + p7x^3, p1x + p3x^3}
"vmla.f32 d1, d3, d1[0] \n\t" //d1 = d1 + d3*d0 = {...., p1x + p3x^3 + p5x^5 + p7x^7}
//"vmov.f32 s0, s3 \n\t" //s0 = s3
"vmov.f32 r0, s3 \n\t"
:
: "r"(__cosf_rng), "r"(__cosf_lut)
: "q0", "q1", "q2", "q3", "q8", "q9"
);
}
float cosf_neon_sfp(float x)
{
float xx = x + M_PI_2;
cosf_neon_hfp(xx);
//asm volatile("vmov.f32 r0, s0 \n\t");
}
#include <stdio.h>
#include <math.h>
#define M_PI 3.14159265358979323846 /* pi */
#define M_PI_2 1.57079632679489661923 /* pi/2 */
#ifdef GCC
#define ALIGN(A) __attribute__ ((aligned (A))
#else
#define ALIGN(A)
#endif
static const float __cosf_rng[2] = {
2.0 / M_PI,
M_PI / 2.0
} ALIGN(16);
static const float __cosf_lut[4] = {
-0.00018365f, //p7
-0.16664831f, //p3
+0.00830636f, //p5
+0.99999661f, //p1
} ALIGN(16);
float cosf_neon_hfp(float x)
{
asm volatile (
"vld1.f32 d3, [%0] \n\t" //d3 = {invrange, range}
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x}
"vabs.f32 d1, d0 \n\t" //d1 = {ax, ax}
"vmul.f32 d2, d1, d3[0] \n\t" //d2 = d1 * d3[0]
"vcvt.u32.f32 d2, d2 \n\t" //d2 = (int) d2
"vmov.i32 d5, #1 \n\t" //d5 = 1
"vcvt.f32.u32 d4, d2 \n\t" //d4 = (float) d2
"vshr.u32 d7, d2, #1 \n\t" //d7 = d2 >> 1
"vmls.f32 d1, d4, d3[1] \n\t" //d1 = d1 - d4 * d3[1]
"vand.i32 d5, d2, d5 \n\t" //d5 = d2 & d5
"vclt.f32 d18, d0, #0 \n\t" //d18 = (d0 < 0.0)
"vcvt.f32.u32 d6, d5 \n\t" //d6 = (float) d5
"vmls.f32 d1, d6, d3[1] \n\t" //d1 = d1 - d6 * d3[1]
"veor.i32 d5, d5, d7 \n\t" //d5 = d5 ^ d7
"vmul.f32 d2, d1, d1 \n\t" //d2 = d1*d1 = {x^2, x^2}
"vld1.32 {d16, d17}, [%1] \n\t" //q8 = {p7, p3, p5, p1}
"veor.i32 d5, d5, d18 \n\t" //d5 = d5 ^ d18
"vshl.i32 d5, d5, #31 \n\t" //d5 = d5 << 31
"veor.i32 d1, d1, d5 \n\t" //d1 = d1 ^ d5
"vmul.f32 d3, d2, d2 \n\t" //d3 = d2*d2 = {x^4, x^4}
"vmul.f32 q0, q8, d1[0] \n\t" //q0 = q8 * d1[0] = {p7x, p3x, p5x, p1x}
"vmla.f32 d1, d0, d2[0] \n\t" //d1 = d1 + d0*d2 = {p5x + p7x^3, p1x + p3x^3}
"vmla.f32 d1, d3, d1[0] \n\t" //d1 = d1 + d3*d0 = {...., p1x + p3x^3 + p5x^5 + p7x^7}
//"vmov.f32 s0, s3 \n\t" //s0 = s3
"vmov.f32 r0, s3 \n\t"
:
: "r"(__cosf_rng), "r"(__cosf_lut)
: "q0", "q1", "q2", "q3", "q8", "q9"
);
}
float cosf_neon_sfp(float x)
{
asm volatile("vdup.f32 d0, r0 \n\t");
x = x + M_PI_2;
cosf_neon_hfp(x);
//asm volatile("vmov.f32 r0, s0 \n\t");
}
int main(char **argv, int argc)
{
float cosf_val = 0;
cosf_val = cosf_neon_sfp(0.366519);
printf("------------------------------------------------------\n");
printf("cosf_neon value is %f(the correct is 0.933580)\n", cosf_val);
printf("cos of math is %f\n", cos(0.366519));
printf("--------------------------END-------------------------\n");
return 0;
}
float cosf_neon_sfp(float x)
{
#ifdef __MATH_NEON
float xx = x + M_PI_2;
asm volatile ("vdup.f32 d0, r0 \n\t");
asm volatile (
"vld1.f32 d3, [%0] \n\t" //d3 = {invrange, range}
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x}
"vabs.f32 d1, d0 \n\t" //d1 = {ax, ax}
"vmul.f32 d2, d1, d3[0] \n\t" //d2 = d1 * d3[0]
"vcvt.u32.f32 d2, d2 \n\t" //d2 = (int) d2
"vmov.i32 d5, #1 \n\t" //d5 = 1
"vcvt.f32.u32 d4, d2 \n\t" //d4 = (float) d2
"vshr.u32 d7, d2, #1 \n\t" //d7 = d2 >> 1
"vmls.f32 d1, d4, d3[1] \n\t" //d1 = d1 - d4 * d3[1]
"vand.i32 d5, d2, d5 \n\t" //d5 = d2 & d5
"vclt.f32 d18, d0, #0 \n\t" //d18 = (d0 < 0.0)
"vcvt.f32.u32 d6, d5 \n\t" //d6 = (float) d5
"vmls.f32 d1, d6, d3[1] \n\t" //d1 = d1 - d6 * d3[1]
"veor.i32 d5, d5, d7 \n\t" //d5 = d5 ^ d7
"vmul.f32 d2, d1, d1 \n\t" //d2 = d1*d1 = {x^2, x^2}
"vld1.32 {d16, d17}, [%1] \n\t" //q8 = {p7, p3, p5, p1}
"veor.i32 d5, d5, d18 \n\t" //d5 = d5 ^ d18
"vshl.i32 d5, d5, #31 \n\t" //d5 = d5 << 31
"veor.i32 d1, d1, d5 \n\t" //d1 = d1 ^ d5
"vmul.f32 d3, d2, d2 \n\t" //d3 = d2*d2 = {x^4, x^4}
"vmul.f32 q0, q8, d1[0] \n\t" //q0 = q8 * d1[0] = {p7x, p3x, p5x, p1x}
"vmla.f32 d1, d0, d2[0] \n\t" //d1 = d1 + d0*d2 = {p5x + p7x^3, p1x + p3x^3}
"vmla.f32 d1, d3, d1[0] \n\t" //d1 = d1 + d3*d0 = {...., p1x + p3x^3 + p5x^5 + p7x^7}
"vmov.f32 s0, s3 \n\t" //s0 = s3
:
: "r"(__cosf_rng), "r"(__cosf_lut)
: "q0", "q1", "q2", "q3", "q8", "q9"
);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return cosf_c(x);
#endif
}
float cosf_neon_hfp(float x)
{
#ifdef __MATH_NEON
float xx = x + M_PI_2;
return sinf_neon_hfp(xx);
#endif
}
float sinf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vdup.f32 d0, r0 \n\t");
sinf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return sinf_c(x);
#endif
}
float sinf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 d3, [%0] \n\t" //d3 = {invrange, range}
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x}
"vabs.f32 d1, d0 \n\t" //d1 = {ax, ax}
"vmul.f32 d2, d1, d3[0] \n\t" //d2 = d1 * d3[0]
"vcvt.u32.f32 d2, d2 \n\t" //d2 = (int) d2
"vmov.i32 d5, #1 \n\t" //d5 = 1
"vcvt.f32.u32 d4, d2 \n\t" //d4 = (float) d2
"vshr.u32 d7, d2, #1 \n\t" //d7 = d2 >> 1
"vmls.f32 d1, d4, d3[1] \n\t" //d1 = d1 - d4 * d3[1]
"vand.i32 d5, d2, d5 \n\t" //d5 = d2 & d5
"vclt.f32 d18, d0, #0 \n\t" //d18 = (d0 < 0.0)
"vcvt.f32.u32 d6, d5 \n\t" //d6 = (float) d5
"vmls.f32 d1, d6, d3[1] \n\t" //d1 = d1 - d6 * d3[1]
"veor.i32 d5, d5, d7 \n\t" //d5 = d5 ^ d7
"vmul.f32 d2, d1, d1 \n\t" //d2 = d1*d1 = {x^2, x^2}
"vld1.32 {d16, d17}, [%1] \n\t" //q8 = {p7, p3, p5, p1}
"veor.i32 d5, d5, d18 \n\t" //d5 = d5 ^ d18
"vshl.i32 d5, d5, #31 \n\t" //d5 = d5 << 31
"veor.i32 d1, d1, d5 \n\t" //d1 = d1 ^ d5
"vmul.f32 d3, d2, d2 \n\t" //d3 = d2*d2 = {x^4, x^4}
"vmul.f32 q0, q8, d1[0] \n\t" //q0 = q8 * d1[0] = {p7x, p3x, p5x, p1x}
"vmla.f32 d1, d0, d2[0] \n\t" //d1 = d1 + d0*d2 = {p5x + p7x^3, p1x + p3x^3}
"vmla.f32 d1, d3, d1[0] \n\t" //d1 = d1 + d3*d0 = {...., p1x + p3x^3 + p5x^5 + p7x^7}
"vmov.f32 s0, s3 \n\t" //s0 = s3
:
: "r"(__sinf_rng), "r"(__sinf_lut)
: "q0", "q1", "q2", "q3", "q8", "q9"
);
#endif
}