ref: 247aa220f71b2c830ce5aa3d0a14588c250b360f
parent: 260679b16ef5aacdfe494de9cd2ef4327fed23ca
author: Siarhei Volkau <lis8215@gmail.com>
date: Sun Aug 24 06:45:26 EDT 2025
MIPS: silk: optimize silk_SMULWB for MIPS32+ MIPS32 has 32x32=>64bit multiplication, although shifting 64-bit result isn't trivial so its worth to shift right 64-bit value to 32 it means just drop LSB register of the result. Since second argument of silk_SMULWB is 16-bit wide we can shift it left by 16 before multiplication to apply technique above to the result. Signed-off-by: Siarhei Volkau <lis8215@gmail.com> Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
--- a/silk/SigProc_FIX.h
+++ b/silk/SigProc_FIX.h
@@ -600,11 +600,13 @@
#define RAND_INCREMENT 907633515
#define silk_RAND(seed) (silk_MLA_ovflw((RAND_INCREMENT), (seed), (RAND_MULTIPLIER)))
-/* Add some multiplication functions that can be easily mapped to ARM. */
+/* Add some multiplication functions that can be easily mapped to ARM/MIPS32. */
/* silk_SMMUL: Signed top word multiply.
ARMv6 2 instruction cycles.
- ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)*/
+ ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)
+ MIPS32 2 instructions mul+mfhi
+ MIPS32r6 1 instruction muh */
/*#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT(silk_SMLAL(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)), 16)*/
/* the following seems faster on x86 */
#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32)
--- a/silk/macros.h
+++ b/silk/macros.h
@@ -104,7 +104,7 @@
(( (a) & ((b)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a)-(b)) : \
((((a)^0x80000000) & (b) & 0x80000000) ? silk_int32_MAX : (a)-(b)) )
-#if defined(FIXED_POINT) && defined(__mips_dsp) && __mips == 32
+#if defined(FIXED_POINT) && defined(__mips)
#include "mips/macros_mipsr1.h"
#endif
--- a/silk/mips/macros_mipsr1.h
+++ b/silk/mips/macros_mipsr1.h
@@ -34,6 +34,8 @@
return x ? __builtin_clz(x) : 32;
}
+#if defined (__mips_dsp) && __mips == 32
+
#undef silk_SMULWB
static inline int silk_SMULWB(int a, int b)
{
@@ -91,5 +93,18 @@
re32 = mips_clz(in32);
return re32;
}
+
+
+#elif defined (__mips_isa_rev) && __mips == 32
+
+#undef silk_SMULWB
+static inline int silk_SMULWB(int a, int b)
+{
+ long long ac = (long long)a * (int)(b << 16);
+
+ return ac >> 32;
+}
+
+#endif
#endif /* SILK_MACROS_MIPSR1_H__ */
--
⑨