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_partial_fast_q31.c
xorjoep 1:24714b45cd1b 4 * Description: Fast Q31 Partial 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 PartialConv
xorjoep 1:24714b45cd1b 37 * @{
xorjoep 1:24714b45cd1b 38 */
xorjoep 1:24714b45cd1b 39
xorjoep 1:24714b45cd1b 40 /**
xorjoep 1:24714b45cd1b 41 * @brief Partial convolution of Q31 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.
xorjoep 1:24714b45cd1b 47 * @param[in] firstIndex is the first output sample to start with.
xorjoep 1:24714b45cd1b 48 * @param[in] numPoints is the number of output points to be computed.
xorjoep 1:24714b45cd1b 49 * @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].
xorjoep 1:24714b45cd1b 50 *
xorjoep 1:24714b45cd1b 51 * \par
xorjoep 1:24714b45cd1b 52 * See <code>arm_conv_partial_q31()</code> for a slower implementation of this function which uses a 64-bit accumulator to provide higher precision.
xorjoep 1:24714b45cd1b 53 */
xorjoep 1:24714b45cd1b 54
xorjoep 1:24714b45cd1b 55 arm_status arm_conv_partial_fast_q31(
xorjoep 1:24714b45cd1b 56 q31_t * pSrcA,
xorjoep 1:24714b45cd1b 57 uint32_t srcALen,
xorjoep 1:24714b45cd1b 58 q31_t * pSrcB,
xorjoep 1:24714b45cd1b 59 uint32_t srcBLen,
xorjoep 1:24714b45cd1b 60 q31_t * pDst,
xorjoep 1:24714b45cd1b 61 uint32_t firstIndex,
xorjoep 1:24714b45cd1b 62 uint32_t numPoints)
xorjoep 1:24714b45cd1b 63 {
xorjoep 1:24714b45cd1b 64 q31_t *pIn1; /* inputA pointer */
xorjoep 1:24714b45cd1b 65 q31_t *pIn2; /* inputB pointer */
xorjoep 1:24714b45cd1b 66 q31_t *pOut = pDst; /* output pointer */
xorjoep 1:24714b45cd1b 67 q31_t *px; /* Intermediate inputA pointer */
xorjoep 1:24714b45cd1b 68 q31_t *py; /* Intermediate inputB pointer */
xorjoep 1:24714b45cd1b 69 q31_t *pSrc1, *pSrc2; /* Intermediate pointers */
xorjoep 1:24714b45cd1b 70 q31_t sum, acc0, acc1, acc2, acc3; /* Accumulators */
xorjoep 1:24714b45cd1b 71 q31_t x0, x1, x2, x3, c0;
xorjoep 1:24714b45cd1b 72 uint32_t j, k, count, check, blkCnt;
xorjoep 1:24714b45cd1b 73 int32_t blockSize1, blockSize2, blockSize3; /* loop counters */
xorjoep 1:24714b45cd1b 74 arm_status status; /* status of Partial convolution */
xorjoep 1:24714b45cd1b 75
xorjoep 1:24714b45cd1b 76
xorjoep 1:24714b45cd1b 77 /* Check for range of output samples to be calculated */
xorjoep 1:24714b45cd1b 78 if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U))))
xorjoep 1:24714b45cd1b 79 {
xorjoep 1:24714b45cd1b 80 /* Set status as ARM_MATH_ARGUMENT_ERROR */
xorjoep 1:24714b45cd1b 81 status = ARM_MATH_ARGUMENT_ERROR;
xorjoep 1:24714b45cd1b 82 }
xorjoep 1:24714b45cd1b 83 else
xorjoep 1:24714b45cd1b 84 {
xorjoep 1:24714b45cd1b 85
xorjoep 1:24714b45cd1b 86 /* The algorithm implementation is based on the lengths of the inputs. */
xorjoep 1:24714b45cd1b 87 /* srcB is always made to slide across srcA. */
xorjoep 1:24714b45cd1b 88 /* So srcBLen is always considered as shorter or equal to srcALen */
xorjoep 1:24714b45cd1b 89 if (srcALen >= srcBLen)
xorjoep 1:24714b45cd1b 90 {
xorjoep 1:24714b45cd1b 91 /* Initialization of inputA pointer */
xorjoep 1:24714b45cd1b 92 pIn1 = pSrcA;
xorjoep 1:24714b45cd1b 93
xorjoep 1:24714b45cd1b 94 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 95 pIn2 = pSrcB;
xorjoep 1:24714b45cd1b 96 }
xorjoep 1:24714b45cd1b 97 else
xorjoep 1:24714b45cd1b 98 {
xorjoep 1:24714b45cd1b 99 /* Initialization of inputA pointer */
xorjoep 1:24714b45cd1b 100 pIn1 = pSrcB;
xorjoep 1:24714b45cd1b 101
xorjoep 1:24714b45cd1b 102 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 103 pIn2 = pSrcA;
xorjoep 1:24714b45cd1b 104
xorjoep 1:24714b45cd1b 105 /* srcBLen is always considered as shorter or equal to srcALen */
xorjoep 1:24714b45cd1b 106 j = srcBLen;
xorjoep 1:24714b45cd1b 107 srcBLen = srcALen;
xorjoep 1:24714b45cd1b 108 srcALen = j;
xorjoep 1:24714b45cd1b 109 }
xorjoep 1:24714b45cd1b 110
xorjoep 1:24714b45cd1b 111 /* Conditions to check which loopCounter holds
xorjoep 1:24714b45cd1b 112 * the first and last indices of the output samples to be calculated. */
xorjoep 1:24714b45cd1b 113 check = firstIndex + numPoints;
xorjoep 1:24714b45cd1b 114 blockSize3 = ((int32_t)check > (int32_t)srcALen) ? (int32_t)check - (int32_t)srcALen : 0;
xorjoep 1:24714b45cd1b 115 blockSize3 = ((int32_t)firstIndex > (int32_t)srcALen - 1) ? blockSize3 - (int32_t)firstIndex + (int32_t)srcALen : blockSize3;
xorjoep 1:24714b45cd1b 116 blockSize1 = (((int32_t) srcBLen - 1) - (int32_t) firstIndex);
xorjoep 1:24714b45cd1b 117 blockSize1 = (blockSize1 > 0) ? ((check > (srcBLen - 1U)) ? blockSize1 :
xorjoep 1:24714b45cd1b 118 (int32_t) numPoints) : 0;
xorjoep 1:24714b45cd1b 119 blockSize2 = (int32_t) check - ((blockSize3 + blockSize1) +
xorjoep 1:24714b45cd1b 120 (int32_t) firstIndex);
xorjoep 1:24714b45cd1b 121 blockSize2 = (blockSize2 > 0) ? blockSize2 : 0;
xorjoep 1:24714b45cd1b 122
xorjoep 1:24714b45cd1b 123 /* 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] */
xorjoep 1:24714b45cd1b 124 /* The function is internally
xorjoep 1:24714b45cd1b 125 * divided into three stages according to the number of multiplications that has to be
xorjoep 1:24714b45cd1b 126 * taken place between inputA samples and inputB samples. In the first stage of the
xorjoep 1:24714b45cd1b 127 * algorithm, the multiplications increase by one for every iteration.
xorjoep 1:24714b45cd1b 128 * In the second stage of the algorithm, srcBLen number of multiplications are done.
xorjoep 1:24714b45cd1b 129 * In the third stage of the algorithm, the multiplications decrease by one
xorjoep 1:24714b45cd1b 130 * for every iteration. */
xorjoep 1:24714b45cd1b 131
xorjoep 1:24714b45cd1b 132 /* Set the output pointer to point to the firstIndex
xorjoep 1:24714b45cd1b 133 * of the output sample to be calculated. */
xorjoep 1:24714b45cd1b 134 pOut = pDst + firstIndex;
xorjoep 1:24714b45cd1b 135
xorjoep 1:24714b45cd1b 136 /* --------------------------
xorjoep 1:24714b45cd1b 137 * Initializations of stage1
xorjoep 1:24714b45cd1b 138 * -------------------------*/
xorjoep 1:24714b45cd1b 139
xorjoep 1:24714b45cd1b 140 /* sum = x[0] * y[0]
xorjoep 1:24714b45cd1b 141 * sum = x[0] * y[1] + x[1] * y[0]
xorjoep 1:24714b45cd1b 142 * ....
xorjoep 1:24714b45cd1b 143 * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0]
xorjoep 1:24714b45cd1b 144 */
xorjoep 1:24714b45cd1b 145
xorjoep 1:24714b45cd1b 146 /* In this stage the MAC operations are increased by 1 for every iteration.
xorjoep 1:24714b45cd1b 147 The count variable holds the number of MAC operations performed.
xorjoep 1:24714b45cd1b 148 Since the partial convolution starts from firstIndex
xorjoep 1:24714b45cd1b 149 Number of Macs to be performed is firstIndex + 1 */
xorjoep 1:24714b45cd1b 150 count = 1U + firstIndex;
xorjoep 1:24714b45cd1b 151
xorjoep 1:24714b45cd1b 152 /* Working pointer of inputA */
xorjoep 1:24714b45cd1b 153 px = pIn1;
xorjoep 1:24714b45cd1b 154
xorjoep 1:24714b45cd1b 155 /* Working pointer of inputB */
xorjoep 1:24714b45cd1b 156 pSrc2 = pIn2 + firstIndex;
xorjoep 1:24714b45cd1b 157 py = pSrc2;
xorjoep 1:24714b45cd1b 158
xorjoep 1:24714b45cd1b 159 /* ------------------------
xorjoep 1:24714b45cd1b 160 * Stage1 process
xorjoep 1:24714b45cd1b 161 * ----------------------*/
xorjoep 1:24714b45cd1b 162
xorjoep 1:24714b45cd1b 163 /* The first loop starts here */
xorjoep 1:24714b45cd1b 164 while (blockSize1 > 0)
xorjoep 1:24714b45cd1b 165 {
xorjoep 1:24714b45cd1b 166 /* Accumulator is made zero for every iteration */
xorjoep 1:24714b45cd1b 167 sum = 0;
xorjoep 1:24714b45cd1b 168
xorjoep 1:24714b45cd1b 169 /* Apply loop unrolling and compute 4 MACs simultaneously. */
xorjoep 1:24714b45cd1b 170 k = count >> 2U;
xorjoep 1:24714b45cd1b 171
xorjoep 1:24714b45cd1b 172 /* First part of the processing with loop unrolling. Compute 4 MACs at a time.
xorjoep 1:24714b45cd1b 173 ** a second loop below computes MACs for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 174 while (k > 0U)
xorjoep 1:24714b45cd1b 175 {
xorjoep 1:24714b45cd1b 176 /* x[0] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 177 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 178 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 179
xorjoep 1:24714b45cd1b 180 /* x[1] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 181 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 182 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 183
xorjoep 1:24714b45cd1b 184 /* x[2] * y[srcBLen - 3] */
xorjoep 1:24714b45cd1b 185 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 186 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 187
xorjoep 1:24714b45cd1b 188 /* x[3] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 189 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 190 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 191
xorjoep 1:24714b45cd1b 192 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 193 k--;
xorjoep 1:24714b45cd1b 194 }
xorjoep 1:24714b45cd1b 195
xorjoep 1:24714b45cd1b 196 /* If the count is not a multiple of 4, compute any remaining MACs here.
xorjoep 1:24714b45cd1b 197 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 198 k = count % 0x4U;
xorjoep 1:24714b45cd1b 199
xorjoep 1:24714b45cd1b 200 while (k > 0U)
xorjoep 1:24714b45cd1b 201 {
xorjoep 1:24714b45cd1b 202 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 203 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 204 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 205
xorjoep 1:24714b45cd1b 206 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 207 k--;
xorjoep 1:24714b45cd1b 208 }
xorjoep 1:24714b45cd1b 209
xorjoep 1:24714b45cd1b 210 /* Store the result in the accumulator in the destination buffer. */
xorjoep 1:24714b45cd1b 211 *pOut++ = sum << 1;
xorjoep 1:24714b45cd1b 212
xorjoep 1:24714b45cd1b 213 /* Update the inputA and inputB pointers for next MAC calculation */
xorjoep 1:24714b45cd1b 214 py = ++pSrc2;
xorjoep 1:24714b45cd1b 215 px = pIn1;
xorjoep 1:24714b45cd1b 216
xorjoep 1:24714b45cd1b 217 /* Increment the MAC count */
xorjoep 1:24714b45cd1b 218 count++;
xorjoep 1:24714b45cd1b 219
xorjoep 1:24714b45cd1b 220 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 221 blockSize1--;
xorjoep 1:24714b45cd1b 222 }
xorjoep 1:24714b45cd1b 223
xorjoep 1:24714b45cd1b 224 /* --------------------------
xorjoep 1:24714b45cd1b 225 * Initializations of stage2
xorjoep 1:24714b45cd1b 226 * ------------------------*/
xorjoep 1:24714b45cd1b 227
xorjoep 1:24714b45cd1b 228 /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0]
xorjoep 1:24714b45cd1b 229 * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0]
xorjoep 1:24714b45cd1b 230 * ....
xorjoep 1:24714b45cd1b 231 * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0]
xorjoep 1:24714b45cd1b 232 */
xorjoep 1:24714b45cd1b 233
xorjoep 1:24714b45cd1b 234 /* Working pointer of inputA */
xorjoep 1:24714b45cd1b 235 if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0)
xorjoep 1:24714b45cd1b 236 {
xorjoep 1:24714b45cd1b 237 px = pIn1 + firstIndex - srcBLen + 1;
xorjoep 1:24714b45cd1b 238 }
xorjoep 1:24714b45cd1b 239 else
xorjoep 1:24714b45cd1b 240 {
xorjoep 1:24714b45cd1b 241 px = pIn1;
xorjoep 1:24714b45cd1b 242 }
xorjoep 1:24714b45cd1b 243
xorjoep 1:24714b45cd1b 244 /* Working pointer of inputB */
xorjoep 1:24714b45cd1b 245 pSrc2 = pIn2 + (srcBLen - 1U);
xorjoep 1:24714b45cd1b 246 py = pSrc2;
xorjoep 1:24714b45cd1b 247
xorjoep 1:24714b45cd1b 248 /* count is index by which the pointer pIn1 to be incremented */
xorjoep 1:24714b45cd1b 249 count = 0U;
xorjoep 1:24714b45cd1b 250
xorjoep 1:24714b45cd1b 251 /* -------------------
xorjoep 1:24714b45cd1b 252 * Stage2 process
xorjoep 1:24714b45cd1b 253 * ------------------*/
xorjoep 1:24714b45cd1b 254
xorjoep 1:24714b45cd1b 255 /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed.
xorjoep 1:24714b45cd1b 256 * So, to loop unroll over blockSize2,
xorjoep 1:24714b45cd1b 257 * srcBLen should be greater than or equal to 4 */
xorjoep 1:24714b45cd1b 258 if (srcBLen >= 4U)
xorjoep 1:24714b45cd1b 259 {
xorjoep 1:24714b45cd1b 260 /* Loop unroll over blockSize2 */
xorjoep 1:24714b45cd1b 261 blkCnt = ((uint32_t) blockSize2 >> 2U);
xorjoep 1:24714b45cd1b 262
xorjoep 1:24714b45cd1b 263 while (blkCnt > 0U)
xorjoep 1:24714b45cd1b 264 {
xorjoep 1:24714b45cd1b 265 /* Set all accumulators to zero */
xorjoep 1:24714b45cd1b 266 acc0 = 0;
xorjoep 1:24714b45cd1b 267 acc1 = 0;
xorjoep 1:24714b45cd1b 268 acc2 = 0;
xorjoep 1:24714b45cd1b 269 acc3 = 0;
xorjoep 1:24714b45cd1b 270
xorjoep 1:24714b45cd1b 271 /* read x[0], x[1], x[2] samples */
xorjoep 1:24714b45cd1b 272 x0 = *(px++);
xorjoep 1:24714b45cd1b 273 x1 = *(px++);
xorjoep 1:24714b45cd1b 274 x2 = *(px++);
xorjoep 1:24714b45cd1b 275
xorjoep 1:24714b45cd1b 276 /* Apply loop unrolling and compute 4 MACs simultaneously. */
xorjoep 1:24714b45cd1b 277 k = srcBLen >> 2U;
xorjoep 1:24714b45cd1b 278
xorjoep 1:24714b45cd1b 279 /* First part of the processing with loop unrolling. Compute 4 MACs at a time.
xorjoep 1:24714b45cd1b 280 ** a second loop below computes MACs for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 281 do
xorjoep 1:24714b45cd1b 282 {
xorjoep 1:24714b45cd1b 283 /* Read y[srcBLen - 1] sample */
xorjoep 1:24714b45cd1b 284 c0 = *(py--);
xorjoep 1:24714b45cd1b 285
xorjoep 1:24714b45cd1b 286 /* Read x[3] sample */
xorjoep 1:24714b45cd1b 287 x3 = *(px++);
xorjoep 1:24714b45cd1b 288
xorjoep 1:24714b45cd1b 289 /* Perform the multiply-accumulate */
xorjoep 1:24714b45cd1b 290 /* acc0 += x[0] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 291 acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32);
xorjoep 1:24714b45cd1b 292
xorjoep 1:24714b45cd1b 293 /* acc1 += x[1] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 294 acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32);
xorjoep 1:24714b45cd1b 295
xorjoep 1:24714b45cd1b 296 /* acc2 += x[2] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 297 acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32);
xorjoep 1:24714b45cd1b 298
xorjoep 1:24714b45cd1b 299 /* acc3 += x[3] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 300 acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32);
xorjoep 1:24714b45cd1b 301
xorjoep 1:24714b45cd1b 302 /* Read y[srcBLen - 2] sample */
xorjoep 1:24714b45cd1b 303 c0 = *(py--);
xorjoep 1:24714b45cd1b 304
xorjoep 1:24714b45cd1b 305 /* Read x[4] sample */
xorjoep 1:24714b45cd1b 306 x0 = *(px++);
xorjoep 1:24714b45cd1b 307
xorjoep 1:24714b45cd1b 308 /* Perform the multiply-accumulate */
xorjoep 1:24714b45cd1b 309 /* acc0 += x[1] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 310 acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x1 * c0)) >> 32);
xorjoep 1:24714b45cd1b 311 /* acc1 += x[2] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 312 acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x2 * c0)) >> 32);
xorjoep 1:24714b45cd1b 313 /* acc2 += x[3] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 314 acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x3 * c0)) >> 32);
xorjoep 1:24714b45cd1b 315 /* acc3 += x[4] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 316 acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x0 * c0)) >> 32);
xorjoep 1:24714b45cd1b 317
xorjoep 1:24714b45cd1b 318 /* Read y[srcBLen - 3] sample */
xorjoep 1:24714b45cd1b 319 c0 = *(py--);
xorjoep 1:24714b45cd1b 320
xorjoep 1:24714b45cd1b 321 /* Read x[5] sample */
xorjoep 1:24714b45cd1b 322 x1 = *(px++);
xorjoep 1:24714b45cd1b 323
xorjoep 1:24714b45cd1b 324 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 325 /* acc0 += x[2] * y[srcBLen - 3] */
xorjoep 1:24714b45cd1b 326 acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x2 * c0)) >> 32);
xorjoep 1:24714b45cd1b 327 /* acc1 += x[3] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 328 acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x3 * c0)) >> 32);
xorjoep 1:24714b45cd1b 329 /* acc2 += x[4] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 330 acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x0 * c0)) >> 32);
xorjoep 1:24714b45cd1b 331 /* acc3 += x[5] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 332 acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x1 * c0)) >> 32);
xorjoep 1:24714b45cd1b 333
xorjoep 1:24714b45cd1b 334 /* Read y[srcBLen - 4] sample */
xorjoep 1:24714b45cd1b 335 c0 = *(py--);
xorjoep 1:24714b45cd1b 336
xorjoep 1:24714b45cd1b 337 /* Read x[6] sample */
xorjoep 1:24714b45cd1b 338 x2 = *(px++);
xorjoep 1:24714b45cd1b 339
xorjoep 1:24714b45cd1b 340 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 341 /* acc0 += x[3] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 342 acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x3 * c0)) >> 32);
xorjoep 1:24714b45cd1b 343 /* acc1 += x[4] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 344 acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x0 * c0)) >> 32);
xorjoep 1:24714b45cd1b 345 /* acc2 += x[5] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 346 acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x1 * c0)) >> 32);
xorjoep 1:24714b45cd1b 347 /* acc3 += x[6] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 348 acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x2 * c0)) >> 32);
xorjoep 1:24714b45cd1b 349
xorjoep 1:24714b45cd1b 350
xorjoep 1:24714b45cd1b 351 } while (--k);
xorjoep 1:24714b45cd1b 352
xorjoep 1:24714b45cd1b 353 /* If the srcBLen is not a multiple of 4, compute any remaining MACs here.
xorjoep 1:24714b45cd1b 354 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 355 k = srcBLen % 0x4U;
xorjoep 1:24714b45cd1b 356
xorjoep 1:24714b45cd1b 357 while (k > 0U)
xorjoep 1:24714b45cd1b 358 {
xorjoep 1:24714b45cd1b 359 /* Read y[srcBLen - 5] sample */
xorjoep 1:24714b45cd1b 360 c0 = *(py--);
xorjoep 1:24714b45cd1b 361
xorjoep 1:24714b45cd1b 362 /* Read x[7] sample */
xorjoep 1:24714b45cd1b 363 x3 = *(px++);
xorjoep 1:24714b45cd1b 364
xorjoep 1:24714b45cd1b 365 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 366 /* acc0 += x[4] * y[srcBLen - 5] */
xorjoep 1:24714b45cd1b 367 acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32);
xorjoep 1:24714b45cd1b 368 /* acc1 += x[5] * y[srcBLen - 5] */
xorjoep 1:24714b45cd1b 369 acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32);
xorjoep 1:24714b45cd1b 370 /* acc2 += x[6] * y[srcBLen - 5] */
xorjoep 1:24714b45cd1b 371 acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32);
xorjoep 1:24714b45cd1b 372 /* acc3 += x[7] * y[srcBLen - 5] */
xorjoep 1:24714b45cd1b 373 acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32);
xorjoep 1:24714b45cd1b 374
xorjoep 1:24714b45cd1b 375 /* Reuse the present samples for the next MAC */
xorjoep 1:24714b45cd1b 376 x0 = x1;
xorjoep 1:24714b45cd1b 377 x1 = x2;
xorjoep 1:24714b45cd1b 378 x2 = x3;
xorjoep 1:24714b45cd1b 379
xorjoep 1:24714b45cd1b 380 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 381 k--;
xorjoep 1:24714b45cd1b 382 }
xorjoep 1:24714b45cd1b 383
xorjoep 1:24714b45cd1b 384 /* Store the result in the accumulator in the destination buffer. */
xorjoep 1:24714b45cd1b 385 *pOut++ = (q31_t) (acc0 << 1);
xorjoep 1:24714b45cd1b 386 *pOut++ = (q31_t) (acc1 << 1);
xorjoep 1:24714b45cd1b 387 *pOut++ = (q31_t) (acc2 << 1);
xorjoep 1:24714b45cd1b 388 *pOut++ = (q31_t) (acc3 << 1);
xorjoep 1:24714b45cd1b 389
xorjoep 1:24714b45cd1b 390 /* Increment the pointer pIn1 index, count by 4 */
xorjoep 1:24714b45cd1b 391 count += 4U;
xorjoep 1:24714b45cd1b 392
xorjoep 1:24714b45cd1b 393 /* Update the inputA and inputB pointers for next MAC calculation */
xorjoep 1:24714b45cd1b 394 if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0)
xorjoep 1:24714b45cd1b 395 {
xorjoep 1:24714b45cd1b 396 px = pIn1 + firstIndex - srcBLen + 1 + count;
xorjoep 1:24714b45cd1b 397 }
xorjoep 1:24714b45cd1b 398 else
xorjoep 1:24714b45cd1b 399 {
xorjoep 1:24714b45cd1b 400 px = pIn1 + count;
xorjoep 1:24714b45cd1b 401 }
xorjoep 1:24714b45cd1b 402 py = pSrc2;
xorjoep 1:24714b45cd1b 403
xorjoep 1:24714b45cd1b 404 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 405 blkCnt--;
xorjoep 1:24714b45cd1b 406 }
xorjoep 1:24714b45cd1b 407
xorjoep 1:24714b45cd1b 408 /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here.
xorjoep 1:24714b45cd1b 409 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 410 blkCnt = (uint32_t) blockSize2 % 0x4U;
xorjoep 1:24714b45cd1b 411
xorjoep 1:24714b45cd1b 412 while (blkCnt > 0U)
xorjoep 1:24714b45cd1b 413 {
xorjoep 1:24714b45cd1b 414 /* Accumulator is made zero for every iteration */
xorjoep 1:24714b45cd1b 415 sum = 0;
xorjoep 1:24714b45cd1b 416
xorjoep 1:24714b45cd1b 417 /* Apply loop unrolling and compute 4 MACs simultaneously. */
xorjoep 1:24714b45cd1b 418 k = srcBLen >> 2U;
xorjoep 1:24714b45cd1b 419
xorjoep 1:24714b45cd1b 420 /* First part of the processing with loop unrolling. Compute 4 MACs at a time.
xorjoep 1:24714b45cd1b 421 ** a second loop below computes MACs for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 422 while (k > 0U)
xorjoep 1:24714b45cd1b 423 {
xorjoep 1:24714b45cd1b 424 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 425 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 426 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 427 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 428 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 429 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 430 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 431 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 432 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 433
xorjoep 1:24714b45cd1b 434 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 435 k--;
xorjoep 1:24714b45cd1b 436 }
xorjoep 1:24714b45cd1b 437
xorjoep 1:24714b45cd1b 438 /* If the srcBLen is not a multiple of 4, compute any remaining MACs here.
xorjoep 1:24714b45cd1b 439 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 440 k = srcBLen % 0x4U;
xorjoep 1:24714b45cd1b 441
xorjoep 1:24714b45cd1b 442 while (k > 0U)
xorjoep 1:24714b45cd1b 443 {
xorjoep 1:24714b45cd1b 444 /* Perform the multiply-accumulate */
xorjoep 1:24714b45cd1b 445 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 446 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 447
xorjoep 1:24714b45cd1b 448 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 449 k--;
xorjoep 1:24714b45cd1b 450 }
xorjoep 1:24714b45cd1b 451
xorjoep 1:24714b45cd1b 452 /* Store the result in the accumulator in the destination buffer. */
xorjoep 1:24714b45cd1b 453 *pOut++ = sum << 1;
xorjoep 1:24714b45cd1b 454
xorjoep 1:24714b45cd1b 455 /* Increment the MAC count */
xorjoep 1:24714b45cd1b 456 count++;
xorjoep 1:24714b45cd1b 457
xorjoep 1:24714b45cd1b 458 /* Update the inputA and inputB pointers for next MAC calculation */
xorjoep 1:24714b45cd1b 459 if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0)
xorjoep 1:24714b45cd1b 460 {
xorjoep 1:24714b45cd1b 461 px = pIn1 + firstIndex - srcBLen + 1 + count;
xorjoep 1:24714b45cd1b 462 }
xorjoep 1:24714b45cd1b 463 else
xorjoep 1:24714b45cd1b 464 {
xorjoep 1:24714b45cd1b 465 px = pIn1 + count;
xorjoep 1:24714b45cd1b 466 }
xorjoep 1:24714b45cd1b 467 py = pSrc2;
xorjoep 1:24714b45cd1b 468
xorjoep 1:24714b45cd1b 469 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 470 blkCnt--;
xorjoep 1:24714b45cd1b 471 }
xorjoep 1:24714b45cd1b 472 }
xorjoep 1:24714b45cd1b 473 else
xorjoep 1:24714b45cd1b 474 {
xorjoep 1:24714b45cd1b 475 /* If the srcBLen is not a multiple of 4,
xorjoep 1:24714b45cd1b 476 * the blockSize2 loop cannot be unrolled by 4 */
xorjoep 1:24714b45cd1b 477 blkCnt = (uint32_t) blockSize2;
xorjoep 1:24714b45cd1b 478
xorjoep 1:24714b45cd1b 479 while (blkCnt > 0U)
xorjoep 1:24714b45cd1b 480 {
xorjoep 1:24714b45cd1b 481 /* Accumulator is made zero for every iteration */
xorjoep 1:24714b45cd1b 482 sum = 0;
xorjoep 1:24714b45cd1b 483
xorjoep 1:24714b45cd1b 484 /* srcBLen number of MACS should be performed */
xorjoep 1:24714b45cd1b 485 k = srcBLen;
xorjoep 1:24714b45cd1b 486
xorjoep 1:24714b45cd1b 487 while (k > 0U)
xorjoep 1:24714b45cd1b 488 {
xorjoep 1:24714b45cd1b 489 /* Perform the multiply-accumulate */
xorjoep 1:24714b45cd1b 490 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 491 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 492
xorjoep 1:24714b45cd1b 493 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 494 k--;
xorjoep 1:24714b45cd1b 495 }
xorjoep 1:24714b45cd1b 496
xorjoep 1:24714b45cd1b 497 /* Store the result in the accumulator in the destination buffer. */
xorjoep 1:24714b45cd1b 498 *pOut++ = sum << 1;
xorjoep 1:24714b45cd1b 499
xorjoep 1:24714b45cd1b 500 /* Increment the MAC count */
xorjoep 1:24714b45cd1b 501 count++;
xorjoep 1:24714b45cd1b 502
xorjoep 1:24714b45cd1b 503 /* Update the inputA and inputB pointers for next MAC calculation */
xorjoep 1:24714b45cd1b 504 if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0)
xorjoep 1:24714b45cd1b 505 {
xorjoep 1:24714b45cd1b 506 px = pIn1 + firstIndex - srcBLen + 1 + count;
xorjoep 1:24714b45cd1b 507 }
xorjoep 1:24714b45cd1b 508 else
xorjoep 1:24714b45cd1b 509 {
xorjoep 1:24714b45cd1b 510 px = pIn1 + count;
xorjoep 1:24714b45cd1b 511 }
xorjoep 1:24714b45cd1b 512 py = pSrc2;
xorjoep 1:24714b45cd1b 513
xorjoep 1:24714b45cd1b 514 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 515 blkCnt--;
xorjoep 1:24714b45cd1b 516 }
xorjoep 1:24714b45cd1b 517 }
xorjoep 1:24714b45cd1b 518
xorjoep 1:24714b45cd1b 519
xorjoep 1:24714b45cd1b 520 /* --------------------------
xorjoep 1:24714b45cd1b 521 * Initializations of stage3
xorjoep 1:24714b45cd1b 522 * -------------------------*/
xorjoep 1:24714b45cd1b 523
xorjoep 1:24714b45cd1b 524 /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1]
xorjoep 1:24714b45cd1b 525 * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2]
xorjoep 1:24714b45cd1b 526 * ....
xorjoep 1:24714b45cd1b 527 * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2]
xorjoep 1:24714b45cd1b 528 * sum += x[srcALen-1] * y[srcBLen-1]
xorjoep 1:24714b45cd1b 529 */
xorjoep 1:24714b45cd1b 530
xorjoep 1:24714b45cd1b 531 /* In this stage the MAC operations are decreased by 1 for every iteration.
xorjoep 1:24714b45cd1b 532 The count variable holds the number of MAC operations performed */
xorjoep 1:24714b45cd1b 533 count = srcBLen - 1U;
xorjoep 1:24714b45cd1b 534
xorjoep 1:24714b45cd1b 535 /* Working pointer of inputA */
xorjoep 1:24714b45cd1b 536 pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U);
xorjoep 1:24714b45cd1b 537 px = pSrc1;
xorjoep 1:24714b45cd1b 538
xorjoep 1:24714b45cd1b 539 /* Working pointer of inputB */
xorjoep 1:24714b45cd1b 540 pSrc2 = pIn2 + (srcBLen - 1U);
xorjoep 1:24714b45cd1b 541 py = pSrc2;
xorjoep 1:24714b45cd1b 542
xorjoep 1:24714b45cd1b 543 /* -------------------
xorjoep 1:24714b45cd1b 544 * Stage3 process
xorjoep 1:24714b45cd1b 545 * ------------------*/
xorjoep 1:24714b45cd1b 546
xorjoep 1:24714b45cd1b 547 while (blockSize3 > 0)
xorjoep 1:24714b45cd1b 548 {
xorjoep 1:24714b45cd1b 549 /* Accumulator is made zero for every iteration */
xorjoep 1:24714b45cd1b 550 sum = 0;
xorjoep 1:24714b45cd1b 551
xorjoep 1:24714b45cd1b 552 /* Apply loop unrolling and compute 4 MACs simultaneously. */
xorjoep 1:24714b45cd1b 553 k = count >> 2U;
xorjoep 1:24714b45cd1b 554
xorjoep 1:24714b45cd1b 555 /* First part of the processing with loop unrolling. Compute 4 MACs at a time.
xorjoep 1:24714b45cd1b 556 ** a second loop below computes MACs for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 557 while (k > 0U)
xorjoep 1:24714b45cd1b 558 {
xorjoep 1:24714b45cd1b 559 /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 560 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 561 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 562
xorjoep 1:24714b45cd1b 563 /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 564 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 565 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 566
xorjoep 1:24714b45cd1b 567 /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */
xorjoep 1:24714b45cd1b 568 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 569 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 570
xorjoep 1:24714b45cd1b 571 /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 572 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 573 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 574
xorjoep 1:24714b45cd1b 575 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 576 k--;
xorjoep 1:24714b45cd1b 577 }
xorjoep 1:24714b45cd1b 578
xorjoep 1:24714b45cd1b 579 /* If the count is not a multiple of 4, compute any remaining MACs here.
xorjoep 1:24714b45cd1b 580 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 581 k = count % 0x4U;
xorjoep 1:24714b45cd1b 582
xorjoep 1:24714b45cd1b 583 while (k > 0U)
xorjoep 1:24714b45cd1b 584 {
xorjoep 1:24714b45cd1b 585 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 586 /* sum += x[srcALen-1] * y[srcBLen-1] */
xorjoep 1:24714b45cd1b 587 sum = (q31_t) ((((q63_t) sum << 32) +
xorjoep 1:24714b45cd1b 588 ((q63_t) * px++ * (*py--))) >> 32);
xorjoep 1:24714b45cd1b 589
xorjoep 1:24714b45cd1b 590 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 591 k--;
xorjoep 1:24714b45cd1b 592 }
xorjoep 1:24714b45cd1b 593
xorjoep 1:24714b45cd1b 594 /* Store the result in the accumulator in the destination buffer. */
xorjoep 1:24714b45cd1b 595 *pOut++ = sum << 1;
xorjoep 1:24714b45cd1b 596
xorjoep 1:24714b45cd1b 597 /* Update the inputA and inputB pointers for next MAC calculation */
xorjoep 1:24714b45cd1b 598 px = ++pSrc1;
xorjoep 1:24714b45cd1b 599 py = pSrc2;
xorjoep 1:24714b45cd1b 600
xorjoep 1:24714b45cd1b 601 /* Decrement the MAC count */
xorjoep 1:24714b45cd1b 602 count--;
xorjoep 1:24714b45cd1b 603
xorjoep 1:24714b45cd1b 604 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 605 blockSize3--;
xorjoep 1:24714b45cd1b 606
xorjoep 1:24714b45cd1b 607 }
xorjoep 1:24714b45cd1b 608
xorjoep 1:24714b45cd1b 609 /* set status as ARM_MATH_SUCCESS */
xorjoep 1:24714b45cd1b 610 status = ARM_MATH_SUCCESS;
xorjoep 1:24714b45cd1b 611 }
xorjoep 1:24714b45cd1b 612
xorjoep 1:24714b45cd1b 613 /* Return to application */
xorjoep 1:24714b45cd1b 614 return (status);
xorjoep 1:24714b45cd1b 615
xorjoep 1:24714b45cd1b 616 }
xorjoep 1:24714b45cd1b 617
xorjoep 1:24714b45cd1b 618 /**
xorjoep 1:24714b45cd1b 619 * @} end of PartialConv group
xorjoep 1:24714b45cd1b 620 */