| #include "edge-impulse-sdk/dsp/config.hpp" |
| #if EIDSP_LOAD_CMSIS_DSP_SOURCES |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include "edge-impulse-sdk/CMSIS/DSP/Include/dsp/matrix_functions.h" |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE) |
|
|
| #define MVE_ASRL_SAT16(acc, shift) ((sqrshrl_sat48(acc, -(32-shift)) >> 32) & 0xffffffff) |
|
|
| #define MATRIX_DIM2 2 |
| #define MATRIX_DIM3 3 |
| #define MATRIX_DIM4 4 |
|
|
| __STATIC_INLINE arm_status arm_mat_mult_q15_2x2_mve( |
| const arm_matrix_instance_q15 * pSrcA, |
| const arm_matrix_instance_q15 * pSrcB, |
| arm_matrix_instance_q15 * pDst) |
| { |
| q15_t *pInB = pSrcB->pData; |
| q15_t *pInA = pSrcA->pData; |
| q15_t *pOut = pDst->pData; |
| uint16x8_t vecColBOffs; |
| q15_t *pInA0 = pInA; |
| q15_t *pInA1 = pInA0 + MATRIX_DIM2; |
| q63_t acc0, acc1; |
| q15x8_t vecB, vecA0, vecA1; |
| mve_pred16_t p0 = vctp16q(MATRIX_DIM2); |
|
|
| vecColBOffs = vidupq_u16((uint32_t)0, 2); |
|
|
| pInB = pSrcB->pData; |
|
|
| vecB = vldrhq_gather_shifted_offset_z_s16((q15_t const *)pInB, vecColBOffs, p0); |
|
|
| vecA0 = vldrhq_s16(pInA0); |
| vecA1 = vldrhq_s16(pInA1); |
|
|
| acc0 = vmlaldavq(vecA0, vecB); |
| acc1 = vmlaldavq(vecA1, vecB); |
|
|
| acc0 = asrl(acc0, 15); |
| acc1 = asrl(acc1, 15); |
|
|
| pOut[0 * MATRIX_DIM2] = (q15_t) __SSAT(acc0, 16); |
| pOut[1 * MATRIX_DIM2] = (q15_t) __SSAT(acc1, 16); |
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrhq_gather_shifted_offset_z_s16(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmlaldavq(vecA0, vecB); |
| acc1 = vmlaldavq(vecA1, vecB); |
|
|
| acc0 = asrl(acc0, 15); |
| acc1 = asrl(acc1, 15); |
|
|
| pOut[0 * MATRIX_DIM2] = (q15_t) __SSAT(acc0, 16); |
| pOut[1 * MATRIX_DIM2] = (q15_t) __SSAT(acc1, 16); |
|
|
| |
| |
| |
| return (ARM_MATH_SUCCESS); |
| } |
|
|
|
|
|
|
| __STATIC_INLINE arm_status arm_mat_mult_q15_3x3_mve( |
| const arm_matrix_instance_q15 * pSrcA, |
| const arm_matrix_instance_q15 * pSrcB, |
| arm_matrix_instance_q15 * pDst) |
| { |
| q15_t *pInB = pSrcB->pData; |
| q15_t *pInA = pSrcA->pData; |
| q15_t *pOut = pDst->pData; |
| uint16x8_t vecColBOffs; |
| q15_t *pInA0 = pInA; |
| q15_t *pInA1 = pInA0 + MATRIX_DIM3; |
| q15_t *pInA2 = pInA1 + MATRIX_DIM3; |
| q63_t acc0, acc1, acc2; |
| q15x8_t vecB, vecA0, vecA1, vecA2; |
| mve_pred16_t p0 = vctp16q(MATRIX_DIM3); |
|
|
| vecColBOffs = vidupq_u16((uint32_t)0, 1); |
| vecColBOffs = vecColBOffs * MATRIX_DIM3; |
|
|
| pInB = pSrcB->pData; |
|
|
| vecB = vldrhq_gather_shifted_offset_z_s16((q15_t const *)pInB, vecColBOffs, p0); |
|
|
| vecA0 = vldrhq_s16(pInA0); |
| vecA1 = vldrhq_s16(pInA1); |
| vecA2 = vldrhq_s16(pInA2); |
|
|
| acc0 = vmlaldavq(vecA0, vecB); |
| acc1 = vmlaldavq(vecA1, vecB); |
| acc2 = vmlaldavq(vecA2, vecB); |
|
|
| acc0 = asrl(acc0, 15); |
| acc1 = asrl(acc1, 15); |
| acc2 = asrl(acc2, 15); |
|
|
| pOut[0 * MATRIX_DIM3] = (q15_t) __SSAT(acc0, 16); |
| pOut[1 * MATRIX_DIM3] = (q15_t) __SSAT(acc1, 16); |
| pOut[2 * MATRIX_DIM3] = (q15_t) __SSAT(acc2, 16); |
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrhq_gather_shifted_offset_z_s16(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmlaldavq(vecA0, vecB); |
| acc1 = vmlaldavq(vecA1, vecB); |
| acc2 = vmlaldavq(vecA2, vecB); |
|
|
| acc0 = asrl(acc0, 15); |
| acc1 = asrl(acc1, 15); |
| acc2 = asrl(acc2, 15); |
|
|
| pOut[0 * MATRIX_DIM3] = (q15_t) __SSAT(acc0, 16); |
| pOut[1 * MATRIX_DIM3] = (q15_t) __SSAT(acc1, 16); |
| pOut[2 * MATRIX_DIM3] = (q15_t) __SSAT(acc2, 16); |
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrhq_gather_shifted_offset_z_s16(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmlaldavq(vecA0, vecB); |
| acc1 = vmlaldavq(vecA1, vecB); |
| acc2 = vmlaldavq(vecA2, vecB); |
|
|
| acc0 = asrl(acc0, 15); |
| acc1 = asrl(acc1, 15); |
| acc2 = asrl(acc2, 15); |
|
|
| pOut[0 * MATRIX_DIM3] = (q15_t) __SSAT(acc0, 16); |
| pOut[1 * MATRIX_DIM3] = (q15_t) __SSAT(acc1, 16); |
| pOut[2 * MATRIX_DIM3] = (q15_t) __SSAT(acc2, 16); |
| |
| |
| |
| return (ARM_MATH_SUCCESS); |
| } |
|
|
|
|
| __STATIC_INLINE arm_status arm_mat_mult_q15_4x4_mve( |
| const arm_matrix_instance_q15 * pSrcA, |
| const arm_matrix_instance_q15 * pSrcB, |
| arm_matrix_instance_q15 * pDst) |
| { |
| q15_t *pInB = pSrcB->pData; |
| q15_t *pInA = pSrcA->pData; |
| q15_t *pOut = pDst->pData; |
| uint16x8_t vecColBOffs; |
| q15_t *pInA0 = pInA; |
| q15_t *pInA1 = pInA0 + MATRIX_DIM4; |
| q15_t *pInA2 = pInA1 + MATRIX_DIM4; |
| q15_t *pInA3 = pInA2 + MATRIX_DIM4; |
| q63_t acc0, acc1, acc2, acc3; |
| q15x8_t vecB, vecA0, vecA1, vecA2, vecA3; |
| mve_pred16_t p0 = vctp16q(MATRIX_DIM4); |
|
|
| vecColBOffs = vidupq_u16((uint32_t)0, 4); |
|
|
| pInB = pSrcB->pData; |
|
|
| vecB = vldrhq_gather_shifted_offset_z_s16((q15_t const *)pInB, vecColBOffs, p0); |
|
|
| vecA0 = vldrhq_s16(pInA0); |
| vecA1 = vldrhq_s16(pInA1); |
| vecA2 = vldrhq_s16(pInA2); |
| vecA3 = vldrhq_s16(pInA3); |
|
|
| acc0 = vmlaldavq(vecA0, vecB); |
| acc1 = vmlaldavq(vecA1, vecB); |
| acc2 = vmlaldavq(vecA2, vecB); |
| acc3 = vmlaldavq(vecA3, vecB); |
|
|
| acc0 = asrl(acc0, 15); |
| acc1 = asrl(acc1, 15); |
| acc2 = asrl(acc2, 15); |
| acc3 = asrl(acc3, 15); |
|
|
| pOut[0 * MATRIX_DIM4] = (q15_t) __SSAT(acc0, 16); |
| pOut[1 * MATRIX_DIM4] = (q15_t) __SSAT(acc1, 16); |
| pOut[2 * MATRIX_DIM4] = (q15_t) __SSAT(acc2, 16); |
| pOut[3 * MATRIX_DIM4] = (q15_t) __SSAT(acc3, 16); |
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrhq_gather_shifted_offset_z_s16(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmlaldavq(vecA0, vecB); |
| acc1 = vmlaldavq(vecA1, vecB); |
| acc2 = vmlaldavq(vecA2, vecB); |
| acc3 = vmlaldavq(vecA3, vecB); |
|
|
| acc0 = asrl(acc0, 15); |
| acc1 = asrl(acc1, 15); |
| acc2 = asrl(acc2, 15); |
| acc3 = asrl(acc3, 15); |
|
|
| pOut[0 * MATRIX_DIM4] = (q15_t) __SSAT(acc0, 16); |
| pOut[1 * MATRIX_DIM4] = (q15_t) __SSAT(acc1, 16); |
| pOut[2 * MATRIX_DIM4] = (q15_t) __SSAT(acc2, 16); |
| pOut[3 * MATRIX_DIM4] = (q15_t) __SSAT(acc3, 16); |
|
|
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrhq_gather_shifted_offset_z_s16(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmlaldavq(vecA0, vecB); |
| acc1 = vmlaldavq(vecA1, vecB); |
| acc2 = vmlaldavq(vecA2, vecB); |
| acc3 = vmlaldavq(vecA3, vecB); |
|
|
| acc0 = asrl(acc0, 15); |
| acc1 = asrl(acc1, 15); |
| acc2 = asrl(acc2, 15); |
| acc3 = asrl(acc3, 15); |
|
|
| pOut[0 * MATRIX_DIM4] = (q15_t) __SSAT(acc0, 16); |
| pOut[1 * MATRIX_DIM4] = (q15_t) __SSAT(acc1, 16); |
| pOut[2 * MATRIX_DIM4] = (q15_t) __SSAT(acc2, 16); |
| pOut[3 * MATRIX_DIM4] = (q15_t) __SSAT(acc3, 16); |
|
|
| pOut++; |
|
|
| |
| pInB = pInB + 1; |
|
|
| vecB = vldrhq_gather_shifted_offset_z_s16(pInB, vecColBOffs, p0); |
|
|
| acc0 = vmlaldavq(vecA0, vecB); |
| acc1 = vmlaldavq(vecA1, vecB); |
| acc2 = vmlaldavq(vecA2, vecB); |
| acc3 = vmlaldavq(vecA3, vecB); |
|
|
| acc0 = asrl(acc0, 15); |
| acc1 = asrl(acc1, 15); |
| acc2 = asrl(acc2, 15); |
| acc3 = asrl(acc3, 15); |
|
|
| pOut[0 * MATRIX_DIM4] = (q15_t) __SSAT(acc0, 16); |
| pOut[1 * MATRIX_DIM4] = (q15_t) __SSAT(acc1, 16); |
| pOut[2 * MATRIX_DIM4] = (q15_t) __SSAT(acc2, 16); |
| pOut[3 * MATRIX_DIM4] = (q15_t) __SSAT(acc3, 16); |
| |
| |
| |
| return (ARM_MATH_SUCCESS); |
| } |
|
|
|
|
| arm_status arm_mat_mult_q15( |
| const arm_matrix_instance_q15 * pSrcA, |
| const arm_matrix_instance_q15 * pSrcB, |
| arm_matrix_instance_q15 * pDst, |
| q15_t * pState) |
| { |
| q15_t *pInA = pSrcA->pData; |
| q15_t *pInB = pSrcB->pData; |
| q15_t *pInA2; |
| q15_t *pInB2; |
| q15_t *px; |
| q15_t *px2; |
| uint32_t numRowsA = pSrcA->numRows; |
| uint32_t numColsB = pSrcB->numCols; |
| uint32_t numColsA = pSrcA->numCols; |
| uint32_t numRowsB = pSrcB->numRows; |
| uint32_t col, i = 0u, j, row = numRowsB; |
| q15_t *pSrcBT = pState; |
| uint32_t blkCnt; |
| arm_status status; |
| arm_matrix_instance_q15 BT; |
|
|
| #ifdef ARM_MATH_MATRIX_CHECK |
|
|
| |
| if ((pSrcA->numCols != pSrcB->numRows) || |
| (pSrcA->numRows != pDst->numRows) || |
| (pSrcB->numCols != pDst->numCols) ) |
| { |
| |
| status = ARM_MATH_SIZE_MISMATCH; |
| } |
| else |
| #endif |
| { |
| |
| if (numRowsA == numColsB && numColsB == numColsA) { |
|
|
| if (numRowsA == 1) { |
| q63_t sum; |
| sum = pInA[0] * pInB[0]; |
| pDst->pData[0] = (q15_t) __SSAT((sum >> 15), 16); |
| return (ARM_MATH_SUCCESS); |
| } else if (numRowsA == 2) |
| return arm_mat_mult_q15_2x2_mve(pSrcA, pSrcB, pDst); |
| else if (numRowsA == 3) |
| return arm_mat_mult_q15_3x3_mve(pSrcA, pSrcB, pDst); |
| else if (numRowsA == 4) |
| return arm_mat_mult_q15_4x4_mve(pSrcA, pSrcB, pDst); |
| } |
|
|
| |
| |
| |
|
|
| BT.numRows = numColsB; |
| BT.numCols = numRowsB; |
| BT.pData = pSrcBT; |
|
|
| arm_mat_trans_q15(pSrcB, &BT); |
|
|
|
|
| |
| |
| |
| i = 0; |
| row = numRowsA >> 1; |
| px = pDst->pData; |
| px2 = px + numColsB; |
|
|
| |
| |
| |
|
|
| |
| |
| |
| while (row > 0u) { |
| |
| |
| |
| col = numColsB >> 1; |
| |
| |
| |
| |
| pInB = pSrcBT; |
| pInB2 = pInB + numRowsB; |
| j = 0; |
|
|
| |
| |
| |
| while (col > 0u) { |
| q15_t const *pSrcAVec, *pSrcBVec, *pSrcA2Vec, *pSrcB2Vec; |
| q15x8_t vecA, vecA2, vecB, vecB2; |
| q63_t acc0, acc1, acc2, acc3; |
|
|
| |
| |
| |
| pInA = pSrcA->pData + i; |
| pInA2 = pInA + numColsA; |
| pInB = pSrcBT + j; |
| pInB2 = pInB + numRowsB; |
|
|
|
|
| pSrcAVec = (q15_t const *) pInA; |
| pSrcA2Vec = (q15_t const *) pInA2; |
| pSrcBVec = (q15_t const *) pInB; |
| pSrcB2Vec = (q15_t const *) pInB2; |
|
|
| acc0 = 0LL; |
| acc1 = 0LL; |
| acc2 = 0LL; |
| acc3 = 0LL; |
|
|
| vecA = vld1q(pSrcAVec); |
| pSrcAVec += 8; |
|
|
| blkCnt = numColsA / 8; |
| while (blkCnt > 0U) { |
| vecB = vld1q(pSrcBVec); |
| pSrcBVec += 8; |
| acc0 = vmlaldavaq(acc0, vecA, vecB); |
| vecA2 = vld1q(pSrcA2Vec); |
| pSrcA2Vec += 8; |
| acc1 = vmlaldavaq(acc1, vecA2, vecB); |
| vecB2 = vld1q(pSrcB2Vec); |
| pSrcB2Vec += 8; |
| acc2 = vmlaldavaq(acc2, vecA, vecB2); |
| vecA = vld1q(pSrcAVec); |
| pSrcAVec += 8; |
| acc3 = vmlaldavaq(acc3, vecA2, vecB2); |
|
|
| blkCnt--; |
| } |
| |
| |
| |
| blkCnt = numColsA & 7; |
| if (blkCnt > 0U) { |
| mve_pred16_t p0 = vctp16q(blkCnt); |
| vecB = vld1q(pSrcBVec); |
| acc0 = vmlaldavaq_p(acc0, vecA, vecB, p0); |
| vecA2 = vld1q(pSrcA2Vec); |
| acc1 = vmlaldavaq_p(acc1, vecA2, vecB, p0); |
| vecB2 = vld1q(pSrcB2Vec); |
| acc2 = vmlaldavaq_p(acc2, vecA, vecB2, p0); |
| vecA = vld1q(pSrcAVec); |
| acc3 = vmlaldavaq_p(acc3, vecA2, vecB2, p0); |
| } |
|
|
| *px++ = (q15_t) MVE_ASRL_SAT16(acc0, 15); |
| *px++ = (q15_t) MVE_ASRL_SAT16(acc2, 15); |
| *px2++ = (q15_t) MVE_ASRL_SAT16(acc1, 15); |
| *px2++ = (q15_t) MVE_ASRL_SAT16(acc3, 15); |
| j += numRowsB * 2; |
| |
| |
| |
| col--; |
|
|
| } |
|
|
| i = i + numColsA * 2; |
| px = px2 + (numColsB & 1u); |
| px2 = px + numColsB; |
| |
| |
| |
| row--; |
| } |
|
|
| |
| |
| |
|
|
| if (numColsB & 1u) { |
| row = numRowsA & (~0x1); |
| px = pDst->pData + numColsB - 1; |
| i = 0; |
|
|
| |
| |
| |
| while (row > 0) { |
| q15_t const *pSrcAVec, *pSrcBVec; |
| q15x8_t vecA, vecB; |
| q63_t acc0; |
|
|
| |
| |
| |
| pInB = pSrcBT + numRowsB * (numColsB - 1); |
| pInA = pSrcA->pData + i; |
|
|
| pSrcAVec = (q15_t const *) pInA; |
| pSrcBVec = (q15_t const *) pInB; |
|
|
| acc0 = 0LL; |
| blkCnt = (numColsA) / 8; |
| while (blkCnt > 0U) { |
| vecA = vld1q(pSrcAVec); |
| pSrcAVec += 8; |
| vecB = vld1q(pSrcBVec); |
| pSrcBVec += 8; |
| acc0 = vmlaldavaq(acc0, vecA, vecB); |
|
|
| blkCnt--; |
| } |
| |
| |
| |
| blkCnt = (numColsA & 7); |
| if (blkCnt > 0U) { |
| mve_pred16_t p0 = vctp16q(blkCnt); |
| vecA = vld1q(pSrcAVec); |
| vecB = vld1q(pSrcBVec); |
| acc0 = vmlaldavaq_p(acc0, vecA, vecB, p0); |
| } |
|
|
| *px = (q15_t) MVE_ASRL_SAT16(acc0, 15); |
|
|
| px += numColsB; |
|
|
| i += numColsA; |
| |
| |
| |
| row--; |
| } |
| } |
|
|
| if (numRowsA & 1u) { |
| col = numColsB; |
| i = 0u; |
| |
| |
| |
| px = pDst->pData + (numColsB) * (numRowsA - 1); |
| |
| |
| |
| while (col > 0) { |
| q15_t const *pSrcAVec, *pSrcBVec; |
| q15x8_t vecA, vecB; |
| q63_t acc0; |
|
|
| |
| |
| |
| pInA = pSrcA->pData + (numRowsA - 1) * numColsA; |
| pInB = pSrcBT + i; |
|
|
| |
| |
| |
| pSrcAVec = (q15_t const *) pInA; |
| pSrcBVec = (q15_t const *) pInB; |
| acc0 = 0LL; |
|
|
| blkCnt = ((numColsA) / 8); |
| while (blkCnt > 0U) { |
| vecA = vld1q(pSrcAVec); |
| pSrcAVec += 8; |
| vecB = vld1q(pSrcBVec); |
| pSrcBVec += 8; |
| acc0 = vmlaldavaq(acc0, vecA, vecB); |
|
|
| blkCnt--; |
| } |
| |
| |
| |
| blkCnt = (numColsA & 7); |
| if (blkCnt > 0U) { |
| mve_pred16_t p0 = vctp16q(blkCnt); |
| vecA = vld1q(pSrcAVec); |
| vecB = vld1q(pSrcBVec); |
| acc0 = vmlaldavaq_p(acc0, vecA, vecB, p0); |
| } |
|
|
| *px++ = (q15_t) MVE_ASRL_SAT16(acc0, 15); |
|
|
| i += numColsA; |
|
|
| |
| |
| |
| col--; |
| } |
| } |
|
|
| |
| status = ARM_MATH_SUCCESS; |
| } |
| |
| return (status); |
| } |
|
|
| #else |
| arm_status arm_mat_mult_q15( |
| const arm_matrix_instance_q15 * pSrcA, |
| const arm_matrix_instance_q15 * pSrcB, |
| arm_matrix_instance_q15 * pDst, |
| q15_t * pState) |
| { |
| q63_t sum; |
|
|
| #if defined (ARM_MATH_DSP) |
|
|
| q15_t *pSrcBT = pState; |
| q15_t *pInA = pSrcA->pData; |
| q15_t *pInB = pSrcB->pData; |
| q15_t *px; |
| uint16_t numRowsA = pSrcA->numRows; |
| uint16_t numColsB = pSrcB->numCols; |
| uint16_t numColsA = pSrcA->numCols; |
| uint16_t numRowsB = pSrcB->numRows; |
| uint32_t col, i = 0U, row = numRowsB, colCnt; |
| arm_status status; |
|
|
| q31_t inA1, inB1, inA2, inB2; |
| arm_matrix_instance_q15 BT; |
|
|
| #ifdef ARM_MATH_MATRIX_CHECK |
|
|
| |
| if ((pSrcA->numCols != pSrcB->numRows) || |
| (pSrcA->numRows != pDst->numRows) || |
| (pSrcB->numCols != pDst->numCols) ) |
| { |
| |
| status = ARM_MATH_SIZE_MISMATCH; |
| } |
| else |
|
|
| #endif |
| { |
|
|
| BT.numRows = numColsB; |
| BT.numCols = numRowsB; |
| BT.pData = pSrcBT; |
|
|
| arm_mat_trans_q15(pSrcB,&BT); |
| |
| row = numRowsA; |
| i = 0U; |
| px = pDst->pData; |
|
|
| |
| |
| do |
| { |
| |
| col = numColsB; |
|
|
| |
| pInB = pSrcBT; |
|
|
| |
| do |
| { |
| |
| sum = 0; |
|
|
| |
| pInA = pSrcA->pData + i; |
|
|
| |
| colCnt = numColsA >> 2U; |
|
|
| |
| while (colCnt > 0U) |
| { |
| |
|
|
| |
| inA1 = read_q15x2_ia (&pInA); |
| inB1 = read_q15x2_ia (&pInB); |
|
|
| inA2 = read_q15x2_ia (&pInA); |
| inB2 = read_q15x2_ia (&pInB); |
|
|
| |
| sum = __SMLALD(inA1, inB1, sum); |
| sum = __SMLALD(inA2, inB2, sum); |
|
|
| |
| colCnt--; |
| } |
|
|
| |
| colCnt = numColsA % 0x4U; |
|
|
| while (colCnt > 0U) |
| { |
| |
| sum += *pInA++ * *pInB++; |
|
|
| |
| colCnt--; |
| } |
|
|
| |
| *px = (q15_t) (__SSAT((sum >> 15), 16)); |
| px++; |
|
|
| |
| col--; |
|
|
| } while (col > 0U); |
|
|
| i = i + numColsA; |
|
|
| |
| row--; |
|
|
| } while (row > 0U); |
|
|
| #else |
|
|
| q15_t *pIn1 = pSrcA->pData; |
| q15_t *pIn2 = pSrcB->pData; |
| q15_t *pInA = pSrcA->pData; |
| q15_t *pInB = pSrcB->pData; |
| q15_t *pOut = pDst->pData; |
| q15_t *px; |
| uint16_t numColsB = pSrcB->numCols; |
| uint16_t numColsA = pSrcA->numCols; |
| uint16_t numRowsA = pSrcA->numRows; |
| uint32_t col, i = 0U, row = numRowsA, colCnt; |
| arm_status status; |
| (void)pState; |
|
|
| #ifdef ARM_MATH_MATRIX_CHECK |
|
|
| |
| if ((pSrcA->numCols != pSrcB->numRows) || |
| (pSrcA->numRows != pDst->numRows) || |
| (pSrcB->numCols != pDst->numCols) ) |
| { |
| |
| status = ARM_MATH_SIZE_MISMATCH; |
| } |
| else |
|
|
| #endif |
|
|
| { |
| |
| |
| do |
| { |
| |
| px = pOut + i; |
|
|
| |
| col = numColsB; |
|
|
| |
| pIn2 = pSrcB->pData; |
|
|
| |
| do |
| { |
| |
| sum = 0; |
|
|
| |
| pIn1 = pInA; |
|
|
| |
| colCnt = numColsA; |
|
|
| |
| while (colCnt > 0U) |
| { |
| |
|
|
| |
| sum += (q31_t) * pIn1++ * *pIn2; |
| pIn2 += numColsB; |
|
|
| |
| colCnt--; |
| } |
|
|
| |
|
|
| |
| *px++ = (q15_t) __SSAT((sum >> 15), 16); |
|
|
| |
| col--; |
|
|
| |
| pIn2 = pInB + (numColsB - col); |
|
|
| } while (col > 0U); |
|
|
| |
| i = i + numColsB; |
| pInA = pInA + numColsA; |
|
|
| |
| row--; |
|
|
| } while (row > 0U); |
|
|
| #endif |
|
|
| |
| status = ARM_MATH_SUCCESS; |
| } |
|
|
| |
| return (status); |
| } |
| #endif |
|
|
| |
| |
| |
|
|
| #endif |
|
|