1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Andree Buschmann
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 .section .text, "ax", %progbits
24 /****************************************************************************
25 * void mpc_decoder_windowing_D(...)
27 * 2nd step within synthesis filter. Does the dewindowing.
29 * Uses un-shifted D[]-values. D[] will always be the second operand of
30 * smull/smlal to achieve higher speed as D[] has lower amplitude than V[].
31 ****************************************************************************/
33 .global mpc_decoder_windowing_D
34 .type mpc_decoder_windowing_D, %function
36 mpc_decoder_windowing_D:
41 /************************************************************************
42 * Reference implementation.
43 ***********************************************************************/
44 stmfd sp!, {r4-r8, lr}
48 ldmia r2!, { r3-r6 } /* load D[00..03] */
51 ldr r7, [r1, #96*4] /* 1 */
53 ldr r7, [r1, #128*4] /* 2 */
55 ldr r7, [r1, #224*4] /* 3 */
57 ldmia r2!, { r3-r6 } /* load D[04..07] */
58 ldr r7, [r1, #256*4] /* 4 */
60 ldr r7, [r1, #352*4] /* 5 */
62 ldr r7, [r1, #384*4] /* 6 */
64 ldr r7, [r1, #480*4] /* 7 */
66 ldmia r2!, { r3-r6 } /* load D[08..11] */
67 ldr r7, [r1, #512*4] /* 8 */
69 ldr r7, [r1, #608*4] /* 9 */
71 ldr r7, [r1, #640*4] /* 10 */
73 ldr r7, [r1, #736*4] /* 11 */
75 ldmia r2!, { r3-r6 } /* load D[12..15] */
76 ldr r7, [r1, #768*4] /* 12 */
78 ldr r7, [r1, #864*4] /* 13 */
80 ldr r7, [r1, #896*4] /* 14 */
82 ldr r7, [r1, #992*4] /* 15 */
85 orr r8, r8, r12, lsl #16 /* (lo>>16) || (hi<<16) */
86 str r8, [r0], #4 /* store Data */
87 add r1, r1, #4 /* V++ */
92 ldmfd sp!, {r4-r8, pc}
94 mpc_decoder_windowing_D:
99 /************************************************************************
100 * Further speed up through making use of symmetries within D[]-window.
101 * The row V[00] can be extracted as it has symmetries within this single
102 * row. 8 smull/mlal and 8 ldr's can be saved at the cost of 2 add's.
103 * The rows V[01..15] are symmetric to V[31..17]. 15 x 16 ldr's can be
104 * saved at the cost of 15 x 4 + 1 add's.
105 * The row V[16] can be extracted as it has symmetries within this single
106 * row. 8 smull/mlal and 8 ldr's can be saved.
107 ***********************************************************************/
108 stmfd sp!, {r4-r11, lr}
110 /******************************************
111 * row 0 with internal symmetry
112 *****************************************/
113 add r2, r2, #4 /* D+=1, r2 = D[01] as D[00] = 0 */
114 ldmia r2!, { r3-r6 } /* load D[01..04] */
115 ldr r7 , [r1, #96*4] /* 1 */
116 ldr r10, [r1, #992*4] /* 15 */
117 rsb r10, r10, r7 /* V[01] - V[15] */
118 smull r8, r9, r10, r3
119 ldr r7 , [r1, #128*4] /* 2 */
120 ldr r10, [r1, #896*4] /* 14 */
121 add r10, r10, r7 /* V[02] + V[14] */
122 smlal r8, r9, r10, r4
123 ldr r7 , [r1, #224*4] /* 3 */
124 ldr r10, [r1, #864*4] /* 13 */
125 rsb r10, r10, r7 /* V[03] - V[13] */
126 smlal r8, r9, r10, r5
127 ldr r7 , [r1, #256*4] /* 4 */
128 ldr r10, [r1, #768*4] /* 12 */
129 add r10, r10, r7 /* V[04] + V[12] */
130 smlal r8, r9, r10, r6
131 ldmia r2!, { r3-r6 } /* load D[05..08] */
132 ldr r7 , [r1, #352*4] /* 5 */
133 ldr r10, [r1, #736*4] /* 11 */
134 rsb r10, r10, r7 /* V[05] - V[11] */
135 smlal r8, r9, r10, r3
136 ldr r7 , [r1, #384*4] /* 6 */
137 ldr r10, [r1, #640*4] /* 10 */
138 add r10, r10, r7 /* V[06] + V[10] */
139 smlal r8, r9, r10, r4
140 ldr r7 , [r1, #480*4] /* 7 */
141 ldr r10, [r1, #608*4] /* 9 */
142 rsb r10, r10, r7 /* V[07] - V[09] */
143 smlal r8, r9, r10, r5
144 ldr r10, [r1, #512*4] /* 8 */
145 smlal r8, r9, r10, r6
147 orr r8, r8, r9, lsl #16 /* (lo>>16) || (hi<<16) */
148 str r8, [r0], #4 /* store Data */
149 add r1, r1, #4 /* V+=1, r1 = V[01] */
150 add r2, r2, #7*4 /* D+=7, r2 = D[16] */
152 /******************************************
153 * rows 01..15 are symmetrc to rows 31..17
154 * r8 = lo, r9 = hi of 01..15
156 * r10 = lo, r11 = hi of 31..17
158 *****************************************/
160 add r12, r1, #30*4 /* r12 = V[31] */
162 ldmia r2!, { r3-r6 } /* load D[00..03] */
163 ldr r7, [r12, #768*4] /* 12 */
164 smull r10, r11, r7, r6
165 ldr r7, [r12, #864*4] /* 13 */
166 smlal r10, r11, r7, r5
167 ldr r7, [r12, #896*4] /* 14 */
168 smlal r10, r11, r7, r4
169 ldr r7, [r12, #992*4] /* 15 */
170 smlal r10, r11, r7, r3
173 ldr r7, [r1, #96*4] /* 1 */
175 ldr r7, [r1, #128*4] /* 2 */
177 ldr r7, [r1, #224*4] /* 3 */
179 ldmia r2!, { r3-r6 } /* load D[04..07] */
180 ldr r7, [r1, #256*4] /* 4 */
182 ldr r7, [r1, #352*4] /* 5 */
184 ldr r7, [r1, #384*4] /* 6 */
186 ldr r7, [r1, #480*4] /* 7 */
188 ldr r7, [r12, #512*4] /* 8 */
189 smlal r10, r11, r7, r6
190 ldr r7, [r12, #608*4] /* 9 */
191 smlal r10, r11, r7, r5
192 ldr r7, [r12, #640*4] /* 10 */
193 smlal r10, r11, r7, r4
194 ldr r7, [r12, #736*4] /* 11 */
195 smlal r10, r11, r7, r3
196 ldmia r2!, { r3-r6 } /* load D[08..11] */
197 ldr r7, [r12, #256*4] /* 4 */
198 smlal r10, r11, r7, r6
199 ldr r7, [r12, #352*4] /* 5 */
200 smlal r10, r11, r7, r5
201 ldr r7, [r12, #384*4] /* 6 */
202 smlal r10, r11, r7, r4
203 ldr r7, [r12, #480*4] /* 7 */
204 smlal r10, r11, r7, r3
205 ldr r7, [r1, #512*4] /* 8 */
207 ldr r7, [r1, #608*4] /* 9 */
209 ldr r7, [r1, #640*4] /* 10 */
211 ldr r7, [r1, #736*4] /* 11 */
213 ldmia r2!, { r3-r6 } /* load D[12..15] */
214 ldr r7, [r1, #768*4] /* 12 */
216 ldr r7, [r1, #864*4] /* 13 */
218 ldr r7, [r1, #896*4] /* 14 */
220 ldr r7, [r1, #992*4] /* 15 */
222 ldr r7, [r12] /* 0 */
223 smlal r10, r11, r7, r6
224 ldr r7, [r12, #96*4] /* 1 */
225 smlal r10, r11, r7, r5
226 ldr r7, [r12, #128*4] /* 2 */
227 smlal r10, r11, r7, r4
228 ldr r7, [r12, #224*4] /* 3 */
229 smlal r10, r11, r7, r3
230 /* store Data[01..15] */
232 orr r8, r8, r9, lsl #16 /* (lo>>16) || (hi<<16) */
233 str r8, [r0] /* store Data */
234 /* store Data[31..17] */
235 add r0, r0, lr, asl #3 /* r0 = r0 + 2*lr [words] */
236 mov r10, r10, lsr #16
237 orr r10, r10, r11, lsl #16 /* (lo>>16) || (hi<<16) */
238 rsb r10, r10, #0 /* r10 = -r10 */
239 str r10, [r0], #4 /* store Data */
240 sub r0, r0, lr, asl #3 /* r0 = r0 - 2*lr [words] */
241 /* correct adresses for next loop */
242 sub r12, r12, #4 /* r12 = V-- */
243 add r1, r1, #4 /* r1 = V++ */
248 /******************************************
249 * V[16] with internal symmetry
250 *****************************************/
251 ldmia r2!, { r3-r6 } /* load D[00..03] */
252 ldr r7 , [r1] /* 0 */
253 ldr r10, [r1, #992*4] /* 15 */
254 rsb r10, r10, r7 /* V[00] - V[15] */
255 smull r8, r9, r10, r3
256 ldr r7 , [r1, #96*4] /* 1 */
257 ldr r10, [r1, #896*4] /* 14 */
258 rsb r10, r10, r7 /* V[01] - V[14] */
259 smlal r8, r9, r10, r4
260 ldr r7 , [r1, #128*4] /* 2 */
261 ldr r10, [r1, #864*4] /* 13 */
262 rsb r10, r10, r7 /* V[02] - V[13] */
263 smlal r8, r9, r10, r5
264 ldr r7 , [r1, #224*4] /* 3 */
265 ldr r10, [r1, #768*4] /* 12 */
266 rsb r10, r10, r7 /* V[03] - V[12] */
267 smlal r8, r9, r10, r6
268 ldmia r2!, { r3-r6 } /* load D[04..07] */
269 ldr r7 , [r1, #256*4] /* 4 */
270 ldr r10, [r1, #736*4] /* 11 */
271 rsb r10, r10, r7 /* V[04] - V[11] */
272 smlal r8, r9, r10, r3
273 ldr r7 , [r1, #352*4] /* 5 */
274 ldr r10, [r1, #640*4] /* 10 */
275 rsb r10, r10, r7 /* V[05] - V[10] */
276 smlal r8, r9, r10, r4
277 ldr r7 , [r1, #384*4] /* 6 */
278 ldr r10, [r1, #608*4] /* 9 */
279 rsb r10, r10, r7 /* V[06] - V[09] */
280 smlal r8, r9, r10, r5
281 ldr r7 , [r1, #480*4] /* 7 */
282 ldr r10, [r1, #512*4] /* 8 */
283 rsb r10, r10, r7 /* V[07] - V[08] */
284 smlal r8, r9, r10, r6
286 orr r8, r8, r9, lsl #16 /* (lo>>16) || (hi<<16) */
287 str r8, [r0], #4 /* store Data */
288 add r1, r1, #4 /* V++ */
290 ldmfd sp!, {r4-r11, pc}
292 .mpc_dewindowing_end:
293 .size mpc_decoder_windowing_D,.mpc_dewindowing_end-mpc_decoder_windowing_D