1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        arm_cmplx_conj_q31.c
4  * Description:  Q31 complex conjugate
5  *
6  * $Date:        23 April 2021
7  * $Revision:    V1.9.0
8  *
9  * Target Processor: Cortex-M and Cortex-A cores
10  * -------------------------------------------------------------------- */
11 /*
12  * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
13  *
14  * SPDX-License-Identifier: Apache-2.0
15  *
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
19  *
20  * www.apache.org/licenses/LICENSE-2.0
21  *
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.
27  */
28 
29 #include "dsp/complex_math_functions.h"
30 
31 /**
32   @ingroup groupCmplxMath
33  */
34 
35 /**
36   @addtogroup cmplx_conj
37   @{
38  */
39 
40 /**
41   @brief         Q31 complex conjugate.
42   @param[in]     pSrc        points to the input vector
43   @param[out]    pDst        points to the output vector
44   @param[in]     numSamples  number of samples in each vector
45   @return        none
46 
47   @par           Scaling and Overflow Behavior
48                    The function uses saturating arithmetic.
49                    The Q31 value -1 (0x80000000) is saturated to the maximum allowable positive value 0x7FFFFFFF.
50  */
51 
52 #if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
53 
arm_cmplx_conj_q31(const q31_t * pSrc,q31_t * pDst,uint32_t numSamples)54 void arm_cmplx_conj_q31(
55   const q31_t * pSrc,
56         q31_t * pDst,
57         uint32_t numSamples)
58 {
59 
60     uint32_t blockSize = numSamples * CMPLX_DIM;   /* loop counters */
61     uint32_t blkCnt;
62     q31x4x2_t vecSrc;
63     q31_t in;                                      /* Temporary input variable */
64     q31x4_t zero;
65 
66     zero = vdupq_n_s32(0);
67 
68 
69     /* Compute 4 real samples at a time */
70     blkCnt = blockSize >> 3U;
71 
72     while (blkCnt > 0U)
73     {
74 
75         vecSrc = vld2q(pSrc);
76         vecSrc.val[1] = vqsubq(zero, vecSrc.val[1]);
77         vst2q(pDst,vecSrc);
78         /*
79          * Decrement the blkCnt loop counter
80          * Advance vector source and destination pointers
81          */
82         pSrc += 8;
83         pDst += 8;
84         blkCnt --;
85     }
86 
87      /* Tail */
88     blkCnt = (blockSize & 0x7) >> 1;
89 
90     while (blkCnt > 0U)
91     {
92       /* C[0] + jC[1] = A[0]+ j(-1)A[1] */
93 
94       /* Calculate Complex Conjugate and store result in destination buffer. */
95       *pDst++ =  *pSrc++;
96       in = *pSrc++;
97       *pDst++ = __QSUB(0, in);
98 
99       /* Decrement loop counter */
100       blkCnt--;
101     }
102 
103 
104 }
105 #else
106 
arm_cmplx_conj_q31(const q31_t * pSrc,q31_t * pDst,uint32_t numSamples)107 void arm_cmplx_conj_q31(
108   const q31_t * pSrc,
109         q31_t * pDst,
110         uint32_t numSamples)
111 {
112         uint32_t blkCnt;                               /* Loop counter */
113         q31_t in;                                      /* Temporary input variable */
114 
115 #if defined (ARM_MATH_LOOPUNROLL)
116 
117   /* Loop unrolling: Compute 4 outputs at a time */
118   blkCnt = numSamples >> 2U;
119 
120   while (blkCnt > 0U)
121   {
122     /* C[0] + jC[1] = A[0]+ j(-1)A[1] */
123 
124     /* Calculate Complex Conjugate and store result in destination buffer. */
125     *pDst++ =  *pSrc++;
126     in = *pSrc++;
127 #if defined (ARM_MATH_DSP)
128     *pDst++ = __QSUB(0, in);
129 #else
130     *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
131 #endif
132 
133     *pDst++ =  *pSrc++;
134     in =  *pSrc++;
135 #if defined (ARM_MATH_DSP)
136     *pDst++ = __QSUB(0, in);
137 #else
138     *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
139 #endif
140 
141     *pDst++ =  *pSrc++;
142     in = *pSrc++;
143 #if defined (ARM_MATH_DSP)
144     *pDst++ = __QSUB(0, in);
145 #else
146     *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
147 #endif
148 
149     *pDst++ =  *pSrc++;
150     in = *pSrc++;
151 #if defined (ARM_MATH_DSP)
152     *pDst++ = __QSUB(0, in);
153 #else
154     *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
155 #endif
156 
157     /* Decrement loop counter */
158     blkCnt--;
159   }
160 
161   /* Loop unrolling: Compute remaining outputs */
162   blkCnt = numSamples % 0x4U;
163 
164 #else
165 
166   /* Initialize blkCnt with number of samples */
167   blkCnt = numSamples;
168 
169 #endif /* #if defined (ARM_MATH_LOOPUNROLL) */
170 
171   while (blkCnt > 0U)
172   {
173     /* C[0] + jC[1] = A[0]+ j(-1)A[1] */
174 
175     /* Calculate Complex Conjugate and store result in destination buffer. */
176     *pDst++ =  *pSrc++;
177     in = *pSrc++;
178 #if defined (ARM_MATH_DSP)
179     *pDst++ = __QSUB(0, in);
180 #else
181     *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
182 #endif
183 
184     /* Decrement loop counter */
185     blkCnt--;
186   }
187 
188 }
189 #endif /* defined(ARM_MATH_MVEI) */
190 
191 /**
192   @} end of cmplx_conj group
193  */
194