2 * libmad - MPEG audio decoder library
3 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 # ifndef LIBMAD_FIXED_H
23 # define LIBMAD_FIXED_H
27 typedef int32_t mad_fixed_t
;
29 typedef int32_t mad_fixed64hi_t
;
30 typedef uint32_t mad_fixed64lo_t
;
32 # if defined(_MSC_VER)
33 # define mad_fixed64_t signed __int64
34 # elif 1 || defined(__GNUC__)
35 # define mad_fixed64_t signed long long
38 # if defined(FPM_FLOAT)
39 typedef double mad_sample_t
;
41 typedef mad_fixed_t mad_sample_t
;
45 * Fixed-point format: 0xABBBBBBB
46 * A == whole part (sign + 3 bits)
47 * B == fractional part (28 bits)
49 * Values are signed two's complement, so the effective range is:
50 * 0x80000000 to 0x7fffffff
51 * -8.0 to +7.9999999962747097015380859375
53 * The smallest representable value is:
54 * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
56 * 28 bits of fractional accuracy represent about
57 * 8.6 digits of decimal accuracy.
59 * Fixed-point numbers can be added or subtracted as normal
60 * integers, but multiplication requires shifting the 64-bit result
61 * from 56 fractional bits back to 28 (and rounding.)
63 * Changing the definition of MAD_F_FRACBITS is only partially
64 * supported, and must be done with care.
67 # define MAD_F_FRACBITS 28
69 # if MAD_F_FRACBITS == 28
70 # define MAD_F(x) ((mad_fixed_t) (x##L))
72 # if MAD_F_FRACBITS < 28
73 # warning "MAD_F_FRACBITS < 28"
74 # define MAD_F(x) ((mad_fixed_t) \
76 (1L << (28 - MAD_F_FRACBITS - 1))) >> \
77 (28 - MAD_F_FRACBITS)))
78 # elif MAD_F_FRACBITS > 28
79 # error "MAD_F_FRACBITS > 28 not currently supported"
80 # define MAD_F(x) ((mad_fixed_t) \
81 ((x##L) << (MAD_F_FRACBITS - 28)))
85 # define MAD_F_MIN ((mad_fixed_t) -0x80000000L)
86 # define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL)
88 # define MAD_F_ONE MAD_F(0x10000000)
90 # define mad_f_tofixed(x) ((mad_fixed_t) \
91 ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
92 # define mad_f_todouble(x) ((double) \
93 ((x) / (double) (1L << MAD_F_FRACBITS)))
95 # define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS)
96 # define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1))
97 /* (x should be positive) */
99 # define mad_f_fromint(x) ((x) << MAD_F_FRACBITS)
101 # define mad_f_add(x, y) ((x) + (y))
102 # define mad_f_sub(x, y) ((x) - (y))
104 # if defined(FPM_FLOAT)
105 # error "FPM_FLOAT not yet supported"
108 # define MAD_F(x) mad_f_todouble(x)
110 # define mad_f_mul(x, y) ((x) * (y))
111 # define mad_f_scale64
113 # elif defined(FPM_64BIT)
116 * This version should be the most accurate if 64-bit types are supported by
117 * the compiler, although it may not be the most efficient.
119 # if defined(OPT_ACCURACY)
120 # define mad_f_mul(x, y) \
122 ((((mad_fixed64_t) (x) * (y)) + \
123 (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
125 # define mad_f_mul(x, y) \
126 ((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS))
129 # define MAD_F_SCALEBITS MAD_F_FRACBITS
131 /* --- Intel --------------------------------------------------------------- */
133 # elif defined(FPM_INTEL)
135 # if defined(_MSC_VER)
136 # pragma warning(push)
137 # pragma warning(disable: 4035) /* no return value */
139 mad_fixed_t
mad_f_mul_inline(mad_fixed_t x
, mad_fixed_t y
)
142 fracbits
= MAD_F_FRACBITS
148 shrd eax
, edx
, fracbits
151 /* implicit return of eax */
153 # pragma warning(pop)
155 # define mad_f_mul mad_f_mul_inline
156 # define mad_f_scale64
159 * This Intel version is fast and accurate; the disposition of the least
160 * significant bit depends on OPT_ACCURACY via mad_f_scale64().
162 # define MAD_F_MLX(hi, lo, x, y) \
164 : "=a" (lo), "=d" (hi) \
165 : "%a" (x), "rm" (y) \
168 # if defined(OPT_ACCURACY)
170 * This gives best accuracy but is not very fast.
172 # define MAD_F_MLA(hi, lo, x, y) \
173 ({ mad_fixed64hi_t __hi; \
174 mad_fixed64lo_t __lo; \
175 MAD_F_MLX(__hi, __lo, (x), (y)); \
176 asm ("addl %2,%0\n\t" \
178 : "=rm" (lo), "=rm" (hi) \
179 : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \
182 # endif /* OPT_ACCURACY */
184 # if defined(OPT_ACCURACY)
186 * Surprisingly, this is faster than SHRD followed by ADC.
188 # define mad_f_scale64(hi, lo) \
189 ({ mad_fixed64hi_t __hi_; \
190 mad_fixed64lo_t __lo_; \
191 mad_fixed_t __result; \
192 asm ("addl %4,%2\n\t" \
194 : "=rm" (__lo_), "=rm" (__hi_) \
195 : "0" (lo), "1" (hi), \
196 "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \
198 asm ("shrdl %3,%2,%1" \
200 : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \
204 # elif defined(OPT_INTEL)
206 * Alternate Intel scaling that may or may not perform better.
208 # define mad_f_scale64(hi, lo) \
209 ({ mad_fixed_t __result; \
210 asm ("shrl %3,%1\n\t" \
214 : "0" (lo), "r" (hi), \
215 "I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS) \
220 # define mad_f_scale64(hi, lo) \
221 ({ mad_fixed_t __result; \
222 asm ("shrdl %3,%2,%1" \
224 : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \
228 # endif /* OPT_ACCURACY */
230 # define MAD_F_SCALEBITS MAD_F_FRACBITS
233 /* --- ARM ----------------------------------------------------------------- */
235 # elif defined(FPM_ARM)
238 * This ARM V4 version is as accurate as FPM_64BIT but much faster. The
239 * least significant bit is properly rounded at no CPU cycle cost!
243 * This is faster than the default implementation via MAD_F_MLX() and
246 # define mad_f_mul(x, y) \
247 ({ mad_fixed64hi_t __hi; \
248 mad_fixed64lo_t __lo; \
249 mad_fixed_t __result; \
250 asm ("smull %0, %1, %3, %4\n\t" \
251 "movs %0, %0, lsr %5\n\t" \
252 "adc %2, %0, %1, lsl %6" \
253 : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
254 : "%r" (x), "r" (y), \
255 "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
261 # define MAD_F_MLX(hi, lo, x, y) \
262 asm ("smull %0, %1, %2, %3" \
263 : "=&r" (lo), "=&r" (hi) \
266 # define MAD_F_MLA(hi, lo, x, y) \
267 asm ("smlal %0, %1, %2, %3" \
268 : "+r" (lo), "+r" (hi) \
271 # define MAD_F_MLN(hi, lo) \
272 asm ("rsbs %0, %2, #0\n\t" \
274 : "=r" (lo), "=r" (hi) \
275 : "0" (lo), "1" (hi) \
278 # define mad_f_scale64(hi, lo) \
279 ({ mad_fixed_t __result; \
280 asm ("movs %0, %1, lsr %3\n\t" \
281 "adc %0, %0, %2, lsl %4" \
283 : "r" (lo), "r" (hi), \
284 "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
289 # define MAD_F_SCALEBITS MAD_F_FRACBITS
291 /* --- MIPS ---------------------------------------------------------------- */
293 # elif defined(FPM_MIPS)
296 typedef unsigned int u64_di_t
__attribute__ ((mode (DI
)));
297 # define MAD_F_MLX(hi, lo, x, y) \
299 u64_di_t __ll = (u64_di_t) (x) * (y); \
305 * This MIPS version is fast and accurate; the disposition of the least
306 * significant bit depends on OPT_ACCURACY via mad_f_scale64().
308 # define MAD_F_MLX(hi, lo, x, y) \
310 : "=l" (lo), "=h" (hi) \
313 # if defined(HAVE_MADD_ASM)
314 # define MAD_F_MLA(hi, lo, x, y) \
316 : "+l" (lo), "+h" (hi) \
318 # elif defined(HAVE_MADD16_ASM)
320 * This loses significant accuracy due to the 16-bit integer limit in the
321 * multiply/accumulate instruction.
323 # define MAD_F_ML0(hi, lo, x, y) \
325 : "=l" (lo), "=h" (hi) \
326 : "%r" ((x) >> 12), "r" ((y) >> 16))
327 # define MAD_F_MLA(hi, lo, x, y) \
328 asm ("madd16 %2,%3" \
329 : "+l" (lo), "+h" (hi) \
330 : "%r" ((x) >> 12), "r" ((y) >> 16))
331 # define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo))
336 # if defined(OPT_SPEED)
337 # define mad_f_scale64(hi, lo) \
338 ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
339 # define MAD_F_SCALEBITS MAD_F_FRACBITS
342 /* --- SPARC --------------------------------------------------------------- */
344 # elif defined(FPM_SPARC)
347 * This SPARC V8 version is fast and accurate; the disposition of the least
348 * significant bit depends on OPT_ACCURACY via mad_f_scale64().
350 # define MAD_F_MLX(hi, lo, x, y) \
351 asm ("smul %2, %3, %0\n\t" \
353 : "=r" (lo), "=r" (hi) \
354 : "%r" (x), "rI" (y))
356 /* --- PowerPC ------------------------------------------------------------- */
358 # elif defined(FPM_PPC)
361 * This PowerPC version is fast and accurate; the disposition of the least
362 * significant bit depends on OPT_ACCURACY via mad_f_scale64().
364 # define MAD_F_MLX(hi, lo, x, y) \
366 asm ("mullw %0,%1,%2" \
368 : "%r" (x), "r" (y)); \
369 asm ("mulhw %0,%1,%2" \
371 : "%r" (x), "r" (y)); \
375 # if defined(OPT_ACCURACY)
377 * This gives best accuracy but is not very fast.
379 # define MAD_F_MLA(hi, lo, x, y) \
380 ({ mad_fixed64hi_t __hi; \
381 mad_fixed64lo_t __lo; \
382 MAD_F_MLX(__hi, __lo, (x), (y)); \
383 asm ("addc %0,%2,%3\n\t" \
385 : "=r" (lo), "=r" (hi) \
386 : "%r" (lo), "r" (__lo), \
387 "%r" (hi), "r" (__hi) \
392 # if defined(OPT_ACCURACY)
394 * This is slower than the truncating version below it.
396 # define mad_f_scale64(hi, lo) \
397 ({ mad_fixed_t __result, __round; \
398 asm ("rotrwi %0,%1,%2" \
400 : "r" (lo), "i" (MAD_F_SCALEBITS)); \
401 asm ("extrwi %0,%1,1,0" \
404 asm ("insrwi %0,%1,%2,0" \
406 : "r" (hi), "i" (MAD_F_SCALEBITS)); \
407 asm ("add %0,%1,%2" \
409 : "%r" (__result), "r" (__round)); \
413 # define mad_f_scale64(hi, lo) \
414 ({ mad_fixed_t __result; \
415 asm ("rotrwi %0,%1,%2" \
417 : "r" (lo), "i" (MAD_F_SCALEBITS)); \
418 asm ("insrwi %0,%1,%2,0" \
420 : "r" (hi), "i" (MAD_F_SCALEBITS)); \
425 # define MAD_F_SCALEBITS MAD_F_FRACBITS
427 # elif defined(FPM_COLDFIRE_EMAC)
429 /* mad_f_mul using the Coldfire MCF5249 EMAC unit. Loses 3 bits of accuracy.
430 Note that we don't define any of the libmad accumulator macros, as
431 any functions that use these should have the relevant sections rewritten
432 in assembler to utilise the EMAC accumulators properly.
433 Assumes the default +/- 3.28 fixed point format
435 #define mad_f_mul(x, y) \
437 mad_fixed64hi_t hi; \
438 asm volatile("mac.l %[a], %[b], %%acc0\n\t" \
439 "movclr.l %%acc0, %[hi]\n\t" \
442 : [a] "r" ((x)), [b] "r" ((y))); \
445 /* Define dummy mad_f_scale64 to prevent libmad from defining MAD_F_SCALEBITS
446 below. Having MAD_F_SCALEBITS defined screws up the PRESHIFT macro in synth.c
448 #define mad_f_scale64(hi, lo) (lo)
450 /* --- Default ------------------------------------------------------------- */
452 # elif defined(FPM_DEFAULT)
455 * This version is the most portable but it loses significant accuracy.
456 * Furthermore, accuracy is biased against the second argument, so care
457 * should be taken when ordering operands.
459 * The scale factors are constant as this is not used with SSO.
461 * Pre-rounding is required to stay within the limits of compliance.
463 # if defined(OPT_SPEED)
464 # define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16))
466 # define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \
467 (((y) + (1L << 15)) >> 16))
470 /* ------------------------------------------------------------------------- */
473 # error "no FPM selected"
476 /* default implementations */
478 # if !defined(mad_f_mul)
479 # define mad_f_mul(x, y) \
480 ({ register mad_fixed64hi_t __hi; \
481 register mad_fixed64lo_t __lo; \
482 MAD_F_MLX(__hi, __lo, (x), (y)); \
483 mad_f_scale64(__hi, __lo); \
487 # if !defined(MAD_F_MLA)
488 # define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y)))
489 # define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y)))
490 # define MAD_F_MLN(hi, lo) ((lo) = -(lo))
491 # define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
494 # if !defined(MAD_F_ML0)
495 # define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y))
498 # if !defined(MAD_F_MLN)
499 # define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi))
502 # if !defined(MAD_F_MLZ)
503 # define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo))
506 # if !defined(mad_f_scale64)
507 # if defined(OPT_ACCURACY)
508 # define mad_f_scale64(hi, lo) \
510 (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \
511 ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
513 # define mad_f_scale64(hi, lo) \
515 (((hi) << (32 - MAD_F_SCALEBITS)) | \
516 ((lo) >> MAD_F_SCALEBITS)))
518 # define MAD_F_SCALEBITS MAD_F_FRACBITS