forked from len0rd/rockbox
libdemac: ARMv7 assembler optimisation for the filters, tested on Nokia N900. Speedup is 2.1x for -c5000 compared to the ARMv6 asm. Note that actually compiling it on device requires hand-assembling the 'vadd' and 'vsub' instructions due to a bug in binutils 2.18.50, and making the standalone decoder use it requires Makefile and demac_config.h hacks.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27944 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
dd5e3eb542
commit
811877e5b3
2 changed files with 216 additions and 0 deletions
|
|
@ -41,6 +41,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
|||
|
||||
#ifdef CPU_COLDFIRE
|
||||
#include "vector_math16_cf.h"
|
||||
#elif defined(CPU_ARM) && (ARM_ARCH >= 7)
|
||||
#include "vector_math16_armv7.h"
|
||||
#elif defined(CPU_ARM) && (ARM_ARCH >= 6)
|
||||
#include "vector_math16_armv6.h"
|
||||
#elif defined(CPU_ARM) && (ARM_ARCH >= 5)
|
||||
|
|
|
|||
214
apps/codecs/demac/libdemac/vector_math16_armv7.h
Normal file
214
apps/codecs/demac/libdemac/vector_math16_armv7.h
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
|
||||
libdemac - A Monkey's Audio decoder
|
||||
|
||||
$Id$
|
||||
|
||||
Copyright (C) Dave Chapman 2007
|
||||
|
||||
ARMv7 neon vector math copyright (C) 2010 Jens Arnold
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
||||
|
||||
*/
|
||||
|
||||
#define FUSED_VECTOR_MATH
|
||||
|
||||
#if ORDER > 32
|
||||
#define REPEAT_BLOCK(x) x x x
|
||||
#elif ORDER > 16
|
||||
#define REPEAT_BLOCK(x) x
|
||||
#else
|
||||
#define REPEAT_BLOCK(x)
|
||||
#endif
|
||||
|
||||
/* Calculate scalarproduct, then add a 2nd vector (fused for performance) */
|
||||
static inline int32_t vector_sp_add(int16_t* v1, int16_t* f2, int16_t* s2)
|
||||
{
|
||||
int res;
|
||||
#if ORDER > 64
|
||||
int cnt = ORDER>>6;
|
||||
#endif
|
||||
|
||||
asm volatile (
|
||||
#if ORDER > 64
|
||||
"vmov.i16 q0, #0 \n"
|
||||
"1: \n"
|
||||
"subs %[cnt], %[cnt], #1 \n"
|
||||
#endif
|
||||
"vld1.16 {d6-d9}, [%[f2]]! \n"
|
||||
"vld1.16 {d2-d5}, [%[v1]] \n"
|
||||
"vld1.16 {d10-d13}, [%[s2]]! \n"
|
||||
#if ORDER > 64
|
||||
"vmlal.s16 q0, d2, d6 \n"
|
||||
#else
|
||||
"vmull.s16 q0, d2, d6 \n"
|
||||
#endif
|
||||
"vmlal.s16 q0, d3, d7 \n"
|
||||
"vmlal.s16 q0, d4, d8 \n"
|
||||
"vmlal.s16 q0, d5, d9 \n"
|
||||
"vadd.i16 q1, q1, q5 \n"
|
||||
"vadd.i16 q2, q2, q6 \n"
|
||||
"vst1.16 {d2-d5}, [%[v1]]! \n"
|
||||
|
||||
REPEAT_BLOCK(
|
||||
"vld1.16 {d6-d9}, [%[f2]]! \n"
|
||||
"vld1.16 {d2-d5}, [%[v1]] \n"
|
||||
"vld1.16 {d10-d13}, [%[s2]]! \n"
|
||||
"vmlal.s16 q0, d2, d6 \n"
|
||||
"vmlal.s16 q0, d3, d7 \n"
|
||||
"vmlal.s16 q0, d4, d8 \n"
|
||||
"vmlal.s16 q0, d5, d9 \n"
|
||||
"vadd.i16 q1, q1, q5 \n"
|
||||
"vadd.i16 q2, q2, q6 \n"
|
||||
"vst1.16 {d2-d5}, [%[v1]]! \n"
|
||||
)
|
||||
#if ORDER > 64
|
||||
"bne 1b \n"
|
||||
#endif
|
||||
"vpadd.i32 d0, d0, d1 \n"
|
||||
"vpaddl.s32 d0, d0 \n"
|
||||
"vmov.32 %[res], d0[0] \n"
|
||||
: /* outputs */
|
||||
#if ORDER > 64
|
||||
[cnt]"+r"(cnt),
|
||||
#endif
|
||||
[v1] "+r"(v1),
|
||||
[f2] "+r"(f2),
|
||||
[s2] "+r"(s2),
|
||||
[res]"=r"(res)
|
||||
: /* inputs */
|
||||
: /* clobbers */
|
||||
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
|
||||
"d8", "d9", "d10", "d11", "d12", "d13", "memory"
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Calculate scalarproduct, then subtract a 2nd vector (fused for performance) */
|
||||
static inline int32_t vector_sp_sub(int16_t* v1, int16_t* f2, int16_t* s2)
|
||||
{
|
||||
int res;
|
||||
#if ORDER > 64
|
||||
int cnt = ORDER>>6;
|
||||
#endif
|
||||
|
||||
asm volatile (
|
||||
#if ORDER > 64
|
||||
"vmov.i16 q0, #0 \n"
|
||||
"1: \n"
|
||||
"subs %[cnt], %[cnt], #1 \n"
|
||||
#endif
|
||||
"vld1.16 {d6-d9}, [%[f2]]! \n"
|
||||
"vld1.16 {d2-d5}, [%[v1]] \n"
|
||||
"vld1.16 {d10-d13}, [%[s2]]! \n"
|
||||
#if ORDER > 64
|
||||
"vmlal.s16 q0, d2, d6 \n"
|
||||
#else
|
||||
"vmull.s16 q0, d2, d6 \n"
|
||||
#endif
|
||||
"vmlal.s16 q0, d3, d7 \n"
|
||||
"vmlal.s16 q0, d4, d8 \n"
|
||||
"vmlal.s16 q0, d5, d9 \n"
|
||||
"vsub.i16 q1, q1, q5 \n"
|
||||
"vsub.i16 q2, q2, q6 \n"
|
||||
"vst1.16 {d2-d5}, [%[v1]]! \n"
|
||||
|
||||
REPEAT_BLOCK(
|
||||
"vld1.16 {d6-d9}, [%[f2]]! \n"
|
||||
"vld1.16 {d2-d5}, [%[v1]] \n"
|
||||
"vld1.16 {d10-d13}, [%[s2]]! \n"
|
||||
"vmlal.s16 q0, d2, d6 \n"
|
||||
"vmlal.s16 q0, d3, d7 \n"
|
||||
"vmlal.s16 q0, d4, d8 \n"
|
||||
"vmlal.s16 q0, d5, d9 \n"
|
||||
"vsub.i16 q1, q1, q5 \n"
|
||||
"vsub.i16 q2, q2, q6 \n"
|
||||
"vst1.16 {d2-d5}, [%[v1]]! \n"
|
||||
)
|
||||
#if ORDER > 64
|
||||
"bne 1b \n"
|
||||
#endif
|
||||
"vpadd.i32 d0, d0, d1 \n"
|
||||
"vpaddl.s32 d0, d0 \n"
|
||||
"vmov.32 %[res], d0[0] \n"
|
||||
: /* outputs */
|
||||
#if ORDER > 64
|
||||
[cnt]"+r"(cnt),
|
||||
#endif
|
||||
[v1] "+r"(v1),
|
||||
[f2] "+r"(f2),
|
||||
[s2] "+r"(s2),
|
||||
[res]"=r"(res)
|
||||
: /* inputs */
|
||||
: /* clobbers */
|
||||
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
|
||||
"d8", "d9", "d10", "d11", "d12", "d13", "memory"
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline int32_t scalarproduct(int16_t* v1, int16_t* v2)
|
||||
{
|
||||
int res;
|
||||
#if ORDER > 64
|
||||
int cnt = ORDER>>6;
|
||||
#endif
|
||||
|
||||
asm volatile (
|
||||
#if ORDER > 64
|
||||
"vmov.i16 q0, #0 \n"
|
||||
"1: \n"
|
||||
"subs %[cnt], %[cnt], #1 \n"
|
||||
#endif
|
||||
"vld1.16 {d2-d5}, [%[v1]]! \n"
|
||||
"vld1.16 {d6-d9}, [%[v2]]! \n"
|
||||
#if ORDER > 64
|
||||
"vmlal.s16 q0, d2, d6 \n"
|
||||
#else
|
||||
"vmull.s16 q0, d2, d6 \n"
|
||||
#endif
|
||||
"vmlal.s16 q0, d3, d7 \n"
|
||||
"vmlal.s16 q0, d4, d8 \n"
|
||||
"vmlal.s16 q0, d5, d9 \n"
|
||||
|
||||
REPEAT_BLOCK(
|
||||
"vld1.16 {d2-d5}, [%[v1]]! \n"
|
||||
"vld1.16 {d6-d9}, [%[v2]]! \n"
|
||||
"vmlal.s16 q0, d2, d6 \n"
|
||||
"vmlal.s16 q0, d3, d7 \n"
|
||||
"vmlal.s16 q0, d4, d8 \n"
|
||||
"vmlal.s16 q0, d5, d9 \n"
|
||||
)
|
||||
#if ORDER > 64
|
||||
"bne 1b \n"
|
||||
#endif
|
||||
"vpadd.i32 d0, d0, d1 \n"
|
||||
"vpaddl.s32 d0, d0 \n"
|
||||
"vmov.32 %[res], d0[0] \n"
|
||||
: /* outputs */
|
||||
#if ORDER > 64
|
||||
[cnt]"+r"(cnt),
|
||||
#endif
|
||||
[v1] "+r"(v1),
|
||||
[v2] "+r"(v2),
|
||||
[res]"=r"(res)
|
||||
: /* inputs */
|
||||
: /* clobbers */
|
||||
"d0", "d1", "d2", "d3", "d4",
|
||||
"d5", "d6", "d7", "d8", "d9"
|
||||
);
|
||||
return res;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue