00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <inttypes.h>
00029
00030 #define PRECISION 16
00031 #define PRECISION64 16
00032
00033 #define fixtof64(x) (float)((float)(x) / (float)(1 << PRECISION64)) //does not work on int64_t!
00034 #define ftofix32(x) ((int32_t)((x) * (float)(1 << PRECISION) + ((x) < 0 ? -0.5 : 0.5)))
00035 #define itofix64(x) (IntTo64(x))
00036 #define itofix32(x) ((x) << PRECISION)
00037 #define fixtoi32(x) ((x) >> PRECISION)
00038 #define fixtoi64(x) (IntFrom64(x))
00039
00040
00041
00042 int64_t IntTo64(int x);
00043 int IntFrom64(int64_t x);
00044 int32_t Fixed32From64(int64_t x);
00045 int64_t Fixed32To64(int32_t x);
00046 int64_t fixmul64byfixed(int64_t x, int32_t y);
00047 int32_t fixdiv32(int32_t x, int32_t y);
00048 int64_t fixdiv64(int64_t x, int64_t y);
00049 int32_t fixsqrt32(int32_t x);
00050 long fsincos(unsigned long phase, int32_t *cos);
00051
00052 #ifdef __arm__
00053
00054
00055
00056 #define fixmul32(x, y) \
00057 ({ int32_t __hi; \
00058 uint32_t __lo; \
00059 int32_t __result; \
00060 asm ("smull %0, %1, %3, %4\n\t" \
00061 "movs %0, %0, lsr %5\n\t" \
00062 "adc %2, %0, %1, lsl %6" \
00063 : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
00064 : "%r" (x), "r" (y), \
00065 "M" (PRECISION), "M" (32 - PRECISION) \
00066 : "cc"); \
00067 __result; \
00068 })
00069
00070 #define fixmul32b(x, y) \
00071 ({ int32_t __hi; \
00072 uint32_t __lo; \
00073 int32_t __result; \
00074 asm ("smull %0, %1, %3, %4\n\t" \
00075 "movs %2, %1, lsl #1" \
00076 : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
00077 : "%r" (x), "r" (y) \
00078 : "cc"); \
00079 __result; \
00080 })
00081
00082 #elif defined(CPU_COLDFIRE)
00083
00084 static inline int32_t fixmul32(int32_t x, int32_t y)
00085 {
00086 #if PRECISION != 16
00087 #warning Coldfire fixmul32() only works for PRECISION == 16
00088 #endif
00089 int32_t t1;
00090 asm (
00091 "mac.l %[x], %[y], %%acc0 \n"
00092 "mulu.l %[y], %[x] \n"
00093 "movclr.l %%acc0, %[t1] \n"
00094 "lsr.l #1, %[t1] \n"
00095 "move.w %[t1], %[x] \n"
00096 "swap %[x] \n"
00097 : [t1] "=&d" (t1), [x] "+d" (x)
00098 : [y] "d" (y)
00099 );
00100 return x;
00101 }
00102
00103 static inline int32_t fixmul32b(int32_t x, int32_t y)
00104 {
00105 asm (
00106 "mac.l %[x], %[y], %%acc0 \n"
00107 "movclr.l %%acc0, %[x] \n"
00108 : [x] "+d" (x)
00109 : [y] "d" (y)
00110 );
00111 return x;
00112 }
00113
00114 #else
00115
00116 static inline int32_t fixmul32(int32_t x, int32_t y)
00117 {
00118 int64_t temp;
00119 temp = x;
00120 temp *= y;
00121
00122 temp >>= PRECISION;
00123
00124 return (int32_t)temp;
00125 }
00126
00127 static inline int32_t fixmul32b(int32_t x, int32_t y)
00128 {
00129 int64_t temp;
00130
00131 temp = x;
00132 temp *= y;
00133
00134 temp >>= 31;
00135
00136 return (int32_t)temp;
00137 }
00138
00139 #endif
00140
00141 #ifdef __arm__
00142 static inline
00143 void CMUL(int32_t *x, int32_t *y,
00144 int32_t a, int32_t b,
00145 int32_t t, int32_t v)
00146 {
00147
00148
00149 int x1, y1, l;
00150 asm(
00151 "smull %[l], %[y1], %[b], %[t] \n"
00152 "smlal %[l], %[y1], %[a], %[v] \n"
00153 "rsb %[b], %[b], #0 \n"
00154 "smull %[l], %[x1], %[a], %[t] \n"
00155 "smlal %[l], %[x1], %[b], %[v] \n"
00156 : [l] "=&r" (l), [x1]"=&r" (x1), [y1]"=&r" (y1), [b] "+r" (b)
00157 : [a] "r" (a), [t] "r" (t), [v] "r" (v)
00158 : "cc"
00159 );
00160 *x = x1 << 1;
00161 *y = y1 << 1;
00162 }
00163 #elif defined CPU_COLDFIRE
00164 static inline
00165 void CMUL(int32_t *x, int32_t *y,
00166 int32_t a, int32_t b,
00167 int32_t t, int32_t v)
00168 {
00169 asm volatile ("mac.l %[a], %[t], %%acc0;"
00170 "msac.l %[b], %[v], %%acc0;"
00171 "mac.l %[b], %[t], %%acc1;"
00172 "mac.l %[a], %[v], %%acc1;"
00173 "movclr.l %%acc0, %[a];"
00174 "move.l %[a], (%[x]);"
00175 "movclr.l %%acc1, %[a];"
00176 "move.l %[a], (%[y]);"
00177 : [a] "+&r" (a)
00178 : [x] "a" (x), [y] "a" (y),
00179 [b] "r" (b), [t] "r" (t), [v] "r" (v)
00180 : "cc", "memory");
00181 }
00182 #else
00183 static inline
00184 void CMUL(int32_t *pre,
00185 int32_t *pim,
00186 int32_t are,
00187 int32_t aim,
00188 int32_t bre,
00189 int32_t bim)
00190 {
00191
00192 int32_t _aref = are;
00193 int32_t _aimf = aim;
00194 int32_t _bref = bre;
00195 int32_t _bimf = bim;
00196 int32_t _r1 = fixmul32b(_bref, _aref);
00197 int32_t _r2 = fixmul32b(_bimf, _aimf);
00198 int32_t _r3 = fixmul32b(_bref, _aimf);
00199 int32_t _r4 = fixmul32b(_bimf, _aref);
00200 *pre = _r1 - _r2;
00201 *pim = _r3 + _r4;
00202
00203 }
00204 #endif