shithub: opus

Download patch

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__ */
--