Path: blob/master/libs/mpg123/src/libmpg123/optimize.h
4394 views
#ifndef MPG123_H_OPTIMIZE1#define MPG123_H_OPTIMIZE2/*3optimize: get a grip on the different optimizations45copyright 2007-2013 by the mpg123 project - free software under the terms of the LGPL 2.16see COPYING and AUTHORS files in distribution or http://mpg123.org7initially written by Thomas Orgis, taking from mpg123.[hc]89for building mpg123 with one optimization only, you have to choose exclusively between10OPT_GENERIC (generic C code for everyone)11OPT_GENERIC_DITHER (same with dithering for 1to1)12OPT_I386 (Intel i386)13OPT_I486 (Somewhat special code for i486; does not work together with others.)14OPT_I586 (Intel Pentium)15OPT_I586_DITHER (Intel Pentium with dithering/noise shaping for enhanced quality)16OPT_MMX (Intel Pentium and compatibles with MMX, fast, but not the best accuracy)17OPT_3DNOW (AMD 3DNow!, K6-2/3, Athlon, compatibles...)18OPT_3DNOW_VINTAGE19OPT_3DNOWEXT (AMD 3DNow! extended, generally Athlon, compatibles...)20OPT_3DNOWEXT_VINTAGE21OPT_SSE22OPT_SSE_VINTAGE23OPT_ALTIVEC (Motorola/IBM PPC with AltiVec under MacOSX)24OPT_X86_64 (x86-64 / AMD64 / Intel 64)25OPT_AVX2627or you define OPT_MULTI and give a combination which makes sense (do not include i486, do not mix altivec and x86).2829I still have to examine the dynamics of this here together with REAL_IS_FIXED.30Basic point is: Don't use REAL_IS_FIXED with something else than generic or i386.3132Also, one should minimize code size by really ensuring that only functions that are really needed are included.33Currently, all generic functions will be always there (to be safe for fallbacks for advanced decoders).34Strictly, at least the INT123_synth_1to1 should not be necessary for single-decoder mode.35*/363738/* Runtime optimization interface now here: */3940/* Nedit inline Perl script to generate decoder list and name mapping in one place41optimize.c defining I_AM_OPTIMIZE to get the names4243perl <<'EOT'44## order is important (autodec first, nodec last)45@names=46(47['autodec', 'auto']48,['generic', 'generic']49,['generic_dither', 'generic_dither']50,['idrei', 'i386']51,['ivier', 'i486']52,['ifuenf', 'i586']53,['ifuenf_dither', 'i586_dither']54,['mmx', 'MMX']55,['dreidnow', '3DNow']56,['dreidnowext', '3DNowExt']57,['altivec', 'AltiVec']58,['sse', 'SSE']59,['x86_64', 'x86-64']60,['arm','ARM']61,['neon','NEON']62,['avx','AVX']63,['dreidnow_vintage', '3DNow_vintage']64,['dreidnowext_vintage', '3DNowExt_vintage']65,['sse_vintage', 'SSE_vintage']66,['nodec', 'nodec']67);6869print "enum optdec\n{\n";70for my $n (@names)71{72$name = $n->[0];73$enum = $name eq 'autodec' ? $name = " $name=0" : ",$name";74print "\t$enum\n"75}76print "};\n";77print "##ifdef I_AM_OPTIMIZE\n";78for my $n (@names)79{80my $key = $n->[0];81my $val = $n->[1];82print "static const char dn_$key\[\] = \"$val\";\n";83}84print "static const char* decname[] =\n{\n";85for my $n (@names)86{87my $key = $n->[0];88print "\t".($key eq 'autodec' ? ' ' : ',')."dn_$key\n";89}90print "};\n##endif"91EOT92*/93enum optdec94{95autodec=096,generic97,generic_dither98,idrei99,ivier100,ifuenf101,ifuenf_dither102,mmx103,dreidnow104,dreidnowext105,altivec106,sse107,x86_64108,arm109,neon110,neon64111,avx112,dreidnow_vintage113,dreidnowext_vintage114,sse_vintage115,nodec116};117#ifdef I_AM_OPTIMIZE118static const char dn_autodec[] = "auto";119static const char dn_generic[] = "generic";120static const char dn_generic_dither[] = "generic_dither";121static const char dn_idrei[] = "i386";122static const char dn_ivier[] = "i486";123static const char dn_ifuenf[] = "i586";124static const char dn_ifuenf_dither[] = "i586_dither";125static const char dn_mmx[] = "MMX";126static const char dn_dreidnow[] = "3DNow";127static const char dn_dreidnowext[] = "3DNowExt";128static const char dn_altivec[] = "AltiVec";129static const char dn_sse[] = "SSE";130static const char dn_x86_64[] = "x86-64";131static const char dn_arm[] = "ARM";132static const char dn_neon[] = "NEON";133static const char dn_neon64[] = "NEON64";134static const char dn_avx[] = "AVX";135static const char dn_dreidnow_vintage[] = "3DNow_vintage";136static const char dn_dreidnowext_vintage[] = "3DNowExt_vintage";137static const char dn_sse_vintage[] = "SSE_vintage";138static const char dn_nodec[] = "nodec";139static const char* decname[] =140{141dn_autodec142,dn_generic143,dn_generic_dither144,dn_idrei145,dn_ivier146,dn_ifuenf147,dn_ifuenf_dither148,dn_mmx149,dn_dreidnow150,dn_dreidnowext151,dn_altivec152,dn_sse153,dn_x86_64154,dn_arm155,dn_neon156,dn_neon64157,dn_avx158,dn_dreidnow_vintage159,dn_dreidnowext_vintage160,dn_sse_vintage161,dn_nodec162};163#endif164165enum optcla { nocla=0, normal, mmxsse };166167/* - Set up the table of synth functions for current decoder choice. */168int INT123_frame_cpu_opt(mpg123_handle *fr, const char* cpu);169/* - Choose, from the synth table, the synth functions to use for current output format/rate. */170int INT123_set_synth_functions(mpg123_handle *fr);171/* - Parse decoder name and return numerical code. */172enum optdec INT123_dectype(const char* decoder);173/* - Return the default decoder type. */174enum optdec INT123_defdec(void);175/* - Return the class of a decoder type (mmxsse or normal). */176enum optcla INT123_decclass(const enum optdec);177178/* Now comes a whole lot of definitions, for multi decoder mode and single decoder mode.179Because of the latter, it may look redundant at times. */180181/* this is included in mpg123.h, which includes config.h */182#ifdef CCALIGN183#define ALIGNED(a) __attribute__((aligned(a)))184#else185#define ALIGNED(a)186#endif187188/* Safety catch for invalid decoder choice. */189#ifdef REAL_IS_FIXED190#if (defined OPT_I486) || (defined OPT_I586) || (defined OPT_I586_DITHER) \191|| (defined OPT_MMX) || (defined OPT_SSE) || (defined_OPT_ALTIVEC) \192|| (defined OPT_3DNOW) || (defined OPT_3DNOWEXT) || (defined OPT_X86_64) \193|| (defined OPT_3DNOW_VINTAGE) || (defined OPT_3DNOWEXT_VINTAGE) \194|| (defined OPT_SSE_VINTAGE) \195|| (defined OPT_NEON) || (defined OPT_NEON64) || (defined OPT_AVX) \196|| (defined OPT_GENERIC_DITHER)197#error "Bad decoder choice together with fixed point math!"198#endif199#endif200201#if (defined NO_LAYER1 && defined NO_LAYER2)202#define NO_LAYER12203#endif204205#ifdef OPT_GENERIC206#ifndef OPT_MULTI207# define defopt generic208#endif209#endif210211#ifdef OPT_GENERIC_DITHER212#define OPT_DITHER213#ifndef OPT_MULTI214# define defopt generic_dither215#endif216#endif217218/* i486 is special... always alone! */219#ifdef OPT_I486220#define OPT_X86221#define defopt ivier222#ifdef OPT_MULTI223#error "i486 can only work alone!"224#endif225#define FIR_BUFFER_SIZE 128226#define FIR_SIZE 16227#endif228229#ifdef OPT_I386230#define OPT_X86231#ifndef OPT_MULTI232# define defopt idrei233#endif234#endif235236#ifdef OPT_I586237#define OPT_X86238#ifndef OPT_MULTI239# define defopt ifuenf240#endif241#endif242243#ifdef OPT_I586_DITHER244#define OPT_X86245#define OPT_DITHER246#ifndef OPT_MULTI247# define defopt ifuenf_dither248#endif249#endif250251/* We still have some special code around MMX tables. */252253#ifdef OPT_MMX254#define OPT_MMXORSSE255#define OPT_X86256#ifndef OPT_MULTI257# define defopt mmx258#endif259#endif260261#ifdef OPT_SSE262#define OPT_MMXORSSE263#define OPT_MPLAYER264#define OPT_X86265#ifndef OPT_MULTI266# define defopt sse267# define opt_dct36(fr) INT123_dct36_sse268#endif269#endif270271#ifdef OPT_SSE_VINTAGE272#define OPT_MMXORSSE273#define OPT_MPLAYER274#define OPT_X86275#ifndef OPT_MULTI276# define defopt sse277#endif278#endif279280#ifdef OPT_3DNOWEXT281#define OPT_MMXORSSE282#define OPT_MPLAYER283#define OPT_X86284#ifndef OPT_MULTI285# define defopt dreidnowext286#endif287#endif288289/* same as above but also using 3DNowExt INT123_dct36 */290#ifdef OPT_3DNOWEXT_VINTAGE291#define OPT_MMXORSSE292#define OPT_MPLAYER293#define OPT_X86294#ifndef OPT_MULTI295# define defopt dreidnowext_vintage296# define opt_dct36(fr) INT123_dct36_3dnowext297#endif298#endif299300#ifdef OPT_MPLAYER301extern const int INT123_costab_mmxsse[];302#endif303304/* 3dnow used to use INT123_synth_1to1_i586 for mono / 8bit conversion - was that intentional? */305/* I'm trying to skip the pentium code here ... until I see that that is indeed a bad idea */306#ifdef OPT_3DNOW307#define OPT_X86308#ifndef OPT_MULTI309# define defopt dreidnow310#endif311#endif312313/* same as above but also using 3DNow INT123_dct36 */314#ifdef OPT_3DNOW_VINTAGE315#define OPT_X86316#ifndef OPT_MULTI317# define defopt dreidnow_vintage318# define opt_dct36(fr) INT123_dct36_3dnow319#endif320#endif321322#ifdef OPT_ALTIVEC323#ifndef OPT_MULTI324# define defopt altivec325#endif326#endif327328#ifdef OPT_X86_64329#define OPT_MMXORSSE330#ifndef OPT_MULTI331# define defopt x86_64332# define opt_dct36(fr) INT123_dct36_x86_64333#endif334#endif335336#ifdef OPT_AVX337#define OPT_MMXORSSE338#ifndef OPT_MULTI339# define defopt avx340# define opt_dct36(fr) INT123_dct36_avx341#endif342#endif343344#ifdef OPT_ARM345#ifndef OPT_MULTI346# define defopt arm347#endif348#endif349350#ifdef OPT_NEON351#define OPT_MMXORSSE352#ifndef OPT_MULTI353# define defopt neon354# define opt_dct36(fr) INT123_dct36_neon355#endif356#endif357358#ifdef OPT_NEON64359#define OPT_MMXORSSE360#ifndef OPT_MULTI361# define defopt neon64362# define opt_dct36(fr) INT123_dct36_neon64363#endif364#endif365366#ifdef OPT_MULTI367368# define defopt nodec369370# ifndef NO_LAYER3371# 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)372# define OPT_THE_DCT36373# define opt_dct36(fr) ((fr)->cpu_opts.the_dct36)374# endif375# endif376377#endif /* OPT_MULTI else */378379# ifndef opt_dct36380# define opt_dct36(fr) INT123_dct36381# endif382383#endif /* MPG123_H_OPTIMIZE */384385386