Initial code package commit.
[apps/c55x-digital-mic-decimation.git] / src / BlkFirDecim_f2.asm
1 ;============================================================================
2 ; Copyright (c) 2016 Texas Instruments Incorporated.
3 ;
4 ;  Redistribution and use in source and binary forms, with or without
5 ;  modification, are permitted provided that the following conditions
6 ;  are met:
7 ;
8 ;    Redistributions of source code must retain the above copyright
9 ;    notice, this list of conditions and the following disclaimer.
10 ;
11 ;    Redistributions in binary form must reproduce the above copyright
12 ;    notice, this list of conditions and the following disclaimer in the
13 ;    documentation and/or other materials provided with the
14 ;    distribution.
15 ;
16 ;    Neither the name of Texas Instruments Incorporated nor the names of
17 ;    its contributors may be used to endorse or promote products derived
18 ;    from this software without specific prior written permission.
19 ;
20 ;  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ;  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 ;  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 ;  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 ;  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 ;  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 ;  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 ;  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 ;  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 ;  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 ;  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ;
32 ;===============================================================================
33 ; Function:    _blkFirDecim2
34 ; Processor:   C55xx, Rev. 3
35 ; Description: 
36 ;   Block decimating FIR.
37 ;   S18Q16 input and output data, S16Q15 coefficients.
38 ;   Decimation factor fixed at 2.
39 ;   Computes two outputs per inner loop 
40 ;   (assumes even number of outputs).
41 ;
42 ;   x cycle inner loop.
43 ;
44 ;   C-callable.
45 ;   Mnemonic assembly.
46 ;
47 ; Usage:    void blkFirDecim2(
48 ;               Int32   *inSamps,       -> XAR0
49 ;               Int16   *coefs,         -> XAR1
50 ;               Int32   *outSamps,      -> XAR2
51 ;               Int32   *dlyBuf,        -> XAR3
52 ;               Uint16  numInSamps,     -> T0
53 ;               Uint16  numCoefs        -> T1
54 ;           );
55 ;
56 ;****************************************************************
58                 .C54CM_off                      ; enable assembler for C54CM=0
59                 .ARMS_off                       ; enable assembler for ARMS=0
60                 .CPL_on                         ; enable assembler for CPL=1
62                 .mmregs                         ; enable mem mapped register names
64                 .def    _blkFirDecim2
66 ; Stack frame
67 ; -----------
68 RET_ADDR_SZ     .set    1                       ; return address
69 REG_SAVE_SZ     .set    0                       ; save-on-entry registers saved
70 FRAME_SZ        .set    0                       ; local variables
71 ARG_BLK_SZ      .set    0                       ; argument block
72 PARAM_OFFSET    .set    ARG_BLK_SZ + FRAME_SZ + REG_SAVE_SZ + RET_ADDR_SZ   ; offset to function arguments on stack
74 ; Local variables
75 ; ---------------
77 ; Register usage
78 ; --------------
79                 .asg    AR0, x_ptr              ; linear pointer
80                 .asg    CDP, h_ptr              ; circular pointer
81                 .asg    AR2, r_ptr              ; linear pointer
82                 .asg    AR4, db_ptr2            ; circular pointer (lagging delay buffer pointer)
83                 .asg    AR5, db_ptr1            ; circular pointer (leading delay buffer pointer)
85                 .asg    BSAC, h_base            ; base addr for h_ptr
86                 .asg    BKC, h_sz               ; circ buffer size for h_sz
87                 .asg    XCDP, xh_base           ; extended base addr for h_ptr
88                 .asg    BSA45, db_base          ; base addr for db_ptr
89                 .asg    BK47, db_sz             ; circ buffer size for db_ptr
90                 .asg    XAR4, xdb_base2         ; extended base addr for db_ptr2 (lagging delay buffer pointer)
91                 .asg    XAR5, xdb_base1         ; extended base addr for db_ptr1 (leading delay buffer pointer)
93                 .asg    BRC0, outer_cnt         ; outer loop count
94                 .asg    BRC1, inner_cnt         ; inner loop count
96 ST2mask         .set    0000000100110000b       ; circular/linear pointers
98 QUANT_TRUNC     .set    0                       ; truncate
99 QUANT_RND       .set    1                       ; round according to rounding mode
100 QUANT_MODE      .set    QUANT_RND
103                 .text
104 _blkFirDecim2:
107 ; Save any save-on-entry registers that are used
108 ;----------------------------------------------------------------
111 ; Allocate the local frame and argument block
112 ;----------------------------------------------------------------
113                 AADD        #-(ARG_BLK_SZ + FRAME_SZ), SP 
116 ; Save entry values for later
117 ;----------------------------------------------------------------
120 ; Configure the status registers as needed
121 ;----------------------------------------------------------------
122                 AND         #001FFh, mmap(ST0_55)   ; clear ACOV[0-3], TC[1-2], and C
124                 OR          #04540h, mmap(ST1_55)   ; set CPL, M40, SXMD, and FRCT
125                 ;AND         #0F9DFh, mmap(ST1_55)   ; clear M40, SATD, 54CM 
127                 BCLR        ARMS                    ; clear ARMS
129                 ;AND         #0FCDDh, mmap(ST3_55)   ; clear SATA, SMUL ; note -- must always write 1100b to bits 11-8, 0b to bit 4
132 ; Setup passed parameters in their destination registers
133 ; Setup circular/linear CDP/ARx behavior
134 ;----------------------------------------------------------------
136 ; x pointer - passed in its destination register, need do nothing
138 ; h pointer
139                 MOV         XAR1, xh_base           ; h array address
140                 MOV         mmap(AR1), h_base       ; base address of coefficients
141                 MOV         #0, h_ptr               ; point to first coefficient
142                 MOV         mmap(T1), h_sz          ; coefficient array size h_sz = nh
144 ; r pointer - already passed in its destination register
146 ; db pointers
147                 ; Initialize lagging delay pointer
148                 MOV         XAR3, xdb_base2         ; db array address
149                 ; Read index of oldest db entry
150                 MOV         dbl(*AR3+), AC0
151                 MOV         AC0, db_ptr2
152                 MOV         mmap(AR3), db_base      ; base address for db_ptr
153                 ; db_sz = 2*(nh+2) (x2 for 32-bit array)
154                 MOV         T1, AC0
155                 ADD         #2, AC0
156                 MOV         AC0 << #1, mmap(db_sz)
158 ; Set circular/linear ARx behavior
159                 OR          #ST2mask, mmap(ST2_55)  ; config circ/linear pointers
161                ; Initialize leading delay pointer
162                 AMOV        xdb_base2, xdb_base1
163                 ;AMAR        *db_ptr1-
164                 ;AMAR        *db_ptr1-
167 ; Setup loop counts
168 ;----------------------------------------------------------------
169                 MOV                     T0, AC0                                 ; AC0 = nx (nx unsigned, constrained to < 32768 since SXM is enabled)
170              || AMAR        *db_ptr1-
171                 SFTS        AC0, #-2                ; AC0 = (nx/2)/2
172              || AMAR        *db_ptr1-
173                 SUB         #1, AC0                 ; AC0 = (nx/2)/2-1
174                 MOV         AC0, mmap(outer_cnt)    ; outer_cnt = (nx/D)/2-1=(nx/4)-1
175     
176                 SUB         #3, T1
177                 MOV         T1, mmap(inner_cnt)     ; inner_cnt = nh-3
181 ; Start of outer loop
182 ;----------------------------------------------------------------
183                 RPTBLOCAL   loop0-1                 ; outer loop (nx/D)=(nx/2) iterations
185                 ; Place 1 sample in delay line at lagging index
186                 MOV         dbl(*x_ptr+), dbl(*db_ptr2)
187     
188                 ; Place D=2 samples in delay line at leading index
189                 MOV         dbl(*x_ptr+), dbl(*db_ptr1-)
190                 MOV         dbl(*x_ptr+), dbl(*db_ptr1)
192                 ; Sum h*x nh-iterations for next r value
193                 MPY         *db_ptr2+, *h_ptr, AC3          ; High x Low
194              :: MPY         *db_ptr1+, *h_ptr, AC1          ; High x Low
195                 MPY         uns(*db_ptr2+), *h_ptr+, AC2    ; Low x Low
196              :: MPY         uns(*db_ptr1+), *h_ptr+, AC0    ; Low x Low
198              || RPTBLOCAL   loop1-1
199                 MAC         *db_ptr2+, *h_ptr, AC3          ; High x Low
200              :: MAC         *db_ptr1+, *h_ptr, AC1          ; High x Low
201                 MAC         uns(*db_ptr2+), *h_ptr+, AC2    ; Low x Low
202              :: MAC         uns(*db_ptr1+), *h_ptr+, AC0    ; Low x Low
203 loop1:
205                 MAC         *db_ptr2+, *h_ptr, AC3          ; High x Low
206              :: MAC         *db_ptr1+, *h_ptr, AC1          ; High x Low
207                 .if (QUANT_MODE == QUANT_TRUNC)
208                 MAC         uns(*db_ptr2-), *h_ptr+, AC2    ; Low x Low
209              :: MAC         uns(*db_ptr1-), *h_ptr+, AC0    ; Low x Low
210                 .else
211                 MACR        uns(*db_ptr2-), *h_ptr+, AC2    ; Low x Low
212              :: MACR        uns(*db_ptr1-), *h_ptr+, AC0    ; Low x Low
213                 .endif
215                 ADD         AC3 << #16, AC2
216                 ADD         AC1 << #16, AC0
218                 ; Store result to memory
219                 SFTS        AC2, #-16
220                 MOV         AC2, dbl(*r_ptr+)       ; store S18Q16 value to memory
221              || SFTS        AC0, #-16
222                 MOV         AC0, dbl(*r_ptr+)       ; store S18Q16 value to memory
223     
224                 ; Place D-1=2-1=1 sample in delay line at lagging index
225                 MOV         dbl(*x_ptr+), dbl(*db_ptr2-)
226 loop0: ; end of outer loop
227     
229 ; Update the db entry point
230 ;----------------------------------------------------------------
231                 MOV         db_ptr2, *-AR3           ; update 1st element of db array
234 ; Restore status regs to expected C-convention values as needed
235 ;----------------------------------------------------------------
236                 BCLR        M40                     ; clear M40
237                 BCLR        FRCT                    ; clear FRCT
239                 AND         #0FE00h, mmap(ST2_55)   ; clear CDPLC and AR[7-0]LC
240                 BSET        ARMS                    ; set SMUL
242                 ;BSET        SMUL                    ; set SMUL
245 ; Deallocate the local frame and argument block
246 ;----------------------------------------------------------------
247                 AADD        #(ARG_BLK_SZ + FRAME_SZ), SP 
250 ; Restore any save-on-entry registers that are used
251 ;----------------------------------------------------------------
254 ; Return to calling function
255 ;----------------------------------------------------------------
256                 RET                             ; return to calling function