[opus] [Opus] [Patch]01-Add ARM5E macros

Aurélien Zanelli aurelien.zanelli at parrot.com
Fri May 17 09:25:23 PDT 2013


Hello,

This is a first patch which add macros for ARMv5E.
Also, I copy headers from other files and add company name, tell me if 
I'm wrong.

Also, if you have any question or comment about it, feel free to contact me.

Best regards,
-- 
Aurélien Zanelli
Parrot SA
174, quai de Jemmapes
75010 Paris
France
-------------- next part --------------
diff --git a/celt/fixed_arm5e.h b/celt/fixed_arm5e.h
new file mode 100644
index 0000000..9eb970a
--- /dev/null
+++ b/celt/fixed_arm5e.h
@@ -0,0 +1,99 @@
+/* Copyright (C) 2007-2009 Xiph.Org Foundation
+   Copyright (C) 2003-2008 Jean-Marc Valin
+   Copyright (C) 2007-2008 CSIRO
+   Copyright (C) 2013      Parrot */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef FIXED_ARM5E_H
+#define FIXED_ARM5E_H
+
+/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
+#undef MULT16_32_Q16
+static inline opus_val32 MULT16_32_Q16(opus_val16 a, opus_val32 b)
+{
+  int res;
+  __asm__(
+      "smulwb %0, %1, %2;\n"
+      : "=&r"(res)
+      : "%r"(b),"r"(a)
+      );
+  return res;
+}
+
+
+/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
+#undef MULT16_32_Q15
+static inline opus_val32 MULT16_32_Q15(opus_val16 a, opus_val32 b)
+{
+  int res;
+  __asm__(
+      "smulwb %0, %1, %2;\n"
+      : "=&r"(res)
+      : "%r"(b<<1),"r"(a)
+      );
+  return res;
+}
+
+
+/** 16x32 multiply-add, followed by a 15-bit shift right. Results fits in 32 bits */
+#undef MAC16_32_Q15
+static inline opus_val32 MAC16_32_Q15(opus_val32 c, opus_val16 a, opus_val32 b)
+{
+  int res;
+  __asm__(
+      "smlawb %0, %1, %2, %3;\n"
+      : "=&r"(res)
+      : "%r"(b<<1),"r"(a), "r"(c)
+      );
+  return res;
+}
+
+/** 16x16 multiply-add where the result fits in 32 bits */
+#undef MAC16_16
+static inline opus_val32 MAC16_16(opus_val32 c, opus_val16 a, opus_val16 b)
+{
+  __asm__(
+      "smlabb %0, %1, %2, %0;\n"
+      : "=&r"(c), "=r"(a), "=r"(b)
+      : "0"(c), "1"(a), "2"(b)
+      );
+  return c;
+}
+
+/** 16x16 multiplication where the result fits in 32 bits */
+#undef MULT16_16
+static inline opus_val32 MULT16_16(opus_val16 a, opus_val16 b)
+{
+  int res;
+  __asm__(
+      "smulbb %0, %1, %2;\n"
+      : "=&r"(res)
+      : "r"(a), "r"(b)
+      );
+  return res;
+}
+
+#endif
diff --git a/silk/SigProc_FIX.h b/silk/SigProc_FIX.h
index cf1ab36..bccd73d 100644
--- a/silk/SigProc_FIX.h
+++ b/silk/SigProc_FIX.h
@@ -576,6 +576,10 @@ static inline opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
 #include "MacroCount.h"
 #include "MacroDebug.h"
 
+#ifdef ARM5E_ASM
+#include "SigProc_FIX_arm5e.h"
+#endif
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/silk/SigProc_FIX_arm5e.h b/silk/SigProc_FIX_arm5e.h
new file mode 100644
index 0000000..52032f6
--- /dev/null
+++ b/silk/SigProc_FIX_arm5e.h
@@ -0,0 +1,68 @@
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Copyright (c) 2013       Parrot
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the 
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ?AS IS?
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef SILK_SIGPROC_FIX_ARM5E_H
+#define SILK_SIGPROC_FIX_ARM5E_H
+
+#undef silk_MLA
+static inline opus_int32 silk_MLA(opus_int32 a, opus_int32 b, opus_int32 c)
+{
+  opus_int32 res;
+  __asm__(
+      "mla %0, %1, %2, %3;\n"
+      : "=&r"(res)
+      : "r"(b), "r"(c), "r"(a)
+      );
+  return res;
+}
+
+#undef silk_SMULTT
+static inline opus_int32 silk_SMULTT(opus_int32 a, opus_int32 b)
+{
+  opus_int32 res;
+  __asm__(
+      "smultt %0, %1, %2;\n"
+      : "=&r"(res)
+      : "r"(a), "r"(b)
+      );
+  return res;
+}
+
+#undef silk_SMLATT
+static inline opus_int32 silk_SMLATT(opus_int32 a, opus_int32 b, opus_int32 c)
+{
+  opus_int32 res;
+  __asm__(
+      "smlatt %0, %1, %2, %3;\n"
+      : "=&r"(res)
+      : "r"(b), "r"(c), "r"(a)
+      );
+  return res;
+}
+
+#endif
diff --git a/silk/macros.h b/silk/macros.h
index 31344cf..fd9ad5d 100644
--- a/silk/macros.h
+++ b/silk/macros.h
@@ -32,6 +32,10 @@ POSSIBILITY OF SUCH DAMAGE.
 #include "config.h"
 #endif
 
+#ifdef ARM5E_ASM
+#include "macros_arm5e.h"
+#else /* Generic macro */
+
 /* This is an inline header file for general platform. */
 
 /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
