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

📄 fft.asm

📁 同样是浮点型的fft算法一样为vc开发的
💻 ASM
字号:
;Fuction:   实现dif基2的复数FFT运算
	.mmregs
;    .cpl_on
    .include "Rx_twiddle.inc"
	.bss  temp_fft,2
;	.ref  _twiddle
;//-----------------------------------------------------------------------------
;// Program section
;//-----------------------------------------------------------------------------

    .sect ".fftcode"
	.global  _cfft
;  	.text
_cfft:
;//-----------------------------------------------------------------------------
;// Context save / get arguments将子程序所用寄存器进行压站保护
;//-----------------------------------------------------------------------------
        PSH	mmap(ST1_55)
        PSH	mmap(ST2_55)  

        AADD	#-17, SP                            ; create local frame 
        
        MOV	XAR0, dbl(*SP(#0))                   	; SP(#0) is xy 
        MOV	pair(T0), dbl(*SP(#2))                  ; SP(#2) is nx, SP(#3) is scale
        MOV	XAR5, dbl(*SP(#4))                      ; save on entry
        MOV	XAR6, dbl(*SP(#6))                      ; save on entry
        MOV	XAR7, dbl(*SP(#8))                      ; save on entry
        MOV	pair(T2), dbl(*SP(#10))                 ; save on entry
                                                    ; SP(#12) is tempmem
                                                    ; SP(#14) is tempmem1
;//-----------------------------------------------------------------------------
;// Initialization code  
;//-----------------------------------------------------------------------------

Initialize:                                                
	OR    #010FH,mmap(ST2_55)      				;CDP,AR0,AR1,AR2,AR3设置为循环寻址
	MOV   XAR0,XAR1							    ;向量FFT_VECTOR.
	MOV   XAR0,XAR2
	MOV   XAR0,XAR3
	MOV   mmap(AR2),BSA23        				;设置BSA23
	MOV   mmap(AR2),BSA01        				;设置BSA01
	AMOV  #ctwiddle,XCDP  						;CDP指向旋转因子
	MOV   CDP,mmap(BSAC)         			    ;设置BSAC。        (twiddle)
	MOV   #0,AR1                 				;AR1的初始偏移为0
	MOV   #0,AR2                 				;AR2的初始偏移为0
	MOV   #2,AR3                 				;AR3的初始偏移为2

	MOV   #0,CDP                 				;CDP的初始偏移为0。
	AMOV  #temp_fft,XAR6         				;AR6指向一个分配的临时区
	MOV   XAR6,XAR7              				;AR7也指向一个分配的临时区
	ADD   #1,AR7                 				;AR7指针加1
	MOV   #512,T0                  				;FFT变换的长度为LENGTH
	MOV   mmap(T0),BKC                 			;系数存储器的长度为LENGTH
	SUB   #2,T0,T1
	MOV   T1,CSR                 				;CSR循环计数器为(LENGTH-2)
	MOV   T0,T3
	SFTL  T3,#-1                 				;T3=(LENGTH/2)
	SUB   #2,T3,T1
	MOV   mmap(T1),BRC0          				;外循环计数器为(LENGTH/2-2)
	SFTL  T0,#1
	MOV   mmap(T0),BK03                  		;输入数据存储器的长度为2*LENGTH
	MOV   #4,T1
;-------------------------------------------------------------------------------
;基2(DIF)-第一级变换
;-------------------------------------------------------------------------------
    MOV   #0,mmap(AR0)
    ;MOV	#1, BRC0
    ;RPTBLOCAL	first_stage
    MOV   dbl(*AR0+),AC0                ;为了防止溢出,变换数据除以2
    RPT   CSR
    MOV   AC0>>#1,dual(*AR1+)
    ||MOV dbl(*AR0+),AC0
    MOV   AC0>>#1,dual(*AR1+)
first_stage:                             ;第一级变换开始
	MOV   dbl(*AR3),AC0
	SUB   AC0,dual(*AR2),AC2
	RPTBLOCAL    fftloop1
	ADD   dual(*AR2),AC0,AC1             ;xi+1(k)=xi(k+1)+xi(k)
	||MOV   AC2,dbl(*AR6) 
	
	MPY   *AR6,*CDP+,AC2                 ;xi+1(k+1)=(xi(k)-xi+1(k))*WN
	::MPY *AR7,*CDP+,AC3                 ;xi(k)-xi(k+1)
	MOV   AC1,dbl(*(AR2+T1))             ;保存xi+1(k)到AR2所指的k位置
	MOV   dbl(*AR3(T1)),AC0
	
	MASR  *AR6,*CDP+,AC3
	::MACR *AR7,*CDP+,AC2
	MOV   pair(HI(AC2)),dbl(*(AR3+T1))   ;保存xi+1(k+1)到AR3所指的k+1位置
	||SUB   AC0,dual(*AR2),AC2
fftloop1:
	ADD	  dual(*AR2), AC0, AC1      
	||MOV AC2, dbl(*AR6)                 ; store tr, ti

    MPY	  *AR6, *CDP+, AC2               ; c*tr
    ::MPY *AR7, *CDP+, AC3               ; c*ti

    MOV	  AC1, dbl(*(AR2+T1))            ; store ar, ai

    MASR  *AR6, *CDP+, AC3  			 ; bi' = c*ti - s*tr 
    ::MACR	*AR7, *CDP+, AC2   			 ; br' = c*tr + s*ti 

    MOV	  pair(HI(AC2)), dbl(*(AR3+T1))  ; store br', bi'  
;-----------------------------------------------------------------
;基2(DIF)-除去第一级后的所有其他级变换
;-----------------------------------------------------------------
radix_2_stages:
	MOV	*SP(#2), AC0
	||SFTS	T3, #-1	                      ;T3=(LENGTH/4)
    SFTS	AC0, #-4          	  			; last two stage shift right by 4
	||SFTS	AR3, #1                       ; pointer to AR3
    MOV	    AC0, AR4
	||MOV  #2, T0
	MOV  #2, T2
outer_loop:
	SUB #1,T3,T1
    MOV	T1, BRC0
    SUB	#2, T2, T1
    MOV	T1, BRC1
    SFTS	T2, #1
    ADD	#2, T2, T1
    SFTS	AR4, #-1
;------------------------------------------------------------------------------------    
    MOV	dbl(*AR0+), AC0                        ; 为了防止溢出,在每一级均需除以2
    RPT	CSR
    MOV	AC0 >> #1, dual(*AR1+) 	
	   ||MOV	dbl(*AR0+), AC0
    MOV	AC0 >> #1, dual(*AR1+)
;--------------------------------------------------------------------------------------	
	RPTBLOCAL  fftloop2 
	MOV	dbl(*AR3), AC0                         	; load ar,ai
	SUB	AC0, dual(*AR2), AC2
	
	RPTBLOCAL	fftloop3
	ADD	dual(*AR2), AC0, AC1
	||MOV	AC2, dbl(*AR6)	
	MOV	AC1, dbl(*AR2+)
	||MOV	dbl(*AR3(T0)), AC0                      ; store tr, ti
	
	MPY	*AR6, *CDP+, AC2 
	::MPY	*AR7, *CDP+, AC3
	
	MASR	*AR6, *CDP-, AC3  					; bi' = c*ti - s*tr
    ::MACR	*AR7, *CDP-, AC2   					; br' = c*tr + s*ti
	MOV	pair(HI(AC2)), dbl(*AR3+)               ; store br', bi'
	||SUB	AC0, dual(*AR2), AC2
	
fftloop3:
	ADD	dual(*AR2), AC0, AC1
	||MOV	AC2, dbl(*AR6)  
	MOV	AC1, dbl(*(AR2+T1)) 
	                	; store ar, ai                    	; store tr, ti
	MPY	*AR6, *CDP+, AC2               			; c*tr
    ::MPY *AR7, *CDP+, AC3                		; c*ti
	
	MASR *AR6, *CDP+, AC3	  					; bi' = c*ti - s*tr	
    ::MACR	*AR7, *CDP+, AC2	   				; br' = c*tr + s*ti	
	MOV	pair(HI(AC2)), dbl(*(AR3+T1))       	; 修改AR3的指针
fftloop2:
	SFTS	AR3, #1
	||MOV	#0, CDP                             ; rewind coefficient pointer
    SFTS	T3, #-1
	||BCC	outer_loop, AR4 != #0
;//-----------------------------------------------------------------------------
;// Radix-4 stage
;//-----------------------------------------------------------------------------

radix_4_stage:

        BCC	no_scale_4, AR5 == #0

	||MOV	#1, BRC0                               ; 2 x scale by 2 is faster  
;	MOV #0,AR0                                     ;更新AR0的值以便进行移位运算
;        RPTBLOCAL	loop4-1
        MOV	dbl(*AR0+), AC0                        ; scale by 2 - prime the pipe
        RPT	CSR
		MOV	AC0 >> #1, dual(*AR1+)
		||MOV	dbl(*AR0+), AC0
		MOV	AC0 >> #1, dual(*AR1+)

loop4:

no_scale_4:

        AND	#0FEF0h, mmap(ST2_55)                  ; linear addr for AR2, AR3, Ar1, AR0

        MOV	dbl(*SP(#0)), XAR0                     ; point to data
        MOV	*SP(#2), T0
        SFTS	T0, #-1                         	; DR0 = 2*nx/4
        MOV	T0, T1                              	; DR1 = 2*nx/4 
        MOV	XAR0, XAR1                            	; AR1 = AR0
        ADD	T1, AR1                         		; AR1 = AR0 + 1*2*nx/4
        MOV	XAR0, XAR2                             ; AR2 = AR0
        ADD	T0, T1                         ; DR1 = 2*(2*nx/4)
        ADD	T1, AR2                          ; AR2 = AR0 + 2*2*nx/4
        MOV	XAR0, XAR3                             ; AR3 = #fftdata
        ADD	T0, T1                         ; DR1 = 3*(2*nx/4)
        ADD	T1, AR3                         ; AR3 = AR0 + 3*2*nx/4
        SFTL	T0, #-1                        ; nx/4
        SUB	#2, T0                          ; nx/4 - 2
        MOV	XSP, XAR7 
        ADD	#14, AR7                         ; temp mem in local frame
;        MOV	mmap(T0), BRC0 				;外循环计数器没有用到											
;       MOV	T0, AR4                               ; patch because CCS1.00b does 
;       ADD	#1, T0, AR4                          ; not work with localrepeat{}

;        .if  $isdefed("SI_BUGS")
;        MOV	XAR1, XAR5
;	MOV	#1, T0
;        .else
        MOV	XAR1, XAR5
		MOV	#1, T0
;        .endif

        MOV	#2, T1                               ; 
	||MOV	dbl(*AR0), AC0                        ; (0-in)	

	ADD	dual(*AR1), AC0, AC2

        MOV	dbl(*AR2), AC1                     ; (2-in)
		||MOV	AC2, dbl(*AR6)			
  
	SUB	dual(*(AR1+T1)), AC0
;    MOV #1,AR0                                 ;为了防止T0的错误
	ADD	dual(*AR3), AC1, AC3
	||MOV	AC0, dbl(*AR7(T0))                      ; (r0-r1),(i0-i1) (unaligned)  

	SUB	dual(*AR3), AC1

	ADD	dual(*AR6), AC3, AC2
	||MOV	AC1, T2                               ; move (i2-i3)

	SUB	AC3, dual(*AR6), AC3
	||MOV	AC2, dbl(*(AR0+T1)) 

	SUBADD	T2, *AR7(T0), AC0
	||MOV	HI(AC1), T3                           ; move (r2-r3)

	ADDSUB	T3, *AR7, AC1

loop_start:                                     ; CCS1.02b - wrong result 
	RPTBLOCAL	loop5

        MOV	AC3, dbl(*(AR2+T1))                   ; * (2 - out)
	||MOV	dbl(*AR0), AC3                     ; (0-in)	

	ADD	dual(*AR1), AC3, AC2
	||MOV	pair(HI(AC0)), dbl(*(AR3+T1))               ; * store 3-re, 3 -im

        MOV	pair(LO(AC0)), dbl(*(AR5+T1))             ; * (1 - out)
	||MOV	dbl(*AR2), AC1                     ; (2-in)

	SUB	dual(*(AR1+T1)), AC3
	||MOV	AC2, dbl(*AR6)                        ; store out  (r0+r1),(i0+i1)

	ADD	dual(*AR3), AC1, AC3
	||MOv	AC3, dbl(*AR7(T0))                      ; (r0-r1),(i0-i1) (unaligned) 
  
	SUB	dual(*AR3), AC1

        MOV	AC1, T2                               ; move (i2-i3)
	||ADD	dual(*AR6), AC3, AC2

	SUB	AC3, dual(*AR6), AC3
	||MOV	AC2, dbl(*(AR0+T1))

	SUBADD	T2, *AR7(T0), AC0
	||MOV	HI(AC1), T3                           ; move (r2-r3)

	ADDSUB	T3, *AR7, AC1

loop5:

;       SUB	#1, AR4                          ; 
;       BCC	loop_start, AR4!=#0             ; 

        MOV	AC3, dbl(*(AR2+T1))

        MOV	pair(LO(AC0)), dbl(*(AR5+T1))             ; store 1-re, 1 -im

        MOV	pair(HI(AC0)), dbl(*(AR3+T1))             ; store 3-re, 3 -im
;//-----------------------------------------------------------------------------
;// Context restore
;//-----------------------------------------------------------------------------

        MOV	dbl(*SP(#10)), pair(T2)
        MOV	dbl(*SP(#8)), XAR7
        MOV	dbl(*SP(#6)), XAR6
        MOV	dbl(*SP(#4)), XAR5
        MOV	dbl(*SP(#2)), pair(T0)                     ;
        MOV	dbl(*SP(#0)), XAR0                			;
 

        AADD	#17, SP                           ; destroy local frame  

        POP	mmap(ST2_55)
        POP	mmap(ST1_55)

;//-----------------------------------------------------------------------------
;// Return
;//-----------------------------------------------------------------------------
        RET    

        .end     		

					 

⌨️ 快捷键说明

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