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_mat_mult_q15.c
xorjoep 1:24714b45cd1b 4 * Description: Q15 matrix multiplication
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 groupMatrix
xorjoep 1:24714b45cd1b 33 */
xorjoep 1:24714b45cd1b 34
xorjoep 1:24714b45cd1b 35 /**
xorjoep 1:24714b45cd1b 36 * @addtogroup MatrixMult
xorjoep 1:24714b45cd1b 37 * @{
xorjoep 1:24714b45cd1b 38 */
xorjoep 1:24714b45cd1b 39
xorjoep 1:24714b45cd1b 40
xorjoep 1:24714b45cd1b 41 /**
xorjoep 1:24714b45cd1b 42 * @brief Q15 matrix multiplication
xorjoep 1:24714b45cd1b 43 * @param[in] *pSrcA points to the first input matrix structure
xorjoep 1:24714b45cd1b 44 * @param[in] *pSrcB points to the second input matrix structure
xorjoep 1:24714b45cd1b 45 * @param[out] *pDst points to output matrix structure
xorjoep 1:24714b45cd1b 46 * @param[in] *pState points to the array for storing intermediate results (Unused)
xorjoep 1:24714b45cd1b 47 * @return The function returns either
xorjoep 1:24714b45cd1b 48 * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
xorjoep 1:24714b45cd1b 49 *
xorjoep 1:24714b45cd1b 50 * @details
xorjoep 1:24714b45cd1b 51 * <b>Scaling and Overflow Behavior:</b>
xorjoep 1:24714b45cd1b 52 *
xorjoep 1:24714b45cd1b 53 * \par
xorjoep 1:24714b45cd1b 54 * The function is implemented using a 64-bit internal accumulator. The inputs to the
xorjoep 1:24714b45cd1b 55 * multiplications are in 1.15 format and multiplications yield a 2.30 result.
xorjoep 1:24714b45cd1b 56 * The 2.30 intermediate
xorjoep 1:24714b45cd1b 57 * results are accumulated in a 64-bit accumulator in 34.30 format. This approach
xorjoep 1:24714b45cd1b 58 * provides 33 guard bits and there is no risk of overflow. The 34.30 result is then
xorjoep 1:24714b45cd1b 59 * truncated to 34.15 format by discarding the low 15 bits and then saturated to
xorjoep 1:24714b45cd1b 60 * 1.15 format.
xorjoep 1:24714b45cd1b 61 *
xorjoep 1:24714b45cd1b 62 * \par
xorjoep 1:24714b45cd1b 63 * Refer to <code>arm_mat_mult_fast_q15()</code> for a faster but less precise version of this function for Cortex-M3 and Cortex-M4.
xorjoep 1:24714b45cd1b 64 *
xorjoep 1:24714b45cd1b 65 */
xorjoep 1:24714b45cd1b 66
xorjoep 1:24714b45cd1b 67 arm_status arm_mat_mult_q15(
xorjoep 1:24714b45cd1b 68 const arm_matrix_instance_q15 * pSrcA,
xorjoep 1:24714b45cd1b 69 const arm_matrix_instance_q15 * pSrcB,
xorjoep 1:24714b45cd1b 70 arm_matrix_instance_q15 * pDst,
xorjoep 1:24714b45cd1b 71 q15_t * pState)
xorjoep 1:24714b45cd1b 72 {
xorjoep 1:24714b45cd1b 73 q63_t sum; /* accumulator */
xorjoep 1:24714b45cd1b 74
xorjoep 1:24714b45cd1b 75 #if defined (ARM_MATH_DSP)
xorjoep 1:24714b45cd1b 76
xorjoep 1:24714b45cd1b 77 /* Run the below code for Cortex-M4 and Cortex-M3 */
xorjoep 1:24714b45cd1b 78
xorjoep 1:24714b45cd1b 79 q15_t *pSrcBT = pState; /* input data matrix pointer for transpose */
xorjoep 1:24714b45cd1b 80 q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
xorjoep 1:24714b45cd1b 81 q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
xorjoep 1:24714b45cd1b 82 q15_t *px; /* Temporary output data matrix pointer */
xorjoep 1:24714b45cd1b 83 uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
xorjoep 1:24714b45cd1b 84 uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
xorjoep 1:24714b45cd1b 85 uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
xorjoep 1:24714b45cd1b 86 uint16_t numRowsB = pSrcB->numRows; /* number of rows of input matrix A */
xorjoep 1:24714b45cd1b 87 uint16_t col, i = 0U, row = numRowsB, colCnt; /* loop counters */
xorjoep 1:24714b45cd1b 88 arm_status status; /* status of matrix multiplication */
xorjoep 1:24714b45cd1b 89
xorjoep 1:24714b45cd1b 90 #ifndef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 91
xorjoep 1:24714b45cd1b 92 q31_t in; /* Temporary variable to hold the input value */
xorjoep 1:24714b45cd1b 93 q31_t pSourceA1, pSourceB1, pSourceA2, pSourceB2;
xorjoep 1:24714b45cd1b 94
xorjoep 1:24714b45cd1b 95 #else
xorjoep 1:24714b45cd1b 96
xorjoep 1:24714b45cd1b 97 q15_t in; /* Temporary variable to hold the input value */
xorjoep 1:24714b45cd1b 98 q15_t inA1, inB1, inA2, inB2;
xorjoep 1:24714b45cd1b 99
xorjoep 1:24714b45cd1b 100 #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
xorjoep 1:24714b45cd1b 101
xorjoep 1:24714b45cd1b 102 #ifdef ARM_MATH_MATRIX_CHECK
xorjoep 1:24714b45cd1b 103 /* Check for matrix mismatch condition */
xorjoep 1:24714b45cd1b 104 if ((pSrcA->numCols != pSrcB->numRows) ||
xorjoep 1:24714b45cd1b 105 (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
xorjoep 1:24714b45cd1b 106 {
xorjoep 1:24714b45cd1b 107 /* Set status as ARM_MATH_SIZE_MISMATCH */
xorjoep 1:24714b45cd1b 108 status = ARM_MATH_SIZE_MISMATCH;
xorjoep 1:24714b45cd1b 109 }
xorjoep 1:24714b45cd1b 110 else
xorjoep 1:24714b45cd1b 111 #endif /* #ifdef ARM_MATH_MATRIX_CHECK */
xorjoep 1:24714b45cd1b 112 {
xorjoep 1:24714b45cd1b 113 /* Matrix transpose */
xorjoep 1:24714b45cd1b 114 do
xorjoep 1:24714b45cd1b 115 {
xorjoep 1:24714b45cd1b 116 /* Apply loop unrolling and exchange the columns with row elements */
xorjoep 1:24714b45cd1b 117 col = numColsB >> 2;
xorjoep 1:24714b45cd1b 118
xorjoep 1:24714b45cd1b 119 /* The pointer px is set to starting address of the column being processed */
xorjoep 1:24714b45cd1b 120 px = pSrcBT + i;
xorjoep 1:24714b45cd1b 121
xorjoep 1:24714b45cd1b 122 /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
xorjoep 1:24714b45cd1b 123 ** a second loop below computes the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 124 while (col > 0U)
xorjoep 1:24714b45cd1b 125 {
xorjoep 1:24714b45cd1b 126 #ifndef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 127
xorjoep 1:24714b45cd1b 128 /* Read two elements from the row */
xorjoep 1:24714b45cd1b 129 in = *__SIMD32(pInB)++;
xorjoep 1:24714b45cd1b 130
xorjoep 1:24714b45cd1b 131 /* Unpack and store one element in the destination */
xorjoep 1:24714b45cd1b 132 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 133
xorjoep 1:24714b45cd1b 134 *px = (q15_t) in;
xorjoep 1:24714b45cd1b 135
xorjoep 1:24714b45cd1b 136 #else
xorjoep 1:24714b45cd1b 137
xorjoep 1:24714b45cd1b 138 *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
xorjoep 1:24714b45cd1b 139
xorjoep 1:24714b45cd1b 140 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
xorjoep 1:24714b45cd1b 141
xorjoep 1:24714b45cd1b 142 /* Update the pointer px to point to the next row of the transposed matrix */
xorjoep 1:24714b45cd1b 143 px += numRowsB;
xorjoep 1:24714b45cd1b 144
xorjoep 1:24714b45cd1b 145 /* Unpack and store the second element in the destination */
xorjoep 1:24714b45cd1b 146 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 147
xorjoep 1:24714b45cd1b 148 *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
xorjoep 1:24714b45cd1b 149
xorjoep 1:24714b45cd1b 150 #else
xorjoep 1:24714b45cd1b 151
xorjoep 1:24714b45cd1b 152 *px = (q15_t) in;
xorjoep 1:24714b45cd1b 153
xorjoep 1:24714b45cd1b 154 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
xorjoep 1:24714b45cd1b 155
xorjoep 1:24714b45cd1b 156 /* Update the pointer px to point to the next row of the transposed matrix */
xorjoep 1:24714b45cd1b 157 px += numRowsB;
xorjoep 1:24714b45cd1b 158
xorjoep 1:24714b45cd1b 159 /* Read two elements from the row */
xorjoep 1:24714b45cd1b 160 in = *__SIMD32(pInB)++;
xorjoep 1:24714b45cd1b 161
xorjoep 1:24714b45cd1b 162 /* Unpack and store one element in the destination */
xorjoep 1:24714b45cd1b 163 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 164
xorjoep 1:24714b45cd1b 165 *px = (q15_t) in;
xorjoep 1:24714b45cd1b 166
xorjoep 1:24714b45cd1b 167 #else
xorjoep 1:24714b45cd1b 168
xorjoep 1:24714b45cd1b 169 *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
xorjoep 1:24714b45cd1b 170
xorjoep 1:24714b45cd1b 171 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
xorjoep 1:24714b45cd1b 172
xorjoep 1:24714b45cd1b 173 /* Update the pointer px to point to the next row of the transposed matrix */
xorjoep 1:24714b45cd1b 174 px += numRowsB;
xorjoep 1:24714b45cd1b 175
xorjoep 1:24714b45cd1b 176 /* Unpack and store the second element in the destination */
xorjoep 1:24714b45cd1b 177
xorjoep 1:24714b45cd1b 178 #ifndef ARM_MATH_BIG_ENDIAN
xorjoep 1:24714b45cd1b 179
xorjoep 1:24714b45cd1b 180 *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
xorjoep 1:24714b45cd1b 181
xorjoep 1:24714b45cd1b 182 #else
xorjoep 1:24714b45cd1b 183
xorjoep 1:24714b45cd1b 184 *px = (q15_t) in;
xorjoep 1:24714b45cd1b 185
xorjoep 1:24714b45cd1b 186 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
xorjoep 1:24714b45cd1b 187
xorjoep 1:24714b45cd1b 188 /* Update the pointer px to point to the next row of the transposed matrix */
xorjoep 1:24714b45cd1b 189 px += numRowsB;
xorjoep 1:24714b45cd1b 190
xorjoep 1:24714b45cd1b 191 #else
xorjoep 1:24714b45cd1b 192
xorjoep 1:24714b45cd1b 193 /* Read one element from the row */
xorjoep 1:24714b45cd1b 194 in = *pInB++;
xorjoep 1:24714b45cd1b 195
xorjoep 1:24714b45cd1b 196 /* Store one element in the destination */
xorjoep 1:24714b45cd1b 197 *px = in;
xorjoep 1:24714b45cd1b 198
xorjoep 1:24714b45cd1b 199 /* Update the pointer px to point to the next row of the transposed matrix */
xorjoep 1:24714b45cd1b 200 px += numRowsB;
xorjoep 1:24714b45cd1b 201
xorjoep 1:24714b45cd1b 202 /* Read one element from the row */
xorjoep 1:24714b45cd1b 203 in = *pInB++;
xorjoep 1:24714b45cd1b 204
xorjoep 1:24714b45cd1b 205 /* Store one element in the destination */
xorjoep 1:24714b45cd1b 206 *px = in;
xorjoep 1:24714b45cd1b 207
xorjoep 1:24714b45cd1b 208 /* Update the pointer px to point to the next row of the transposed matrix */
xorjoep 1:24714b45cd1b 209 px += numRowsB;
xorjoep 1:24714b45cd1b 210
xorjoep 1:24714b45cd1b 211 /* Read one element from the row */
xorjoep 1:24714b45cd1b 212 in = *pInB++;
xorjoep 1:24714b45cd1b 213
xorjoep 1:24714b45cd1b 214 /* Store one element in the destination */
xorjoep 1:24714b45cd1b 215 *px = in;
xorjoep 1:24714b45cd1b 216
xorjoep 1:24714b45cd1b 217 /* Update the pointer px to point to the next row of the transposed matrix */
xorjoep 1:24714b45cd1b 218 px += numRowsB;
xorjoep 1:24714b45cd1b 219
xorjoep 1:24714b45cd1b 220 /* Read one element from the row */
xorjoep 1:24714b45cd1b 221 in = *pInB++;
xorjoep 1:24714b45cd1b 222
xorjoep 1:24714b45cd1b 223 /* Store one element in the destination */
xorjoep 1:24714b45cd1b 224 *px = in;
xorjoep 1:24714b45cd1b 225
xorjoep 1:24714b45cd1b 226 /* Update the pointer px to point to the next row of the transposed matrix */
xorjoep 1:24714b45cd1b 227 px += numRowsB;
xorjoep 1:24714b45cd1b 228
xorjoep 1:24714b45cd1b 229 #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
xorjoep 1:24714b45cd1b 230
xorjoep 1:24714b45cd1b 231 /* Decrement the column loop counter */
xorjoep 1:24714b45cd1b 232 col--;
xorjoep 1:24714b45cd1b 233 }
xorjoep 1:24714b45cd1b 234
xorjoep 1:24714b45cd1b 235 /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
xorjoep 1:24714b45cd1b 236 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 237 col = numColsB % 0x4U;
xorjoep 1:24714b45cd1b 238
xorjoep 1:24714b45cd1b 239 while (col > 0U)
xorjoep 1:24714b45cd1b 240 {
xorjoep 1:24714b45cd1b 241 /* Read and store the input element in the destination */
xorjoep 1:24714b45cd1b 242 *px = *pInB++;
xorjoep 1:24714b45cd1b 243
xorjoep 1:24714b45cd1b 244 /* Update the pointer px to point to the next row of the transposed matrix */
xorjoep 1:24714b45cd1b 245 px += numRowsB;
xorjoep 1:24714b45cd1b 246
xorjoep 1:24714b45cd1b 247 /* Decrement the column loop counter */
xorjoep 1:24714b45cd1b 248 col--;
xorjoep 1:24714b45cd1b 249 }
xorjoep 1:24714b45cd1b 250
xorjoep 1:24714b45cd1b 251 i++;
xorjoep 1:24714b45cd1b 252
xorjoep 1:24714b45cd1b 253 /* Decrement the row loop counter */
xorjoep 1:24714b45cd1b 254 row--;
xorjoep 1:24714b45cd1b 255
xorjoep 1:24714b45cd1b 256 } while (row > 0U);
xorjoep 1:24714b45cd1b 257
xorjoep 1:24714b45cd1b 258 /* Reset the variables for the usage in the following multiplication process */
xorjoep 1:24714b45cd1b 259 row = numRowsA;
xorjoep 1:24714b45cd1b 260 i = 0U;
xorjoep 1:24714b45cd1b 261 px = pDst->pData;
xorjoep 1:24714b45cd1b 262
xorjoep 1:24714b45cd1b 263 /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
xorjoep 1:24714b45cd1b 264 /* row loop */
xorjoep 1:24714b45cd1b 265 do
xorjoep 1:24714b45cd1b 266 {
xorjoep 1:24714b45cd1b 267 /* For every row wise process, the column loop counter is to be initiated */
xorjoep 1:24714b45cd1b 268 col = numColsB;
xorjoep 1:24714b45cd1b 269
xorjoep 1:24714b45cd1b 270 /* For every row wise process, the pIn2 pointer is set
xorjoep 1:24714b45cd1b 271 ** to the starting address of the transposed pSrcB data */
xorjoep 1:24714b45cd1b 272 pInB = pSrcBT;
xorjoep 1:24714b45cd1b 273
xorjoep 1:24714b45cd1b 274 /* column loop */
xorjoep 1:24714b45cd1b 275 do
xorjoep 1:24714b45cd1b 276 {
xorjoep 1:24714b45cd1b 277 /* Set the variable sum, that acts as accumulator, to zero */
xorjoep 1:24714b45cd1b 278 sum = 0;
xorjoep 1:24714b45cd1b 279
xorjoep 1:24714b45cd1b 280 /* Apply loop unrolling and compute 2 MACs simultaneously. */
xorjoep 1:24714b45cd1b 281 colCnt = numColsA >> 2;
xorjoep 1:24714b45cd1b 282
xorjoep 1:24714b45cd1b 283 /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
xorjoep 1:24714b45cd1b 284 pInA = pSrcA->pData + i;
xorjoep 1:24714b45cd1b 285
xorjoep 1:24714b45cd1b 286
xorjoep 1:24714b45cd1b 287 /* matrix multiplication */
xorjoep 1:24714b45cd1b 288 while (colCnt > 0U)
xorjoep 1:24714b45cd1b 289 {
xorjoep 1:24714b45cd1b 290 /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
xorjoep 1:24714b45cd1b 291 #ifndef UNALIGNED_SUPPORT_DISABLE
xorjoep 1:24714b45cd1b 292
xorjoep 1:24714b45cd1b 293 /* read real and imag values from pSrcA and pSrcB buffer */
xorjoep 1:24714b45cd1b 294 pSourceA1 = *__SIMD32(pInA)++;
xorjoep 1:24714b45cd1b 295 pSourceB1 = *__SIMD32(pInB)++;
xorjoep 1:24714b45cd1b 296
xorjoep 1:24714b45cd1b 297 pSourceA2 = *__SIMD32(pInA)++;
xorjoep 1:24714b45cd1b 298 pSourceB2 = *__SIMD32(pInB)++;
xorjoep 1:24714b45cd1b 299
xorjoep 1:24714b45cd1b 300 /* Multiply and Accumlates */
xorjoep 1:24714b45cd1b 301 sum = __SMLALD(pSourceA1, pSourceB1, sum);
xorjoep 1:24714b45cd1b 302 sum = __SMLALD(pSourceA2, pSourceB2, sum);
xorjoep 1:24714b45cd1b 303
xorjoep 1:24714b45cd1b 304 #else
xorjoep 1:24714b45cd1b 305 /* read real and imag values from pSrcA and pSrcB buffer */
xorjoep 1:24714b45cd1b 306 inA1 = *pInA++;
xorjoep 1:24714b45cd1b 307 inB1 = *pInB++;
xorjoep 1:24714b45cd1b 308 inA2 = *pInA++;
xorjoep 1:24714b45cd1b 309 /* Multiply and Accumlates */
xorjoep 1:24714b45cd1b 310 sum += inA1 * inB1;
xorjoep 1:24714b45cd1b 311 inB2 = *pInB++;
xorjoep 1:24714b45cd1b 312
xorjoep 1:24714b45cd1b 313 inA1 = *pInA++;
xorjoep 1:24714b45cd1b 314 inB1 = *pInB++;
xorjoep 1:24714b45cd1b 315 /* Multiply and Accumlates */
xorjoep 1:24714b45cd1b 316 sum += inA2 * inB2;
xorjoep 1:24714b45cd1b 317 inA2 = *pInA++;
xorjoep 1:24714b45cd1b 318 inB2 = *pInB++;
xorjoep 1:24714b45cd1b 319
xorjoep 1:24714b45cd1b 320 /* Multiply and Accumlates */
xorjoep 1:24714b45cd1b 321 sum += inA1 * inB1;
xorjoep 1:24714b45cd1b 322 sum += inA2 * inB2;
xorjoep 1:24714b45cd1b 323
xorjoep 1:24714b45cd1b 324 #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
xorjoep 1:24714b45cd1b 325
xorjoep 1:24714b45cd1b 326 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 327 colCnt--;
xorjoep 1:24714b45cd1b 328 }
xorjoep 1:24714b45cd1b 329
xorjoep 1:24714b45cd1b 330 /* process remaining column samples */
xorjoep 1:24714b45cd1b 331 colCnt = numColsA & 3U;
xorjoep 1:24714b45cd1b 332
xorjoep 1:24714b45cd1b 333 while (colCnt > 0U)
xorjoep 1:24714b45cd1b 334 {
xorjoep 1:24714b45cd1b 335 /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
xorjoep 1:24714b45cd1b 336 sum += *pInA++ * *pInB++;
xorjoep 1:24714b45cd1b 337
xorjoep 1:24714b45cd1b 338 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 339 colCnt--;
xorjoep 1:24714b45cd1b 340 }
xorjoep 1:24714b45cd1b 341
xorjoep 1:24714b45cd1b 342 /* Saturate and store the result in the destination buffer */
xorjoep 1:24714b45cd1b 343 *px = (q15_t) (__SSAT((sum >> 15), 16));
xorjoep 1:24714b45cd1b 344 px++;
xorjoep 1:24714b45cd1b 345
xorjoep 1:24714b45cd1b 346 /* Decrement the column loop counter */
xorjoep 1:24714b45cd1b 347 col--;
xorjoep 1:24714b45cd1b 348
xorjoep 1:24714b45cd1b 349 } while (col > 0U);
xorjoep 1:24714b45cd1b 350
xorjoep 1:24714b45cd1b 351 i = i + numColsA;
xorjoep 1:24714b45cd1b 352
xorjoep 1:24714b45cd1b 353 /* Decrement the row loop counter */
xorjoep 1:24714b45cd1b 354 row--;
xorjoep 1:24714b45cd1b 355
xorjoep 1:24714b45cd1b 356 } while (row > 0U);
xorjoep 1:24714b45cd1b 357
xorjoep 1:24714b45cd1b 358 #else
xorjoep 1:24714b45cd1b 359
xorjoep 1:24714b45cd1b 360 /* Run the below code for Cortex-M0 */
xorjoep 1:24714b45cd1b 361
xorjoep 1:24714b45cd1b 362 q15_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
xorjoep 1:24714b45cd1b 363 q15_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
xorjoep 1:24714b45cd1b 364 q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
xorjoep 1:24714b45cd1b 365 q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
xorjoep 1:24714b45cd1b 366 q15_t *pOut = pDst->pData; /* output data matrix pointer */
xorjoep 1:24714b45cd1b 367 q15_t *px; /* Temporary output data matrix pointer */
xorjoep 1:24714b45cd1b 368 uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
xorjoep 1:24714b45cd1b 369 uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
xorjoep 1:24714b45cd1b 370 uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
xorjoep 1:24714b45cd1b 371 uint16_t col, i = 0U, row = numRowsA, colCnt; /* loop counters */
xorjoep 1:24714b45cd1b 372 arm_status status; /* status of matrix multiplication */
xorjoep 1:24714b45cd1b 373
xorjoep 1:24714b45cd1b 374 #ifdef ARM_MATH_MATRIX_CHECK
xorjoep 1:24714b45cd1b 375
xorjoep 1:24714b45cd1b 376 /* Check for matrix mismatch condition */
xorjoep 1:24714b45cd1b 377 if ((pSrcA->numCols != pSrcB->numRows) ||
xorjoep 1:24714b45cd1b 378 (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
xorjoep 1:24714b45cd1b 379 {
xorjoep 1:24714b45cd1b 380 /* Set status as ARM_MATH_SIZE_MISMATCH */
xorjoep 1:24714b45cd1b 381 status = ARM_MATH_SIZE_MISMATCH;
xorjoep 1:24714b45cd1b 382 }
xorjoep 1:24714b45cd1b 383 else
xorjoep 1:24714b45cd1b 384 #endif /* #ifdef ARM_MATH_MATRIX_CHECK */
xorjoep 1:24714b45cd1b 385
xorjoep 1:24714b45cd1b 386 {
xorjoep 1:24714b45cd1b 387 /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
xorjoep 1:24714b45cd1b 388 /* row loop */
xorjoep 1:24714b45cd1b 389 do
xorjoep 1:24714b45cd1b 390 {
xorjoep 1:24714b45cd1b 391 /* Output pointer is set to starting address of the row being processed */
xorjoep 1:24714b45cd1b 392 px = pOut + i;
xorjoep 1:24714b45cd1b 393
xorjoep 1:24714b45cd1b 394 /* For every row wise process, the column loop counter is to be initiated */
xorjoep 1:24714b45cd1b 395 col = numColsB;
xorjoep 1:24714b45cd1b 396
xorjoep 1:24714b45cd1b 397 /* For every row wise process, the pIn2 pointer is set
xorjoep 1:24714b45cd1b 398 ** to the starting address of the pSrcB data */
xorjoep 1:24714b45cd1b 399 pIn2 = pSrcB->pData;
xorjoep 1:24714b45cd1b 400
xorjoep 1:24714b45cd1b 401 /* column loop */
xorjoep 1:24714b45cd1b 402 do
xorjoep 1:24714b45cd1b 403 {
xorjoep 1:24714b45cd1b 404 /* Set the variable sum, that acts as accumulator, to zero */
xorjoep 1:24714b45cd1b 405 sum = 0;
xorjoep 1:24714b45cd1b 406
xorjoep 1:24714b45cd1b 407 /* Initiate the pointer pIn1 to point to the starting address of pSrcA */
xorjoep 1:24714b45cd1b 408 pIn1 = pInA;
xorjoep 1:24714b45cd1b 409
xorjoep 1:24714b45cd1b 410 /* Matrix A columns number of MAC operations are to be performed */
xorjoep 1:24714b45cd1b 411 colCnt = numColsA;
xorjoep 1:24714b45cd1b 412
xorjoep 1:24714b45cd1b 413 /* matrix multiplication */
xorjoep 1:24714b45cd1b 414 while (colCnt > 0U)
xorjoep 1:24714b45cd1b 415 {
xorjoep 1:24714b45cd1b 416 /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
xorjoep 1:24714b45cd1b 417 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 418 sum += (q31_t) * pIn1++ * *pIn2;
xorjoep 1:24714b45cd1b 419 pIn2 += numColsB;
xorjoep 1:24714b45cd1b 420
xorjoep 1:24714b45cd1b 421 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 422 colCnt--;
xorjoep 1:24714b45cd1b 423 }
xorjoep 1:24714b45cd1b 424
xorjoep 1:24714b45cd1b 425 /* Convert the result from 34.30 to 1.15 format and store the saturated value in destination buffer */
xorjoep 1:24714b45cd1b 426 /* Saturate and store the result in the destination buffer */
xorjoep 1:24714b45cd1b 427 *px++ = (q15_t) __SSAT((sum >> 15), 16);
xorjoep 1:24714b45cd1b 428
xorjoep 1:24714b45cd1b 429 /* Decrement the column loop counter */
xorjoep 1:24714b45cd1b 430 col--;
xorjoep 1:24714b45cd1b 431
xorjoep 1:24714b45cd1b 432 /* Update the pointer pIn2 to point to the starting address of the next column */
xorjoep 1:24714b45cd1b 433 pIn2 = pInB + (numColsB - col);
xorjoep 1:24714b45cd1b 434
xorjoep 1:24714b45cd1b 435 } while (col > 0U);
xorjoep 1:24714b45cd1b 436
xorjoep 1:24714b45cd1b 437 /* Update the pointer pSrcA to point to the starting address of the next row */
xorjoep 1:24714b45cd1b 438 i = i + numColsB;
xorjoep 1:24714b45cd1b 439 pInA = pInA + numColsA;
xorjoep 1:24714b45cd1b 440
xorjoep 1:24714b45cd1b 441 /* Decrement the row loop counter */
xorjoep 1:24714b45cd1b 442 row--;
xorjoep 1:24714b45cd1b 443
xorjoep 1:24714b45cd1b 444 } while (row > 0U);
xorjoep 1:24714b45cd1b 445
xorjoep 1:24714b45cd1b 446 #endif /* #if defined (ARM_MATH_DSP) */
xorjoep 1:24714b45cd1b 447 /* set status as ARM_MATH_SUCCESS */
xorjoep 1:24714b45cd1b 448 status = ARM_MATH_SUCCESS;
xorjoep 1:24714b45cd1b 449 }
xorjoep 1:24714b45cd1b 450
xorjoep 1:24714b45cd1b 451 /* Return to application */
xorjoep 1:24714b45cd1b 452 return (status);
xorjoep 1:24714b45cd1b 453 }
xorjoep 1:24714b45cd1b 454
xorjoep 1:24714b45cd1b 455 /**
xorjoep 1:24714b45cd1b 456 * @} end of MatrixMult group
xorjoep 1:24714b45cd1b 457 */