The CMSIS DSP 5 library

Dependents:   Nucleo-Heart-Rate ejercicioVrms2 PROYECTOFINAL ejercicioVrms ... more

Committer:
xorjoep
Date:
Thu Jun 21 11:56:27 2018 +0000
Revision:
3:4098b9d3d571
Parent:
1:24714b45cd1b
headers is a folder not a library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xorjoep 1:24714b45cd1b 1 /* ----------------------------------------------------------------------
xorjoep 1:24714b45cd1b 2 * Project: CMSIS DSP Library
xorjoep 1:24714b45cd1b 3 * Title: arm_conv_opt_q15.c
xorjoep 1:24714b45cd1b 4 * Description: Convolution of Q15 sequences
xorjoep 1:24714b45cd1b 5 *
xorjoep 1:24714b45cd1b 6 * $Date: 27. January 2017
xorjoep 1:24714b45cd1b 7 * $Revision: V.1.5.1
xorjoep 1:24714b45cd1b 8 *
xorjoep 1:24714b45cd1b 9 * Target Processor: Cortex-M cores
xorjoep 1:24714b45cd1b 10 * -------------------------------------------------------------------- */
xorjoep 1:24714b45cd1b 11 /*
xorjoep 1:24714b45cd1b 12 * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
xorjoep 1:24714b45cd1b 13 *
xorjoep 1:24714b45cd1b 14 * SPDX-License-Identifier: Apache-2.0
xorjoep 1:24714b45cd1b 15 *
xorjoep 1:24714b45cd1b 16 * Licensed under the Apache License, Version 2.0 (the License); you may
xorjoep 1:24714b45cd1b 17 * not use this file except in compliance with the License.
xorjoep 1:24714b45cd1b 18 * You may obtain a copy of the License at
xorjoep 1:24714b45cd1b 19 *
xorjoep 1:24714b45cd1b 20 * www.apache.org/licenses/LICENSE-2.0
xorjoep 1:24714b45cd1b 21 *
xorjoep 1:24714b45cd1b 22 * Unless required by applicable law or agreed to in writing, software
xorjoep 1:24714b45cd1b 23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
xorjoep 1:24714b45cd1b 24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
xorjoep 1:24714b45cd1b 25 * See the License for the specific language governing permissions and
xorjoep 1:24714b45cd1b 26 * limitations under the License.
xorjoep 1:24714b45cd1b 27 */
xorjoep 1:24714b45cd1b 28
xorjoep 1:24714b45cd1b 29 #include "arm_math.h"
xorjoep 1:24714b45cd1b 30
xorjoep 1:24714b45cd1b 31 /**
xorjoep 1:24714b45cd1b 32 * @ingroup groupFilters
xorjoep 1:24714b45cd1b 33 */
xorjoep 1:24714b45cd1b 34
xorjoep 1:24714b45cd1b 35 /**
xorjoep 1:24714b45cd1b 36 * @addtogroup Conv
xorjoep 1:24714b45cd1b 37 * @{
xorjoep 1:24714b45cd1b 38 */
xorjoep 1:24714b45cd1b 39
xorjoep 1:24714b45cd1b 40 /**
xorjoep 1:24714b45cd1b 41 * @brief Convolution of Q15 sequences.
xorjoep 1:24714b45cd1b 42 * @param[in] *pSrcA points to the first input sequence.
xorjoep 1:24714b45cd1b 43 * @param[in] srcALen length of the first input sequence.
xorjoep 1:24714b45cd1b 44 * @param[in] *pSrcB points to the second input sequence.
xorjoep 1:24714b45cd1b 45 * @param[in] srcBLen length of the second input sequence.
xorjoep 1:24714b45cd1b 46 * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1.
xorjoep 1:24714b45cd1b 47 * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
xorjoep 1:24714b45cd1b 48 * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
xorjoep 1:24714b45cd1b 49 * @return none.
xorjoep 1:24714b45cd1b 50 *
xorjoep 1:24714b45cd1b 51 * \par Restrictions
xorjoep 1:24714b45cd1b 52 * If the silicon does not support unaligned memory access enable the macro UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 53 * In this case input, output, scratch1 and scratch2 buffers should be aligned by 32-bit
xorjoep 1:24714b45cd1b 54 *
xorjoep 1:24714b45cd1b 55 *
xorjoep 1:24714b45cd1b 56 * @details
xorjoep 1:24714b45cd1b 57 * <b>Scaling and Overflow Behavior:</b>
xorjoep 1:24714b45cd1b 58 *
xorjoep 1:24714b45cd1b 59 * \par
xorjoep 1:24714b45cd1b 60 * The function is implemented using a 64-bit internal accumulator.
xorjoep 1:24714b45cd1b 61 * Both inputs are in 1.15 format and multiplications yield a 2.30 result.
xorjoep 1:24714b45cd1b 62 * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
xorjoep 1:24714b45cd1b 63 * This approach provides 33 guard bits and there is no risk of overflow.
xorjoep 1:24714b45cd1b 64 * The 34.30 result is then truncated to 34.15 format by discarding the low 15 bits and then saturated to 1.15 format.
xorjoep 1:24714b45cd1b 65 *
xorjoep 1:24714b45cd1b 66 *
xorjoep 1:24714b45cd1b 67 * \par
xorjoep 1:24714b45cd1b 68 * Refer to <code>arm_conv_fast_q15()</code> for a faster but less precise version of this function for Cortex-M3 and Cortex-M4.
xorjoep 1:24714b45cd1b 69 *
xorjoep 1:24714b45cd1b 70 *
xorjoep 1:24714b45cd1b 71 */
xorjoep 1:24714b45cd1b 72
xorjoep 1:24714b45cd1b 73 void arm_conv_opt_q15(
xorjoep 1:24714b45cd1b 74 q15_t * pSrcA,
xorjoep 1:24714b45cd1b 75 uint32_t srcALen,
xorjoep 1:24714b45cd1b 76 q15_t * pSrcB,
xorjoep 1:24714b45cd1b 77 uint32_t srcBLen,
xorjoep 1:24714b45cd1b 78 q15_t * pDst,
xorjoep 1:24714b45cd1b 79 q15_t * pScratch1,
xorjoep 1:24714b45cd1b 80 q15_t * pScratch2)
xorjoep 1:24714b45cd1b 81 {
xorjoep 1:24714b45cd1b 82 q63_t acc0, acc1, acc2, acc3; /* Accumulator */
xorjoep 1:24714b45cd1b 83 q31_t x1, x2, x3; /* Temporary variables to hold state and coefficient values */
xorjoep 1:24714b45cd1b 84 q31_t y1, y2; /* State variables */
xorjoep 1:24714b45cd1b 85 q15_t *pOut = pDst; /* output pointer */
xorjoep 1:24714b45cd1b 86 q15_t *pScr1 = pScratch1; /* Temporary pointer for scratch1 */
xorjoep 1:24714b45cd1b 87 q15_t *pScr2 = pScratch2; /* Temporary pointer for scratch1 */
xorjoep 1:24714b45cd1b 88 q15_t *pIn1; /* inputA pointer */
xorjoep 1:24714b45cd1b 89 q15_t *pIn2; /* inputB pointer */
xorjoep 1:24714b45cd1b 90 q15_t *px; /* Intermediate inputA pointer */
xorjoep 1:24714b45cd1b 91 q15_t *py; /* Intermediate inputB pointer */
xorjoep 1:24714b45cd1b 92 uint32_t j, k, blkCnt; /* loop counter */
xorjoep 1:24714b45cd1b 93 uint32_t tapCnt; /* loop count */
xorjoep 1:24714b45cd1b 94 #ifdef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 95
xorjoep 1:24714b45cd1b 96 q15_t a, b;
xorjoep 1:24714b45cd1b 97
xorjoep 1:24714b45cd1b 98 #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
xorjoep 1:24714b45cd1b 99
xorjoep 1:24714b45cd1b 100 /* The algorithm implementation is based on the lengths of the inputs. */
xorjoep 1:24714b45cd1b 101 /* srcB is always made to slide across srcA. */
xorjoep 1:24714b45cd1b 102 /* So srcBLen is always considered as shorter or equal to srcALen */
xorjoep 1:24714b45cd1b 103 if (srcALen >= srcBLen)
xorjoep 1:24714b45cd1b 104 {
xorjoep 1:24714b45cd1b 105 /* Initialization of inputA pointer */
xorjoep 1:24714b45cd1b 106 pIn1 = pSrcA;
xorjoep 1:24714b45cd1b 107
xorjoep 1:24714b45cd1b 108 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 109 pIn2 = pSrcB;
xorjoep 1:24714b45cd1b 110
xorjoep 1:24714b45cd1b 111 }
xorjoep 1:24714b45cd1b 112 else
xorjoep 1:24714b45cd1b 113 {
xorjoep 1:24714b45cd1b 114 /* Initialization of inputA pointer */
xorjoep 1:24714b45cd1b 115 pIn1 = pSrcB;
xorjoep 1:24714b45cd1b 116
xorjoep 1:24714b45cd1b 117 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 118 pIn2 = pSrcA;
xorjoep 1:24714b45cd1b 119
xorjoep 1:24714b45cd1b 120 /* srcBLen is always considered as shorter or equal to srcALen */
xorjoep 1:24714b45cd1b 121 j = srcBLen;
xorjoep 1:24714b45cd1b 122 srcBLen = srcALen;
xorjoep 1:24714b45cd1b 123 srcALen = j;
xorjoep 1:24714b45cd1b 124 }
xorjoep 1:24714b45cd1b 125
xorjoep 1:24714b45cd1b 126 /* pointer to take end of scratch2 buffer */
xorjoep 1:24714b45cd1b 127 pScr2 = pScratch2 + srcBLen - 1;
xorjoep 1:24714b45cd1b 128
xorjoep 1:24714b45cd1b 129 /* points to smaller length sequence */
xorjoep 1:24714b45cd1b 130 px = pIn2;
xorjoep 1:24714b45cd1b 131
xorjoep 1:24714b45cd1b 132 /* Apply loop unrolling and do 4 Copies simultaneously. */
xorjoep 1:24714b45cd1b 133 k = srcBLen >> 2U;
xorjoep 1:24714b45cd1b 134
xorjoep 1:24714b45cd1b 135 /* First part of the processing with loop unrolling copies 4 data points at a time.
xorjoep 1:24714b45cd1b 136 ** a second loop below copies for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 137 /* Copy smaller length input sequence in reverse order into second scratch buffer */
xorjoep 1:24714b45cd1b 138 while (k > 0U)
xorjoep 1:24714b45cd1b 139 {
xorjoep 1:24714b45cd1b 140 /* copy second buffer in reversal manner */
xorjoep 1:24714b45cd1b 141 *pScr2-- = *px++;
xorjoep 1:24714b45cd1b 142 *pScr2-- = *px++;
xorjoep 1:24714b45cd1b 143 *pScr2-- = *px++;
xorjoep 1:24714b45cd1b 144 *pScr2-- = *px++;
xorjoep 1:24714b45cd1b 145
xorjoep 1:24714b45cd1b 146 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 147 k--;
xorjoep 1:24714b45cd1b 148 }
xorjoep 1:24714b45cd1b 149
xorjoep 1:24714b45cd1b 150 /* If the count is not a multiple of 4, copy remaining samples here.
xorjoep 1:24714b45cd1b 151 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 152 k = srcBLen % 0x4U;
xorjoep 1:24714b45cd1b 153
xorjoep 1:24714b45cd1b 154 while (k > 0U)
xorjoep 1:24714b45cd1b 155 {
xorjoep 1:24714b45cd1b 156 /* copy second buffer in reversal manner for remaining samples */
xorjoep 1:24714b45cd1b 157 *pScr2-- = *px++;
xorjoep 1:24714b45cd1b 158
xorjoep 1:24714b45cd1b 159 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 160 k--;
xorjoep 1:24714b45cd1b 161 }
xorjoep 1:24714b45cd1b 162
xorjoep 1:24714b45cd1b 163 /* Initialze temporary scratch pointer */
xorjoep 1:24714b45cd1b 164 pScr1 = pScratch1;
xorjoep 1:24714b45cd1b 165
xorjoep 1:24714b45cd1b 166 /* Assuming scratch1 buffer is aligned by 32-bit */
xorjoep 1:24714b45cd1b 167 /* Fill (srcBLen - 1U) zeros in scratch buffer */
xorjoep 1:24714b45cd1b 168 arm_fill_q15(0, pScr1, (srcBLen - 1U));
xorjoep 1:24714b45cd1b 169
xorjoep 1:24714b45cd1b 170 /* Update temporary scratch pointer */
xorjoep 1:24714b45cd1b 171 pScr1 += (srcBLen - 1U);
xorjoep 1:24714b45cd1b 172
xorjoep 1:24714b45cd1b 173 /* Copy bigger length sequence(srcALen) samples in scratch1 buffer */
xorjoep 1:24714b45cd1b 174
xorjoep 1:24714b45cd1b 175 #ifndef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 176
xorjoep 1:24714b45cd1b 177 /* Copy (srcALen) samples in scratch buffer */
xorjoep 1:24714b45cd1b 178 arm_copy_q15(pIn1, pScr1, srcALen);
xorjoep 1:24714b45cd1b 179
xorjoep 1:24714b45cd1b 180 /* Update pointers */
xorjoep 1:24714b45cd1b 181 pScr1 += srcALen;
xorjoep 1:24714b45cd1b 182
xorjoep 1:24714b45cd1b 183 #else
xorjoep 1:24714b45cd1b 184
xorjoep 1:24714b45cd1b 185 /* Apply loop unrolling and do 4 Copies simultaneously. */
xorjoep 1:24714b45cd1b 186 k = srcALen >> 2U;
xorjoep 1:24714b45cd1b 187
xorjoep 1:24714b45cd1b 188 /* First part of the processing with loop unrolling copies 4 data points at a time.
xorjoep 1:24714b45cd1b 189 ** a second loop below copies for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 190 while (k > 0U)
xorjoep 1:24714b45cd1b 191 {
xorjoep 1:24714b45cd1b 192 /* copy second buffer in reversal manner */
xorjoep 1:24714b45cd1b 193 *pScr1++ = *pIn1++;
xorjoep 1:24714b45cd1b 194 *pScr1++ = *pIn1++;
xorjoep 1:24714b45cd1b 195 *pScr1++ = *pIn1++;
xorjoep 1:24714b45cd1b 196 *pScr1++ = *pIn1++;
xorjoep 1:24714b45cd1b 197
xorjoep 1:24714b45cd1b 198 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 199 k--;
xorjoep 1:24714b45cd1b 200 }
xorjoep 1:24714b45cd1b 201
xorjoep 1:24714b45cd1b 202 /* If the count is not a multiple of 4, copy remaining samples here.
xorjoep 1:24714b45cd1b 203 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 204 k = srcALen % 0x4U;
xorjoep 1:24714b45cd1b 205
xorjoep 1:24714b45cd1b 206 while (k > 0U)
xorjoep 1:24714b45cd1b 207 {
xorjoep 1:24714b45cd1b 208 /* copy second buffer in reversal manner for remaining samples */
xorjoep 1:24714b45cd1b 209 *pScr1++ = *pIn1++;
xorjoep 1:24714b45cd1b 210
xorjoep 1:24714b45cd1b 211 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 212 k--;
xorjoep 1:24714b45cd1b 213 }
xorjoep 1:24714b45cd1b 214
xorjoep 1:24714b45cd1b 215 #endif
xorjoep 1:24714b45cd1b 216
xorjoep 1:24714b45cd1b 217
xorjoep 1:24714b45cd1b 218 #ifndef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 219
xorjoep 1:24714b45cd1b 220 /* Fill (srcBLen - 1U) zeros at end of scratch buffer */
xorjoep 1:24714b45cd1b 221 arm_fill_q15(0, pScr1, (srcBLen - 1U));
xorjoep 1:24714b45cd1b 222
xorjoep 1:24714b45cd1b 223 /* Update pointer */
xorjoep 1:24714b45cd1b 224 pScr1 += (srcBLen - 1U);
xorjoep 1:24714b45cd1b 225
xorjoep 1:24714b45cd1b 226 #else
xorjoep 1:24714b45cd1b 227
xorjoep 1:24714b45cd1b 228 /* Apply loop unrolling and do 4 Copies simultaneously. */
xorjoep 1:24714b45cd1b 229 k = (srcBLen - 1U) >> 2U;
xorjoep 1:24714b45cd1b 230
xorjoep 1:24714b45cd1b 231 /* First part of the processing with loop unrolling copies 4 data points at a time.
xorjoep 1:24714b45cd1b 232 ** a second loop below copies for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 233 while (k > 0U)
xorjoep 1:24714b45cd1b 234 {
xorjoep 1:24714b45cd1b 235 /* copy second buffer in reversal manner */
xorjoep 1:24714b45cd1b 236 *pScr1++ = 0;
xorjoep 1:24714b45cd1b 237 *pScr1++ = 0;
xorjoep 1:24714b45cd1b 238 *pScr1++ = 0;
xorjoep 1:24714b45cd1b 239 *pScr1++ = 0;
xorjoep 1:24714b45cd1b 240
xorjoep 1:24714b45cd1b 241 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 242 k--;
xorjoep 1:24714b45cd1b 243 }
xorjoep 1:24714b45cd1b 244
xorjoep 1:24714b45cd1b 245 /* If the count is not a multiple of 4, copy remaining samples here.
xorjoep 1:24714b45cd1b 246 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 247 k = (srcBLen - 1U) % 0x4U;
xorjoep 1:24714b45cd1b 248
xorjoep 1:24714b45cd1b 249 while (k > 0U)
xorjoep 1:24714b45cd1b 250 {
xorjoep 1:24714b45cd1b 251 /* copy second buffer in reversal manner for remaining samples */
xorjoep 1:24714b45cd1b 252 *pScr1++ = 0;
xorjoep 1:24714b45cd1b 253
xorjoep 1:24714b45cd1b 254 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 255 k--;
xorjoep 1:24714b45cd1b 256 }
xorjoep 1:24714b45cd1b 257
xorjoep 1:24714b45cd1b 258 #endif
xorjoep 1:24714b45cd1b 259
xorjoep 1:24714b45cd1b 260 /* Temporary pointer for scratch2 */
xorjoep 1:24714b45cd1b 261 py = pScratch2;
xorjoep 1:24714b45cd1b 262
xorjoep 1:24714b45cd1b 263
xorjoep 1:24714b45cd1b 264 /* Initialization of pIn2 pointer */
xorjoep 1:24714b45cd1b 265 pIn2 = py;
xorjoep 1:24714b45cd1b 266
xorjoep 1:24714b45cd1b 267 /* First part of the processing with loop unrolling process 4 data points at a time.
xorjoep 1:24714b45cd1b 268 ** a second loop below process for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 269
xorjoep 1:24714b45cd1b 270 /* Actual convolution process starts here */
xorjoep 1:24714b45cd1b 271 blkCnt = (srcALen + srcBLen - 1U) >> 2;
xorjoep 1:24714b45cd1b 272
xorjoep 1:24714b45cd1b 273 while (blkCnt > 0)
xorjoep 1:24714b45cd1b 274 {
xorjoep 1:24714b45cd1b 275 /* Initialze temporary scratch pointer as scratch1 */
xorjoep 1:24714b45cd1b 276 pScr1 = pScratch1;
xorjoep 1:24714b45cd1b 277
xorjoep 1:24714b45cd1b 278 /* Clear Accumlators */
xorjoep 1:24714b45cd1b 279 acc0 = 0;
xorjoep 1:24714b45cd1b 280 acc1 = 0;
xorjoep 1:24714b45cd1b 281 acc2 = 0;
xorjoep 1:24714b45cd1b 282 acc3 = 0;
xorjoep 1:24714b45cd1b 283
xorjoep 1:24714b45cd1b 284 /* Read two samples from scratch1 buffer */
xorjoep 1:24714b45cd1b 285 x1 = *__SIMD32(pScr1)++;
xorjoep 1:24714b45cd1b 286
xorjoep 1:24714b45cd1b 287 /* Read next two samples from scratch1 buffer */
xorjoep 1:24714b45cd1b 288 x2 = *__SIMD32(pScr1)++;
xorjoep 1:24714b45cd1b 289
xorjoep 1:24714b45cd1b 290 tapCnt = (srcBLen) >> 2U;
xorjoep 1:24714b45cd1b 291
xorjoep 1:24714b45cd1b 292 while (tapCnt > 0U)
xorjoep 1:24714b45cd1b 293 {
xorjoep 1:24714b45cd1b 294
xorjoep 1:24714b45cd1b 295 #ifndef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 296
xorjoep 1:24714b45cd1b 297 /* Read four samples from smaller buffer */
xorjoep 1:24714b45cd1b 298 y1 = _SIMD32_OFFSET(pIn2);
xorjoep 1:24714b45cd1b 299 y2 = _SIMD32_OFFSET(pIn2 + 2U);
xorjoep 1:24714b45cd1b 300
xorjoep 1:24714b45cd1b 301 /* multiply and accumlate */
xorjoep 1:24714b45cd1b 302 acc0 = __SMLALD(x1, y1, acc0);
xorjoep 1:24714b45cd1b 303 acc2 = __SMLALD(x2, y1, acc2);
xorjoep 1:24714b45cd1b 304
xorjoep 1:24714b45cd1b 305 /* pack input data */
xorjoep 1:24714b45cd1b 306 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 307 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 308 #else
xorjoep 1:24714b45cd1b 309 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 310 #endif
xorjoep 1:24714b45cd1b 311
xorjoep 1:24714b45cd1b 312 /* multiply and accumlate */
xorjoep 1:24714b45cd1b 313 acc1 = __SMLALDX(x3, y1, acc1);
xorjoep 1:24714b45cd1b 314
xorjoep 1:24714b45cd1b 315 /* Read next two samples from scratch1 buffer */
xorjoep 1:24714b45cd1b 316 x1 = _SIMD32_OFFSET(pScr1);
xorjoep 1:24714b45cd1b 317
xorjoep 1:24714b45cd1b 318 /* multiply and accumlate */
xorjoep 1:24714b45cd1b 319 acc0 = __SMLALD(x2, y2, acc0);
xorjoep 1:24714b45cd1b 320 acc2 = __SMLALD(x1, y2, acc2);
xorjoep 1:24714b45cd1b 321
xorjoep 1:24714b45cd1b 322 /* pack input data */
xorjoep 1:24714b45cd1b 323 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 324 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 325 #else
xorjoep 1:24714b45cd1b 326 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 327 #endif
xorjoep 1:24714b45cd1b 328
xorjoep 1:24714b45cd1b 329 acc3 = __SMLALDX(x3, y1, acc3);
xorjoep 1:24714b45cd1b 330 acc1 = __SMLALDX(x3, y2, acc1);
xorjoep 1:24714b45cd1b 331
xorjoep 1:24714b45cd1b 332 x2 = _SIMD32_OFFSET(pScr1 + 2U);
xorjoep 1:24714b45cd1b 333
xorjoep 1:24714b45cd1b 334 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 335 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 336 #else
xorjoep 1:24714b45cd1b 337 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 338 #endif
xorjoep 1:24714b45cd1b 339
xorjoep 1:24714b45cd1b 340 acc3 = __SMLALDX(x3, y2, acc3);
xorjoep 1:24714b45cd1b 341
xorjoep 1:24714b45cd1b 342 #else
xorjoep 1:24714b45cd1b 343
xorjoep 1:24714b45cd1b 344 /* Read four samples from smaller buffer */
xorjoep 1:24714b45cd1b 345 a = *pIn2;
xorjoep 1:24714b45cd1b 346 b = *(pIn2 + 1);
xorjoep 1:24714b45cd1b 347
xorjoep 1:24714b45cd1b 348 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 349 y1 = __PKHBT(a, b, 16);
xorjoep 1:24714b45cd1b 350 #else
xorjoep 1:24714b45cd1b 351 y1 = __PKHBT(b, a, 16);
xorjoep 1:24714b45cd1b 352 #endif
xorjoep 1:24714b45cd1b 353
xorjoep 1:24714b45cd1b 354 a = *(pIn2 + 2);
xorjoep 1:24714b45cd1b 355 b = *(pIn2 + 3);
xorjoep 1:24714b45cd1b 356 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 357 y2 = __PKHBT(a, b, 16);
xorjoep 1:24714b45cd1b 358 #else
xorjoep 1:24714b45cd1b 359 y2 = __PKHBT(b, a, 16);
xorjoep 1:24714b45cd1b 360 #endif
xorjoep 1:24714b45cd1b 361
xorjoep 1:24714b45cd1b 362 acc0 = __SMLALD(x1, y1, acc0);
xorjoep 1:24714b45cd1b 363
xorjoep 1:24714b45cd1b 364 acc2 = __SMLALD(x2, y1, acc2);
xorjoep 1:24714b45cd1b 365
xorjoep 1:24714b45cd1b 366 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 367 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 368 #else
xorjoep 1:24714b45cd1b 369 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 370 #endif
xorjoep 1:24714b45cd1b 371
xorjoep 1:24714b45cd1b 372 acc1 = __SMLALDX(x3, y1, acc1);
xorjoep 1:24714b45cd1b 373
xorjoep 1:24714b45cd1b 374 a = *pScr1;
xorjoep 1:24714b45cd1b 375 b = *(pScr1 + 1);
xorjoep 1:24714b45cd1b 376
xorjoep 1:24714b45cd1b 377 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 378 x1 = __PKHBT(a, b, 16);
xorjoep 1:24714b45cd1b 379 #else
xorjoep 1:24714b45cd1b 380 x1 = __PKHBT(b, a, 16);
xorjoep 1:24714b45cd1b 381 #endif
xorjoep 1:24714b45cd1b 382
xorjoep 1:24714b45cd1b 383 acc0 = __SMLALD(x2, y2, acc0);
xorjoep 1:24714b45cd1b 384
xorjoep 1:24714b45cd1b 385 acc2 = __SMLALD(x1, y2, acc2);
xorjoep 1:24714b45cd1b 386
xorjoep 1:24714b45cd1b 387 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 388 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 389 #else
xorjoep 1:24714b45cd1b 390 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 391 #endif
xorjoep 1:24714b45cd1b 392
xorjoep 1:24714b45cd1b 393 acc3 = __SMLALDX(x3, y1, acc3);
xorjoep 1:24714b45cd1b 394
xorjoep 1:24714b45cd1b 395 acc1 = __SMLALDX(x3, y2, acc1);
xorjoep 1:24714b45cd1b 396
xorjoep 1:24714b45cd1b 397 a = *(pScr1 + 2);
xorjoep 1:24714b45cd1b 398 b = *(pScr1 + 3);
xorjoep 1:24714b45cd1b 399
xorjoep 1:24714b45cd1b 400 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 401 x2 = __PKHBT(a, b, 16);
xorjoep 1:24714b45cd1b 402 #else
xorjoep 1:24714b45cd1b 403 x2 = __PKHBT(b, a, 16);
xorjoep 1:24714b45cd1b 404 #endif
xorjoep 1:24714b45cd1b 405
xorjoep 1:24714b45cd1b 406 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 407 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 408 #else
xorjoep 1:24714b45cd1b 409 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 410 #endif
xorjoep 1:24714b45cd1b 411
xorjoep 1:24714b45cd1b 412 acc3 = __SMLALDX(x3, y2, acc3);
xorjoep 1:24714b45cd1b 413
xorjoep 1:24714b45cd1b 414 #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
xorjoep 1:24714b45cd1b 415
xorjoep 1:24714b45cd1b 416 pIn2 += 4U;
xorjoep 1:24714b45cd1b 417 pScr1 += 4U;
xorjoep 1:24714b45cd1b 418
xorjoep 1:24714b45cd1b 419
xorjoep 1:24714b45cd1b 420 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 421 tapCnt--;
xorjoep 1:24714b45cd1b 422 }
xorjoep 1:24714b45cd1b 423
xorjoep 1:24714b45cd1b 424 /* Update scratch pointer for remaining samples of smaller length sequence */
xorjoep 1:24714b45cd1b 425 pScr1 -= 4U;
xorjoep 1:24714b45cd1b 426
xorjoep 1:24714b45cd1b 427 /* apply same above for remaining samples of smaller length sequence */
xorjoep 1:24714b45cd1b 428 tapCnt = (srcBLen) & 3U;
xorjoep 1:24714b45cd1b 429
xorjoep 1:24714b45cd1b 430 while (tapCnt > 0U)
xorjoep 1:24714b45cd1b 431 {
xorjoep 1:24714b45cd1b 432
xorjoep 1:24714b45cd1b 433 /* accumlate the results */
xorjoep 1:24714b45cd1b 434 acc0 += (*pScr1++ * *pIn2);
xorjoep 1:24714b45cd1b 435 acc1 += (*pScr1++ * *pIn2);
xorjoep 1:24714b45cd1b 436 acc2 += (*pScr1++ * *pIn2);
xorjoep 1:24714b45cd1b 437 acc3 += (*pScr1++ * *pIn2++);
xorjoep 1:24714b45cd1b 438
xorjoep 1:24714b45cd1b 439 pScr1 -= 3U;
xorjoep 1:24714b45cd1b 440
xorjoep 1:24714b45cd1b 441 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 442 tapCnt--;
xorjoep 1:24714b45cd1b 443 }
xorjoep 1:24714b45cd1b 444
xorjoep 1:24714b45cd1b 445 blkCnt--;
xorjoep 1:24714b45cd1b 446
xorjoep 1:24714b45cd1b 447
xorjoep 1:24714b45cd1b 448 /* Store the results in the accumulators in the destination buffer. */
xorjoep 1:24714b45cd1b 449
xorjoep 1:24714b45cd1b 450 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 451
xorjoep 1:24714b45cd1b 452 *__SIMD32(pOut)++ =
xorjoep 1:24714b45cd1b 453 __PKHBT(__SSAT((acc0 >> 15), 16), __SSAT((acc1 >> 15), 16), 16);
xorjoep 1:24714b45cd1b 454
xorjoep 1:24714b45cd1b 455 *__SIMD32(pOut)++ =
xorjoep 1:24714b45cd1b 456 __PKHBT(__SSAT((acc2 >> 15), 16), __SSAT((acc3 >> 15), 16), 16);
xorjoep 1:24714b45cd1b 457
xorjoep 1:24714b45cd1b 458 #else
xorjoep 1:24714b45cd1b 459
xorjoep 1:24714b45cd1b 460 *__SIMD32(pOut)++ =
xorjoep 1:24714b45cd1b 461 __PKHBT(__SSAT((acc1 >> 15), 16), __SSAT((acc0 >> 15), 16), 16);
xorjoep 1:24714b45cd1b 462
xorjoep 1:24714b45cd1b 463 *__SIMD32(pOut)++ =
xorjoep 1:24714b45cd1b 464 __PKHBT(__SSAT((acc3 >> 15), 16), __SSAT((acc2 >> 15), 16), 16);
xorjoep 1:24714b45cd1b 465
xorjoep 1:24714b45cd1b 466
xorjoep 1:24714b45cd1b 467 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
xorjoep 1:24714b45cd1b 468
xorjoep 1:24714b45cd1b 469 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 470 pIn2 = py;
xorjoep 1:24714b45cd1b 471
xorjoep 1:24714b45cd1b 472 pScratch1 += 4U;
xorjoep 1:24714b45cd1b 473
xorjoep 1:24714b45cd1b 474 }
xorjoep 1:24714b45cd1b 475
xorjoep 1:24714b45cd1b 476
xorjoep 1:24714b45cd1b 477 blkCnt = (srcALen + srcBLen - 1U) & 0x3;
xorjoep 1:24714b45cd1b 478
xorjoep 1:24714b45cd1b 479 /* Calculate convolution for remaining samples of Bigger length sequence */
xorjoep 1:24714b45cd1b 480 while (blkCnt > 0)
xorjoep 1:24714b45cd1b 481 {
xorjoep 1:24714b45cd1b 482 /* Initialze temporary scratch pointer as scratch1 */
xorjoep 1:24714b45cd1b 483 pScr1 = pScratch1;
xorjoep 1:24714b45cd1b 484
xorjoep 1:24714b45cd1b 485 /* Clear Accumlators */
xorjoep 1:24714b45cd1b 486 acc0 = 0;
xorjoep 1:24714b45cd1b 487
xorjoep 1:24714b45cd1b 488 tapCnt = (srcBLen) >> 1U;
xorjoep 1:24714b45cd1b 489
xorjoep 1:24714b45cd1b 490 while (tapCnt > 0U)
xorjoep 1:24714b45cd1b 491 {
xorjoep 1:24714b45cd1b 492
xorjoep 1:24714b45cd1b 493 /* Read next two samples from scratch1 buffer */
xorjoep 1:24714b45cd1b 494 acc0 += (*pScr1++ * *pIn2++);
xorjoep 1:24714b45cd1b 495 acc0 += (*pScr1++ * *pIn2++);
xorjoep 1:24714b45cd1b 496
xorjoep 1:24714b45cd1b 497 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 498 tapCnt--;
xorjoep 1:24714b45cd1b 499 }
xorjoep 1:24714b45cd1b 500
xorjoep 1:24714b45cd1b 501 tapCnt = (srcBLen) & 1U;
xorjoep 1:24714b45cd1b 502
xorjoep 1:24714b45cd1b 503 /* apply same above for remaining samples of smaller length sequence */
xorjoep 1:24714b45cd1b 504 while (tapCnt > 0U)
xorjoep 1:24714b45cd1b 505 {
xorjoep 1:24714b45cd1b 506
xorjoep 1:24714b45cd1b 507 /* accumlate the results */
xorjoep 1:24714b45cd1b 508 acc0 += (*pScr1++ * *pIn2++);
xorjoep 1:24714b45cd1b 509
xorjoep 1:24714b45cd1b 510 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 511 tapCnt--;
xorjoep 1:24714b45cd1b 512 }
xorjoep 1:24714b45cd1b 513
xorjoep 1:24714b45cd1b 514 blkCnt--;
xorjoep 1:24714b45cd1b 515
xorjoep 1:24714b45cd1b 516 /* The result is in 2.30 format. Convert to 1.15 with saturation.
xorjoep 1:24714b45cd1b 517 ** Then store the output in the destination buffer. */
xorjoep 1:24714b45cd1b 518 *pOut++ = (q15_t) (__SSAT((acc0 >> 15), 16));
xorjoep 1:24714b45cd1b 519
xorjoep 1:24714b45cd1b 520
xorjoep 1:24714b45cd1b 521 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 522 pIn2 = py;
xorjoep 1:24714b45cd1b 523
xorjoep 1:24714b45cd1b 524 pScratch1 += 1U;
xorjoep 1:24714b45cd1b 525
xorjoep 1:24714b45cd1b 526 }
xorjoep 1:24714b45cd1b 527
xorjoep 1:24714b45cd1b 528 }
xorjoep 1:24714b45cd1b 529
xorjoep 1:24714b45cd1b 530
xorjoep 1:24714b45cd1b 531 /**
xorjoep 1:24714b45cd1b 532 * @} end of Conv group
xorjoep 1:24714b45cd1b 533 */