summaryrefslogtreecommitdiff
path: root/apps/fracmul.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/fracmul.h')
-rw-r--r--apps/fracmul.h93
1 files changed, 93 insertions, 0 deletions
diff --git a/apps/fracmul.h b/apps/fracmul.h
new file mode 100644
index 0000000000..5cc83af624
--- /dev/null
+++ b/apps/fracmul.h
@@ -0,0 +1,93 @@
1#ifndef _FRACMUL_H
2#define _FRACMUL_H
3
4/** FRACTIONAL MULTIPLICATION - TAKEN FROM apps/dsp.h
5 * Multiply two fixed point numbers with 31 fractional bits:
6 * FRACMUL(x, y)
7 *
8 * Multiply two fixed point numbers with 31 fractional bits,
9 * then shift left by z bits:
10 * FRACMUL_SHL(x, y, z)
11 * NOTE: z must be in the range 1-8 on Coldfire targets.
12 */
13
14
15/* A bunch of fixed point assembler helper macros */
16#if defined(CPU_COLDFIRE)
17/* These macros use the Coldfire EMAC extension and need the MACSR flags set
18 * to fractional mode with no rounding.
19 */
20
21/* Multiply two S.31 fractional integers and return the sign bit and the
22 * 31 most significant bits of the result.
23 */
24#define FRACMUL(x, y) \
25({ \
26 long t; \
27 asm ("mac.l %[a], %[b], %%acc0\n\t" \
28 "movclr.l %%acc0, %[t]\n\t" \
29 : [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); \
30 t; \
31})
32
33/* Multiply two S.31 fractional integers, and return the 32 most significant
34 * bits after a shift left by the constant z. NOTE: Only works for shifts of
35 * 1 to 8 on Coldfire!
36 */
37#define FRACMUL_SHL(x, y, z) \
38({ \
39 long t, t2; \
40 asm ("mac.l %[a], %[b], %%acc0\n\t" \
41 "moveq.l %[d], %[t]\n\t" \
42 "move.l %%accext01, %[t2]\n\t" \
43 "and.l %[mask], %[t2]\n\t" \
44 "lsr.l %[t], %[t2]\n\t" \
45 "movclr.l %%acc0, %[t]\n\t" \
46 "asl.l %[c], %[t]\n\t" \
47 "or.l %[t2], %[t]\n\t" \
48 : [t] "=&d" (t), [t2] "=&d" (t2) \
49 : [a] "r" (x), [b] "r" (y), [mask] "d" (0xff), \
50 [c] "i" ((z)), [d] "i" (8 - (z))); \
51 t; \
52})
53
54#elif defined(CPU_ARM)
55
56/* Multiply two S.31 fractional integers and return the sign bit and the
57 * 31 most significant bits of the result.
58 */
59#define FRACMUL(x, y) \
60({ \
61 long t, t2; \
62 asm ("smull %[t], %[t2], %[a], %[b]\n\t" \
63 "mov %[t2], %[t2], asl #1\n\t" \
64 "orr %[t], %[t2], %[t], lsr #31\n\t" \
65 : [t] "=&r" (t), [t2] "=&r" (t2) \
66 : [a] "r" (x), [b] "r" (y)); \
67 t; \
68})
69
70/* Multiply two S.31 fractional integers, and return the 32 most significant
71 * bits after a shift left by the constant z.
72 */
73#define FRACMUL_SHL(x, y, z) \
74({ \
75 long t, t2; \
76 asm ("smull %[t], %[t2], %[a], %[b]\n\t" \
77 "mov %[t2], %[t2], asl %[c]\n\t" \
78 "orr %[t], %[t2], %[t], lsr %[d]\n\t" \
79 : [t] "=&r" (t), [t2] "=&r" (t2) \
80 : [a] "r" (x), [b] "r" (y), \
81 [c] "M" ((z) + 1), [d] "M" (31 - (z))); \
82 t; \
83})
84
85#else
86
87#define FRACMUL(x, y) (long) (((((long long) (x)) * ((long long) (y))) >> 31))
88#define FRACMUL_SHL(x, y, z) \
89((long)(((((long long) (x)) * ((long long) (y))) >> (31 - (z)))))
90
91#endif
92
93#endif