mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
audio-resampler: fix neon assembler
This commit is contained in:
parent
027165621b
commit
9182ea17b5
1 changed files with 274 additions and 111 deletions
|
@ -19,7 +19,7 @@
|
|||
|
||||
static inline void
|
||||
inner_product_gint16_full_1_neon (gint16 * o, const gint16 * a,
|
||||
const gint16 * b, gint len, const gint16 * icoeff)
|
||||
const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
|
||||
{
|
||||
uint32_t remainder = len % 16;
|
||||
len = len - remainder;
|
||||
|
@ -62,48 +62,53 @@ inner_product_gint16_full_1_neon (gint16 * o, const gint16 * a,
|
|||
|
||||
static inline void
|
||||
inner_product_gint16_linear_1_neon (gint16 * o, const gint16 * a,
|
||||
const gint16 * b, gint len, const gint16 * icoeff)
|
||||
const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
|
||||
{
|
||||
uint32_t remainder = len % 8;
|
||||
uint32_t remainder = len % 16;
|
||||
const gint16 *c[2] = {(gint16*)((gint8*)b + 0*bstride),
|
||||
(gint16*)((gint8*)b + 1*bstride)};
|
||||
len = len - remainder;
|
||||
|
||||
asm volatile (" vmov.s16 q0, #0\n"
|
||||
" vmov.s16 q1, #0\n"
|
||||
" cmp %[len], #0\n"
|
||||
" beq 2f\n"
|
||||
" vmov.s16 q1, #0\n"
|
||||
"1:"
|
||||
" vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
|
||||
" vld1.16 {d20, d21}, [%[a]]!\n"
|
||||
" vmov.16 q11, q10\n"
|
||||
" vzip.16 q10, q11\n"
|
||||
" subs %[len], %[len], #8\n"
|
||||
" vmlal.s16 q0, d16, d20\n"
|
||||
" vmlal.s16 q1, d17, d21\n"
|
||||
" vmlal.s16 q0, d18, d22\n"
|
||||
" vmlal.s16 q1, d19, d23\n"
|
||||
" vld1.16 {d16, d17, d18, d19}, [%[c0]]!\n"
|
||||
" vld1.16 {d20, d21, d22, d23}, [%[c1]]!\n"
|
||||
" vld1.16 {d24, d25, d26, d27}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #16\n"
|
||||
" vmlal.s16 q0, d16, d24\n"
|
||||
" vmlal.s16 q1, d20, d24\n"
|
||||
" vmlal.s16 q0, d17, d25\n"
|
||||
" vmlal.s16 q1, d21, d25\n"
|
||||
" vmlal.s16 q0, d18, d26\n"
|
||||
" vmlal.s16 q1, d22, d26\n"
|
||||
" vmlal.s16 q0, d19, d27\n"
|
||||
" vmlal.s16 q1, d23, d27\n"
|
||||
" bne 1b\n"
|
||||
" vadd.s32 q0, q0, q1\n"
|
||||
"2:"
|
||||
" cmp %[remainder], #0\n"
|
||||
" beq 4f\n"
|
||||
"3:"
|
||||
" vld1.16 {d16, d17}, [%[b]]!\n"
|
||||
" vld1.16 {d16}, [%[c0]]!\n"
|
||||
" vld1.16 {d17}, [%[c1]]!\n"
|
||||
" vld1.16 {d20}, [%[a]]!\n"
|
||||
" vmov.16 d21, d20\n"
|
||||
" vzip.16 d20, d21\n"
|
||||
" subs %[remainder], %[remainder], #4\n"
|
||||
" vmlal.s16 q0, d16, d20\n"
|
||||
" vmlal.s16 q0, d17, d21\n"
|
||||
" vmlal.s16 q1, d17, d20\n"
|
||||
" bne 3b\n"
|
||||
"4:"
|
||||
" vld2.16 {d20[], d21[]}, [%[ic]]\n"
|
||||
" vshrn.s32 d0, q0, #15\n"
|
||||
" vld1.16 {d20}, [%[ic]]\n"
|
||||
" vshrn.s32 d2, q1, #15\n"
|
||||
" vmull.s16 q0, d0, d20\n"
|
||||
" vmlal.s16 q0, d2, d21\n"
|
||||
" vadd.s32 d0, d0, d1\n"
|
||||
" vpadd.s32 d0, d0, d0\n"
|
||||
" vqrshrn.s32 d0, q0, #15\n"
|
||||
" vst1.s16 d0[0], [%[o]]\n"
|
||||
: [a] "+r" (a), [b] "+r" (b),
|
||||
: [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
|
||||
[len] "+r" (len), [remainder] "+r" (remainder)
|
||||
: [o] "r" (o), [ic] "r" (icoeff)
|
||||
: "cc", "q0", "q1",
|
||||
|
@ -113,41 +118,91 @@ inner_product_gint16_linear_1_neon (gint16 * o, const gint16 * a,
|
|||
|
||||
static inline void
|
||||
inner_product_gint16_cubic_1_neon (gint16 * o, const gint16 * a,
|
||||
const gint16 * b, gint len, const gint16 * icoeff)
|
||||
const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
|
||||
{
|
||||
const gint16 *c[4] = {(gint16*)((gint8*)b + 0*bstride),
|
||||
(gint16*)((gint8*)b + 1*bstride),
|
||||
(gint16*)((gint8*)b + 2*bstride),
|
||||
(gint16*)((gint8*)b + 3*bstride)};
|
||||
|
||||
asm volatile (" vmov.s32 q0, #0\n"
|
||||
" vmov.s32 q1, #0\n"
|
||||
" vmov.s32 q2, #0\n"
|
||||
" vmov.s32 q3, #0\n"
|
||||
" cmp %[len], #0\n"
|
||||
" beq 2f\n"
|
||||
" vmov.s32 q1, #0\n"
|
||||
"1:"
|
||||
" vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
|
||||
" vld4.16 {d20[], d21[], d22[], d23[]}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #4\n"
|
||||
" vmlal.s16 q0, d16, d20\n"
|
||||
" vmlal.s16 q1, d17, d21\n"
|
||||
" vmlal.s16 q0, d18, d22\n"
|
||||
" vmlal.s16 q1, d19, d23\n"
|
||||
" vld1.16 {d16, d17}, [%[c0]]!\n"
|
||||
" vld1.16 {d18, d19}, [%[c1]]!\n"
|
||||
" vld1.16 {d20, d21}, [%[c2]]!\n"
|
||||
" vld1.16 {d22, d23}, [%[c3]]!\n"
|
||||
" vld1.16 {d24, d25}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #8\n"
|
||||
" vmlal.s16 q0, d16, d24\n"
|
||||
" vmlal.s16 q1, d18, d24\n"
|
||||
" vmlal.s16 q2, d20, d24\n"
|
||||
" vmlal.s16 q3, d22, d24\n"
|
||||
" vmlal.s16 q0, d17, d25\n"
|
||||
" vmlal.s16 q1, d19, d25\n"
|
||||
" vmlal.s16 q2, d21, d25\n"
|
||||
" vmlal.s16 q3, d23, d25\n"
|
||||
" bne 1b\n"
|
||||
" vadd.s32 q0, q0, q1\n"
|
||||
"2:"
|
||||
" vld4.16 {d20[], d21[], d22[], d23[]}, [%[ic]]\n"
|
||||
" vshrn.s32 d0, q0, #15\n"
|
||||
" vld1.16 {d20}, [%[ic]]\n"
|
||||
" vshrn.s32 d2, q1, #15\n"
|
||||
" vshrn.s32 d4, q2, #15\n"
|
||||
" vshrn.s32 d6, q3, #15\n"
|
||||
" vmull.s16 q0, d0, d20\n"
|
||||
" vmlal.s16 q0, d2, d21\n"
|
||||
" vmlal.s16 q0, d4, d22\n"
|
||||
" vmlal.s16 q0, d6, d23\n"
|
||||
" vadd.s32 d0, d0, d1\n"
|
||||
" vpadd.s32 d0, d0, d0\n"
|
||||
" vqrshrn.s32 d0, q0, #15\n"
|
||||
" vst1.s16 d0[0], [%[o]]\n"
|
||||
: [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+r" (len)
|
||||
: [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
|
||||
[c2] "+r" (c[2]), [c3] "+r" (c[3]), [len] "+r" (len)
|
||||
: [o] "r" (o), [ic] "r" (icoeff)
|
||||
: "cc", "q0", "q1",
|
||||
: "cc", "q0", "q1", "q2", "q3",
|
||||
"d16", "d17", "d18", "d19",
|
||||
"d20", "d21", "d22", "d23" , "memory");
|
||||
"d20", "d21", "d22", "d23", "d24", "d25", "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
interpolate_gint16_linear_neon (gpointer op, const gpointer ap,
|
||||
gint len, const gpointer icp, gint astride)
|
||||
{
|
||||
gint16 *o = op, *a = ap, *ic = icp;
|
||||
const gint16 *c[2] = {(gint16*)((gint8*)a + 0*astride),
|
||||
(gint16*)((gint8*)a + 1*astride)};
|
||||
|
||||
asm volatile (" cmp %[len], #0\n"
|
||||
" beq 2f\n"
|
||||
" vld2.16 {d20[], d21[]}, [%[ic]]\n"
|
||||
"1:"
|
||||
" vld1.16 {d16, d17}, [%[c0]]!\n"
|
||||
" vld1.16 {d18, d19}, [%[c1]]!\n"
|
||||
" subs %[len], %[len], #8\n"
|
||||
" vmull.s16 q0, d16, d20\n"
|
||||
" vmull.s16 q1, d17, d20\n"
|
||||
" vmlal.s16 q0, d18, d21\n"
|
||||
" vmlal.s16 q1, d19, d21\n"
|
||||
" vqrshrn.s32 d0, q0, #15\n"
|
||||
" vqrshrn.s32 d1, q1, #15\n"
|
||||
" vst1.s16 {d0, d1}, [%[o]]!\n"
|
||||
" bne 1b\n"
|
||||
"2:"
|
||||
: [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
|
||||
[len] "+r" (len), [o] "+r" (o)
|
||||
: [ic] "r" (ic)
|
||||
: "cc", "q0", "q1",
|
||||
"d16", "d17", "d18", "d19", "d20", "d21", "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
inner_product_gint32_full_1_neon (gint32 * o, const gint32 * a,
|
||||
const gint32 * b, gint len, const gint32 * icoeff)
|
||||
const gint32 * b, gint len, const gint32 * icoeff, gint bstride)
|
||||
{
|
||||
uint32_t remainder = len % 8;
|
||||
len = len - remainder;
|
||||
|
@ -190,82 +245,138 @@ inner_product_gint32_full_1_neon (gint32 * o, const gint32 * a,
|
|||
|
||||
static inline void
|
||||
inner_product_gint32_linear_1_neon (gint32 * o, const gint32 * a,
|
||||
const gint32 * b, gint len, const gint32 * icoeff)
|
||||
const gint32 * b, gint len, const gint32 * icoeff, gint bstride)
|
||||
{
|
||||
const gint32 *c[2] = {(gint32*)((gint8*)b + 0*bstride),
|
||||
(gint32*)((gint8*)b + 1*bstride)};
|
||||
|
||||
asm volatile (" vmov.s64 q0, #0\n"
|
||||
" vmov.s64 q1, #0\n"
|
||||
" cmp %[len], #0\n"
|
||||
" beq 2f\n"
|
||||
" vmov.s64 q1, #0\n"
|
||||
"1:"
|
||||
" vld1.s32 {d16, d17, d18, d19}, [%[b]]!\n"
|
||||
" vld2.s32 {d20[], d21[]}, [%[a]]!\n"
|
||||
" vld2.s32 {d22[], d23[]}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #4\n"
|
||||
" vmlal.s32 q0, d16, d20\n"
|
||||
" vmlal.s32 q1, d17, d21\n"
|
||||
" vmlal.s32 q0, d18, d22\n"
|
||||
" vmlal.s32 q1, d19, d23\n"
|
||||
" vld1.32 {d16, d17, d18, d19}, [%[c0]]!\n"
|
||||
" vld1.32 {d20, d21, d22, d23}, [%[c1]]!\n"
|
||||
" vld1.32 {d24, d25, d26, d27}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #8\n"
|
||||
" vmlal.s32 q0, d16, d24\n"
|
||||
" vmlal.s32 q1, d20, d24\n"
|
||||
" vmlal.s32 q0, d17, d25\n"
|
||||
" vmlal.s32 q1, d21, d25\n"
|
||||
" vmlal.s32 q0, d18, d26\n"
|
||||
" vmlal.s32 q1, d22, d26\n"
|
||||
" vmlal.s32 q0, d19, d27\n"
|
||||
" vmlal.s32 q1, d23, d27\n"
|
||||
" bne 1b\n"
|
||||
" vadd.s64 q0, q0, q1\n"
|
||||
"2:"
|
||||
" vld1.s32 {d20}, [%[ic]]\n"
|
||||
" vld2.32 {d20[], d21[]}, [%[ic]]\n"
|
||||
" vshrn.s64 d0, q0, #31\n"
|
||||
" vshrn.s64 d2, q1, #31\n"
|
||||
" vmull.s32 q0, d0, d20\n"
|
||||
" vmlal.s32 q0, d2, d21\n"
|
||||
" vadd.s64 d0, d0, d1\n"
|
||||
" vqrshrn.s64 d0, q0, #31\n"
|
||||
" vst1.s32 d0[0], [%[o]]\n"
|
||||
: [a] "+r" (a), [b] "+r" (b),
|
||||
: [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
|
||||
[len] "+r" (len)
|
||||
: [o] "r" (o), [ic] "r" (icoeff)
|
||||
: "cc", "q0", "q1",
|
||||
"d16", "d17", "d18", "d19",
|
||||
"d20", "d21", "d22", "d23", "memory");
|
||||
"d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
inner_product_gint32_cubic_1_neon (gint32 * o, const gint32 * a,
|
||||
const gint32 * b, gint len, const gint32 * icoeff)
|
||||
const gint32 * b, gint len, const gint32 * icoeff, gint bstride)
|
||||
{
|
||||
const gint32 *c[4] = {(gint32*)((gint8*)b + 0*bstride),
|
||||
(gint32*)((gint8*)b + 1*bstride),
|
||||
(gint32*)((gint8*)b + 2*bstride),
|
||||
(gint32*)((gint8*)b + 3*bstride)};
|
||||
|
||||
asm volatile (" vmov.s64 q0, #0\n"
|
||||
" vmov.s64 q1, #0\n"
|
||||
" vmov.s64 q2, #0\n"
|
||||
" vmov.s64 q3, #0\n"
|
||||
" cmp %[len], #0\n"
|
||||
" beq 2f\n"
|
||||
" vmov.s64 q1, #0\n"
|
||||
"1:"
|
||||
" vld1.s32 {q4, q5}, [%[b]]!\n"
|
||||
" vld1.s32 {q6, q7}, [%[b]]!\n"
|
||||
" vld1.s32 {d16[], d17[]}, [%[a]]!\n"
|
||||
" vld1.s32 {d18[], d19[]}, [%[a]]!\n"
|
||||
" vld1.s32 {d20[], d21[]}, [%[a]]!\n"
|
||||
" vld1.s32 {d22[], d23[]}, [%[a]]!\n"
|
||||
" vld1.32 {d16, d17}, [%[c0]]!\n"
|
||||
" vld1.32 {d18, d19}, [%[c1]]!\n"
|
||||
" vld1.32 {d20, d21}, [%[c2]]!\n"
|
||||
" vld1.32 {d22, d23}, [%[c3]]!\n"
|
||||
" vld1.32 {d24, d25}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #4\n"
|
||||
" vmlal.s32 q0, d16, d8\n"
|
||||
" vmlal.s32 q1, d17, d9\n"
|
||||
" vmlal.s32 q0, d18, d10\n"
|
||||
" vmlal.s32 q1, d19, d11\n"
|
||||
" vmlal.s32 q0, d20, d12\n"
|
||||
" vmlal.s32 q1, d21, d13\n"
|
||||
" vmlal.s32 q0, d22, d14\n"
|
||||
" vmlal.s32 q1, d23, d15\n"
|
||||
" vmlal.s32 q0, d16, d24\n"
|
||||
" vmlal.s32 q1, d18, d24\n"
|
||||
" vmlal.s32 q2, d20, d24\n"
|
||||
" vmlal.s32 q3, d22, d24\n"
|
||||
" vmlal.s32 q0, d17, d25\n"
|
||||
" vmlal.s32 q1, d19, d25\n"
|
||||
" vmlal.s32 q2, d21, d25\n"
|
||||
" vmlal.s32 q3, d23, d25\n"
|
||||
" bne 1b\n"
|
||||
"2:"
|
||||
" vld1.s32 {d20, d21}, [%[ic]]\n"
|
||||
" vshrn.s64 d16, q0, #31\n"
|
||||
" vshrn.s64 d17, q1, #31\n"
|
||||
" vmull.s32 q0, d20, d16\n"
|
||||
" vmlal.s32 q0, d21, d17\n"
|
||||
" vld4.32 {d20[], d21[], d22[], d23[]}, [%[ic]]\n"
|
||||
" vshrn.s64 d0, q0, #31\n"
|
||||
" vshrn.s64 d2, q1, #31\n"
|
||||
" vshrn.s64 d4, q2, #31\n"
|
||||
" vshrn.s64 d6, q3, #31\n"
|
||||
" vmull.s32 q0, d0, d20\n"
|
||||
" vmlal.s32 q0, d2, d21\n"
|
||||
" vmlal.s32 q0, d4, d22\n"
|
||||
" vmlal.s32 q0, d6, d23\n"
|
||||
" vadd.s64 d0, d0, d1\n"
|
||||
" vqrshrn.s64 d0, q0, #31\n"
|
||||
" vst1.s32 d0[0], [%[o]]\n"
|
||||
: [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+r" (len)
|
||||
: [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
|
||||
[c2] "+r" (c[2]), [c3] "+r" (c[3]), [len] "+r" (len)
|
||||
: [o] "r" (o), [ic] "r" (icoeff)
|
||||
: "cc", "q0", "q1", "q4", "q5", "q6", "q7", "q8",
|
||||
"q9", "q10", "q11", "memory");
|
||||
: "cc", "q0", "q1", "q2", "q3",
|
||||
"d16", "d17", "d18", "d19",
|
||||
"d20", "d21", "d22", "d23", "d24", "d25", "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
interpolate_gint32_linear_neon (gpointer op, const gpointer ap,
|
||||
gint len, const gpointer icp, gint astride)
|
||||
{
|
||||
gint32 *o = op, *a = ap, *ic = icp;
|
||||
const gint32 *c[2] = {(gint32*)((gint8*)a + 0*astride),
|
||||
(gint32*)((gint8*)a + 1*astride)};
|
||||
|
||||
asm volatile (" cmp %[len], #0\n"
|
||||
" beq 2f\n"
|
||||
" vld2.32 {d24[], d25[]}, [%[ic]]!\n"
|
||||
"1:"
|
||||
" vld1.32 {d16, d17, d18, d19}, [%[c0]]!\n"
|
||||
" vld1.32 {d20, d21, d22, d23}, [%[c1]]!\n"
|
||||
" subs %[len], %[len], #8\n"
|
||||
" vmull.s32 q0, d16, d24\n"
|
||||
" vmull.s32 q1, d17, d24\n"
|
||||
" vmull.s32 q2, d18, d24\n"
|
||||
" vmull.s32 q3, d19, d24\n"
|
||||
" vmlal.s32 q0, d20, d25\n"
|
||||
" vmlal.s32 q1, d21, d25\n"
|
||||
" vmlal.s32 q2, d22, d25\n"
|
||||
" vmlal.s32 q3, d23, d25\n"
|
||||
" vqrshrn.s64 d0, q0, #31\n"
|
||||
" vqrshrn.s64 d1, q1, #31\n"
|
||||
" vqrshrn.s64 d2, q2, #31\n"
|
||||
" vqrshrn.s64 d3, q3, #31\n"
|
||||
" vst1.s32 {d0, d1, d2, d3}, [%[o]]!\n"
|
||||
" bne 1b\n"
|
||||
"2:"
|
||||
: [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
|
||||
[len] "+r" (len)
|
||||
: [o] "r" (o), [ic] "r" (ic)
|
||||
: "cc", "q0", "q1", "q2", "q3",
|
||||
"d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
inner_product_gfloat_full_1_neon (gfloat * o, const gfloat * a,
|
||||
const gfloat * b, gint len, const gfloat * icoeff)
|
||||
const gfloat * b, gint len, const gfloat * icoeff, gint bstride)
|
||||
{
|
||||
uint32_t remainder = len % 16;
|
||||
len = len - remainder;
|
||||
|
@ -308,70 +419,116 @@ inner_product_gfloat_full_1_neon (gfloat * o, const gfloat * a,
|
|||
|
||||
static inline void
|
||||
inner_product_gfloat_linear_1_neon (gfloat * o, const gfloat * a,
|
||||
const gfloat * b, gint len, const gfloat * icoeff)
|
||||
const gfloat * b, gint len, const gfloat * icoeff, gint bstride)
|
||||
{
|
||||
const gfloat *c[2] = {(gfloat*)((gint8*)b + 0*bstride),
|
||||
(gfloat*)((gint8*)b + 1*bstride)};
|
||||
|
||||
asm volatile (" vmov.f32 q0, #0.0\n"
|
||||
" vmov.f32 q1, #0.0\n"
|
||||
" cmp %[len], #0\n"
|
||||
" beq 2f\n"
|
||||
" vmov.f32 q1, #0.0\n"
|
||||
"1:"
|
||||
" vld1.f32 {d16, d17, d18, d19}, [%[b]]!\n"
|
||||
" vld2.f32 {d20[], d21[]}, [%[a]]!\n"
|
||||
" vld2.f32 {d22[], d23[]}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #4\n"
|
||||
" vmla.f32 q0, q8, q10\n"
|
||||
" vmla.f32 q1, q9, q11\n"
|
||||
" vld1.f32 {q8, q9}, [%[c0]]!\n"
|
||||
" vld1.f32 {q10, q11}, [%[c1]]!\n"
|
||||
" vld1.f32 {q12, q13}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #8\n"
|
||||
" vmla.f32 q0, q8, q12\n"
|
||||
" vmla.f32 q1, q10, q12\n"
|
||||
" vmla.f32 q0, q9, q13\n"
|
||||
" vmla.f32 q1, q11, q13\n"
|
||||
" bne 1b\n"
|
||||
" vadd.f32 q0, q0, q1\n"
|
||||
"2:"
|
||||
" vld1.f32 {q10}, [%[ic]]\n"
|
||||
" vmul.f32 q0, q0, q10\n"
|
||||
" vadd.f32 d0, d0, d1\n"
|
||||
" vld2.f32 {d20[], d21[]}, [%[ic]]\n"
|
||||
" vmul.f32 d0, d0, d20\n"
|
||||
" vmla.f32 d0, d1, d20\n"
|
||||
" vmla.f32 d0, d2, d21\n"
|
||||
" vmla.f32 d0, d3, d21\n"
|
||||
" vpadd.f32 d0, d0, d0\n"
|
||||
" vst1.f32 d0[0], [%[o]]\n"
|
||||
: [a] "+r" (a), [b] "+r" (b),
|
||||
: [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
|
||||
[len] "+r" (len)
|
||||
: [o] "r" (o), [ic] "r" (icoeff)
|
||||
: "cc", "q0", "q1",
|
||||
"d16", "d17", "d18", "d19",
|
||||
"d20", "d21", "d22", "d23", "memory");
|
||||
"q8", "q9", "q10", "q11", "q12", "q13", "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
inner_product_gfloat_cubic_1_neon (gfloat * o, const gfloat * a,
|
||||
const gfloat * b, gint len, const gfloat * icoeff)
|
||||
const gfloat * b, gint len, const gfloat * icoeff, gint bstride)
|
||||
{
|
||||
const gfloat *c[4] = {(gfloat*)((gint8*)b + 0*bstride),
|
||||
(gfloat*)((gint8*)b + 1*bstride),
|
||||
(gfloat*)((gint8*)b + 2*bstride),
|
||||
(gfloat*)((gint8*)b + 3*bstride)};
|
||||
|
||||
asm volatile (" vmov.f32 q0, #0.0\n"
|
||||
" vmov.f32 q1, #0.0\n"
|
||||
" vmov.f32 q2, #0.0\n"
|
||||
" vmov.f32 q3, #0.0\n"
|
||||
" cmp %[len], #0\n"
|
||||
" beq 2f\n"
|
||||
" vmov.f32 q1, #0.0\n"
|
||||
"1:"
|
||||
" vld1.f32 {q4, q5}, [%[b]]!\n"
|
||||
" vld1.f32 {q6, q7}, [%[b]]!\n"
|
||||
" vld1.f32 {d16[], d17[]}, [%[a]]!\n"
|
||||
" vld1.f32 {d18[], d19[]}, [%[a]]!\n"
|
||||
" vld1.f32 {d20[], d21[]}, [%[a]]!\n"
|
||||
" vld1.f32 {d22[], d23[]}, [%[a]]!\n"
|
||||
" vld1.f32 {q8}, [%[c0]]!\n"
|
||||
" vld1.f32 {q9}, [%[c1]]!\n"
|
||||
" vld1.f32 {q10}, [%[c2]]!\n"
|
||||
" vld1.f32 {q11}, [%[c3]]!\n"
|
||||
" vld1.f32 {q12}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #4\n"
|
||||
" vmla.f32 q0, q4, q8\n"
|
||||
" vmla.f32 q1, q5, q9\n"
|
||||
" vmla.f32 q0, q6, q10\n"
|
||||
" vmla.f32 q1, q7, q11\n"
|
||||
" vmla.f32 q0, q8, q12\n"
|
||||
" vmla.f32 q1, q9, q12\n"
|
||||
" vmla.f32 q2, q10, q12\n"
|
||||
" vmla.f32 q3, q11, q12\n"
|
||||
" bne 1b\n"
|
||||
" vadd.f32 q0, q0, q1\n"
|
||||
"2:"
|
||||
" vld1.f32 {q10}, [%[ic]]\n"
|
||||
" vmul.f32 q0, q0, q10\n"
|
||||
" vadd.f32 d0, d0, d1\n"
|
||||
" vld4.f32 {d20[], d21[], d22[], d23[]}, [%[ic]]\n"
|
||||
" vmul.f32 d0, d0, d20\n"
|
||||
" vmla.f32 d0, d1, d20\n"
|
||||
" vmla.f32 d0, d2, d21\n"
|
||||
" vmla.f32 d0, d3, d21\n"
|
||||
" vmla.f32 d0, d4, d22\n"
|
||||
" vmla.f32 d0, d5, d22\n"
|
||||
" vmla.f32 d0, d6, d23\n"
|
||||
" vmla.f32 d0, d7, d23\n"
|
||||
" vpadd.f32 d0, d0, d0\n"
|
||||
" vst1.f32 d0[0], [%[o]]\n"
|
||||
: [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+r" (len)
|
||||
: [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
|
||||
[c2] "+r" (c[2]), [c3] "+r" (c[3]), [len] "+r" (len)
|
||||
: [o] "r" (o), [ic] "r" (icoeff)
|
||||
: "cc", "q0", "q1", "q4", "q5", "q6", "q7", "q8",
|
||||
"q9", "q10", "q11", "memory");
|
||||
: "cc", "q0", "q1", "q2", "q3",
|
||||
"q8", "q9", "q10", "q11", "q12", "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
interpolate_gfloat_linear_neon (gpointer op, const gpointer ap,
|
||||
gint len, const gpointer icp, gint astride)
|
||||
{
|
||||
gfloat *o = op, *a = ap, *ic = icp;
|
||||
const gfloat *c[2] = {(gfloat*)((gint8*)a + 0*astride),
|
||||
(gfloat*)((gint8*)a + 1*astride)};
|
||||
|
||||
asm volatile (" cmp %[len], #0\n"
|
||||
" beq 2f\n"
|
||||
" vld2.32 {d24[], d26[]}, [%[ic]]!\n"
|
||||
" vmov.32 d25, d24\n"
|
||||
" vmov.32 d27, d26\n"
|
||||
"1:"
|
||||
" vld1.32 {q8, q9}, [%[c0]]!\n"
|
||||
" vld1.32 {q10, q11}, [%[c1]]!\n"
|
||||
" subs %[len], %[len], #8\n"
|
||||
" vmul.f32 q0, q8, q12\n"
|
||||
" vmul.f32 q1, q9, q12\n"
|
||||
" vmla.f32 q0, q10, q13\n"
|
||||
" vmla.f32 q1, q11, q13\n"
|
||||
" vst1.f32 {q0, q1}, [%[o]]!\n"
|
||||
" bne 1b\n"
|
||||
"2:"
|
||||
: [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
|
||||
[len] "+r" (len)
|
||||
: [o] "r" (o), [ic] "r" (ic)
|
||||
: "cc", "q0", "q1",
|
||||
"q8", "q9", "q10", "q11", "q12", "q13", "memory");
|
||||
}
|
||||
MAKE_RESAMPLE_FUNC (gint16, full, 1, neon);
|
||||
MAKE_RESAMPLE_FUNC (gint16, linear, 1, neon);
|
||||
MAKE_RESAMPLE_FUNC (gint16, cubic, 1, neon);
|
||||
|
@ -393,12 +550,18 @@ audio_resampler_check_neon (const gchar *option)
|
|||
resample_gint16_linear_1 = resample_gint16_linear_1_neon;
|
||||
resample_gint16_cubic_1 = resample_gint16_cubic_1_neon;
|
||||
|
||||
interpolate_gint16_linear = interpolate_gint16_linear_neon;
|
||||
|
||||
resample_gint32_full_1 = resample_gint32_full_1_neon;
|
||||
resample_gint32_linear_1 = resample_gint32_linear_1_neon;
|
||||
resample_gint32_cubic_1 = resample_gint32_cubic_1_neon;
|
||||
|
||||
interpolate_gint32_linear = interpolate_gint32_linear_neon;
|
||||
|
||||
resample_gfloat_full_1 = resample_gfloat_full_1_neon;
|
||||
resample_gfloat_linear_1 = resample_gfloat_linear_1_neon;
|
||||
resample_gfloat_cubic_1 = resample_gfloat_cubic_1_neon;
|
||||
|
||||
interpolate_gfloat_linear = interpolate_gfloat_linear_neon;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue