ReactOS 0.4.15-dev-8061-g57b775e
optimize.h
Go to the documentation of this file.
1#ifndef MPG123_H_OPTIMIZE
2#define MPG123_H_OPTIMIZE
3/*
4 optimize: get a grip on the different optimizations
5
6 copyright 2007-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
7 see COPYING and AUTHORS files in distribution or http://mpg123.org
8 initially written by Thomas Orgis, taking from mpg123.[hc]
9
10 for building mpg123 with one optimization only, you have to choose exclusively between
11 OPT_GENERIC (generic C code for everyone)
12 OPT_GENERIC_DITHER (same with dithering for 1to1)
13 OPT_I386 (Intel i386)
14 OPT_I486 (Somewhat special code for i486; does not work together with others.)
15 OPT_I586 (Intel Pentium)
16 OPT_I586_DITHER (Intel Pentium with dithering/noise shaping for enhanced quality)
17 OPT_MMX (Intel Pentium and compatibles with MMX, fast, but not the best accuracy)
18 OPT_3DNOW (AMD 3DNow!, K6-2/3, Athlon, compatibles...)
19 OPT_3DNOW_VINTAGE
20 OPT_3DNOWEXT (AMD 3DNow! extended, generally Athlon, compatibles...)
21 OPT_3DNOWEXT_VINTAGE
22 OPT_SSE
23 OPT_SSE_VINTAGE
24 OPT_ALTIVEC (Motorola/IBM PPC with AltiVec under MacOSX)
25 OPT_X86_64 (x86-64 / AMD64 / Intel 64)
26 OPT_AVX
27
28 or you define OPT_MULTI and give a combination which makes sense (do not include i486, do not mix altivec and x86).
29
30 I still have to examine the dynamics of this here together with REAL_IS_FIXED.
31 Basic point is: Don't use REAL_IS_FIXED with something else than generic or i386.
32
33 Also, one should minimize code size by really ensuring that only functions that are really needed are included.
34 Currently, all generic functions will be always there (to be safe for fallbacks for advanced decoders).
35 Strictly, at least the synth_1to1 should not be necessary for single-decoder mode.
36*/
37
38
39/* Runtime optimization interface now here: */
40
41/* Nedit inline Perl script to generate decoder list and name mapping in one place
42 optimize.c defining I_AM_OPTIMIZE to get the names
43
44perl <<'EOT'
45## order is important (autodec first, nodec last)
46@names=
47(
48 ['autodec', 'auto']
49,['generic', 'generic']
50,['generic_dither', 'generic_dither']
51,['idrei', 'i386']
52,['ivier', 'i486']
53,['ifuenf', 'i586']
54,['ifuenf_dither', 'i586_dither']
55,['mmx', 'MMX']
56,['dreidnow', '3DNow']
57,['dreidnowext', '3DNowExt']
58,['altivec', 'AltiVec']
59,['sse', 'SSE']
60,['x86_64', 'x86-64']
61,['arm','ARM']
62,['neon','NEON']
63,['avx','AVX']
64,['dreidnow_vintage', '3DNow_vintage']
65,['dreidnowext_vintage', '3DNowExt_vintage']
66,['sse_vintage', 'SSE_vintage']
67,['nodec', 'nodec']
68);
69
70print "enum optdec\n{\n";
71for my $n (@names)
72{
73 $name = $n->[0];
74 $enum = $name eq 'autodec' ? $name = " $name=0" : ",$name";
75 print "\t$enum\n"
76}
77print "};\n";
78print "##ifdef I_AM_OPTIMIZE\n";
79for my $n (@names)
80{
81 my $key = $n->[0];
82 my $val = $n->[1];
83 print "static const char dn_$key\[\] = \"$val\";\n";
84}
85print "static const char* decname[] =\n{\n";
86for my $n (@names)
87{
88 my $key = $n->[0];
89 print "\t".($key eq 'autodec' ? ' ' : ',')."dn_$key\n";
90}
91print "};\n##endif"
92EOT
93*/
95{
96 autodec=0
118#ifdef I_AM_OPTIMIZE
119static const char dn_autodec[] = "auto";
120static const char dn_generic[] = "generic";
121static const char dn_generic_dither[] = "generic_dither";
122static const char dn_idrei[] = "i386";
123static const char dn_ivier[] = "i486";
124static const char dn_ifuenf[] = "i586";
125static const char dn_ifuenf_dither[] = "i586_dither";
126static const char dn_mmx[] = "MMX";
127static const char dn_dreidnow[] = "3DNow";
128static const char dn_dreidnowext[] = "3DNowExt";
129static const char dn_altivec[] = "AltiVec";
130static const char dn_sse[] = "SSE";
131static const char dn_x86_64[] = "x86-64";
132static const char dn_arm[] = "ARM";
133static const char dn_neon[] = "NEON";
134static const char dn_neon64[] = "NEON64";
135static const char dn_avx[] = "AVX";
136static const char dn_dreidnow_vintage[] = "3DNow_vintage";
137static const char dn_dreidnowext_vintage[] = "3DNowExt_vintage";
138static const char dn_sse_vintage[] = "SSE_vintage";
139static const char dn_nodec[] = "nodec";
140static const char* decname[] =
141{
142 dn_autodec
143 ,dn_generic
144 ,dn_generic_dither
145 ,dn_idrei
146 ,dn_ivier
147 ,dn_ifuenf
148 ,dn_ifuenf_dither
149 ,dn_mmx
150 ,dn_dreidnow
151 ,dn_dreidnowext
152 ,dn_altivec
153 ,dn_sse
154 ,dn_x86_64
155 ,dn_arm
156 ,dn_neon
157 ,dn_neon64
158 ,dn_avx
159 ,dn_dreidnow_vintage
160 ,dn_dreidnowext_vintage
161 ,dn_sse_vintage
162 ,dn_nodec
163};
164#endif
165
167
168/* - Set up the table of synth functions for current decoder choice. */
169int frame_cpu_opt(mpg123_handle *fr, const char* cpu);
170/* - Choose, from the synth table, the synth functions to use for current output format/rate. */
172/* - Parse decoder name and return numerical code. */
173enum optdec dectype(const char* decoder);
174/* - Return the default decoder type. */
175enum optdec defdec(void);
176/* - Return the class of a decoder type (mmxsse or normal). */
177enum optcla decclass(const enum optdec);
178
179/* Now comes a whole lot of definitions, for multi decoder mode and single decoder mode.
180 Because of the latter, it may look redundant at times. */
181
182/* this is included in mpg123.h, which includes config.h */
183#ifdef CCALIGN
184#ifdef _MSC_VER
185#define ALIGNED(a) __declspec(align(a))
186#else
187#define ALIGNED(a) __attribute__((aligned(a)))
188#endif
189#else
190#define ALIGNED(a)
191#endif
192
193/* Safety catch for invalid decoder choice. */
194#ifdef REAL_IS_FIXED
195#if (defined OPT_I486) || (defined OPT_I586) || (defined OPT_I586_DITHER) \
196 || (defined OPT_MMX) || (defined OPT_SSE) || (defined_OPT_ALTIVEC) \
197 || (defined OPT_3DNOW) || (defined OPT_3DNOWEXT) || (defined OPT_X86_64) \
198 || (defined OPT_3DNOW_VINTAGE) || (defined OPT_3DNOWEXT_VINTAGE) \
199 || (defined OPT_SSE_VINTAGE) \
200 || (defined OPT_NEON) || (defined OPT_NEON64) || (defined OPT_AVX) \
201 || (defined OPT_GENERIC_DITHER)
202#error "Bad decoder choice together with fixed point math!"
203#endif
204#endif
205
206#if (defined NO_LAYER1 && defined NO_LAYER2)
207#define NO_LAYER12
208#endif
209
210#ifdef OPT_GENERIC
211#ifndef OPT_MULTI
212# define defopt generic
213#endif
214#endif
215
216#ifdef OPT_GENERIC_DITHER
217#define OPT_DITHER
218#ifndef OPT_MULTI
219# define defopt generic_dither
220#endif
221#endif
222
223/* i486 is special... always alone! */
224#ifdef OPT_I486
225#define OPT_X86
226#define defopt ivier
227#ifdef OPT_MULTI
228#error "i486 can only work alone!"
229#endif
230#define FIR_BUFFER_SIZE 128
231#define FIR_SIZE 16
232#endif
233
234#ifdef OPT_I386
235#define OPT_X86
236#ifndef OPT_MULTI
237# define defopt idrei
238#endif
239#endif
240
241#ifdef OPT_I586
242#define OPT_X86
243#ifndef OPT_MULTI
244# define defopt ifuenf
245#endif
246#endif
247
248#ifdef OPT_I586_DITHER
249#define OPT_X86
250#define OPT_DITHER
251#ifndef OPT_MULTI
252# define defopt ifuenf_dither
253#endif
254#endif
255
256/* We still have some special code around MMX tables. */
257
258#ifdef OPT_MMX
259#define OPT_MMXORSSE
260#define OPT_X86
261#ifndef OPT_MULTI
262# define defopt mmx
263#endif
264#endif
265
266#ifdef OPT_SSE
267#define OPT_MMXORSSE
268#define OPT_MPLAYER
269#define OPT_X86
270#ifndef OPT_MULTI
271# define defopt sse
272# define opt_dct36(fr) dct36_sse
273#endif
274#endif
275
276#ifdef OPT_SSE_VINTAGE
277#define OPT_MMXORSSE
278#define OPT_MPLAYER
279#define OPT_X86
280#ifndef OPT_MULTI
281# define defopt sse
282#endif
283#endif
284
285#ifdef OPT_3DNOWEXT
286#define OPT_MMXORSSE
287#define OPT_MPLAYER
288#define OPT_X86
289#ifndef OPT_MULTI
290# define defopt dreidnowext
291#endif
292#endif
293
294/* same as above but also using 3DNowExt dct36 */
295#ifdef OPT_3DNOWEXT_VINTAGE
296#define OPT_MMXORSSE
297#define OPT_MPLAYER
298#define OPT_X86
299#ifndef OPT_MULTI
300# define defopt dreidnowext_vintage
301# define opt_dct36(fr) dct36_3dnowext
302#endif
303#endif
304
305#ifdef OPT_MPLAYER
306extern const int costab_mmxsse[];
307#endif
308
309/* 3dnow used to use synth_1to1_i586 for mono / 8bit conversion - was that intentional? */
310/* I'm trying to skip the pentium code here ... until I see that that is indeed a bad idea */
311#ifdef OPT_3DNOW
312#define OPT_X86
313#ifndef OPT_MULTI
314# define defopt dreidnow
315#endif
316#endif
317
318/* same as above but also using 3DNow dct36 */
319#ifdef OPT_3DNOW_VINTAGE
320#define OPT_X86
321#ifndef OPT_MULTI
322# define defopt dreidnow_vintage
323# define opt_dct36(fr) dct36_3dnow
324#endif
325#endif
326
327#ifdef OPT_ALTIVEC
328#ifndef OPT_MULTI
329# define defopt altivec
330#endif
331#endif
332
333#ifdef OPT_X86_64
334#define OPT_MMXORSSE
335#ifndef OPT_MULTI
336# define defopt x86_64
337# define opt_dct36(fr) dct36_x86_64
338#endif
339#endif
340
341#ifdef OPT_AVX
342#define OPT_MMXORSSE
343#ifndef OPT_MULTI
344# define defopt avx
345# define opt_dct36(fr) dct36_avx
346#endif
347#endif
348
349#ifdef OPT_ARM
350#ifndef OPT_MULTI
351# define defopt arm
352#endif
353#endif
354
355#ifdef OPT_NEON
356#define OPT_MMXORSSE
357#ifndef OPT_MULTI
358# define defopt neon
359# define opt_dct36(fr) dct36_neon
360#endif
361#endif
362
363#ifdef OPT_NEON64
364#define OPT_MMXORSSE
365#ifndef OPT_MULTI
366# define defopt neon64
367# define opt_dct36(fr) dct36_neon64
368#endif
369#endif
370
371/* used for multi opt mode and the single 3dnow mode to have the old 3dnow test flag still working */
372void check_decoders(void);
373
374/*
375 Now come two blocks of standard definitions for multi-decoder mode and single-decoder mode.
376 Most stuff is so automatic that it's indeed generated by some inline shell script.
377 Remember to use these scripts when possible, instead of direct repetitive hacking.
378*/
379
380#ifdef OPT_MULTI
381
382# define defopt nodec
383
384# if (defined OPT_3DNOW_VINTAGE || defined OPT_3DNOWEXT_VINTAGE || defined OPT_SSE || defined OPT_X86_64 || defined OPT_AVX || defined OPT_NEON || defined OPT_NEON64)
385# define opt_dct36(fr) ((fr)->cpu_opts.the_dct36)
386# endif
387
388#endif /* OPT_MULTI else */
389
390# ifndef opt_dct36
391# define opt_dct36(fr) dct36
392# endif
393
394#endif /* MPG123_H_OPTIMIZE */
395
#define costab_mmxsse
Definition: intsym.h:365
#define decclass
Definition: intsym.h:235
#define set_synth_functions
Definition: intsym.h:232
#define dectype
Definition: intsym.h:233
#define frame_cpu_opt
Definition: intsym.h:231
void check_decoders(void)
Definition: optimize.c:1084
optcla
Definition: optimize.h:166
@ mmxsse
Definition: optimize.h:166
@ nocla
Definition: optimize.h:166
@ normal
Definition: optimize.h:166
enum optdec defdec(void)
Definition: optimize.c:139
optdec
Definition: optimize.h:95
@ avx
Definition: optimize.h:112
@ ivier
Definition: optimize.h:100
@ x86_64
Definition: optimize.h:108
@ neon64
Definition: optimize.h:111
@ dreidnowext_vintage
Definition: optimize.h:114
@ dreidnow
Definition: optimize.h:104
@ nodec
Definition: optimize.h:116
@ sse_vintage
Definition: optimize.h:115
@ generic_dither
Definition: optimize.h:98
@ ifuenf
Definition: optimize.h:101
@ altivec
Definition: optimize.h:106
@ autodec
Definition: optimize.h:96
@ arm
Definition: optimize.h:109
@ dreidnowext
Definition: optimize.h:105
@ sse
Definition: optimize.h:107
@ ifuenf_dither
Definition: optimize.h:102
@ mmx
Definition: optimize.h:103
@ generic
Definition: optimize.h:97
@ neon
Definition: optimize.h:110
@ dreidnow_vintage
Definition: optimize.h:113
@ idrei
Definition: optimize.h:99