⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iir16_mac.s

📁 freescale MAC DSP的算法库(FFT
💻 S
字号:
;*********************************************
;* Freescale Semiconductor Inc.
;* (c) Copyright 2001 Freescale Semiconductor Inc.
;* ALL RIGHTS RESERVED.
;*********************************************
;* FILE NAME: iir16.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	_IIR16_MAC
;******************************************************
;* NAME: void IIR16( struct tIirStruct *pIIR, Frac16* pX, Frac16* pY, unsigned int n)
;*
;* DESCRIPTION: Computes a Infinite Impulse Response (IIR) filter for a array of 16-bit fractional data values.
;******************************************************
;* Used registers:
;*	a2       pIIR	- Pointer to a data structure containing private data for the IIR filter
;*	68(a7)   pX		- Pointer to the input array of n data elements
;*	72(a7)   pY		- Pointer to the output array of n data elements
;*	d6       n		- Length of the input and output vectors
;*	d2       k		- Counter for inner loop
;*	d1       i		- Counter for outer loop
;*	d0       N		- Length of coefficients array(N<=n)
;*	a0       pCurY	- Pointer to the current Y
;*	a1       pCurX	- Pointer to the current X
;*	a3       pCurCoef	- Pointer to the current coefficient -> {a0,a1,b1,a2,b2...}
;*	a4       pCurHistory - Pointer to the current element of history buffer
;*	a5       pPredY  	- Pointer to the previous Y
;*	acc      output	- Accumulator
;******************************************************
_IIR16_MAC:
;---=Saving values of used registers=---
	lea -60(a7),a7
	movem.l d0-d7/a0-a6,(a7)
;---=Most useful parameters are moved from stack to registers.=---	
	move.l 76(a7),d6        ;	n				- Length of the input and output vectors
	move.l 72(a7),a0        ; 	pCurY=pY;			- Pointer to the current Y.
	move.l 64(a7),a2        ; 	-=N=pIIR->iIirCoefCount/2+1;=-
	move.l 4(a2),d0
	lsr.l	#1,d0
	addq.l #1,d0
;---====== 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 .ENDFORi1           ; 	{                         -=If (i=>N) then jump to .ENDFORi1=-
	move.l #0,acc           ;	output=0;                 -=Accumulator initialization=-
	move.l 68(a7),a6        ; 	pCurX=pX+i-1;		  -=Current sample pointer initialization=-
	lea (0,a6,d1.l*2),a1
	move.l 72(a7),a6        ; 	pPredY=pY+i-2;            -=Previous Y pointer initialization=-
	lea (-2,a6,d1.l*2),a5
	;---== Begin of cycle Getting Y[i] ==---
	move.l (a2),a3          ; 	pCurCoef=pIIR->pIirCoef;  -=Current coefficient pointer initialization=-
	;-=output=*pCurX--*(*pCurCoef++);=-
	move.w -(a1),d3         ;                               -=Getting current sample=-
	move.w (a3)+,d4         ;                               -=Getting current coefficient=-
	mac.w	d3.l,d4.l,<<      ;                               -=Getting first iteration of inner loop=-
	moveq	#1,d2             ; 	for(k=1;k<i;k++)          -=Begin of inner loop=-
	move.l (a3)+,d4         ;                               -=Getting next current coefficient=-
.FORk1:                       ; 	{
	cmp.l	d1,d2             ;                               -=Comparing "k" with "i"=-
	bcc .ENDFORk1           ;                               -=If (k=>i) then jump to .ENDFORk1=-
	;-=use move long, parallel filling register,
	;  predecriment and post increment and use left shifting to get fractional multiplication=-	
	;-=output+=*pCurX--*(*pCurCoef++);=-
	move.w -(a1),d3         ;                               -=Getting next current sample=-
	mac.w	d3.l,d4.u,<<      ;                               -=First MAC=-
	;-=output+=*pPredY--*(*pCurCoef++);=-
	move.w -(a5),d3         ;                               -=Getting previous Y=-
	mac.w	d3.l,d4.l,<<,(a3)+,d4;                            -=Second MAC and getting next current coefficient=-

	addq.l  #1,d2           ;                               -=Incrementing "k"=-
	bra .FORk1              ;                               -=Jumping to .FORk1=-
.ENDFORk1:                    ; 	}//for(k=1)
;---==Testing that History Buffer is filled => this is not first calling of this function==--	
	tst.l	12(a2)            ; 	if(pIIR->iIirHistoryCount>0)    -=Testing that pFIR->iFirHistoryCount>0=-
	beq .ENDFORk2           ; 	{                               -=If (pFIR->iFirHistoryCount=0) then jump to .ENDFORk2=-
	move.l 8(a2),a6         ; 	pCurHistory=pIIR->pIirHistory+pIIR->iIirHistoryCount-1;
	move.l 12(a2),d7
	lea (0,a6,d7.l*2),a4
	move.l d1,d2            ; 	for(k=i;k<N;k++)                -=Begin of inner loop=-	
.FORk2:
	cmp.l	d0,d2             ;                                     -=Comparing "k" with "N"=-
	bcc  .ENDFORk2          ; 	{                               -=If (k=>N) then jump to .ENDFORk2=-
	;-=use move long, parallel filling register,
	;  predecriment and post increment and use left shifting to get fractional multiplication=-
	;-=output+=*pCurHistory--*(*pCurCoef++);=-
	move.l -(a4),d3         ;                                     -=Getting next current element of history buffer=-
	mac.w	d3.u,d4.l,<<      ;                                     -=First MAC=-
	;-=output+=*pCurHistory--*(*pCurCoef++);=-
	mac.w	d3.l,d4.u,<<,(a3)+,d4; 	                                -=Second MAC and getting next current coefficient=-
	addq.l #1,d2            ;                                     -=Incrementing "k"=-
	bra .FORk2              ; 	}//for(k=i)                     -=Jumping to .FORk2=-
.ENDFORk2:                    ; 	}
;---== 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=-
.ENDFORi1:                    ; 	}//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 .ENDFORi2           ; 	{                               -=If (i>n) then jump to .ENDFORi2=-
	move.l #0,acc           ; 	output=0;                       -=Accumulator initialization=-
	move.l 68(a7),a6        ; 	pCurX=pX+i-1;                   -=Current sample pointer initialization=-
	lea (0,a6,d1.l*2),a1
	move.l 72(a7),a6        ; 	pPredY=pY+i-2;                  -=Previous Y pointer initialization
	lea (-2,a6,d1.l*2),a5
	move.l (a2),a3          ; 	pCurCoef=pIIR->pIirCoef;        -=Current coefficient pointer initialization=-
;---== Begin of cycle Getting Y[i] ==---
    ;  -=output=*pCurX--*(*pCurCoef++);=-
	move.w -(a1),d3         ;                                     -=Getting current sample=-
	move.w (a3)+,d4         ;                                     -=Getting current coefficient=-
	mac.w	d3.l,d4.l,<<      ;                                     -=Getting first iteration of inner loop=-
	moveq	#1,d2             ; 	for(k=1;k<N;k++)                -=Begin of inner loop=-
	move.l (a3)+,d4         ;                                     -=Getting next current coefficient=-
.FORk3:
	cmp.l	d0,d2             ;                                     -=Comparing "k" with "N"=-
	bcc .ENDFORk3           ; 	{                               -=If (k=>N) then jump to .ENDFORk3=-
	;-=use move long, parallel filling register,
	;  predecriment and post increment and use left shifting to get fractional multiplication=-
	;-=output+=*pCurX--*(*pCurCoef++);=-
	move.w -(a1),d3         ;                                     -=Getting next current sample=- 	
	mac.w	d3.l,d4.u,<<      ;                                     -=First MAC=-
	;-=output+=*pPredY--*(*pCurCoef++);=-
	move.w -(a5),d3         ;                                     -=Getting previous Y=-	
	mac.w	d3.l,d4.l,<<,(a3)+,d4;                                  -=Second MAC and getting next current coefficient=-

	addq.l #1,d2            ;                                     -=Incrementing "k"=-
	bra .FORk3              ;                                     -=Jumping to .FORk3=-
.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 .FORi1=-
.ENDFORi2:                    ; 	}//for(i)
;---====== End of cycle Y[N]..Y[n] ======---
;---====== Begin of History Buffer Loading ======---
	move.l 68(a7),a6        ;	-=pCurX=pX+n-N+1;=-
	move.l d6,d7
	sub.l	d0,d7
	lea (2,a6,d7.l*2),a1
	move.l 72(a7),a6        ; 	pCurY=pY+n-N+1;
	lea (2,a6,d7.l*2),a0	;
	move.l 8(a2),a4         ; 	pCurHistory=pIIR->pIirHistory;
	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.l a0,a6            ;        *pCurHistory++=*pCurY++;
	addq.l #2,a0
	move.w (a6),(a4)+
	move.w (a1)+,(a4)+      ;	*pCurHistory++=*pCurX++;
	addq.l #1,d1            ;                                    -=Incrementing "i"=-
	bra .FORbuf             ;                                    -=Jumping to .FORbuf=-
.ENDbuf:                      ; 	}
	move.l 4(a2),d7         ;	pIIR->iIirHistoryCount=pIIR->iIirCoefCount-1;
	subq.l #1,d7
	move.l d7,12(a2)        ;}//end				       -=setting pFIR->iFirHistoryCount by pIIR->iIirCoefCount-1 =-
;---====== End of History Buffer Loading ======--
;-=Restoring values of used registers=-
	movem.l (a7),d0-d7/a0-a6 	
	lea 60(a7),a7

	rts


	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -