📄 cfft32c.asm
字号:
ADDL ACC,P<<PM ; ACC=(PR+QR*WR+QI*WI)/2 WR PR QR WR+n WI+n
MOVL *XAR6++,ACC ; PR'=(PR+QR*WR+QI*WI)/2 WR PI QR WR+n WI+n
SUBL P,ACC ; P=(PR-QR*WR-QI*WI)/2 WR PI QR WR+n WI+n
MOVL *XAR2++,P ; QR'=(PR-QR*WR-QI*WI)/2 WR PI QI WR+n WI+n
MOVL ACC,XAR5 ; ACC=(QI*WR-QR*WI)/2 WR PI QI WR+n WI+n
MOVL P,*XAR6 ; P=PI WR PI QI WR+n WI+n
ADDL ACC,P<<PM ; ACC=(PI+QI*WR-QR*WI)/2 WR PI QI WR+n WI+n
MOVL *XAR6++,ACC ; (PI+QI*WR-QR*WI)/2 WR PR+1 QI WR+n WI+n
SUBL P,ACC ; P=(PI-QI*WR+QR*WI)/2 WR PR+1 QI WR+n WI+n
MOVL *XAR2++,P ; QI'=(PI-QI*WR+QR*WI)/2 WR PR+1 QR+1 WR+n WI+n
.endm
;----------------------------------------------------
; MACRO 'COMBO' SPM set to 1bit right shift
; Number of WORDS/Number of Cycles 33
; USAGE: RADIX 4 USED AT THE FIRST STAGE
;
; REGISTER USED: XAR0,XAR1,XAR2,XAR3,XAR4,XAR5,XAR6,ACC,XT,P
;
; POINTERS AT ENTRY
; AR6->(R1,I1)
; AR2->(R2,I2)
; AR3->(R3,I3)
; AR4->(R4,I4)
; AR5-> Temporary Variable
; CALCULATION PERFORMED: INPLACE COMPUTATION
; AR6 -> R1'=(R1+R2+R3+R4)/4
; AR2 -> R2'=(R1-R2+I3-I4)/4
; AR3 -> R3'=(R1+R2-R3-R4)/4
; AR4 -> R4'=(R1-R2-I3+I4)/4
; AR6+1 -> I1'=(I1+I2+I3+I4)/4
; AR2+1 -> I2'=(I1-I2-R3+R4)/4
; AR3+1 -> I3'=(I1+I2-I3-I4)/4
; AR4+1 -> I4'=(I1-I2+R3-R4)/4
; POINTERS AT EXIT
; AR6->(R5,I5)
; AR2->(R6,I6)
; AR3->(R7,I7)
; AR4->(R8,I8)
;---------------------------------------------------
; (Content of REG after exec.)
COMBO .macro ; AR6 AR2 AR3 AR4
MOVL ACC,*XAR3 ; ACC=R3 R1 R2 R3 R4
SFR ACC,#1 ; ACC=R3/2
MOVL P,*XAR4 ; P=R4
SUBL ACC,P<<PM ; ACC=(R3-R4)/2
MOVL XT,ACC ; T=(R3-R4)/2
ADDL ACC,P ; ACC=(R3+R4)/2
MOVL XAR1,ACC ; XAR1=(R3+R4)/2
MOVL ACC,*XAR6 ; ACC=R1
SFR ACC,#1 ; ACC=R1/2
MOVL P,*XAR2 ; P=R2
SUBL ACC,P<<PM ; ACC=R1-R2/2
MOVL *-SP[TEMP],ACC ; temp=(R1-R2)/2
ADDL ACC,*XAR2 ; ACC=(R1+R2)/2
SFR ACC,#1 ; ACC=(R1+R2)/4
MOVL P,XAR1 ; P=(R3+R4)/2
ADDL ACC,P<<PM ; ACC=(R1+R2+R3+R4)/4
MOVL *XAR6++,ACC ; R1'=(R1+R2+R3+R4)/4
SUBL ACC,P ; ACC=(R1+R2-R3-R4)/4
MOVL *XAR3++,ACC ; R3'=(R1+R2-R3-R4)/4
MOVL ACC,*XAR3 ; ACC=I3
SFR ACC,#1 ; ACC=I3/2
MOVL P,*+XAR4[2] ; P=I4
SUBL ACC,P<<PM ; ACC=(I3-I4)/2
MOVL XAR1,ACC ; XAR1=(I3-I4)/2
ADDL ACC,P ; ACC=(I3+I4)/2
MOVL XAR5,ACC ; XAR5=(I3+I4)/2
MOVL ACC,*-SP[TEMP] ; ACC=(R1-R2)/2
SFR ACC,#1 ; ACC=(R1-R2)/4
MOVL P,XAR1 ; P=(I3-I4)/2
ADDL ACC,P<<PM ; ACC=(R1-R2+I3-I4)/4
MOVL *XAR2++,ACC ; R2'=(R1-R2+I3-I4)/4
SUBL ACC,P ; ACC=(R1-R2-I3+I4)/4
MOVL *XAR4++,ACC ; R4'=(R1-R2-I3+I4)/4
MOVL ACC,*XAR6 ; ACC=I1
SFR ACC,#1 ; ACC=I1/2
MOVL P,*XAR2 ; P=I2
SUBL ACC,P<<PM ; ACC=(I1-I2)/2
MOVL *-SP[TEMP],ACC ; temp=(I1-I2)/2
ADDL ACC,P ; ACC=(I1+I2)/2
SFR ACC,#1 ; ACC=(I1+I2)/4
MOVL P,XAR5 ; P=(I3+I4)/2
ADDL ACC,P<<PM ; ACC=(I1+I2+I3+I4)/4
MOVL *XAR6,ACC ; I1'=(I1+I2+I3+I4)/4
NOP *0++
SUBL ACC,P ; ACC=(I1+I2-I3-I4)/4
MOVL *XAR3,ACC ; I3'=(I1+I2-I3-I4)/4
NOP *0++
MOVL ACC,*-SP[TEMP] ; ACC=(I1-I2)/2
SFR ACC,#1 ; ACC=(I1-I2)/4
MOVL P,XT ; P=(R3-R4)/2
ADDL ACC,P<<PM ; ACC=ACC=(I1-I2+R3-R4)/4
MOVL *XAR4,ACC ; I4'=(I1-I2+R3-R4)/4
NOP *0++
SUBL ACC,P ; ACC=(I1-I2-R3+R4)/4
MOVL *XAR2,ACC ; I2'=(I1-I2-R3+R4)/4
NOP *0++
.endm
;====================================================================
; Function Local Frame
;====================================================================
; |_______|
; |_______|<- Stack Pointer (SP) <---SP
; |_______|<- GLCB (SP-1)
; |_______|<- BLC (Butterfly loop counter) (SP-2)
; |_______|<- GLC (Group loop counter) (SP-3)
; |_______|<- SLC (Stage loop counter) (SP-4)
; |_______|<- TOST (Twiddle offset, for decimation) (SP-5)
; |_______|<- DOST (Data offset) (SP-6)
; |_______|<- TEMP (SP-7) & (SP-8)
;===================================================================
FFT_LOCAL_FRAME .set 10
GLCB .set 1
BLC .set 2
GLC .set 3
SLC .set 4
TOST .set 5
DOST .set 6
TEMP .set 8
WRWIOST .set 9
_CFFT32_calc:
PUSH XAR1 ; Context Save
PUSH XAR2
PUSH XAR3
ADDB SP,#FFT_LOCAL_FRAME ; Create Local Frame
SETC SXM
SPM -1 ; SPM set to 1bit right shift
MOVL XAR7,XAR4 ; XAR7->FFT_handle
MOVL XAR2,*XAR7 ; XAR2=ipcbptr
MOVL XAR3,XAR2 ; XAR3=ipcbptr
MOVL XAR4,XAR2 ; XAR4=ipcbptr
MOVL XAR6,XAR2 ; XAR6=ipcbptr
ADDB XAR2,#4 ; XAR2=ipcbptr+4
ADDB XAR3,#8 ; XAR3=ipcbptr+8
ADDB XAR4,#12 ; XAR4=ipcbptr+12
MOVB XAR0,#14 ; XAR0=14
;-----------------------------------------------------------------
; Stage 1 & 2 - Using the RADIX 4 COMBO Macro
;-----------------------------------------------------------------
MOVL *-SP[2],XAR7 ; (SP-2)=FFT_handle
MOV ACC,*+XAR7[4]<<14
SUB ACC,#1<<14
MOV AR7,AH ; Loop (N/4 - 1) times
STAGE1_2_LP:
COMBO
BANZ STAGE1_2_LP,AR7--
;------------------------------------------------------------------
; Stage 3 - Using ZEROI, PBY4I,PBY2I,P3BY4I Macros
;------------------------------------------------------------------
MOVL XAR7,*-SP[2] ; XAR7=FFT_handle
MOVL XAR6,*XAR7 ; XAR6=ipcbptr
MOVL XAR2,*XAR7 ; XAR2=ipcbptr
ADDB XAR2,#16 ; XAR2=ipcbptr+16
MOVB XAR0,#18
MOV AL,#COS45K_LSW
MOV AH,#COS45K_MSW
MOVL XT,ACC ; XT=COS(45) in Q31 format
MOV ACC,*+XAR7[4]<<13
SUB ACC,#1<<13
MOV AR1,AH ; Loop (N/8 - 1) times
STAGE3_LP: ZEROI
PBY4I
PBY2I
P3BY4I ; AR7 at end, Use *0+ modify
BANZ STAGE3_LP,AR1--
;--------------------------------------------------------
; Stage 4 to LOG2(N) - Using BFLY Macro
;--------------------------------------------------------
; Initialisation
; 1. Initialise the Butterfly loop(BLC), Group loop(GLC) & Stage loop counter(SLC)
; 2. Initialise the Data offset(DOST) and twiddle factor offset (TOST)
MOV ACC,*+XAR7[4]<<12 ; AH=(N/16)
MOV *-SP[GLCB],AH ; GLCB=N/16
MOV *-SP[GLC],AH ; GLC=N/16
MOVB *-SP[BLC],#8,UNC; BLC=8
; Twiddle factor offset
LSL ACC,#1
MOV T,AH ; T=N/8
ADDB XAR7,#13
MPY ACC,T,*XAR7 ; ACC=ratio*N/8
SUBB XAR7,#13
MOV *-SP[TOST],AL ; TOST=ratio*N/8
MOV ACC,*+XAR7[5] ; ACC=nrstage
SUB ACC,#3 ; ACC=nrstage-3
MOV *-SP[SLC],AL ; SLC=nrState-3
MOVB *-SP[DOST],#32,UNC ; DOST=32
MOV ACC,*+XAR7[4]<<15 ; AH=N/2
ADDB XAR7,#13
MOV T,*XAR7 ; T=ratio
SUBB XAR7,#13
MPY ACC,T,AH ; ACC=ratio*N/2
ADDL ACC,*+XAR7[2] ;
MOVL *-SP[WRWIOST],ACC ; WRWIOST=tfptr+ratio*N/2 ----> COS(Angle)
SLP: ; Stage loop
MOVL XAR6,*XAR7 ; XAR6=ipcbptr -----> P
MOVL ACC,*XAR7 ; ACC=ipcbptr
ADD ACC,*-SP[DOST] ; ACC=ipcbptr+DOST
MOVL XAR2,ACC ; XAR2->ipcbptr+DOST -----> Q
MOVZ AR0,*-SP[TOST] ; AR0=TOST
GLP: ; Group loop
MOVL XAR3,*-SP[WRWIOST]
MOVL XAR4,*+XAR7[2] ; XAR4=tfptr ---> SIN(Angle)
MOVZ AR1,*-SP[BLC] ; AR1=BLC
SUBB XAR1,#1
BLP: ; Butterfly loop
BFLY 7
BANZ BLP,AR1-- ; Butterfly loop
; Operations performed between the group
; 1. Manuplating the P & Q pointer to point to the next group
; 2. Reinitialising the WI and WR twiddle factor pointer
; 3. Decrementing the Group Count by 1, till all the group in the stage is computed
; 4. Reinitialising the Butterfly loop index for next group
; ARP=AR2
MOVU ACC,*-SP[DOST] ; ACC=DOST
ADDL XAR6,ACC
ADDL XAR2,ACC
DEC *-SP[GLC]
BF GLP,NEQ ; Group Loop
; Operation Performed, between the stage
; 1. Mutiply the data offset by 2
; 2. Divide the Group count by 2
; 3. Divide the Twiddle offset by 2
; 4. Multiply the butterfly count by 2
; 5. Decrementing the stage count by 1, till all the stage gets over
; 6. Reinitialising the P & Q data pointer to the first group of next stage
MOV ACC,*-SP[DOST]<<1
MOV *-SP[DOST],AL ; DOST=DOST*2
MOV ACC,*-SP[BLC]<<1
MOV *-SP[BLC],AL ; BLC=BLC*2
MOV ACC,*-SP[TOST]<<15
MOV *-SP[TOST],AH ; TOST=TOST/2
MOV ACC,*-SP[GLCB]<<15
MOV *-SP[GLCB],AH ; GLCB=GLCB/2
MOV *-SP[GLC],AH ; GLC=GLCB/2
DEC *-SP[SLC]
BF SLP,NEQ ; Stage loop
SPM 0 ; SPM set to 0
SUBB SP,#FFT_LOCAL_FRAME ; Clear local frame
POP XAR3 ; Context Restore
POP XAR2
POP XAR1
LRETR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -