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