diff libgsmefr/basic_op.h @ 349:ed8762eea8a1

libgsmefr: use some inline functions from PacketVideo
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 22 Apr 2024 08:14:20 +0000
parents 1c514150c033
children 9b05bbc23b8a
line wrap: on
line diff
--- a/libgsmefr/basic_op.h	Mon Apr 22 00:05:01 2024 +0000
+++ b/libgsmefr/basic_op.h	Mon Apr 22 08:14:20 2024 +0000
@@ -4,7 +4,9 @@
  * The original version contained only function declarations,
  * resulting in a function call for every elementary operation;
  * the present version implements most of these operations as inline
- * functions.
+ * functions.  (Further update: for extra speed-up, the some inline
+ * function implementations have been lifted from PacketVideo AMR
+ * version, aka libopencore-amrnb.)
  *
  * Elimination of Overflow flag: examination of EFR code reveals that
  * both Carry and Overflow flags are accessed outside of basicop2.c
@@ -159,24 +161,9 @@
 
 static inline Word16 abs_s (Word16 var1)
 {
-    Word16 var_out;
-
-    if (unlikely(var1 == (Word16) 0X8000))
-    {
-        var_out = MAX_16;
-    }
-    else
-    {
-        if (var1 < 0)
-        {
-            var_out = -var1;
-        }
-        else
-        {
-            var_out = var1;
-        }
-    }
-    return (var_out);
+    Word16 y = var1 - (var1 < 0);
+    y = y ^ (y >> 15);
+    return (y);
 }
 
 /*___________________________________________________________________________
@@ -216,29 +203,23 @@
 
 static inline Word16 shl (Word16 var1, Word16 var2)
 {
-    Word32 result;
+    Word16 var_out;
 
-    if (var2 < 0) {
+    if (unlikely(var2 < 0)) {
         var2 = -var2;
-        if (unlikely(var2 >= 15))
-            return (var1 < 0) ? -1 : 0;
-        else
-            return var1 >> var2;
+        if (unlikely(var2 > 15))
+            var2 = 15;
+        var_out = var1 >> var2;
     } else {
-        result = (Word32) var1 << var2;
-        if (var1 > 0) {
-            if (unlikely((var2 >= 15) || (result & 0xFFFF8000)))
-                return MAX_16;
-            else
-                return (Word16) result;
-        } else if (var1 < 0) {
-            if (unlikely((var2 >= 16) || ((result & 0xFFFF8000) != 0xFFFF8000)))
-                return MIN_16;
-            else
-                return (Word16) result;
-        } else
-            return 0;
+        if (unlikely(var2 > 15))
+            var2 = 15;
+        var_out = var1 << var2;
+        if (unlikely(var_out >> var2 != var1))
+        {
+            var_out = (var1 >> 15) ^ MAX_16;
+        }
     }
+    return var_out;
 }
 
 /*___________________________________________________________________________
@@ -278,29 +259,23 @@
 
 static inline Word16 shr (Word16 var1, Word16 var2)
 {
-    Word32 result;
+    Word16 var_out;
 
-    if (var2 < 0) {
+    if (unlikely(var2 < 0)) {
         var2 = -var2;
-        result = (Word32) var1 << var2;
-        if (var1 > 0) {
-            if (unlikely((var2 >= 15) || (result & 0xFFFF8000)))
-                return MAX_16;
-            else
-                return (Word16) result;
-        } else if (var1 < 0) {
-            if (unlikely((var2 >= 16) || ((result & 0xFFFF8000) != 0xFFFF8000)))
-                return MIN_16;
-            else
-                return (Word16) result;
-        } else
-            return 0;
+        if (unlikely(var2 > 15))
+            var2 = 15;
+        var_out = var1 << var2;
+        if (unlikely(var_out >> var2 != var1))
+        {
+            var_out = (var1 >> 15) ^ MAX_16;
+        }
     } else {
-        if (unlikely(var2 >= 15))
-            return (var1 < 0) ? -1 : 0;
-        else
-            return var1 >> var2;
+        if (unlikely(var2 > 15))
+            var2 = 15;
+        var_out = var1 >> var2;
     }
+    return var_out;
 }
 
 /*___________________________________________________________________________
@@ -340,10 +315,20 @@
 
 static inline Word16 mult (Word16 var1, Word16 var2)
 {
-    if (unlikely(var1 == MIN_16 && var2 == MIN_16))
-        return MAX_16;
-    else
-        return ((Word32) var1 * var2) >> 15;
+    register Word32 product;
+
+    product = ((Word32) var1 * var2) >> 15;
+
+    /* Saturate result (if necessary). */
+    /* var1 * var2 >0x00007fff is the only case */
+    /* that saturation occurs. */
+
+    if (unlikely(product > 0x00007fff))
+        product = (Word32) MAX_16;
+
+    /* Return the product as a 16 bit value by type casting Word32 to Word16 */
+
+    return ((Word16) product);
 }
 
 /*___________________________________________________________________________
@@ -629,11 +614,21 @@
 
 static inline Word32 L_mult (Word16 var1, Word16 var2)
 {
-    if (unlikely(var1 == MIN_16 && var2 == MIN_16)) {
+    register Word32 L_product;
+
+    L_product = (Word32) var1 * var2;
+
+    if (likely(L_product != (Word32) 0x40000000))
+    {
+        L_product <<= 1;          /* Multiply by 2 */
+    }
+    else
+    {
         Overflow = 1;
-        return MAX_32;
-    } else
-        return ((Word32) var1 * var2) << 1;
+        L_product = MAX_32;
+    }
+
+    return (L_product);
 }
 
 /*___________________________________________________________________________
@@ -804,13 +799,14 @@
 {
     Word32 L_var_out;
 
-    if (var2 < 0) {
+    if (unlikely(var2 < 0)) {
         var2 = -var2;
-        if (unlikely(var2 >= 31))
-            L_var_out = (L_var1 < 0) ? -1 : 0;
-        else
-            L_var_out = L_var1 >> var2;
+        if (unlikely(var2 > 31))
+            var2 = 31;
+        L_var_out = L_var1 >> var2;
     } else {
+        if (unlikely(var2 > 31))
+            var2 = 31;
         L_var_out = L_var1 << var2;
         if (unlikely(L_var_out >> var2 != L_var1))
             L_var_out = (L_var1 >> 31) ^ MAX_32;
@@ -856,16 +852,17 @@
 {
     Word32 L_var_out;
 
-    if (var2 < 0) {
+    if (unlikely(var2 < 0)) {
         var2 = -var2;
+        if (unlikely(var2 > 31))
+            var2 = 31;
         L_var_out = L_var1 << var2;
         if (unlikely(L_var_out >> var2 != L_var1))
             L_var_out = (L_var1 >> 31) ^ MAX_32;
     } else {
-        if (unlikely(var2 >= 31))
-            L_var_out = (L_var1 < 0) ? -1 : 0;
-        else
-            L_var_out = L_var1 >> var2;
+        if (unlikely(var2 > 31))
+            var2 = 31;
+        L_var_out = L_var1 >> var2;
     }
     return (L_var_out);
 }