fs_rad4.h

来自「realview22.rar」· C头文件 代码 · 共 124 行

H
124
字号
;
; $Copyright: 
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
;   (C) COPYRIGHT 2000,2002 ARM Limited
;       ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File:     fs_rad4.h,v
; Revision: 1.4
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; The macro in this file is first stage radix-4
; It bit reverses (assuming a power of 2 FFT) and performs the first stage
;

        MACRO
        FS_RAD4
        SETSHIFT postldshift, 2*norm
        SETSHIFT postmulshift, 2*norm+qshift
        IF "$prescale"<>""
          STMFD sp!, {dptr, N, r3}
        ELSE
          STMFD sp!, {dptr, N}
        ENDIF
        MOV     bitrev, #0
        MOV     dinc, N, LSL#($datalog-2)
00      ; first stage loop

        IF reversed
          ; load data serially
          LOADDATAI inptr, #1<<datainlog, x0r, x0i
          LOADDATAI inptr, #1<<datainlog, x1r, x1i
          LOADDATAI inptr, #1<<datainlog, x2r, x2i
          LOADDATAI inptr, #1<<datainlog, x3r, x3i
        ELSE
          ; load data from input array in bit reversed order 0,2,1,3
          ADD   t0, inptr, bitrev, LSL#$datalog
          LOADDATAI t0, dinc, x0r, x0i
          LOADDATAI t0, dinc, x2r, x2i
          LOADDATAI t0, dinc, x1r, x1i
          LOADDATAI t0, dinc, x3r, x3i
        ENDIF
        
        IF "$prescale"="P"
          LDR   t0, [sp, #8]
          MOV   x0r, x0r, LSL t0
          MOV   x0i, x0i, LSL t0
          MOV   x1r, x1r, LSL t0
          MOV   x1i, x1i, LSL t0
          MOV   x2r, x2r, LSL t0
          MOV   x2i, x2i, LSL t0
          MOV   x3r, x3r, LSL t0
          MOV   x3i, x3i, LSL t0
        ENDIF
        
        ; do the 4 point transform
        SHIFTDATA x0r, x0i
        ; first stage + 4 element bit reverse
        SETREGS h,t0,t1,x0r,x0i,x1r,x1i,x2r,x2i
        ADD     $h0r, x0r, x1r $postldshift
        ADD     $h0i, x0i, x1i $postldshift
        SUB     $h1r, x0r, x1r $postldshift
        SUB     $h1i, x0i, x1i $postldshift
        ADD     $h2r, x2r, x3r
        ADD     $h2i, x2i, x3i
        SUB     $h3r, x2r, x3r
        SUB     $h3i, x2i, x3i
        ; second stage
        SETREG  y0,x3r,x3i
        ADD     $y0r, $h0r, $h2r $postldshift
        ADD     $y0i, $h0i, $h2i $postldshift
        STORE   dptr, #1<<$datalog, $y0r, $y0i
        SUBi    $y0r, $h1r, $h3i $postldshift
        ADDi    $y0i, $h1i, $h3r $postldshift
        STORE   dptr, #1<<$datalog, $y0r, $y0i
        SUB     $y0r, $h0r, $h2r $postldshift
        SUB     $y0i, $h0i, $h2i $postldshift
        STORE   dptr, #1<<$datalog, $y0r, $y0i
        ADDi    $y0r, $h1r, $h3i $postldshift
        SUBi    $y0i, $h1i, $h3r $postldshift
        STORE   dptr, #1<<$datalog, $y0r, $y0i

        IF reversed
          ; standard increment
          SUBS  dinc, dinc, #1<<$datalog
          BGT   %BT00
        ELSE
          ; bit reversed increment
          EOR   bitrev, bitrev, dinc, LSR#($datalog-2+3) ; t0 = (N/4)>>1
          TST   bitrev, dinc, LSR#($datalog-2+3)
          BNE   %BT00
          ; get here for 1/2 the loops - carry to next bit
          EOR   bitrev, bitrev, dinc, LSR#($datalog-2+4)
          TST   bitrev, dinc, LSR#($datalog-2+4)
          BNE   %BT00
          ; get here for 1/4 of the loops - stop unrolling
          MOV   t0, dinc, LSR#($datalog-2+5)
05        ; bit reverse increment loop
          EOR   bitrev, bitrev, t0
          TST   bitrev, t0
          BNE   %BT00
          ; get here for 1/8 of the loops (or when finished)
          MOVS  t0, t0, LSR#1   ; move down to next bit
          BNE   %BT05           ; carry on if we haven't run off the bottom
        ENDIF
        IF "$prescale"<>""
          LDMFD sp!, {dptr, N, r3}
        ELSE
          LDMFD sp!, {dptr, N}
        ENDIF
        MOV     count, N, LSR#2         ; we have N/4 blocks 4 each
        MOV     dinc, #4<<$datalog      ; initial skip is 4 elements
        MEND

        END

⌨️ 快捷键说明

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