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 44 perl <<'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 70 print "enum optdec\n{\n"; 71 for my $n (@names) 72 { 73 $name = $n->[0]; 74 $enum = $name eq 'autodec' ? $name = " $name=0" : ",$name"; 75 print "\t$enum\n" 76 } 77 print "};\n"; 78 print "##ifdef I_AM_OPTIMIZE\n"; 79 for my $n (@names) 80 { 81 my $key = $n->[0]; 82 my $val = $n->[1]; 83 print "static const char dn_$key\[\] = \"$val\";\n"; 84 } 85 print "static const char* decname[] =\n{\n"; 86 for my $n (@names) 87 { 88 my $key = $n->[0]; 89 print "\t".($key eq 'autodec' ? ' ' : ',')."dn_$key\n"; 90 } 91 print "};\n##endif" 92 EOT 93 */ 94 enum optdec 95 { 96 autodec=0 97 ,generic 98 ,generic_dither 99 ,idrei 100 ,ivier 101 ,ifuenf 102 ,ifuenf_dither 103 ,mmx 104 ,dreidnow 105 ,dreidnowext 106 ,altivec 107 ,sse 108 ,x86_64 109 ,arm 110 ,neon 111 ,neon64 112 ,avx 113 ,dreidnow_vintage 114 ,dreidnowext_vintage 115 ,sse_vintage 116 ,nodec 117 }; 118 #ifdef I_AM_OPTIMIZE 119 static const char dn_autodec[] = "auto"; 120 static const char dn_generic[] = "generic"; 121 static const char dn_generic_dither[] = "generic_dither"; 122 static const char dn_idrei[] = "i386"; 123 static const char dn_ivier[] = "i486"; 124 static const char dn_ifuenf[] = "i586"; 125 static const char dn_ifuenf_dither[] = "i586_dither"; 126 static const char dn_mmx[] = "MMX"; 127 static const char dn_dreidnow[] = "3DNow"; 128 static const char dn_dreidnowext[] = "3DNowExt"; 129 static const char dn_altivec[] = "AltiVec"; 130 static const char dn_sse[] = "SSE"; 131 static const char dn_x86_64[] = "x86-64"; 132 static const char dn_arm[] = "ARM"; 133 static const char dn_neon[] = "NEON"; 134 static const char dn_neon64[] = "NEON64"; 135 static const char dn_avx[] = "AVX"; 136 static const char dn_dreidnow_vintage[] = "3DNow_vintage"; 137 static const char dn_dreidnowext_vintage[] = "3DNowExt_vintage"; 138 static const char dn_sse_vintage[] = "SSE_vintage"; 139 static const char dn_nodec[] = "nodec"; 140 static 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 166 enum optcla { nocla=0, normal, mmxsse }; 167 168 /* - Set up the table of synth functions for current decoder choice. */ 169 int 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. */ 171 int set_synth_functions(mpg123_handle *fr); 172 /* - Parse decoder name and return numerical code. */ 173 enum optdec dectype(const char* decoder); 174 /* - Return the default decoder type. */ 175 enum optdec defdec(void); 176 /* - Return the class of a decoder type (mmxsse or normal). */ 177 enum 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 306 extern 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 */ 372 void 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 396