summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-10-12 23:16:40 +0000
committerJens Arnold <amiconn@rockbox.org>2005-10-12 23:16:40 +0000
commit507f72cd8ccce7e6c6bb84416b22f8c49ab66c87 (patch)
tree58055a7546afc3e661a722b14f5ca905b169a2e0 /apps
parent0059995326348bb9026ff91b6ff2be56f0059661 (diff)
downloadrockbox-507f72cd8ccce7e6c6bb84416b22f8c49ab66c87.tar.gz
rockbox-507f72cd8ccce7e6c6bb84416b22f8c49ab66c87.tar.bz2
rockbox-507f72cd8ccce7e6c6bb84416b22f8c49ab66c87.zip
Musepack: emacified multiplication routines, gives a nice speed boost.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7624 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/codecs/libmusepack/math.h63
-rw-r--r--apps/codecs/libmusepack/mpc_decoder.c2
2 files changed, 62 insertions, 3 deletions
diff --git a/apps/codecs/libmusepack/math.h b/apps/codecs/libmusepack/math.h
index a89ef76f58..247e9d03cd 100644
--- a/apps/codecs/libmusepack/math.h
+++ b/apps/codecs/libmusepack/math.h
@@ -68,6 +68,66 @@ typedef mpc_int64_t MPC_SAMPLE_FORMAT_MULTIPLY;
#define MAKE_MPC_SAMPLE(X) (MPC_SAMPLE_FORMAT)((double)(X) * (double)(((mpc_int64_t)1)<<MPC_FIXED_POINT_FRACTPART))
#define MAKE_MPC_SAMPLE_EX(X,Y) (MPC_SAMPLE_FORMAT)((double)(X) * (double)(((mpc_int64_t)1)<<(Y)))
+#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
+
+#define MPC_MULTIPLY(X,Y) mpc_multiply((X), (Y))
+#define MPC_MULTIPLY_EX(X,Y,Z) mpc_multiply_ex((X), (Y), (Z))
+
+static inline MPC_SAMPLE_FORMAT mpc_multiply(MPC_SAMPLE_FORMAT x,
+ MPC_SAMPLE_FORMAT y)
+{
+ MPC_SAMPLE_FORMAT t1, t2;
+ asm volatile (
+ "mac.l %[x],%[y],%%acc0\n" /* multiply */
+ "mulu.l %[y],%[x] \n" /* get lower half, avoid emac stall */
+ "movclr.l %%acc0,%[t1] \n" /* get higher half */
+ "moveq.l #17,%[t2] \n"
+ "asl.l %[t2],%[t1] \n" /* hi <<= 17, plus one free */
+ "moveq.l #14,%[t2] \n"
+ "lsr.l %[t2],%[x] \n" /* (unsigned)lo >>= 14 */
+ "or.l %[x],%[t1] \n" /* combine result */
+ : /* outputs */
+ [t1]"=&d"(t1),
+ [t2]"=&d"(t2),
+ [x] "+d" (x)
+ : /* inputs */
+ [y] "d" (y)
+ );
+ return t1;
+}
+
+static inline MPC_SAMPLE_FORMAT mpc_multiply_ex(MPC_SAMPLE_FORMAT x,
+ MPC_SAMPLE_FORMAT y,
+ unsigned shift)
+{
+ MPC_SAMPLE_FORMAT t1, t2;
+ asm volatile (
+ "mac.l %[x],%[y],%%acc0\n" /* multiply */
+ "mulu.l %[y],%[x] \n" /* get lower half, avoid emac stall */
+ "movclr.l %%acc0,%[t1] \n" /* get higher half */
+ "moveq.l #31,%[t2] \n"
+ "sub.l %[sh],%[t2] \n" /* t2 = 31 - shift */
+ "ble.s 1f \n"
+ "asl.l %[t2],%[t1] \n" /* hi <<= 31 - shift */
+ "lsr.l %[sh],%[x] \n" /* (unsigned)lo >>= shift */
+ "or.l %[x],%[t1] \n" /* combine result */
+ "bra.s 2f \n"
+ "1: \n"
+ "neg.l %[t2] \n" /* t2 = shift - 31 */
+ "asr.l %[t2],%[t1] \n" /* hi >>= t2 */
+ "2: \n"
+ : /* outputs */
+ [t1]"=&d"(t1),
+ [t2]"=&d"(t2),
+ [x] "+d" (x)
+ : /* inputs */
+ [y] "d" (y),
+ [sh]"d" (shift)
+ );
+ return t1;
+}
+#else /* libmusepack standard */
+
#define MPC_MULTIPLY_NOTRUNCATE(X,Y) \
(((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> MPC_FIXED_POINT_FRACTPART)
@@ -88,11 +148,10 @@ static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY_EX(MPC_SAMPLE_FORMAT item1,MPC_SAMP
assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp);
return (MPC_SAMPLE_FORMAT)temp;
}
-
#else
-
#define MPC_MULTIPLY(X,Y) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_NOTRUNCATE(X,Y))
#define MPC_MULTIPLY_EX(X,Y,Z) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z))
+#endif
#endif
diff --git a/apps/codecs/libmusepack/mpc_decoder.c b/apps/codecs/libmusepack/mpc_decoder.c
index a37dc4583c..166c9f7232 100644
--- a/apps/codecs/libmusepack/mpc_decoder.c
+++ b/apps/codecs/libmusepack/mpc_decoder.c
@@ -1175,7 +1175,7 @@ void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r)
mpc_decoder_init_huffman_sv7(d);
#if defined(CPU_COLDFIRE)&& !defined(SIMULATOR)
- coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_ROUND | EMAC_SATURATE);
+ coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE);
#endif
}