]> git.sesse.net Git - vlc/blob - plugins/downmix/ac3_downmix_sse.c
* AC3 IMDCT and downmix functions are now in plugins, --imdct and
[vlc] / plugins / downmix / ac3_downmix_sse.c
1 /*****************************************************************************
2  * ac3_downmix_sse.c: accelerated SSE ac3 downmix functions
3  *****************************************************************************
4  * Copyright (C) 1999, 2000, 2001 VideoLAN
5  * $Id: ac3_downmix_sse.c,v 1.1 2001/05/15 16:19:42 sam Exp $
6  *
7  * Authors: Renaud Dartus <reno@videolan.org>
8  *          Aaron Holtzman <aholtzma@engr.uvic.ca>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #define MODULE_NAME downmixsse
26 #include "modules_inner.h"
27
28 /*****************************************************************************
29  * Preamble
30  *****************************************************************************/
31 #include "defs.h"
32
33 #include "config.h"
34 #include "common.h"
35 #include "threads.h"
36 #include "mtime.h"
37 #include "tests.h"
38
39 #include "ac3_downmix.h"
40
41 void sqrt2_sse (void)
42 {
43     __asm__ (".float 0f0.7071068");
44 }
45
46 void _M( downmix_3f_2r_to_2ch ) (float * samples, dm_par_t * dm_par)
47 {
48     __asm__ __volatile__ (
49     "pushl %%ecx\n"
50     "movl  $64,  %%ecx\n"            /* loop counter */
51
52     "movss    (%%ebx), %%xmm5\n"        /* unit */
53     "shufps    $0, %%xmm5, %%xmm5\n"    /* unit | unit | unit | unit */
54
55     "movss    4(%%ebx), %%xmm6\n"        /* clev */
56     "shufps    $0, %%xmm6, %%xmm6\n"    /* clev | clev | clev | clev */
57
58     "movss    8(%%ebx), %%xmm7\n"        /* slev */
59     "shufps    $0, %%xmm7, %%xmm7\n"    /* slev | slev | slev | slev */
60
61 ".loop:\n"
62     "movups    (%%eax),     %%xmm0\n"  /* left */
63     "movups    2048(%%eax), %%xmm1\n"  /* right */
64     "movups 1024(%%eax), %%xmm2\n"    /* center */
65     "movups    3072(%%eax), %%xmm3\n"    /* leftsur */
66     "movups    4096(%%eax), %%xmm4\n"    /* rithgsur */
67     "mulps    %%xmm5, %%xmm0\n"
68     "mulps    %%xmm5, %%xmm1\n"
69     "mulps    %%xmm6, %%xmm2\n"
70     "addps    %%xmm2, %%xmm0\n"
71     "addps     %%xmm2, %%xmm1\n"
72     "mulps    %%xmm7, %%xmm3\n"
73     "mulps    %%xmm7, %%xmm4\n"
74     "addps    %%xmm3, %%xmm0\n"
75     "addps    %%xmm4, %%xmm1\n"
76
77     "movups    %%xmm0, (%%eax)\n"
78     "movups    %%xmm1, 1024(%%eax)\n"
79
80     "addl    $16, %%eax\n"
81     "decl     %%ecx\n"
82     "jnz    .loop\n"
83     
84     "popl   %%ecx\n"
85     : "=a" (samples)
86     : "a" (samples), "b" (dm_par));
87 }
88
89 void _M( downmix_2f_2r_to_2ch ) (float *samples, dm_par_t * dm_par)
90 {
91     __asm__ __volatile__ (
92     "pushl %%ecx\n"
93     "movl  $64, %%ecx\n"            /* loop counter */
94
95     "movss  (%%ebx), %%xmm5\n"        /* unit */
96     "shufps $0, %%xmm5, %%xmm5\n"   /* unit | unit | unit | unit */
97
98     "movss    8(%%ebx), %%xmm7\n"        /* slev */
99     "shufps    $0, %%xmm7, %%xmm7\n"    /* slev | slev | slev | slev */
100
101 ".loop3:\n"
102     "movups    (%%eax), %%xmm0\n"      /* left */
103     "movups    1024(%%eax), %%xmm1\n"  /* right */
104     "movups 2048(%%eax), %%xmm3\n"    /* leftsur */
105     "movups    3072(%%eax), %%xmm4\n"    /* rightsur */
106     "mulps    %%xmm5, %%xmm0\n"
107     "mulps    %%xmm5, %%xmm1\n"
108     "mulps    %%xmm7, %%xmm3\n"
109     "mulps    %%xmm7, %%xmm4\n"
110     "addps    %%xmm3, %%xmm0\n"
111     "addps    %%xmm4, %%xmm1\n"
112
113     "movups    %%xmm0, (%%eax)\n"
114     "movups    %%xmm1, 1024(%%eax)\n"
115
116     "addl    $16, %%eax\n"
117     "decl     %%ecx\n"
118     "jnz    .loop3\n"
119
120     "popl    %%ecx\n"
121     : "=a" (samples)
122     : "a" (samples), "b" (dm_par));
123 }
124
125 void _M( downmix_3f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
126 {
127     __asm__ __volatile__ (
128
129     "pushl    %%ecx\n"
130     "movl    $64, %%ecx\n"            /* loop counter */
131
132     "movss    (%%ebx), %%xmm5\n"        /* unit */
133     "shufps    $0, %%xmm5, %%xmm5\n"    /* unit | unit | unit | unit */
134
135     "movss    4(%%ebx), %%xmm6\n"        /* clev */
136     "shufps    $0, %%xmm6, %%xmm6\n"    /* clev | clev | clev | clev */
137
138     "movss    8(%%ebx), %%xmm7\n"        /* slev */
139     "shufps    $0, %%xmm7, %%xmm7\n"    /* slev | slev | slev | slev */
140
141 ".loop4:\n"
142     "movups    (%%eax), %%xmm0\n"      /* left */
143     "movups    2048(%%eax), %%xmm1\n"  /* right */
144     "movups    1024(%%eax), %%xmm2\n"    /* center */
145     "movups    3072(%%eax), %%xmm3\n"    /* sur */
146     "mulps    %%xmm5, %%xmm0\n"
147     "mulps    %%xmm5, %%xmm1\n"
148     "mulps    %%xmm6, %%xmm2\n"
149     "addps    %%xmm2, %%xmm0\n"
150     "mulps    %%xmm7, %%xmm3\n"
151     "addps     %%xmm2, %%xmm1\n"
152     "subps    %%xmm3, %%xmm0\n"
153     "addps    %%xmm3, %%xmm1\n"
154
155     "movups    %%xmm0, (%%eax)\n"
156     "movups    %%xmm1, 1024(%%eax)\n"
157
158     "addl    $16, %%eax\n"
159     "decl     %%ecx\n"
160     "jnz    .loop4\n"
161
162     "popl    %%ecx\n"
163     : "=a" (samples)
164     : "a" (samples), "b" (dm_par));
165
166 }
167
168 void _M( downmix_2f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
169 {
170     __asm__ __volatile__ (
171     "pushl    %%ecx\n"
172     "movl    $64, %%ecx\n"            /* loop counter */
173
174     "movss    (%%ebx), %%xmm5\n"        /* unit */
175     "shufps    $0, %%xmm5, %%xmm5\n"    /* unit | unit | unit | unit */
176
177     "movss    8(%%ebx), %%xmm7\n"        /* slev */
178     "shufps    $0, %%xmm7, %%xmm7\n"    /* slev | slev | slev | slev */
179
180 ".loop5:\n"
181     "movups    (%%eax), %%xmm0\n"      /* left */
182     "movups    1024(%%eax), %%xmm1\n"  /* right */
183     "movups    2048(%%eax), %%xmm3\n"    /* sur */
184     "mulps    %%xmm5, %%xmm0\n"
185     "mulps    %%xmm5, %%xmm1\n"
186     "mulps    %%xmm7, %%xmm3\n"
187     "subps    %%xmm3, %%xmm0\n"
188     "addps    %%xmm3, %%xmm1\n"
189
190     "movups    %%xmm0, (%%eax)\n"
191     "movups    %%xmm1, 1024(%%eax)\n"
192
193     "addl    $16, %%eax\n"
194     "decl     %%ecx\n"
195     "jnz    .loop5\n"
196
197     "popl    %%ecx\n"
198     : "=a" (samples)
199     : "a" (samples), "b" (dm_par));
200
201
202 }
203
204 void _M( downmix_3f_0r_to_2ch ) (float *samples, dm_par_t * dm_par)
205 {
206     __asm__ __volatile__ (
207     "pushl    %%ecx\n"
208     "movl    $64, %%ecx\n"            /* loop counter */
209
210     "movss    (%%ebx), %%xmm5\n"        /* unit */
211     "shufps    $0, %%xmm5, %%xmm5\n"    /* unit | unit | unit | unit */
212
213     "movss    4(%%ebx), %%xmm6\n"        /* clev */
214     "shufps    $0, %%xmm6, %%xmm6\n"    /* clev | clev | clev | clev */
215
216 ".loop6:\n"
217     "movups    (%%eax), %%xmm0\n"      /*left */
218     "movups    2048(%%eax), %%xmm1\n"  /* right */
219     "movups 1024(%%eax), %%xmm2\n"    /* center */
220     "mulps    %%xmm5, %%xmm0\n"
221     "mulps    %%xmm5, %%xmm1\n"
222     "mulps    %%xmm6, %%xmm2\n"
223     "addps    %%xmm2, %%xmm0\n"
224     "addps     %%xmm2, %%xmm1\n"
225
226     "movups    %%xmm0, (%%eax)\n"
227     "movups    %%xmm1, 1024(%%eax)\n"
228
229     "addl    $16, %%eax\n"
230     "decl     %%ecx\n"
231     "jnz    .loop6\n"
232
233     "popl    %%ecx\n"
234     : "=a" (samples)
235     : "a" (samples), "b" (dm_par));
236 }
237     
238 void _M( stream_sample_1ch_to_s16 ) (s16 *s16_samples, float *left)
239 {
240     __asm__ __volatile__ (
241     "pushl %%ecx\n"
242     "pushl %%edx\n"
243
244     "movl   $sqrt2_sse, %%edx\n"
245     "movss (%%edx), %%xmm7\n"
246     "shufps $0, %%xmm7, %%xmm7\n"   /* sqrt2 | sqrt2 | sqrt2 | sqrt2 */
247     "movl $64, %%ecx\n"
248
249 ".loop2:\n"
250     "movups (%%ebx), %%xmm0\n"        /* c3 | c2 | c1 | c0 */
251     "mulps   %%xmm7, %%xmm0\n"
252     "movhlps %%xmm0, %%xmm2\n"        /* c3 | c2 */
253
254     "cvtps2pi %%xmm0, %%mm0\n"        /* c1 c0 --> mm0, int_32 */
255     "cvtps2pi %%xmm2, %%mm1\n"        /* c3 c2 --> mm1, int_32 */
256
257     "packssdw %%mm0, %%mm0\n"        /* c1 c1 c0 c0 --> mm0, int_16 */
258     "packssdw %%mm1, %%mm1\n"        /* c3 c3 c2 c2 --> mm1, int_16 */
259
260     "movq %%mm0, (%%eax)\n"
261     "movq %%mm1, 8(%%eax)\n"
262     "addl $16, %%eax\n"
263     "addl $16, %%ebx\n"
264
265     "decl %%ecx\n"
266     "jnz .loop2\n"
267
268     "popl %%edx\n"
269     "popl %%ecx\n"
270     "emms\n"
271     : "=a" (s16_samples), "=b" (left)
272     : "a" (s16_samples), "b" (left));
273 }
274
275 void _M( stream_sample_2ch_to_s16 ) (s16 *s16_samples, float *left, float *right)
276 {
277
278     __asm__ __volatile__ (
279     "pushl %%ecx\n"
280     "movl $64, %%ecx\n"
281
282 ".loop1:\n"
283     "movups  (%%ebx), %%xmm0\n"    /* l3 | l2 | l1 | l0 */
284     "movups  (%%edx), %%xmm1\n"    /* r3 | r2 | r1 | r0 */
285     "movhlps  %%xmm0, %%xmm2\n"    /* l3 | l2 */
286     "movhlps  %%xmm1, %%xmm3\n"    /* r3 | r2 */
287     "unpcklps %%xmm1, %%xmm0\n"    /* r1 | l1 | r0 | l0 */
288     "unpcklps %%xmm3, %%xmm2\n"    /* r3 | l3 | r2 | l2 */
289
290     "cvtps2pi %%xmm0, %%mm0\n"    /* r0 l0 --> mm0, int_32 */
291     "movhlps  %%xmm0, %%xmm0\n"
292     "cvtps2pi %%xmm0, %%mm1\n"    /* r1 l1 --> mm1, int_32 */
293     "cvtps2pi %%xmm2, %%mm2\n"    /* r2 l2 --> mm2, int_32 */
294     "movhlps  %%xmm2, %%xmm2\n"
295     "cvtps2pi %%xmm2, %%mm3\n"    /* r3 l3 --> mm3, int_32 */
296     
297     "packssdw %%mm1, %%mm0\n"    /* r1 l1 r0 l0 --> mm0, int_16 */
298     "packssdw %%mm3, %%mm2\n"    /* r3 l3 r2 l2 --> mm2, int_16 */
299
300     "movq %%mm0, (%%eax)\n"
301     "movq %%mm2, 8(%%eax)\n"
302     "addl $16, %%eax\n"
303     "addl $16, %%ebx\n"
304     "addl $16, %%edx\n"
305
306     "decl %%ecx\n"
307     "jnz .loop1\n"
308
309     "popl %%ecx\n"
310     "emms\n"
311     : "=a" (s16_samples), "=b" (left), "=d" (right)
312     : "a" (s16_samples), "b" (left), "d" (right));
313     
314 }
315