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_fast_opt_q15.c
xorjoep 1:24714b45cd1b 4 * Description: Fast Q15 Convolution
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 (fast version) for Cortex-M3 and Cortex-M4.
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 * <b>Scaling and Overflow Behavior:</b>
xorjoep 1:24714b45cd1b 56 *
xorjoep 1:24714b45cd1b 57 * \par
xorjoep 1:24714b45cd1b 58 * This fast version uses a 32-bit accumulator with 2.30 format.
xorjoep 1:24714b45cd1b 59 * The accumulator maintains full precision of the intermediate multiplication results
xorjoep 1:24714b45cd1b 60 * but provides only a single guard bit. There is no saturation on intermediate additions.
xorjoep 1:24714b45cd1b 61 * Thus, if the accumulator overflows it wraps around and distorts the result.
xorjoep 1:24714b45cd1b 62 * The input signals should be scaled down to avoid intermediate overflows.
xorjoep 1:24714b45cd1b 63 * Scale down the inputs by log2(min(srcALen, srcBLen)) (log2 is read as log to the base 2) times to avoid overflows,
xorjoep 1:24714b45cd1b 64 * as maximum of min(srcALen, srcBLen) number of additions are carried internally.
xorjoep 1:24714b45cd1b 65 * The 2.30 accumulator is right shifted by 15 bits and then saturated to 1.15 format to yield the final result.
xorjoep 1:24714b45cd1b 66 *
xorjoep 1:24714b45cd1b 67 * \par
xorjoep 1:24714b45cd1b 68 * See <code>arm_conv_q15()</code> for a slower implementation of this function which uses 64-bit accumulation to avoid wrap around distortion.
xorjoep 1:24714b45cd1b 69 */
xorjoep 1:24714b45cd1b 70
xorjoep 1:24714b45cd1b 71 void arm_conv_fast_opt_q15(
xorjoep 1:24714b45cd1b 72 q15_t * pSrcA,
xorjoep 1:24714b45cd1b 73 uint32_t srcALen,
xorjoep 1:24714b45cd1b 74 q15_t * pSrcB,
xorjoep 1:24714b45cd1b 75 uint32_t srcBLen,
xorjoep 1:24714b45cd1b 76 q15_t * pDst,
xorjoep 1:24714b45cd1b 77 q15_t * pScratch1,
xorjoep 1:24714b45cd1b 78 q15_t * pScratch2)
xorjoep 1:24714b45cd1b 79 {
xorjoep 1:24714b45cd1b 80 q31_t acc0, acc1, acc2, acc3; /* Accumulators */
xorjoep 1:24714b45cd1b 81 q31_t x1, x2, x3; /* Temporary variables to hold state and coefficient values */
xorjoep 1:24714b45cd1b 82 q31_t y1, y2; /* State variables */
xorjoep 1:24714b45cd1b 83 q15_t *pOut = pDst; /* output pointer */
xorjoep 1:24714b45cd1b 84 q15_t *pScr1 = pScratch1; /* Temporary pointer for scratch1 */
xorjoep 1:24714b45cd1b 85 q15_t *pScr2 = pScratch2; /* Temporary pointer for scratch1 */
xorjoep 1:24714b45cd1b 86 q15_t *pIn1; /* inputA pointer */
xorjoep 1:24714b45cd1b 87 q15_t *pIn2; /* inputB pointer */
xorjoep 1:24714b45cd1b 88 q15_t *px; /* Intermediate inputA pointer */
xorjoep 1:24714b45cd1b 89 q15_t *py; /* Intermediate inputB pointer */
xorjoep 1:24714b45cd1b 90 uint32_t j, k, blkCnt; /* loop counter */
xorjoep 1:24714b45cd1b 91 uint32_t tapCnt; /* loop count */
xorjoep 1:24714b45cd1b 92 #ifdef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 93
xorjoep 1:24714b45cd1b 94 q15_t a, b;
xorjoep 1:24714b45cd1b 95
xorjoep 1:24714b45cd1b 96 #endif /* #ifdef UNALIGNED_SUPPORT_DISABLE */
xorjoep 1:24714b45cd1b 97
xorjoep 1:24714b45cd1b 98 /* The algorithm implementation is based on the lengths of the inputs. */
xorjoep 1:24714b45cd1b 99 /* srcB is always made to slide across srcA. */
xorjoep 1:24714b45cd1b 100 /* So srcBLen is always considered as shorter or equal to srcALen */
xorjoep 1:24714b45cd1b 101 if (srcALen >= srcBLen)
xorjoep 1:24714b45cd1b 102 {
xorjoep 1:24714b45cd1b 103 /* Initialization of inputA pointer */
xorjoep 1:24714b45cd1b 104 pIn1 = pSrcA;
xorjoep 1:24714b45cd1b 105
xorjoep 1:24714b45cd1b 106 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 107 pIn2 = pSrcB;
xorjoep 1:24714b45cd1b 108 }
xorjoep 1:24714b45cd1b 109 else
xorjoep 1:24714b45cd1b 110 {
xorjoep 1:24714b45cd1b 111 /* Initialization of inputA pointer */
xorjoep 1:24714b45cd1b 112 pIn1 = pSrcB;
xorjoep 1:24714b45cd1b 113
xorjoep 1:24714b45cd1b 114 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 115 pIn2 = pSrcA;
xorjoep 1:24714b45cd1b 116
xorjoep 1:24714b45cd1b 117 /* srcBLen is always considered as shorter or equal to srcALen */
xorjoep 1:24714b45cd1b 118 j = srcBLen;
xorjoep 1:24714b45cd1b 119 srcBLen = srcALen;
xorjoep 1:24714b45cd1b 120 srcALen = j;
xorjoep 1:24714b45cd1b 121 }
xorjoep 1:24714b45cd1b 122
xorjoep 1:24714b45cd1b 123 /* Pointer to take end of scratch2 buffer */
xorjoep 1:24714b45cd1b 124 pScr2 = pScratch2 + srcBLen - 1;
xorjoep 1:24714b45cd1b 125
xorjoep 1:24714b45cd1b 126 /* points to smaller length sequence */
xorjoep 1:24714b45cd1b 127 px = pIn2;
xorjoep 1:24714b45cd1b 128
xorjoep 1:24714b45cd1b 129 /* Apply loop unrolling and do 4 Copies simultaneously. */
xorjoep 1:24714b45cd1b 130 k = srcBLen >> 2U;
xorjoep 1:24714b45cd1b 131
xorjoep 1:24714b45cd1b 132 /* First part of the processing with loop unrolling copies 4 data points at a time.
xorjoep 1:24714b45cd1b 133 ** a second loop below copies for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 134
xorjoep 1:24714b45cd1b 135 /* Copy smaller length input sequence in reverse order into second scratch buffer */
xorjoep 1:24714b45cd1b 136 while (k > 0U)
xorjoep 1:24714b45cd1b 137 {
xorjoep 1:24714b45cd1b 138 /* copy second buffer in reversal manner */
xorjoep 1:24714b45cd1b 139 *pScr2-- = *px++;
xorjoep 1:24714b45cd1b 140 *pScr2-- = *px++;
xorjoep 1:24714b45cd1b 141 *pScr2-- = *px++;
xorjoep 1:24714b45cd1b 142 *pScr2-- = *px++;
xorjoep 1:24714b45cd1b 143
xorjoep 1:24714b45cd1b 144 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 145 k--;
xorjoep 1:24714b45cd1b 146 }
xorjoep 1:24714b45cd1b 147
xorjoep 1:24714b45cd1b 148 /* If the count is not a multiple of 4, copy remaining samples here.
xorjoep 1:24714b45cd1b 149 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 150 k = srcBLen % 0x4U;
xorjoep 1:24714b45cd1b 151
xorjoep 1:24714b45cd1b 152 while (k > 0U)
xorjoep 1:24714b45cd1b 153 {
xorjoep 1:24714b45cd1b 154 /* copy second buffer in reversal manner for remaining samples */
xorjoep 1:24714b45cd1b 155 *pScr2-- = *px++;
xorjoep 1:24714b45cd1b 156
xorjoep 1:24714b45cd1b 157 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 158 k--;
xorjoep 1:24714b45cd1b 159 }
xorjoep 1:24714b45cd1b 160
xorjoep 1:24714b45cd1b 161 /* Initialze temporary scratch pointer */
xorjoep 1:24714b45cd1b 162 pScr1 = pScratch1;
xorjoep 1:24714b45cd1b 163
xorjoep 1:24714b45cd1b 164 /* Assuming scratch1 buffer is aligned by 32-bit */
xorjoep 1:24714b45cd1b 165 /* Fill (srcBLen - 1U) zeros in scratch1 buffer */
xorjoep 1:24714b45cd1b 166 arm_fill_q15(0, pScr1, (srcBLen - 1U));
xorjoep 1:24714b45cd1b 167
xorjoep 1:24714b45cd1b 168 /* Update temporary scratch pointer */
xorjoep 1:24714b45cd1b 169 pScr1 += (srcBLen - 1U);
xorjoep 1:24714b45cd1b 170
xorjoep 1:24714b45cd1b 171 /* Copy bigger length sequence(srcALen) samples in scratch1 buffer */
xorjoep 1:24714b45cd1b 172
xorjoep 1:24714b45cd1b 173 #ifndef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 174
xorjoep 1:24714b45cd1b 175 /* Copy (srcALen) samples in scratch buffer */
xorjoep 1:24714b45cd1b 176 arm_copy_q15(pIn1, pScr1, srcALen);
xorjoep 1:24714b45cd1b 177
xorjoep 1:24714b45cd1b 178 /* Update pointers */
xorjoep 1:24714b45cd1b 179 pScr1 += srcALen;
xorjoep 1:24714b45cd1b 180
xorjoep 1:24714b45cd1b 181 #else
xorjoep 1:24714b45cd1b 182
xorjoep 1:24714b45cd1b 183 /* Apply loop unrolling and do 4 Copies simultaneously. */
xorjoep 1:24714b45cd1b 184 k = srcALen >> 2U;
xorjoep 1:24714b45cd1b 185
xorjoep 1:24714b45cd1b 186 /* First part of the processing with loop unrolling copies 4 data points at a time.
xorjoep 1:24714b45cd1b 187 ** a second loop below copies for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 188 while (k > 0U)
xorjoep 1:24714b45cd1b 189 {
xorjoep 1:24714b45cd1b 190 /* copy second buffer in reversal manner */
xorjoep 1:24714b45cd1b 191 *pScr1++ = *pIn1++;
xorjoep 1:24714b45cd1b 192 *pScr1++ = *pIn1++;
xorjoep 1:24714b45cd1b 193 *pScr1++ = *pIn1++;
xorjoep 1:24714b45cd1b 194 *pScr1++ = *pIn1++;
xorjoep 1:24714b45cd1b 195
xorjoep 1:24714b45cd1b 196 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 197 k--;
xorjoep 1:24714b45cd1b 198 }
xorjoep 1:24714b45cd1b 199
xorjoep 1:24714b45cd1b 200 /* If the count is not a multiple of 4, copy remaining samples here.
xorjoep 1:24714b45cd1b 201 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 202 k = srcALen % 0x4U;
xorjoep 1:24714b45cd1b 203
xorjoep 1:24714b45cd1b 204 while (k > 0U)
xorjoep 1:24714b45cd1b 205 {
xorjoep 1:24714b45cd1b 206 /* copy second buffer in reversal manner for remaining samples */
xorjoep 1:24714b45cd1b 207 *pScr1++ = *pIn1++;
xorjoep 1:24714b45cd1b 208
xorjoep 1:24714b45cd1b 209 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 210 k--;
xorjoep 1:24714b45cd1b 211 }
xorjoep 1:24714b45cd1b 212
xorjoep 1:24714b45cd1b 213 #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
xorjoep 1:24714b45cd1b 214
xorjoep 1:24714b45cd1b 215
xorjoep 1:24714b45cd1b 216 #ifndef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 217
xorjoep 1:24714b45cd1b 218 /* Fill (srcBLen - 1U) zeros at end of scratch buffer */
xorjoep 1:24714b45cd1b 219 arm_fill_q15(0, pScr1, (srcBLen - 1U));
xorjoep 1:24714b45cd1b 220
xorjoep 1:24714b45cd1b 221 /* Update pointer */
xorjoep 1:24714b45cd1b 222 pScr1 += (srcBLen - 1U);
xorjoep 1:24714b45cd1b 223
xorjoep 1:24714b45cd1b 224 #else
xorjoep 1:24714b45cd1b 225
xorjoep 1:24714b45cd1b 226 /* Apply loop unrolling and do 4 Copies simultaneously. */
xorjoep 1:24714b45cd1b 227 k = (srcBLen - 1U) >> 2U;
xorjoep 1:24714b45cd1b 228
xorjoep 1:24714b45cd1b 229 /* First part of the processing with loop unrolling copies 4 data points at a time.
xorjoep 1:24714b45cd1b 230 ** a second loop below copies for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 231 while (k > 0U)
xorjoep 1:24714b45cd1b 232 {
xorjoep 1:24714b45cd1b 233 /* copy second buffer in reversal manner */
xorjoep 1:24714b45cd1b 234 *pScr1++ = 0;
xorjoep 1:24714b45cd1b 235 *pScr1++ = 0;
xorjoep 1:24714b45cd1b 236 *pScr1++ = 0;
xorjoep 1:24714b45cd1b 237 *pScr1++ = 0;
xorjoep 1:24714b45cd1b 238
xorjoep 1:24714b45cd1b 239 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 240 k--;
xorjoep 1:24714b45cd1b 241 }
xorjoep 1:24714b45cd1b 242
xorjoep 1:24714b45cd1b 243 /* If the count is not a multiple of 4, copy remaining samples here.
xorjoep 1:24714b45cd1b 244 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 245 k = (srcBLen - 1U) % 0x4U;
xorjoep 1:24714b45cd1b 246
xorjoep 1:24714b45cd1b 247 while (k > 0U)
xorjoep 1:24714b45cd1b 248 {
xorjoep 1:24714b45cd1b 249 /* copy second buffer in reversal manner for remaining samples */
xorjoep 1:24714b45cd1b 250 *pScr1++ = 0;
xorjoep 1:24714b45cd1b 251
xorjoep 1:24714b45cd1b 252 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 253 k--;
xorjoep 1:24714b45cd1b 254 }
xorjoep 1:24714b45cd1b 255
xorjoep 1:24714b45cd1b 256 #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
xorjoep 1:24714b45cd1b 257
xorjoep 1:24714b45cd1b 258 /* Temporary pointer for scratch2 */
xorjoep 1:24714b45cd1b 259 py = pScratch2;
xorjoep 1:24714b45cd1b 260
xorjoep 1:24714b45cd1b 261
xorjoep 1:24714b45cd1b 262 /* Initialization of pIn2 pointer */
xorjoep 1:24714b45cd1b 263 pIn2 = py;
xorjoep 1:24714b45cd1b 264
xorjoep 1:24714b45cd1b 265 /* First part of the processing with loop unrolling process 4 data points at a time.
xorjoep 1:24714b45cd1b 266 ** a second loop below process for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 267
xorjoep 1:24714b45cd1b 268 /* Actual convolution process starts here */
xorjoep 1:24714b45cd1b 269 blkCnt = (srcALen + srcBLen - 1U) >> 2;
xorjoep 1:24714b45cd1b 270
xorjoep 1:24714b45cd1b 271 while (blkCnt > 0)
xorjoep 1:24714b45cd1b 272 {
xorjoep 1:24714b45cd1b 273 /* Initialze temporary scratch pointer as scratch1 */
xorjoep 1:24714b45cd1b 274 pScr1 = pScratch1;
xorjoep 1:24714b45cd1b 275
xorjoep 1:24714b45cd1b 276 /* Clear Accumlators */
xorjoep 1:24714b45cd1b 277 acc0 = 0;
xorjoep 1:24714b45cd1b 278 acc1 = 0;
xorjoep 1:24714b45cd1b 279 acc2 = 0;
xorjoep 1:24714b45cd1b 280 acc3 = 0;
xorjoep 1:24714b45cd1b 281
xorjoep 1:24714b45cd1b 282 /* Read two samples from scratch1 buffer */
xorjoep 1:24714b45cd1b 283 x1 = *__SIMD32(pScr1)++;
xorjoep 1:24714b45cd1b 284
xorjoep 1:24714b45cd1b 285 /* Read next two samples from scratch1 buffer */
xorjoep 1:24714b45cd1b 286 x2 = *__SIMD32(pScr1)++;
xorjoep 1:24714b45cd1b 287
xorjoep 1:24714b45cd1b 288 tapCnt = (srcBLen) >> 2U;
xorjoep 1:24714b45cd1b 289
xorjoep 1:24714b45cd1b 290 while (tapCnt > 0U)
xorjoep 1:24714b45cd1b 291 {
xorjoep 1:24714b45cd1b 292
xorjoep 1:24714b45cd1b 293 #ifndef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 294
xorjoep 1:24714b45cd1b 295 /* Read four samples from smaller buffer */
xorjoep 1:24714b45cd1b 296 y1 = _SIMD32_OFFSET(pIn2);
xorjoep 1:24714b45cd1b 297 y2 = _SIMD32_OFFSET(pIn2 + 2U);
xorjoep 1:24714b45cd1b 298
xorjoep 1:24714b45cd1b 299 /* multiply and accumlate */
xorjoep 1:24714b45cd1b 300 acc0 = __SMLAD(x1, y1, acc0);
xorjoep 1:24714b45cd1b 301 acc2 = __SMLAD(x2, y1, acc2);
xorjoep 1:24714b45cd1b 302
xorjoep 1:24714b45cd1b 303 /* pack input data */
xorjoep 1:24714b45cd1b 304 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 305 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 306 #else
xorjoep 1:24714b45cd1b 307 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 308 #endif
xorjoep 1:24714b45cd1b 309
xorjoep 1:24714b45cd1b 310 /* multiply and accumlate */
xorjoep 1:24714b45cd1b 311 acc1 = __SMLADX(x3, y1, acc1);
xorjoep 1:24714b45cd1b 312
xorjoep 1:24714b45cd1b 313 /* Read next two samples from scratch1 buffer */
xorjoep 1:24714b45cd1b 314 x1 = _SIMD32_OFFSET(pScr1);
xorjoep 1:24714b45cd1b 315
xorjoep 1:24714b45cd1b 316 /* multiply and accumlate */
xorjoep 1:24714b45cd1b 317 acc0 = __SMLAD(x2, y2, acc0);
xorjoep 1:24714b45cd1b 318 acc2 = __SMLAD(x1, y2, acc2);
xorjoep 1:24714b45cd1b 319
xorjoep 1:24714b45cd1b 320 /* pack input data */
xorjoep 1:24714b45cd1b 321 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 322 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 323 #else
xorjoep 1:24714b45cd1b 324 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 325 #endif
xorjoep 1:24714b45cd1b 326
xorjoep 1:24714b45cd1b 327 acc3 = __SMLADX(x3, y1, acc3);
xorjoep 1:24714b45cd1b 328 acc1 = __SMLADX(x3, y2, acc1);
xorjoep 1:24714b45cd1b 329
xorjoep 1:24714b45cd1b 330 x2 = _SIMD32_OFFSET(pScr1 + 2U);
xorjoep 1:24714b45cd1b 331
xorjoep 1:24714b45cd1b 332 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 333 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 334 #else
xorjoep 1:24714b45cd1b 335 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 336 #endif
xorjoep 1:24714b45cd1b 337
xorjoep 1:24714b45cd1b 338 acc3 = __SMLADX(x3, y2, acc3);
xorjoep 1:24714b45cd1b 339
xorjoep 1:24714b45cd1b 340 #else
xorjoep 1:24714b45cd1b 341
xorjoep 1:24714b45cd1b 342 /* Read four samples from smaller buffer */
xorjoep 1:24714b45cd1b 343 a = *pIn2;
xorjoep 1:24714b45cd1b 344 b = *(pIn2 + 1);
xorjoep 1:24714b45cd1b 345
xorjoep 1:24714b45cd1b 346 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 347 y1 = __PKHBT(a, b, 16);
xorjoep 1:24714b45cd1b 348 #else
xorjoep 1:24714b45cd1b 349 y1 = __PKHBT(b, a, 16);
xorjoep 1:24714b45cd1b 350 #endif
xorjoep 1:24714b45cd1b 351
xorjoep 1:24714b45cd1b 352 a = *(pIn2 + 2);
xorjoep 1:24714b45cd1b 353 b = *(pIn2 + 3);
xorjoep 1:24714b45cd1b 354 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 355 y2 = __PKHBT(a, b, 16);
xorjoep 1:24714b45cd1b 356 #else
xorjoep 1:24714b45cd1b 357 y2 = __PKHBT(b, a, 16);
xorjoep 1:24714b45cd1b 358 #endif
xorjoep 1:24714b45cd1b 359
xorjoep 1:24714b45cd1b 360 acc0 = __SMLAD(x1, y1, acc0);
xorjoep 1:24714b45cd1b 361
xorjoep 1:24714b45cd1b 362 acc2 = __SMLAD(x2, y1, acc2);
xorjoep 1:24714b45cd1b 363
xorjoep 1:24714b45cd1b 364 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 365 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 366 #else
xorjoep 1:24714b45cd1b 367 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 368 #endif
xorjoep 1:24714b45cd1b 369
xorjoep 1:24714b45cd1b 370 acc1 = __SMLADX(x3, y1, acc1);
xorjoep 1:24714b45cd1b 371
xorjoep 1:24714b45cd1b 372 a = *pScr1;
xorjoep 1:24714b45cd1b 373 b = *(pScr1 + 1);
xorjoep 1:24714b45cd1b 374
xorjoep 1:24714b45cd1b 375 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 376 x1 = __PKHBT(a, b, 16);
xorjoep 1:24714b45cd1b 377 #else
xorjoep 1:24714b45cd1b 378 x1 = __PKHBT(b, a, 16);
xorjoep 1:24714b45cd1b 379 #endif
xorjoep 1:24714b45cd1b 380
xorjoep 1:24714b45cd1b 381 acc0 = __SMLAD(x2, y2, acc0);
xorjoep 1:24714b45cd1b 382
xorjoep 1:24714b45cd1b 383 acc2 = __SMLAD(x1, y2, acc2);
xorjoep 1:24714b45cd1b 384
xorjoep 1:24714b45cd1b 385 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 386 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 387 #else
xorjoep 1:24714b45cd1b 388 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 389 #endif
xorjoep 1:24714b45cd1b 390
xorjoep 1:24714b45cd1b 391 acc3 = __SMLADX(x3, y1, acc3);
xorjoep 1:24714b45cd1b 392
xorjoep 1:24714b45cd1b 393 acc1 = __SMLADX(x3, y2, acc1);
xorjoep 1:24714b45cd1b 394
xorjoep 1:24714b45cd1b 395 a = *(pScr1 + 2);
xorjoep 1:24714b45cd1b 396 b = *(pScr1 + 3);
xorjoep 1:24714b45cd1b 397
xorjoep 1:24714b45cd1b 398 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 399 x2 = __PKHBT(a, b, 16);
xorjoep 1:24714b45cd1b 400 #else
xorjoep 1:24714b45cd1b 401 x2 = __PKHBT(b, a, 16);
xorjoep 1:24714b45cd1b 402 #endif
xorjoep 1:24714b45cd1b 403
xorjoep 1:24714b45cd1b 404 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 405 x3 = __PKHBT(x2, x1, 0);
xorjoep 1:24714b45cd1b 406 #else
xorjoep 1:24714b45cd1b 407 x3 = __PKHBT(x1, x2, 0);
xorjoep 1:24714b45cd1b 408 #endif
xorjoep 1:24714b45cd1b 409
xorjoep 1:24714b45cd1b 410 acc3 = __SMLADX(x3, y2, acc3);
xorjoep 1:24714b45cd1b 411
xorjoep 1:24714b45cd1b 412 #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
xorjoep 1:24714b45cd1b 413
xorjoep 1:24714b45cd1b 414 /* update scratch pointers */
xorjoep 1:24714b45cd1b 415 pIn2 += 4U;
xorjoep 1:24714b45cd1b 416 pScr1 += 4U;
xorjoep 1:24714b45cd1b 417
xorjoep 1:24714b45cd1b 418
xorjoep 1:24714b45cd1b 419 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 420 tapCnt--;
xorjoep 1:24714b45cd1b 421 }
xorjoep 1:24714b45cd1b 422
xorjoep 1:24714b45cd1b 423 /* Update scratch pointer for remaining samples of smaller length sequence */
xorjoep 1:24714b45cd1b 424 pScr1 -= 4U;
xorjoep 1:24714b45cd1b 425
xorjoep 1:24714b45cd1b 426 /* apply same above for remaining samples of smaller length sequence */
xorjoep 1:24714b45cd1b 427 tapCnt = (srcBLen) & 3U;
xorjoep 1:24714b45cd1b 428
xorjoep 1:24714b45cd1b 429 while (tapCnt > 0U)
xorjoep 1:24714b45cd1b 430 {
xorjoep 1:24714b45cd1b 431
xorjoep 1:24714b45cd1b 432 /* accumlate the results */
xorjoep 1:24714b45cd1b 433 acc0 += (*pScr1++ * *pIn2);
xorjoep 1:24714b45cd1b 434 acc1 += (*pScr1++ * *pIn2);
xorjoep 1:24714b45cd1b 435 acc2 += (*pScr1++ * *pIn2);
xorjoep 1:24714b45cd1b 436 acc3 += (*pScr1++ * *pIn2++);
xorjoep 1:24714b45cd1b 437
xorjoep 1:24714b45cd1b 438 pScr1 -= 3U;
xorjoep 1:24714b45cd1b 439
xorjoep 1:24714b45cd1b 440 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 441 tapCnt--;
xorjoep 1:24714b45cd1b 442 }
xorjoep 1:24714b45cd1b 443
xorjoep 1:24714b45cd1b 444 blkCnt--;
xorjoep 1:24714b45cd1b 445
xorjoep 1:24714b45cd1b 446
xorjoep 1:24714b45cd1b 447 /* Store the results in the accumulators in the destination buffer. */
xorjoep 1:24714b45cd1b 448
xorjoep 1:24714b45cd1b 449 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 450
xorjoep 1:24714b45cd1b 451 *__SIMD32(pOut)++ =
xorjoep 1:24714b45cd1b 452 __PKHBT(__SSAT((acc0 >> 15), 16), __SSAT((acc1 >> 15), 16), 16);
xorjoep 1:24714b45cd1b 453
xorjoep 1:24714b45cd1b 454 *__SIMD32(pOut)++ =
xorjoep 1:24714b45cd1b 455 __PKHBT(__SSAT((acc2 >> 15), 16), __SSAT((acc3 >> 15), 16), 16);
xorjoep 1:24714b45cd1b 456
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
xorjoep 1:24714b45cd1b 468 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
xorjoep 1:24714b45cd1b 469
xorjoep 1:24714b45cd1b 470 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 471 pIn2 = py;
xorjoep 1:24714b45cd1b 472
xorjoep 1:24714b45cd1b 473 pScratch1 += 4U;
xorjoep 1:24714b45cd1b 474
xorjoep 1:24714b45cd1b 475 }
xorjoep 1:24714b45cd1b 476
xorjoep 1:24714b45cd1b 477
xorjoep 1:24714b45cd1b 478 blkCnt = (srcALen + srcBLen - 1U) & 0x3;
xorjoep 1:24714b45cd1b 479
xorjoep 1:24714b45cd1b 480 /* Calculate convolution for remaining samples of Bigger length sequence */
xorjoep 1:24714b45cd1b 481 while (blkCnt > 0)
xorjoep 1:24714b45cd1b 482 {
xorjoep 1:24714b45cd1b 483 /* Initialze temporary scratch pointer as scratch1 */
xorjoep 1:24714b45cd1b 484 pScr1 = pScratch1;
xorjoep 1:24714b45cd1b 485
xorjoep 1:24714b45cd1b 486 /* Clear Accumlators */
xorjoep 1:24714b45cd1b 487 acc0 = 0;
xorjoep 1:24714b45cd1b 488
xorjoep 1:24714b45cd1b 489 tapCnt = (srcBLen) >> 1U;
xorjoep 1:24714b45cd1b 490
xorjoep 1:24714b45cd1b 491 while (tapCnt > 0U)
xorjoep 1:24714b45cd1b 492 {
xorjoep 1:24714b45cd1b 493
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 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 521 pIn2 = py;
xorjoep 1:24714b45cd1b 522
xorjoep 1:24714b45cd1b 523 pScratch1 += 1U;
xorjoep 1:24714b45cd1b 524
xorjoep 1:24714b45cd1b 525 }
xorjoep 1:24714b45cd1b 526
xorjoep 1:24714b45cd1b 527 }
xorjoep 1:24714b45cd1b 528
xorjoep 1:24714b45cd1b 529 /**
xorjoep 1:24714b45cd1b 530 * @} end of Conv group
xorjoep 1:24714b45cd1b 531 */