FS#10512: Bookmarking does not behave correctly (fixes r22192)
[kugel-rb/myfork.git] / apps / fracmul.h
blob5cc83af624e44c660d9359aa584a17579b6e040e
1 #ifndef _FRACMUL_H
2 #define _FRACMUL_H
4 /** FRACTIONAL MULTIPLICATION - TAKEN FROM apps/dsp.h
5 * Multiply two fixed point numbers with 31 fractional bits:
6 * FRACMUL(x, y)
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.
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.
21 /* Multiply two S.31 fractional integers and return the sign bit and the
22 * 31 most significant bits of the result.
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; \
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!
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; \
54 #elif defined(CPU_ARM)
56 /* Multiply two S.31 fractional integers and return the sign bit and the
57 * 31 most significant bits of the result.
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; \
70 /* Multiply two S.31 fractional integers, and return the 32 most significant
71 * bits after a shift left by the constant z.
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; \
85 #else
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)))))
91 #endif
93 #endif