1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: arm_mat_trans_q15.c
4 * Description: Q15 matrix transpose
6 * $Date: 27. January 2017
9 * Target Processor: Cortex-M cores
10 * -------------------------------------------------------------------- */
12 * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
14 * SPDX-License-Identifier: Apache-2.0
16 * Licensed under the Apache License, Version 2.0 (the License); you may
17 * not use this file except in compliance with the License.
18 * You may obtain a copy of the License at
20 * www.apache.org/licenses/LICENSE-2.0
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
32 * @ingroup groupMatrix
36 * @addtogroup MatrixTrans
41 * @brief Q15 matrix transpose.
42 * @param[in] *pSrc points to the input matrix
43 * @param[out] *pDst points to the output matrix
44 * @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
45 * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
48 arm_status
arm_mat_trans_q15(
49 const arm_matrix_instance_q15
* pSrc
,
50 arm_matrix_instance_q15
* pDst
)
52 q15_t
*pSrcA
= pSrc
->pData
; /* input data matrix pointer */
53 q15_t
*pOut
= pDst
->pData
; /* output data matrix pointer */
54 uint16_t nRows
= pSrc
->numRows
; /* number of nRows */
55 uint16_t nColumns
= pSrc
->numCols
; /* number of nColumns */
56 uint16_t col
, row
= nRows
, i
= 0U; /* row and column loop counters */
57 arm_status status
; /* status of matrix transpose */
59 #if defined (ARM_MATH_DSP)
61 /* Run the below code for Cortex-M4 and Cortex-M3 */
62 #ifndef UNALIGNED_SUPPORT_DISABLE
64 q31_t in
; /* variable to hold temporary output */
70 #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
72 #ifdef ARM_MATH_MATRIX_CHECK
75 /* Check for matrix mismatch condition */
76 if ((pSrc
->numRows
!= pDst
->numCols
) || (pSrc
->numCols
!= pDst
->numRows
))
78 /* Set status as ARM_MATH_SIZE_MISMATCH */
79 status
= ARM_MATH_SIZE_MISMATCH
;
82 #endif /* #ifdef ARM_MATH_MATRIX_CHECK */
85 /* Matrix transpose by exchanging the rows with columns */
90 /* Apply loop unrolling and exchange the columns with row elements */
93 /* The pointer pOut is set to starting address of the column being processed */
94 pOut
= pDst
->pData
+ i
;
96 /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
97 ** a second loop below computes the remaining 1 to 3 samples. */
100 #ifndef UNALIGNED_SUPPORT_DISABLE
102 /* Read two elements from the row */
103 in
= *__SIMD32(pSrcA
)++;
105 /* Unpack and store one element in the destination */
106 #ifndef ARM_MATH_BIG_ENDIAN
112 *pOut
= (q15_t
) ((in
& (q31_t
) 0xffff0000) >> 16);
114 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
116 /* Update the pointer pOut to point to the next row of the transposed matrix */
119 /* Unpack and store the second element in the destination */
121 #ifndef ARM_MATH_BIG_ENDIAN
123 *pOut
= (q15_t
) ((in
& (q31_t
) 0xffff0000) >> 16);
129 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
131 /* Update the pointer pOut to point to the next row of the transposed matrix */
134 /* Read two elements from the row */
135 #ifndef ARM_MATH_BIG_ENDIAN
137 in
= *__SIMD32(pSrcA
)++;
141 in
= *__SIMD32(pSrcA
)++;
143 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
145 /* Unpack and store one element in the destination */
146 #ifndef ARM_MATH_BIG_ENDIAN
152 *pOut
= (q15_t
) ((in
& (q31_t
) 0xffff0000) >> 16);
154 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
156 /* Update the pointer pOut to point to the next row of the transposed matrix */
159 /* Unpack and store the second element in the destination */
160 #ifndef ARM_MATH_BIG_ENDIAN
162 *pOut
= (q15_t
) ((in
& (q31_t
) 0xffff0000) >> 16);
168 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */
171 /* Read one element from the row */
174 /* Store one element in the destination */
177 /* Update the pointer px to point to the next row of the transposed matrix */
180 /* Read one element from the row */
183 /* Store one element in the destination */
186 /* Update the pointer px to point to the next row of the transposed matrix */
189 /* Read one element from the row */
192 /* Store one element in the destination */
195 /* Update the pointer px to point to the next row of the transposed matrix */
198 /* Read one element from the row */
201 /* Store one element in the destination */
204 #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
206 /* Update the pointer pOut to point to the next row of the transposed matrix */
209 /* Decrement the column loop counter */
213 /* Perform matrix transpose for last 3 samples here. */
214 col
= nColumns
% 0x4U
;
218 /* Run the below code for Cortex-M0 */
220 #ifdef ARM_MATH_MATRIX_CHECK
222 /* Check for matrix mismatch condition */
223 if ((pSrc
->numRows
!= pDst
->numCols
) || (pSrc
->numCols
!= pDst
->numRows
))
225 /* Set status as ARM_MATH_SIZE_MISMATCH */
226 status
= ARM_MATH_SIZE_MISMATCH
;
229 #endif /* #ifdef ARM_MATH_MATRIX_CHECK */
232 /* Matrix transpose by exchanging the rows with columns */
236 /* The pointer pOut is set to starting address of the column being processed */
237 pOut
= pDst
->pData
+ i
;
239 /* Initialize column loop counter */
242 #endif /* #if defined (ARM_MATH_DSP) */
246 /* Read and store the input element in the destination */
249 /* Update the pointer pOut to point to the next row of the transposed matrix */
252 /* Decrement the column loop counter */
258 /* Decrement the row loop counter */
263 /* set status as ARM_MATH_SUCCESS */
264 status
= ARM_MATH_SUCCESS
;
266 /* Return to application */
271 * @} end of MatrixTrans group