00001 /* ---------------------------------------------------------------------- 00002 * Copyright (C) 2011 ARM Limited. All rights reserved. 00003 * 00004 * $Date: 15. December 2011 00005 * $Revision: V2.0.0 00006 * 00007 * Project: Cortex-R DSP Library 00008 * Title: arm_mat_trans_q15.c 00009 * 00010 * Description: Q15 matrix transpose. 00011 * 00012 * Target Processor: Cortex-R4/R5 00013 * 00014 * Version 1.0.0 2011/03/08 00015 * Alpha release. 00016 * 00017 * Version 1.0.1 2011/09/30 00018 * Beta release. 00019 * 00020 * Version 2.0.0 2011/12/15 00021 * Final release. 00022 * 00023 * -------------------------------------------------------------------- */ 00024 00025 #include "arm_math.h" 00026 00036 /* 00037 * @brief Q15 matrix transpose. 00038 * @param[in] *pSrc points to the input matrix 00039 * @param[out] *pDst points to the output matrix 00040 * @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code> 00041 * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. 00042 * 00043 * \par Conditions for optimum performance 00044 * Input and output buffers should be aligned by 32-bit 00045 * 00046 */ 00047 00048 arm_status arm_mat_trans_q15( 00049 const arm_matrix_instance_q15 * pSrc, 00050 arm_matrix_instance_q15 * pDst) 00051 { 00052 q15_t *pSrcA = pSrc->pData; /* input data matrix pointer */ 00053 q15_t *pOut = pDst->pData; /* output data matrix pointer */ 00054 uint16_t nRows = pSrc->numRows; /* number of nRows */ 00055 uint16_t nColumns = pSrc->numCols; /* number of nColumns */ 00056 uint16_t col, row = nRows, i = 0u; /* row and column loop counters */ 00057 q31_t in; /* variable to hold temporary output */ 00058 arm_status status; /* status of matrix transpose */ 00059 00060 00061 #ifdef ARM_MATH_MATRIX_CHECK 00062 /* Check for matrix mismatch condition */ 00063 if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows)) 00064 { 00065 /* Set status as ARM_MATH_SIZE_MISMATCH */ 00066 status = ARM_MATH_SIZE_MISMATCH; 00067 } 00068 else 00069 #endif 00070 { 00071 /* Matrix transpose by exchanging the rows with columns */ 00072 /* row loop */ 00073 do 00074 { 00075 /* Apply loop unrolling and exchange the columns with row elements */ 00076 col = nColumns >> 2u; 00077 00078 /* The pointer pOut is set to starting address of the column being processed */ 00079 pOut = pDst->pData + i; 00080 00081 /* First part of the processing with loop unrolling. Compute 4 outputs at a time. 00082 ** a second loop below computes the remaining 1 to 3 samples. */ 00083 while(col > 0u) 00084 { 00085 /* Read two elements from the row */ 00086 in = *__SIMD32(pSrcA)++; 00087 00088 /* Unpack and store one element in the destination */ 00089 #ifndef ARM_MATH_BIG_ENDIAN 00090 00091 *pOut = (q15_t) in; 00092 00093 #else 00094 00095 *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); 00096 00097 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */ 00098 00099 /* Update the pointer pOut to point to the next row of the transposed matrix */ 00100 pOut += nRows; 00101 00102 /* Unpack and store the second element in the destination */ 00103 00104 #ifndef ARM_MATH_BIG_ENDIAN 00105 00106 *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); 00107 00108 #else 00109 00110 *pOut = (q15_t) in; 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 /* Read two elements from the row */ 00118 in = *__SIMD32(pSrcA)++; 00119 00120 /* Unpack and store one element in the destination */ 00121 #ifndef ARM_MATH_BIG_ENDIAN 00122 00123 *pOut = (q15_t) in; 00124 00125 #else 00126 00127 *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); 00128 00129 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */ 00130 00131 /* Update the pointer pOut to point to the next row of the transposed matrix */ 00132 pOut += nRows; 00133 00134 /* Unpack and store the second element in the destination */ 00135 #ifndef ARM_MATH_BIG_ENDIAN 00136 00137 *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); 00138 00139 #else 00140 00141 *pOut = (q15_t) in; 00142 00143 #endif /* #ifndef ARM_MATH_BIG_ENDIAN */ 00144 00145 /* Update the pointer pOut to point to the next row of the transposed matrix */ 00146 pOut += nRows; 00147 00148 /* Decrement the column loop counter */ 00149 col--; 00150 } 00151 00152 /* Perform matrix transpose for last 3 samples here. */ 00153 col = nColumns % 0x4u; 00154 00155 while(col > 0u) 00156 { 00157 /* Read and store the input element in the destination */ 00158 *pOut = *pSrcA++; 00159 00160 /* Update the pointer pOut to point to the next row of the transposed matrix */ 00161 pOut += nRows; 00162 00163 /* Decrement the column loop counter */ 00164 col--; 00165 } 00166 00167 i++; 00168 00169 /* Decrement the row loop counter */ 00170 row--; 00171 00172 } while(row > 0u); 00173 00174 /* set status as ARM_MATH_SUCCESS */ 00175 status = ARM_MATH_SUCCESS; 00176 } 00177 /* Return to application */ 00178 return (status); 00179 } 00180