diff options
Diffstat (limited to 'Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_conv_partial_fast_q31.c')
-rw-r--r-- | Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_conv_partial_fast_q31.c | 280 |
1 files changed, 139 insertions, 141 deletions
diff --git a/Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_conv_partial_fast_q31.c b/Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_conv_partial_fast_q31.c index af3724dc1..f232d51f0 100644 --- a/Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_conv_partial_fast_q31.c +++ b/Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_conv_partial_fast_q31.c @@ -3,13 +3,13 @@ * Title: arm_conv_partial_fast_q31.c * Description: Fast Q31 Partial convolution * - * $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,50 +29,55 @@ #include "arm_math.h" /** - * @ingroup groupFilters + @ingroup groupFilters */ /** - * @addtogroup PartialConv - * @{ + @addtogroup PartialConv + @{ */ /** - * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the location where the output result is written. - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - * - * \par - * See <code>arm_conv_partial_q31()</code> for a slower implementation of this function which uses a 64-bit accumulator to provide higher precision. + @brief Partial convolution of Q31 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the location where the output result is written + @param[in] firstIndex is the first output sample to start with + @param[in] numPoints is the number of output points to be computed + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : requested subset is not in the range [0 srcALen+srcBLen-2] + + @remark + Refer to \ref arm_conv_partial_q31() for a slower implementation of this function which uses a 64-bit accumulator to provide higher precision. */ arm_status arm_conv_partial_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints) + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints) { - q31_t *pIn1; /* inputA pointer */ - q31_t *pIn2; /* inputB pointer */ - q31_t *pOut = pDst; /* output pointer */ - q31_t *px; /* Intermediate inputA pointer */ - q31_t *py; /* Intermediate inputB pointer */ - q31_t *pSrc1, *pSrc2; /* Intermediate pointers */ - q31_t sum, acc0, acc1, acc2, acc3; /* Accumulators */ - q31_t x0, x1, x2, x3, c0; - uint32_t j, k, count, check, blkCnt; - int32_t blockSize1, blockSize2, blockSize3; /* loop counters */ - arm_status status; /* status of Partial convolution */ - + const q31_t *pIn1; /* InputA pointer */ + const q31_t *pIn2; /* InputB pointer */ + q31_t *pOut = pDst; /* Output pointer */ + const q31_t *px; /* Intermediate inputA pointer */ + const q31_t *py; /* Intermediate inputB pointer */ + const q31_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q31_t sum; /* Accumulators */ + uint32_t j, k, count, check, blkCnt; + int32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + arm_status status; /* Status of Partial convolution */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc0, acc1, acc2, acc3; /* Accumulators */ + q31_t x0, x1, x2, x3, c0; +#endif /* Check for range of output samples to be calculated */ if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) @@ -82,7 +87,6 @@ arm_status arm_conv_partial_fast_q31( } else { - /* The algorithm implementation is based on the lengths of the inputs. */ /* srcB is always made to slide across srcA. */ /* So srcBLen is always considered as shorter or equal to srcALen */ @@ -113,11 +117,9 @@ arm_status arm_conv_partial_fast_q31( check = firstIndex + numPoints; blockSize3 = ((int32_t)check > (int32_t)srcALen) ? (int32_t)check - (int32_t)srcALen : 0; blockSize3 = ((int32_t)firstIndex > (int32_t)srcALen - 1) ? blockSize3 - (int32_t)firstIndex + (int32_t)srcALen : blockSize3; - blockSize1 = (((int32_t) srcBLen - 1) - (int32_t) firstIndex); - blockSize1 = (blockSize1 > 0) ? ((check > (srcBLen - 1U)) ? blockSize1 : - (int32_t) numPoints) : 0; - blockSize2 = (int32_t) check - ((blockSize3 + blockSize1) + - (int32_t) firstIndex); + blockSize1 = ((int32_t) srcBLen - 1) - (int32_t) firstIndex; + blockSize1 = (blockSize1 > 0) ? ((check > (srcBLen - 1U)) ? blockSize1 : (int32_t) numPoints) : 0; + blockSize2 = (int32_t) check - ((blockSize3 + blockSize1) + (int32_t) firstIndex); blockSize2 = (blockSize2 > 0) ? blockSize2 : 0; /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ @@ -160,50 +162,56 @@ arm_status arm_conv_partial_fast_q31( * Stage1 process * ----------------------*/ - /* The first loop starts here */ - while (blockSize1 > 0) + /* The first stage starts here */ + while (blockSize1 > 0U) { /* Accumulator is made zero for every iteration */ sum = 0; - /* Apply loop unrolling and compute 4 MACs simultaneously. */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ k = count >> 2U; - /* First part of the processing with loop unrolling. Compute 4 MACs at a time. - ** a second loop below computes MACs for the remaining 1 to 3 samples. */ while (k > 0U) { /* x[0] * y[srcBLen - 1] */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); /* x[1] * y[srcBLen - 2] */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); /* x[2] * y[srcBLen - 3] */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); /* x[3] * y[srcBLen - 4] */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } - /* If the count is not a multiple of 4, compute any remaining MACs here. - ** No loop unrolling is used. */ + /* Loop unrolling: Compute remaining outputs */ k = count % 0x4U; +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + while (k > 0U) { - /* Perform the multiply-accumulates */ + /* Perform the multiply-accumulate */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } @@ -214,10 +222,10 @@ arm_status arm_conv_partial_fast_q31( py = ++pSrc2; px = pIn1; - /* Increment the MAC count */ + /* Increment MAC count */ count++; - /* Decrement the loop counter */ + /* Decrement loop counter */ blockSize1--; } @@ -234,12 +242,13 @@ arm_status arm_conv_partial_fast_q31( /* Working pointer of inputA */ if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0) { - px = pIn1 + firstIndex - srcBLen + 1; + pSrc1 = pIn1 + firstIndex - srcBLen + 1; } else { - px = pIn1; + pSrc1 = pIn1; } + px = pSrc1; /* Working pointer of inputB */ pSrc2 = pIn2 + (srcBLen - 1U); @@ -257,7 +266,9 @@ arm_status arm_conv_partial_fast_q31( * srcBLen should be greater than or equal to 4 */ if (srcBLen >= 4U) { - /* Loop unroll over blockSize2 */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ blkCnt = ((uint32_t) blockSize2 >> 2U); while (blkCnt > 0U) @@ -269,9 +280,9 @@ arm_status arm_conv_partial_fast_q31( acc3 = 0; /* read x[0], x[1], x[2] samples */ - x0 = *(px++); - x1 = *(px++); - x2 = *(px++); + x0 = *px++; + x1 = *px++; + x2 = *px++; /* Apply loop unrolling and compute 4 MACs simultaneously. */ k = srcBLen >> 2U; @@ -281,29 +292,24 @@ arm_status arm_conv_partial_fast_q31( do { /* Read y[srcBLen - 1] sample */ - c0 = *(py--); - + c0 = *py--; /* Read x[3] sample */ - x3 = *(px++); + x3 = *px++; /* Perform the multiply-accumulate */ /* acc0 += x[0] * y[srcBLen - 1] */ acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); - /* acc1 += x[1] * y[srcBLen - 1] */ acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); - /* acc2 += x[2] * y[srcBLen - 1] */ acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); - /* acc3 += x[3] * y[srcBLen - 1] */ acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); /* Read y[srcBLen - 2] sample */ - c0 = *(py--); - + c0 = *py--; /* Read x[4] sample */ - x0 = *(px++); + x0 = *px++; /* Perform the multiply-accumulate */ /* acc0 += x[1] * y[srcBLen - 2] */ @@ -316,10 +322,9 @@ arm_status arm_conv_partial_fast_q31( acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x0 * c0)) >> 32); /* Read y[srcBLen - 3] sample */ - c0 = *(py--); - + c0 = *py--; /* Read x[5] sample */ - x1 = *(px++); + x1 = *px++; /* Perform the multiply-accumulates */ /* acc0 += x[2] * y[srcBLen - 3] */ @@ -332,10 +337,9 @@ arm_status arm_conv_partial_fast_q31( acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x1 * c0)) >> 32); /* Read y[srcBLen - 4] sample */ - c0 = *(py--); - + c0 = *py--; /* Read x[6] sample */ - x2 = *(px++); + x2 = *px++; /* Perform the multiply-accumulates */ /* acc0 += x[3] * y[srcBLen - 4] */ @@ -347,7 +351,6 @@ arm_status arm_conv_partial_fast_q31( /* acc3 += x[6] * y[srcBLen - 4] */ acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x2 * c0)) >> 32); - } while (--k); /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. @@ -357,10 +360,9 @@ arm_status arm_conv_partial_fast_q31( while (k > 0U) { /* Read y[srcBLen - 5] sample */ - c0 = *(py--); - + c0 = *py--; /* Read x[7] sample */ - x3 = *(px++); + x3 = *px++; /* Perform the multiply-accumulates */ /* acc0 += x[4] * y[srcBLen - 5] */ @@ -391,34 +393,33 @@ arm_status arm_conv_partial_fast_q31( count += 4U; /* Update the inputA and inputB pointers for next MAC calculation */ - if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0) - { - px = pIn1 + firstIndex - srcBLen + 1 + count; - } - else - { - px = pIn1 + count; - } + px = pSrc1 + count; py = pSrc2; - /* Decrement the loop counter */ + /* Decrement loop counter */ blkCnt--; } - /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here. - ** No loop unrolling is used. */ + /* Loop unrolling: Compute remaining outputs */ blkCnt = (uint32_t) blockSize2 % 0x4U; +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + while (blkCnt > 0U) { /* Accumulator is made zero for every iteration */ sum = 0; - /* Apply loop unrolling and compute 4 MACs simultaneously. */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ k = srcBLen >> 2U; - /* First part of the processing with loop unrolling. Compute 4 MACs at a time. - ** a second loop below computes MACs for the remaining 1 to 3 samples. */ while (k > 0U) { /* Perform the multiply-accumulates */ @@ -431,42 +432,41 @@ arm_status arm_conv_partial_fast_q31( sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) * px++ * (*py--))) >> 32); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } - /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. - ** No loop unrolling is used. */ + /* Loop unrolling: Compute remaining outputs */ k = srcBLen % 0x4U; +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + while (k > 0U) { /* Perform the multiply-accumulate */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } /* Store the result in the accumulator in the destination buffer. */ *pOut++ = sum << 1; - /* Increment the MAC count */ + /* Increment MAC count */ count++; /* Update the inputA and inputB pointers for next MAC calculation */ - if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0) - { - px = pIn1 + firstIndex - srcBLen + 1 + count; - } - else - { - px = pIn1 + count; - } + px = pSrc1 + count; py = pSrc2; - /* Decrement the loop counter */ + /* Decrement loop counter */ blkCnt--; } } @@ -488,9 +488,9 @@ arm_status arm_conv_partial_fast_q31( { /* Perform the multiply-accumulate */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } @@ -501,14 +501,7 @@ arm_status arm_conv_partial_fast_q31( count++; /* Update the inputA and inputB pointers for next MAC calculation */ - if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0) - { - px = pIn1 + firstIndex - srcBLen + 1 + count; - } - else - { - px = pIn1 + count; - } + px = pSrc1 + count; py = pSrc2; /* Decrement the loop counter */ @@ -544,50 +537,56 @@ arm_status arm_conv_partial_fast_q31( * Stage3 process * ------------------*/ - while (blockSize3 > 0) + while (blockSize3 > 0U) { /* Accumulator is made zero for every iteration */ sum = 0; - /* Apply loop unrolling and compute 4 MACs simultaneously. */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ k = count >> 2U; - /* First part of the processing with loop unrolling. Compute 4 MACs at a time. - ** a second loop below computes MACs for the remaining 1 to 3 samples. */ while (k > 0U) { /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } - /* If the count is not a multiple of 4, compute any remaining MACs here. - ** No loop unrolling is used. */ + /* Loop unrolling: Compute remaining outputs */ k = count % 0x4U; +#else + + /* Initialize blkCnt with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + while (k > 0U) { /* Perform the multiply-accumulates */ /* sum += x[srcALen-1] * y[srcBLen-1] */ sum = (q31_t) ((((q63_t) sum << 32) + - ((q63_t) * px++ * (*py--))) >> 32); + ((q63_t) *px++ * (*py--))) >> 32); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } @@ -598,15 +597,14 @@ arm_status arm_conv_partial_fast_q31( px = ++pSrc1; py = pSrc2; - /* Decrement the MAC count */ + /* Decrement MAC count */ count--; /* Decrement the loop counter */ blockSize3--; - } - /* set status as ARM_MATH_SUCCESS */ + /* Set status as ARM_MATH_SUCCESS */ status = ARM_MATH_SUCCESS; } @@ -616,5 +614,5 @@ arm_status arm_conv_partial_fast_q31( } /** - * @} end of PartialConv group + @} end of PartialConv group */ |