diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-02-23 22:39:12 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-02-23 22:39:12 +0000 |
commit | c2925814cea31709a73b46b539d27ab0c8793d98 (patch) | |
tree | e2f8f361ea3fcc1928e9b95718eafe688f740794 | |
parent | 87c20b7762ddf114b5da43fc34e73cc6b903d5ea (diff) | |
download | rockbox-c2925814cea31709a73b46b539d27ab0c8793d98.tar.gz rockbox-c2925814cea31709a73b46b539d27ab0c8793d98.zip |
SPC Codec: Fix an overflow issue in echo with left shifting by 9 that showed on some files by using mac.l instead which is ok since the little beastie seems to prefer multiplying things. Mark asm blocks volatile so gcc doesn't get any ideas that the code can be removed as happened to me once already.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12464 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs/spc/Spc_Dsp.h | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/apps/codecs/spc/Spc_Dsp.h b/apps/codecs/spc/Spc_Dsp.h index b00cec9bd1..6b530a7a62 100644 --- a/apps/codecs/spc/Spc_Dsp.h +++ b/apps/codecs/spc/Spc_Dsp.h | |||
@@ -528,7 +528,7 @@ static void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) | |||
528 | #define IF_RBE(...) __VA_ARGS__ | 528 | #define IF_RBE(...) __VA_ARGS__ |
529 | #ifdef CPU_COLDFIRE | 529 | #ifdef CPU_COLDFIRE |
530 | /* Initialize mask register with the buffer address mask */ | 530 | /* Initialize mask register with the buffer address mask */ |
531 | asm ("move.l %[m], %%mask" : : [m]"i"(fir_buf_mask)); | 531 | asm volatile ("move.l %[m], %%mask" : : [m]"i"(fir_buf_mask)); |
532 | const int echo_wrap = (this->r.g.echo_delay & 15) * 0x800; | 532 | const int echo_wrap = (this->r.g.echo_delay & 15) * 0x800; |
533 | const int echo_start = this->r.g.echo_page * 0x100; | 533 | const int echo_start = this->r.g.echo_page * 0x100; |
534 | #endif /* CPU_COLDFIRE */ | 534 | #endif /* CPU_COLDFIRE */ |
@@ -976,7 +976,7 @@ static void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) | |||
976 | uint32_t f = voice->position; | 976 | uint32_t f = voice->position; |
977 | int32_t y1; | 977 | int32_t y1; |
978 | 978 | ||
979 | asm ( | 979 | asm volatile ( |
980 | "move.l %[f], %[y0] \r\n" /* separate fraction */ | 980 | "move.l %[f], %[y0] \r\n" /* separate fraction */ |
981 | "and.l #0xfff, %[f] \r\n" /* and whole parts */ | 981 | "and.l #0xfff, %[f] \r\n" /* and whole parts */ |
982 | "lsr.l %[sh], %[y0] \r\n" | 982 | "lsr.l %[sh], %[y0] \r\n" |
@@ -1095,10 +1095,9 @@ static void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) | |||
1095 | 1095 | ||
1096 | /* Apply echo FIR filter to output - circular buffer is hardware | 1096 | /* Apply echo FIR filter to output - circular buffer is hardware |
1097 | incremented and masked; FIR coefficients and buffer history are | 1097 | incremented and masked; FIR coefficients and buffer history are |
1098 | loaded in parallel with multiply accumulate operations. Apply | 1098 | loaded in parallel with multiply accumulate operations. */ |
1099 | scale factor to do hardware clipping later. */ | ||
1100 | int _0, _1, _2; | 1099 | int _0, _1, _2; |
1101 | asm ( | 1100 | asm volatile ( |
1102 | "move.l (%[fir_c]) , %[_2] \r\n" | 1101 | "move.l (%[fir_c]) , %[_2] \r\n" |
1103 | "mac.w %[fb]u, %[_2]u, <<, (%[fir_p])+&, %[_0], %%acc0 \r\n" | 1102 | "mac.w %[fb]u, %[_2]u, <<, (%[fir_p])+&, %[_0], %%acc0 \r\n" |
1104 | "mac.w %[fb]l, %[_2]u, <<, (%[fir_p])& , %[_1], %%acc1 \r\n" | 1103 | "mac.w %[fb]l, %[_2]u, <<, (%[fir_p])& , %[_1], %%acc1 \r\n" |
@@ -1125,7 +1124,7 @@ static void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) | |||
1125 | ); | 1124 | ); |
1126 | 1125 | ||
1127 | /* Generate output */ | 1126 | /* Generate output */ |
1128 | asm ( | 1127 | asm volatile ( |
1129 | "mac.l %[chans_0], %[gv_0] , %%acc2 \r\n" | 1128 | "mac.l %[chans_0], %[gv_0] , %%acc2 \r\n" |
1130 | "mac.l %[chans_1], %[gv_1] , %%acc3 \r\n" | 1129 | "mac.l %[chans_1], %[gv_1] , %%acc3 \r\n" |
1131 | "mac.l %[ev_0], %[out_0], >>, %%acc2 \r\n" | 1130 | "mac.l %[ev_0], %[out_0], >>, %%acc2 \r\n" |
@@ -1141,12 +1140,10 @@ static void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) | |||
1141 | /* Feedback into echo buffer */ | 1140 | /* Feedback into echo buffer */ |
1142 | if ( !(this->r.g.flags & 0x20) ) | 1141 | if ( !(this->r.g.flags & 0x20) ) |
1143 | { | 1142 | { |
1144 | asm ( | 1143 | asm volatile ( |
1145 | "lsl.l %[sh], %[e0] \r\n" | 1144 | "mac.l %[sh], %[e0] , %%acc0 \r\n" |
1146 | "move.l %[e0], %%acc0 \r\n" | ||
1147 | "mac.l %[out_0], %[ef], <<, %%acc0 \r\n" | 1145 | "mac.l %[out_0], %[ef], <<, %%acc0 \r\n" |
1148 | "lsl.l %[sh], %[e1] \r\n" | 1146 | "mac.l %[sh], %[e1] , %%acc1 \r\n" |
1149 | "move.l %[e1], %%acc1 \r\n" | ||
1150 | "mac.l %[out_1], %[ef], <<, %%acc1 \r\n" | 1147 | "mac.l %[out_1], %[ef], <<, %%acc1 \r\n" |
1151 | "movclr.l %%acc0, %[e0] \r\n" | 1148 | "movclr.l %%acc0, %[e0] \r\n" |
1152 | "movclr.l %%acc1, %[e1] \r\n" | 1149 | "movclr.l %%acc1, %[e1] \r\n" |
@@ -1155,13 +1152,14 @@ static void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) | |||
1155 | : [e0]"+&d"(echo_0), [e1]"+&d"(echo_1) | 1152 | : [e0]"+&d"(echo_0), [e1]"+&d"(echo_1) |
1156 | : [out_0]"r"(out_0), [out_1]"r"(out_1), | 1153 | : [out_0]"r"(out_0), [out_1]"r"(out_1), |
1157 | [ef]"r"((int)this->r.g.echo_feedback), | 1154 | [ef]"r"((int)this->r.g.echo_feedback), |
1158 | [sh]"d"(9) | 1155 | [sh]"r"(1 << 9) |
1159 | ); | 1156 | ); |
1157 | |||
1160 | *(int32_t *)echo_ptr = swap_odd_even32(echo_0); | 1158 | *(int32_t *)echo_ptr = swap_odd_even32(echo_0); |
1161 | } | 1159 | } |
1162 | 1160 | ||
1163 | /* Output final samples */ | 1161 | /* Output final samples */ |
1164 | asm ( | 1162 | asm volatile ( |
1165 | "movclr.l %%acc2, %[out_0] \r\n" | 1163 | "movclr.l %%acc2, %[out_0] \r\n" |
1166 | "movclr.l %%acc3, %[out_1] \r\n" | 1164 | "movclr.l %%acc3, %[out_1] \r\n" |
1167 | "asr.l %[gm], %[out_0] \r\n" | 1165 | "asr.l %[gm], %[out_0] \r\n" |