summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2009-02-15 17:07:18 +0000
committerJens Arnold <amiconn@rockbox.org>2009-02-15 17:07:18 +0000
commit789b0a2eb9ae94a10abd590c91e3ae8588137e37 (patch)
tree5ad1fd1d69ffe5852ba7d14072498c93497ec8ba
parentd70902feb8e2689080d0360f504ffc4772cc0dc6 (diff)
Add an unsigned 32*32->top32 bit multiply for resizing on SH1, and switch to 32 bit precision using that.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20012 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/recorder/resize.h42
1 files changed, 41 insertions, 1 deletions
diff --git a/apps/recorder/resize.h b/apps/recorder/resize.h
index 4e71fb8732..d1dabaae09 100644
--- a/apps/recorder/resize.h
+++ b/apps/recorder/resize.h
@@ -59,7 +59,47 @@
t; \
})
#elif (CONFIG_CPU == SH7034)
-#define SC_SHIFT 24
+/* multiply two unsigned 32 bit values and return the top 32 bit
+ * of the 64 bit result */
+static inline unsigned sc_mul32(unsigned a, unsigned b)
+{
+ unsigned r, t1, t2, t3;
+
+ asm (
+ "swap.w %[a], %[t1] \n" /* t1 = ba */
+ "mulu %[t1], %[b] \n" /* a * d */
+ "swap.w %[b], %[t3] \n" /* t3 = dc */
+ "sts macl, %[t2] \n" /* t2 = a * d */
+ "mulu %[t1], %[t3] \n" /* a * c */
+ "sts macl, %[r] \n" /* hi = a * c */
+ "mulu %[a], %[t3] \n" /* b * c */
+ "clrt \n"
+ "sts macl, %[t3] \n" /* t3 = b * c */
+ "addc %[t2], %[t3] \n" /* t3 += t2, carry -> t2 */
+ "movt %[t2] \n"
+ "mulu %[a], %[b] \n" /* b * d */
+ "mov %[t3], %[t1] \n" /* t2t3 <<= 16 */
+ "xtrct %[t2], %[t1] \n"
+ "mov %[t1], %[t2] \n"
+ "shll16 %[t3] \n"
+ "sts macl, %[t1] \n" /* lo = b * d */
+ "clrt \n" /* hi.lo += t2t3 */
+ "addc %[t3], %[t1] \n"
+ "addc %[t2], %[r] \n"
+ : /* outputs */
+ [r] "=&r"(r),
+ [t1]"=&r"(t1),
+ [t2]"=&r"(t2),
+ [t3]"=&r"(t3)
+ : /* inputs */
+ [a] "r" (a),
+ [b] "r" (b)
+ );
+ return r;
+}
+#define SC_MUL(x, y) sc_mul32(x, y)
+#define SC_MUL_INIT
+#define SC_MUL_END
#endif
#ifndef SC_SHIFT