00001 /* ---------------------------------------------------------------------- 00002 * Copyright (C) 2010 ARM Limited. All rights reserved. 00003 * 00004 * $Date: 15. July 2011 00005 * $Revision: V1.0.10 00006 * 00007 * Project: CMSIS DSP Library 00008 * Title: arm_mat_trans_q15.c 00009 * 00010 * Description: Q15 matrix transpose. 00011 * 00012 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 00013 * 00014 * Version 1.0.10 2011/7/15 00015 * Big Endian support added and Merged M0 and M3/M4 Source code. 00016 * 00017 * Version 1.0.3 2010/11/29 00018 * Re-organized the CMSIS folders and updated documentation. 00019 * 00020 * Version 1.0.2 2010/11/11 00021 * Documentation updated. 00022 * 00023 * Version 1.0.1 2010/10/05 00024 * Production release and review comments incorporated. 00025 * 00026 * Version 1.0.0 2010/09/20 00027 * Production release and review comments incorporated. 00028 * 00029 * Version 0.0.5 2010/04/26 00030 * incorporated review comments and updated with latest CMSIS layer 00031 * 00032 * Version 0.0.3 2010/03/10 00033 * Initial version 00034 * -------------------------------------------------------------------- */ 00035 00036 #include "arm_math.h" 00037 00047 /* 00048 * @brief Q15 matrix transpose. 00049 * @param[in] *pSrc points to the input matrix 00050 * @param[out] *pDst points to the output matrix 00051 * @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code> 00052 * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. 00053 */ 00054 00055 arm_status arm_mat_trans_q15( 00056 const arm_matrix_instance_q15 * pSrc, 00057 arm_matrix_instance_q15 * pDst) 00058 { 00059 q15_t *pSrcA = pSrc->pData; /* input data matrix pointer */ 00060 q15_t *pOut = pDst->pData; /* output data matrix pointer */ 00061 uint16_t nRows = pSrc->numRows; /* number of nRows */ 00062 uint16_t nColumns = pSrc->numCols; /* number of nColumns */ 00063 uint16_t col, row = nRows, i = 0u; /* row and column loop counters */ 00064 arm_status status; /* status of matrix transpose */ 00065 00066 #ifndef ARM_MATH_CM0 00067 00068 /* Run the below code for Cortex-M4 and Cortex-M3 */ 00069 00070 q31_t in; /* variable to hold temporary output */ 00071 00072 00073 #ifdef ARM_MATH_MATRIX_CHECK 00074 00075 00076 /* Check for matrix mismatch condition */ 00077 if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows)) 00078 { 00079 /* Set status as ARM_MATH_SIZE_MISMATCH */ 00080 status = ARM_MATH_SIZE_MISMATCH; 00081 } 00082 else 00083 #endif /* #ifdef ARM_MATH_MATRIX_CHECK */ 00084 00085 { 00086 /* Matrix transpose by exchanging the rows with columns */ 00087 /* row loop */ 00088 do 00089 { 00090 /* Apply loop unrolling and exchange the columns with row elements */ 00091 col = nColumns >> 2u; 00092 00093 /* The pointer pOut is set to starting address of the column being processed */ 00094 pOut = pDst->pData + i; 00095 00096 /* First part of the processing with loop unrolling. Compute 4 outputs at a time. 00097 ** a second loop below computes the remaining 1 to 3 samples. */ 00098 while(col > 0u) 00099 { 00100 /* Read two elements from the row */ 00101 in = *__SIMD32(pSrcA)++; 00102 00103 /* Unpack and store one element in the destination */ 00104 #ifndef ARM_MATH_BIG_ENDIAN 00105 00106 *pOut = (q15_t) in; 00107 00108 #else 00109 00110 *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); 00111 00112 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */ 00113 00114 /* Update the pointer pOut to point to the next row of the transposed matrix */ 00115 pOut += nRows; 00116 00117 /* Unpack and store the second element in the destination */ 00118 00119 #ifndef ARM_MATH_BIG_ENDIAN 00120 00121 *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); 00122 00123 #else 00124 00125 *pOut = (q15_t) in; 00126 00127 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */ 00128 00129 /* Update the pointer pOut to point to the next row of the transposed matrix */ 00130 pOut += nRows; 00131 00132 /* Read two elements from the row */ 00133 #ifndef ARM_MATH_BIG_ENDIAN 00134 00135 in = *__SIMD32(pSrcA)++; 00136 00137 #else 00138 00139 in = *__SIMD32(pSrcA)++; 00140 00141 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */ 00142 00143 /* Unpack and store one element in the destination */ 00144 #ifndef ARM_MATH_BIG_ENDIAN 00145 00146 *pOut = (q15_t) in; 00147 00148 #else 00149 00150 *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); 00151 00152 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */ 00153 00154 /* Update the pointer pOut to point to the next row of the transposed matrix */ 00155 pOut += nRows; 00156 00157 /* Unpack and store the second element in the destination */ 00158 #ifndef ARM_MATH_BIG_ENDIAN 00159 00160 *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); 00161 00162 #else 00163 00164 *pOut = (q15_t) in; 00165 00166 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */ 00167 00168 /* Update the pointer pOut to point to the next row of the transposed matrix */ 00169 pOut += nRows; 00170 00171 /* Decrement the column loop counter */ 00172 col--; 00173 } 00174 00175 /* Perform matrix transpose for last 3 samples here. */ 00176 col = nColumns % 0x4u; 00177 00178 #else 00179 00180 /* Run the below code for Cortex-M0 */ 00181 00182 #ifdef ARM_MATH_MATRIX_CHECK 00183 00184 /* Check for matrix mismatch condition */ 00185 if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows)) 00186 { 00187 /* Set status as ARM_MATH_SIZE_MISMATCH */ 00188 status = ARM_MATH_SIZE_MISMATCH; 00189 } 00190 else 00191 #endif /* #ifdef ARM_MATH_MATRIX_CHECK */ 00192 00193 { 00194 /* Matrix transpose by exchanging the rows with columns */ 00195 /* row loop */ 00196 do 00197 { 00198 /* The pointer pOut is set to starting address of the column being processed */ 00199 pOut = pDst->pData + i; 00200 00201 /* Initialize column loop counter */ 00202 col = nColumns; 00203 00204 #endif /* #ifndef ARM_MATH_CM0 */ 00205 00206 while(col > 0u) 00207 { 00208 /* Read and store the input element in the destination */ 00209 *pOut = *pSrcA++; 00210 00211 /* Update the pointer pOut to point to the next row of the transposed matrix */ 00212 pOut += nRows; 00213 00214 /* Decrement the column loop counter */ 00215 col--; 00216 } 00217 00218 i++; 00219 00220 /* Decrement the row loop counter */ 00221 row--; 00222 00223 } while(row > 0u); 00224 00225 /* set status as ARM_MATH_SUCCESS */ 00226 status = ARM_MATH_SUCCESS; 00227 } 00228 /* Return to application */ 00229 return (status); 00230 } 00231