]> git.sesse.net Git - vlc/blob - plugins/downmix/ac3_downmix_sse.c
* Added error checking in pthread wrapper ; as a result, intf_msg.h must
[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.6 2001/11/28 15:08:05 massiot 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
36 #include "ac3_downmix.h"
37
38 static const float sqrt2_sse __asm__ ("sqrt2_sse") __attribute__ ((aligned (16))) = 0.7071068;
39
40 void _M( downmix_3f_2r_to_2ch ) (float * samples, dm_par_t * dm_par)
41 {
42     __asm__ __volatile__ (
43     ".align 16\n"
44     "pushl %%ebx\n"
45     "movl  $64, %%ebx\n"            /* loop counter */
46
47     "movss     (%%ecx), %%xmm5\n"   /* unit */
48     "shufps $0, %%xmm5, %%xmm5\n"   /* unit | unit | unit | unit */
49
50     "movss    4(%%ecx), %%xmm6\n"   /* clev */
51     "shufps $0, %%xmm6, %%xmm6\n"   /* clev | clev | clev | clev */
52
53     "movss    8(%%ecx), %%xmm7\n"   /* slev */
54     "shufps $0, %%xmm7, %%xmm7\n"   /* slev | slev | slev | slev */
55
56     ".align 16\n"
57 ".loop:\n"
58     "movaps     (%%eax), %%xmm0\n"  /* left */
59     "movaps 2048(%%eax), %%xmm1\n"  /* right */
60     "movaps 1024(%%eax), %%xmm2\n"  /* center */
61     "movaps 3072(%%eax), %%xmm3\n"  /* leftsur */
62     "movaps 4096(%%eax), %%xmm4\n"  /* rithgsur */
63     "mulps %%xmm5, %%xmm0\n"
64     "mulps %%xmm5, %%xmm1\n"
65     "mulps %%xmm6, %%xmm2\n"
66     "addps %%xmm2, %%xmm0\n"
67     "addps %%xmm2, %%xmm1\n"
68     "mulps %%xmm7, %%xmm3\n"
69     "mulps %%xmm7, %%xmm4\n"
70     "addps %%xmm3, %%xmm0\n"
71     "addps %%xmm4, %%xmm1\n"
72
73     "movaps %%xmm0, (%%eax)\n"
74     "movaps %%xmm1, 1024(%%eax)\n"
75
76     "addl $16, %%eax\n"
77     "decl %%ebx\n"
78     "jnz  .loop\n"
79     
80     "popl %%ebx\n"
81     : "=a" (samples)
82     : "a" (samples), "c" (dm_par));
83 }
84
85 void _M( downmix_2f_2r_to_2ch ) (float *samples, dm_par_t * dm_par)
86 {
87     __asm__ __volatile__ (
88     ".align 16\n"
89     "pushl %%ebx\n"
90     "movl  $64, %%ebx\n"            /* loop counter */
91
92     "movss     (%%ecx), %%xmm5\n"   /* unit */
93     "shufps $0, %%xmm5, %%xmm5\n"   /* unit | unit | unit | unit */
94
95     "movss    8(%%ecx), %%xmm7\n"   /* slev */
96     "shufps $0, %%xmm7, %%xmm7\n"   /* slev | slev | slev | slev */
97
98     ".align 16\n"
99 ".loop3:\n"
100     "movaps     (%%eax), %%xmm0\n"  /* left */
101     "movaps 1024(%%eax), %%xmm1\n"  /* right */
102     "movaps 2048(%%eax), %%xmm3\n"  /* leftsur */
103     "movaps 3072(%%eax), %%xmm4\n"  /* rightsur */
104     "mulps %%xmm5, %%xmm0\n"
105     "mulps %%xmm5, %%xmm1\n"
106     "mulps %%xmm7, %%xmm3\n"
107     "mulps %%xmm7, %%xmm4\n"
108     "addps %%xmm3, %%xmm0\n"
109     "addps %%xmm4, %%xmm1\n"
110
111     "movaps %%xmm0, (%%eax)\n"
112     "movaps %%xmm1, 1024(%%eax)\n"
113
114     "addl $16, %%eax\n"
115     "decl %%ebx\n"
116     "jnz  .loop3\n"
117
118     "popl %%ebx\n"
119     : "=a" (samples)
120     : "a" (samples), "c" (dm_par));
121 }
122
123 void _M( downmix_3f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
124 {
125     __asm__ __volatile__ (
126     ".align 16\n"
127     "pushl %%ebx\n"
128     "movl  $64, %%ebx\n"            /* loop counter */
129
130     "movss     (%%ecx), %%xmm5\n"   /* unit */
131     "shufps $0, %%xmm5, %%xmm5\n"   /* unit | unit | unit | unit */
132
133     "movss    4(%%ecx), %%xmm6\n"   /* clev */
134     "shufps $0, %%xmm6, %%xmm6\n"   /* clev | clev | clev | clev */
135
136     "movss    8(%%ecx), %%xmm7\n"   /* slev */
137     "shufps $0, %%xmm7, %%xmm7\n"   /* slev | slev | slev | slev */
138
139     ".align 16\n"
140 ".loop4:\n"
141     "movaps     (%%eax), %%xmm0\n"  /* left */
142     "movaps 2048(%%eax), %%xmm1\n"  /* right */
143     "movaps 1024(%%eax), %%xmm2\n"  /* center */
144     "movaps 3072(%%eax), %%xmm3\n"  /* sur */
145     "mulps %%xmm5, %%xmm0\n"
146     "mulps %%xmm5, %%xmm1\n"
147     "mulps %%xmm6, %%xmm2\n"
148     "addps %%xmm2, %%xmm0\n"
149     "mulps %%xmm7, %%xmm3\n"
150     "addps %%xmm2, %%xmm1\n"
151     "subps %%xmm3, %%xmm0\n"
152     "addps %%xmm3, %%xmm1\n"
153
154     "movaps %%xmm0, (%%eax)\n"
155     "movaps %%xmm1, 1024(%%eax)\n"
156
157     "addl $16, %%eax\n"
158     "decl %%ebx\n"
159     "jnz  .loop4\n"
160
161     "popl %%ebx\n"
162     : "=a" (samples)
163     : "a" (samples), "c" (dm_par));
164 }
165
166 void _M( downmix_2f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
167 {
168     __asm__ __volatile__ (
169     ".align 16\n"
170     "pushl %%ebx\n"
171     "movl  $64, %%ebx\n"            /* loop counter */
172
173     "movss     (%%ecx), %%xmm5\n"   /* unit */
174     "shufps $0, %%xmm5, %%xmm5\n"   /* unit | unit | unit | unit */
175
176     "movss    8(%%ecx), %%xmm7\n"   /* slev */
177     "shufps $0, %%xmm7, %%xmm7\n"   /* slev | slev | slev | slev */
178
179     ".align 16\n"
180 ".loop5:\n"
181     "movaps     (%%eax), %%xmm0\n"  /* left */
182     "movaps 1024(%%eax), %%xmm1\n"  /* right */
183     "movaps 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     "movaps %%xmm0, (%%eax)\n"
191     "movaps %%xmm1, 1024(%%eax)\n"
192
193     "addl $16, %%eax\n"
194     "decl %%ebx\n"
195     "jnz  .loop5\n"
196
197     "popl %%ebx\n"
198     : "=a" (samples)
199     : "a" (samples), "c" (dm_par));
200 }
201
202 void _M( downmix_3f_0r_to_2ch ) (float *samples, dm_par_t * dm_par)
203 {
204     __asm__ __volatile__ (
205     ".align 16\n"
206     "pushl %%ebx\n"
207     "movl  $64, %%ebx\n"           /* loop counter */
208
209     "movss     (%%ecx), %%xmm5\n"  /* unit */
210     "shufps $0, %%xmm5, %%xmm5\n"  /* unit | unit | unit | unit */
211
212     "movss    4(%%ecx), %%xmm6\n"  /* clev */
213     "shufps $0, %%xmm6, %%xmm6\n"  /* clev | clev | clev | clev */
214
215     ".align 16\n"
216 ".loop6:\n"
217     "movaps     (%%eax), %%xmm0\n"  /*left */
218     "movaps 2048(%%eax), %%xmm1\n"  /* right */
219     "movaps 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     "movaps %%xmm0, (%%eax)\n"
227     "movaps %%xmm1, 1024(%%eax)\n"
228
229     "addl $16, %%eax\n"
230     "decl %%ebx\n"
231     "jnz  .loop6\n"
232
233     "popl %%ebx\n"
234     : "=a" (samples)
235     : "a" (samples), "c" (dm_par));
236 }
237     
238 void _M( stream_sample_1ch_to_s16 ) (s16 *s16_samples, float *left)
239 {
240     __asm__ __volatile__ (
241     ".align 16\n"
242     "pushl %%ebx\n"
243     "pushl %%edx\n"
244
245     "movl   $sqrt2_sse, %%edx\n"
246     "movss  (%%edx), %%xmm7\n"
247     "shufps $0, %%xmm7, %%xmm7\n"  /* sqrt2 | sqrt2 | sqrt2 | sqrt2 */
248     "movl   $64, %%ebx\n"
249     
250     ".align 16\n"
251 ".loop2:\n"
252     "movaps (%%ecx), %%xmm0\n"     /* c3 | c2 | c1 | c0 */
253     "mulps   %%xmm7, %%xmm0\n"
254     "movhlps %%xmm0, %%xmm2\n"     /* c3 | c2 */
255
256     "cvtps2pi %%xmm0, %%mm0\n"     /* c1 c0 --> mm0, int_32 */
257     "cvtps2pi %%xmm2, %%mm1\n"     /* c3 c2 --> mm1, int_32 */
258
259     "packssdw %%mm0, %%mm0\n"      /* c1 c1 c0 c0 --> mm0, int_16 */
260     "packssdw %%mm1, %%mm1\n"      /* c3 c3 c2 c2 --> mm1, int_16 */
261
262     "movq %%mm0, (%%eax)\n"
263     "movq %%mm1, 8(%%eax)\n"
264     "addl $16, %%eax\n"
265     "addl $16, %%ecx\n"
266
267     "decl %%ebx\n"
268     "jnz .loop2\n"
269
270     "popl %%edx\n"
271     "popl %%ebx\n"
272     "emms\n"
273     : "=a" (s16_samples), "=c" (left)
274     : "a" (s16_samples), "c" (left));
275 }
276
277 void _M( stream_sample_2ch_to_s16 ) (s16 *s16_samples, float *left, float *right)
278 {
279     __asm__ __volatile__ (
280     ".align 16\n"
281     "pushl %%ebx\n"
282     "movl  $64, %%ebx\n"
283
284     ".align 16\n"
285 ".loop1:\n"
286     "movaps  (%%ecx), %%xmm0\n"   /* l3 | l2 | l1 | l0 */
287     "movaps  (%%edx), %%xmm1\n"   /* r3 | r2 | r1 | r0 */
288     "movhlps  %%xmm0, %%xmm2\n"   /* l3 | l2 */
289     "movhlps  %%xmm1, %%xmm3\n"   /* r3 | r2 */
290     "unpcklps %%xmm1, %%xmm0\n"   /* r1 | l1 | r0 | l0 */
291     "unpcklps %%xmm3, %%xmm2\n"   /* r3 | l3 | r2 | l2 */
292
293     "cvtps2pi %%xmm0, %%mm0\n"    /* r0 l0 --> mm0, int_32 */
294     "movhlps  %%xmm0, %%xmm0\n"
295     "cvtps2pi %%xmm0, %%mm1\n"    /* r1 l1 --> mm1, int_32 */
296     "cvtps2pi %%xmm2, %%mm2\n"    /* r2 l2 --> mm2, int_32 */
297     "movhlps  %%xmm2, %%xmm2\n"
298     "cvtps2pi %%xmm2, %%mm3\n"    /* r3 l3 --> mm3, int_32 */
299     
300     "packssdw %%mm1, %%mm0\n"     /* r1 l1 r0 l0 --> mm0, int_16 */
301     "packssdw %%mm3, %%mm2\n"     /* r3 l3 r2 l2 --> mm2, int_16 */
302
303     "movq %%mm0, (%%eax)\n"
304     "movq %%mm2, 8(%%eax)\n"
305     "addl $16, %%eax\n"
306     "addl $16, %%ecx\n"
307     "addl $16, %%edx\n"
308
309     "decl %%ebx\n"
310     "jnz .loop1\n"
311
312     "popl %%ebx\n"
313     "emms\n"
314     : "=a" (s16_samples), "=c" (left), "=d" (right)
315     : "a" (s16_samples), "c" (left), "d" (right));
316     
317 }
318