/*---------------------------------------------------------------------------- macros.h - general-purpose macros Floating Point: ----------------------------------------------------------------------------- FIR(taps,res,data,coef,acc,prod,Id,Md,Ic,Mc) N-tap FIR filtering DIVIDE(q,n,d,two,tmp) Division RECIP_SQRT(RES,C,three,half,Yi,Yn) 1 / Square Root SQRT(res,C,three,half,Yi,Yn) Square Root Fixed Point: ----------------------------------------------------------------------------- SWAP(a,b) swap registers w/o temp var MEM_INC(space,loc) increment a memory location MEM_DEC(space,loc) decrement a memory location CLEAR(reg) set Rn=0 as alu instruction a TEMPLATE is included at the end ----------------------------------------------------------------------------- Author: Jim Donahue (most translated from assembly run-time library) Release: 3/19/91 ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- FIR - FIR Filter Macro Register Usage: taps = integer number of taps res = f0-f15 result register data = f0-f3 FIR data register coef = f4-f7 FIR coefficient register prod = f12-f15 DATA*COEF product acc = f8-f11 accumulator/temporary reg Id,Md = i0-7,m0-7 DATA index & modify regs Ic,Mc = i8-i15,m8-m15 COEF index & modify regs Indirectly affected registers: ASTAT,STKY, LCNTR Looping: 1 level Special Cases: taps > 3 Cycles: taps + 3 + [6 misses] Created: 3/19/91 ----------------------------------------------------------------------------*/ #define FIR(taps,res,data,coef,acc,prod,Id,Md,Ic,Mc) \ data=dm(Id,Md), coef=pm(Ic,Mc); \ acc=data*coef, data=dm(Id,Md), coef=pm(Ic,Mc); \ prod=data*coef, data=dm(Id,Md), coef=pm(Ic,Mc); \ lcntr=taps-3, do (PC,1) until lce; \ prod=data*coef, acc=acc+prod, data=dm(Id,Md), coef=pm(Ic,Mc); \ prod=data*coef, acc=acc+prod; \ res=acc+prod /*---------------------------------------------------------------------------- DIVIDE - Divide Macro Register Usage: q = f0-f15 Quotient n = f4-f7 Numerator d = f12-f15 Denominator two = f8-f11 must have 2.0 pre-stored tmp = f0-f3 Indirectly affected registers: ASTAT,STKY Looping: none Special Cases: q may be any register, all others must be distinct. Cycles: 8 Created: 3/19/91 ----------------------------------------------------------------------------*/ #define DIVIDE(q,n,d,two,tmp) \ n=RECIPS d, tmp=n; /*Get 8 bit seed R0=1/D*/ \ d=n*d; /*D(prime) = D*R0*/ \ tmp=tmp*n, n=two-d; /*N=2-D(prime), TMP=N*R0*/ \ d=n*d; /*D=D(prime)=D(prime)*R1*/ \ tmp=tmp*n, n=two-d; /*TMP=N*R0*R1, N=R2=2-D(prime)*/ \ d=n*d; /*D=D(prime)=D(prime)*R2*/ \ tmp=tmp*n, n=two-d; /*TMP=N*R0*R1*R2, N=R3=2-D(prime)*/ \ q=tmp*n /*---------------------------------------------------------------------------- RECIP_SQRT - Square Root Macro Register Usage: res = f0-f15 Square Root of x x = f0-f15 input value three = f8-f11 must have 3.0 pre-stored half = f0-f3 must have 1.0 pre-stored Yi = f4-f7 Yn = f12-f15 Indirectly affected registers: ASTAT,STKY Looping: none Special Cases: RES may be any register, all others must be distinct. Cycles: 14 Created: 3/19/91 ----------------------------------------------------------------------------*/ #define RECIP_SQRT(RES,C,three,half,Yi,Yn) \ Yi=RSQRTS x; /*Fetch seed*/ \ \ Yn=Yi*Yi; /*Yn= Y0^2*/ \ Yn=Yn*x; /*Yn= C*Y0^2*/ \ Yi=half*Yi,Yn=three-Yn; /*Y0=.5*Y0, Yn=3-C*Y0^2*/ \ Yi=Yi*Yn; /*Yi=Y1= .5*Y0*(3-C*Y0^2)*/ \ \ Yn=Yi*Yi; /*Yn= Y1^2*/ \ Yn=Yn*x; /*Yn= C*Y1^2*/ \ Yi=half*Yi,Yn=three-Yn; /*Yi=.5*Y1, Yn=3-C*Y1^2*/ \ Yi=Yi*Yn; /*Yi=Y2= .5*Y1*(3-C*Y1^2)*/ \ \ Yn=Yi*Yi; /*Yn= Y2^2*/ \ Yn=Yn*x; /*Yn= C*Y2^2*/ \ Yi=half*Yi,Yn=three-Yn; /*Yi=.5*Y2, Yn=3-C*Y2^2*/ \ /*res = Y3 = .5*Y2*(3-C*Y2^2)*/ \ res=Yi*Yn /*---------------------------------------------------------------------------- SQRT - Square Root Macro Register Usage: res = f0-f15 Square Root of x x = f0-f15 input value three = f8-f11 must have 3.0 pre-stored half = f0-f3 must have 1.0 pre-stored Yi = f4-f7 Yn = f12-f15 Indirectly affected registers: ASTAT,STKY Looping: none Special Cases: res may be any register, all others must be distinct. Cycles: 15 Created: 3/19/91 ----------------------------------------------------------------------------*/ #define SQRT(res,C,three,half,Yi,Yn) \ RECIP_SQRT(res,C,three,half,Yi,Yn); \ res=Yi*x /*---------------------------------------------------------------------------- SWAP - swap registers without temporary variable Register Usage: a = r0-r15 register A b = r0-r15 register B Indirectly affected registers: ASTAT, STKY Looping: none Special Cases: a and b must be distinct Cycles: 3 Created: 3/19/91 ----------------------------------------------------------------------------*/ #define SWAP(a,b) \ a = a XOR b; \ b = a XOR b; \ a = a XOR b /*---------------------------------------------------------------------------- MEM_INC - increment a memory location Register Usage: space = DM or PM memory space loc = integer>0 address location tmp_reg = r0-r15 temp register Indirectly affected registers: ASTAT, STKY Looping: none Special Cases: loc must be < 2**24 for PM, < 2**32 for DM Cycles: 3 Created: 3/19/91 ----------------------------------------------------------------------------*/ #define MEM_INC(space,loc) \ tmp_reg = space(loc); \ tmp_reg = tmp_reg+1; \ space(loc) = tmp_reg /*---------------------------------------------------------------------------- MEM_DEC - decrement a memory location Register Usage: space = DM or PM memory space loc = integer>0 address location tmp_reg = r0-r15 temp register Indirectly affected registers: ASTAT, STKY Looping: none Special Cases: loc must be < 2**24 for PM, < 2**32 for DM Cycles: 3 Created: 3/19/91 ----------------------------------------------------------------------------*/ #define MEM_DEC(space,loc) \ tmp_reg = space(loc); \ tmp_reg = tmp_reg-1; \ space(loc) = tmp_reg /*---------------------------------------------------------------------------- CLEAR - clear a register file register as an alu instruction Register Usage: reg = r0-r15 Indirectly affected registers: ASTAT, STKY Looping: none Special Cases: Cycles: 1 Created: 3/20/91 ----------------------------------------------------------------------------*/ #define CLEAR(reg) \ reg = reg xor reg /*---------------------------------------------------------------------------- TEMPLATE - description of macro Register Usage: var = f0-f15 Variable Description Indirectly affected registers: REGNAMES Looping: depth Special Cases: description of restrictions or special cases Cycles: cycle_count Created: date ----------------------------------------------------------------------------*/ /* this is ALL commented out now ... #define TEMPLATE(outvars,invars,tmpvars...) \ instr; /* comments here */ \ instr; /* comments here */ \ final_instr */ /*notice - no final SEMICOLON,BACKSLASH, or COMMENT*/