summaryrefslogtreecommitdiff
path: root/DSP/Source/BasicMathFunctions
diff options
context:
space:
mode:
authorrihab kouki <rihab.kouki@st.com>2020-07-28 11:24:49 +0100
committerrihab kouki <rihab.kouki@st.com>2020-07-28 11:24:49 +0100
commit96d6da4e252b06dcfdc041e7df23e86161c33007 (patch)
treea262f59bb1db7ec7819acae435f5049cbe5e2354 /DSP/Source/BasicMathFunctions
parent9f95ff5b6ba01db09552b84a0ab79607060a2666 (diff)
downloadst-cmsis-core-lowfat-master.tar.gz
st-cmsis-core-lowfat-master.tar.bz2
st-cmsis-core-lowfat-master.zip
Official ARM version: v5.6.0HEADmaster
Diffstat (limited to 'DSP/Source/BasicMathFunctions')
-rw-r--r--DSP/Source/BasicMathFunctions/BasicMathFunctions.c63
-rw-r--r--DSP/Source/BasicMathFunctions/CMakeLists.txt16
-rw-r--r--DSP/Source/BasicMathFunctions/arm_abs_f32.c143
-rw-r--r--DSP/Source/BasicMathFunctions/arm_abs_q15.c149
-rw-r--r--DSP/Source/BasicMathFunctions/arm_abs_q31.c112
-rw-r--r--DSP/Source/BasicMathFunctions/arm_abs_q7.c139
-rw-r--r--DSP/Source/BasicMathFunctions/arm_add_f32.c139
-rw-r--r--DSP/Source/BasicMathFunctions/arm_add_q15.c116
-rw-r--r--DSP/Source/BasicMathFunctions/arm_add_q31.c108
-rw-r--r--DSP/Source/BasicMathFunctions/arm_add_q7.c97
-rw-r--r--DSP/Source/BasicMathFunctions/arm_dot_prod_f32.c130
-rw-r--r--DSP/Source/BasicMathFunctions/arm_dot_prod_q15.c112
-rw-r--r--DSP/Source/BasicMathFunctions/arm_dot_prod_q31.c110
-rw-r--r--DSP/Source/BasicMathFunctions/arm_dot_prod_q7.c118
-rw-r--r--DSP/Source/BasicMathFunctions/arm_mult_f32.c160
-rw-r--r--DSP/Source/BasicMathFunctions/arm_mult_q15.c121
-rw-r--r--DSP/Source/BasicMathFunctions/arm_mult_q31.c133
-rw-r--r--DSP/Source/BasicMathFunctions/arm_mult_q7.c86
-rw-r--r--DSP/Source/BasicMathFunctions/arm_negate_f32.c137
-rw-r--r--DSP/Source/BasicMathFunctions/arm_negate_q15.c109
-rw-r--r--DSP/Source/BasicMathFunctions/arm_negate_q31.c113
-rw-r--r--DSP/Source/BasicMathFunctions/arm_negate_q7.c101
-rw-r--r--DSP/Source/BasicMathFunctions/arm_offset_f32.c151
-rw-r--r--DSP/Source/BasicMathFunctions/arm_offset_q15.c105
-rw-r--r--DSP/Source/BasicMathFunctions/arm_offset_q31.c118
-rw-r--r--DSP/Source/BasicMathFunctions/arm_offset_q7.c99
-rw-r--r--DSP/Source/BasicMathFunctions/arm_scale_f32.c166
-rw-r--r--DSP/Source/BasicMathFunctions/arm_scale_q15.c124
-rw-r--r--DSP/Source/BasicMathFunctions/arm_scale_q31.c264
-rw-r--r--DSP/Source/BasicMathFunctions/arm_scale_q7.c110
-rw-r--r--DSP/Source/BasicMathFunctions/arm_shift_q15.c213
-rw-r--r--DSP/Source/BasicMathFunctions/arm_shift_q31.c214
-rw-r--r--DSP/Source/BasicMathFunctions/arm_shift_q7.c193
-rw-r--r--DSP/Source/BasicMathFunctions/arm_sub_f32.c148
-rw-r--r--DSP/Source/BasicMathFunctions/arm_sub_q15.c110
-rw-r--r--DSP/Source/BasicMathFunctions/arm_sub_q31.c106
-rw-r--r--DSP/Source/BasicMathFunctions/arm_sub_q7.c94
37 files changed, 2282 insertions, 2445 deletions
diff --git a/DSP/Source/BasicMathFunctions/BasicMathFunctions.c b/DSP/Source/BasicMathFunctions/BasicMathFunctions.c
new file mode 100644
index 0000000..b444c11
--- /dev/null
+++ b/DSP/Source/BasicMathFunctions/BasicMathFunctions.c
@@ -0,0 +1,63 @@
+/* ----------------------------------------------------------------------
+ * Project: CMSIS DSP Library
+ * Title: BasicMathFunctions.c
+ * Description: Combination of all basic math function source files.
+ *
+ * $Date: 18. March 2019
+ * $Revision: V1.0.0
+ *
+ * Target Processor: Cortex-M cores
+ * -------------------------------------------------------------------- */
+/*
+ * Copyright (C) 2019 ARM Limited or its affiliates. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "arm_abs_f32.c"
+#include "arm_abs_q15.c"
+#include "arm_abs_q31.c"
+#include "arm_abs_q7.c"
+#include "arm_add_f32.c"
+#include "arm_add_q15.c"
+#include "arm_add_q31.c"
+#include "arm_add_q7.c"
+#include "arm_dot_prod_f32.c"
+#include "arm_dot_prod_q15.c"
+#include "arm_dot_prod_q31.c"
+#include "arm_dot_prod_q7.c"
+#include "arm_mult_f32.c"
+#include "arm_mult_q15.c"
+#include "arm_mult_q31.c"
+#include "arm_mult_q7.c"
+#include "arm_negate_f32.c"
+#include "arm_negate_q15.c"
+#include "arm_negate_q31.c"
+#include "arm_negate_q7.c"
+#include "arm_offset_f32.c"
+#include "arm_offset_q15.c"
+#include "arm_offset_q31.c"
+#include "arm_offset_q7.c"
+#include "arm_scale_f32.c"
+#include "arm_scale_q15.c"
+#include "arm_scale_q31.c"
+#include "arm_scale_q7.c"
+#include "arm_shift_q15.c"
+#include "arm_shift_q31.c"
+#include "arm_shift_q7.c"
+#include "arm_sub_f32.c"
+#include "arm_sub_q15.c"
+#include "arm_sub_q31.c"
+#include "arm_sub_q7.c"
diff --git a/DSP/Source/BasicMathFunctions/CMakeLists.txt b/DSP/Source/BasicMathFunctions/CMakeLists.txt
new file mode 100644
index 0000000..717669f
--- /dev/null
+++ b/DSP/Source/BasicMathFunctions/CMakeLists.txt
@@ -0,0 +1,16 @@
+cmake_minimum_required (VERSION 3.6)
+
+project(CMSISDSPBasicMath)
+
+
+file(GLOB SRC "./*_*.c")
+
+add_library(CMSISDSPBasicMath STATIC ${SRC})
+
+configdsp(CMSISDSPBasicMath ..)
+
+### Includes
+target_include_directories(CMSISDSPBasicMath PUBLIC "${DSP}/../../Include")
+
+
+
diff --git a/DSP/Source/BasicMathFunctions/arm_abs_f32.c b/DSP/Source/BasicMathFunctions/arm_abs_f32.c
index f88ef95..a7d2624 100644
--- a/DSP/Source/BasicMathFunctions/arm_abs_f32.c
+++ b/DSP/Source/BasicMathFunctions/arm_abs_f32.c
@@ -3,13 +3,13 @@
* Title: arm_abs_f32.c
* Description: Floating-point vector absolute value
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -30,124 +30,117 @@
#include <math.h>
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @defgroup BasicAbs Vector Absolute Value
- *
- * Computes the absolute value of a vector on an element-by-element basis.
- *
- * <pre>
- * pDst[n] = abs(pSrc[n]), 0 <= n < blockSize.
- * </pre>
- *
- * The functions support in-place computation allowing the source and
- * destination pointers to reference the same memory buffer.
- * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
+ @defgroup BasicAbs Vector Absolute Value
+
+ Computes the absolute value of a vector on an element-by-element basis.
+
+ <pre>
+ pDst[n] = abs(pSrc[n]), 0 <= n < blockSize.
+ </pre>
+
+ The functions support in-place computation allowing the source and
+ destination pointers to reference the same memory buffer.
+ There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
- * @addtogroup BasicAbs
- * @{
+ @addtogroup BasicAbs
+ @{
*/
/**
- * @brief Floating-point vector absolute value.
- * @param[in] *pSrc points to the input buffer
- * @param[out] *pDst points to the output buffer
- * @param[in] blockSize number of samples in each vector
- * @return none.
+ @brief Floating-point vector absolute value.
+ @param[in] pSrc points to the input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
*/
void arm_abs_f32(
- float32_t * pSrc,
- float32_t * pDst,
- uint32_t blockSize)
+ const float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t in1, in2, in3, in4; /* temporary variables */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2U;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while (blkCnt > 0U)
- {
- /* C = |A| */
- /* Calculate absolute and then store the results in the destination buffer. */
- /* read sample from source */
- in1 = *pSrc;
- in2 = *(pSrc + 1);
- in3 = *(pSrc + 2);
+#if defined(ARM_MATH_NEON)
+ float32x4_t vec1;
+ float32x4_t res;
- /* find absolute value */
- in1 = fabsf(in1);
+ /* Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
- /* read sample from source */
- in4 = *(pSrc + 3);
+ while (blkCnt > 0U)
+ {
+ /* C = |A| */
- /* find absolute value */
- in2 = fabsf(in2);
+ /* Calculate absolute values and then store the results in the destination buffer. */
+ vec1 = vld1q_f32(pSrc);
+ res = vabsq_f32(vec1);
+ vst1q_f32(pDst, res);
- /* read sample from source */
- *pDst = in1;
+ /* Increment pointers */
+ pSrc += 4;
+ pDst += 4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
- /* find absolute value */
- in3 = fabsf(in3);
+ /* Tail */
+ blkCnt = blockSize & 0x3;
- /* find absolute value */
- in4 = fabsf(in4);
+#else
+#if defined (ARM_MATH_LOOPUNROLL)
- /* store result to destination */
- *(pDst + 1) = in2;
+ /* Loop unrolling: Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
- /* store result to destination */
- *(pDst + 2) = in3;
+ while (blkCnt > 0U)
+ {
+ /* C = |A| */
- /* store result to destination */
- *(pDst + 3) = in4;
+ /* Calculate absolute and store result in destination buffer. */
+ *pDst++ = fabsf(*pSrc++);
+ *pDst++ = fabsf(*pSrc++);
- /* Update source pointer to process next sampels */
- pSrc += 4U;
+ *pDst++ = fabsf(*pSrc++);
- /* Update destination pointer to process next sampels */
- pDst += 4U;
+ *pDst++ = fabsf(*pSrc++);
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+#endif /* #if defined(ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = |A| */
- /* Calculate absolute and then store the results in the destination buffer. */
+
+ /* Calculate absolute and store result in destination buffer. */
*pDst++ = fabsf(*pSrc++);
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of BasicAbs group
+ @} end of BasicAbs group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_abs_q15.c b/DSP/Source/BasicMathFunctions/arm_abs_q15.c
index ec47fff..eb944ce 100644
--- a/DSP/Source/BasicMathFunctions/arm_abs_q15.c
+++ b/DSP/Source/BasicMathFunctions/arm_abs_q15.c
@@ -3,13 +3,13 @@
* Title: arm_abs_q15.c
* Description: Q15 vector absolute value
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,139 +29,104 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicAbs
- * @{
+ @addtogroup BasicAbs
+ @{
*/
/**
- * @brief Q15 vector absolute value.
- * @param[in] *pSrc points to the input buffer
- * @param[out] *pDst points to the output buffer
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * The Q15 value -1 (0x8000) will be saturated to the maximum allowable positive value 0x7FFF.
+ @brief Q15 vector absolute value.
+ @param[in] pSrc points to the input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ The Q15 value -1 (0x8000) will be saturated to the maximum allowable positive value 0x7FFF.
*/
void arm_abs_q15(
- q15_t * pSrc,
- q15_t * pDst,
- uint32_t blockSize)
+ const q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
- __SIMD32_TYPE *simd;
+ uint32_t blkCnt; /* Loop counter */
+ q15_t in; /* Temporary input variable */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
+#if defined (ARM_MATH_LOOPUNROLL)
- q15_t in1; /* Input value1 */
- q15_t in2; /* Input value2 */
-
-
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- simd = __SIMD32_CONST(pDst);
while (blkCnt > 0U)
{
/* C = |A| */
- /* Read two inputs */
- in1 = *pSrc++;
- in2 = *pSrc++;
-
-
- /* Store the Absolute result in the destination buffer by packing the two values, in a single cycle */
-#ifndef ARM_MATH_BIG_ENDIAN
- *simd++ =
- __PKHBT(((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)),
- ((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)), 16);
+ /* Calculate absolute of input (if -1 then saturated to 0x7fff) and store result in destination buffer. */
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in);
#else
+ *pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
+#endif
-
- *simd++ =
- __PKHBT(((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)),
- ((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)), 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- in1 = *pSrc++;
- in2 = *pSrc++;
-
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *simd++ =
- __PKHBT(((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)),
- ((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)), 16);
-
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in);
#else
+ *pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
+#endif
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
+#endif
- *simd++ =
- __PKHBT(((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)),
- ((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)), 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- pDst = (q15_t *)simd;
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
- while (blkCnt > 0U)
- {
- /* C = |A| */
- /* Read the input */
- in1 = *pSrc++;
-
- /* Calculate absolute value of input and then store the result in the destination buffer. */
- *pDst++ = (in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
#else
- /* Run the below code for Cortex-M0 */
-
- q15_t in; /* Temporary input variable */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = |A| */
- /* Read the input */
- in = *pSrc++;
- /* Calculate absolute value of input and then store the result in the destination buffer. */
+ /* Calculate absolute of input (if -1 then saturated to 0x7fff) and store result in destination buffer. */
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in);
+#else
*pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
}
/**
- * @} end of BasicAbs group
+ @} end of BasicAbs group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_abs_q31.c b/DSP/Source/BasicMathFunctions/arm_abs_q31.c
index 2733f51..bf7608b 100644
--- a/DSP/Source/BasicMathFunctions/arm_abs_q31.c
+++ b/DSP/Source/BasicMathFunctions/arm_abs_q31.c
@@ -3,13 +3,13 @@
* Title: arm_abs_q31.c
* Description: Q31 vector absolute value
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,90 +29,104 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicAbs
- * @{
+ @addtogroup BasicAbs
+ @{
*/
-
/**
- * @brief Q31 vector absolute value.
- * @param[in] *pSrc points to the input buffer
- * @param[out] *pDst points to the output buffer
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * The Q31 value -1 (0x80000000) will be saturated to the maximum allowable positive value 0x7FFFFFFF.
+ @brief Q31 vector absolute value.
+ @param[in] pSrc points to the input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ The Q31 value -1 (0x80000000) will be saturated to the maximum allowable positive value 0x7FFFFFFF.
*/
void arm_abs_q31(
- q31_t * pSrc,
- q31_t * pDst,
- uint32_t blockSize)
+ const q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
- q31_t in; /* Input value */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+ q31_t in; /* Temporary variable */
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1, in2, in3, in4;
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = |A| */
- /* Calculate absolute of input (if -1 then saturated to 0x7fffffff) and then store the results in the destination buffer. */
- in1 = *pSrc++;
- in2 = *pSrc++;
- in3 = *pSrc++;
- in4 = *pSrc++;
-
- *pDst++ = (in1 > 0) ? in1 : (q31_t)__QSUB(0, in1);
- *pDst++ = (in2 > 0) ? in2 : (q31_t)__QSUB(0, in2);
- *pDst++ = (in3 > 0) ? in3 : (q31_t)__QSUB(0, in3);
- *pDst++ = (in4 > 0) ? in4 : (q31_t)__QSUB(0, in4);
-
- /* Decrement the loop counter */
+
+ /* Calculate absolute of input (if -1 then saturated to 0x7fffffff) and store result in destination buffer. */
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
+#endif
+
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
+#endif
+
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
+#endif
+
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = |A| */
- /* Calculate absolute value of the input (if -1 then saturated to 0x7fffffff) and then store the results in the destination buffer. */
+
+ /* Calculate absolute of input (if -1 then saturated to 0x7fffffff) and store result in destination buffer. */
in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in);
+#else
*pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
}
/**
- * @} end of BasicAbs group
+ @} end of BasicAbs group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_abs_q7.c b/DSP/Source/BasicMathFunctions/arm_abs_q7.c
index d0acbfc..a6c4a6c 100644
--- a/DSP/Source/BasicMathFunctions/arm_abs_q7.c
+++ b/DSP/Source/BasicMathFunctions/arm_abs_q7.c
@@ -3,13 +3,13 @@
* Title: arm_abs_q7.c
* Description: Q7 vector absolute value
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,117 +29,106 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicAbs
- * @{
+ @addtogroup BasicAbs
+ @{
*/
/**
- * @brief Q7 vector absolute value.
- * @param[in] *pSrc points to the input buffer
- * @param[out] *pDst points to the output buffer
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * \par Conditions for optimum performance
- * Input and output buffers should be aligned by 32-bit
- *
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * The Q7 value -1 (0x80) will be saturated to the maximum allowable positive value 0x7F.
+ @brief Q7 vector absolute value.
+ @param[in] pSrc points to the input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Conditions for optimum performance
+ Input and output buffers should be aligned by 32-bit
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ The Q7 value -1 (0x80) will be saturated to the maximum allowable positive value 0x7F.
*/
void arm_abs_q7(
- q7_t * pSrc,
- q7_t * pDst,
- uint32_t blockSize)
+ const q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
- q7_t in; /* Input value1 */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+ q7_t in; /* Temporary input variable */
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1, in2, in3, in4; /* temporary input variables */
- q31_t out1, out2, out3, out4; /* temporary output variables */
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = |A| */
- /* Read inputs */
- in1 = (q31_t) * pSrc;
- in2 = (q31_t) * (pSrc + 1);
- in3 = (q31_t) * (pSrc + 2);
-
- /* find absolute value */
- out1 = (in1 > 0) ? in1 : (q31_t)__QSUB8(0, in1);
-
- /* read input */
- in4 = (q31_t) * (pSrc + 3);
-
- /* find absolute value */
- out2 = (in2 > 0) ? in2 : (q31_t)__QSUB8(0, in2);
- /* store result to destination */
- *pDst = (q7_t) out1;
-
- /* find absolute value */
- out3 = (in3 > 0) ? in3 : (q31_t)__QSUB8(0, in3);
-
- /* find absolute value */
- out4 = (in4 > 0) ? in4 : (q31_t)__QSUB8(0, in4);
-
- /* store result to destination */
- *(pDst + 1) = (q7_t) out2;
+ /* Calculate absolute of input (if -1 then saturated to 0x7f) and store result in destination buffer. */
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q7_t)__QSUB(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in);
+#endif
- /* store result to destination */
- *(pDst + 2) = (q7_t) out3;
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q7_t)__QSUB(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in);
+#endif
- /* store result to destination */
- *(pDst + 3) = (q7_t) out4;
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q7_t)__QSUB(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in);
+#endif
- /* update pointers to process next samples */
- pSrc += 4U;
- pDst += 4U;
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q7_t)__QSUB(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
+
#else
- /* Run the below code for Cortex-M0 */
+ /* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #define ARM_MATH_CM0_FAMILY */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = |A| */
- /* Read the input */
- in = *pSrc++;
- /* Store the Absolute result in the destination buffer */
- *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? 0x7f : -in);
+ /* Calculate absolute of input (if -1 then saturated to 0x7f) and store result in destination buffer. */
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (in > 0) ? in : (q7_t) __QSUB(0, in);
+#else
+ *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of BasicAbs group
+ @} end of BasicAbs group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_add_f32.c b/DSP/Source/BasicMathFunctions/arm_add_f32.c
index 78feb64..1c66a24 100644
--- a/DSP/Source/BasicMathFunctions/arm_add_f32.c
+++ b/DSP/Source/BasicMathFunctions/arm_add_f32.c
@@ -3,13 +3,13 @@
* Title: arm_add_f32.c
* Description: Floating-point vector addition
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,110 +29,117 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @defgroup BasicAdd Vector Addition
- *
- * Element-by-element addition of two vectors.
- *
- * <pre>
- * pDst[n] = pSrcA[n] + pSrcB[n], 0 <= n < blockSize.
- * </pre>
- *
- * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
+ @defgroup BasicAdd Vector Addition
+
+ Element-by-element addition of two vectors.
+
+ <pre>
+ pDst[n] = pSrcA[n] + pSrcB[n], 0 <= n < blockSize.
+ </pre>
+
+ There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
- * @addtogroup BasicAdd
- * @{
+ @addtogroup BasicAdd
+ @{
*/
/**
- * @brief Floating-point vector addition.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
+ @brief Floating-point vector addition.
+ @param[in] pSrcA points to first input vector
+ @param[in] pSrcB points to second input vector
+ @param[out] pDst points to output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
*/
void arm_add_f32(
- float32_t * pSrcA,
- float32_t * pSrcB,
- float32_t * pDst,
- uint32_t blockSize)
+ const float32_t * pSrcA,
+ const float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+
+#if defined(ARM_MATH_NEON)
+ float32x4_t vec1;
+ float32x4_t vec2;
+ float32x4_t res;
+
+ /* Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
+
+ while (blkCnt > 0U)
+ {
+ /* C = A + B */
+
+ /* Add and then store the results in the destination buffer. */
+ vec1 = vld1q_f32(pSrcA);
+ vec2 = vld1q_f32(pSrcB);
+ res = vaddq_f32(vec1, vec2);
+ vst1q_f32(pDst, res);
+
+ /* Increment pointers */
+ pSrcA += 4;
+ pSrcB += 4;
+ pDst += 4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Tail */
+ blkCnt = blockSize & 0x3;
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t inA1, inA2, inA3, inA4; /* temporary input variabels */
- float32_t inB1, inB2, inB3, inB4; /* temporary input variables */
+#else
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A + B */
- /* Add and then store the results in the destination buffer. */
-
- /* read four inputs from sourceA and four inputs from sourceB */
- inA1 = *pSrcA;
- inB1 = *pSrcB;
- inA2 = *(pSrcA + 1);
- inB2 = *(pSrcB + 1);
- inA3 = *(pSrcA + 2);
- inB3 = *(pSrcB + 2);
- inA4 = *(pSrcA + 3);
- inB4 = *(pSrcB + 3);
-
- /* C = A + B */
- /* add and store result to destination */
- *pDst = inA1 + inB1;
- *(pDst + 1) = inA2 + inB2;
- *(pDst + 2) = inA3 + inB3;
- *(pDst + 3) = inA4 + inB4;
-
- /* update pointers to process next samples */
- pSrcA += 4U;
- pSrcB += 4U;
- pDst += 4U;
+ /* Add and store result in destination buffer. */
+ *pDst++ = (*pSrcA++) + (*pSrcB++);
+ *pDst++ = (*pSrcA++) + (*pSrcB++);
+ *pDst++ = (*pSrcA++) + (*pSrcB++);
+ *pDst++ = (*pSrcA++) + (*pSrcB++);
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+#endif /* #if defined(ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = A + B */
- /* Add and then store the results in the destination buffer. */
+
+ /* Add and store result in destination buffer. */
*pDst++ = (*pSrcA++) + (*pSrcB++);
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of BasicAdd group
+ @} end of BasicAdd group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_add_q15.c b/DSP/Source/BasicMathFunctions/arm_add_q15.c
index 80a523f..bc62937 100644
--- a/DSP/Source/BasicMathFunctions/arm_add_q15.c
+++ b/DSP/Source/BasicMathFunctions/arm_add_q15.c
@@ -3,13 +3,13 @@
* Title: arm_add_q15.c
* Description: Q15 vector addition
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,100 +29,98 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicAdd
- * @{
+ @addtogroup BasicAdd
+ @{
*/
/**
- * @brief Q15 vector addition.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
+ @brief Q15 vector addition.
+ @param[in] pSrcA points to the first input vector
+ @param[in] pSrcB points to the second input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
*/
void arm_add_q15(
- q15_t * pSrcA,
- q15_t * pSrcB,
- q15_t * pDst,
- uint32_t blockSize)
+ const q15_t * pSrcA,
+ const q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
+ uint32_t blkCnt; /* Loop counter */
-#if defined (ARM_MATH_DSP)
+#if defined (ARM_MATH_LOOPUNROLL)
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t inA1, inA2, inB1, inB2;
+#if defined (ARM_MATH_DSP)
+ q31_t inA1, inA2;
+ q31_t inB1, inB2;
+#endif
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A + B */
- /* Add and then store the results in the destination buffer. */
- inA1 = *__SIMD32(pSrcA)++;
- inA2 = *__SIMD32(pSrcA)++;
- inB1 = *__SIMD32(pSrcB)++;
- inB2 = *__SIMD32(pSrcB)++;
- *__SIMD32(pDst)++ = __QADD16(inA1, inB1);
- *__SIMD32(pDst)++ = __QADD16(inA2, inB2);
+#if defined (ARM_MATH_DSP)
+ /* read 2 times 2 samples at a time from sourceA */
+ inA1 = read_q15x2_ia ((q15_t **) &pSrcA);
+ inA2 = read_q15x2_ia ((q15_t **) &pSrcA);
+ /* read 2 times 2 samples at a time from sourceB */
+ inB1 = read_q15x2_ia ((q15_t **) &pSrcB);
+ inB2 = read_q15x2_ia ((q15_t **) &pSrcB);
+
+ /* Add and store 2 times 2 samples at a time */
+ write_q15x2_ia (&pDst, __QADD16(inA1, inB1));
+ write_q15x2_ia (&pDst, __QADD16(inA2, inB2));
+#else
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16);
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16);
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16);
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
- while (blkCnt > 0U)
- {
- /* C = A + B */
- /* Add and then store the results in the destination buffer. */
- *pDst++ = (q15_t) __QADD16(*pSrcA++, *pSrcB++);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
#else
- /* Run the below code for Cortex-M0 */
-
-
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A + B */
- /* Add and then store the results in the destination buffer. */
- *pDst++ = (q15_t) __SSAT(((q31_t) * pSrcA++ + *pSrcB++), 16);
- /* Decrement the loop counter */
+ /* Add and store result in destination buffer. */
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (q15_t) __QADD16(*pSrcA++, *pSrcB++);
+#else
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16);
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
-
}
/**
- * @} end of BasicAdd group
+ @} end of BasicAdd group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_add_q31.c b/DSP/Source/BasicMathFunctions/arm_add_q31.c
index c008bcc..3c1cbc2 100644
--- a/DSP/Source/BasicMathFunctions/arm_add_q31.c
+++ b/DSP/Source/BasicMathFunctions/arm_add_q31.c
@@ -3,13 +3,13 @@
* Title: arm_add_q31.c
* Description: Q31 vector addition
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,108 +29,80 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicAdd
- * @{
+ @addtogroup BasicAdd
+ @{
*/
-
/**
- * @brief Q31 vector addition.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] will be saturated.
+ @brief Q31 vector addition.
+ @param[in] pSrcA points to the first input vector
+ @param[in] pSrcB points to the second input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
*/
void arm_add_q31(
- q31_t * pSrcA,
- q31_t * pSrcB,
- q31_t * pDst,
- uint32_t blockSize)
+ const q31_t * pSrcA,
+ const q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t inA1, inA2, inA3, inA4;
- q31_t inB1, inB2, inB3, inB4;
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A + B */
- /* Add and then store the results in the destination buffer. */
- inA1 = *pSrcA++;
- inA2 = *pSrcA++;
- inB1 = *pSrcB++;
- inB2 = *pSrcB++;
-
- inA3 = *pSrcA++;
- inA4 = *pSrcA++;
- inB3 = *pSrcB++;
- inB4 = *pSrcB++;
-
- *pDst++ = __QADD(inA1, inB1);
- *pDst++ = __QADD(inA2, inB2);
- *pDst++ = __QADD(inA3, inB3);
- *pDst++ = __QADD(inA4, inB4);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4U;
+ /* Add and store result in destination buffer. */
+ *pDst++ = __QADD(*pSrcA++, *pSrcB++);
- while (blkCnt > 0U)
- {
- /* C = A + B */
- /* Add and then store the results in the destination buffer. */
*pDst++ = __QADD(*pSrcA++, *pSrcB++);
- /* Decrement the loop counter */
- blkCnt--;
- }
+ *pDst++ = __QADD(*pSrcA++, *pSrcB++);
-#else
+ *pDst++ = __QADD(*pSrcA++, *pSrcB++);
- /* Run the below code for Cortex-M0 */
+ /* Decrement loop counter */
+ blkCnt--;
+ }
+ /* Loop unrolling: Compute remaining outputs */
+ blkCnt = blockSize % 0x4U;
+#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A + B */
- /* Add and then store the results in the destination buffer. */
- *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrcA++ + *pSrcB++);
- /* Decrement the loop counter */
+ /* Add and store result in destination buffer. */
+ *pDst++ = __QADD(*pSrcA++, *pSrcB++);
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
}
/**
- * @} end of BasicAdd group
+ @} end of BasicAdd group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_add_q7.c b/DSP/Source/BasicMathFunctions/arm_add_q7.c
index ab4e785..f9c4a95 100644
--- a/DSP/Source/BasicMathFunctions/arm_add_q7.c
+++ b/DSP/Source/BasicMathFunctions/arm_add_q7.c
@@ -3,13 +3,13 @@
* Title: arm_add_q7.c
* Description: Q7 vector addition
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,94 +29,81 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicAdd
- * @{
+ @addtogroup BasicAdd
+ @{
*/
/**
- * @brief Q7 vector addition.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
+ @brief Q7 vector addition.
+ @param[in] pSrcA points to the first input vector
+ @param[in] pSrcB points to the second input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
*/
void arm_add_q7(
- q7_t * pSrcA,
- q7_t * pSrcB,
- q7_t * pDst,
- uint32_t blockSize)
+ const q7_t * pSrcA,
+ const q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
+#if defined (ARM_MATH_LOOPUNROLL)
-
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A + B */
- /* Add and then store the results in the destination buffer. */
- *__SIMD32(pDst)++ = __QADD8(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++);
- /* Decrement the loop counter */
+#if defined (ARM_MATH_DSP)
+ /* Add and store result in destination buffer (4 samples at a time). */
+ write_q7x4_ia (&pDst, __QADD8 (read_q7x4_ia ((q7_t **) &pSrcA), read_q7x4_ia ((q7_t **) &pSrcB)));
+#else
+ *pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8);
+ *pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8);
+ *pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8);
+ *pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8);
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
- while (blkCnt > 0U)
- {
- /* C = A + B */
- /* Add and then store the results in the destination buffer. */
- *pDst++ = (q7_t) __SSAT(*pSrcA++ + *pSrcB++, 8);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
#else
- /* Run the below code for Cortex-M0 */
-
-
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A + B */
- /* Add and then store the results in the destination buffer. */
- *pDst++ = (q7_t) __SSAT((q15_t) * pSrcA++ + *pSrcB++, 8);
- /* Decrement the loop counter */
+ /* Add and store result in destination buffer. */
+ *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ + *pSrcB++, 8);
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
-
}
/**
- * @} end of BasicAdd group
+ @} end of BasicAdd group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_dot_prod_f32.c b/DSP/Source/BasicMathFunctions/arm_dot_prod_f32.c
index 0cd0afc..3eee3b9 100644
--- a/DSP/Source/BasicMathFunctions/arm_dot_prod_f32.c
+++ b/DSP/Source/BasicMathFunctions/arm_dot_prod_f32.c
@@ -3,13 +3,13 @@
* Title: arm_dot_prod_f32.c
* Description: Floating-point dot product
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,95 +29,135 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @defgroup dot_prod Vector Dot Product
- *
- * Computes the dot product of two vectors.
- * The vectors are multiplied element-by-element and then summed.
- *
- * <pre>
- * sum = pSrcA[0]*pSrcB[0] + pSrcA[1]*pSrcB[1] + ... + pSrcA[blockSize-1]*pSrcB[blockSize-1]
- * </pre>
- *
- * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
+ @defgroup BasicDotProd Vector Dot Product
+
+ Computes the dot product of two vectors.
+ The vectors are multiplied element-by-element and then summed.
+
+ <pre>
+ sum = pSrcA[0]*pSrcB[0] + pSrcA[1]*pSrcB[1] + ... + pSrcA[blockSize-1]*pSrcB[blockSize-1]
+ </pre>
+
+ There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
- * @addtogroup dot_prod
- * @{
+ @addtogroup BasicDotProd
+ @{
*/
/**
- * @brief Dot product of floating-point vectors.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[in] blockSize number of samples in each vector
- * @param[out] *result output result returned here
- * @return none.
+ @brief Dot product of floating-point vectors.
+ @param[in] pSrcA points to the first input vector.
+ @param[in] pSrcB points to the second input vector.
+ @param[in] blockSize number of samples in each vector.
+ @param[out] result output result returned here.
+ @return none
*/
-
void arm_dot_prod_f32(
- float32_t * pSrcA,
- float32_t * pSrcB,
- uint32_t blockSize,
- float32_t * result)
+ const float32_t * pSrcA,
+ const float32_t * pSrcB,
+ uint32_t blockSize,
+ float32_t * result)
{
- float32_t sum = 0.0f; /* Temporary result storage */
- uint32_t blkCnt; /* loop counter */
+ uint32_t blkCnt; /* Loop counter */
+ float32_t sum = 0.0f; /* Temporary return variable */
+
+#if defined(ARM_MATH_NEON)
+ float32x4_t vec1;
+ float32x4_t vec2;
+ float32x4_t res;
+ float32x4_t accum = vdupq_n_f32(0);
+
+ /* Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
+
+ vec1 = vld1q_f32(pSrcA);
+ vec2 = vld1q_f32(pSrcB);
+
+ while (blkCnt > 0U)
+ {
+ /* C = A[0]*B[0] + A[1]*B[1] + A[2]*B[2] + ... + A[blockSize-1]*B[blockSize-1] */
+ /* Calculate dot product and then store the result in a temporary buffer. */
+
+ accum = vmlaq_f32(accum, vec1, vec2);
+
+ /* Increment pointers */
+ pSrcA += 4;
+ pSrcB += 4;
+
+ vec1 = vld1q_f32(pSrcA);
+ vec2 = vld1q_f32(pSrcB);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+#if __aarch64__
+ sum = vpadds_f32(vpadd_f32(vget_low_f32(accum), vget_high_f32(accum)));
+#else
+ sum = (vpadd_f32(vget_low_f32(accum), vget_high_f32(accum)))[0] + (vpadd_f32(vget_low_f32(accum), vget_high_f32(accum)))[1];
+#endif
+ /* Tail */
+ blkCnt = blockSize & 0x3;
-#if defined (ARM_MATH_DSP)
+#else
+#if defined (ARM_MATH_LOOPUNROLL)
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
- /* Calculate dot product and then store the result in a temporary buffer */
+
+ /* Calculate dot product and store result in a temporary buffer. */
sum += (*pSrcA++) * (*pSrcB++);
+
sum += (*pSrcA++) * (*pSrcB++);
+
sum += (*pSrcA++) * (*pSrcB++);
+
sum += (*pSrcA++) * (*pSrcB++);
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
-
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+#endif /* #if defined(ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
- /* Calculate dot product and then store the result in a temporary buffer. */
+
+ /* Calculate dot product and store result in a temporary buffer. */
sum += (*pSrcA++) * (*pSrcB++);
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* Store the result back in the destination buffer */
+
+ /* Store result in destination buffer */
*result = sum;
}
/**
- * @} end of dot_prod group
+ @} end of BasicDotProd group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_dot_prod_q15.c b/DSP/Source/BasicMathFunctions/arm_dot_prod_q15.c
index dec4ec5..e303b09 100644
--- a/DSP/Source/BasicMathFunctions/arm_dot_prod_q15.c
+++ b/DSP/Source/BasicMathFunctions/arm_dot_prod_q15.c
@@ -3,13 +3,13 @@
* Title: arm_dot_prod_q15.c
* Description: Q15 dot product
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,100 +29,92 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup dot_prod
- * @{
+ @addtogroup BasicDotProd
+ @{
*/
/**
- * @brief Dot product of Q15 vectors.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[in] blockSize number of samples in each vector
- * @param[out] *result output result returned here
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The intermediate multiplications are in 1.15 x 1.15 = 2.30 format and these
- * results are added to a 64-bit accumulator in 34.30 format.
- * Nonsaturating additions are used and given that there are 33 guard bits in the accumulator
- * there is no risk of overflow.
- * The return result is in 34.30 format.
+ @brief Dot product of Q15 vectors.
+ @param[in] pSrcA points to the first input vector
+ @param[in] pSrcB points to the second input vector
+ @param[in] blockSize number of samples in each vector
+ @param[out] result output result returned here
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The intermediate multiplications are in 1.15 x 1.15 = 2.30 format and these
+ results are added to a 64-bit accumulator in 34.30 format.
+ Nonsaturating additions are used and given that there are 33 guard bits in the accumulator
+ there is no risk of overflow.
+ The return result is in 34.30 format.
*/
void arm_dot_prod_q15(
- q15_t * pSrcA,
- q15_t * pSrcB,
- uint32_t blockSize,
- q63_t * result)
+ const q15_t * pSrcA,
+ const q15_t * pSrcB,
+ uint32_t blockSize,
+ q63_t * result)
{
- q63_t sum = 0; /* Temporary result storage */
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+ q63_t sum = 0; /* Temporary return variable */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
+#if defined (ARM_MATH_LOOPUNROLL)
-
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
- /* Calculate dot product and then store the result in a temporary buffer. */
- sum = __SMLALD(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++, sum);
- sum = __SMLALD(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++, sum);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4U;
-
- while (blkCnt > 0U)
- {
- /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
- /* Calculate dot product and then store the results in a temporary buffer. */
- sum = __SMLALD(*pSrcA++, *pSrcB++, sum);
+#if defined (ARM_MATH_DSP)
+ /* Calculate dot product and store result in a temporary buffer. */
+ sum = __SMLALD(read_q15x2_ia ((q15_t **) &pSrcA), read_q15x2_ia ((q15_t **) &pSrcB), sum);
+ sum = __SMLALD(read_q15x2_ia ((q15_t **) &pSrcA), read_q15x2_ia ((q15_t **) &pSrcB), sum);
+#else
+ sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++);
+ sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++);
+ sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++);
+ sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+ /* Loop unrolling: Compute remaining outputs */
+ blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
- /* Calculate dot product and then store the results in a temporary buffer. */
- sum += (q63_t) ((q31_t) * pSrcA++ * *pSrcB++);
- /* Decrement the loop counter */
+ /* Calculate dot product and store result in a temporary buffer. */
+//#if defined (ARM_MATH_DSP)
+// sum = __SMLALD(*pSrcA++, *pSrcB++, sum);
+//#else
+ sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++);
+//#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
- /* Store the result in the destination buffer in 34.30 format */
+ /* Store result in destination buffer in 34.30 format */
*result = sum;
-
}
/**
- * @} end of dot_prod group
+ @} end of BasicDotProd group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_dot_prod_q31.c b/DSP/Source/BasicMathFunctions/arm_dot_prod_q31.c
index 67ae887..76cd577 100644
--- a/DSP/Source/BasicMathFunctions/arm_dot_prod_q31.c
+++ b/DSP/Source/BasicMathFunctions/arm_dot_prod_q31.c
@@ -3,13 +3,13 @@
* Title: arm_dot_prod_q31.c
* Description: Q31 dot product
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,103 +29,87 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup dot_prod
- * @{
+ @addtogroup BasicDotProd
+ @{
*/
/**
- * @brief Dot product of Q31 vectors.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[in] blockSize number of samples in each vector
- * @param[out] *result output result returned here
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The intermediate multiplications are in 1.31 x 1.31 = 2.62 format and these
- * are truncated to 2.48 format by discarding the lower 14 bits.
- * The 2.48 result is then added without saturation to a 64-bit accumulator in 16.48 format.
- * There are 15 guard bits in the accumulator and there is no risk of overflow as long as
- * the length of the vectors is less than 2^16 elements.
- * The return result is in 16.48 format.
+ @brief Dot product of Q31 vectors.
+ @param[in] pSrcA points to the first input vector.
+ @param[in] pSrcB points to the second input vector.
+ @param[in] blockSize number of samples in each vector.
+ @param[out] result output result returned here.
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The intermediate multiplications are in 1.31 x 1.31 = 2.62 format and these
+ are truncated to 2.48 format by discarding the lower 14 bits.
+ The 2.48 result is then added without saturation to a 64-bit accumulator in 16.48 format.
+ There are 15 guard bits in the accumulator and there is no risk of overflow as long as
+ the length of the vectors is less than 2^16 elements.
+ The return result is in 16.48 format.
*/
void arm_dot_prod_q31(
- q31_t * pSrcA,
- q31_t * pSrcB,
- uint32_t blockSize,
- q63_t * result)
+ const q31_t * pSrcA,
+ const q31_t * pSrcB,
+ uint32_t blockSize,
+ q63_t * result)
{
- q63_t sum = 0; /* Temporary result storage */
- uint32_t blkCnt; /* loop counter */
-
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+ q63_t sum = 0; /* Temporary return variable */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t inA1, inA2, inA3, inA4;
- q31_t inB1, inB2, inB3, inB4;
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
- /* Calculate dot product and then store the result in a temporary buffer. */
- inA1 = *pSrcA++;
- inA2 = *pSrcA++;
- inA3 = *pSrcA++;
- inA4 = *pSrcA++;
- inB1 = *pSrcB++;
- inB2 = *pSrcB++;
- inB3 = *pSrcB++;
- inB4 = *pSrcB++;
-
- sum += ((q63_t) inA1 * inB1) >> 14U;
- sum += ((q63_t) inA2 * inB2) >> 14U;
- sum += ((q63_t) inA3 * inB3) >> 14U;
- sum += ((q63_t) inA4 * inB4) >> 14U;
-
- /* Decrement the loop counter */
+
+ /* Calculate dot product and store result in a temporary buffer. */
+ sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U;
+
+ sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U;
+
+ sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U;
+
+ sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U;
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
-
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
- /* Calculate dot product and then store the result in a temporary buffer. */
- sum += ((q63_t) * pSrcA++ * *pSrcB++) >> 14U;
- /* Decrement the loop counter */
+ /* Calculate dot product and store result in a temporary buffer. */
+ sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U;
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* Store the result in the destination buffer in 16.48 format */
+ /* Store result in destination buffer in 16.48 format */
*result = sum;
}
/**
- * @} end of dot_prod group
+ @} end of BasicDotProd group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_dot_prod_q7.c b/DSP/Source/BasicMathFunctions/arm_dot_prod_q7.c
index 487efe3..8e18a73 100644
--- a/DSP/Source/BasicMathFunctions/arm_dot_prod_q7.c
+++ b/DSP/Source/BasicMathFunctions/arm_dot_prod_q7.c
@@ -3,13 +3,13 @@
* Title: arm_dot_prod_q7.c
* Description: Q7 dot product
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,61 +29,58 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup dot_prod
- * @{
+ @addtogroup BasicDotProd
+ @{
*/
/**
- * @brief Dot product of Q7 vectors.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[in] blockSize number of samples in each vector
- * @param[out] *result output result returned here
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The intermediate multiplications are in 1.7 x 1.7 = 2.14 format and these
- * results are added to an accumulator in 18.14 format.
- * Nonsaturating additions are used and there is no danger of wrap around as long as
- * the vectors are less than 2^18 elements long.
- * The return result is in 18.14 format.
+ @brief Dot product of Q7 vectors.
+ @param[in] pSrcA points to the first input vector
+ @param[in] pSrcB points to the second input vector
+ @param[in] blockSize number of samples in each vector
+ @param[out] result output result returned here
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The intermediate multiplications are in 1.7 x 1.7 = 2.14 format and these
+ results are added to an accumulator in 18.14 format.
+ Nonsaturating additions are used and there is no danger of wrap around as long as
+ the vectors are less than 2^18 elements long.
+ The return result is in 18.14 format.
*/
void arm_dot_prod_q7(
- q7_t * pSrcA,
- q7_t * pSrcB,
- uint32_t blockSize,
- q31_t * result)
+ const q7_t * pSrcA,
+ const q7_t * pSrcB,
+ uint32_t blockSize,
+ q31_t * result)
{
- uint32_t blkCnt; /* loop counter */
+ uint32_t blkCnt; /* Loop counter */
+ q31_t sum = 0; /* Temporary return variable */
- q31_t sum = 0; /* Temporary variables to store output */
+#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
+ q31_t input1, input2; /* Temporary variables */
+ q31_t inA1, inA2, inB1, inB2; /* Temporary variables */
+#endif
-/* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q31_t input1, input2; /* Temporary variables to store input */
- q31_t inA1, inA2, inB1, inB2; /* Temporary variables to store input */
-
-
-
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
+ /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
+
+#if defined (ARM_MATH_DSP)
/* read 4 samples at a time from sourceA */
- input1 = *__SIMD32(pSrcA)++;
+ input1 = read_q7x4_ia ((q7_t **) &pSrcA);
/* read 4 samples at a time from sourceB */
- input2 = *__SIMD32(pSrcB)++;
+ input2 = read_q7x4_ia ((q7_t **) &pSrcB);
/* extract two q7_t samples to q15_t samples */
inA1 = __SXTB16(__ROR(input1, 8));
@@ -97,51 +94,46 @@ void arm_dot_prod_q7(
/* multiply and accumulate two samples at a time */
sum = __SMLAD(inA1, inB1, sum);
sum = __SMLAD(inA2, inB2, sum);
+#else
+ sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++);
+ sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++);
+ sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++);
+ sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
- while (blkCnt > 0U)
- {
- /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
- /* Dot product and then store the results in a temporary buffer. */
- sum = __SMLAD(*pSrcA++, *pSrcB++, sum);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
#else
- /* Run the below code for Cortex-M0 */
-
-
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
- /* Dot product and then store the results in a temporary buffer. */
- sum += (q31_t) ((q15_t) * pSrcA++ * *pSrcB++);
- /* Decrement the loop counter */
+ /* Calculate dot product and store result in a temporary buffer. */
+//#if defined (ARM_MATH_DSP)
+// sum = __SMLAD(*pSrcA++, *pSrcB++, sum);
+//#else
+ sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++);
+//#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
-
- /* Store the result in the destination buffer in 18.14 format */
+ /* Store result in destination buffer in 18.14 format */
*result = sum;
}
/**
- * @} end of dot_prod group
+ @} end of BasicDotProd group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_mult_f32.c b/DSP/Source/BasicMathFunctions/arm_mult_f32.c
index e4a9ef2..53ad73c 100644
--- a/DSP/Source/BasicMathFunctions/arm_mult_f32.c
+++ b/DSP/Source/BasicMathFunctions/arm_mult_f32.c
@@ -3,13 +3,13 @@
* Title: arm_mult_f32.c
* Description: Floating-point vector multiplication
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,134 +29,120 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @defgroup BasicMult Vector Multiplication
- *
- * Element-by-element multiplication of two vectors.
- *
- * <pre>
- * pDst[n] = pSrcA[n] * pSrcB[n], 0 <= n < blockSize.
- * </pre>
- *
- * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
+ @defgroup BasicMult Vector Multiplication
+
+ Element-by-element multiplication of two vectors.
+
+ <pre>
+ pDst[n] = pSrcA[n] * pSrcB[n], 0 <= n < blockSize.
+ </pre>
+
+ There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
- * @addtogroup BasicMult
- * @{
+ @addtogroup BasicMult
+ @{
*/
/**
- * @brief Floating-point vector multiplication.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
+ @brief Floating-point vector multiplication.
+ @param[in] pSrcA points to the first input vector.
+ @param[in] pSrcB points to the second input vector.
+ @param[out] pDst points to the output vector.
+ @param[in] blockSize number of samples in each vector.
+ @return none
*/
void arm_mult_f32(
- float32_t * pSrcA,
- float32_t * pSrcB,
- float32_t * pDst,
- uint32_t blockSize)
+ const float32_t * pSrcA,
+ const float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counters */
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+
+#if defined(ARM_MATH_NEON)
+ float32x4_t vec1;
+ float32x4_t vec2;
+ float32x4_t res;
+
+ /* Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
+
+ while (blkCnt > 0U)
+ {
+ /* C = A * B */
+
+ /* Multiply the inputs and then store the results in the destination buffer. */
+ vec1 = vld1q_f32(pSrcA);
+ vec2 = vld1q_f32(pSrcB);
+ res = vmulq_f32(vec1, vec2);
+ vst1q_f32(pDst, res);
+
+ /* Increment pointers */
+ pSrcA += 4;
+ pSrcB += 4;
+ pDst += 4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Tail */
+ blkCnt = blockSize & 0x3;
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t inA1, inA2, inA3, inA4; /* temporary input variables */
- float32_t inB1, inB2, inB3, inB4; /* temporary input variables */
- float32_t out1, out2, out3, out4; /* temporary output variables */
+#else
+#if defined (ARM_MATH_LOOPUNROLL)
- /* loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A * B */
- /* Multiply the inputs and store the results in output buffer */
- /* read sample from sourceA */
- inA1 = *pSrcA;
- /* read sample from sourceB */
- inB1 = *pSrcB;
- /* read sample from sourceA */
- inA2 = *(pSrcA + 1);
- /* read sample from sourceB */
- inB2 = *(pSrcB + 1);
-
- /* out = sourceA * sourceB */
- out1 = inA1 * inB1;
-
- /* read sample from sourceA */
- inA3 = *(pSrcA + 2);
- /* read sample from sourceB */
- inB3 = *(pSrcB + 2);
-
- /* out = sourceA * sourceB */
- out2 = inA2 * inB2;
-
- /* read sample from sourceA */
- inA4 = *(pSrcA + 3);
- /* store result to destination buffer */
- *pDst = out1;
-
- /* read sample from sourceB */
- inB4 = *(pSrcB + 3);
-
- /* out = sourceA * sourceB */
- out3 = inA3 * inB3;
-
- /* store result to destination buffer */
- *(pDst + 1) = out2;
+ /* Multiply inputs and store result in destination buffer. */
+ *pDst++ = (*pSrcA++) * (*pSrcB++);
- /* out = sourceA * sourceB */
- out4 = inA4 * inB4;
- /* store result to destination buffer */
- *(pDst + 2) = out3;
- /* store result to destination buffer */
- *(pDst + 3) = out4;
+ *pDst++ = (*pSrcA++) * (*pSrcB++);
+ *pDst++ = (*pSrcA++) * (*pSrcB++);
- /* update pointers to process next samples */
- pSrcA += 4U;
- pSrcB += 4U;
- pDst += 4U;
+ *pDst++ = (*pSrcA++) * (*pSrcB++);
- /* Decrement the blockSize loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+#endif /* #if defined(ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = A * B */
- /* Multiply the inputs and store the results in output buffer */
+
+ /* Multiply input and store result in destination buffer. */
*pDst++ = (*pSrcA++) * (*pSrcB++);
- /* Decrement the blockSize loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of BasicMult group
+ @} end of BasicMult group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_mult_q15.c b/DSP/Source/BasicMathFunctions/arm_mult_q15.c
index 8e20963..37aa924 100644
--- a/DSP/Source/BasicMathFunctions/arm_mult_q15.c
+++ b/DSP/Source/BasicMathFunctions/arm_mult_q15.c
@@ -3,13 +3,13 @@
* Title: arm_mult_q15.c
* Description: Q15 vector multiplication
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,65 +29,65 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicMult
- * @{
+ @addtogroup BasicMult
+ @{
*/
-
/**
- * @brief Q15 vector multiplication
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
+ @brief Q15 vector multiplication
+ @param[in] pSrcA points to first input vector
+ @param[in] pSrcB points to second input vector
+ @param[out] pDst points to output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
*/
void arm_mult_q15(
- q15_t * pSrcA,
- q15_t * pSrcB,
- q15_t * pDst,
- uint32_t blockSize)
+ const q15_t * pSrcA,
+ const q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counters */
+ uint32_t blkCnt; /* Loop counter */
-#if defined (ARM_MATH_DSP)
+#if defined (ARM_MATH_LOOPUNROLL)
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t inA1, inA2, inB1, inB2; /* temporary input variables */
- q15_t out1, out2, out3, out4; /* temporary output variables */
- q31_t mul1, mul2, mul3, mul4; /* temporary variables */
+#if defined (ARM_MATH_DSP)
+ q31_t inA1, inA2, inB1, inB2; /* Temporary input variables */
+ q15_t out1, out2, out3, out4; /* Temporary output variables */
+ q31_t mul1, mul2, mul3, mul4; /* Temporary variables */
+#endif
- /* loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
- /* read two samples at a time from sourceA */
- inA1 = *__SIMD32(pSrcA)++;
- /* read two samples at a time from sourceB */
- inB1 = *__SIMD32(pSrcB)++;
- /* read two samples at a time from sourceA */
- inA2 = *__SIMD32(pSrcA)++;
- /* read two samples at a time from sourceB */
- inB2 = *__SIMD32(pSrcB)++;
+ /* C = A * B */
+
+#if defined (ARM_MATH_DSP)
+ /* read 2 samples at a time from sourceA */
+ inA1 = read_q15x2_ia ((q15_t **) &pSrcA);
+ /* read 2 samples at a time from sourceB */
+ inB1 = read_q15x2_ia ((q15_t **) &pSrcB);
+ /* read 2 samples at a time from sourceA */
+ inA2 = read_q15x2_ia ((q15_t **) &pSrcA);
+ /* read 2 samples at a time from sourceB */
+ inB2 = read_q15x2_ia ((q15_t **) &pSrcB);
/* multiply mul = sourceA * sourceB */
mul1 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16));
- mul2 = (q31_t) ((q15_t) inA1 * (q15_t) inB1);
+ mul2 = (q31_t) ((q15_t) (inA1 ) * (q15_t) (inB1 ));
mul3 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB2 >> 16));
- mul4 = (q31_t) ((q15_t) inA2 * (q15_t) inB2);
+ mul4 = (q31_t) ((q15_t) (inA2 ) * (q15_t) (inB2 ));
/* saturate result to 16 bit */
out1 = (q15_t) __SSAT(mul1 >> 15, 16);
@@ -95,48 +95,49 @@ void arm_mult_q15(
out3 = (q15_t) __SSAT(mul3 >> 15, 16);
out4 = (q15_t) __SSAT(mul4 >> 15, 16);
- /* store the result */
+ /* store result to destination */
#ifndef ARM_MATH_BIG_ENDIAN
-
- *__SIMD32(pDst)++ = __PKHBT(out2, out1, 16);
- *__SIMD32(pDst)++ = __PKHBT(out4, out3, 16);
-
+ write_q15x2_ia (&pDst, __PKHBT(out2, out1, 16));
+ write_q15x2_ia (&pDst, __PKHBT(out4, out3, 16));
#else
-
- *__SIMD32(pDst)++ = __PKHBT(out2, out1, 16);
- *__SIMD32(pDst)++ = __PKHBT(out4, out3, 16);
-
+ write_q15x2_ia (&pDst, __PKHBT(out1, out2, 16));
+ write_q15x2_ia (&pDst, __PKHBT(out3, out4, 16));
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
- /* Decrement the blockSize loop counter */
+#else
+ *pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
+ *pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
+ *pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
+ *pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
-
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A * B */
- /* Multiply the inputs and store the result in the destination buffer */
+
+ /* Multiply inputs and store result in destination buffer. */
*pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
- /* Decrement the blockSize loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of BasicMult group
+ @} end of BasicMult group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_mult_q31.c b/DSP/Source/BasicMathFunctions/arm_mult_q31.c
index c302b01..9592684 100644
--- a/DSP/Source/BasicMathFunctions/arm_mult_q31.c
+++ b/DSP/Source/BasicMathFunctions/arm_mult_q31.c
@@ -3,13 +3,13 @@
* Title: arm_mult_q31.c
* Description: Q31 vector multiplication
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,120 +29,91 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicMult
- * @{
+ @addtogroup BasicMult
+ @{
*/
/**
- * @brief Q31 vector multiplication.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] will be saturated.
+ @brief Q31 vector multiplication.
+ @param[in] pSrcA points to the first input vector.
+ @param[in] pSrcB points to the second input vector.
+ @param[out] pDst points to the output vector.
+ @param[in] blockSize number of samples in each vector.
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] are saturated.
*/
void arm_mult_q31(
- q31_t * pSrcA,
- q31_t * pSrcB,
- q31_t * pDst,
- uint32_t blockSize)
+ const q31_t * pSrcA,
+ const q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counters */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+ q31_t out; /* Temporary output variable */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t inA1, inA2, inA3, inA4; /* temporary input variables */
- q31_t inB1, inB2, inB3, inB4; /* temporary input variables */
- q31_t out1, out2, out3, out4; /* temporary output variables */
+#if defined (ARM_MATH_LOOPUNROLL)
- /* loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A * B */
- /* Multiply the inputs and then store the results in the destination buffer. */
- inA1 = *pSrcA++;
- inA2 = *pSrcA++;
- inA3 = *pSrcA++;
- inA4 = *pSrcA++;
- inB1 = *pSrcB++;
- inB2 = *pSrcB++;
- inB3 = *pSrcB++;
- inB4 = *pSrcB++;
-
- out1 = ((q63_t) inA1 * inB1) >> 32;
- out2 = ((q63_t) inA2 * inB2) >> 32;
- out3 = ((q63_t) inA3 * inB3) >> 32;
- out4 = ((q63_t) inA4 * inB4) >> 32;
-
- out1 = __SSAT(out1, 31);
- out2 = __SSAT(out2, 31);
- out3 = __SSAT(out3, 31);
- out4 = __SSAT(out4, 31);
-
- *pDst++ = out1 << 1U;
- *pDst++ = out2 << 1U;
- *pDst++ = out3 << 1U;
- *pDst++ = out4 << 1U;
-
- /* Decrement the blockSize loop counter */
- blkCnt--;
- }
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4U;
+ /* Multiply inputs and store result in destination buffer. */
+ out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32;
+ out = __SSAT(out, 31);
+ *pDst++ = out << 1U;
- while (blkCnt > 0U)
- {
- /* C = A * B */
- /* Multiply the inputs and then store the results in the destination buffer. */
- inA1 = *pSrcA++;
- inB1 = *pSrcB++;
- out1 = ((q63_t) inA1 * inB1) >> 32;
- out1 = __SSAT(out1, 31);
- *pDst++ = out1 << 1U;
-
- /* Decrement the blockSize loop counter */
+ out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32;
+ out = __SSAT(out, 31);
+ *pDst++ = out << 1U;
+
+ out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32;
+ out = __SSAT(out, 31);
+ *pDst++ = out << 1U;
+
+ out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32;
+ out = __SSAT(out, 31);
+ *pDst++ = out << 1U;
+
+ /* Decrement loop counter */
blkCnt--;
}
-#else
+ /* Loop unrolling: Compute remaining outputs */
+ blkCnt = blockSize % 0x4U;
- /* Run the below code for Cortex-M0 */
+#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A * B */
- /* Multiply the inputs and then store the results in the destination buffer. */
- *pDst++ =
- (q31_t) clip_q63_to_q31(((q63_t) (*pSrcA++) * (*pSrcB++)) >> 31);
- /* Decrement the blockSize loop counter */
+ /* Multiply inputs and store result in destination buffer. */
+ out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32;
+ out = __SSAT(out, 31);
+ *pDst++ = out << 1U;
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
}
/**
- * @} end of BasicMult group
+ @} end of BasicMult group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_mult_q7.c b/DSP/Source/BasicMathFunctions/arm_mult_q7.c
index d8a2f8a..5587ce5 100644
--- a/DSP/Source/BasicMathFunctions/arm_mult_q7.c
+++ b/DSP/Source/BasicMathFunctions/arm_mult_q7.c
@@ -3,13 +3,13 @@
* Title: arm_mult_q7.c
* Description: Q7 vector multiplication
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,87 +29,91 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicMult
- * @{
+ @addtogroup BasicMult
+ @{
*/
/**
- * @brief Q7 vector multiplication
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
+ @brief Q7 vector multiplication
+ @param[in] pSrcA points to the first input vector
+ @param[in] pSrcB points to the second input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
*/
void arm_mult_q7(
- q7_t * pSrcA,
- q7_t * pSrcB,
- q7_t * pDst,
- uint32_t blockSize)
+ const q7_t * pSrcA,
+ const q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counters */
+ uint32_t blkCnt; /* Loop counter */
-#if defined (ARM_MATH_DSP)
+#if defined (ARM_MATH_LOOPUNROLL)
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q7_t out1, out2, out3, out4; /* Temporary variables to store the product */
+#if defined (ARM_MATH_DSP)
+ q7_t out1, out2, out3, out4; /* Temporary output variables */
+#endif
- /* loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A * B */
- /* Multiply the inputs and store the results in temporary variables */
+
+#if defined (ARM_MATH_DSP)
+ /* Multiply inputs and store results in temporary variables */
out1 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
out2 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
out3 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
out4 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
- /* Store the results of 4 inputs in the destination buffer in single cycle by packing */
- *__SIMD32(pDst)++ = __PACKq7(out1, out2, out3, out4);
+ /* Pack and store result in destination buffer (in single write) */
+ write_q7x4_ia (&pDst, __PACKq7(out1, out2, out3, out4));
+#else
+ *pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
+ *pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
+ *pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
+ *pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
+#endif
- /* Decrement the blockSize loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
-
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A * B */
- /* Multiply the inputs and store the result in the destination buffer */
+
+ /* Multiply input and store result in destination buffer. */
*pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
- /* Decrement the blockSize loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of BasicMult group
+ @} end of BasicMult group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_negate_f32.c b/DSP/Source/BasicMathFunctions/arm_negate_f32.c
index e39624c..f807112 100644
--- a/DSP/Source/BasicMathFunctions/arm_negate_f32.c
+++ b/DSP/Source/BasicMathFunctions/arm_negate_f32.c
@@ -3,13 +3,13 @@
* Title: arm_negate_f32.c
* Description: Negates floating-point vectors
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,106 +29,117 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @defgroup negate Vector Negate
- *
- * Negates the elements of a vector.
- *
- * <pre>
- * pDst[n] = -pSrc[n], 0 <= n < blockSize.
- * </pre>
- *
- * The functions support in-place computation allowing the source and
- * destination pointers to reference the same memory buffer.
- * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
+ @defgroup BasicNegate Vector Negate
+
+ Negates the elements of a vector.
+
+ <pre>
+ pDst[n] = -pSrc[n], 0 <= n < blockSize.
+ </pre>
+
+ The functions support in-place computation allowing the source and
+ destination pointers to reference the same memory buffer.
+ There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
- * @addtogroup negate
- * @{
+ @addtogroup BasicNegate
+ @{
*/
/**
- * @brief Negates the elements of a floating-point vector.
- * @param[in] *pSrc points to the input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
+ @brief Negates the elements of a floating-point vector.
+ @param[in] pSrc points to input vector.
+ @param[out] pDst points to output vector.
+ @param[in] blockSize number of samples in each vector.
+ @return none
*/
void arm_negate_f32(
- float32_t * pSrc,
- float32_t * pDst,
- uint32_t blockSize)
+ const float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
+ uint32_t blkCnt; /* Loop counter */
+#if defined(ARM_MATH_NEON_EXPERIMENTAL)
+ float32x4_t vec1;
+ float32x4_t res;
-#if defined (ARM_MATH_DSP)
+ /* Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t in1, in2, in3, in4; /* temporary variables */
+ while (blkCnt > 0U)
+ {
+ /* C = -A */
- /*loop Unrolling */
+ /* Negate and then store the results in the destination buffer. */
+ vec1 = vld1q_f32(pSrc);
+ res = vnegq_f32(vec1);
+ vst1q_f32(pDst, res);
+
+ /* Increment pointers */
+ pSrc += 4;
+ pDst += 4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Tail */
+ blkCnt = blockSize & 0x3;
+
+#else
+#if defined (ARM_MATH_LOOPUNROLL)
+
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
- /* read inputs from source */
- in1 = *pSrc;
- in2 = *(pSrc + 1);
- in3 = *(pSrc + 2);
- in4 = *(pSrc + 3);
-
- /* negate the input */
- in1 = -in1;
- in2 = -in2;
- in3 = -in3;
- in4 = -in4;
-
- /* store the result to destination */
- *pDst = in1;
- *(pDst + 1) = in2;
- *(pDst + 2) = in3;
- *(pDst + 3) = in4;
-
- /* update pointers to process next samples */
- pSrc += 4U;
- pDst += 4U;
-
- /* Decrement the loop counter */
+ /* C = -A */
+
+ /* Negate and store result in destination buffer. */
+ *pDst++ = -*pSrc++;
+
+ *pDst++ = -*pSrc++;
+
+ *pDst++ = -*pSrc++;
+
+ *pDst++ = -*pSrc++;
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+#endif /* #if defined(ARM_MATH_NEON_EXPERIMENTAL) */
while (blkCnt > 0U)
{
/* C = -A */
- /* Negate and then store the results in the destination buffer. */
+
+ /* Negate and store result in destination buffer. */
*pDst++ = -*pSrc++;
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of negate group
+ @} end of BasicNegate group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_negate_q15.c b/DSP/Source/BasicMathFunctions/arm_negate_q15.c
index 9624160..267e4cc 100644
--- a/DSP/Source/BasicMathFunctions/arm_negate_q15.c
+++ b/DSP/Source/BasicMathFunctions/arm_negate_q15.c
@@ -3,13 +3,13 @@
* Title: arm_negate_q15.c
* Description: Negates Q15 vectors
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,103 +29,98 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup negate
- * @{
+ @addtogroup BasicNegate
+ @{
*/
/**
- * @brief Negates the elements of a Q15 vector.
- * @param[in] *pSrc points to the input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * \par Conditions for optimum performance
- * Input and output buffers should be aligned by 32-bit
- *
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * The Q15 value -1 (0x8000) will be saturated to the maximum allowable positive value 0x7FFF.
+ @brief Negates the elements of a Q15 vector.
+ @param[in] pSrc points to the input vector.
+ @param[out] pDst points to the output vector.
+ @param[in] blockSize number of samples in each vector.
+ @return none
+
+ @par Conditions for optimum performance
+ Input and output buffers should be aligned by 32-bit
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ The Q15 value -1 (0x8000) is saturated to the maximum allowable positive value 0x7FFF.
*/
void arm_negate_q15(
- q15_t * pSrc,
- q15_t * pDst,
- uint32_t blockSize)
+ const q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
- q15_t in;
-
-#if defined (ARM_MATH_DSP)
-
-/* Run the below code for Cortex-M4 and Cortex-M3 */
+ uint32_t blkCnt; /* Loop counter */
+ q15_t in; /* Temporary input variable */
- q31_t in1, in2; /* Temporary variables */
+#if defined (ARM_MATH_LOOPUNROLL)
+#if defined (ARM_MATH_DSP)
+ q31_t in1; /* Temporary input variables */
+#endif
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = -A */
- /* Read two inputs at a time */
- in1 = _SIMD32_OFFSET(pSrc);
- in2 = _SIMD32_OFFSET(pSrc + 2);
- /* negate two samples at a time */
- in1 = __QSUB16(0, in1);
+#if defined (ARM_MATH_DSP)
+ /* Negate and store result in destination buffer (2 samples at a time). */
+ in1 = read_q15x2_ia ((q15_t **) &pSrc);
+ write_q15x2_ia (&pDst, __QSUB16(0, in1));
- /* negate two samples at a time */
- in2 = __QSUB16(0, in2);
+ in1 = read_q15x2_ia ((q15_t **) &pSrc);
+ write_q15x2_ia (&pDst, __QSUB16(0, in1));
+#else
+ in = *pSrc++;
+ *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in;
- /* store the result to destination 2 samples at a time */
- _SIMD32_OFFSET(pDst) = in1;
- /* store the result to destination 2 samples at a time */
- _SIMD32_OFFSET(pDst + 2) = in2;
+ in = *pSrc++;
+ *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in;
+ in = *pSrc++;
+ *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in;
- /* update pointers to process next samples */
- pSrc += 4U;
- pDst += 4U;
+ in = *pSrc++;
+ *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in;
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = -A */
- /* Negate and then store the result in the destination buffer. */
+
+ /* Negate and store result in destination buffer. */
in = *pSrc++;
- *pDst++ = (in == (q15_t) 0x8000) ? 0x7fff : -in;
+ *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in;
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of negate group
+ @} end of BasicNegate group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_negate_q31.c b/DSP/Source/BasicMathFunctions/arm_negate_q31.c
index 4a5a58d..645fb0a 100644
--- a/DSP/Source/BasicMathFunctions/arm_negate_q31.c
+++ b/DSP/Source/BasicMathFunctions/arm_negate_q31.c
@@ -3,13 +3,13 @@
* Title: arm_negate_q31.c
* Description: Negates Q31 vectors
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,89 +29,104 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup negate
- * @{
+ @addtogroup BasicNegate
+ @{
*/
/**
- * @brief Negates the elements of a Q31 vector.
- * @param[in] *pSrc points to the input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * The Q31 value -1 (0x80000000) will be saturated to the maximum allowable positive value 0x7FFFFFFF.
+ @brief Negates the elements of a Q31 vector.
+ @param[in] pSrc points to the input vector.
+ @param[out] pDst points to the output vector.
+ @param[in] blockSize number of samples in each vector.
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ The Q31 value -1 (0x80000000) is saturated to the maximum allowable positive value 0x7FFFFFFF.
*/
void arm_negate_q31(
- q31_t * pSrc,
- q31_t * pDst,
- uint32_t blockSize)
+ const q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize)
{
- q31_t in; /* Temporary variable */
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+ q31_t in; /* Temporary input variable */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1, in2, in3, in4;
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = -A */
- /* Negate and then store the results in the destination buffer. */
- in1 = *pSrc++;
- in2 = *pSrc++;
- in3 = *pSrc++;
- in4 = *pSrc++;
-
- *pDst++ = __QSUB(0, in1);
- *pDst++ = __QSUB(0, in2);
- *pDst++ = __QSUB(0, in3);
- *pDst++ = __QSUB(0, in4);
-
- /* Decrement the loop counter */
+
+ /* Negate and store result in destination buffer. */
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = __QSUB(0, in);
+#else
+ *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
+#endif
+
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = __QSUB(0, in);
+#else
+ *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
+#endif
+
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = __QSUB(0, in);
+#else
+ *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
+#endif
+
+ in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = __QSUB(0, in);
+#else
+ *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
-
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = -A */
- /* Negate and then store the result in the destination buffer. */
+
+ /* Negate and store result in destination buffer. */
in = *pSrc++;
+#if defined (ARM_MATH_DSP)
+ *pDst++ = __QSUB(0, in);
+#else
*pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of negate group
+ @} end of BasicNegate group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_negate_q7.c b/DSP/Source/BasicMathFunctions/arm_negate_q7.c
index d72c317..40a373e 100644
--- a/DSP/Source/BasicMathFunctions/arm_negate_q7.c
+++ b/DSP/Source/BasicMathFunctions/arm_negate_q7.c
@@ -3,13 +3,13 @@
* Title: arm_negate_q7.c
* Description: Negates Q7 vectors
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,85 +29,98 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup negate
- * @{
+ @addtogroup BasicNegate
+ @{
*/
/**
- * @brief Negates the elements of a Q7 vector.
- * @param[in] *pSrc points to the input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * The Q7 value -1 (0x80) will be saturated to the maximum allowable positive value 0x7F.
+ @brief Negates the elements of a Q7 vector.
+ @param[in] pSrc points to the input vector.
+ @param[out] pDst points to the output vector.
+ @param[in] blockSize number of samples in each vector.
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ The Q7 value -1 (0x80) is saturated to the maximum allowable positive value 0x7F.
*/
void arm_negate_q7(
- q7_t * pSrc,
- q7_t * pDst,
- uint32_t blockSize)
+ const q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
- q7_t in;
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+ q7_t in; /* Temporary input variable */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t input; /* Input values1-4 */
- q31_t zero = 0x00000000;
+#if defined (ARM_MATH_LOOPUNROLL)
+#if defined (ARM_MATH_DSP)
+ q31_t in1; /* Temporary input variable */
+#endif
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = -A */
- /* Read four inputs */
- input = *__SIMD32(pSrc)++;
- /* Store the Negated results in the destination buffer in a single cycle by packing the results */
- *__SIMD32(pDst)++ = __QSUB8(zero, input);
+#if defined (ARM_MATH_DSP)
+ /* Negate and store result in destination buffer (4 samples at a time). */
+ in1 = read_q7x4_ia ((q7_t **) &pSrc);
+ write_q7x4_ia (&pDst, __QSUB8(0, in1));
+#else
+ in = *pSrc++;
+ *pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in;
+
+ in = *pSrc++;
+ *pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in;
+
+ in = *pSrc++;
+ *pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in;
- /* Decrement the loop counter */
+ in = *pSrc++;
+ *pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in;
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = -A */
- /* Negate and then store the results in the destination buffer. */ \
- in = *pSrc++;
- *pDst++ = (in == (q7_t) 0x80) ? 0x7f : -in;
- /* Decrement the loop counter */
+ /* Negate and store result in destination buffer. */
+ in = *pSrc++;
+
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (q7_t) __QSUB(0, in);
+#else
+ *pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in;
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of negate group
+ @} end of BasicNegate group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_offset_f32.c b/DSP/Source/BasicMathFunctions/arm_offset_f32.c
index ebc20a4..b10e3f1 100644
--- a/DSP/Source/BasicMathFunctions/arm_offset_f32.c
+++ b/DSP/Source/BasicMathFunctions/arm_offset_f32.c
@@ -3,13 +3,13 @@
* Title: arm_offset_f32.c
* Description: Floating-point vector offset
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,126 +29,119 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @defgroup offset Vector Offset
- *
- * Adds a constant offset to each element of a vector.
- *
- * <pre>
- * pDst[n] = pSrc[n] + offset, 0 <= n < blockSize.
- * </pre>
- *
- * The functions support in-place computation allowing the source and
- * destination pointers to reference the same memory buffer.
- * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
+ @defgroup BasicOffset Vector Offset
+
+ Adds a constant offset to each element of a vector.
+
+ <pre>
+ pDst[n] = pSrc[n] + offset, 0 <= n < blockSize.
+ </pre>
+
+ The functions support in-place computation allowing the source and
+ destination pointers to reference the same memory buffer.
+ There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
- * @addtogroup offset
- * @{
+ @addtogroup BasicOffset
+ @{
*/
/**
- * @brief Adds a constant offset to a floating-point vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] offset is the offset to be added
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
+ @brief Adds a constant offset to a floating-point vector.
+ @param[in] pSrc points to the input vector
+ @param[in] offset is the offset to be added
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
*/
-
void arm_offset_f32(
- float32_t * pSrc,
- float32_t offset,
- float32_t * pDst,
- uint32_t blockSize)
+ const float32_t * pSrc,
+ float32_t offset,
+ float32_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+
+#if defined(ARM_MATH_NEON_EXPERIMENTAL)
+ float32x4_t vec1;
+ float32x4_t res;
+
+ /* Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
+
+ while (blkCnt > 0U)
+ {
+ /* C = A + offset */
+
+ /* Add offset and then store the results in the destination buffer. */
+ vec1 = vld1q_f32(pSrc);
+ res = vaddq_f32(vec1,vdupq_n_f32(offset));
+ vst1q_f32(pDst, res);
+
+ /* Increment pointers */
+ pSrc += 4;
+ pDst += 4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Tail */
+ blkCnt = blockSize & 0x3;
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t in1, in2, in3, in4;
+#else
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A + offset */
- /* Add offset and then store the results in the destination buffer. */
- /* read samples from source */
- in1 = *pSrc;
- in2 = *(pSrc + 1);
-
- /* add offset to input */
- in1 = in1 + offset;
-
- /* read samples from source */
- in3 = *(pSrc + 2);
-
- /* add offset to input */
- in2 = in2 + offset;
- /* read samples from source */
- in4 = *(pSrc + 3);
-
- /* add offset to input */
- in3 = in3 + offset;
-
- /* store result to destination */
- *pDst = in1;
-
- /* add offset to input */
- in4 = in4 + offset;
-
- /* store result to destination */
- *(pDst + 1) = in2;
+ /* Add offset and store result in destination buffer. */
+ *pDst++ = (*pSrc++) + offset;
- /* store result to destination */
- *(pDst + 2) = in3;
+ *pDst++ = (*pSrc++) + offset;
- /* store result to destination */
- *(pDst + 3) = in4;
+ *pDst++ = (*pSrc++) + offset;
- /* update pointers to process next samples */
- pSrc += 4U;
- pDst += 4U;
+ *pDst++ = (*pSrc++) + offset;
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+#endif /* #if defined(ARM_MATH_NEON_EXPERIMENTAL) */
while (blkCnt > 0U)
{
/* C = A + offset */
- /* Add offset and then store the result in the destination buffer. */
+
+ /* Add offset and store result in destination buffer. */
*pDst++ = (*pSrc++) + offset;
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of offset group
+ @} end of BasicOffset group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_offset_q15.c b/DSP/Source/BasicMathFunctions/arm_offset_q15.c
index dab0b10..cd2f22b 100644
--- a/DSP/Source/BasicMathFunctions/arm_offset_q15.c
+++ b/DSP/Source/BasicMathFunctions/arm_offset_q15.c
@@ -3,13 +3,13 @@
* Title: arm_offset_q15.c
* Description: Q15 vector offset
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,96 +29,93 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup offset
- * @{
+ @addtogroup BasicOffset
+ @{
*/
/**
- * @brief Adds a constant offset to a Q15 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] offset is the offset to be added
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
+ @brief Adds a constant offset to a Q15 vector.
+ @param[in] pSrc points to the input vector
+ @param[in] offset is the offset to be added
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
*/
void arm_offset_q15(
- q15_t * pSrc,
- q15_t offset,
- q15_t * pDst,
- uint32_t blockSize)
+ const q15_t * pSrc,
+ q15_t offset,
+ q15_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
+ uint32_t blkCnt; /* Loop counter */
-#if defined (ARM_MATH_DSP)
+#if defined (ARM_MATH_LOOPUNROLL)
-/* Run the below code for Cortex-M4 and Cortex-M3 */
+#if defined (ARM_MATH_DSP)
q31_t offset_packed; /* Offset packed to 32 bit */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2U;
-
/* Offset is packed to 32 bit in order to use SIMD32 for addition */
offset_packed = __PKHBT(offset, offset, 16);
+#endif
+
+ /* Loop unrolling: Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A + offset */
- /* Add offset and then store the results in the destination buffer, 2 samples at a time. */
- *__SIMD32(pDst)++ = __QADD16(*__SIMD32(pSrc)++, offset_packed);
- *__SIMD32(pDst)++ = __QADD16(*__SIMD32(pSrc)++, offset_packed);
- /* Decrement the loop counter */
+#if defined (ARM_MATH_DSP)
+ /* Add offset and store result in destination buffer (2 samples at a time). */
+ write_q15x2_ia (&pDst, __QADD16(read_q15x2_ia ((q15_t **) &pSrc), offset_packed));
+ write_q15x2_ia (&pDst, __QADD16(read_q15x2_ia ((q15_t **) &pSrc), offset_packed));
+#else
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16);
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16);
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16);
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16);
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
- while (blkCnt > 0U)
- {
- /* C = A + offset */
- /* Add offset and then store the results in the destination buffer. */
- *pDst++ = (q15_t) __QADD16(*pSrc++, offset);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A + offset */
- /* Add offset and then store the results in the destination buffer. */
- *pDst++ = (q15_t) __SSAT(((q31_t) * pSrc++ + offset), 16);
- /* Decrement the loop counter */
+ /* Add offset and store result in destination buffer. */
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (q15_t) __QADD16(*pSrc++, offset);
+#else
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16);
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
}
/**
- * @} end of offset group
+ @} end of BasicOffset group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_offset_q31.c b/DSP/Source/BasicMathFunctions/arm_offset_q31.c
index 655426e..5de36b4 100644
--- a/DSP/Source/BasicMathFunctions/arm_offset_q31.c
+++ b/DSP/Source/BasicMathFunctions/arm_offset_q31.c
@@ -3,13 +3,13 @@
* Title: arm_offset_q31.c
* Description: Q31 vector offset
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,100 +29,100 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup offset
- * @{
+ @addtogroup BasicOffset
+ @{
*/
/**
- * @brief Adds a constant offset to a Q31 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] offset is the offset to be added
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
+ @brief Adds a constant offset to a Q31 vector.
+ @param[in] pSrc points to the input vector
+ @param[in] offset is the offset to be added
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
*/
void arm_offset_q31(
- q31_t * pSrc,
- q31_t offset,
- q31_t * pDst,
- uint32_t blockSize)
+ const q31_t * pSrc,
+ q31_t offset,
+ q31_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1, in2, in3, in4;
+#if defined (ARM_MATH_LOOPUNROLL)
-
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A + offset */
- /* Add offset and then store the results in the destination buffer. */
- in1 = *pSrc++;
- in2 = *pSrc++;
- in3 = *pSrc++;
- in4 = *pSrc++;
-
- *pDst++ = __QADD(in1, offset);
- *pDst++ = __QADD(in2, offset);
- *pDst++ = __QADD(in3, offset);
- *pDst++ = __QADD(in4, offset);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4U;
+ /* Add offset and store result in destination buffer. */
+#if defined (ARM_MATH_DSP)
+ *pDst++ = __QADD(*pSrc++, offset);
+#else
+ *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset);
+#endif
- while (blkCnt > 0U)
- {
- /* C = A + offset */
- /* Add offset and then store the result in the destination buffer. */
+#if defined (ARM_MATH_DSP)
+ *pDst++ = __QADD(*pSrc++, offset);
+#else
+ *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset);
+#endif
+
+#if defined (ARM_MATH_DSP)
*pDst++ = __QADD(*pSrc++, offset);
+#else
+ *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset);
+#endif
+
+#if defined (ARM_MATH_DSP)
+ *pDst++ = __QADD(*pSrc++, offset);
+#else
+ *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
-#else
+ /* Loop unrolling: Compute remaining outputs */
+ blkCnt = blockSize % 0x4U;
- /* Run the below code for Cortex-M0 */
+#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A + offset */
- /* Add offset and then store the result in the destination buffer. */
+
+ /* Add offset and store result in destination buffer. */
+#if defined (ARM_MATH_DSP)
+ *pDst++ = __QADD(*pSrc++, offset);
+#else
*pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
}
/**
- * @} end of offset group
+ @} end of BasicOffset group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_offset_q7.c b/DSP/Source/BasicMathFunctions/arm_offset_q7.c
index 5de6241..f67db45 100644
--- a/DSP/Source/BasicMathFunctions/arm_offset_q7.c
+++ b/DSP/Source/BasicMathFunctions/arm_offset_q7.c
@@ -3,13 +3,13 @@
* Title: arm_offset_q7.c
* Description: Q7 vector offset
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,95 +29,88 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup offset
- * @{
+ @addtogroup BasicOffset
+ @{
*/
/**
- * @brief Adds a constant offset to a Q7 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] offset is the offset to be added
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
+ @brief Adds a constant offset to a Q7 vector.
+ @param[in] pSrc points to the input vector
+ @param[in] offset is the offset to be added
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
*/
void arm_offset_q7(
- q7_t * pSrc,
- q7_t offset,
- q7_t * pDst,
- uint32_t blockSize)
+ const q7_t * pSrc,
+ q7_t offset,
+ q7_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
+ uint32_t blkCnt; /* Loop counter */
-#if defined (ARM_MATH_DSP)
+#if defined (ARM_MATH_LOOPUNROLL)
-/* Run the below code for Cortex-M4 and Cortex-M3 */
+#if defined (ARM_MATH_DSP)
q31_t offset_packed; /* Offset packed to 32 bit */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2U;
-
/* Offset is packed to 32 bit in order to use SIMD32 for addition */
offset_packed = __PACKq7(offset, offset, offset, offset);
+#endif
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while (blkCnt > 0U)
- {
- /* C = A + offset */
- /* Add offset and then store the results in the destination bufferfor 4 samples at a time. */
- *__SIMD32(pDst)++ = __QADD8(*__SIMD32(pSrc)++, offset_packed);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4U;
+ /* Loop unrolling: Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + offset */
- /* Add offset and then store the result in the destination buffer. */
+
+#if defined (ARM_MATH_DSP)
+ /* Add offset and store result in destination buffer (4 samples at a time). */
+ write_q7x4_ia (&pDst, __QADD8(read_q7x4_ia ((q7_t **) &pSrc), offset_packed));
+#else
+ *pDst++ = (q7_t) __SSAT(*pSrc++ + offset, 8);
+ *pDst++ = (q7_t) __SSAT(*pSrc++ + offset, 8);
+ *pDst++ = (q7_t) __SSAT(*pSrc++ + offset, 8);
*pDst++ = (q7_t) __SSAT(*pSrc++ + offset, 8);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
-#else
+ /* Loop unrolling: Compute remaining outputs */
+ blkCnt = blockSize % 0x4U;
- /* Run the below code for Cortex-M0 */
+#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A + offset */
- /* Add offset and then store the result in the destination buffer. */
- *pDst++ = (q7_t) __SSAT((q15_t) * pSrc++ + offset, 8);
- /* Decrement the loop counter */
+ /* Add offset and store result in destination buffer. */
+ *pDst++ = (q7_t) __SSAT((q15_t) *pSrc++ + offset, 8);
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
}
/**
- * @} end of offset group
+ @} end of BasicOffset group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_scale_f32.c b/DSP/Source/BasicMathFunctions/arm_scale_f32.c
index c90c037..72ecbe5 100644
--- a/DSP/Source/BasicMathFunctions/arm_scale_f32.c
+++ b/DSP/Source/BasicMathFunctions/arm_scale_f32.c
@@ -3,13 +3,13 @@
* Title: arm_scale_f32.c
* Description: Multiplies a floating-point vector by a scalar
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,129 +29,131 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @defgroup scale Vector Scale
- *
- * Multiply a vector by a scalar value. For floating-point data, the algorithm used is:
- *
- * <pre>
- * pDst[n] = pSrc[n] * scale, 0 <= n < blockSize.
- * </pre>
- *
- * In the fixed-point Q7, Q15, and Q31 functions, <code>scale</code> is represented by
- * a fractional multiplication <code>scaleFract</code> and an arithmetic shift <code>shift</code>.
- * The shift allows the gain of the scaling operation to exceed 1.0.
- * The algorithm used with fixed-point data is:
- *
- * <pre>
- * pDst[n] = (pSrc[n] * scaleFract) << shift, 0 <= n < blockSize.
- * </pre>
- *
- * The overall scale factor applied to the fixed-point data is
- * <pre>
- * scale = scaleFract * 2^shift.
- * </pre>
- *
- * The functions support in-place computation allowing the source and destination
- * pointers to reference the same memory buffer.
+ @defgroup BasicScale Vector Scale
+
+ Multiply a vector by a scalar value. For floating-point data, the algorithm used is:
+
+ <pre>
+ pDst[n] = pSrc[n] * scale, 0 <= n < blockSize.
+ </pre>
+
+ In the fixed-point Q7, Q15, and Q31 functions, <code>scale</code> is represented by
+ a fractional multiplication <code>scaleFract</code> and an arithmetic shift <code>shift</code>.
+ The shift allows the gain of the scaling operation to exceed 1.0.
+ The algorithm used with fixed-point data is:
+
+ <pre>
+ pDst[n] = (pSrc[n] * scaleFract) << shift, 0 <= n < blockSize.
+ </pre>
+
+ The overall scale factor applied to the fixed-point data is
+ <pre>
+ scale = scaleFract * 2^shift.
+ </pre>
+
+ The functions support in-place computation allowing the source and destination
+ pointers to reference the same memory buffer.
*/
/**
- * @addtogroup scale
- * @{
+ @addtogroup BasicScale
+ @{
*/
/**
- * @brief Multiplies a floating-point vector by a scalar.
- * @param[in] *pSrc points to the input vector
- * @param[in] scale scale factor to be applied
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
+ @brief Multiplies a floating-point vector by a scalar.
+ @param[in] pSrc points to the input vector
+ @param[in] scale scale factor to be applied
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
*/
-
void arm_scale_f32(
- float32_t * pSrc,
- float32_t scale,
- float32_t * pDst,
- uint32_t blockSize)
+ const float32_t *pSrc,
+ float32_t scale,
+ float32_t *pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+#if defined(ARM_MATH_NEON_EXPERIMENTAL)
+ float32x4_t vec1;
+ float32x4_t res;
+
+ /* Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
+
+ while (blkCnt > 0U)
+ {
+ /* C = A * scale */
+
+ /* Scale the input and then store the results in the destination buffer. */
+ vec1 = vld1q_f32(pSrc);
+ res = vmulq_f32(vec1, vdupq_n_f32(scale));
+ vst1q_f32(pDst, res);
+
+ /* Increment pointers */
+ pSrc += 4;
+ pDst += 4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Tail */
+ blkCnt = blockSize & 0x3;
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t in1, in2, in3, in4; /* temporary variabels */
+#else
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A * scale */
- /* Scale the input and then store the results in the destination buffer. */
- /* read input samples from source */
- in1 = *pSrc;
- in2 = *(pSrc + 1);
-
- /* multiply with scaling factor */
- in1 = in1 * scale;
- /* read input sample from source */
- in3 = *(pSrc + 2);
-
- /* multiply with scaling factor */
- in2 = in2 * scale;
+ /* Scale input and store result in destination buffer. */
+ *pDst++ = (*pSrc++) * scale;
- /* read input sample from source */
- in4 = *(pSrc + 3);
+ *pDst++ = (*pSrc++) * scale;
- /* multiply with scaling factor */
- in3 = in3 * scale;
- in4 = in4 * scale;
- /* store the result to destination */
- *pDst = in1;
- *(pDst + 1) = in2;
- *(pDst + 2) = in3;
- *(pDst + 3) = in4;
+ *pDst++ = (*pSrc++) * scale;
- /* update pointers to process next samples */
- pSrc += 4U;
- pDst += 4U;
+ *pDst++ = (*pSrc++) * scale;
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+#endif /* #if defined(ARM_MATH_NEON_EXPERIMENTAL) */
while (blkCnt > 0U)
{
/* C = A * scale */
- /* Scale the input and then store the result in the destination buffer. */
+
+ /* Scale input and store result in destination buffer. */
*pDst++ = (*pSrc++) * scale;
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of scale group
+ @} end of BasicScale group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_scale_q15.c b/DSP/Source/BasicMathFunctions/arm_scale_q15.c
index 9d5727d..039b93d 100644
--- a/DSP/Source/BasicMathFunctions/arm_scale_q15.c
+++ b/DSP/Source/BasicMathFunctions/arm_scale_q15.c
@@ -3,13 +3,13 @@
* Title: arm_scale_q15.c
* Description: Multiplies a Q15 vector by a scalar
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,66 +29,66 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup scale
- * @{
+ @addtogroup BasicScale
+ @{
*/
/**
- * @brief Multiplies a Q15 vector by a scalar.
- * @param[in] *pSrc points to the input vector
- * @param[in] scaleFract fractional portion of the scale value
- * @param[in] shift number of bits to shift the result by
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.15 format.
- * These are multiplied to yield a 2.30 intermediate result and this is shifted with saturation to 1.15 format.
+ @brief Multiplies a Q15 vector by a scalar.
+ @param[in] pSrc points to the input vector
+ @param[in] scaleFract fractional portion of the scale value
+ @param[in] shift number of bits to shift the result by
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.15 format.
+ These are multiplied to yield a 2.30 intermediate result and this is shifted with saturation to 1.15 format.
*/
-
void arm_scale_q15(
- q15_t * pSrc,
- q15_t scaleFract,
- int8_t shift,
- q15_t * pDst,
- uint32_t blockSize)
+ const q15_t *pSrc,
+ q15_t scaleFract,
+ int8_t shift,
+ q15_t *pDst,
+ uint32_t blockSize)
{
- int8_t kShift = 15 - shift; /* shift to apply after scaling */
- uint32_t blkCnt; /* loop counter */
+ uint32_t blkCnt; /* Loop counter */
+ int8_t kShift = 15 - shift; /* Shift to apply after scaling */
+#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
+ q31_t inA1, inA2;
+ q31_t out1, out2, out3, out4; /* Temporary output variables */
+ q15_t in1, in2, in3, in4; /* Temporary input variables */
+#endif
+#endif
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q15_t in1, in2, in3, in4;
- q31_t inA1, inA2; /* Temporary variables */
- q31_t out1, out2, out3, out4;
-
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
- /* Reading 2 inputs from memory */
- inA1 = *__SIMD32(pSrc)++;
- inA2 = *__SIMD32(pSrc)++;
-
/* C = A * scale */
- /* Scale the inputs and then store the 2 results in the destination buffer
+
+#if defined (ARM_MATH_DSP)
+ /* read 2 times 2 samples at a time from source */
+ inA1 = read_q15x2_ia ((q15_t **) &pSrc);
+ inA2 = read_q15x2_ia ((q15_t **) &pSrc);
+
+ /* Scale inputs and store result in temporary variables
* in single cycle by packing the outputs */
out1 = (q31_t) ((q15_t) (inA1 >> 16) * scaleFract);
- out2 = (q31_t) ((q15_t) inA1 * scaleFract);
+ out2 = (q31_t) ((q15_t) (inA1 ) * scaleFract);
out3 = (q31_t) ((q15_t) (inA2 >> 16) * scaleFract);
- out4 = (q31_t) ((q15_t) inA2 * scaleFract);
+ out4 = (q31_t) ((q15_t) (inA2 ) * scaleFract);
/* apply shifting */
out1 = out1 >> kShift;
@@ -102,49 +102,43 @@ void arm_scale_q15(
in3 = (q15_t) (__SSAT(out3, 16));
in4 = (q15_t) (__SSAT(out4, 16));
- /* store the result to destination */
- *__SIMD32(pDst)++ = __PKHBT(in2, in1, 16);
- *__SIMD32(pDst)++ = __PKHBT(in4, in3, 16);
+ /* store result to destination */
+ write_q15x2_ia (&pDst, __PKHBT(in2, in1, 16));
+ write_q15x2_ia (&pDst, __PKHBT(in4, in3, 16));
+#else
+ *pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16));
+ *pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16));
+ *pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16));
+ *pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16));
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
- while (blkCnt > 0U)
- {
- /* C = A * scale */
- /* Scale the input and then store the result in the destination buffer. */
- *pDst++ = (q15_t) (__SSAT(((*pSrc++) * scaleFract) >> kShift, 16));
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A * scale */
- /* Scale the input and then store the result in the destination buffer. */
- *pDst++ = (q15_t) (__SSAT(((q31_t) * pSrc++ * scaleFract) >> kShift, 16));
- /* Decrement the loop counter */
+ /* Scale input and store result in destination buffer. */
+ *pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16));
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
}
/**
- * @} end of scale group
+ @} end of BasicScale group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_scale_q31.c b/DSP/Source/BasicMathFunctions/arm_scale_q31.c
index e89524d..d762ca7 100644
--- a/DSP/Source/BasicMathFunctions/arm_scale_q31.c
+++ b/DSP/Source/BasicMathFunctions/arm_scale_q31.c
@@ -3,13 +3,13 @@
* Title: arm_scale_q31.c
* Description: Multiplies a Q31 vector by a scalar
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,199 +29,163 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup scale
- * @{
+ @addtogroup BasicScale
+ @{
*/
/**
- * @brief Multiplies a Q31 vector by a scalar.
- * @param[in] *pSrc points to the input vector
- * @param[in] scaleFract fractional portion of the scale value
- * @param[in] shift number of bits to shift the result by
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.31 format.
- * These are multiplied to yield a 2.62 intermediate result and this is shifted with saturation to 1.31 format.
+ @brief Multiplies a Q31 vector by a scalar.
+ @param[in] pSrc points to the input vector
+ @param[in] scaleFract fractional portion of the scale value
+ @param[in] shift number of bits to shift the result by
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.31 format.
+ These are multiplied to yield a 2.62 intermediate result and this is shifted with saturation to 1.31 format.
*/
void arm_scale_q31(
- q31_t * pSrc,
- q31_t scaleFract,
- int8_t shift,
- q31_t * pDst,
- uint32_t blockSize)
+ const q31_t *pSrc,
+ q31_t scaleFract,
+ int8_t shift,
+ q31_t *pDst,
+ uint32_t blockSize)
{
- int8_t kShift = shift + 1; /* Shift to apply after scaling */
- int8_t sign = (kShift & 0x80);
- uint32_t blkCnt; /* loop counter */
- q31_t in, out;
-
-#if defined (ARM_MATH_DSP)
-
-/* Run the below code for Cortex-M4 and Cortex-M3 */
+ uint32_t blkCnt; /* Loop counter */
+ q31_t in, out; /* Temporary variables */
+ int8_t kShift = shift + 1; /* Shift to apply after scaling */
+ int8_t sign = (kShift & 0x80);
- q31_t in1, in2, in3, in4; /* temporary input variables */
- q31_t out1, out2, out3, out4; /* temporary output variabels */
+#if defined (ARM_MATH_LOOPUNROLL)
-
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
if (sign == 0U)
{
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
- /* read four inputs from source */
- in1 = *pSrc;
- in2 = *(pSrc + 1);
- in3 = *(pSrc + 2);
- in4 = *(pSrc + 3);
-
- /* multiply input with scaler value */
- in1 = ((q63_t) in1 * scaleFract) >> 32;
- in2 = ((q63_t) in2 * scaleFract) >> 32;
- in3 = ((q63_t) in3 * scaleFract) >> 32;
- in4 = ((q63_t) in4 * scaleFract) >> 32;
-
- /* apply shifting */
- out1 = in1 << kShift;
- out2 = in2 << kShift;
-
- /* saturate the results. */
- if (in1 != (out1 >> kShift))
- out1 = 0x7FFFFFFF ^ (in1 >> 31);
-
- if (in2 != (out2 >> kShift))
- out2 = 0x7FFFFFFF ^ (in2 >> 31);
-
- out3 = in3 << kShift;
- out4 = in4 << kShift;
-
- *pDst = out1;
- *(pDst + 1) = out2;
-
- if (in3 != (out3 >> kShift))
- out3 = 0x7FFFFFFF ^ (in3 >> 31);
-
- if (in4 != (out4 >> kShift))
- out4 = 0x7FFFFFFF ^ (in4 >> 31);
-
- /* Store result destination */
- *(pDst + 2) = out3;
- *(pDst + 3) = out4;
-
- /* Update pointers to process next sampels */
- pSrc += 4U;
- pDst += 4U;
-
- /* Decrement the loop counter */
+ /* C = A * scale */
+
+ /* Scale input and store result in destination buffer. */
+ in = *pSrc++; /* read input from source */
+ in = ((q63_t) in * scaleFract) >> 32; /* multiply input with scaler value */
+ out = in << kShift; /* apply shifting */
+ if (in != (out >> kShift)) /* saturate the result */
+ out = 0x7FFFFFFF ^ (in >> 31);
+ *pDst++ = out; /* Store result destination */
+
+ in = *pSrc++;
+ in = ((q63_t) in * scaleFract) >> 32;
+ out = in << kShift;
+ if (in != (out >> kShift))
+ out = 0x7FFFFFFF ^ (in >> 31);
+ *pDst++ = out;
+
+ in = *pSrc++;
+ in = ((q63_t) in * scaleFract) >> 32;
+ out = in << kShift;
+ if (in != (out >> kShift))
+ out = 0x7FFFFFFF ^ (in >> 31);
+ *pDst++ = out;
+
+ in = *pSrc++;
+ in = ((q63_t) in * scaleFract) >> 32;
+ out = in << kShift;
+ if (in != (out >> kShift))
+ out = 0x7FFFFFFF ^ (in >> 31);
+ *pDst++ = out;
+
+ /* Decrement loop counter */
blkCnt--;
}
-
}
else
{
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
- /* read four inputs from source */
- in1 = *pSrc;
- in2 = *(pSrc + 1);
- in3 = *(pSrc + 2);
- in4 = *(pSrc + 3);
-
- /* multiply input with scaler value */
- in1 = ((q63_t) in1 * scaleFract) >> 32;
- in2 = ((q63_t) in2 * scaleFract) >> 32;
- in3 = ((q63_t) in3 * scaleFract) >> 32;
- in4 = ((q63_t) in4 * scaleFract) >> 32;
-
- /* apply shifting */
- out1 = in1 >> -kShift;
- out2 = in2 >> -kShift;
-
- out3 = in3 >> -kShift;
- out4 = in4 >> -kShift;
-
- /* Store result destination */
- *pDst = out1;
- *(pDst + 1) = out2;
-
- *(pDst + 2) = out3;
- *(pDst + 3) = out4;
-
- /* Update pointers to process next sampels */
- pSrc += 4U;
- pDst += 4U;
-
- /* Decrement the loop counter */
+ /* C = A * scale */
+
+ /* Scale input and store result in destination buffer. */
+ in = *pSrc++; /* read four inputs from source */
+ in = ((q63_t) in * scaleFract) >> 32; /* multiply input with scaler value */
+ out = in >> -kShift; /* apply shifting */
+ *pDst++ = out; /* Store result destination */
+
+ in = *pSrc++;
+ in = ((q63_t) in * scaleFract) >> 32;
+ out = in >> -kShift;
+ *pDst++ = out;
+
+ in = *pSrc++;
+ in = ((q63_t) in * scaleFract) >> 32;
+ out = in >> -kShift;
+ *pDst++ = out;
+
+ in = *pSrc++;
+ in = ((q63_t) in * scaleFract) >> 32;
+ out = in >> -kShift;
+ *pDst++ = out;
+
+ /* Decrement loop counter */
blkCnt--;
}
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
- if (sign == 0)
+ if (sign == 0U)
{
- while (blkCnt > 0U)
- {
- /* C = A * scale */
- /* Scale the input and then store the result in the destination buffer. */
- in = *pSrc++;
- in = ((q63_t) in * scaleFract) >> 32;
-
- out = in << kShift;
-
- if (in != (out >> kShift))
- out = 0x7FFFFFFF ^ (in >> 31);
+ while (blkCnt > 0U)
+ {
+ /* C = A * scale */
- *pDst++ = out;
+ /* Scale input and store result in destination buffer. */
+ in = *pSrc++;
+ in = ((q63_t) in * scaleFract) >> 32;
+ out = in << kShift;
+ if (in != (out >> kShift))
+ out = 0x7FFFFFFF ^ (in >> 31);
+ *pDst++ = out;
- /* Decrement the loop counter */
- blkCnt--;
- }
+ /* Decrement loop counter */
+ blkCnt--;
+ }
}
else
{
- while (blkCnt > 0U)
- {
- /* C = A * scale */
- /* Scale the input and then store the result in the destination buffer. */
- in = *pSrc++;
- in = ((q63_t) in * scaleFract) >> 32;
-
- out = in >> -kShift;
-
- *pDst++ = out;
+ while (blkCnt > 0U)
+ {
+ /* C = A * scale */
- /* Decrement the loop counter */
- blkCnt--;
- }
+ /* Scale input and store result in destination buffer. */
+ in = *pSrc++;
+ in = ((q63_t) in * scaleFract) >> 32;
+ out = in >> -kShift;
+ *pDst++ = out;
+ /* Decrement loop counter */
+ blkCnt--;
+ }
}
+
}
/**
- * @} end of scale group
+ @} end of BasicScale group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_scale_q7.c b/DSP/Source/BasicMathFunctions/arm_scale_q7.c
index 6cf1bbb..cb967d2 100644
--- a/DSP/Source/BasicMathFunctions/arm_scale_q7.c
+++ b/DSP/Source/BasicMathFunctions/arm_scale_q7.c
@@ -3,13 +3,13 @@
* Title: arm_scale_q7.c
* Description: Multiplies a Q7 vector by a scalar
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,109 +29,101 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup scale
- * @{
+ @addtogroup BasicScale
+ @{
*/
/**
- * @brief Multiplies a Q7 vector by a scalar.
- * @param[in] *pSrc points to the input vector
- * @param[in] scaleFract fractional portion of the scale value
- * @param[in] shift number of bits to shift the result by
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.7 format.
- * These are multiplied to yield a 2.14 intermediate result and this is shifted with saturation to 1.7 format.
+ @brief Multiplies a Q7 vector by a scalar.
+ @param[in] pSrc points to the input vector
+ @param[in] scaleFract fractional portion of the scale value
+ @param[in] shift number of bits to shift the result by
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.7 format.
+ These are multiplied to yield a 2.14 intermediate result and this is shifted with saturation to 1.7 format.
*/
void arm_scale_q7(
- q7_t * pSrc,
- q7_t scaleFract,
- int8_t shift,
- q7_t * pDst,
- uint32_t blockSize)
+ const q7_t * pSrc,
+ q7_t scaleFract,
+ int8_t shift,
+ q7_t * pDst,
+ uint32_t blockSize)
{
- int8_t kShift = 7 - shift; /* shift to apply after scaling */
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+ int8_t kShift = 7 - shift; /* Shift to apply after scaling */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q7_t in1, in2, in3, in4, out1, out2, out3, out4; /* Temporary variables to store input & output */
+#if defined (ARM_MATH_LOOPUNROLL)
+#if defined (ARM_MATH_DSP)
+ q7_t in1, in2, in3, in4; /* Temporary input variables */
+ q7_t out1, out2, out3, out4; /* Temporary output variables */
+#endif
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
+ /* C = A * scale */
+
+#if defined (ARM_MATH_DSP)
/* Reading 4 inputs from memory */
in1 = *pSrc++;
in2 = *pSrc++;
in3 = *pSrc++;
in4 = *pSrc++;
- /* C = A * scale */
- /* Scale the inputs and then store the results in the temporary variables. */
+ /* Scale inputs and store result in the temporary variable. */
out1 = (q7_t) (__SSAT(((in1) * scaleFract) >> kShift, 8));
out2 = (q7_t) (__SSAT(((in2) * scaleFract) >> kShift, 8));
out3 = (q7_t) (__SSAT(((in3) * scaleFract) >> kShift, 8));
out4 = (q7_t) (__SSAT(((in4) * scaleFract) >> kShift, 8));
- /* Packing the individual outputs into 32bit and storing in
- * destination buffer in single write */
- *__SIMD32(pDst)++ = __PACKq7(out1, out2, out3, out4);
+ /* Pack and store result in destination buffer (in single write) */
+ write_q7x4_ia (&pDst, __PACKq7(out1, out2, out3, out4));
+#else
+ *pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8));
+ *pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8));
+ *pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8));
+ *pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8));
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
- while (blkCnt > 0U)
- {
- /* C = A * scale */
- /* Scale the input and then store the result in the destination buffer. */
- *pDst++ = (q7_t) (__SSAT(((*pSrc++) * scaleFract) >> kShift, 8));
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A * scale */
- /* Scale the input and then store the result in the destination buffer. */
- *pDst++ = (q7_t) (__SSAT((((q15_t) * pSrc++ * scaleFract) >> kShift), 8));
- /* Decrement the loop counter */
+ /* Scale input and store result in destination buffer. */
+ *pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8));
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
}
/**
- * @} end of scale group
+ @} end of BasicScale group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_shift_q15.c b/DSP/Source/BasicMathFunctions/arm_shift_q15.c
index d2cd037..8a15155 100644
--- a/DSP/Source/BasicMathFunctions/arm_shift_q15.c
+++ b/DSP/Source/BasicMathFunctions/arm_shift_q15.c
@@ -3,13 +3,13 @@
* Title: arm_shift_q15.c
* Description: Shifts the elements of a Q15 vector by a specified number of bits
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,208 +29,173 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup shift
- * @{
+ @addtogroup BasicShift
+ @{
*/
/**
- * @brief Shifts the elements of a Q15 vector a specified number of bits.
- * @param[in] *pSrc points to the input vector
- * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
+ @brief Shifts the elements of a Q15 vector a specified number of bits
+ @param[in] pSrc points to the input vector
+ @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
*/
void arm_shift_q15(
- q15_t * pSrc,
- int8_t shiftBits,
- q15_t * pDst,
- uint32_t blockSize)
+ const q15_t * pSrc,
+ int8_t shiftBits,
+ q15_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
- uint8_t sign; /* Sign of shiftBits */
-
-#if defined (ARM_MATH_DSP)
-
-/* Run the below code for Cortex-M4 and Cortex-M3 */
+ uint32_t blkCnt; /* Loop counter */
+ uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */
- q15_t in1, in2; /* Temporary variables */
+#if defined (ARM_MATH_LOOPUNROLL)
+#if defined (ARM_MATH_DSP)
+ q15_t in1, in2; /* Temporary input variables */
+#endif
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* Getting the sign of shiftBits */
- sign = (shiftBits & 0x80);
-
/* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
- /* Read 2 inputs */
- in1 = *pSrc++;
- in2 = *pSrc++;
/* C = A << shiftBits */
- /* Shift the inputs and then store the results in the destination buffer. */
-#ifndef ARM_MATH_BIG_ENDIAN
- *__SIMD32(pDst)++ = __PKHBT(__SSAT((in1 << shiftBits), 16),
- __SSAT((in2 << shiftBits), 16), 16);
+#if defined (ARM_MATH_DSP)
+ /* read 2 samples from source */
+ in1 = *pSrc++;
+ in2 = *pSrc++;
+ /* Shift the inputs and then store the results in the destination buffer. */
+#ifndef ARM_MATH_BIG_ENDIAN
+ write_q15x2_ia (&pDst, __PKHBT(__SSAT((in1 << shiftBits), 16),
+ __SSAT((in2 << shiftBits), 16), 16));
#else
+ write_q15x2_ia (&pDst, __PKHBT(__SSAT((in2 << shiftBits), 16),
+ __SSAT((in1 << shiftBits), 16), 16));
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
- *__SIMD32(pDst)++ = __PKHBT(__SSAT((in2 << shiftBits), 16),
- __SSAT((in1 << shiftBits), 16), 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
+ /* read 2 samples from source */
in1 = *pSrc++;
in2 = *pSrc++;
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *__SIMD32(pDst)++ = __PKHBT(__SSAT((in1 << shiftBits), 16),
- __SSAT((in2 << shiftBits), 16), 16);
-
+#ifndef ARM_MATH_BIG_ENDIAN
+ write_q15x2_ia (&pDst, __PKHBT(__SSAT((in1 << shiftBits), 16),
+ __SSAT((in2 << shiftBits), 16), 16));
#else
+ write_q15x2_ia (&pDst, __PKHBT(__SSAT((in2 << shiftBits), 16),
+ __SSAT((in1 << shiftBits), 16), 16));
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
- *__SIMD32(pDst)++ = __PKHBT(__SSAT((in2 << shiftBits), 16),
- __SSAT((in1 << shiftBits), 16), 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4U;
-
- while (blkCnt > 0U)
- {
- /* C = A << shiftBits */
- /* Shift and then store the results in the destination buffer. */
- *pDst++ = __SSAT((*pSrc++ << shiftBits), 16);
+#else
+ *pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16);
+ *pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16);
+ *pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16);
+ *pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
}
else
{
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
- /* Read 2 inputs */
+ /* C = A >> shiftBits */
+
+#if defined (ARM_MATH_DSP)
+ /* read 2 samples from source */
in1 = *pSrc++;
in2 = *pSrc++;
- /* C = A >> shiftBits */
/* Shift the inputs and then store the results in the destination buffer. */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *__SIMD32(pDst)++ = __PKHBT((in1 >> -shiftBits),
- (in2 >> -shiftBits), 16);
-
+#ifndef ARM_MATH_BIG_ENDIAN
+ write_q15x2_ia (&pDst, __PKHBT((in1 >> -shiftBits),
+ (in2 >> -shiftBits), 16));
#else
+ write_q15x2_ia (&pDst, __PKHBT((in2 >> -shiftBits),
+ (in1 >> -shiftBits), 16));
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
- *__SIMD32(pDst)++ = __PKHBT((in2 >> -shiftBits),
- (in1 >> -shiftBits), 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
+ /* read 2 samples from source */
in1 = *pSrc++;
in2 = *pSrc++;
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *__SIMD32(pDst)++ = __PKHBT((in1 >> -shiftBits),
- (in2 >> -shiftBits), 16);
-
+#ifndef ARM_MATH_BIG_ENDIAN
+ write_q15x2_ia (&pDst, __PKHBT((in1 >> -shiftBits),
+ (in2 >> -shiftBits), 16));
#else
+ write_q15x2_ia (&pDst, __PKHBT((in2 >> -shiftBits),
+ (in1 >> -shiftBits), 16));
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
- *__SIMD32(pDst)++ = __PKHBT((in2 >> -shiftBits),
- (in1 >> -shiftBits), 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4U;
-
- while (blkCnt > 0U)
- {
- /* C = A >> shiftBits */
- /* Shift the inputs and then store the results in the destination buffer. */
+#else
+ *pDst++ = (*pSrc++ >> -shiftBits);
+ *pDst++ = (*pSrc++ >> -shiftBits);
+ *pDst++ = (*pSrc++ >> -shiftBits);
*pDst++ = (*pSrc++ >> -shiftBits);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
}
+ /* Loop unrolling: Compute remaining outputs */
+ blkCnt = blockSize % 0x4U;
+
#else
- /* Run the below code for Cortex-M0 */
+ /* Initialize blkCnt with number of samples */
+ blkCnt = blockSize;
- /* Getting the sign of shiftBits */
- sign = (shiftBits & 0x80);
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
/* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
- /* Initialize blkCnt with number of samples */
- blkCnt = blockSize;
-
while (blkCnt > 0U)
{
/* C = A << shiftBits */
- /* Shift and then store the results in the destination buffer. */
- *pDst++ = __SSAT(((q31_t) * pSrc++ << shiftBits), 16);
- /* Decrement the loop counter */
+ /* Shift input and store result in destination buffer. */
+ *pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16);
+
+ /* Decrement loop counter */
blkCnt--;
}
}
else
{
- /* Initialize blkCnt with number of samples */
- blkCnt = blockSize;
-
while (blkCnt > 0U)
{
/* C = A >> shiftBits */
- /* Shift the inputs and then store the results in the destination buffer. */
+
+ /* Shift input and store result in destination buffer. */
*pDst++ = (*pSrc++ >> -shiftBits);
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
}
/**
- * @} end of shift group
+ @} end of BasicShift group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_shift_q31.c b/DSP/Source/BasicMathFunctions/arm_shift_q31.c
index 7e728d4..db6060a 100644
--- a/DSP/Source/BasicMathFunctions/arm_shift_q31.c
+++ b/DSP/Source/BasicMathFunctions/arm_shift_q31.c
@@ -3,13 +3,13 @@
* Title: arm_shift_q31.c
* Description: Shifts the elements of a Q31 vector by a specified number of bits
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,163 +29,153 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @defgroup shift Vector Shift
- *
- * Shifts the elements of a fixed-point vector by a specified number of bits.
- * There are separate functions for Q7, Q15, and Q31 data types.
- * The underlying algorithm used is:
- *
- * <pre>
- * pDst[n] = pSrc[n] << shift, 0 <= n < blockSize.
- * </pre>
- *
- * If <code>shift</code> is positive then the elements of the vector are shifted to the left.
- * If <code>shift</code> is negative then the elements of the vector are shifted to the right.
- *
- * The functions support in-place computation allowing the source and destination
- * pointers to reference the same memory buffer.
+ @defgroup BasicShift Vector Shift
+
+ Shifts the elements of a fixed-point vector by a specified number of bits.
+ There are separate functions for Q7, Q15, and Q31 data types.
+ The underlying algorithm used is:
+
+ <pre>
+ pDst[n] = pSrc[n] << shift, 0 <= n < blockSize.
+ </pre>
+
+ If <code>shift</code> is positive then the elements of the vector are shifted to the left.
+ If <code>shift</code> is negative then the elements of the vector are shifted to the right.
+
+ The functions support in-place computation allowing the source and destination
+ pointers to reference the same memory buffer.
*/
/**
- * @addtogroup shift
- * @{
+ @addtogroup BasicShift
+ @{
*/
/**
- * @brief Shifts the elements of a Q31 vector a specified number of bits.
- * @param[in] *pSrc points to the input vector
- * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
+ @brief Shifts the elements of a Q31 vector a specified number of bits.
+ @param[in] pSrc points to the input vector
+ @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in the vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
*/
void arm_shift_q31(
- q31_t * pSrc,
- int8_t shiftBits,
- q31_t * pDst,
- uint32_t blockSize)
+ const q31_t * pSrc,
+ int8_t shiftBits,
+ q31_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
- uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */
+ uint32_t blkCnt; /* Loop counter */
+ uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */
-#if defined (ARM_MATH_DSP)
+#if defined (ARM_MATH_LOOPUNROLL)
- q31_t in1, in2, in3, in4; /* Temporary input variables */
- q31_t out1, out2, out3, out4; /* Temporary output variables */
+ q31_t in, out; /* Temporary variables */
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
-
+ /* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
- /* C = A << shiftBits */
- /* Shift the input and then store the results in the destination buffer. */
- in1 = *pSrc;
- in2 = *(pSrc + 1);
- out1 = in1 << shiftBits;
- in3 = *(pSrc + 2);
- out2 = in2 << shiftBits;
- in4 = *(pSrc + 3);
- if (in1 != (out1 >> shiftBits))
- out1 = 0x7FFFFFFF ^ (in1 >> 31);
-
- if (in2 != (out2 >> shiftBits))
- out2 = 0x7FFFFFFF ^ (in2 >> 31);
-
- *pDst = out1;
- out3 = in3 << shiftBits;
- *(pDst + 1) = out2;
- out4 = in4 << shiftBits;
-
- if (in3 != (out3 >> shiftBits))
- out3 = 0x7FFFFFFF ^ (in3 >> 31);
-
- if (in4 != (out4 >> shiftBits))
- out4 = 0x7FFFFFFF ^ (in4 >> 31);
-
- *(pDst + 2) = out3;
- *(pDst + 3) = out4;
-
- /* Update destination pointer to process next sampels */
- pSrc += 4U;
- pDst += 4U;
-
- /* Decrement the loop counter */
+ /* C = A << shiftBits */
+
+ /* Shift input and store result in destination buffer. */
+ in = *pSrc++;
+ out = in << shiftBits;
+ if (in != (out >> shiftBits))
+ out = 0x7FFFFFFF ^ (in >> 31);
+ *pDst++ = out;
+
+ in = *pSrc++;
+ out = in << shiftBits;
+ if (in != (out >> shiftBits))
+ out = 0x7FFFFFFF ^ (in >> 31);
+ *pDst++ = out;
+
+ in = *pSrc++;
+ out = in << shiftBits;
+ if (in != (out >> shiftBits))
+ out = 0x7FFFFFFF ^ (in >> 31);
+ *pDst++ = out;
+
+ in = *pSrc++;
+ out = in << shiftBits;
+ if (in != (out >> shiftBits))
+ out = 0x7FFFFFFF ^ (in >> 31);
+ *pDst++ = out;
+
+ /* Decrement loop counter */
blkCnt--;
}
}
else
{
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
- /* C = A >> shiftBits */
- /* Shift the input and then store the results in the destination buffer. */
- in1 = *pSrc;
- in2 = *(pSrc + 1);
- in3 = *(pSrc + 2);
- in4 = *(pSrc + 3);
+ /* C = A >> shiftBits */
- *pDst = (in1 >> -shiftBits);
- *(pDst + 1) = (in2 >> -shiftBits);
- *(pDst + 2) = (in3 >> -shiftBits);
- *(pDst + 3) = (in4 >> -shiftBits);
-
-
- pSrc += 4U;
- pDst += 4U;
+ /* Shift input and store results in destination buffer. */
+ *pDst++ = (*pSrc++ >> -shiftBits);
+ *pDst++ = (*pSrc++ >> -shiftBits);
+ *pDst++ = (*pSrc++ >> -shiftBits);
+ *pDst++ = (*pSrc++ >> -shiftBits);
+ /* Decrement loop counter */
blkCnt--;
}
-
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
-
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
- while (blkCnt > 0U)
+ /* If the shift value is positive then do right shift else left shift */
+ if (sign == 0U)
{
- /* C = A (>> or <<) shiftBits */
- /* Shift the input and then store the result in the destination buffer. */
- *pDst++ = (sign == 0U) ? clip_q63_to_q31((q63_t) * pSrc++ << shiftBits) :
- (*pSrc++ >> -shiftBits);
+ while (blkCnt > 0U)
+ {
+ /* C = A << shiftBits */
+
+ /* Shift input and store result in destination buffer. */
+ *pDst++ = clip_q63_to_q31((q63_t) *pSrc++ << shiftBits);
- /* Decrement the loop counter */
- blkCnt--;
+ /* Decrement loop counter */
+ blkCnt--;
+ }
}
+ else
+ {
+ while (blkCnt > 0U)
+ {
+ /* C = A >> shiftBits */
+ /* Shift input and store result in destination buffer. */
+ *pDst++ = (*pSrc++ >> -shiftBits);
+
+ /* Decrement loop counter */
+ blkCnt--;
+ }
+ }
}
/**
- * @} end of shift group
+ @} end of BasicShift group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_shift_q7.c b/DSP/Source/BasicMathFunctions/arm_shift_q7.c
index fd508b4..c4163fc 100644
--- a/DSP/Source/BasicMathFunctions/arm_shift_q7.c
+++ b/DSP/Source/BasicMathFunctions/arm_shift_q7.c
@@ -3,13 +3,13 @@
* Title: arm_shift_q7.c
* Description: Processing function for the Q7 Shifting
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,180 +29,147 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup shift
- * @{
+ @addtogroup BasicShift
+ @{
*/
-
/**
- * @brief Shifts the elements of a Q7 vector a specified number of bits.
- * @param[in] *pSrc points to the input vector
- * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in the vector
- * @return none.
- *
- * \par Conditions for optimum performance
- * Input and output buffers should be aligned by 32-bit
- *
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q7 range [0x8 0x7F] will be saturated.
+ @brief Shifts the elements of a Q7 vector a specified number of bits
+ @param[in] pSrc points to the input vector
+ @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par onditions for optimum performance
+ Input and output buffers should be aligned by 32-bit
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
*/
void arm_shift_q7(
- q7_t * pSrc,
- int8_t shiftBits,
- q7_t * pDst,
- uint32_t blockSize)
+ const q7_t * pSrc,
+ int8_t shiftBits,
+ q7_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
- uint8_t sign; /* Sign of shiftBits */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+ uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q7_t in1; /* Input value1 */
- q7_t in2; /* Input value2 */
- q7_t in3; /* Input value3 */
- q7_t in4; /* Input value4 */
+#if defined (ARM_MATH_LOOPUNROLL)
+#if defined (ARM_MATH_DSP)
+ q7_t in1, in2, in3, in4; /* Temporary input variables */
+#endif
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* Getting the sign of shiftBits */
- sign = (shiftBits & 0x80);
-
/* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A << shiftBits */
- /* Read 4 inputs */
- in1 = *pSrc;
- in2 = *(pSrc + 1);
- in3 = *(pSrc + 2);
- in4 = *(pSrc + 3);
-
- /* Store the Shifted result in the destination buffer in single cycle by packing the outputs */
- *__SIMD32(pDst)++ = __PACKq7(__SSAT((in1 << shiftBits), 8),
- __SSAT((in2 << shiftBits), 8),
- __SSAT((in3 << shiftBits), 8),
- __SSAT((in4 << shiftBits), 8));
- /* Update source pointer to process next sampels */
- pSrc += 4U;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4U;
-
- while (blkCnt > 0U)
- {
- /* C = A << shiftBits */
- /* Shift the input and then store the result in the destination buffer. */
- *pDst++ = (q7_t) __SSAT((*pSrc++ << shiftBits), 8);
+#if defined (ARM_MATH_DSP)
+ /* Read 4 inputs */
+ in1 = *pSrc++;
+ in2 = *pSrc++;
+ in3 = *pSrc++;
+ in4 = *pSrc++;
+
+ /* Pack and store result in destination buffer (in single write) */
+ write_q7x4_ia (&pDst, __PACKq7(__SSAT((in1 << shiftBits), 8),
+ __SSAT((in2 << shiftBits), 8),
+ __SSAT((in3 << shiftBits), 8),
+ __SSAT((in4 << shiftBits), 8) ));
+#else
+ *pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8);
+ *pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8);
+ *pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8);
+ *pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
}
else
{
- shiftBits = -shiftBits;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A >> shiftBits */
- /* Read 4 inputs */
- in1 = *pSrc;
- in2 = *(pSrc + 1);
- in3 = *(pSrc + 2);
- in4 = *(pSrc + 3);
-
- /* Store the Shifted result in the destination buffer in single cycle by packing the outputs */
- *__SIMD32(pDst)++ = __PACKq7((in1 >> shiftBits), (in2 >> shiftBits),
- (in3 >> shiftBits), (in4 >> shiftBits));
-
- pSrc += 4U;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4U;
-
- while (blkCnt > 0U)
- {
- /* C = A >> shiftBits */
- /* Shift the input and then store the result in the destination buffer. */
+#if defined (ARM_MATH_DSP)
+ /* Read 4 inputs */
in1 = *pSrc++;
- *pDst++ = (in1 >> shiftBits);
+ in2 = *pSrc++;
+ in3 = *pSrc++;
+ in4 = *pSrc++;
+
+ /* Pack and store result in destination buffer (in single write) */
+ write_q7x4_ia (&pDst, __PACKq7((in1 >> -shiftBits),
+ (in2 >> -shiftBits),
+ (in3 >> -shiftBits),
+ (in4 >> -shiftBits) ));
+#else
+ *pDst++ = (*pSrc++ >> -shiftBits);
+ *pDst++ = (*pSrc++ >> -shiftBits);
+ *pDst++ = (*pSrc++ >> -shiftBits);
+ *pDst++ = (*pSrc++ >> -shiftBits);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
}
+ /* Loop unrolling: Compute remaining outputs */
+ blkCnt = blockSize % 0x4U;
+
#else
- /* Run the below code for Cortex-M0 */
+ /* Initialize blkCnt with number of samples */
+ blkCnt = blockSize;
- /* Getting the sign of shiftBits */
- sign = (shiftBits & 0x80);
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
/* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
- /* Initialize blkCnt with number of samples */
- blkCnt = blockSize;
-
while (blkCnt > 0U)
{
/* C = A << shiftBits */
- /* Shift the input and then store the result in the destination buffer. */
- *pDst++ = (q7_t) __SSAT(((q15_t) * pSrc++ << shiftBits), 8);
- /* Decrement the loop counter */
+ /* Shift input and store result in destination buffer. */
+ *pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8);
+
+ /* Decrement loop counter */
blkCnt--;
}
}
else
{
- /* Initialize blkCnt with number of samples */
- blkCnt = blockSize;
-
while (blkCnt > 0U)
{
/* C = A >> shiftBits */
- /* Shift the input and then store the result in the destination buffer. */
+
+ /* Shift input and store result in destination buffer. */
*pDst++ = (*pSrc++ >> -shiftBits);
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
}
-#endif /* #if defined (ARM_MATH_DSP) */
}
/**
- * @} end of shift group
+ @} end of BasicShift group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_sub_f32.c b/DSP/Source/BasicMathFunctions/arm_sub_f32.c
index 74a2944..4c97af3 100644
--- a/DSP/Source/BasicMathFunctions/arm_sub_f32.c
+++ b/DSP/Source/BasicMathFunctions/arm_sub_f32.c
@@ -1,15 +1,15 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_sub_f32.c
- * Description: Floating-point vector subtraction.
+ * Description: Floating-point vector subtraction
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,110 +29,120 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @defgroup BasicSub Vector Subtraction
- *
- * Element-by-element subtraction of two vectors.
- *
- * <pre>
- * pDst[n] = pSrcA[n] - pSrcB[n], 0 <= n < blockSize.
- * </pre>
- *
- * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
+ @defgroup BasicSub Vector Subtraction
+
+ Element-by-element subtraction of two vectors.
+
+ <pre>
+ pDst[n] = pSrcA[n] - pSrcB[n], 0 <= n < blockSize.
+ </pre>
+
+ There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
- * @addtogroup BasicSub
- * @{
+ @addtogroup BasicSub
+ @{
*/
-
/**
- * @brief Floating-point vector subtraction.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
+ @brief Floating-point vector subtraction.
+ @param[in] pSrcA points to the first input vector
+ @param[in] pSrcB points to the second input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
*/
void arm_sub_f32(
- float32_t * pSrcA,
- float32_t * pSrcB,
- float32_t * pDst,
- uint32_t blockSize)
+ const float32_t * pSrcA,
+ const float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
+
+#if defined(ARM_MATH_NEON)
+ float32x4_t vec1;
+ float32x4_t vec2;
+ float32x4_t res;
+
+ /* Compute 4 outputs at a time */
+ blkCnt = blockSize >> 2U;
+
+ while (blkCnt > 0U)
+ {
+ /* C = A - B */
+
+ /* Subtract and then store the results in the destination buffer. */
+ vec1 = vld1q_f32(pSrcA);
+ vec2 = vld1q_f32(pSrcB);
+ res = vsubq_f32(vec1, vec2);
+ vst1q_f32(pDst, res);
+
+ /* Increment pointers */
+ pSrcA += 4;
+ pSrcB += 4;
+ pDst += 4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Tail */
+ blkCnt = blockSize & 0x3;
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t inA1, inA2, inA3, inA4; /* temporary variables */
- float32_t inB1, inB2, inB3, inB4; /* temporary variables */
+#else
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A - B */
- /* Subtract and then store the results in the destination buffer. */
- /* Read 4 input samples from sourceA and sourceB */
- inA1 = *pSrcA;
- inB1 = *pSrcB;
- inA2 = *(pSrcA + 1);
- inB2 = *(pSrcB + 1);
- inA3 = *(pSrcA + 2);
- inB3 = *(pSrcB + 2);
- inA4 = *(pSrcA + 3);
- inB4 = *(pSrcB + 3);
-
- /* dst = srcA - srcB */
- /* subtract and store the result */
- *pDst = inA1 - inB1;
- *(pDst + 1) = inA2 - inB2;
- *(pDst + 2) = inA3 - inB3;
- *(pDst + 3) = inA4 - inB4;
-
-
- /* Update pointers to process next sampels */
- pSrcA += 4U;
- pSrcB += 4U;
- pDst += 4U;
-
- /* Decrement the loop counter */
+
+ /* Subtract and store result in destination buffer. */
+ *pDst++ = (*pSrcA++) - (*pSrcB++);
+
+ *pDst++ = (*pSrcA++) - (*pSrcB++);
+
+ *pDst++ = (*pSrcA++) - (*pSrcB++);
+
+ *pDst++ = (*pSrcA++) - (*pSrcB++);
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
-#endif /* #if defined (ARM_MATH_DSP) */
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+#endif /* #if defined(ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = A - B */
- /* Subtract and then store the results in the destination buffer. */
+
+ /* Subtract and store result in destination buffer. */
*pDst++ = (*pSrcA++) - (*pSrcB++);
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
+
}
/**
- * @} end of BasicSub group
+ @} end of BasicSub group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_sub_q15.c b/DSP/Source/BasicMathFunctions/arm_sub_q15.c
index 17942eb..835917e 100644
--- a/DSP/Source/BasicMathFunctions/arm_sub_q15.c
+++ b/DSP/Source/BasicMathFunctions/arm_sub_q15.c
@@ -3,13 +3,13 @@
* Title: arm_sub_q15.c
* Description: Q15 vector subtraction
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,100 +29,98 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicSub
- * @{
+ @addtogroup BasicSub
+ @{
*/
/**
- * @brief Q15 vector subtraction.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
+ @brief Q15 vector subtraction.
+ @param[in] pSrcA points to the first input vector
+ @param[in] pSrcB points to the second input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
*/
void arm_sub_q15(
- q15_t * pSrcA,
- q15_t * pSrcB,
- q15_t * pDst,
- uint32_t blockSize)
+ const q15_t * pSrcA,
+ const q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
+ uint32_t blkCnt; /* Loop counter */
+#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
-
-/* Run the below code for Cortex-M4 and Cortex-M3 */
q31_t inA1, inA2;
q31_t inB1, inB2;
+#endif
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A - B */
- /* Subtract and then store the results in the destination buffer two samples at a time. */
- inA1 = *__SIMD32(pSrcA)++;
- inA2 = *__SIMD32(pSrcA)++;
- inB1 = *__SIMD32(pSrcB)++;
- inB2 = *__SIMD32(pSrcB)++;
- *__SIMD32(pDst)++ = __QSUB16(inA1, inB1);
- *__SIMD32(pDst)++ = __QSUB16(inA2, inB2);
+#if defined (ARM_MATH_DSP)
+ /* read 2 times 2 samples at a time from sourceA */
+ inA1 = read_q15x2_ia ((q15_t **) &pSrcA);
+ inA2 = read_q15x2_ia ((q15_t **) &pSrcA);
+ /* read 2 times 2 samples at a time from sourceB */
+ inB1 = read_q15x2_ia ((q15_t **) &pSrcB);
+ inB2 = read_q15x2_ia ((q15_t **) &pSrcB);
+
+ /* Subtract and store 2 times 2 samples at a time */
+ write_q15x2_ia (&pDst, __QSUB16(inA1, inB1));
+ write_q15x2_ia (&pDst, __QSUB16(inA2, inB2));
+#else
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16);
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16);
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16);
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16);
+#endif
- /* Decrement the loop counter */
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
- while (blkCnt > 0U)
- {
- /* C = A - B */
- /* Subtract and then store the result in the destination buffer. */
- *pDst++ = (q15_t) __QSUB16(*pSrcA++, *pSrcB++);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A - B */
- /* Subtract and then store the result in the destination buffer. */
- *pDst++ = (q15_t) __SSAT(((q31_t) * pSrcA++ - *pSrcB++), 16);
- /* Decrement the loop counter */
+ /* Subtract and store result in destination buffer. */
+#if defined (ARM_MATH_DSP)
+ *pDst++ = (q15_t) __QSUB16(*pSrcA++, *pSrcB++);
+#else
+ *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16);
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
-
}
/**
- * @} end of BasicSub group
+ @} end of BasicSub group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_sub_q31.c b/DSP/Source/BasicMathFunctions/arm_sub_q31.c
index 72b8597..bac1927 100644
--- a/DSP/Source/BasicMathFunctions/arm_sub_q31.c
+++ b/DSP/Source/BasicMathFunctions/arm_sub_q31.c
@@ -3,13 +3,13 @@
* Title: arm_sub_q31.c
* Description: Q31 vector subtraction
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,106 +29,80 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicSub
- * @{
+ @addtogroup BasicSub
+ @{
*/
/**
- * @brief Q31 vector subtraction.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
+ @brief Q31 vector subtraction.
+ @param[in] pSrcA points to the first input vector
+ @param[in] pSrcB points to the second input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
*/
void arm_sub_q31(
- q31_t * pSrcA,
- q31_t * pSrcB,
- q31_t * pDst,
- uint32_t blockSize)
+ const q31_t * pSrcA,
+ const q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t inA1, inA2, inA3, inA4;
- q31_t inB1, inB2, inB3, inB4;
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A - B */
- /* Subtract and then store the results in the destination buffer. */
- inA1 = *pSrcA++;
- inA2 = *pSrcA++;
- inB1 = *pSrcB++;
- inB2 = *pSrcB++;
-
- inA3 = *pSrcA++;
- inA4 = *pSrcA++;
- inB3 = *pSrcB++;
- inB4 = *pSrcB++;
-
- *pDst++ = __QSUB(inA1, inB1);
- *pDst++ = __QSUB(inA2, inB2);
- *pDst++ = __QSUB(inA3, inB3);
- *pDst++ = __QSUB(inA4, inB4);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4U;
+ /* Subtract and store result in destination buffer. */
+ *pDst++ = __QSUB(*pSrcA++, *pSrcB++);
- while (blkCnt > 0U)
- {
- /* C = A - B */
- /* Subtract and then store the result in the destination buffer. */
*pDst++ = __QSUB(*pSrcA++, *pSrcB++);
- /* Decrement the loop counter */
+ *pDst++ = __QSUB(*pSrcA++, *pSrcB++);
+
+ *pDst++ = __QSUB(*pSrcA++, *pSrcB++);
+
+ /* Decrement loop counter */
blkCnt--;
}
-#else
+ /* Loop unrolling: Compute remaining outputs */
+ blkCnt = blockSize % 0x4U;
- /* Run the below code for Cortex-M0 */
+#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A - B */
- /* Subtract and then store the result in the destination buffer. */
- *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrcA++ - *pSrcB++);
- /* Decrement the loop counter */
+ /* Subtract and store result in destination buffer. */
+ *pDst++ = __QSUB(*pSrcA++, *pSrcB++);
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
}
/**
- * @} end of BasicSub group
+ @} end of BasicSub group
*/
diff --git a/DSP/Source/BasicMathFunctions/arm_sub_q7.c b/DSP/Source/BasicMathFunctions/arm_sub_q7.c
index d211f40..a55a8fd 100644
--- a/DSP/Source/BasicMathFunctions/arm_sub_q7.c
+++ b/DSP/Source/BasicMathFunctions/arm_sub_q7.c
@@ -3,13 +3,13 @@
* Title: arm_sub_q7.c
* Description: Q7 vector subtraction
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,91 +29,81 @@
#include "arm_math.h"
/**
- * @ingroup groupMath
+ @ingroup groupMath
*/
/**
- * @addtogroup BasicSub
- * @{
+ @addtogroup BasicSub
+ @{
*/
/**
- * @brief Q7 vector subtraction.
- * @param[in] *pSrcA points to the first input vector
- * @param[in] *pSrcB points to the second input vector
- * @param[out] *pDst points to the output vector
- * @param[in] blockSize number of samples in each vector
- * @return none.
- *
- * <b>Scaling and Overflow Behavior:</b>
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
+ @brief Q7 vector subtraction.
+ @param[in] pSrcA points to the first input vector
+ @param[in] pSrcB points to the second input vector
+ @param[out] pDst points to the output vector
+ @param[in] blockSize number of samples in each vector
+ @return none
+
+ @par Scaling and Overflow Behavior
+ The function uses saturating arithmetic.
+ Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
*/
void arm_sub_q7(
- q7_t * pSrcA,
- q7_t * pSrcB,
- q7_t * pDst,
- uint32_t blockSize)
+ const q7_t * pSrcA,
+ const q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize)
{
- uint32_t blkCnt; /* loop counter */
-
-#if defined (ARM_MATH_DSP)
+ uint32_t blkCnt; /* Loop counter */
-/* Run the below code for Cortex-M4 and Cortex-M3 */
+#if defined (ARM_MATH_LOOPUNROLL)
- /*loop Unrolling */
+ /* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A - B */
- /* Subtract and then store the results in the destination buffer 4 samples at a time. */
- *__SIMD32(pDst)++ = __QSUB8(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++);
- /* Decrement the loop counter */
+#if defined (ARM_MATH_DSP)
+ /* Subtract and store result in destination buffer (4 samples at a time). */
+ write_q7x4_ia (&pDst, __QSUB8(read_q7x4_ia ((q7_t **) &pSrcA), read_q7x4_ia ((q7_t **) &pSrcB)));
+#else
+ *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8);
+ *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8);
+ *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8);
+ *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8);
+#endif
+
+ /* Decrement loop counter */
blkCnt--;
}
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
+ /* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
- while (blkCnt > 0U)
- {
- /* C = A - B */
- /* Subtract and then store the result in the destination buffer. */
- *pDst++ = __SSAT(*pSrcA++ - *pSrcB++, 8);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
#else
- /* Run the below code for Cortex-M0 */
-
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+
while (blkCnt > 0U)
{
/* C = A - B */
- /* Subtract and then store the result in the destination buffer. */
- *pDst++ = (q7_t) __SSAT((q15_t) * pSrcA++ - *pSrcB++, 8);
- /* Decrement the loop counter */
+ /* Subtract and store result in destination buffer. */
+ *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8);
+
+ /* Decrement loop counter */
blkCnt--;
}
-#endif /* #if defined (ARM_MATH_DSP) */
-
-
}
/**
- * @} end of BasicSub group
+ @} end of BasicSub group
*/