A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 102 lines 2.9 kB view raw
1#ifndef _FRACMUL_H 2#define _FRACMUL_H 3 4#include <stdint.h> 5#include "gcc_extensions.h" 6 7/** FRACTIONAL MULTIPLICATION 8 * Multiply two fixed point numbers with 31 fractional bits: 9 * FRACMUL(x, y) 10 * 11 * Multiply two fixed point numbers with 31 fractional bits, 12 * then shift left by z bits: 13 * FRACMUL_SHL(x, y, z) 14 * NOTE: z must be in the range 1-8 on Coldfire targets. 15 */ 16 17 18/* A bunch of fixed point assembler helper macros */ 19#if defined(CPU_COLDFIRE) 20/* These macros use the Coldfire EMAC extension and need the MACSR flags set 21 * to fractional mode with no rounding. 22 */ 23 24/* Multiply two S.31 fractional integers and return the sign bit and the 25 * 31 most significant bits of the result. 26 */ 27static inline int32_t FRACMUL(int32_t x, int32_t y) 28{ 29 int32_t t; 30 asm ("mac.l %[a], %[b], %%acc0\n\t" 31 "movclr.l %%acc0, %[t]\n\t" 32 : [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); 33 return t; 34} 35 36/* Multiply two S.31 fractional integers, and return the 32 most significant 37 * bits after a shift left by the constant z. NOTE: Only works for shifts of 38 * 1 to 8 on Coldfire! 39 */ 40static FORCE_INLINE int32_t FRACMUL_SHL(int32_t x, int32_t y, int z) 41{ 42 int32_t t, t2; 43 asm ("mac.l %[a], %[b], %%acc0\n\t" 44 "move.l %[d], %[t]\n\t" 45 "move.l %%accext01, %[t2]\n\t" 46 "and.l %[mask], %[t2]\n\t" 47 "lsr.l %[t], %[t2]\n\t" 48 "movclr.l %%acc0, %[t]\n\t" 49 "asl.l %[c], %[t]\n\t" 50 "or.l %[t2], %[t]\n\t" 51 : [t] "=&d" (t), [t2] "=&d" (t2) 52 : [a] "r" (x), [b] "r" (y), [mask] "d" (0xff), 53 [c] "id" ((z)), [d] "id" (8 - (z))); 54 return t; 55} 56 57#elif defined(CPU_ARM) 58 59/* Multiply two S.31 fractional integers and return the sign bit and the 60 * 31 most significant bits of the result. 61 */ 62static inline int32_t FRACMUL(int32_t x, int32_t y) 63{ 64 int32_t t, t2; 65 asm ("smull %[t], %[t2], %[a], %[b]\n\t" 66 "mov %[t2], %[t2], asl #1\n\t" 67 "orr %[t], %[t2], %[t], lsr #31\n\t" 68 : [t] "=&r" (t), [t2] "=&r" (t2) 69 : [a] "r" (x), [b] "r" (y)); 70 return t; 71} 72 73/* Multiply two S.31 fractional integers, and return the 32 most significant 74 * bits after a shift left by the constant z. 75 */ 76static FORCE_INLINE int32_t FRACMUL_SHL(int32_t x, int32_t y, int z) 77{ 78 int32_t t, t2; 79 asm ("smull %[t], %[t2], %[a], %[b]\n\t" 80 "mov %[t2], %[t2], asl %[c]\n\t" 81 "orr %[t], %[t2], %[t], lsr %[d]\n\t" 82 : [t] "=&r" (t), [t2] "=&r" (t2) 83 : [a] "r" (x), [b] "r" (y), 84 [c] "Mr" ((z) + 1), [d] "Mr" (31 - (z))); 85 return t; 86} 87 88#else 89 90static inline int32_t FRACMUL(int32_t x, int32_t y) 91{ 92 return (int32_t) (((int64_t)x * y) >> 31); 93} 94 95static inline int32_t FRACMUL_SHL(int32_t x, int32_t y, int z) 96{ 97 return (int32_t) (((int64_t)x * y) >> (31 - z)); 98} 99 100#endif 101 102#endif