/* This assembly file contains various support routines that are used by the FFT modules The C runtime Library Gordon A. Sterling Created on 7/28/90 Updated on 3/95 by AS - eliminated redundant cycle */ #include "lib_glob.h" #include "trn_glob.h" .SEGMENT/CODE Code_Space_Name; .FILE RTL_FILENAME; /* This routine performs a bit reversal of the input data to the output data Calling Parameters R0 --> Input buffer R1 --> Output buffer R2 == Length of buffer Return Registers R0 == Modify value R7 == Log2(N) Altered Registers R2, R3, R4, R7, R8, R12, dm_bse, dm_ptr, dm_mdf, dm_lnt, dma_b, dma_i, dma_m, dma_l, dmb_b, dmb_i, dmb_m, dmb_l Cycle Count (N+2) * 8 */ .GLOBAL ___lib_bitrev; ___lib_bitrev: R4=EXP R2, dma_m=R0; /*Tst for size of N, Pt to buf base*/ R12=30; /*Redundant sign bits -30*/ R12=R4+R12, dm_lnt=dm_0; /* is the shift val, clr length reg*/ R12=-R12, R7=R12; /*Need to negate result*/ R12=R12+1, dm_bse=R0; /*Decrement count by one*/ R4=0x80000000; /*Base modify value*/ R4=LSHIFT R4 BY R12, dma_b=R1; /*Compute modify value*/ dma_l=0; /*Clear length registers*/ COMP(R0,R1), dmb_b=dm_0; /*Test for same buffer, Pt to output again*/ IF NE JUMP (PC, two_buffers) (DB); /*Do the easy copy*/ dmb_l=0; /*Clear length*/ R12=R12-R12, dm_mdf=R4; /*Clear count register*/ /* This routine is executed if the desired output buffer is the same as */ /* the input buffer. It only does a copy if the address has not been */ /* previously bit reversed. It takes longer than the quick copy, but */ /* it is safe for the same array case. */ LCNTR=R2, DO bit_rev UNTIL LCE; /*Loop once for each point*/ R8=dma_i; /*Fetch current address*/ MODIFY(dmb_i, dm_mdf); /*Increment stored pointer*/ F2=DM(dm_ptr,dm_1); /*Read current point*/ COMP(R8,R12), F4=DM(dma_m, dma_i);/*Compare to current point*/ IF LT DM(dm_M1,dm_ptr)=F4; /*Write out bit reversed point*/ IF LT DM(dma_m,dma_i)=F2; /*Write out current point*/ R12=R12+1, dma_i=dmb_i; /*Increment current count*/ bit_rev: BITREV(dma_i,0); /*Reverse point*/ RTS (DB); /*Return to caller*/ R0=dm_mdf; /*Copy modify value*/ NOP; /*DEAD CYCLE*/ /* If the output buffer is distinct from the input buffer, this copy */ /* is called. This routine runs somewhat faster than the other copy */ /* routine which does a safe copy (will not overwrite data. */ two_buffers: dma_m=R1; /*Point to output array*/ dma_b=0; /*Clear output pointer*/ LCNTR=R2, DO rev_copy UNTIL LCE;/*Loop once for each point*/ MODIFY(dmb_i, dm_mdf); /*Increment stored pointer*/ F2=DM(dm_ptr,dm_1); /*Read current point*/ DM(dma_m,dma_i)=F2; /*Write out current point*/ dma_i=dmb_i; /*Increment current count*/ rev_copy: BITREV(dma_i,0); /*Reverse point*/ RTS (DB); R0=dm_mdf; NOP; .ENDSEG;