?? fir16_mac.s
字號:
;*********************************************
;* Freescale Semiconductor Inc.
;* (c) Copyright 2001 Freescale Semiconductor Inc.
;* ALL RIGHTS RESERVED.
;*********************************************
;* FILE NAME: fir16.s
;*********************************************
;!! These functions are "hand coded" in assembler and
;!! the C source is used as comments for short and clear description.
;!! C code used only for more clear andestending what assembler code do, where it is possible.
// .section .dspcode,4,c ;-=Locate the code in the ".dspcode" section.=-
.section .text ;-=Locate the code in the ".text" section.=-
.ALIGN 4
.XDEF _FIR16_MAC
;******************************************************
;* NAME: void FIR16(struct tFir16Struct* pFIR, Frac16* pX, Frac16* pY, unsigned int n)
;*
;* DESCRIPTION: Computes a Finite Impulse Response for a array of 16-bit fractional data values.
;******************************************************
;* Used registers:
;* 64(a7) a2 pFIR - Pointer to a data structure containing private data for the FIR filter.
;* 68(a7) a5 pX - Pointer to the input array of n data elements.
;* 72(a7) pY - Pointer to the output array of n data elements.
;* 76(a7) d6 n - Length of the input and output arrays.
;* d0 N - Length of coefficients vector(N<=n).
;* d1 i - Counter for outer loop.
;* d2 k - Counter for inner loop.
;* a0 pCurY - Pointer to the current Y.
;* a1 pCurX - Pointer to the current X.
;* a3 pCurCoef - Pointer to the current coefficient.
;* a4 pCurHistory - Pointer to the current element of history buffer.
;* a6 pFIR->pFirHistory - History buffer.
;* acc output - Accumulator.
;******************************************************
_FIR16_MAC:
;---=Saving values of used registers.=---
lea -60(a7),a7
movem.l d0-d7/a0-a6,(a7)
;---=Moving of most useful parameters from stack to registers.=---
move.l 76(a7),d6 ;n - Length of the input and output arrays.
move.l 72(a7),a0 ;pCurY - Pointer to the current Y.
move.l 68(a7),a5 ;pX - Pointer to the input array of n data elements.
move.l 64(a7),a2 ;pFIR - Pointer to a data structure containing private data for the FIR filter.
move.l 4(a2),d0 ;N - Length of coefficients vector.
move.l 8(a2),a6 ;pFIR->pFirHistory - History buffer.
;---====== Begin of cycle of getting Y[1]..Y[N-1] ======---
moveq #1,d1 ; for(i=1;i<N;i++) -=Begin of outer loop (number 1)=-
.FORi1:
cmp.l d0,d1 ; -=Comparing "i" with "N"
bcc .NEXTi1 ; { -=If (i=>N) then jump to .NEXTi1=-
move.l #0,acc ; output=0; -=Accumulator initialization=-
lea (0,a5,d1.l*2),a1 ; pCurX=pX+i; -=Current sample pointer initialization=-
move.l (a2),a3 ; pCurCoef=pFIR->pFirCoef; -=Current coefficient pointer initialization=-
;---== Begin of cycle Getting Y[i] ==---
moveq #0,d2 ; k=0 -=Begin of inner loop=-
btst #0,d1 ; -=Testing that "i" is even or not=-
beq .EVENk1 ; -=If "i" is even then jump to .EVENk1=-
;-=we do this omly in case of "i" is odd number=-
move.w (a3)+,d4 ; -=Getting current coefficient=-
move.w -(a1),d3 ; -=Getting current sample=-
mac.w d3.l,d4.l,<< ; -=Getting first iteration of inner loop=-
addq.l #1,d2 ; -=Incrementing "k"=-
.EVENk1:
move.l (a3)+,d4 ; -=Getting next current coefficient=-
.FORk1: ; for(k=0;k<i;k++) -=Begin of main part of inner loop=-
cmp.l d1,d2 ; { -=Comparing "k" with "i"=-
bcc .ENDFORk1 ; -=If (k=>i) then jump to .ENDFORk1=-
;-=In one program loop we do two MAC operation = 2 FIR inner loop itteration;
; use move long, parallel filling register,
; predecriment and post increment and use left shifting to get fractional multiplication=-
;-=output+=*pCurX--*(*pCurCoef++)=-
move.l -(a1),d3 ; -=Getting next current sample=-
mac.w d3.u,d4.l,<< ; -=First MAC=-
mac.w d3.l,d4.u,<<,(a3)+,d4 ; -=Second MAC and getting next current coefficient=-
addq.l #2,d2 ; -=Incrementing "k" by 2=-
bra .FORk1 ; } -=Jumping to .FORk1=-
.ENDFORk1:
subq.l #4,a3 ; -=Restoring pointer to the current coefficient=
;---==Testing that History Buffer is filled => this is not first calling of this function==--
tst.l 12(a2) ; if(pFIR->iFirHistoryCount>0) -=Testing that pFIR->iFirHistoryCount>0=-
beq .NEXTif ; { -=If (pFIR->iFirHistoryCount=0) then jump to .NEXTif=-
lea (-2,a6,d0.l*2),a4 ; pCurHistory=pFIR->pFirHistory+N-2;
move.l d1,d2 ; -= k=i.Begin of inner loop=-
move.l d0,d7
sub.l d1,d7
btst #0,d7 ; -=Testing that "N-i" is even or not=-
beq .EVENk2 ; -=If "N-i" is even then jump to .EVENk2=-
;-=we do this omly in case of "N-i" is odd number=-
move.w (a3)+,d4 ; -=Getting current coefficient=-
move.w -(a4),d5 ; -=Getting current element of history buffer=-
mac.w d5.l,d4.l,<< ; -=Getting next(first) iteration of inner loop=-
addq.l #1,d2 ; -=Incrementing "k"=-
.EVENk2:
move.l (a3)+,d4 ; -=Getting next current coefficient=-
.FORk2: ; for(k=i;k<N;k++) -=Begin of main part (2) of inner loop=-
cmp.l d0,d2 ; -=Comparing "k" with "N"=-
bcc .NEXTif ; { -=If (k=>N) then jump to .NEXTif=-
;-=In one program loop we do two MAC operation = 2 FIR inner loop itteration;
; use move long, parallel filling register,
; predecriment and post increment and use left shifting to get fractional multiplication=-
;-=output+=*pCurHistory--*(*pCurCoef++)=-
move.l -(a4),d5 ; -=Getting next current element of history buffer=-
mac.w d5.u,d4.l,<< ; -=First MAC=-
mac.w d5.l,d4.u,<<,(a3)+,d4; -=Second MAC and getting next current coefficient=-
addq.l #2,d2 ; -=Incrementing "k" by 2=-
bra .FORk2 ; } -=Jumping to .FORk2=-
.NEXTif: ; }//iFirHistoryCount>0
;---== End of cycle of getting Y[i] ==---
move.l acc,d7 ; *pCurY++=output; -=Moving accumulator to general register=-
;-=we need to transfer only upper word=-
swap d7 ; -=Aligning most significant 16 bits of acc=-
move.w d7,(a0)+ ; -=Store Y[i]=-
addq.l #1,d1 ; i++ -=Incrementing "i"=-
bra .FORi1 ; -=Jumping to .FORi1=-
.NEXTi1: ; }//for(i)
;---====== End of cycle Y[1]..Y[N-1] ======---
;---====== Begin of cycle of getting Y[N]..Y[n] ======---
move.l d0,d1 ; for(i=N;i<=n;i++) -=Begin of outer loop (number 2)=-
.FORi2:
cmp.l d6,d1 ; -=Comparing "i" with "N"=-
bhi .NEXTi2 ; { -=If (i>n) then jump to .NEXTi2=-
move.l #0,acc ; output=0; -=Accumulator initialization=-
lea (0,a5,d1.l*2),a1 ; pCurX=pX+i-1; -=Current sample pointer initialization=-
move.l (a2),a3 ; pCurCoef=pFIR->pFirCoef; -=Current coefficient pointer initialization=-
;---== Begin of cycle of getting Y[i] ==---
moveq #0,d2 ; k=0 -=Begin of inner loop=-
btst #0,d0 ; -=Testing that "N" is even or not=-
beq .EVENk3 ; -=If "N" is even then jump to .EVENk3=-
;-=we do this omly in case of "N" is odd number=-
move.w (a3)+,d4 ; -=Getting current coefficient=-
move.w -(a1),d3 ; -=Getting current sample=-
mac.w d3.l,d4.l,<< ; -=Getting first iteration of inner loop=-
addq.l #1,d2 ; -=Incrementing "k"=-
.EVENk3:
move.l (a3)+,d4 ; -=Getting next current coefficient=-
.FORk3: ; for(k=0;k<N;k++) -=Begin of main part of inner loop=-
cmp.l d0,d2 ; { -=Comparing "k" with "N"=-
bcc .ENDFORk3 ; -=If (k=>N) then jump to .ENDFORk3=-
;-=In one program loop we do two MAC operation = 2 FIR inner loop itteration;
; use move long, parallel filling register,
; predecriment and post increment and use left shifting to get fractional multiplication=-
;-=output+=*pCurX--*(*pCurCoef++);=-
move.l -(a1),d3 ; -=Getting next current sample=-
mac.w d3.u,d4.l,<< ; -=First MAC=-
mac.w d3.l,d4.u,<<,(a3)+,d4; -=Second MAC and getting next current coefficient=-
addq.l #2,d2 ; -=Incrementing "k" by 2=-
bra .FORk3 ; } -=Jumping to .FORk1=-
.ENDFORk3:
;---== End of cycle of getting Y[i] ==---
move.l acc,d7 ; *pCurY++=output; -=Moving accumulator to general register=-
;-=we need to transfer only upper word=-
swap d7 ; -=Aligning most significant 16 bits of acc=-
move.w d7,(a0)+ ; -=Store Y[i]=-
addq.l #1,d1 ; i++ -=Incrementing "i"=-
bra .FORi2 ; -=Jumping to .FORi2=-
.NEXTi2: ; }//for(i)
;---====== End of cycle Y[N]..Y[n] ======---
;---====== Begin of History Buffer Loading ======---
move.l d6,d7 ; -=pCurX=pX+n-N+1;=-
sub.l d0,d7
lea (2,a5,d7.l*2),a1
move.l a6,a4 ; pCurHistory=pFIR->pFirHistory;
moveq #1,d1 ; for(i=1;i<N;i++) -= i=1 =-
.FORbuf:
cmp.l d0,d1 ; -=Comparing "i" with "N"=-
bcc .ENDbuf ; { -=If (i=>N) then jump to .ENDbuf=-
move.w (a1)+,(a4)+ ; *pCurHistory++=*pCurX++;
addq.l #1,d1 ; -=Incrementing "i"=-
bra .FORbuf ; -=Jumping to .FORbuf=-
.ENDbuf: ; }
subq.l #1,d1 ; pFIR->iFirHistoryCount=N-1;
move.l d1,12(a2) ; }//end -=setting pFIR->iFirHistoryCount by N-1 =-
;---====== End of History Buffer Loading ======---
;-=Restoring values of used registers=-
movem.l (a7),d0-d7/a0-a6
lea 60(a7),a7
rts
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -