diff options
author | Nils Wallménius <nils@rockbox.org> | 2011-06-05 13:12:51 +0000 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2011-06-05 13:12:51 +0000 |
commit | 965113ed5051d3e9e4b563b8da1f5523c5470a76 (patch) | |
tree | ea3f7922e5075a96e21fa44e4c78f8a0df56c378 | |
parent | 9f65f2b6adc24964ac3fe03a75616fab96769bb7 (diff) | |
download | rockbox-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.h | 11 | ||||
-rw-r--r-- | apps/codecs/lib/asm_mcf5249.h | 15 | ||||
-rw-r--r-- | apps/codecs/lib/codeclib_misc.h | 7 | ||||
-rw-r--r-- | apps/codecs/libcook/cook_fixpoint.h | 10 |
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 | ||
55 | static 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 | ||
64 | static 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 | |||
64 | static inline | 79 | static inline |
65 | void XPROD31(int32_t a, int32_t b, | 80 | void 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 | |||
68 | static inline int32_t MULT31(int32_t x, int32_t y) { | 69 | static 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 | ||
79 | static 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 |
73 | static inline FIXP fixp_mult_su(FIXP a, FIXPU b) | 73 | static 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])) |