summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2011-06-05 13:12:51 +0000
committerNils Wallménius <nils@rockbox.org>2011-06-05 13:12:51 +0000
commit965113ed5051d3e9e4b563b8da1f5523c5470a76 (patch)
treeea3f7922e5075a96e21fa44e4c78f8a0df56c378
parent9f65f2b6adc24964ac3fe03a75616fab96769bb7 (diff)
downloadrockbox-965113ed5051d3e9e4b563b8da1f5523c5470a76.tar.gz
rockbox-965113ed5051d3e9e4b563b8da1f5523c5470a76.zip
FS#12146: Fix libcook bugs introduced in r22055 by Sean Bartell.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29973 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/lib/asm_arm.h11
-rw-r--r--apps/codecs/lib/asm_mcf5249.h15
-rw-r--r--apps/codecs/lib/codeclib_misc.h7
-rw-r--r--apps/codecs/libcook/cook_fixpoint.h10
4 files changed, 38 insertions, 5 deletions
diff --git a/apps/codecs/lib/asm_arm.h b/apps/codecs/lib/asm_arm.h
index c0f9440450..629e47b3bd 100644
--- a/apps/codecs/lib/asm_arm.h
+++ b/apps/codecs/lib/asm_arm.h
@@ -52,6 +52,17 @@ static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) {
52 return(hi); 52 return(hi);
53} 53}
54 54
55static inline int32_t MULT31_SHIFT16(int32_t x, int32_t y) {
56 int32_t lo,hi;
57 asm volatile("smull %0, %1, %2, %3\n\t"
58 "movs %0, %0, lsr #16\n\t"
59 "adc %1, %0, %1, lsl #16\n\t"
60 : "=&r"(lo),"=&r"(hi)
61 : "r"(x),"r"(y)
62 : "cc" );
63 return(hi);
64}
65
55#define XPROD32(a, b, t, v, x, y) \ 66#define XPROD32(a, b, t, v, x, y) \
56{ \ 67{ \
57 int32_t l; \ 68 int32_t l; \
diff --git a/apps/codecs/lib/asm_mcf5249.h b/apps/codecs/lib/asm_mcf5249.h
index 49d2ddf7cb..5fb3cff94a 100644
--- a/apps/codecs/lib/asm_mcf5249.h
+++ b/apps/codecs/lib/asm_mcf5249.h
@@ -61,6 +61,21 @@ static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) {
61 return r; 61 return r;
62} 62}
63 63
64static inline int32_t MULT31_SHIFT16(int32_t x, int32_t y) {
65 int32_t r;
66
67 asm volatile ("mac.l %[x], %[y], %%acc0;" /* multiply */
68 "mulu.l %[y], %[x];" /* get lower half, avoid emac stall */
69 "movclr.l %%acc0, %[r];" /* get higher half */
70 "lsr.l #1, %[r];" /* hi >> 1, to compensate emac shift */
71 "move.w %[r], %[x];" /* x = x & 0xffff0000 | r & 0xffff */
72 "swap %[x];" /* x = (unsigned)x << 16 | (unsigned)x >> 16 */
73 : [r] "=&d" (r), [x] "+d" (x)
74 : [y] "d" (y)
75 : "cc");
76 return x;
77}
78
64static inline 79static inline
65void XPROD31(int32_t a, int32_t b, 80void XPROD31(int32_t a, int32_t b,
66 int32_t t, int32_t v, 81 int32_t t, int32_t v,
diff --git a/apps/codecs/lib/codeclib_misc.h b/apps/codecs/lib/codeclib_misc.h
index f3ec209e78..f3b1805e26 100644
--- a/apps/codecs/lib/codeclib_misc.h
+++ b/apps/codecs/lib/codeclib_misc.h
@@ -65,6 +65,7 @@ static inline int32_t MULT32(int32_t x, int32_t y) {
65 magic.whole = (int64_t)x * y; 65 magic.whole = (int64_t)x * y;
66 return magic.halves.hi; 66 return magic.halves.hi;
67} 67}
68
68static inline int32_t MULT31(int32_t x, int32_t y) { 69static inline int32_t MULT31(int32_t x, int32_t y) {
69 return MULT32(x,y)<<1; 70 return MULT32(x,y)<<1;
70} 71}
@@ -75,6 +76,12 @@ static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) {
75 return ((uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17); 76 return ((uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17);
76} 77}
77 78
79static inline int32_t MULT31_SHIFT16(int32_t x, int32_t y) {
80 union magic magic;
81 magic.whole = (int64_t)x * y;
82 return ((uint32_t)(magic.halves.lo)>>16) | ((magic.halves.hi)<<16);
83}
84
78#else 85#else
79/* 32 bit multiply, more portable but less accurate */ 86/* 32 bit multiply, more portable but less accurate */
80 87
diff --git a/apps/codecs/libcook/cook_fixpoint.h b/apps/codecs/libcook/cook_fixpoint.h
index c8a17c6dc6..5c4a5d1a5a 100644
--- a/apps/codecs/libcook/cook_fixpoint.h
+++ b/apps/codecs/libcook/cook_fixpoint.h
@@ -36,7 +36,7 @@
36 */ 36 */
37 37
38#ifdef ROCKBOX 38#ifdef ROCKBOX
39/* get definitions of MULT31, MULT31_SHIFT15, vect_add, from codelib */ 39/* get definitions of MULT31, MULT31_SHIFT16, vect_add, from codelib */
40#include "codeclib_misc.h" 40#include "codeclib_misc.h"
41#include "codeclib.h" 41#include "codeclib.h"
42#endif 42#endif
@@ -68,7 +68,7 @@ static inline FIXP fixp_pow2(FIXP x, int i)
68 * @param b fix point fraction, 0 <= b < 1 68 * @param b fix point fraction, 0 <= b < 1
69 */ 69 */
70#ifdef ROCKBOX 70#ifdef ROCKBOX
71#define fixp_mult_su(x,y) (MULT31_SHIFT15(x,y)) 71#define fixp_mult_su(x,y) (MULT31_SHIFT16(x,y))
72#else 72#else
73static inline FIXP fixp_mult_su(FIXP a, FIXPU b) 73static inline FIXP fixp_mult_su(FIXP a, FIXPU b)
74{ 74{
@@ -130,18 +130,18 @@ static void scalar_dequant_math(COOKContext *q, int index,
130 int* subband_coef_sign, REAL_T *mlt_p) 130 int* subband_coef_sign, REAL_T *mlt_p)
131{ 131{
132 /* Num. half bits to right shift */ 132 /* Num. half bits to right shift */
133 const int s = (33 - quant_index + av_log2(q->samples_per_channel)) >> 1; 133 const int s = 33 - quant_index + av_log2(q->samples_per_channel);
134 const FIXP *table = quant_tables[s & 1][index]; 134 const FIXP *table = quant_tables[s & 1][index];
135 FIXP f; 135 FIXP f;
136 int i; 136 int i;
137 137
138 138
139 if(s >= 32) 139 if(s >= 64)
140 memset(mlt_p, 0, sizeof(REAL_T)*SUBBAND_SIZE); 140 memset(mlt_p, 0, sizeof(REAL_T)*SUBBAND_SIZE);
141 else 141 else
142 { 142 {
143 for(i=0 ; i<SUBBAND_SIZE ; i++) { 143 for(i=0 ; i<SUBBAND_SIZE ; i++) {
144 f = (table[subband_coef_index[i]])>>s; 144 f = (table[subband_coef_index[i]]) >> (s >> 1);
145 /* noise coding if subband_coef_index[i] == 0 */ 145 /* noise coding if subband_coef_index[i] == 0 */
146 if (((subband_coef_index[i] == 0) && cook_random(q)) || 146 if (((subband_coef_index[i] == 0) && cook_random(q)) ||
147 ((subband_coef_index[i] != 0) && subband_coef_sign[i])) 147 ((subband_coef_index[i] != 0) && subband_coef_sign[i]))