]> git.sesse.net Git - vlc/blob - plugins/imdct/ac3_imdct_3dn.c
* ALL: the first libvlc commit.
[vlc] / plugins / imdct / ac3_imdct_3dn.c
1 /*****************************************************************************
2  * ac3_imdct_3dn.c: accelerated 3D Now! ac3 DCT
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  * $Id: ac3_imdct_3dn.c,v 1.11 2002/06/01 12:31:59 sam Exp $
6  *
7  * Authors: Renaud Dartus <reno@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <math.h>
28 #include <stdio.h>
29
30 #include <vlc/vlc.h>
31
32 #include "ac3_imdct.h"
33 #include "ac3_imdct_common.h"
34 #include "ac3_retables.h"
35
36 #ifndef M_PI
37 #   define M_PI 3.14159265358979323846
38 #endif
39
40 void _M( fft_64p )  ( complex_t *x );
41 void _M( fft_128p ) ( complex_t *a );
42
43 static void imdct512_pre_ifft_twiddle_3dn (const int *pmt, complex_t *buf, float *data, float *xcos_sin_sse);
44 static void imdct512_post_ifft_twiddle_3dn (complex_t *buf, float *xcos_sin_sse);
45 static void imdct512_window_delay_3dn (complex_t *buf, float *data_ptr, float *window_prt, float *delay_prt);
46 static void imdct512_window_delay_nol_3dn (complex_t *buf, float *data_ptr, float *window_prt, float *delay_prt);
47
48
49 void _M( imdct_init ) (imdct_t * p_imdct)
50 {
51         int i;
52         float scale = 181.019;
53
54         for (i=0; i < 128; i++)
55         {
56                 float xcos_i = cos(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
57                 float xsin_i = sin(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
58                 p_imdct->xcos_sin_sse[i * 4]     = xcos_i;
59                 p_imdct->xcos_sin_sse[i * 4 + 1] = -xsin_i;
60                 p_imdct->xcos_sin_sse[i * 4 + 2] = -xsin_i;
61                 p_imdct->xcos_sin_sse[i * 4 + 3] = -xcos_i;
62         }
63 }
64
65 void _M( imdct_do_512 ) (imdct_t * p_imdct, float data[], float delay[])
66 {
67         imdct512_pre_ifft_twiddle_3dn (pm128, p_imdct->buf, data, p_imdct->xcos_sin_sse);
68         _M( fft_128p ) (p_imdct->buf);
69         imdct512_post_ifft_twiddle_3dn (p_imdct->buf, p_imdct->xcos_sin_sse);
70     imdct512_window_delay_3dn (p_imdct->buf, data, window, delay);
71 }
72
73 void _M( imdct_do_512_nol ) (imdct_t * p_imdct, float data[], float delay[])
74 {
75         imdct512_pre_ifft_twiddle_3dn (pm128, p_imdct->buf, data, p_imdct->xcos_sin_sse);  
76         _M( fft_128p ) (p_imdct->buf);
77         imdct512_post_ifft_twiddle_3dn (p_imdct->buf, p_imdct->xcos_sin_sse);
78     imdct512_window_delay_nol_3dn (p_imdct->buf, data, window, delay);
79 }
80
81 static void imdct512_pre_ifft_twiddle_3dn (const int *pmt, complex_t *buf, float *data, float *xcos_sin_sse)
82 {
83     __asm__ __volatile__ (      
84     ".align 16\n"
85         "pushl %%ebx\n"
86         "pushl %%esi\n"
87     
88         "movl $128, %%ebx\n"         /* loop counter */
89
90     ".align 16\n"
91 "0:\n"
92         "movl  (%%eax), %%esi\n"
93         "movd (%%ecx, %%esi, 8), %%mm1\n"   /* 2j */
94     "punpckldq %%mm1, %%mm1\n"          /* 2j | 2j */
95
96         "shll $1, %%esi\n"
97
98         "movq (%%edx, %%esi, 8), %%mm0\n"   /* -s_j | c_j */
99         "movq 8(%%edx, %%esi, 8), %%mm2\n"  /* -c_j | -s_j */
100
101         "negl %%esi\n"
102
103         "movd 1020(%%ecx, %%esi, 4), %%mm4\n" /* 255-2j */
104     "punpckldq %%mm4, %%mm4\n"  /* 255-2j | 255-2j */
105         "addl $4, %%eax\n"
106
107         "pfmul   %%mm4, %%mm0\n"    /* 255-2j * -s_j | 255-2j  * c_j */
108         "pfmul   %%mm1, %%mm2\n"    /* 2j * -c_j | 2j * -s_j */
109         "addl    $8, %%edi\n"
110         "pfadd   %%mm2, %%mm0\n"    /* 2j * -c_j + 255-2j * -s_j | 2j * -s_j + 255-2j * c_j */
111     
112         "movq  %%mm0, -8(%%edi)\n"
113         "decl %%ebx\n"
114         "jnz 0b\n"
115
116         "popl %%esi\n"
117         "popl %%ebx\n"
118
119         "femms\n"
120     : "=D" (buf)
121     : "a" (pmt), "c" (data), "d" (xcos_sin_sse), "D" (buf));
122 }
123
124 static void imdct512_post_ifft_twiddle_3dn (complex_t *buf, float *xcos_sin_sse)
125 {
126     __asm__ __volatile__ ( 
127     ".align 16\n"
128         "pushl %%ebx\n"
129         "movl $64, %%ebx\n"         /* loop counter */
130
131     ".align 16\n"
132 "0:\n"
133         "movq   (%%eax), %%mm0\n"   /* im0 | re0 */
134         "movq     %%mm0, %%mm1\n"   /* im0 | re0 */
135     "punpckldq %%mm0, %%mm0\n"  /* re0 | re0 */
136     "punpckhdq %%mm1, %%mm1\n"  /* im0 | im0 */
137     
138         "movq  (%%ecx), %%mm2\n"    /* -s | c */
139         "movq 8(%%ecx), %%mm3\n"    /* -c | -s */
140     "movq    %%mm3, %%mm4\n"
141
142     "punpckhdq %%mm2,%%mm3\n"   /* -s | -c */
143     "punpckldq %%mm2,%%mm4\n"   /*  c | -s */
144     
145         "movq  8(%%eax), %%mm2\n"   /* im1 | re1 */
146         "movq   %%mm2, %%mm5\n"     /* im1 | re1 */
147     "punpckldq %%mm2, %%mm2\n"  /* re1 | re1 */
148     "punpckhdq %%mm5, %%mm5\n"  /* im1 | im1 */
149
150         "pfmul %%mm3, %%mm0\n"      /* -s * re0 | -c * re0 */
151         "pfmul %%mm4, %%mm1\n"      /* c * im0 | -s * im0 */
152
153         "movq  16(%%ecx), %%mm6\n"  /* -s1 | c1 */
154         "movq  24(%%ecx), %%mm7\n"  /* -c1 | -s1 */
155     "movq   %%mm7, %%mm4\n"
156     
157     "punpckhdq %%mm6,%%mm7\n"   /* -s1 | -c1 */
158     "punpckldq %%mm6,%%mm4\n"   /*  c1 | -s1 */
159     
160         "pfmul %%mm7, %%mm2\n"      /* -s1*re1 | -c1*re1 */
161         "pfmul %%mm4, %%mm5\n"      /* c1*im1 | -s1*im1 */
162
163         "pfadd %%mm1, %%mm0\n"      /* -s * re0 + c * im0 | -c * re0 - s * im0 */
164         "pfadd %%mm5, %%mm2\n"      /* -s1 * re1 + c1 * im1 | -c1 * re1 - s1 * im1 */
165
166         "movq %%mm0, (%%eax)\n"
167         "movq %%mm2, 8(%%eax)\n"
168         "addl $32, %%ecx\n"
169         "addl $16, %%eax\n"
170         "decl %%ebx\n"
171         "jnz 0b\n"
172
173         "popl %%ebx\n"
174         "femms\n"
175     : "=a" (buf)
176     : "a" (buf), "c" (xcos_sin_sse) );
177 }
178
179 static void imdct512_window_delay_3dn (complex_t *buf, float *data_ptr, float *window_prt, float *delay_prt)
180 {
181     __asm__ __volatile__ (
182     ".align 16\n"
183
184         "pushl %%eax\n"
185         "pushl %%ebx\n"
186         "pushl %%ecx\n"
187         "pushl %%edx\n"
188         "pushl %%edi\n"
189         "pushl %%esi\n"
190         "pushl %%ebp\n"
191
192         "movl %%esi, %%ebp\n"         /* buf */
193         "movl $32, %%ebx\n"         /* loop count */
194         "leal 516(%%ebp), %%esi\n"  /* buf[64].im */
195         "leal 504(%%ebp), %%edi\n"  /* buf[63].re */
196
197         
198     ".align 16\n"
199 ".first_128_samples:\n"
200         "movd   (%%esi), %%mm0\n" /* im0 */
201         "movd  8(%%esi), %%mm2\n" /* im1 */
202         "movd   (%%edi), %%mm1\n" /* re0 */
203         "movd -8(%%edi), %%mm3\n" /* re1 */
204
205     "pxor   %%mm4, %%mm4\n"
206     "pxor   %%mm5, %%mm5\n"
207     "pfsub  %%mm0, %%mm4\n" /* -im0 */
208     "pfsub  %%mm2, %%mm5\n" /* -im1 */
209     
210         "punpckldq %%mm1, %%mm4\n"      /* re0 | -im0 */
211         "punpckldq %%mm3, %%mm5\n"      /* re1 | -im1 */
212
213         "movq  (%%edx), %%mm0\n"      /* w1 | w0 */
214         "movq 8(%%edx), %%mm1\n"      /* w3 | w2 */
215         "movq  (%%ecx), %%mm2\n"      /* d1 | d0 */
216         "movq 8(%%ecx), %%mm3\n"      /* d3 | d2 */
217
218     "pfmul     %%mm4, %%mm0\n"      /* w1*re0 | -w0*im0 */
219         "pfmul     %%mm5, %%mm1\n"      /* w3*re1 | -w2*im1 */
220
221     "pfadd     %%mm2, %%mm0\n"      /* w1*re0+d1 | -w0*im0+d0 */
222     "pfadd     %%mm3, %%mm1\n"      /* w3*re1+d3 | -w2*im1+d2 */
223
224         "addl $16, %%edx\n"
225         "movq %%mm0,  (%%eax)\n"
226         "movq %%mm1, 8(%%eax)\n"
227         "addl $16, %%ecx\n"
228         "addl $16, %%esi\n"
229         "addl $16, %%eax\n"
230     "addl $-16, %%edi\n"
231         "decl %%ebx\n"
232         "jnz .first_128_samples\n"
233
234         "movl %%ebp, %%esi\n"    /* buf[0].re */
235         "movl $32, %%ebx\n"         /* loop count */
236         "leal 1020(%%ebp), %%edi\n" /* buf[127].im */
237     
238     ".align 16\n"
239 ".second_128_samples:\n"
240         "movd   (%%esi), %%mm0\n" /* buf[i].re */
241         "movd  8(%%esi), %%mm2\n" /* re1 */
242         "movd   (%%edi), %%mm1\n" /* buf[127-i].im */
243         "movd -8(%%edi), %%mm3\n" /* im1 */
244     
245     "pxor   %%mm4, %%mm4\n"
246     "pxor   %%mm5, %%mm5\n"
247     "pfsub  %%mm0, %%mm4\n" /* -re0 */
248     "pfsub  %%mm2, %%mm5\n" /* -re1 */
249     
250         "punpckldq %%mm1, %%mm4\n"     /* im0 | -re0 */
251         "punpckldq %%mm3, %%mm5\n"     /* im1 | -re1 */
252
253         "movq (%%edx), %%mm0\n"  /* w1 | w0 */
254         "movq 8(%%edx), %%mm1\n"  /* w3 | w2 */
255         "movq (%%ecx), %%mm2\n"  /* d1 | d0 */
256         "movq 8(%%ecx), %%mm3\n"  /* d3 | d2 */
257
258         "addl $16, %%esi\n"
259     
260     "pfmul     %%mm4, %%mm0\n"      /* w1*im0 | -w0*re0 */
261         "pfmul     %%mm5, %%mm1\n"      /* w3*im1 | -w2*re1 */
262     
263         "pfadd %%mm2, %%mm0\n"      /* w1*im0+d1 | -w0*re0+d0 */
264         "pfadd %%mm3, %%mm1\n"      /* w3*im1+d3 | -w2*re1+d2 */
265     
266         "addl $-16, %%edi\n"
267         
268     "movq %%mm0, (%%eax)\n"
269     "movq %%mm1, 8(%%eax)\n"
270     
271     "addl $16, %%edx\n"
272         "addl $16, %%eax\n"
273         "addl $16, %%ecx\n"
274         "decl %%ebx\n"
275         "jnz .second_128_samples\n"
276
277         "leal 512(%%ebp), %%esi\n"  /* buf[64].re */
278         "leal 508(%%ebp), %%edi\n"  /* buf[63].im */
279         "movl $32, %%ebx\n"         /* loop count */
280     "addl $-1024, %%ecx\n"      /* delay */
281
282     ".align 16\n"
283 ".first_128_delay:\n"
284         "movd   (%%esi), %%mm0\n" /* re0 */
285         "movd  8(%%esi), %%mm2\n" /* re1 */
286         "movd   (%%edi), %%mm1\n" /* im0 */
287         "movd -8(%%edi), %%mm3\n" /* im1 */
288
289     "pxor   %%mm4, %%mm4\n"
290     "pxor   %%mm5, %%mm5\n"
291     "pfsub  %%mm0, %%mm4\n" /* -re0 */
292     "pfsub  %%mm2, %%mm5\n" /* -re1 */
293     
294         "punpckldq %%mm1, %%mm4\n"     /* im0 | -re0 */
295         "punpckldq %%mm3, %%mm5\n"     /* im1 | -re1 */
296
297     
298         "movq -16(%%edx), %%mm1\n"   /* w3 | w2 */
299         "movq  -8(%%edx), %%mm0\n"   /* w1 | w0 */
300     
301         "addl $-16, %%edx\n"
302
303     "pfmul     %%mm4, %%mm0\n"      /* w1*im0 | -w0*re0 */
304         "pfmul     %%mm5, %%mm1\n"      /* w3*im1 | -w2*re1 */
305
306         "movq %%mm0, (%%ecx)\n"
307         "movq %%mm1, 8(%%ecx)\n"
308         "addl  $16, %%esi\n"
309         "addl $-16, %%edi\n"
310         "addl  $16, %%ecx\n"
311         "decl %%ebx\n"
312         "jnz .first_128_delay\n"
313
314         "leal    4(%%ebp), %%esi\n" /* buf[0].im */
315         "leal 1016(%%ebp), %%edi\n" /* buf[127].re */
316         "movl $32, %%ebx\n"         /* loop count */
317     
318     ".align 16\n"
319 ".second_128_delay:\n"
320         "movd   (%%esi), %%mm0\n" /* im0 */
321         "movd  8(%%esi), %%mm2\n" /* im1 */
322         "movd   (%%edi), %%mm1\n" /* re0 */
323         "movd -8(%%edi), %%mm3\n" /* re1 */
324
325     "pxor   %%mm4, %%mm4\n"
326     "pxor   %%mm5, %%mm5\n"
327     "pfsub  %%mm1, %%mm4\n" /* -re0 */
328     "pfsub  %%mm3, %%mm5\n" /* -re1 */
329     
330         "punpckldq %%mm4, %%mm0\n"     /* -re0 | im0 */
331         "punpckldq %%mm5, %%mm2\n"     /* -re1 | im1 */
332
333     
334         "movq -16(%%edx), %%mm1\n"   /* w3 | w2 */
335         "movq  -8(%%edx), %%mm3\n"   /* w1 | w0 */
336     
337         "addl $-16, %%edx\n"
338
339     "pfmul     %%mm0, %%mm1\n"      /* -w1*re0 | w0*im0 */
340         "pfmul     %%mm2, %%mm3\n"      /* -w3*re1 | w2*im1 */
341
342     
343         "movq %%mm1, (%%ecx)\n"
344         "movq %%mm3, 8(%%ecx)\n"
345         "addl  $16, %%esi\n"
346         "addl $-16, %%edi\n"
347         "addl  $16, %%ecx\n"
348         "decl %%ebx\n"
349     "jnz .second_128_delay\n"
350
351         "popl %%ebp\n"
352         "popl %%esi\n"
353         "popl %%edi\n"
354         "popl %%edx\n"
355         "popl %%ecx\n"
356         "popl %%ebx\n"
357         "popl %%eax\n"
358         
359         "femms\n"
360     : "=S" (buf), "=a" (data_ptr), "=c" (delay_prt), "=d" (window_prt)
361     : "S" (buf), "a" (data_ptr), "c" (delay_prt), "d" (window_prt));
362 }
363
364 static void imdct512_window_delay_nol_3dn (complex_t *buf, float *data_ptr, float *window_prt, float *delay_prt)
365 {
366     __asm__ __volatile__ (
367     ".align 16\n"
368
369         "pushl %%eax\n"
370         "pushl %%ebx\n"
371         "pushl %%ecx\n"
372         "pushl %%edx\n"
373         "pushl %%edi\n"
374         "pushl %%esi\n"
375         "pushl %%ebp\n"
376
377         "movl %%esi, %%ebp\n"         /* buf */
378         "movl $32, %%ebx\n"         /* loop count */
379         "leal 516(%%ebp), %%esi\n"  /* buf[64].im */
380         "leal 504(%%ebp), %%edi\n"  /* buf[63].re */
381
382     ".align 16\n"
383 ".first_128_samples2:\n"
384         "movd   (%%esi), %%mm0\n" /* im0 */
385         "movd  8(%%esi), %%mm2\n" /* im1 */
386         "movd   (%%edi), %%mm1\n" /* re0 */
387         "movd -8(%%edi), %%mm3\n" /* re1 */
388
389     "pxor   %%mm4, %%mm4\n"
390     "pxor   %%mm5, %%mm5\n"
391     "pfsub  %%mm0, %%mm4\n" /* -im0 */
392     "pfsub  %%mm2, %%mm5\n" /* -im1 */
393     
394         "punpckldq %%mm1, %%mm4\n"      /* re0 | -im0 */
395         "punpckldq %%mm3, %%mm5\n"      /* re1 | -im1 */
396
397         "movq (%%edx), %%mm0\n"      /* w1 | w0 */
398         "movq 8(%%edx), %%mm1\n"     /* w3 | w2 */
399
400     "pfmul     %%mm4, %%mm0\n"      /* w1*re0 | -w0*im0 */
401         "pfmul     %%mm5, %%mm1\n"      /* w3*re1 | -w2*im1 */
402
403         "addl $16, %%edx\n"
404         "movq %%mm0, (%%eax)\n"
405         "movq %%mm1, 8(%%eax)\n"
406         "addl $16, %%ecx\n"
407         "addl $16, %%esi\n"
408         "addl $16, %%eax\n"
409     "addl $-16, %%edi\n"
410         "decl %%ebx\n"
411         "jnz .first_128_samples2\n"
412
413         "movl %%ebp, %%esi\n"    /* buf[0].re */
414         "movl $32, %%ebx\n"         /* loop count */
415         "leal 1020(%%ebp), %%edi\n" /* buf[127].im */
416     
417     ".align 16\n"
418 ".second_128_samples2:\n"
419         "movd   (%%esi), %%mm0\n" /* buf[i].re */
420         "movd  8(%%esi), %%mm2\n" /* re1 */
421         "movd   (%%edi), %%mm1\n" /* buf[127-i].im */
422         "movd -8(%%edi), %%mm3\n" /* im1 */
423
424     "pxor   %%mm4, %%mm4\n"
425     "pxor   %%mm5, %%mm5\n"
426     "pfsub  %%mm0, %%mm4\n" /* -re0 */
427     "pfsub  %%mm2, %%mm5\n" /* -re1 */
428     
429         "punpckldq %%mm1, %%mm4\n"     /* im0 | -re0 */
430         "punpckldq %%mm3, %%mm5\n"     /* im1 | -re1 */
431
432         "movq (%%edx), %%mm0\n"  /* w1 | w0 */
433         "movq 8(%%edx), %%mm1\n"  /* w3 | w2 */
434
435         "addl $16, %%esi\n"
436     
437     "pfmul     %%mm4, %%mm0\n"      /* w1*im0 | -w0*re0 */
438         "pfmul     %%mm5, %%mm1\n"      /* w3*im1 | -w2*re1 */
439     
440         "addl $-16, %%edi\n"
441         
442     "movq %%mm0, (%%eax)\n"
443     "movq %%mm1, 8(%%eax)\n"
444     
445     "addl $16, %%edx\n"
446         "addl $16, %%eax\n"
447         "addl $16, %%ecx\n"
448         "decl %%ebx\n"
449         "jnz .second_128_samples2\n"
450
451         "leal 512(%%ebp), %%esi\n"  /* buf[64].re */
452         "leal 508(%%ebp), %%edi\n"  /* buf[63].im */
453         "movl $32, %%ebx\n"         /* loop count */
454         "addl  $-1024, %%ecx\n"  /* delay */
455
456     ".align 16\n"
457 ".first_128_delays:\n"
458         "movd   (%%esi), %%mm0\n" /* re0 */
459         "movd  8(%%esi), %%mm2\n" /* re1 */
460         "movd   (%%edi), %%mm1\n" /* im0 */
461         "movd -8(%%edi), %%mm3\n" /* im1 */
462
463     "pxor   %%mm4, %%mm4\n"
464     "pxor   %%mm5, %%mm5\n"
465     "pfsub  %%mm0, %%mm4\n" /* -re0 */
466     "pfsub  %%mm2, %%mm5\n" /* -re1 */
467     
468         "punpckldq %%mm1, %%mm4\n"     /* im0 | -re0 */
469         "punpckldq %%mm3, %%mm5\n"     /* im1 | -re1 */
470
471     
472         "movq -16(%%edx), %%mm1\n"   /* w3 | w2 */
473         "movq  -8(%%edx), %%mm0\n"   /* w1 | w0 */
474     
475         "addl $-16, %%edx\n"
476
477     "pfmul     %%mm4, %%mm0\n"      /* w1*im0 | -w0*re0 */
478         "pfmul     %%mm5, %%mm1\n"      /* w3*im1 | -w2*re1 */
479
480     
481         "movq %%mm0, (%%ecx)\n"
482         "movq %%mm1, 8(%%ecx)\n"
483         "addl  $16, %%esi\n"
484         "addl $-16, %%edi\n"
485         "addl  $16, %%ecx\n"
486         "decl %%ebx\n"
487         "jnz .first_128_delays\n"
488
489         "leal    4(%%ebp), %%esi\n" /* buf[0].im */
490         "leal 1016(%%ebp), %%edi\n" /* buf[127].re */
491         "movl $32, %%ebx\n"         /* loop count */
492     
493     ".align 16\n"
494 ".second_128_delays:\n"
495         "movd   (%%esi), %%mm0\n" /* im0 */
496         "movd  8(%%esi), %%mm2\n" /* im1 */
497         "movd   (%%edi), %%mm1\n" /* re0 */
498         "movd -8(%%edi), %%mm3\n" /* re1 */
499
500     "pxor   %%mm4, %%mm4\n"
501     "pxor   %%mm5, %%mm5\n"
502     "pfsub  %%mm1, %%mm4\n" /* -re0 */
503     "pfsub  %%mm3, %%mm5\n" /* -re1 */
504     
505         "punpckldq %%mm4, %%mm0\n"     /* -re0 | im0 */
506         "punpckldq %%mm5, %%mm2\n"     /* -re1 | im1 */
507
508     
509         "movq -16(%%edx), %%mm1\n"   /* w3 | w2 */
510         "movq  -8(%%edx), %%mm3\n"   /* w1 | w0 */
511     
512         "addl $-16, %%edx\n"
513
514     "pfmul     %%mm0, %%mm1\n"      /* -w1*re0 | w0*im0 */
515         "pfmul     %%mm2, %%mm3\n"      /* -w3*re1 | w2*im1 */
516
517     
518         "movq %%mm1, (%%ecx)\n"
519         "movq %%mm3, 8(%%ecx)\n"
520         "addl  $16, %%esi\n"
521         "addl $-16, %%edi\n"
522         "addl  $16, %%ecx\n"
523         "decl %%ebx\n"
524     "jnz .second_128_delays\n"
525
526     "popl %%ebp\n"
527         "popl %%esi\n"
528         "popl %%edi\n"
529         "popl %%edx\n"
530         "popl %%ecx\n"
531         "popl %%ebx\n"
532         "popl %%eax\n"
533         
534         "femms\n"
535     : "=S" (buf), "=a" (data_ptr), "=c" (delay_prt), "=d" (window_prt)
536     : "S" (buf), "a" (data_ptr), "c" (delay_prt), "d" (window_prt));
537 }
538