/* This C language subroutine computes the complex inverse Fast Fourier Transform (FFT) of its input. The Run Time Library for the C Language. Gordon A. Sterling (617) 461 - 3076 DSP Development Tools Engineering Created on 6/19/90 #include
float *___ifftcore(float real_in[], float imag_in[], float real_out[], imag_out[]) The size of the fft is passed in register dm_ptr, and a pointer to the coefficients table is passed in dm_lnt. */ #include "lib_glob.h" #include "trn_glob.h" .SEGMENT/CODE Code_Space_Name; .FILE RTL_FILENAME; .GLOBAL ____ifftcore; .GLOBAL ____xifftcore; ____ifftcore: JUMP (PC, ifft_setup) (DB); pm_ptr=icomplex; R0=R0-R0, pm_lnt=dm_0; /*Clear Real flag*/ ____xifftcore: JUMP (PC, ifft_setup) (DB); pm_ptr=xicomplex; R0=R0-R0, pm_lnt=dm_0; /*Clear Real flag*/ ifft_setup: R2=dma_i; put(R2); R2=dma_m; put(R2); R2=dma_l; put(R2); R2=dmb_i; put(R2); R2=dmb_l; put(R2); R2=dmc_i; put(R2); R2=dmc_l; put(R2); R2=pma_i; put(R2); R2=pma_l; put(R2); put(R3); put(R5); put(R6); put(R7); put(R9); put(R10); R10=PASS R12, put(R11); R11=PASS R8, put(R13); R12=PASS R4, put(R14); put(R15); R0=PASS R0, readparam4(R9); /*Test for real flag*/ IF NE R9=PASS R10, R10=R11;/*Now imag_in passed with real functions*/ R15=dm_ptr; /*Hold N for now (set by caller)*/ R13=dm_lnt; /*Hold imag coeffs for now (set by caller)*/ R14=LSHIFT R15 BY -2; /*Compute N/4*/ R14=R13+R14, dm_lnt=dm_0; /*Hold real coeffs ptr, clr length reg*/ dma_l=0; /*Clear length registers*/ dmb_l=0; /*Clear length registers*/ CALL (PC, ___lib_bitrev) (DB);/*Reverse real input*/ R0=PASS R12, R2=R15; /*Get address of real in, N*/ R1=PASS R10; /*Get address of real out*/ JUMP (pm_0,pm_ptr) (DB);/*Execute specific routine */ pma_l=0; /*Clear length registers*/ dmc_l=0; /*Clear length registers*/ middle_passes: LCNTR=R7, DO stage_loop UNTIL LCE; pm_mdf=R6; /*Load twiddle factor modifer*/ dma_m=R15; /*Load node space modifier*/ dmc_i=R10; /*Point to start of real*/ dma_i=R9; /*Point to start of imag*/ dmb_i=dmc_i; /*Point to X1*/ dm_ptr=dma_i; /*Point to Y1*/ MODIFY(dmb_i,dma_m); MODIFY(dm_ptr,dma_m); LCNTR=R6, DO group_loop UNTIL LCE; pm_ptr=R14; /*Point to real coeffs*/ pma_i=R13; /*Point to imag coeffs*/ F4=DM(dmb_i,dm_0), F0=PM(pm_ptr,pm_mdf); /*Read x1, C*/ F5=DM(dm_ptr,dm_0), F1=PM(pma_i,pm_mdf); /*Read y1, S*/ LCNTR=R15, DO butterfly_loop UNTIL LCE; F11=F0*F4, F8=DM(dmc_i,dm_0); /*Compute CX1, read x0*/ F12=F1*F5, F7=DM(dma_i,dm_0); /*Compute SY1, read y0*/ F11=F0*F5, F12=F11-F12, F0=PM(pm_ptr,pm_mdf); /*Compute CY1,[CX1 + SY1]*/ F12=F1*F4, F2=F8+F12, F3=F8-F12, F1=PM(pma_i,pm_mdf); /*Compute SX1, X0, and X1*/ F12=F11+F12, DM(dmc_i, dm_1)=F2; /*SaveX0,Compute[CY1-SX1]*/ F2=F7+F12, F3=F7-F12, DM(dmb_i, dm_1)=F3; /*Save X1,Compute Y0and Y1*/ DM(dma_i, dm_1)=F2; /*Write out Y0*/ DM(dm_ptr, dm_1)=F3; /*Write out Y1*/ F4=DM(dmb_i,dm_0); butterfly_loop: F5=DM(dm_ptr,dm_0); MODIFY(dmc_i,dma_m); MODIFY(dmb_i,dma_m); MODIFY(dma_i,dma_m); group_loop: MODIFY(dm_ptr,dma_m); R6=ASHIFT R6 BY -1; /*Groups = Groups/2*/ stage_loop: R15=ASHIFT R15 BY 1; /*Node space = Node space *2*/ last_pass: pm_mdf=R6; /*Load twiddle factor modifer*/ dma_m=R15; /*Load node space modifier*/ dmc_i=R10; /*Point to start of real*/ dma_i=R9; /*Point to start of imag*/ dmb_i=dmc_i; /*Point to X1*/ dm_ptr=dma_i; /*Point to Y1*/ MODIFY(dmb_i,dma_m); MODIFY(dm_ptr,dma_m); pm_ptr=R14; /*Point to real coeffs*/ pma_i=R13; /*Point to imag coeffs*/ F4=DM(dmb_i,dm_0), F0=PM(pm_ptr,pm_mdf); F5=DM(dm_ptr,dm_0), F1=PM(pma_i,pm_mdf); LCNTR=R15, DO last_butterfly_loop UNTIL LCE; F11=F0*F4, F8=DM(dmc_i,dm_0); /*Compute CX1*/ F12=F1*F5, F7=DM(dma_i,dm_0); /*Compute SY1*/ F11=F0*F5, F12=F11-F12, F0=PM(pm_ptr,pm_mdf); /*Compute CY1, [CX1 + SY1]*/ F12=F1*F4, F2=F8+F12, F3=F8-F12, F1=PM(pma_i,pm_mdf); /*Compute SX1, X0, and X1*/ F12=F11+F12, DM(dmc_i, dm_1)=F2; /*Write out X0, Compute [CY1 - SX1]*/ F2=F7+F12, F3=F7-F12, DM(dmb_i, dm_1)=F3; /*Write out X1, compute Y0 and Y1*/ DM(dma_i, dm_1)=F2; /*Write out Y0*/ DM(dm_ptr, dm_1)=F3; /*Write out Y1*/ F4=DM(dmb_i,dm_0); last_butterfly_loop:F5=DM(dm_ptr,dm_0); restore_state: R0=PASS R10, FETCH_RETURN /*Point to real output*/ get(R15,1); get(R14,2); get(R13,3); get(R11,4); get(R10,5); get(R9,6); get(R7,7); get(R6,8); get(R5,9); get(R3,10); get(pma_l,11); get(pma_i,12); get(dmc_l,13); get(dmc_i,14); get(dmb_l,15); get(dmb_i,16); get(dma_l,17); get(dma_m,18); get(dma_i,19); RETURN (DB); RESTORE_STACK RESTORE_FRAME /* */ /* */ /* This section of code bitreverses the imaginary portion of the complex input */ /* and computes the first pass of the complex FFT. */ /* */ /* */ icomplex: CALL (PC, ___lib_bitrev) (DB);/*Reverse imag input*/ R0=PASS R11, R2=R15; /*Get address of imag in, N*/ R1=PASS R9; /*Get address of imag out*/ dmc_i=R10; R6=ASHIFT R15 BY -2, F0=DM(dmc_i,dm_0);/*Set twiddle factor modifier (groups)*/ R15=2; /*Set node space modfier for second pass (bfly node)*/ dma_m=2; /*Used for modify*/ dmc_i=R10; /*Point to start of real*/ dma_i=R9; /*Point ot start of imag*/ dmb_i=dmc_i; /*Point to X1*/ dm_ptr=dma_i; /*Point to Y1*/ MODIFY(dmb_i, dm_1); MODIFY(dm_ptr, dm_1); R4=R6+R6, F1=DM(dmb_i,dm_0); /*Loop N/2 times*/ LCNTR=R4, DO complex_group_loop UNTIL LCE; F4=F0+F1, F2=DM(dma_i,dm_0); F5=F0-F1, F3=DM(dm_ptr,dm_0); F4=F2+F3, DM(dmc_i,dma_m)=F4; F5=F2-F3, DM(dmb_i,dma_m)=F5; DM(dma_i,dma_m)=F4; DM(dm_ptr,dma_m)=F5; F0=DM(dmc_i,dm_0); complex_group_loop: F1=DM(dmb_i,dm_0); JUMP (PC, middle_passes) (DB); R7=R7-1; /*First pass broken out*/ R7=R7-1; /*Last pass broken out*/ /* */ /* */ /* This section of code bitreverses the imaginary portion of the complex input */ /* and computes the first pass of the complex FFT. The input to this FFT is an */ /* array of fractional numbers. FFTs are always computed in floating point */ /* so the first pass is used to convert the fractional numbers to floating point*/ /* */ /* */ xicomplex: CALL (PC, ___lib_bitrev)(DB);/*Reverse imag input*/ R0=PASS R11, R2=R15; /*Get address of imag in, N*/ R1=PASS R9; /*Get address of imag out*/ R6=ASHIFT R15 BY -2; /*Set twiddle factor modifier (groups)*/ R15=2; /*Set node space modfier for second pass (bfly node)*/ dma_m=2; /*Used for modify*/ dmc_i=R10; /*Point to start of real*/ dma_i=R9; /*Point ot start of imag*/ dmb_i=dmc_i; /*Point to X1*/ dm_ptr=dma_i; /*Point to Y1*/ MODIFY(dmb_i, dm_1); MODIFY(dm_ptr, dm_1); R4=R6+R6, R0=DM(dmc_i,dm_0); /*Loop N/2 times*/ R11=-31; /*Used for float command*/ F0=FLOAT R0 BY R11, R1=DM(dmb_i,dm_0); LCNTR=R4, DO xcomplex_group_loop UNTIL LCE; F1=FLOAT R1 BY R11, R2=DM(dma_i, dm_0); F4=F0+F1, R3=DM(dm_ptr, dm_0); F5=F0-F1, DM(dmc_i, dma_m)=F4; F2=FLOAT R2 BY R11, DM(dmb_i, dma_m)=F5; F3=FLOAT R3 BY R11, R0=DM(dmc_i, dm_0); F4=F2+F3, R1=DM(dmb_i, dm_0); F5=F2-F3, DM(dma_i, dma_m)=F4; xcomplex_group_loop: F0=FLOAT R0 BY R11, DM(dm_ptr, dma_m)=F5; JUMP (PC, middle_passes) (DB); R7=R7-1; /*First pass broken out*/ R7=R7-1; /*Last pass broken out*/ .ENDSEG;