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