diff options
Diffstat (limited to 'lib/rbcodec/codecs/libatrac/fixp_math.h')
-rw-r--r-- | lib/rbcodec/codecs/libatrac/fixp_math.h | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libatrac/fixp_math.h b/lib/rbcodec/codecs/libatrac/fixp_math.h new file mode 100644 index 0000000000..014c5aa559 --- /dev/null +++ b/lib/rbcodec/codecs/libatrac/fixp_math.h | |||
@@ -0,0 +1,111 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2009 Mohamed Tarek | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include <stdlib.h> | ||
22 | #include <inttypes.h> | ||
23 | |||
24 | /* Macros for converting between various fixed-point representations and floating point. */ | ||
25 | #define ONE_16 (1L << 16) | ||
26 | #define fixtof64(x) (float)((float)(x) / (float)(1 << 16)) //does not work on int64_t! | ||
27 | #define ftofix32(x) ((int32_t)((x) * (float)(1 << 16) + ((x) < 0 ? -0.5 : 0.5))) | ||
28 | #define ftofix31(x) ((int32_t)((x) * (float)(1 << 31) + ((x) < 0 ? -0.5 : 0.5))) | ||
29 | #define fix31tof64(x) (float)((float)(x) / (float)(1 << 31)) | ||
30 | |||
31 | /* Fixed point math routines for use in atrac3.c */ | ||
32 | |||
33 | #if defined(CPU_ARM) | ||
34 | /* Calculates: result = (X*Y)>>16 */ | ||
35 | #define fixmul16(X,Y) \ | ||
36 | ({ \ | ||
37 | int32_t lo; \ | ||
38 | int32_t hi; \ | ||
39 | asm volatile ( \ | ||
40 | "smull %[lo], %[hi], %[x], %[y] \n\t" /* multiply */ \ | ||
41 | "mov %[lo], %[lo], lsr #16 \n\t" /* lo >>= 16 */ \ | ||
42 | "orr %[lo], %[lo], %[hi], lsl #16" /* lo |= (hi << 16) */ \ | ||
43 | : [lo]"=&r"(lo), [hi]"=&r"(hi) \ | ||
44 | : [x]"r"(X), [y]"r"(Y)); \ | ||
45 | lo; \ | ||
46 | }) | ||
47 | |||
48 | /* Calculates: result = (X*Y)>>31 */ | ||
49 | /* Use scratch register r12 */ | ||
50 | #define fixmul31(X,Y) \ | ||
51 | ({ \ | ||
52 | int32_t lo; \ | ||
53 | int32_t hi; \ | ||
54 | asm volatile ( \ | ||
55 | "smull %[lo], %[hi], %[x], %[y] \n\t" /* multiply */ \ | ||
56 | "mov %[lo], %[lo], lsr #31 \n\t" /* lo >>= 31 */ \ | ||
57 | "orr %[lo], %[lo], %[hi], lsl #1" /* lo |= (hi << 1) */ \ | ||
58 | : [lo]"=&r"(lo), [hi]"=&r"(hi) \ | ||
59 | : [x]"r"(X), [y]"r"(Y)); \ | ||
60 | lo; \ | ||
61 | }) | ||
62 | #elif defined(CPU_COLDFIRE) | ||
63 | /* Calculates: result = (X*Y)>>16 */ | ||
64 | #define fixmul16(X,Y) \ | ||
65 | ({ \ | ||
66 | int32_t t, x = (X); \ | ||
67 | asm volatile ( \ | ||
68 | "mac.l %[x],%[y],%%acc0\n\t" /* multiply */ \ | ||
69 | "mulu.l %[y],%[x] \n\t" /* get lower half, avoid emac stall */ \ | ||
70 | "movclr.l %%acc0,%[t] \n\t" /* get higher half */ \ | ||
71 | "lsr.l #1,%[t] \n\t" /* hi >>= 1 to compensate emac shift */ \ | ||
72 | "move.w %[t],%[x] \n\t" /* combine halfwords */\ | ||
73 | "swap %[x] \n\t" \ | ||
74 | : [t]"=&d"(t), [x] "+d" (x) \ | ||
75 | : [y] "d" ((Y))); \ | ||
76 | x; \ | ||
77 | }) | ||
78 | |||
79 | #define fixmul31(X,Y) \ | ||
80 | ({ \ | ||
81 | int32_t t; \ | ||
82 | asm volatile ( \ | ||
83 | "mac.l %[x], %[y], %%acc0\n\t" /* multiply */ \ | ||
84 | "movclr.l %%acc0, %[t]\n\t" /* get higher half as result */ \ | ||
85 | : [t] "=d" (t) \ | ||
86 | : [x] "r" ((X)), [y] "r" ((Y))); \ | ||
87 | t; \ | ||
88 | }) | ||
89 | #else | ||
90 | static inline int32_t fixmul16(int32_t x, int32_t y) | ||
91 | { | ||
92 | int64_t temp; | ||
93 | temp = x; | ||
94 | temp *= y; | ||
95 | |||
96 | temp >>= 16; | ||
97 | |||
98 | return (int32_t)temp; | ||
99 | } | ||
100 | |||
101 | static inline int32_t fixmul31(int32_t x, int32_t y) | ||
102 | { | ||
103 | int64_t temp; | ||
104 | temp = x; | ||
105 | temp *= y; | ||
106 | |||
107 | temp >>= 31; //16+31-16 = 31 bits | ||
108 | |||
109 | return (int32_t)temp; | ||
110 | } | ||
111 | #endif | ||