📄 cfft_fr16.asm
字号:
AR = AX0 - AY0, DM(I0 += M1) = AR;
AR = AX1 + AY1, DM(I6 += M7) = AR;
AR = AX1 - AY1, DM(I0 += M1) = AR;
DM(I6 += M7) = AR;
AX0 = DM(I0 += M1), AY1 = PM(I6 += M7);
AY0 = DM(I6 += M5);
AR = AX0 + AY0, AX1 = DM(I0 += M3);
AR = AX0 - AY0, DM(I0 += M1) = AR;
AR = AX1 - AY1, DM(I6 += M7) = AR;
AR = AX1 + AY1, DM(I0 += M0) = AR;
DM(I6 += M6) = AR;
stage2: AX0 = DM(I0 += M1), AY0 = PM(I6 += M7);
//------------------------MIDDLE STAGES-----------------------------------------
#define USE_LAST_STAGE
L6 = 16; // initial group size(8 long complex)
M6 = 8; // initial data modifiers to move
// between butterfly operands
/* calculate number of remaining stages */
SE = EXP SI (HI); // SI holds n/4
AR = SE; // exponent of n
#ifdef USE_LAST_STAGE
AY0 = 13;
#else
AY0 = 14;
#endif
AR = AR + AY0; // log2(n)+
// 2(stages already done)+
// 1(stage done after)
IF LT JUMP cfft_return_path; // n==4 so done
IF EQ JUMP skip_middle_stages (DB); // n==8 so no middle stages required
AX1 = 4; // hold butterflies per group in AX1
// (AX1 preserved over scaling call)
M7 = 1;
CNTR = AR;
/* calculate twiddle modifier, initially n/8*twiddle stride */
SR = LSHIFT SI BY -1 (LO); // SI holds n/4, divide by 2
AX0 = SR0; // AX0 holds #butterfly groups,
// initially n/8
MY1 = DM(I5 + TWID_STRIDE);
MR = SR0 * MY1 (SS);
SI = MR0; // SI holds modifier value to access
// required successive twiddle values
M1 = 1; // set required values for scaling
M0 = -1;
DO stage_lp UNTIL CE;
CALL (I2) (DB); // call scaling routine for each stage
SE = -1; // SE==-1 for scaling routines entry
M3 = SI; // use M3 to loop through twiddles
I6 = I7; // I6->output address
MY1 = I7;
CNTR = AX0; // set loop counter to number of groups
REG(B6) = MY1; // L6 already set
DO group_lp UNTIL CE; // group loop start
AY1 = DM(I5 + TWIDDLES);
AR = AY1 + 1, MY0 = DM(I6 += M6);
// I6->xipre
I1 = AR; // I1->complex twiddle array(imag)
I0 = AY1; // I0->complex twiddle array
CNTR = AX1; // set loop counter to number of
// butterfly per group
MX1 = DM(I1 += M3); // MX1 = wptr[indx_w].im
DO bfly_lp UNTIL CE; // butterfly loop start
MY0 = DM(I6 += M7);
// MX1 = wptr[indx_w].im
// MY0 = initial xipre(I6->xipim)
SR = MX1 * MY0 (SS), MX0 = DM(I0 += M3);
// xipre * wptr[indx_w].im,
// MX0 = wptr[indx_w].re
MR = MX0 * MY0 (SS), MY0 = DM(I6 += M6);
// xipre * wptr[indx_w].re
// MY0 = xipim(I6->xiim)
MR = MR - MX1 * MY0 (RND), AY1 = DM(I6 += M5);
// MR - xipim * wptr[indx_w].im,
// load xiim(I6->xire)
SR = SR + MX0 * MY0 (RND), AY0 = DM(I6 += M6);
// SR + xipim * wptr[indx_w].re,
// load xire(I6->xipre)
AR = AY0 - MR1, MX1 = DM(I1 += M3);
// new xipre = xire - mult.re,
// MX1 = next wptr[indx_w].im
AR = MR1 + AY0, DM(I6 += M6) = AR;
// new xire = xire + mult.re,
// store new xipre(I6->xire)
AR = SR1 + AY1, DM(I6 += M7) = AR;
// new xiim = xiim + mult.im
// store new xire(I6->xiim)
AR = AY1 - SR1, DM(I6 += M6) = AR;
// new xipim = xiim - mult.im
// store new xiim(I6->xipim)
bfly_lp: DM(I6 += M7) = AR; // store new xipim(I6->next xipre)
// move group base to next group
AR = REG(B6);
AY1 = L6;
AR = AR + AY1;
I6 = AR;
group_lp: REG(B6) = AR;
AR = M6; // need to double data M-regs
AR = AR + AR;
M6 = AR;
AR = AR + AR; // length of group doubles also
L6 = AR;
SR = LSHIFT AX0 BY -1 (LO); // AX0 holds previous #butterfly groups,
// div by 2
AX0 = SR0;
AR = AX1 + AX1; // double butterflies per group (AX1)
AX1 = AR; // for each new group loop
SR = LSHIFT SI BY -1 (LO); // SI holds current twiddle modify
// value, divide by 2
stage_lp: SI = SR0;
//------------------------LAST STAGE--------------------------------------------
/*
* In the last stage of the butterfly the increment in the twiddle factor
* offset is just the value of the twiddle stride. In the last stage there
* is only one butterfly group.
*/
skip_middle_stages:
#ifdef USE_LAST_STAGE
CALL (I2) (DB); // call scaling routine
M1 = 1; // set required values for scaling
SE = -1;
I6 = I7;
AR = DM(I5 + TWID_STRIDE);
AR = AR + AR;
MY0 = I7;
REG(B6) = MY0;
M3 = AR; // M3 holds twiddle modifier
AY1 = DM(I5 + TWIDDLES);
AR = AY1 + 1, MY0 = DM(I6 += M6);
// I6->xipre
I1 = AR; // I1->complex twiddle array(imag)
I0 = AY1; // I0->complex twiddle array
CNTR = AX1; // AX1 should be n/2
MX1 = DM(I1 += M3); // MX1 = wptr[indx_w].im
DO last_stage UNTIL CE;
MY0 = DM(I6 += M7);
// MX1 = wptr[indx_w].im
// MY0 = initial xipre(I6->xipim)
SR = MX1 * MY0 (SS), MX0 = DM(I0 += M3);
// xipre * wptr[indx_w].im,
// MX0 = wptr[indx_w].re
MR = MX0 * MY0 (SS), MY0 = DM(I6 += M6);
// xipre * wptr[indx_w].re
// MY0 = xipim(I6->xiim)
MR = MR - MX1 * MY0 (RND), AY1 = DM(I6 += M5);
// MR - xipim * wptr[indx_w].im,
// load xiim(I6->xire)
SR = SR + MX0 * MY0 (RND), AY0 = DM(I6 += M6);
// SR + xipim * wptr[indx_w].re,
// load xire(I6->xipre)
AR = AY0 - MR1, MX1 = DM(I1 += M3);
// new xipre = xire - mult.re,
// MX1 = next wptr[indx_w].im
AR = MR1 + AY0, DM(I6 += M6) = AR;
// new xire = xire + mult.re,
// store new xipre(I6->xire)
AR = SR1 + AY1, DM(I6 += M7) = AR;
// new xiim = xiim + mult.im
// store new xire(I6->xiim)
AR = AY1 - SR1, DM(I6 += M6) = AR;
// new xipim = xiim - mult.im
// store new xiim(I6->xipim)
last_stage: DM(I6 += M7) = AR; // store new xipim(I6->next xipre)
#endif /* USE_LAST_STAGE */
//------------------------FUNCTION EPILOGUE-------------------------------------
cfft_return_path:
L6 = L5; // re-zero L6 for C-runtime
I6 = I5;
ENA M_MODE, DIS AR_SAT; // set int multiplier and ALU non-sat
MODIFY (I6 += M5); // restore preserved registers
I2 = DM (I6 += M5);
I3 = DM (I6 += M5);
I7 = DM (I6 += M5);
M0 = DM (I6 += M5);
RTS (DB); // return
I4 = I5;
I5 = DM (I5 += M5);
.__cfft_fr16.end:
// end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -