Added all the F4 libraries to the project
[fw/stlink] / exampleF4 / CMSIS / DSP_Lib / Source / ComplexMathFunctions / arm_cmplx_mult_cmplx_q31.c
1 /* ----------------------------------------------------------------------   
2 * Copyright (C) 2010 ARM Limited. All rights reserved.   
3 *   
4 * $Date:        15. July 2011  
5 * $Revision:    V1.0.10  
6 *   
7 * Project:          CMSIS DSP Library   
8 * Title:            arm_cmplx_mult_cmplx_q31.c   
9 *   
10 * Description:  Q31 complex-by-complex multiplication   
11 *   
12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
13 *  
14 * Version 1.0.10 2011/7/15 
15 *    Big Endian support added and Merged M0 and M3/M4 Source code.  
16 *   
17 * Version 1.0.3 2010/11/29  
18 *    Re-organized the CMSIS folders and updated documentation.   
19 *    
20 * Version 1.0.2 2010/11/11   
21 *    Documentation updated.    
22 *   
23 * Version 1.0.1 2010/10/05    
24 *    Production release and review comments incorporated.   
25 *   
26 * Version 1.0.0 2010/09/20    
27 *    Production release and review comments incorporated.   
28 * -------------------------------------------------------------------- */
29
30 #include "arm_math.h"
31
32 /**   
33  * @ingroup groupCmplxMath   
34  */
35
36 /**   
37  * @addtogroup CmplxByCmplxMult   
38  * @{   
39  */
40
41
42 /**   
43  * @brief  Q31 complex-by-complex multiplication   
44  * @param[in]  *pSrcA points to the first input vector   
45  * @param[in]  *pSrcB points to the second input vector   
46  * @param[out]  *pDst  points to the output vector   
47  * @param[in]  numSamples number of complex samples in each vector   
48  * @return none.   
49  *   
50  * <b>Scaling and Overflow Behavior:</b>   
51  * \par   
52  * The function implements 1.31 by 1.31 multiplications and finally output is converted into 3.29 format.   
53  * Input down scaling is not required.   
54  */
55
56 void arm_cmplx_mult_cmplx_q31(
57   q31_t * pSrcA,
58   q31_t * pSrcB,
59   q31_t * pDst,
60   uint32_t numSamples)
61 {
62   q31_t a, b, c, d;                              /* Temporary variables to store real and imaginary values */
63   uint32_t blkCnt;                               /* loop counters */
64
65 #ifndef ARM_MATH_CM0
66
67   /* Run the below code for Cortex-M4 and Cortex-M3 */
68
69   /* loop Unrolling */
70   blkCnt = numSamples >> 2u;
71
72   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.   
73    ** a second loop below computes the remaining 1 to 3 samples. */
74   while(blkCnt > 0u)
75   {
76     /* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1].  */
77     /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i].  */
78     a = *pSrcA++;
79     b = *pSrcA++;
80     c = *pSrcB++;
81     d = *pSrcB++;
82
83     /* store the real result in 3.29 format in the destination buffer. */
84     *pDst++ = (q31_t) ((((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33));
85     /* store the imag result in 3.29 format in the destination buffer. */
86     *pDst++ = (q31_t) ((((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33));
87
88     a = *pSrcA++;
89     b = *pSrcA++;
90     c = *pSrcB++;
91     d = *pSrcB++;
92
93     /* store the result in 3.29 format in the destination buffer. */
94     *pDst++ = (q31_t) ((((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33));
95     /* store the result in 3.29 format in the destination buffer. */
96     *pDst++ = (q31_t) ((((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33));
97
98     a = *pSrcA++;
99     b = *pSrcA++;
100     c = *pSrcB++;
101     d = *pSrcB++;
102
103     /* store the result in 3.29 format in the destination buffer. */
104     *pDst++ = (q31_t) ((((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33));
105     /* store the result in 3.29 format in the destination buffer. */
106     *pDst++ = (q31_t) ((((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33));
107
108     a = *pSrcA++;
109     b = *pSrcA++;
110     c = *pSrcB++;
111     d = *pSrcB++;
112
113     /* store the result in 3.29 format in the destination buffer. */
114     *pDst++ = (q31_t) ((((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33));
115     /* store the result in 3.29 format in the destination buffer. */
116     *pDst++ = (q31_t) ((((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33));
117
118     /* Decrement the blockSize loop counter */
119     blkCnt--;
120   }
121
122   /* If the blockSize is not a multiple of 4, compute any remaining output samples here.   
123    ** No loop unrolling is used. */
124   blkCnt = numSamples % 0x4u;
125
126   while(blkCnt > 0u)
127   {
128     /* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1].  */
129     /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i].  */
130     a = *pSrcA++;
131     b = *pSrcA++;
132     c = *pSrcB++;
133     d = *pSrcB++;
134
135     /* store the result in 3.29 format in the destination buffer. */
136     *pDst++ = (q31_t) ((((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33));
137     /* store the result in 3.29 format in the destination buffer. */
138     *pDst++ = (q31_t) ((((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33));
139
140     /* Decrement the blockSize loop counter */
141     blkCnt--;
142   }
143
144 #else
145
146   /* Run the below code for Cortex-M0 */
147
148   /* loop Unrolling */
149   blkCnt = numSamples >> 1u;
150
151   /* First part of the processing with loop unrolling.  Compute 2 outputs at a time.    
152    ** a second loop below computes the remaining 1 sample. */
153   while(blkCnt > 0u)
154   {
155     /* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1].  */
156     /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i].  */
157     a = *pSrcA++;
158     b = *pSrcA++;
159     c = *pSrcB++;
160     d = *pSrcB++;
161
162     /* store the real result in 3.29 format in the destination buffer. */
163     *pDst++ = (q31_t) ((((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33));
164     /* store the imag result in 3.29 format in the destination buffer. */
165     *pDst++ = (q31_t) ((((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33));
166
167     a = *pSrcA++;
168     b = *pSrcA++;
169     c = *pSrcB++;
170     d = *pSrcB++;
171
172     /* store the result in 3.29 format in the destination buffer. */
173     *pDst++ = (q31_t) ((((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33));
174     /* store the result in 3.29 format in the destination buffer. */
175     *pDst++ = (q31_t) ((((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33));
176
177     /* Decrement the blockSize loop counter */
178     blkCnt--;
179   }
180
181   /* If the blockSize is not a multiple of 2, compute any remaining output samples here.    
182    ** No loop unrolling is used. */
183   blkCnt = numSamples % 0x2u;
184
185   while(blkCnt > 0u)
186   {
187     /* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1].  */
188     /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i].  */
189     a = *pSrcA++;
190     b = *pSrcA++;
191     c = *pSrcB++;
192     d = *pSrcB++;
193
194     /* store the result in 3.29 format in the destination buffer. */
195     *pDst++ = (q31_t) ((((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33));
196     /* store the result in 3.29 format in the destination buffer. */
197     *pDst++ = (q31_t) ((((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33));
198
199     /* Decrement the blockSize loop counter */
200     blkCnt--;
201   }
202
203 #endif /* #ifndef ARM_MATH_CM0 */
204
205 }
206
207 /**   
208  * @} end of CmplxByCmplxMult group   
209  */