summaryrefslogtreecommitdiff
path: root/apps/codecs/libmusepack/mpcdec_math.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libmusepack/mpcdec_math.h')
-rw-r--r--apps/codecs/libmusepack/mpcdec_math.h100
1 files changed, 57 insertions, 43 deletions
diff --git a/apps/codecs/libmusepack/mpcdec_math.h b/apps/codecs/libmusepack/mpcdec_math.h
index f4c87324b5..955681f4e5 100644
--- a/apps/codecs/libmusepack/mpcdec_math.h
+++ b/apps/codecs/libmusepack/mpcdec_math.h
@@ -56,50 +56,64 @@
56 56
57 #define MPC_SHR_RND(X, Y) ((X+(1<<(Y-1)))>>Y) 57 #define MPC_SHR_RND(X, Y) ((X+(1<<(Y-1)))>>Y)
58 58
59 #if defined(CPU_COLDFIRE) 59#if defined(CPU_COLDFIRE)
60 /* Calculate: result = (X*Y)>>14 */
61 #define MPC_MULTIPLY(X,Y) \
62 ({ \
63 MPC_SAMPLE_FORMAT t1; \
64 MPC_SAMPLE_FORMAT t2; \
65 asm volatile ( \
66 "mac.l %[x],%[y],%%acc0\n\t" /* multiply */ \
67 "mulu.l %[y],%[x] \n\t" /* get lower half, avoid emac stall */ \
68 "movclr.l %%acc0,%[t1] \n\t" /* get higher half */ \
69 "moveq.l #17,%[t2] \n\t" \
70 "asl.l %[t2],%[t1] \n\t" /* hi <<= 17, plus one free */ \
71 "moveq.l #14,%[t2] \n\t" \
72 "lsr.l %[t2],%[x] \n\t" /* (unsigned)lo >>= 14 */ \
73 "or.l %[x],%[t1] \n" /* combine result */ \
74 : [t1]"=&d"(t1), [t2]"=&d"(t2) \
75 : [x]"d"((X)), [y] "d"((Y))); \
76 t1; \
77 })
78 60
79 /* Calculate: result = (X*Y)>>Z */ 61 #define MPC_MULTIPLY(X,Y) mpc_multiply((X), (Y))
80 #define MPC_MULTIPLY_EX(X,Y,Z) \ 62 #define MPC_MULTIPLY_EX(X,Y,Z) mpc_multiply_ex((X), (Y), (Z))
81 ({ \ 63
82 MPC_SAMPLE_FORMAT t1; \ 64 static inline MPC_SAMPLE_FORMAT mpc_multiply(MPC_SAMPLE_FORMAT x,
83 MPC_SAMPLE_FORMAT t2; \ 65 MPC_SAMPLE_FORMAT y)
84 asm volatile ( \ 66 {
85 "mac.l %[x],%[y],%%acc0\n\t" /* multiply */ \ 67 MPC_SAMPLE_FORMAT t1, t2;
86 "mulu.l %[y],%[x] \n\t" /* get lower half, avoid emac stall */ \ 68 asm volatile (
87 "movclr.l %%acc0,%[t1] \n\t" /* get higher half */ \ 69 "mac.l %[x],%[y],%%acc0\n" /* multiply */
88 "moveq.l #31,%[t2] \n\t" \ 70 "mulu.l %[y],%[x] \n" /* get lower half, avoid emac stall */
89 "sub.l %[sh],%[t2] \n\t" /* t2 = 31 - shift */ \ 71 "movclr.l %%acc0,%[t1] \n" /* get higher half */
90 "ble.s 1f \n\t" \ 72 "moveq.l #17,%[t2] \n"
91 "asl.l %[t2],%[t1] \n\t" /* hi <<= 31 - shift */ \ 73 "asl.l %[t2],%[t1] \n" /* hi <<= 17, plus one free */
92 "lsr.l %[sh],%[x] \n\t" /* (unsigned)lo >>= shift */ \ 74 "moveq.l #14,%[t2] \n"
93 "or.l %[x],%[t1] \n\t" /* combine result */ \ 75 "lsr.l %[t2],%[x] \n" /* (unsigned)lo >>= 14 */
94 "bra.s 2f \n\t" \ 76 "or.l %[x],%[t1] \n" /* combine result */
95 "1: \n\t" \ 77 : /* outputs */
96 "neg.l %[t2] \n\t" /* t2 = shift - 31 */ \ 78 [t1]"=&d"(t1),
97 "asr.l %[t2],%[t1] \n\t" /* hi >>= t2 */ \ 79 [t2]"=&d"(t2),
98 "2: \n" \ 80 [x] "+d" (x)
99 : [t1]"=&d"(t1), [t2]"=&d"(t2) \ 81 : /* inputs */
100 : [x] "d"((X)), [y] "d"((Y)), [sh]"d"((Z))); \ 82 [y] "d" (y)
101 t1; \ 83 );
102 }) 84 return t1;
85 }
86
87 static inline MPC_SAMPLE_FORMAT mpc_multiply_ex(MPC_SAMPLE_FORMAT x,
88 MPC_SAMPLE_FORMAT y,
89 unsigned shift)
90 {
91 MPC_SAMPLE_FORMAT t1, t2;
92 asm volatile (
93 "mac.l %[x],%[y],%%acc0\n" /* multiply */
94 "mulu.l %[y],%[x] \n" /* get lower half, avoid emac stall */
95 "movclr.l %%acc0,%[t1] \n" /* get higher half */
96 "moveq.l #31,%[t2] \n"
97 "sub.l %[sh],%[t2] \n" /* t2 = 31 - shift */
98 "ble.s 1f \n"
99 "asl.l %[t2],%[t1] \n" /* hi <<= 31 - shift */
100 "lsr.l %[sh],%[x] \n" /* (unsigned)lo >>= shift */
101 "or.l %[x],%[t1] \n" /* combine result */
102 "bra.s 2f \n"
103 "1: \n"
104 "neg.l %[t2] \n" /* t2 = shift - 31 */
105 "asr.l %[t2],%[t1] \n" /* hi >>= t2 */
106 "2: \n"
107 : /* outputs */
108 [t1]"=&d"(t1),
109 [t2]"=&d"(t2),
110 [x] "+d" (x)
111 : /* inputs */
112 [y] "d" (y),
113 [sh]"d" (shift)
114 );
115 return t1;
116 }
103 #elif defined(CPU_ARM) 117 #elif defined(CPU_ARM)
104 /* Calculate: result = (X*Y)>>14 */ 118 /* Calculate: result = (X*Y)>>14 */
105 #define MPC_MULTIPLY(X,Y) \ 119 #define MPC_MULTIPLY(X,Y) \