From 5fd9471c156ca054fbe5fc5d2b002f94645f473c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20Wallm=C3=A9nius?= Date: Tue, 24 May 2011 10:44:12 +0000 Subject: FS#12120. Convert FRACMUL macros into inline functions and fix typecasting for 64 bit platforms so that sims produce the same results as targets. Tweak the cf inline asm to not require an immediate value but add a FORCE_INLINE attribute to one of the cf functions to make sure it gets inlined as that saves both codesize and cycles. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29921 a1c6a512-1295-4272-9138-f99709370657 --- apps/fracmul.h | 105 +++++++++++++++++++++----------------- firmware/include/gcc_extensions.h | 7 +++ 2 files changed, 64 insertions(+), 48 deletions(-) diff --git a/apps/fracmul.h b/apps/fracmul.h index 5cc83af..5dbe4f9 100644 --- a/apps/fracmul.h +++ b/apps/fracmul.h @@ -1,6 +1,9 @@ #ifndef _FRACMUL_H #define _FRACMUL_H +#include +#include "gcc_extensions.h" + /** FRACTIONAL MULTIPLICATION - TAKEN FROM apps/dsp.h * Multiply two fixed point numbers with 31 fractional bits: * FRACMUL(x, y) @@ -21,72 +24,78 @@ /* Multiply two S.31 fractional integers and return the sign bit and the * 31 most significant bits of the result. */ -#define FRACMUL(x, y) \ -({ \ - long t; \ - asm ("mac.l %[a], %[b], %%acc0\n\t" \ - "movclr.l %%acc0, %[t]\n\t" \ - : [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); \ - t; \ -}) +static inline int32_t FRACMUL(int32_t x, int32_t y) +{ + int32_t t; + asm ("mac.l %[a], %[b], %%acc0\n\t" + "movclr.l %%acc0, %[t]\n\t" + : [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); + return t; +} /* Multiply two S.31 fractional integers, and return the 32 most significant * bits after a shift left by the constant z. NOTE: Only works for shifts of * 1 to 8 on Coldfire! */ -#define FRACMUL_SHL(x, y, z) \ -({ \ - long t, t2; \ - asm ("mac.l %[a], %[b], %%acc0\n\t" \ - "moveq.l %[d], %[t]\n\t" \ - "move.l %%accext01, %[t2]\n\t" \ - "and.l %[mask], %[t2]\n\t" \ - "lsr.l %[t], %[t2]\n\t" \ - "movclr.l %%acc0, %[t]\n\t" \ - "asl.l %[c], %[t]\n\t" \ - "or.l %[t2], %[t]\n\t" \ - : [t] "=&d" (t), [t2] "=&d" (t2) \ - : [a] "r" (x), [b] "r" (y), [mask] "d" (0xff), \ - [c] "i" ((z)), [d] "i" (8 - (z))); \ - t; \ -}) +static inline FORCE_INLINE int32_t FRACMUL_SHL(int32_t x, int32_t y, int z) +{ + int32_t t, t2; + asm ("mac.l %[a], %[b], %%acc0\n\t" + "move.l %[d], %[t]\n\t" + "move.l %%accext01, %[t2]\n\t" + "and.l %[mask], %[t2]\n\t" + "lsr.l %[t], %[t2]\n\t" + "movclr.l %%acc0, %[t]\n\t" + "asl.l %[c], %[t]\n\t" + "or.l %[t2], %[t]\n\t" + : [t] "=&d" (t), [t2] "=&d" (t2) + : [a] "r" (x), [b] "r" (y), [mask] "d" (0xff), + [c] "id" ((z)), [d] "id" (8 - (z))); + return t; +} #elif defined(CPU_ARM) /* Multiply two S.31 fractional integers and return the sign bit and the * 31 most significant bits of the result. */ -#define FRACMUL(x, y) \ -({ \ - long t, t2; \ - asm ("smull %[t], %[t2], %[a], %[b]\n\t" \ - "mov %[t2], %[t2], asl #1\n\t" \ - "orr %[t], %[t2], %[t], lsr #31\n\t" \ - : [t] "=&r" (t), [t2] "=&r" (t2) \ - : [a] "r" (x), [b] "r" (y)); \ - t; \ -}) +static inline int32_t FRACMUL(int32_t x, int32_t y) +{ + int32_t t, t2; + asm ("smull %[t], %[t2], %[a], %[b]\n\t" + "mov %[t2], %[t2], asl #1\n\t" + "orr %[t], %[t2], %[t], lsr #31\n\t" + : [t] "=&r" (t), [t2] "=&r" (t2) + : [a] "r" (x), [b] "r" (y)); + return t; +} /* Multiply two S.31 fractional integers, and return the 32 most significant * bits after a shift left by the constant z. */ -#define FRACMUL_SHL(x, y, z) \ -({ \ - long t, t2; \ - asm ("smull %[t], %[t2], %[a], %[b]\n\t" \ - "mov %[t2], %[t2], asl %[c]\n\t" \ - "orr %[t], %[t2], %[t], lsr %[d]\n\t" \ - : [t] "=&r" (t), [t2] "=&r" (t2) \ - : [a] "r" (x), [b] "r" (y), \ - [c] "M" ((z) + 1), [d] "M" (31 - (z))); \ - t; \ -}) +static inline int32_t FRACMUL_SHL(int32_t x, int32_t y, int z) +{ + int32_t t, t2; \ + asm ("smull %[t], %[t2], %[a], %[b]\n\t" + "mov %[t2], %[t2], asl %[c]\n\t" + "orr %[t], %[t2], %[t], lsr %[d]\n\t" + : [t] "=&r" (t), [t2] "=&r" (t2) + : [a] "r" (x), [b] "r" (y), + [c] "M" ((z) + 1), [d] "M" (31 - (z))); + return t; +} #else -#define FRACMUL(x, y) (long) (((((long long) (x)) * ((long long) (y))) >> 31)) -#define FRACMUL_SHL(x, y, z) \ -((long)(((((long long) (x)) * ((long long) (y))) >> (31 - (z))))) +static inline int32_t FRACMUL(int32_t x, int32_t y) +{ + return (int32_t) (((int64_t)x * y) >> 31); +} + +static inline int32_t FRACMUL_SHL(int32_t x, int32_t y, int z) +{ + return (int32_t) (((int64_t)x * y) >> (31 - z)); +} #endif diff --git a/firmware/include/gcc_extensions.h b/firmware/include/gcc_extensions.h index f7580f6..7109eda 100644 --- a/firmware/include/gcc_extensions.h +++ b/firmware/include/gcc_extensions.h @@ -50,4 +50,11 @@ #define NORETURN_ATTR #endif + +#if defined(__GNUC__) +#define FORCE_INLINE inline __attribute__((always_inline)) +#else +#define FORCE_INLINE inline +#endif + #endif /* _GCC_EXTENSIONS_H_ */ -- cgit v1.1