831e604e95ee39fdb9d425865a2d202890e5ccd3
[reactos.git] / lib / 3rdparty / libmpg123 / synth_i586_dither.S
1 /*
2 decode_i586_dither: asm synth with dither noise
3
4 copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
5 see COPYING and AUTHORS files in distribution or http://mpg123.org
6 initially written by Stefan Bieschewski as decode_i586.s without dither
7
8 This version uses "circular" 64k dither noise.
9 (Patch by Adrian <adrian.bacon@xs4all.nl>)
10
11 Thomas learned something about assembler and the stack while making this one thread safe (removing static data).
12 */
13
14 #include "mangle.h"
15
16 .data
17 #ifndef __APPLE__
18 .section .rodata
19 #endif
20 ALIGN8
21 .LC0:
22 .long 0x0,0x40dfffc0
23 ALIGN8
24 .LC1:
25 .long 0x0,0xc0e00000
26 ALIGN8
27 .text
28 /* int synth_1to1_i586_asm_dither(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int bo_and_ditherindex[2], real *decwin, real* dithernoise); */
29 .globl ASM_NAME(synth_1to1_i586_asm_dither)
30 ASM_NAME(synth_1to1_i586_asm_dither):
31 subl $16,%esp
32 pushl %ebp
33 pushl %edi
34 pushl %esi
35 pushl %ebx
36 /* stack: 0(%esp)=%ebx 4=esi 8=edi 12=ebp 16,20,24,28=local 32=back 36=bandptr 40=channel 44=out 48=buffs 52=bo 56=decwin 60=dithernoise */
37 #define BANDPTR 36(%esp)
38 #define CHANNEL 40(%esp)
39 #define OUT 44(%esp)
40 #define BUFFS 48(%esp)
41 #define BO 52(%esp)
42 #define DECWIN 56(%esp)
43 #define DITHERNOISE 60(%esp)
44 /*#define DITHERNOISE $(ASM_NAME(dithernoise))*/
45 #define LOC0 16(%esp)
46 #define LOC1 20(%esp)
47 #define LOC2 24(%esp)
48 #define DITHERINDEX 28(%esp)
49 /* During application of the dithering, we need the shifted locations because there's an additional value on the stack. */
50 #define DITHERNOISE2 64(%esp)
51 #define DITHERINDEX2 32(%esp)
52
53 movl BANDPTR,%eax
54 movl OUT,%esi
55 movl BO, %ebx
56 movl (%ebx),%ebp /* get bo value */
57 movl 4(%ebx),%edi; /* get the ditherindex behind bo */
58 movl %edi,DITHERINDEX
59 xorl %edi,%edi
60 cmpl %edi,CHANNEL
61 jne .L48
62 decl %ebp
63 andl $15,%ebp
64 movl %ebp,(%ebx) /* save bo back */
65 movl BUFFS,%ecx
66 jmp .L49
67 .L48:
68 /* In stereo mode , "rewind" dither pointer 32 samples , so 2nd channel */
69 /* has same dither values. Tested OK for mono and stereo MP2 and MP3 */
70 subl $128,DITHERINDEX /* better move to %edi for the two calculations? */
71 andl $0x0003fffc,DITHERINDEX
72 addl $2,%esi
73 movl BUFFS,%ecx
74 addl $2176,%ecx
75 .L49:
76 /* now the call of dct64 is prepared, stuff pushed to the stack, but soon after it's removed again */
77 testl $1,%ebp
78 je .L50
79 movl %ecx,%ebx
80 movl %ebp,LOC0
81 pushl %eax
82 movl LOC1,%edx
83 leal (%ebx,%edx,4),%eax
84 pushl %eax
85 movl LOC2,%eax
86 incl %eax
87 andl $15,%eax
88 leal 1088(,%eax,4),%eax
89 addl %ebx,%eax
90 jmp .L74
91 .L50:
92 leal 1088(%ecx),%ebx
93 leal 1(%ebp),%edx
94 movl %edx,LOC0
95 pushl %eax
96 leal 1092(%ecx,%ebp,4),%eax
97 pushl %eax
98 leal (%ecx,%ebp,4),%eax
99 .L74:
100 pushl %eax
101 call ASM_NAME(dct64_i386)
102 addl $12,%esp
103 /* Now removed the parameters.
104 stack: 0(%esp)=%ebx 4=esi 8=edi 12=ebp 16,20,24,28=local 32=back 36=bandptr 40=channel 44=out 48=buffs 52=bo 56=decwin 60=dithernoise */
105 movl LOC0,%edx
106 leal 0(,%edx,4),%edx
107 /* movl ASM_VALUE(decwin)+64,%eax */
108 movl DECWIN,%eax
109 addl $64,%eax
110 movl %eax,%ecx
111 subl %edx,%ecx
112 movl $16,%ebp
113 .L55:
114 flds (%ecx)
115 fmuls (%ebx)
116 flds 4(%ecx)
117 fmuls 4(%ebx)
118 fxch %st(1)
119 flds 8(%ecx)
120 fmuls 8(%ebx)
121 fxch %st(2)
122 fsubrp %st,%st(1)
123 flds 12(%ecx)
124 fmuls 12(%ebx)
125 fxch %st(2)
126 faddp %st,%st(1)
127 flds 16(%ecx)
128 fmuls 16(%ebx)
129 fxch %st(2)
130 fsubrp %st,%st(1)
131 flds 20(%ecx)
132 fmuls 20(%ebx)
133 fxch %st(2)
134 faddp %st,%st(1)
135 flds 24(%ecx)
136 fmuls 24(%ebx)
137 fxch %st(2)
138 fsubrp %st,%st(1)
139 flds 28(%ecx)
140 fmuls 28(%ebx)
141 fxch %st(2)
142 faddp %st,%st(1)
143 flds 32(%ecx)
144 fmuls 32(%ebx)
145 fxch %st(2)
146 fsubrp %st,%st(1)
147 flds 36(%ecx)
148 fmuls 36(%ebx)
149 fxch %st(2)
150 faddp %st,%st(1)
151 flds 40(%ecx)
152 fmuls 40(%ebx)
153 fxch %st(2)
154 fsubrp %st,%st(1)
155 flds 44(%ecx)
156 fmuls 44(%ebx)
157 fxch %st(2)
158 faddp %st,%st(1)
159 flds 48(%ecx)
160 fmuls 48(%ebx)
161 fxch %st(2)
162 fsubrp %st,%st(1)
163 flds 52(%ecx)
164 fmuls 52(%ebx)
165 fxch %st(2)
166 faddp %st,%st(1)
167 flds 56(%ecx)
168 fmuls 56(%ebx)
169 fxch %st(2)
170 fsubrp %st,%st(1)
171 flds 60(%ecx)
172 fmuls 60(%ebx)
173 fxch %st(2)
174 subl $4,%esp
175 faddp %st,%st(1)
176 fxch %st(1)
177 fsubrp %st,%st(1)
178
179 addl $4,DITHERINDEX2
180 andl $0x0003fffc,DITHERINDEX2
181 movl DITHERNOISE2,%edi
182 addl DITHERINDEX2,%edi
183
184 fadds (%edi)
185
186 /* fistpl and popl as a unit keep the stack unchanged */
187 fistpl (%esp)
188 popl %eax
189 cmpl $32767,%eax
190 jg 1f
191 cmpl $-32768,%eax
192 jl 2f
193 movw %ax,(%esi)
194 jmp 4f
195 1: movw $32767,(%esi)
196 jmp 3f
197 2: movw $-32768,(%esi)
198 3:
199 /* incl %edi */
200 4:
201 .L54:
202 addl $64,%ebx
203 subl $-128,%ecx
204 addl $4,%esi
205 decl %ebp
206 jnz .L55
207 flds (%ecx)
208 fmuls (%ebx)
209 flds 8(%ecx)
210 fmuls 8(%ebx)
211 flds 16(%ecx)
212 fmuls 16(%ebx)
213 fxch %st(2)
214 faddp %st,%st(1)
215 flds 24(%ecx)
216 fmuls 24(%ebx)
217 fxch %st(2)
218 faddp %st,%st(1)
219 flds 32(%ecx)
220 fmuls 32(%ebx)
221 fxch %st(2)
222 faddp %st,%st(1)
223 flds 40(%ecx)
224 fmuls 40(%ebx)
225 fxch %st(2)
226 faddp %st,%st(1)
227 flds 48(%ecx)
228 fmuls 48(%ebx)
229 fxch %st(2)
230 faddp %st,%st(1)
231 flds 56(%ecx)
232 fmuls 56(%ebx)
233 fxch %st(2)
234 subl $4,%esp
235 faddp %st,%st(1)
236 fxch %st(1)
237 faddp %st,%st(1)
238
239 addl $4,DITHERINDEX2
240 andl $0x0003fffc,DITHERINDEX2
241 movl DITHERNOISE2,%edi
242 addl DITHERINDEX2,%edi
243
244 fadds (%edi)
245 /* fistpl and popl as a unit keep the stack unchanged */
246 fistpl (%esp)
247 popl %eax
248 cmpl $32767,%eax
249 jg 1f
250 cmpl $-32768,%eax
251 jl 2f
252 movw %ax,(%esi)
253 jmp 4f
254 1: movw $32767,(%esi)
255 jmp 3f
256 2: movw $-32768,(%esi)
257 3:
258 /* incl %edi */
259 4:
260 .L62:
261 addl $-64,%ebx
262 addl $4,%esi
263 movl LOC0,%edx
264 leal -128(%ecx,%edx,8),%ecx
265 movl $15,%ebp
266 .L68:
267 flds -4(%ecx)
268 fchs
269 fmuls (%ebx)
270 flds -8(%ecx)
271 fmuls 4(%ebx)
272 fxch %st(1)
273 flds -12(%ecx)
274 fmuls 8(%ebx)
275 fxch %st(2)
276 fsubrp %st,%st(1)
277 flds -16(%ecx)
278 fmuls 12(%ebx)
279 fxch %st(2)
280 fsubrp %st,%st(1)
281 flds -20(%ecx)
282 fmuls 16(%ebx)
283 fxch %st(2)
284 fsubrp %st,%st(1)
285 flds -24(%ecx)
286 fmuls 20(%ebx)
287 fxch %st(2)
288 fsubrp %st,%st(1)
289 flds -28(%ecx)
290 fmuls 24(%ebx)
291 fxch %st(2)
292 fsubrp %st,%st(1)
293 flds -32(%ecx)
294 fmuls 28(%ebx)
295 fxch %st(2)
296 fsubrp %st,%st(1)
297 flds -36(%ecx)
298 fmuls 32(%ebx)
299 fxch %st(2)
300 fsubrp %st,%st(1)
301 flds -40(%ecx)
302 fmuls 36(%ebx)
303 fxch %st(2)
304 fsubrp %st,%st(1)
305 flds -44(%ecx)
306 fmuls 40(%ebx)
307 fxch %st(2)
308 fsubrp %st,%st(1)
309 flds -48(%ecx)
310 fmuls 44(%ebx)
311 fxch %st(2)
312 fsubrp %st,%st(1)
313 flds -52(%ecx)
314 fmuls 48(%ebx)
315 fxch %st(2)
316 fsubrp %st,%st(1)
317 flds -56(%ecx)
318 fmuls 52(%ebx)
319 fxch %st(2)
320 fsubrp %st,%st(1)
321 flds -60(%ecx)
322 fmuls 56(%ebx)
323 fxch %st(2)
324 fsubrp %st,%st(1)
325 flds (%ecx)
326 fmuls 60(%ebx)
327 fxch %st(2)
328 subl $4,%esp
329 fsubrp %st,%st(1)
330 fxch %st(1)
331 fsubrp %st,%st(1)
332
333 addl $4,DITHERINDEX2
334 andl $0x0003fffc,DITHERINDEX2
335 movl DITHERNOISE2,%edi
336 addl DITHERINDEX2,%edi
337
338 fadds (%edi)
339 /* fistpl and popl as a unit keep the stack unchanged */
340 fistpl (%esp)
341 popl %eax
342 cmpl $32767,%eax
343 jg 1f
344 cmpl $-32768,%eax
345 jl 2f
346 movw %ax,(%esi)
347 jmp 4f
348 1: movw $32767,(%esi)
349 jmp 3f
350 2: movw $-32768,(%esi)
351 3:
352 /* incl %edi */
353 4:
354 .L67:
355 addl $-64,%ebx
356 addl $-128,%ecx
357 addl $4,%esi
358 decl %ebp
359 jnz .L68
360 /* return ipv edi 0 in eax */
361 movl $0,%eax
362 /* save ditherindex */
363 movl BO,%ebx
364 movl DITHERINDEX,%esi
365 movl %esi,4(%ebx);
366 /* stack: 0=ebx 4=esi 8=edi 12=ebp 16,20,24,28=local 32=back 36=bandptr 40=channel 44=out 48=buffs 52=bo */
367 popl %ebx
368 popl %esi
369 popl %edi
370 popl %ebp
371 addl $16,%esp
372 /* The stack must be now: 0=back 4=bandptr 8=channel 12=out 16=buffs 20=bo */
373 ret
374
375 NONEXEC_STACK