485e3776be4938207d4dceb7d20ec273511c4123
[platform/upstream/flac.git] / src / libFLAC / ia32 / lpc_asm-unrolled.nasm
1 ;  vim:filetype=nasm ts=8
2
3 ;  libFLAC - Free Lossless Audio Codec library
4 ;  Copyright (C) 2001,2002,2003,2004,2005,2006,2007,2008,2009  Josh Coalson
5 ;
6 ;  Redistribution and use in source and binary forms, with or without
7 ;  modification, are permitted provided that the following conditions
8 ;  are met:
9 ;
10 ;  - Redistributions of source code must retain the above copyright
11 ;  notice, this list of conditions and the following disclaimer.
12 ;
13 ;  - Redistributions in binary form must reproduce the above copyright
14 ;  notice, this list of conditions and the following disclaimer in the
15 ;  documentation and/or other materials provided with the distribution.
16 ;
17 ;  - Neither the name of the Xiph.org Foundation nor the names of its
18 ;  contributors may be used to endorse or promote products derived from
19 ;  this software without specific prior written permission.
20 ;
21 ;  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ;  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 ;  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 ;  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
25 ;  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 ;  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 ;  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 ;  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 ;  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 ;  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 ;  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33 ; [CR] is a note to flag that the instruction can be easily reordered
34
35 %include "nasm.h"
36
37         data_section
38
39 cglobal FLAC__lpc_compute_autocorrelation_asm
40
41         code_section
42
43 ; **********************************************************************
44 ;
45 ; void FLAC__lpc_compute_autocorrelation_asm(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
46 ; {
47 ;       FLAC__real d;
48 ;       unsigned sample, coeff;
49 ;       const unsigned limit = data_len - lag;
50 ;
51 ;       assert(lag > 0);
52 ;       assert(lag <= data_len);
53 ;
54 ;       for(coeff = 0; coeff < lag; coeff++)
55 ;               autoc[coeff] = 0.0;
56 ;       for(sample = 0; sample <= limit; sample++){
57 ;               d = data[sample];
58 ;               for(coeff = 0; coeff < lag; coeff++)
59 ;                       autoc[coeff] += d * data[sample+coeff];
60 ;       }
61 ;       for(; sample < data_len; sample++){
62 ;               d = data[sample];
63 ;               for(coeff = 0; coeff < data_len - sample; coeff++)
64 ;                       autoc[coeff] += d * data[sample+coeff];
65 ;       }
66 ; }
67 ;
68 FLAC__lpc_compute_autocorrelation_asm:
69
70         push    ebp
71         lea     ebp, [esp + 8]
72         push    ebx
73         push    esi
74         push    edi
75
76         mov     edx, [ebp + 8]                  ; edx == lag
77         mov     ecx, [ebp + 4]                  ; ecx == data_len
78         mov     esi, [ebp]                      ; esi == data
79         mov     edi, [ebp + 12]                 ; edi == autoc
80
81         cmp     edx, 1
82         ja      short .lag_above_1
83 .lag_eq_1:
84         fldz                                    ; will accumulate autoc[0]
85         ALIGN 16
86 .lag_1_loop:
87         fld     dword [esi]
88         add     esi, byte 4                     ; sample++
89         fmul    st0, st0
90         faddp   st1, st0
91         dec     ecx
92         jnz     .lag_1_loop
93         fstp    dword [edi]
94         jmp     .end
95
96 .lag_above_1:
97         cmp     edx, 2
98         ja      short .lag_above_2
99 .lag_eq_2:
100         fldz                                    ; will accumulate autoc[1]
101         dec     ecx
102         fldz                                    ; will accumulate autoc[0]
103         fld     dword [esi]
104         ALIGN 16
105 .lag_2_loop:
106         add     esi, byte 4                     ; [CR] sample++
107         fld     st0
108         fmul    st0, st0
109         faddp   st2, st0                        ; add to autoc[0]
110         fld     dword [esi]
111         fmul    st1, st0
112         fxch
113         faddp   st3, st0                        ; add to autoc[1]
114         dec     ecx
115         jnz     .lag_2_loop
116         ; clean up the leftovers
117         fmul    st0, st0
118         faddp   st1, st0                        ; add to autoc[0]
119         fstp    dword [edi]
120         fstp    dword [edi + 4]
121         jmp     .end
122
123 .lag_above_2:
124         cmp     edx, 3
125         ja      short .lag_above_3
126 .lag_eq_3:
127         fldz                                    ; will accumulate autoc[2]
128         dec     ecx
129         fldz                                    ; will accumulate autoc[1]
130         dec     ecx
131         fldz                                    ; will accumulate autoc[0]
132         ALIGN 16
133 .lag_3_loop:
134         fld     dword [esi]
135         fld     st0
136         fmul    st0, st0
137         faddp   st2, st0                        ; add to autoc[0]
138         fld     dword [esi + 4]
139         fmul    st0, st1
140         faddp   st3, st0                        ; add to autoc[1]
141         fld     dword [esi + 8]
142         fmulp   st1, st0
143         add     esi, byte 4                     ; [CR] sample++
144         faddp   st3, st0                        ; add to autoc[2]
145         dec     ecx
146         jnz     .lag_3_loop
147         ; clean up the leftovers
148         fld     dword [esi]
149         fld     st0
150         fmul    st0, st0
151         faddp   st2, st0                        ; add to autoc[0]
152         fld     dword [esi + 4]
153         fmul    st1, st0
154         fxch
155         faddp   st3, st0                        ; add to autoc[1]
156         fmul    st0, st0
157         faddp   st1, st0                        ; add to autoc[0]
158         fstp    dword [edi]
159         fstp    dword [edi + 4]
160         fstp    dword [edi + 8]
161         jmp     .end
162
163 .lag_above_3:
164         cmp     edx, 4
165         ja      near .lag_above_4
166 .lag_eq_4:
167         fldz                                    ; will accumulate autoc[3]
168         dec     ecx
169         fldz                                    ; will accumulate autoc[2]
170         dec     ecx
171         fldz                                    ; will accumulate autoc[1]
172         dec     ecx
173         fldz                                    ; will accumulate autoc[0]
174         ALIGN 16
175 .lag_4_loop:
176         fld     dword [esi]
177         fld     st0
178         fmul    st0, st0
179         faddp   st2, st0                        ; add to autoc[0]
180         fld     dword [esi + 4]
181         fmul    st0, st1
182         faddp   st3, st0                        ; add to autoc[1]
183         fld     dword [esi + 8]
184         fmul    st0, st1
185         faddp   st4, st0                        ; add to autoc[2]
186         fld     dword [esi + 12]
187         fmulp   st1, st0
188         add     esi, byte 4                     ; [CR] sample++
189         faddp   st4, st0                        ; add to autoc[3]
190         dec     ecx
191         jnz     .lag_4_loop
192         ; clean up the leftovers
193         fld     dword [esi]
194         fld     st0
195         fmul    st0, st0
196         faddp   st2, st0                        ; add to autoc[0]
197         fld     dword [esi + 4]
198         fmul    st0, st1
199         faddp   st3, st0                        ; add to autoc[1]
200         fld     dword [esi + 8]
201         fmulp   st1, st0
202         add     esi, byte 4                     ; [CR] sample++
203         faddp   st3, st0                        ; add to autoc[2]
204         fld     dword [esi]
205         fld     st0
206         fmul    st0, st0
207         faddp   st2, st0                        ; add to autoc[0]
208         fld     dword [esi + 4]
209         fmul    st1, st0
210         fxch
211         faddp   st3, st0                        ; add to autoc[1]
212         fmul    st0, st0
213         faddp   st1, st0                        ; add to autoc[0]
214         fstp    dword [edi]
215         fstp    dword [edi + 4]
216         fstp    dword [edi + 8]
217         fstp    dword [edi + 12]
218         jmp     .end
219
220 .lag_above_4:
221         cmp     edx, 5
222         ja      near .lag_above_5
223 .lag_eq_5:
224         fldz                                    ; will accumulate autoc[4]
225         fldz                                    ; will accumulate autoc[3]
226         fldz                                    ; will accumulate autoc[2]
227         fldz                                    ; will accumulate autoc[1]
228         fldz                                    ; will accumulate autoc[0]
229         sub     ecx, byte 4
230         ALIGN 16
231 .lag_5_loop:
232         fld     dword [esi]
233         fld     st0
234         fmul    st0, st0
235         faddp   st2, st0                        ; add to autoc[0]
236         fld     dword [esi + 4]
237         fmul    st0, st1
238         faddp   st3, st0                        ; add to autoc[1]
239         fld     dword [esi + 8]
240         fmul    st0, st1
241         faddp   st4, st0                        ; add to autoc[2]
242         fld     dword [esi + 12]
243         fmul    st0, st1
244         faddp   st5, st0                        ; add to autoc[3]
245         fld     dword [esi + 16]
246         fmulp   st1, st0
247         add     esi, byte 4                     ; [CR] sample++
248         faddp   st5, st0                        ; add to autoc[4]
249         dec     ecx
250         jnz     .lag_5_loop
251         ; clean up the leftovers
252         fld     dword [esi]
253         fld     st0
254         fmul    st0, st0
255         faddp   st2, st0                        ; add to autoc[0]
256         fld     dword [esi + 4]
257         fmul    st0, st1
258         faddp   st3, st0                        ; add to autoc[1]
259         fld     dword [esi + 8]
260         fmul    st0, st1
261         faddp   st4, st0                        ; add to autoc[2]
262         fld     dword [esi + 12]
263         fmulp   st1, st0
264         add     esi, byte 4                     ; [CR] sample++
265         faddp   st4, st0                        ; add to autoc[3]
266         fld     dword [esi]
267         fld     st0
268         fmul    st0, st0
269         faddp   st2, st0                        ; add to autoc[0]
270         fld     dword [esi + 4]
271         fmul    st0, st1
272         faddp   st3, st0                        ; add to autoc[1]
273         fld     dword [esi + 8]
274         fmulp   st1, st0
275         add     esi, byte 4                     ; [CR] sample++
276         faddp   st3, st0                        ; add to autoc[2]
277         fld     dword [esi]
278         fld     st0
279         fmul    st0, st0
280         faddp   st2, st0                        ; add to autoc[0]
281         fld     dword [esi + 4]
282         fmul    st1, st0
283         fxch
284         faddp   st3, st0                        ; add to autoc[1]
285         fmul    st0, st0
286         faddp   st1, st0                        ; add to autoc[0]
287         fstp    dword [edi]
288         fstp    dword [edi + 4]
289         fstp    dword [edi + 8]
290         fstp    dword [edi + 12]
291         fstp    dword [edi + 16]
292         jmp     .end
293
294 .lag_above_5:
295         cmp     edx, 6
296         ja      .lag_above_6
297 .lag_eq_6:
298         fldz                                    ; will accumulate autoc[5]
299         fldz                                    ; will accumulate autoc[4]
300         fldz                                    ; will accumulate autoc[3]
301         fldz                                    ; will accumulate autoc[2]
302         fldz                                    ; will accumulate autoc[1]
303         fldz                                    ; will accumulate autoc[0]
304         sub     ecx, byte 5
305         ALIGN 16
306 .lag_6_loop:
307         fld     dword [esi]
308         fld     st0
309         fmul    st0, st0
310         faddp   st2, st0                        ; add to autoc[0]
311         fld     dword [esi + 4]
312         fmul    st0, st1
313         faddp   st3, st0                        ; add to autoc[1]
314         fld     dword [esi + 8]
315         fmul    st0, st1
316         faddp   st4, st0                        ; add to autoc[2]
317         fld     dword [esi + 12]
318         fmul    st0, st1
319         faddp   st5, st0                        ; add to autoc[3]
320         fld     dword [esi + 16]
321         fmul    st0, st1
322         faddp   st6, st0                        ; add to autoc[4]
323         fld     dword [esi + 20]
324         fmulp   st1, st0
325         add     esi, byte 4                     ; [CR] sample++
326         faddp   st6, st0                        ; add to autoc[5]
327         dec     ecx
328         jnz     .lag_6_loop
329         ; clean up the leftovers
330         fld     dword [esi]
331         fld     st0
332         fmul    st0, st0
333         faddp   st2, st0                        ; add to autoc[0]
334         fld     dword [esi + 4]
335         fmul    st0, st1
336         faddp   st3, st0                        ; add to autoc[1]
337         fld     dword [esi + 8]
338         fmul    st0, st1
339         faddp   st4, st0                        ; add to autoc[2]
340         fld     dword [esi + 12]
341         fmul    st0, st1
342         faddp   st5, st0                        ; add to autoc[3]
343         fld     dword [esi + 16]
344         fmulp   st1, st0
345         add     esi, byte 4                     ; [CR] sample++
346         faddp   st5, st0                        ; add to autoc[4]
347         fld     dword [esi]
348         fld     st0
349         fmul    st0, st0
350         faddp   st2, st0                        ; add to autoc[0]
351         fld     dword [esi + 4]
352         fmul    st0, st1
353         faddp   st3, st0                        ; add to autoc[1]
354         fld     dword [esi + 8]
355         fmul    st0, st1
356         faddp   st4, st0                        ; add to autoc[2]
357         fld     dword [esi + 12]
358         fmulp   st1, st0
359         add     esi, byte 4                     ; [CR] sample++
360         faddp   st4, st0                        ; add to autoc[3]
361         fld     dword [esi]
362         fld     st0
363         fmul    st0, st0
364         faddp   st2, st0                        ; add to autoc[0]
365         fld     dword [esi + 4]
366         fmul    st0, st1
367         faddp   st3, st0                        ; add to autoc[1]
368         fld     dword [esi + 8]
369         fmulp   st1, st0
370         add     esi, byte 4                     ; [CR] sample++
371         faddp   st3, st0                        ; add to autoc[2]
372         fld     dword [esi]
373         fld     st0
374         fmul    st0, st0
375         faddp   st2, st0                        ; add to autoc[0]
376         fld     dword [esi + 4]
377         fmul    st1, st0
378         fxch
379         faddp   st3, st0                        ; add to autoc[1]
380         fmul    st0, st0
381         faddp   st1, st0                        ; add to autoc[0]
382         fstp    dword [edi]
383         fstp    dword [edi + 4]
384         fstp    dword [edi + 8]
385         fstp    dword [edi + 12]
386         fstp    dword [edi + 16]
387         fstp    dword [edi + 20]
388         jmp     .end
389
390 .lag_above_6:
391         ;       for(coeff = 0; coeff < lag; coeff++)
392         ;               autoc[coeff] = 0.0;
393         lea     ecx, [edx * 2]                  ; ecx = # of dwords of 0 to write
394         xor     eax, eax
395         rep     stosd
396         mov     ecx, [ebp + 4]                  ; ecx == data_len
397         mov     edi, [ebp + 12]                 ; edi == autoc
398         ;       const unsigned limit = data_len - lag;
399         sub     ecx, edx
400         inc     ecx                             ; we are looping <= limit so we add one to the counter
401         ;       for(sample = 0; sample <= limit; sample++){
402         ;               d = data[sample];
403         ;               for(coeff = 0; coeff < lag; coeff++)
404         ;                       autoc[coeff] += d * data[sample+coeff];
405         ;       }
406         xor     eax, eax                        ; eax == sample <- 0
407         ALIGN 16
408 .outer_loop:
409         push    eax                             ; save sample
410         fld     dword [esi + eax * 4]           ; ST = d <- data[sample]
411         mov     ebx, eax                        ; ebx == sample+coeff <- sample
412         mov     edx, [ebp + 8]                  ; edx <- lag
413         xor     eax, eax                        ; eax == coeff <- 0
414         ALIGN 16
415 .inner_loop:
416         fld     st0                             ; ST = d d
417         fmul    dword [esi + ebx * 4]           ; ST = d*data[sample+coeff] d
418         fadd    dword [edi + eax * 4]           ; ST = autoc[coeff]+d*data[sample+coeff] d
419         fstp    dword [edi + eax * 4]           ; autoc[coeff]+=d*data[sample+coeff]  ST = d
420         inc     ebx                             ; (sample+coeff)++
421         inc     eax                             ; coeff++
422         dec     edx
423         jnz     .inner_loop
424         pop     eax                             ; restore sample
425         fstp    st0                             ; pop d, ST = empty
426         inc     eax                             ; sample++
427         loop    .outer_loop
428         ;       for(; sample < data_len; sample++){
429         ;               d = data[sample];
430         ;               for(coeff = 0; coeff < data_len - sample; coeff++)
431         ;                       autoc[coeff] += d * data[sample+coeff];
432         ;       }
433         mov     ecx, [ebp + 8]                  ; ecx <- lag
434         dec     ecx                             ; ecx <- lag - 1
435         jz      .outer_end                      ; skip loop if 0
436 .outer_loop2:
437         push    eax                             ; save sample
438         fld     dword [esi + eax * 4]           ; ST = d <- data[sample]
439         mov     ebx, eax                        ; ebx == sample+coeff <- sample
440         mov     edx, [ebp + 4]                  ; edx <- data_len
441         sub     edx, eax                        ; edx <- data_len-sample
442         xor     eax, eax                        ; eax == coeff <- 0
443 .inner_loop2:
444         fld     st0                             ; ST = d d
445         fmul    dword [esi + ebx * 4]           ; ST = d*data[sample+coeff] d
446         fadd    dword [edi + eax * 4]           ; ST = autoc[coeff]+d*data[sample+coeff] d
447         fstp    dword [edi + eax * 4]           ; autoc[coeff]+=d*data[sample+coeff]  ST = d
448         inc     ebx                             ; (sample+coeff)++
449         inc     eax                             ; coeff++
450         dec     edx
451         jnz     .inner_loop2
452         pop     eax                             ; restore sample
453         fstp    st0                             ; pop d, ST = empty
454         inc     eax                             ; sample++
455         loop    .outer_loop2
456 .outer_end:
457         jmp     .end
458
459 .lag_eq_6_plus_1:
460         mov     ecx, [ebp + 4]                  ; ecx == data_len
461         mov     esi, [ebp]                      ; esi == data
462         mov     edi, [ebp + 12]                 ; edi == autoc
463         fldz                                    ; will accumulate autoc[6]
464         sub     ecx, byte 6
465         ALIGN 16
466 .lag_6_1_loop:
467         fld     dword [esi]
468         fld     dword [esi + 24]
469         fmulp   st1, st0
470         add     esi, byte 4                     ; [CR] sample++
471         faddp   st1, st0                        ; add to autoc[6]
472         dec     ecx
473         jnz     .lag_6_1_loop
474         fstp    dword [edi + 24]
475         jmp     .end
476
477 .lag_eq_6_plus_2:
478         mov     ecx, [ebp + 4]                  ; ecx == data_len
479         mov     esi, [ebp]                      ; esi == data
480         mov     edi, [ebp + 12]                 ; edi == autoc
481         fldz                                    ; will accumulate autoc[7]
482         fldz                                    ; will accumulate autoc[6]
483         sub     ecx, byte 7
484         ALIGN 16
485 .lag_6_2_loop:
486         fld     dword [esi]
487         fld     dword [esi + 24]
488         fmul    st0, st1
489         faddp   st2, st0                        ; add to autoc[6]
490         fld     dword [esi + 28]
491         fmulp   st1, st0
492         add     esi, byte 4                     ; [CR] sample++
493         faddp   st2, st0                        ; add to autoc[7]
494         dec     ecx
495         jnz     .lag_6_2_loop
496         ; clean up the leftovers
497         fld     dword [esi]
498         fld     dword [esi + 24]
499         fmulp   st1, st0
500         faddp   st1, st0                        ; add to autoc[6]
501         fstp    dword [edi + 24]
502         fstp    dword [edi + 28]
503         jmp     .end
504
505 .lag_eq_6_plus_3:
506         mov     ecx, [ebp + 4]                  ; ecx == data_len
507         mov     esi, [ebp]                      ; esi == data
508         mov     edi, [ebp + 12]                 ; edi == autoc
509         fldz                                    ; will accumulate autoc[8]
510         fldz                                    ; will accumulate autoc[7]
511         fldz                                    ; will accumulate autoc[6]
512         sub     ecx, byte 8
513         ALIGN 16
514 .lag_6_3_loop:
515         fld     dword [esi]
516         fld     dword [esi + 24]
517         fmul    st0, st1
518         faddp   st2, st0                        ; add to autoc[6]
519         fld     dword [esi + 28]
520         fmul    st0, st1
521         faddp   st3, st0                        ; add to autoc[7]
522         fld     dword [esi + 32]
523         fmulp   st1, st0
524         add     esi, byte 4                     ; [CR] sample++
525         faddp   st3, st0                        ; add to autoc[8]
526         dec     ecx
527         jnz     .lag_6_3_loop
528         ; clean up the leftovers
529         fld     dword [esi]
530         fld     dword [esi + 24]
531         fmul    st0, st1
532         faddp   st2, st0                        ; add to autoc[6]
533         fld     dword [esi + 28]
534         fmulp   st1, st0
535         add     esi, byte 4                     ; [CR] sample++
536         faddp   st2, st0                        ; add to autoc[7]
537         fld     dword [esi]
538         fld     dword [esi + 24]
539         fmulp   st1, st0
540         faddp   st1, st0                        ; add to autoc[6]
541         fstp    dword [edi + 24]
542         fstp    dword [edi + 28]
543         fstp    dword [edi + 32]
544         jmp     .end
545
546 .lag_eq_6_plus_4:
547         mov     ecx, [ebp + 4]                  ; ecx == data_len
548         mov     esi, [ebp]                      ; esi == data
549         mov     edi, [ebp + 12]                 ; edi == autoc
550         fldz                                    ; will accumulate autoc[9]
551         fldz                                    ; will accumulate autoc[8]
552         fldz                                    ; will accumulate autoc[7]
553         fldz                                    ; will accumulate autoc[6]
554         sub     ecx, byte 9
555         ALIGN 16
556 .lag_6_4_loop:
557         fld     dword [esi]
558         fld     dword [esi + 24]
559         fmul    st0, st1
560         faddp   st2, st0                        ; add to autoc[6]
561         fld     dword [esi + 28]
562         fmul    st0, st1
563         faddp   st3, st0                        ; add to autoc[7]
564         fld     dword [esi + 32]
565         fmul    st0, st1
566         faddp   st4, st0                        ; add to autoc[8]
567         fld     dword [esi + 36]
568         fmulp   st1, st0
569         add     esi, byte 4                     ; [CR] sample++
570         faddp   st4, st0                        ; add to autoc[9]
571         dec     ecx
572         jnz     .lag_6_4_loop
573         ; clean up the leftovers
574         fld     dword [esi]
575         fld     dword [esi + 24]
576         fmul    st0, st1
577         faddp   st2, st0                        ; add to autoc[6]
578         fld     dword [esi + 28]
579         fmul    st0, st1
580         faddp   st3, st0                        ; add to autoc[7]
581         fld     dword [esi + 32]
582         fmulp   st1, st0
583         add     esi, byte 4                     ; [CR] sample++
584         faddp   st3, st0                        ; add to autoc[8]
585         fld     dword [esi]
586         fld     dword [esi + 24]
587         fmul    st0, st1
588         faddp   st2, st0                        ; add to autoc[6]
589         fld     dword [esi + 28]
590         fmulp   st1, st0
591         add     esi, byte 4                     ; [CR] sample++
592         faddp   st2, st0                        ; add to autoc[7]
593         fld     dword [esi]
594         fld     dword [esi + 24]
595         fmulp   st1, st0
596         faddp   st1, st0                        ; add to autoc[6]
597         fstp    dword [edi + 24]
598         fstp    dword [edi + 28]
599         fstp    dword [edi + 32]
600         fstp    dword [edi + 36]
601         jmp     .end
602
603 .lag_eq_6_plus_5:
604         mov     ecx, [ebp + 4]                  ; ecx == data_len
605         mov     esi, [ebp]                      ; esi == data
606         mov     edi, [ebp + 12]                 ; edi == autoc
607         fldz                                    ; will accumulate autoc[10]
608         fldz                                    ; will accumulate autoc[9]
609         fldz                                    ; will accumulate autoc[8]
610         fldz                                    ; will accumulate autoc[7]
611         fldz                                    ; will accumulate autoc[6]
612         sub     ecx, byte 10
613         ALIGN 16
614 .lag_6_5_loop:
615         fld     dword [esi]
616         fld     dword [esi + 24]
617         fmul    st0, st1
618         faddp   st2, st0                        ; add to autoc[6]
619         fld     dword [esi + 28]
620         fmul    st0, st1
621         faddp   st3, st0                        ; add to autoc[7]
622         fld     dword [esi + 32]
623         fmul    st0, st1
624         faddp   st4, st0                        ; add to autoc[8]
625         fld     dword [esi + 36]
626         fmul    st0, st1
627         faddp   st5, st0                        ; add to autoc[9]
628         fld     dword [esi + 40]
629         fmulp   st1, st0
630         add     esi, byte 4                     ; [CR] sample++
631         faddp   st5, st0                        ; add to autoc[10]
632         dec     ecx
633         jnz     .lag_6_5_loop
634         ; clean up the leftovers
635         fld     dword [esi]
636         fld     dword [esi + 24]
637         fmul    st0, st1
638         faddp   st2, st0                        ; add to autoc[6]
639         fld     dword [esi + 28]
640         fmul    st0, st1
641         faddp   st3, st0                        ; add to autoc[7]
642         fld     dword [esi + 32]
643         fmul    st0, st1
644         faddp   st4, st0                        ; add to autoc[8]
645         fld     dword [esi + 36]
646         fmulp   st1, st0
647         add     esi, byte 4                     ; [CR] sample++
648         faddp   st4, st0                        ; add to autoc[9]
649         fld     dword [esi]
650         fld     dword [esi + 24]
651         fmul    st0, st1
652         faddp   st2, st0                        ; add to autoc[6]
653         fld     dword [esi + 28]
654         fmul    st0, st1
655         faddp   st3, st0                        ; add to autoc[7]
656         fld     dword [esi + 32]
657         fmulp   st1, st0
658         add     esi, byte 4                     ; [CR] sample++
659         faddp   st3, st0                        ; add to autoc[8]
660         fld     dword [esi]
661         fld     dword [esi + 24]
662         fmul    st0, st1
663         faddp   st2, st0                        ; add to autoc[6]
664         fld     dword [esi + 28]
665         fmulp   st1, st0
666         add     esi, byte 4                     ; [CR] sample++
667         faddp   st2, st0                        ; add to autoc[7]
668         fld     dword [esi]
669         fld     dword [esi + 24]
670         fmulp   st1, st0
671         faddp   st1, st0                        ; add to autoc[6]
672         fstp    dword [edi + 24]
673         fstp    dword [edi + 28]
674         fstp    dword [edi + 32]
675         fstp    dword [edi + 36]
676         fstp    dword [edi + 40]
677         jmp     .end
678
679 .lag_eq_6_plus_6:
680         mov     ecx, [ebp + 4]                  ; ecx == data_len
681         mov     esi, [ebp]                      ; esi == data
682         mov     edi, [ebp + 12]                 ; edi == autoc
683         fldz                                    ; will accumulate autoc[11]
684         fldz                                    ; will accumulate autoc[10]
685         fldz                                    ; will accumulate autoc[9]
686         fldz                                    ; will accumulate autoc[8]
687         fldz                                    ; will accumulate autoc[7]
688         fldz                                    ; will accumulate autoc[6]
689         sub     ecx, byte 11
690         ALIGN 16
691 .lag_6_6_loop:
692         fld     dword [esi]
693         fld     dword [esi + 24]
694         fmul    st0, st1
695         faddp   st2, st0                        ; add to autoc[6]
696         fld     dword [esi + 28]
697         fmul    st0, st1
698         faddp   st3, st0                        ; add to autoc[7]
699         fld     dword [esi + 32]
700         fmul    st0, st1
701         faddp   st4, st0                        ; add to autoc[8]
702         fld     dword [esi + 36]
703         fmul    st0, st1
704         faddp   st5, st0                        ; add to autoc[9]
705         fld     dword [esi + 40]
706         fmul    st0, st1
707         faddp   st6, st0                        ; add to autoc[10]
708         fld     dword [esi + 44]
709         fmulp   st1, st0
710         add     esi, byte 4                     ; [CR] sample++
711         faddp   st6, st0                        ; add to autoc[11]
712         dec     ecx
713         jnz     .lag_6_6_loop
714         ; clean up the leftovers
715         fld     dword [esi]
716         fld     dword [esi + 24]
717         fmul    st0, st1
718         faddp   st2, st0                        ; add to autoc[6]
719         fld     dword [esi + 28]
720         fmul    st0, st1
721         faddp   st3, st0                        ; add to autoc[7]
722         fld     dword [esi + 32]
723         fmul    st0, st1
724         faddp   st4, st0                        ; add to autoc[8]
725         fld     dword [esi + 36]
726         fmul    st0, st1
727         faddp   st5, st0                        ; add to autoc[9]
728         fld     dword [esi + 40]
729         fmulp   st1, st0
730         add     esi, byte 4                     ; [CR] sample++
731         faddp   st5, st0                        ; add to autoc[10]
732         fld     dword [esi]
733         fld     dword [esi + 24]
734         fmul    st0, st1
735         faddp   st2, st0                        ; add to autoc[6]
736         fld     dword [esi + 28]
737         fmul    st0, st1
738         faddp   st3, st0                        ; add to autoc[7]
739         fld     dword [esi + 32]
740         fmul    st0, st1
741         faddp   st4, st0                        ; add to autoc[8]
742         fld     dword [esi + 36]
743         fmulp   st1, st0
744         add     esi, byte 4                     ; [CR] sample++
745         faddp   st4, st0                        ; add to autoc[9]
746         fld     dword [esi]
747         fld     dword [esi + 24]
748         fmul    st0, st1
749         faddp   st2, st0                        ; add to autoc[6]
750         fld     dword [esi + 28]
751         fmul    st0, st1
752         faddp   st3, st0                        ; add to autoc[7]
753         fld     dword [esi + 32]
754         fmulp   st1, st0
755         add     esi, byte 4                     ; [CR] sample++
756         faddp   st3, st0                        ; add to autoc[8]
757         fld     dword [esi]
758         fld     dword [esi + 24]
759         fmul    st0, st1
760         faddp   st2, st0                        ; add to autoc[6]
761         fld     dword [esi + 28]
762         fmulp   st1, st0
763         add     esi, byte 4                     ; [CR] sample++
764         faddp   st2, st0                        ; add to autoc[7]
765         fld     dword [esi]
766         fld     dword [esi + 24]
767         fmulp   st1, st0
768         faddp   st1, st0                        ; add to autoc[6]
769         fstp    dword [edi + 24]
770         fstp    dword [edi + 28]
771         fstp    dword [edi + 32]
772         fstp    dword [edi + 36]
773         fstp    dword [edi + 40]
774         fstp    dword [edi + 44]
775         jmp     .end
776
777 .end:
778         pop     edi
779         pop     esi
780         pop     ebx
781         pop     ebp
782         ret
783
784 end