Gonzalo Brusco
/
QuiPAD
Real Time FIR Filter - Distinctive Excellence award winner :)
Diff: cr_dsplib_blockfir32.s
- Revision:
- 0:b3e50e98acac
diff -r 000000000000 -r b3e50e98acac cr_dsplib_blockfir32.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cr_dsplib_blockfir32.s Sat Aug 13 17:35:52 2011 +0000 @@ -0,0 +1,144 @@ + +; Los cuatro argumentos de la funcion llegan por r0, r1, r2 y r3. +; r0 = Puntero a las muestras de salida. +; r1 = Puntero a las muestras de entrada. +; r2 = Puntero a la estructura de los coeficientes. +; r3 = Cantidad de muestras de entrada. +; r4 = Cantidad de coeficientes. +; r3 y r5 = Temporales donde se cargan los coeficientes de entrada (r3 esta sobrecargado) +; r6,r7,r8,r9 = Acumuladores. +; r10,r11,r12,r14 = Temporales en donde se cargan las muestras de entrada. +; r0 = Se utiliza como mascara (r0 esta sobrecargado) + + AREA asm_func, CODE, READONLY + + EXPORT vF_dspl_blockfir32 + +vF_dspl_blockfir32 + + push {r4-r12,lr} ; Almacena registros en el stack. + ldr r4,[r2,#4] ; Levanta en el registro r4 la cantidad de coeficientes. + ldr r2,[r2] ; Carga en r2 el puntero hacia los coeficientes. + + ; Le resto la cantidad de coeficientes a r3 para evitar que genere el transitorio final. + ; r3 = r3 - r4 + 4 + ; Recordar que las ultimas tres muestras de salida tienen que ser descartadas. + + sub r3,r3,r4 + add r3,r3,#4 + +LoopSample + mov r6,#0 ; Limpia los acumuladores (0 a 3) + mov r7,r6 + mov r8,r6 + mov r9,r6 + + push {r0, r3, r4} ; Guarda r3, r4 y r0 (son registros) en el stack. + + ldr r0,=0x80000000 + + ldmia r1!,{r10,r11,r12,r14} ; Carga 4 muestras en r10, r11, r12 y r14. r1 queda apuntando a la proxima muestra. + + ; Desplazo hacia la izquierda lo mas posible y complemento el bit MSB. + eor r10,r0,r10,LSL#16 + eor r11,r0,r11,LSL#16 + eor r12,r0,r12,LSL#16 + eor r14,r0,r14,LSL#16 + + ; Desplazo aritmeticamente lo mas posible hacia la derecha. + mov r10,r10,ASR#22 + mov r11,r11,ASR#22 + mov r12,r12,ASR#22 + mov r14,r14,ASR#22 + +LoopTaps + ldmia r2!,{r3,r5} ;Carga 2 coeficientes en r3 y r5. r2 queda apuntando al proximo coeficiente. + + ; mla = multiply and accumulate + ; Multiplica un coeficiente por las cuatro muestras leidas y acumula. + mla r6,r10,r3,r6 ; r6 = (r6 + (r10 * r3))[31:0] + mla r7,r11,r3,r7 ; r7 = (r7 + (r11 * r3))[31:0] + mla r8,r12,r3,r8 ; r8 = (r8 + (r12 * r3))[31:0] + mla r9,r14,r3,r9 ; r9 = (r9 + (r14 * r3))[31:0] + + ldr r10,[r1],#4 ; Se carga en r10 lo apuntado por r1. Luego se incrementa r1 en 4 (r1=r1+4) + + ; Enmascaro, complemento el MSB y hago extension de signo. + eor r10,r0,r10,LSL#16 + mov r10,r10,ASR#22 + + ldr r3,[r2],#4 ; Se carga en r3 lo apuntado por r2. Luego se incrementa r1 en 4 (r2=r2+4) + + mla r6,r11,r5,r6 ; r6 = (r6 + (r11 * r5))[31:0] + mla r7,r12,r5,r7 ; r7 = (r7 + (r12 * r5))[31:0] + mla r8,r14,r5,r8 ; r8 = (r8 + (r14 * r5))[31:0] + mla r9,r10,r5,r9 ; r9 = (r9 + (r10 * r5))[31:0] + + ldr r11,[r1],#4 ; Se carga en r11 lo apuntado por r1. Luego se incrementa r1 en 4 (r1=r1+4) + + ; Enmascaro, complemento el MSB y hago extension de signo. + eor r11,r0,r11,LSL#16 + mov r11,r11,ASR#22 + + ldr r5,[r2],#4 ; Se carga en r5 lo apuntado por r2. Luego se incrementa r2 en 4 (r2=r2+4) + ; Supongo que como se trabaja con la memoria alineada de a bytes, incrementar en 4 significa + ; pararse en la proxima muestra (las muestras son de 32 bits). + + mla r6,r12,r3,r6 ; r6 = (r6 + (r12 * r3))[31:0] + mla r7,r14,r3,r7 ; r7 = (r7 + (r14 * r3))[31:0] + mla r8,r10,r3,r8 ; r8 = (r8 + (r10 * r3))[31:0] + mla r9,r11,r3,r9 ; r9 = (r9 + (r11 * r3))[31:0] + + ldr r12,[r1],#4 ; Se carga en r12 lo apuntado por r1. Luego se incrementa r1 en 4 (r1=r1+4) + + ; Enmascaro, complemento el MSB y hago extension de signo. + eor r12,r0,r12,LSL#16 + mov r12,r12,ASR#22 + + subs r4,r4,#4 ;Este resta se puso aqu� para evitar que se forme una burbuja antes del branch. + ;r4 = r4 - 4 + + mla r6,r14,r5,r6 ; r6 = (r6 + (r14 * r5))[31:0] + mla r7,r10,r5,r7 ; r7 = (r7 + (r10 * r5))[31:0] + mla r8,r11,r5,r8 ; r8 = (r8 + (r11 * r5))[31:0] + mla r9,r12,r5,r9 ; r9 = (r9 + (r12 * r5))[31:0] + + ldr r14,[r1],#4 ; Se carga en r14 lo apuntado por r1. Luego se incrementa r1 en 4 (r1=r1+4) + + ; Enmascaro, complemento el MSB y hago extension de signo. + eor r14,r0,r14,LSL#16 + mov r14,r14,ASR#22 + + bne LoopTaps ; Mira si se terminaron los coeficientes. + + ; Enmascaro y complemento el MSB (lo vuelvo a formato DAC). + ldr r0,=0xFFC0 + and r6,r0,r6,LSR#16 + and r7,r0,r7,LSR#16 + and r8,r0,r8,LSR#16 + and r9,r0,r9,LSR#16 + eor r6,r6,#0x8000 + eor r7,r7,#0x8000 + eor r8,r8,#0x8000 + eor r9,r9,#0x8000 + + pop {r0, r3, r4} ; Recupera r3, r4 y r0 desde el stack. + + ; Store the outputs + stmia r0!,{r6,r7,r8,r9} ; Guarda r6-4 en r0. r0 queda apuntando al proximo valor. + + subs r3,r3,#4 ; hoisted up to avoid pipe delay before branch + ; r3 = r3 - 4 + + ; Reset Coeffs to start + sub r2,r2,r4,LSL#2 ; r2 = r2 - (r4 * 4) + + ; Walk along the input data by 4 samples each LoopSample iteration + sub r1,r1,r4,LSL#2 ; r1 = r1 - (r4 * 4) + + bne LoopSample ; Se terminaron las muestras de entrada? + + pop {r4-r12,lr} ; Restauro registros a su estado inicial. + bx lr ; Return + + end \ No newline at end of file