summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Bryant <bryant@rockbox.org>2006-03-04 21:26:47 +0000
committerDave Bryant <bryant@rockbox.org>2006-03-04 21:26:47 +0000
commit6472ecfc2eb9fcdd12de57f1ee8689ed924d1692 (patch)
treef836c866b2687572667a6fc638a19d61c7e55489
parent0b6bb8d8ccaec78e8966f9bf6b9ecfe0ea69412e (diff)
downloadrockbox-6472ecfc2eb9fcdd12de57f1ee8689ed924d1692.zip
rockbox-6472ecfc2eb9fcdd12de57f1ee8689ed924d1692.tar.gz
rockbox-6472ecfc2eb9fcdd12de57f1ee8689ed924d1692.tar.bz2
rockbox-6472ecfc2eb9fcdd12de57f1ee8689ed924d1692.tar.xz
Added a couple inline assembly functions for ARM targets. This just about
doubles the speed of crossfeed and makes a more modest improvement to the replaygain loop. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8904 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/dsp.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index f9d4bf1..0c376a1 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -119,6 +119,39 @@
#define ACC_INIT(acc, x, y) ACC(acc, x, y)
+#elif defined(CPU_ARM) && !defined(SIMULATOR)
+
+/* Multiply two S.31 fractional integers and return the sign bit and the
+ * 31 most significant bits of the result.
+ */
+#define FRACMUL(x, y) \
+({ \
+ long t; \
+ asm volatile ("smull r0, r1, %[a], %[b]\n\t" \
+ "mov %[t], r1, asl #1\n\t" \
+ "orr %[t], %[t], r0, lsr #31\n\t" \
+ : [t] "=r" (t) : [a] "r" (x), [b] "r" (y) : "r0", "r1"); \
+ t; \
+})
+
+#define ACC_INIT(acc, x, y) acc = FRACMUL(x, y)
+#define ACC(acc, x, y) acc += FRACMUL(x, y)
+#define GET_ACC(acc) acc
+
+/* Multiply one S.31-bit and one S8.23 fractional integer and store the
+ * sign bit and the 31 most significant bits of the result to d (and
+ * increase d). Load next value to multiply with into x from s (and
+ * increase s); x must contain the initial value.
+ */
+#define FRACMUL_8_LOOP(x, y, s, d) \
+({ \
+ asm volatile ("smull r0, r1, %[a], %[b]\n\t" \
+ "mov %[t], r1, asl #9\n\t" \
+ "orr %[t], %[t], r0, lsr #23\n\t" \
+ : [t] "=r" (*(d)++) : [a] "r" (x), [b] "r" (y) : "r0", "r1"); \
+ x = *(s)++; \
+})
+
#else
#define ACC_INIT(acc, x, y) acc = FRACMUL(x, y)