@@ -134,5 +138,7 @@ static inline opus_int32 silk_CLZ32(opus_int32 in32)
     (*((Matrix_base_adr) + ((row)+(M)*(column))))
 #endif
 
+#endif
+
 #endif /* SILK_MACROS_H */
 
diff --git a/silk/macros_arm5e.h b/silk/macros_arm5e.h
new file mode 100644
index 0000000..6f47ec4
--- /dev/null
+++ b/silk/macros_arm5e.h
@@ -0,0 +1,197 @@
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Copyright (c) 2013       Parrot
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the 
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ?AS IS?
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef SILK_MACROS_ARM5E_H
+#define SILK_MACROS_ARM5E_H
+
+/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
+static inline opus_int32 silk_SMULWB(opus_int32 a, opus_int16 b)
+{
+  int res;
+  __asm__(
+      "smulwb %0, %1, %2;\n"
+      : "=&r"(res)
+      : "r"(a), "r"(b)
+      );
+  return res;
+}
+
+/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */
+static inline opus_int32 silk_SMLAWB(opus_int32 a, opus_int32 b, opus_int16 c)
+{
+  int res;
+  __asm__(
+      "smlawb %0, %1, %2, %3;\n"
+      : "=&r"(res)
+      : "r"(b), "r"(c), "r"(a)
+      );
+  return res;
+}
+
+/* (a32 * (b32 >> 16)) >> 16 */
+static inline opus_int32 silk_SMULWT(opus_int32 a, opus_int32 b)
+{
+  int res;
+  __asm__(
+      "smulwt %0, %1, %2;\n"
+      : "=&r"(res)
+      : "r"(a), "r"(b)
+      );
+  return res;
+}
+
+/* a32 + (b32 * (c32 >> 16)) >> 16 */
+static inline opus_int32 silk_SMLAWT(opus_int32 a, opus_int32 b, opus_int32 c)
+{
+  int res;
+  __asm__(
+      "smlawt %0, %1, %2, %3;\n"
+      : "=&r"(res)
+      : "r"(b), "r"(c), "r"(a)
+      );
+  return res;
+}
+
+/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */
+static inline opus_int32 silk_SMULBB(opus_int32 a, opus_int32 b)
+{
+  int res;
+  __asm__(
+      "smulbb %0, %1, %2;\n"
+      : "=&r"(res)
+      : "r"(a), "r"(b)
+      );
+  return res;
+}
+
+/* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */
+static inline opus_int32 silk_SMLABB(opus_int32 a, opus_int32 b, opus_int32 c)
+{
+  int res;
+  __asm__(
+      "smlabb %0, %1, %2, %3;\n"
+      : "=&r"(res)
+      : "r"(b), "r"(c), "r"(a)
+      );
+  return res;
+}
+
+/* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */
+static inline opus_int32 silk_SMULBT(opus_int32 a, opus_int32 b)
+{
+  int res;
+  __asm__(
+      "smulbt %0, %1, %2;\n"
+      : "=&r"(res)
+      : "r"(a), "r"(b)
+      );
+  return res;
+}
+
+/* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */
+static inline opus_int32 silk_SMLABT(opus_int32 a, opus_int32 b, opus_int32 c)
+{
+  int res;
+  __asm__(
+      "smlabt %0, %1, %2, %3;\n"
+      : "=&r"(res)
+      : "r"(b), "r"(c), "r"(a)
+      );
+  return res;
+}
+
+/* a64 + (b32 * c32) */
+#define silk_SMLAL(a64, b32, c32)        (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32))))
+
+/* (a32 * b32) >> 16 */
+#define silk_SMULWW(a32, b32)            silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16))
+
+/* a32 + ((b32 * c32) >> 16) */
+#define silk_SMLAWW(a32, b32, c32)       silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16))
+
+/* add/subtract with output saturated */
+static inline opus_int32 silk_ADD_SAT32(opus_int32 a, opus_int32 b)
+{
+  int res;
+  __asm__(
+      "qadd %0, %1, %2;\n"
+      : "=&r"(res)
+      : "r"(a), "r"(b)
+      );
+  return res;
+}
+
+static inline opus_int32 silk_SUB_SAT32(opus_int32 a, opus_int32 b)
+{
+  int res;
+  __asm__(
+      "qsub %0, %1, %2;\n"
+      : "=&r"(res)
+      : "r"(a), "r"(b)
+      );
+  return res;
+}
+
+static inline opus_int32 silk_CLZ16(opus_int16 in16)
+{
+  opus_int32 res;
+  __asm__(
+      "clz %0, %1;\n"
+      "subs %0, %0, #16;\n"
+      "eormi %0, %0, %0;\n"
+      : "=&r"(res)
+      : "r"(in16)
+      );
+  return res;
+}
+
+static inline opus_int32 silk_CLZ32(opus_int32 in32)
+{
+  opus_int32 res;
+  __asm__(
+      "clz %0, %1;\n"
+      : "=&r"(res)
+      : "r"(in32)
+      );
+  return res;
+}
+
+/* Row based */
+#define matrix_ptr(Matrix_base_adr, row, column, N) \
+    (*((Matrix_base_adr) + ((row)*(N)+(column))))
+#define matrix_adr(Matrix_base_adr, row, column, N) \
+      ((Matrix_base_adr) + ((row)*(N)+(column)))
+
+/* Column based */
+#ifndef matrix_c_ptr
+#   define matrix_c_ptr(Matrix_base_adr, row, column, M) \
+    (*((Matrix_base_adr) + ((row)+(M)*(column))))
+#endif
+
+#endif /* SILK_MACROS_H */
+


More information about the opus mailing list