minor formatting changes
[flac.git] / src / libFLAC / ia32 / lpc_asm-unrolled.nasm
1 ; libFLAC - Free Lossless Audio Codec library
2 ; Copyright (C) 2001  Josh Coalson
3 ;
4 ; This library is free software; you can redistribute it and/or
5 ; modify it under the terms of the GNU Library General Public
6 ; License as published by the Free Software Foundation; either
7 ; version 2 of the License, or (at your option) any later version.
8 ;
9 ; This library is distributed in the hope that it will be useful,
10 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 ; Library General Public License for more details.
13 ;
14 ; You should have received a copy of the GNU Library General Public
15 ; License along with this library; if not, write to the
16 ; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 ; Boston, MA  02111-1307, USA.
18
19 ; [CR] is a note to flag that the instruction can be easily reordered
20
21 %include "nasm.h"
22
23         data_section
24
25 cglobal FLAC__lpc_compute_autocorrelation_asm
26
27         code_section
28
29 ; **********************************************************************
30 ;
31 ; void FLAC__lpc_compute_autocorrelation_asm(const real data[], unsigned data_len, unsigned lag, real autoc[])
32 ; {
33 ;       real d;
34 ;       unsigned sample, coeff;
35 ;       const unsigned limit = data_len - lag;
36 ;
37 ;       assert(lag > 0);
38 ;       assert(lag <= data_len);
39 ;
40 ;       for(coeff = 0; coeff < lag; coeff++)
41 ;               autoc[coeff] = 0.0;
42 ;       for(sample = 0; sample <= limit; sample++){
43 ;               d = data[sample];
44 ;               for(coeff = 0; coeff < lag; coeff++)
45 ;                       autoc[coeff] += d * data[sample+coeff];
46 ;       }
47 ;       for(; sample < data_len; sample++){
48 ;               d = data[sample];
49 ;               for(coeff = 0; coeff < data_len - sample; coeff++)
50 ;                       autoc[coeff] += d * data[sample+coeff];
51 ;       }
52 ; }
53 ;
54 FLAC__lpc_compute_autocorrelation_asm:
55
56         push    ebp
57         lea     ebp, [esp + 8]
58         push    ebx
59         push    esi
60         push    edi
61
62         mov     edx, [ebp + 8]                  ; edx == lag
63         mov     ecx, [ebp + 4]                  ; ecx == data_len
64         mov     esi, [ebp]                      ; esi == data
65         mov     edi, [ebp + 12]                 ; edi == autoc
66
67         cmp     edx, 1
68         ja      short .lag_above_1
69 .lag_eq_1:
70         fldz                                    ; will accumulate autoc[0]
71         ALIGN 16
72 .lag_1_loop:
73         fld     dword [esi]
74         add     esi, byte 4                     ; sample++
75         fmul    st0, st0
76         faddp   st1, st0
77         dec     ecx
78         jnz     .lag_1_loop
79         fstp    dword [edi]
80         jmp     .end
81
82 .lag_above_1:
83         cmp     edx, 2
84         ja      short .lag_above_2
85 .lag_eq_2:
86         fldz                                    ; will accumulate autoc[1]
87         dec     ecx
88         fldz                                    ; will accumulate autoc[0]
89         fld     dword [esi]
90         ALIGN 16
91 .lag_2_loop:
92         add     esi, byte 4                     ; [CR] sample++
93         fld     st0
94         fmul    st0, st0
95         faddp   st2, st0                        ; add to autoc[0]
96         fld     dword [esi]
97         fmul    st1, st0
98         fxch
99         faddp   st3, st0                        ; add to autoc[1]
100         dec     ecx
101         jnz     .lag_2_loop
102         ; clean up the leftovers
103         fmul    st0, st0
104         faddp   st1, st0                        ; add to autoc[0]
105         fstp    dword [edi]
106         fstp    dword [edi + 4]
107         jmp     .end
108
109 .lag_above_2:
110         cmp     edx, 3
111         ja      short .lag_above_3
112 .lag_eq_3:
113         fldz                                    ; will accumulate autoc[2]
114         dec     ecx
115         fldz                                    ; will accumulate autoc[1]
116         dec     ecx
117         fldz                                    ; will accumulate autoc[0]
118         ALIGN 16
119 .lag_3_loop:
120         fld     dword [esi]
121         fld     st0
122         fmul    st0, st0
123         faddp   st2, st0                        ; add to autoc[0]
124         fld     dword [esi + 4]
125         fmul    st0, st1
126         faddp   st3, st0                        ; add to autoc[1]
127         fld     dword [esi + 8]
128         fmulp   st1, st0
129         add     esi, byte 4                     ; [CR] sample++
130         faddp   st3, st0                        ; add to autoc[2]
131         dec     ecx
132         jnz     .lag_3_loop
133         ; clean up the leftovers
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    st1, st0
140         fxch
141         faddp   st3, st0                        ; add to autoc[1]
142         fmul    st0, st0
143         faddp   st1, st0                        ; add to autoc[0]
144         fstp    dword [edi]
145         fstp    dword [edi + 4]
146         fstp    dword [edi + 8]
147         jmp     .end
148
149 .lag_above_3:
150         cmp     edx, 4
151         ja      near .lag_above_4
152 .lag_eq_4:
153         fldz                                    ; will accumulate autoc[3]
154         dec     ecx
155         fldz                                    ; will accumulate autoc[2]
156         dec     ecx
157         fldz                                    ; will accumulate autoc[1]
158         dec     ecx
159         fldz                                    ; will accumulate autoc[0]
160         ALIGN 16
161 .lag_4_loop:
162         fld     dword [esi]
163         fld     st0
164         fmul    st0, st0
165         faddp   st2, st0                        ; add to autoc[0]
166         fld     dword [esi + 4]
167         fmul    st0, st1
168         faddp   st3, st0                        ; add to autoc[1]
169         fld     dword [esi + 8]
170         fmul    st0, st1
171         faddp   st4, st0                        ; add to autoc[2]
172         fld     dword [esi + 12]
173         fmulp   st1, st0
174         add     esi, byte 4                     ; [CR] sample++
175         faddp   st4, st0                        ; add to autoc[3]
176         dec     ecx
177         jnz     .lag_4_loop
178         ; clean up the leftovers
179         fld     dword [esi]
180         fld     st0
181         fmul    st0, st0
182         faddp   st2, st0                        ; add to autoc[0]
183         fld     dword [esi + 4]
184         fmul    st0, st1
185         faddp   st3, st0                        ; add to autoc[1]
186         fld     dword [esi + 8]
187         fmulp   st1, st0
188         add     esi, byte 4                     ; [CR] sample++
189         faddp   st3, st0                        ; add to autoc[2]
190         fld     dword [esi]
191         fld     st0
192         fmul    st0, st0
193         faddp   st2, st0                        ; add to autoc[0]
194         fld     dword [esi + 4]
195         fmul    st1, st0
196         fxch
197         faddp   st3, st0                        ; add to autoc[1]
198         fmul    st0, st0
199         faddp   st1, st0                        ; add to autoc[0]
200         fstp    dword [edi]
201         fstp    dword [edi + 4]
202         fstp    dword [edi + 8]
203         fstp    dword [edi + 12]
204         jmp     .end
205
206 .lag_above_4:
207         cmp     edx, 5
208         ja      near .lag_above_5
209 .lag_eq_5:
210         fldz                                    ; will accumulate autoc[4]
211         fldz                                    ; will accumulate autoc[3]
212         fldz                                    ; will accumulate autoc[2]
213         fldz                                    ; will accumulate autoc[1]
214         fldz                                    ; will accumulate autoc[0]
215         sub     ecx, byte 4
216         ALIGN 16
217 .lag_5_loop:
218         fld     dword [esi]
219         fld     st0
220         fmul    st0, st0
221         faddp   st2, st0                        ; add to autoc[0]
222         fld     dword [esi + 4]
223         fmul    st0, st1
224         faddp   st3, st0                        ; add to autoc[1]
225         fld     dword [esi + 8]
226         fmul    st0, st1
227         faddp   st4, st0                        ; add to autoc[2]
228         fld     dword [esi + 12]
229         fmul    st0, st1
230         faddp   st5, st0                        ; add to autoc[3]
231         fld     dword [esi + 16]
232         fmulp   st1, st0
233         add     esi, byte 4                     ; [CR] sample++
234         faddp   st5, st0                        ; add to autoc[4]
235         dec     ecx
236         jnz     .lag_5_loop
237         ; clean up the leftovers
238         fld     dword [esi]
239         fld     st0
240         fmul    st0, st0
241         faddp   st2, st0                        ; add to autoc[0]
242         fld     dword [esi + 4]
243         fmul    st0, st1
244         faddp   st3, st0                        ; add to autoc[1]
245         fld     dword [esi + 8]
246         fmul    st0, st1
247         faddp   st4, st0                        ; add to autoc[2]
248         fld     dword [esi + 12]
249         fmulp   st1, st0
250         add     esi, byte 4                     ; [CR] sample++
251         faddp   st4, st0                        ; add to autoc[3]
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         fmulp   st1, st0
261         add     esi, byte 4                     ; [CR] sample++
262         faddp   st3, st0                        ; add to autoc[2]
263         fld     dword [esi]
264         fld     st0
265         fmul    st0, st0
266         faddp   st2, st0                        ; add to autoc[0]
267         fld     dword [esi + 4]
268         fmul    st1, st0
269         fxch
270         faddp   st3, st0                        ; add to autoc[1]
271         fmul    st0, st0
272         faddp   st1, st0                        ; add to autoc[0]
273         fstp    dword [edi]
274         fstp    dword [edi + 4]
275         fstp    dword [edi + 8]
276         fstp    dword [edi + 12]
277         fstp    dword [edi + 16]
278         jmp     .end
279
280 .lag_above_5:
281         cmp     edx, 6
282         ja      .lag_above_6
283 .lag_eq_6:
284         fldz                                    ; will accumulate autoc[5]
285         fldz                                    ; will accumulate autoc[4]
286         fldz                                    ; will accumulate autoc[3]
287         fldz                                    ; will accumulate autoc[2]
288         fldz                                    ; will accumulate autoc[1]
289         fldz                                    ; will accumulate autoc[0]
290         sub     ecx, byte 5
291         ALIGN 16
292 .lag_6_loop:
293         fld     dword [esi]
294         fld     st0
295         fmul    st0, st0
296         faddp   st2, st0                        ; add to autoc[0]
297         fld     dword [esi + 4]
298         fmul    st0, st1
299         faddp   st3, st0                        ; add to autoc[1]
300         fld     dword [esi + 8]
301         fmul    st0, st1
302         faddp   st4, st0                        ; add to autoc[2]
303         fld     dword [esi + 12]
304         fmul    st0, st1
305         faddp   st5, st0                        ; add to autoc[3]
306         fld     dword [esi + 16]
307         fmul    st0, st1
308         faddp   st6, st0                        ; add to autoc[4]
309         fld     dword [esi + 20]
310         fmulp   st1, st0
311         add     esi, byte 4                     ; [CR] sample++
312         faddp   st6, st0                        ; add to autoc[5]
313         dec     ecx
314         jnz     .lag_6_loop
315         ; clean up the leftovers
316         fld     dword [esi]
317         fld     st0
318         fmul    st0, st0
319         faddp   st2, st0                        ; add to autoc[0]
320         fld     dword [esi + 4]
321         fmul    st0, st1
322         faddp   st3, st0                        ; add to autoc[1]
323         fld     dword [esi + 8]
324         fmul    st0, st1
325         faddp   st4, st0                        ; add to autoc[2]
326         fld     dword [esi + 12]
327         fmul    st0, st1
328         faddp   st5, st0                        ; add to autoc[3]
329         fld     dword [esi + 16]
330         fmulp   st1, st0
331         add     esi, byte 4                     ; [CR] sample++
332         faddp   st5, st0                        ; add to autoc[4]
333         fld     dword [esi]
334         fld     st0
335         fmul    st0, st0
336         faddp   st2, st0                        ; add to autoc[0]
337         fld     dword [esi + 4]
338         fmul    st0, st1
339         faddp   st3, st0                        ; add to autoc[1]
340         fld     dword [esi + 8]
341         fmul    st0, st1
342         faddp   st4, st0                        ; add to autoc[2]
343         fld     dword [esi + 12]
344         fmulp   st1, st0
345         add     esi, byte 4                     ; [CR] sample++
346         faddp   st4, st0                        ; add to autoc[3]
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         fmulp   st1, st0
356         add     esi, byte 4                     ; [CR] sample++
357         faddp   st3, st0                        ; add to autoc[2]
358         fld     dword [esi]
359         fld     st0
360         fmul    st0, st0
361         faddp   st2, st0                        ; add to autoc[0]
362         fld     dword [esi + 4]
363         fmul    st1, st0
364         fxch
365         faddp   st3, st0                        ; add to autoc[1]
366         fmul    st0, st0
367         faddp   st1, st0                        ; add to autoc[0]
368         fstp    dword [edi]
369         fstp    dword [edi + 4]
370         fstp    dword [edi + 8]
371         fstp    dword [edi + 12]
372         fstp    dword [edi + 16]
373         fstp    dword [edi + 20]
374         jmp     .end
375
376 .lag_above_6:
377         ;       for(coeff = 0; coeff < lag; coeff++)
378         ;               autoc[coeff] = 0.0;
379         lea     ecx, [edx * 2]                  ; ecx = # of dwords of 0 to write
380         xor     eax, eax
381         rep     stosd
382         mov     ecx, [ebp + 4]                  ; ecx == data_len
383         mov     edi, [ebp + 12]                 ; edi == autoc
384         ;       const unsigned limit = data_len - lag;
385         sub     ecx, edx
386         inc     ecx                             ; we are looping <= limit so we add one to the counter
387         ;       for(sample = 0; sample <= limit; sample++){
388         ;               d = data[sample];
389         ;               for(coeff = 0; coeff < lag; coeff++)
390         ;                       autoc[coeff] += d * data[sample+coeff];
391         ;       }
392         xor     eax, eax                        ; eax == sample <- 0
393         ALIGN 16
394 .outer_loop:
395         push    eax                             ; save sample
396         fld     dword [esi + eax * 4]           ; ST = d <- data[sample]
397         mov     ebx, eax                        ; ebx == sample+coeff <- sample
398         mov     edx, [ebp + 8]                  ; edx <- lag
399         xor     eax, eax                        ; eax == coeff <- 0
400         ALIGN 16
401 .inner_loop:
402         fld     st0                             ; ST = d d
403         fmul    dword [esi + ebx * 4]           ; ST = d*data[sample+coeff] d
404         fadd    dword [edi + eax * 4]           ; ST = autoc[coeff]+d*data[sample+coeff] d
405         fstp    dword [edi + eax * 4]           ; autoc[coeff]+=d*data[sample+coeff]  ST = d
406         inc     ebx                             ; (sample+coeff)++
407         inc     eax                             ; coeff++
408         dec     edx
409         jnz     .inner_loop
410         pop     eax                             ; restore sample
411         fstp    st0                             ; pop d, ST = empty
412         inc     eax                             ; sample++
413         loop    .outer_loop
414         ;       for(; sample < data_len; sample++){
415         ;               d = data[sample];
416         ;               for(coeff = 0; coeff < data_len - sample; coeff++)
417         ;                       autoc[coeff] += d * data[sample+coeff];
418         ;       }
419         mov     ecx, [ebp + 8]                  ; ecx <- lag
420         dec     ecx                             ; ecx <- lag - 1
421         jz      .outer_end                      ; skip loop if 0
422 .outer_loop2:
423         push    eax                             ; save sample
424         fld     dword [esi + eax * 4]           ; ST = d <- data[sample]
425         mov     ebx, eax                        ; ebx == sample+coeff <- sample
426         mov     edx, [ebp + 4]                  ; edx <- data_len
427         sub     edx, eax                        ; edx <- data_len-sample
428         xor     eax, eax                        ; eax == coeff <- 0
429 .inner_loop2:
430         fld     st0                             ; ST = d d
431         fmul    dword [esi + ebx * 4]           ; ST = d*data[sample+coeff] d
432         fadd    dword [edi + eax * 4]           ; ST = autoc[coeff]+d*data[sample+coeff] d
433         fstp    dword [edi + eax * 4]           ; autoc[coeff]+=d*data[sample+coeff]  ST = d
434         inc     ebx                             ; (sample+coeff)++
435         inc     eax                             ; coeff++
436         dec     edx
437         jnz     .inner_loop2
438         pop     eax                             ; restore sample
439         fstp    st0                             ; pop d, ST = empty
440         inc     eax                             ; sample++
441         loop    .outer_loop2
442 .outer_end:
443         jmp     .end
444
445 .lag_eq_6_1:
446         mov     ecx, [ebp + 4]                  ; ecx == data_len
447         mov     esi, [ebp]                      ; esi == data
448         mov     edi, [ebp + 12]                 ; edi == autoc
449         fldz                                    ; will accumulate autoc[6]
450         sub     ecx, byte 6
451         ALIGN 16
452 .lag_6_1_loop:
453         fld     dword [esi]
454         fld     dword [esi + 24]
455         fmulp   st1, st0
456         add     esi, byte 4                     ; [CR] sample++
457         faddp   st1, st0                        ; add to autoc[6]
458         dec     ecx
459         jnz     .lag_6_1_loop
460         fstp    dword [edi + 24]
461         jmp     .end
462
463 .lag_eq_6_2:
464         mov     ecx, [ebp + 4]                  ; ecx == data_len
465         mov     esi, [ebp]                      ; esi == data
466         mov     edi, [ebp + 12]                 ; edi == autoc
467         fldz                                    ; will accumulate autoc[7]
468         fldz                                    ; will accumulate autoc[6]
469         sub     ecx, byte 7
470         ALIGN 16
471 .lag_6_2_loop:
472         fld     dword [esi]
473         fld     dword [esi + 24]
474         fmul    st0, st1
475         faddp   st2, st0                        ; add to autoc[6]
476         fld     dword [esi + 28]
477         fmulp   st1, st0
478         add     esi, byte 4                     ; [CR] sample++
479         faddp   st2, st0                        ; add to autoc[7]
480         dec     ecx
481         jnz     .lag_6_2_loop
482         ; clean up the leftovers
483         fld     dword [esi]
484         fld     dword [esi + 24]
485         fmulp   st1, st0
486         faddp   st1, st0                        ; add to autoc[6]
487         fstp    dword [edi + 24]
488         fstp    dword [edi + 28]
489         jmp     .end
490
491 .lag_eq_6_3:
492         mov     ecx, [ebp + 4]                  ; ecx == data_len
493         mov     esi, [ebp]                      ; esi == data
494         mov     edi, [ebp + 12]                 ; edi == autoc
495         fldz                                    ; will accumulate autoc[8]
496         fldz                                    ; will accumulate autoc[7]
497         fldz                                    ; will accumulate autoc[6]
498         sub     ecx, byte 8
499         ALIGN 16
500 .lag_6_3_loop:
501         fld     dword [esi]
502         fld     dword [esi + 24]
503         fmul    st0, st1
504         faddp   st2, st0                        ; add to autoc[6]
505         fld     dword [esi + 28]
506         fmul    st0, st1
507         faddp   st3, st0                        ; add to autoc[7]
508         fld     dword [esi + 32]
509         fmulp   st1, st0
510         add     esi, byte 4                     ; [CR] sample++
511         faddp   st3, st0                        ; add to autoc[8]
512         dec     ecx
513         jnz     .lag_6_3_loop
514         ; clean up the leftovers
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         fmulp   st1, st0
521         add     esi, byte 4                     ; [CR] sample++
522         faddp   st2, st0                        ; add to autoc[7]
523         fld     dword [esi]
524         fld     dword [esi + 24]
525         fmulp   st1, st0
526         faddp   st1, st0                        ; add to autoc[6]
527         fstp    dword [edi + 24]
528         fstp    dword [edi + 28]
529         fstp    dword [edi + 32]
530         jmp     .end
531
532 .lag_eq_6_4:
533         mov     ecx, [ebp + 4]                  ; ecx == data_len
534         mov     esi, [ebp]                      ; esi == data
535         mov     edi, [ebp + 12]                 ; edi == autoc
536         fldz                                    ; will accumulate autoc[9]
537         fldz                                    ; will accumulate autoc[8]
538         fldz                                    ; will accumulate autoc[7]
539         fldz                                    ; will accumulate autoc[6]
540         sub     ecx, byte 9
541         ALIGN 16
542 .lag_6_4_loop:
543         fld     dword [esi]
544         fld     dword [esi + 24]
545         fmul    st0, st1
546         faddp   st2, st0                        ; add to autoc[6]
547         fld     dword [esi + 28]
548         fmul    st0, st1
549         faddp   st3, st0                        ; add to autoc[7]
550         fld     dword [esi + 32]
551         fmul    st0, st1
552         faddp   st4, st0                        ; add to autoc[8]
553         fld     dword [esi + 36]
554         fmulp   st1, st0
555         add     esi, byte 4                     ; [CR] sample++
556         faddp   st4, st0                        ; add to autoc[9]
557         dec     ecx
558         jnz     .lag_6_4_loop
559         ; clean up the leftovers
560         fld     dword [esi]
561         fld     dword [esi + 24]
562         fmul    st0, st1
563         faddp   st2, st0                        ; add to autoc[6]
564         fld     dword [esi + 28]
565         fmul    st0, st1
566         faddp   st3, st0                        ; add to autoc[7]
567         fld     dword [esi + 32]
568         fmulp   st1, st0
569         add     esi, byte 4                     ; [CR] sample++
570         faddp   st3, st0                        ; add to autoc[8]
571         fld     dword [esi]
572         fld     dword [esi + 24]
573         fmul    st0, st1
574         faddp   st2, st0                        ; add to autoc[6]
575         fld     dword [esi + 28]
576         fmulp   st1, st0
577         add     esi, byte 4                     ; [CR] sample++
578         faddp   st2, st0                        ; add to autoc[7]
579         fld     dword [esi]
580         fld     dword [esi + 24]
581         fmulp   st1, st0
582         faddp   st1, st0                        ; add to autoc[6]
583         fstp    dword [edi + 24]
584         fstp    dword [edi + 28]
585         fstp    dword [edi + 32]
586         fstp    dword [edi + 36]
587         jmp     .end
588
589 .lag_eq_6_5:
590         mov     ecx, [ebp + 4]                  ; ecx == data_len
591         mov     esi, [ebp]                      ; esi == data
592         mov     edi, [ebp + 12]                 ; edi == autoc
593         fldz                                    ; will accumulate autoc[10]
594         fldz                                    ; will accumulate autoc[9]
595         fldz                                    ; will accumulate autoc[8]
596         fldz                                    ; will accumulate autoc[7]
597         fldz                                    ; will accumulate autoc[6]
598         sub     ecx, byte 10
599         ALIGN 16
600 .lag_6_5_loop:
601         fld     dword [esi]
602         fld     dword [esi + 24]
603         fmul    st0, st1
604         faddp   st2, st0                        ; add to autoc[6]
605         fld     dword [esi + 28]
606         fmul    st0, st1
607         faddp   st3, st0                        ; add to autoc[7]
608         fld     dword [esi + 32]
609         fmul    st0, st1
610         faddp   st4, st0                        ; add to autoc[8]
611         fld     dword [esi + 36]
612         fmul    st0, st1
613         faddp   st5, st0                        ; add to autoc[9]
614         fld     dword [esi + 40]
615         fmulp   st1, st0
616         add     esi, byte 4                     ; [CR] sample++
617         faddp   st5, st0                        ; add to autoc[10]
618         dec     ecx
619         jnz     .lag_6_5_loop
620         ; clean up the leftovers
621         fld     dword [esi]
622         fld     dword [esi + 24]
623         fmul    st0, st1
624         faddp   st2, st0                        ; add to autoc[6]
625         fld     dword [esi + 28]
626         fmul    st0, st1
627         faddp   st3, st0                        ; add to autoc[7]
628         fld     dword [esi + 32]
629         fmul    st0, st1
630         faddp   st4, st0                        ; add to autoc[8]
631         fld     dword [esi + 36]
632         fmulp   st1, st0
633         add     esi, byte 4                     ; [CR] sample++
634         faddp   st4, st0                        ; add to autoc[9]
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         fmulp   st1, st0
644         add     esi, byte 4                     ; [CR] sample++
645         faddp   st3, st0                        ; add to autoc[8]
646         fld     dword [esi]
647         fld     dword [esi + 24]
648         fmul    st0, st1
649         faddp   st2, st0                        ; add to autoc[6]
650         fld     dword [esi + 28]
651         fmulp   st1, st0
652         add     esi, byte 4                     ; [CR] sample++
653         faddp   st2, st0                        ; add to autoc[7]
654         fld     dword [esi]
655         fld     dword [esi + 24]
656         fmulp   st1, st0
657         faddp   st1, st0                        ; add to autoc[6]
658         fstp    dword [edi + 24]
659         fstp    dword [edi + 28]
660         fstp    dword [edi + 32]
661         fstp    dword [edi + 36]
662         fstp    dword [edi + 40]
663         jmp     .end
664
665 .lag_eq_6_6:
666         mov     ecx, [ebp + 4]                  ; ecx == data_len
667         mov     esi, [ebp]                      ; esi == data
668         mov     edi, [ebp + 12]                 ; edi == autoc
669         fldz                                    ; will accumulate autoc[11]
670         fldz                                    ; will accumulate autoc[10]
671         fldz                                    ; will accumulate autoc[9]
672         fldz                                    ; will accumulate autoc[8]
673         fldz                                    ; will accumulate autoc[7]
674         fldz                                    ; will accumulate autoc[6]
675         sub     ecx, byte 11
676         ALIGN 16
677 .lag_6_6_loop:
678         fld     dword [esi]
679         fld     dword [esi + 24]
680         fmul    st0, st1
681         faddp   st2, st0                        ; add to autoc[6]
682         fld     dword [esi + 28]
683         fmul    st0, st1
684         faddp   st3, st0                        ; add to autoc[7]
685         fld     dword [esi + 32]
686         fmul    st0, st1
687         faddp   st4, st0                        ; add to autoc[8]
688         fld     dword [esi + 36]
689         fmul    st0, st1
690         faddp   st5, st0                        ; add to autoc[9]
691         fld     dword [esi + 40]
692         fmul    st0, st1
693         faddp   st6, st0                        ; add to autoc[10]
694         fld     dword [esi + 44]
695         fmulp   st1, st0
696         add     esi, byte 4                     ; [CR] sample++
697         faddp   st6, st0                        ; add to autoc[11]
698         dec     ecx
699         jnz     .lag_6_6_loop
700         ; clean up the leftovers
701         fld     dword [esi]
702         fld     dword [esi + 24]
703         fmul    st0, st1
704         faddp   st2, st0                        ; add to autoc[6]
705         fld     dword [esi + 28]
706         fmul    st0, st1
707         faddp   st3, st0                        ; add to autoc[7]
708         fld     dword [esi + 32]
709         fmul    st0, st1
710         faddp   st4, st0                        ; add to autoc[8]
711         fld     dword [esi + 36]
712         fmul    st0, st1
713         faddp   st5, st0                        ; add to autoc[9]
714         fld     dword [esi + 40]
715         fmulp   st1, st0
716         add     esi, byte 4                     ; [CR] sample++
717         faddp   st5, st0                        ; add to autoc[10]
718         fld     dword [esi]
719         fld     dword [esi + 24]
720         fmul    st0, st1
721         faddp   st2, st0                        ; add to autoc[6]
722         fld     dword [esi + 28]
723         fmul    st0, st1
724         faddp   st3, st0                        ; add to autoc[7]
725         fld     dword [esi + 32]
726         fmul    st0, st1
727         faddp   st4, st0                        ; add to autoc[8]
728         fld     dword [esi + 36]
729         fmulp   st1, st0
730         add     esi, byte 4                     ; [CR] sample++
731         faddp   st4, st0                        ; add to autoc[9]
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         fmulp   st1, st0
741         add     esi, byte 4                     ; [CR] sample++
742         faddp   st3, st0                        ; add to autoc[8]
743         fld     dword [esi]
744         fld     dword [esi + 24]
745         fmul    st0, st1
746         faddp   st2, st0                        ; add to autoc[6]
747         fld     dword [esi + 28]
748         fmulp   st1, st0
749         add     esi, byte 4                     ; [CR] sample++
750         faddp   st2, st0                        ; add to autoc[7]
751         fld     dword [esi]
752         fld     dword [esi + 24]
753         fmulp   st1, st0
754         faddp   st1, st0                        ; add to autoc[6]
755         fstp    dword [edi + 24]
756         fstp    dword [edi + 28]
757         fstp    dword [edi + 32]
758         fstp    dword [edi + 36]
759         fstp    dword [edi + 40]
760         fstp    dword [edi + 44]
761         jmp     .end
762
763 .end:
764         pop     edi
765         pop     esi
766         pop     ebx
767         pop     ebp
768         ret
769
770 end