diff options
Diffstat (limited to 'apps/fracmul.h')
-rw-r--r-- | apps/fracmul.h | 93 |
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 | ||