Merge branch 'jnosky/master'
[fw/stlink] / exampleF4 / CMSIS / DSP_Lib / Source / BasicMathFunctions / arm_shift_q15.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_shift_q15.c   
9 *   
10 * Description:  Shifts the elements of a Q15 vector by a specified number of bits.   
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 * Version 0.0.7  2010/06/10    
30 *    Misra-C changes done   
31 * -------------------------------------------------------------------- */
32
33 #include "arm_math.h"
34
35 /**   
36  * @ingroup groupMath   
37  */
38
39 /**   
40  * @addtogroup shift   
41  * @{   
42  */
43
44 /**   
45  * @brief  Shifts the elements of a Q15 vector a specified number of bits.   
46  * @param[in]  *pSrc points to the input vector   
47  * @param[in]  shiftBits number of bits to shift.  A positive value shifts left; a negative value shifts right.   
48  * @param[out]  *pDst points to the output vector   
49  * @param[in]  blockSize number of samples in the vector   
50  * @return none.   
51  *   
52  * <b>Scaling and Overflow Behavior:</b>   
53  * \par   
54  * The function uses saturating arithmetic.   
55  * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.   
56  */
57
58 void arm_shift_q15(
59   q15_t * pSrc,
60   int8_t shiftBits,
61   q15_t * pDst,
62   uint32_t blockSize)
63 {
64   uint32_t blkCnt;                               /* loop counter */
65   uint8_t sign;                                  /* Sign of shiftBits */
66
67 #ifndef ARM_MATH_CM0
68
69 /* Run the below code for Cortex-M4 and Cortex-M3 */
70
71   q15_t in1, in2;                                /* Temporary variables */
72
73
74   /*loop Unrolling */
75   blkCnt = blockSize >> 2u;
76
77   /* Getting the sign of shiftBits */
78   sign = (shiftBits & 0x80);
79
80   /* If the shift value is positive then do right shift else left shift */
81   if(sign == 0u)
82   {
83     /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.   
84      ** a second loop below computes the remaining 1 to 3 samples. */
85     while(blkCnt > 0u)
86     {
87       /* Read 2 inputs */
88       in1 = *pSrc++;
89       in2 = *pSrc++;
90       /* C = A << shiftBits */
91       /* Shift the inputs and then store the results in the destination buffer. */
92 #ifndef  ARM_MATH_BIG_ENDIAN
93
94       *__SIMD32(pDst)++ = __PKHBT(__SSAT((in1 << shiftBits), 16),
95                                   __SSAT((in2 << shiftBits), 16), 16);
96
97 #else
98
99       *__SIMD32(pDst)++ = __PKHBT(__SSAT((in2 << shiftBits), 16),
100                                   __SSAT((in1 << shiftBits), 16), 16);
101
102 #endif /* #ifndef  ARM_MATH_BIG_ENDIAN    */
103
104       in1 = *pSrc++;
105       in2 = *pSrc++;
106
107 #ifndef  ARM_MATH_BIG_ENDIAN
108
109       *__SIMD32(pDst)++ = __PKHBT(__SSAT((in1 << shiftBits), 16),
110                                   __SSAT((in2 << shiftBits), 16), 16);
111
112 #else
113
114       *__SIMD32(pDst)++ = __PKHBT(__SSAT((in2 << shiftBits), 16),
115                                   __SSAT((in1 << shiftBits), 16), 16);
116
117 #endif /* #ifndef  ARM_MATH_BIG_ENDIAN    */
118
119       /* Decrement the loop counter */
120       blkCnt--;
121     }
122
123     /* If the blockSize is not a multiple of 4, compute any remaining output samples here.   
124      ** No loop unrolling is used. */
125     blkCnt = blockSize % 0x4u;
126
127     while(blkCnt > 0u)
128     {
129       /* C = A << shiftBits */
130       /* Shift and then store the results in the destination buffer. */
131       *pDst++ = __SSAT((*pSrc++ << shiftBits), 16);
132
133       /* Decrement the loop counter */
134       blkCnt--;
135     }
136   }
137   else
138   {
139     /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.   
140      ** a second loop below computes the remaining 1 to 3 samples. */
141     while(blkCnt > 0u)
142     {
143       /* Read 2 inputs */
144       in1 = *pSrc++;
145       in2 = *pSrc++;
146       /* C = A >> shiftBits */
147       /* Shift the inputs and then store the results in the destination buffer. */
148 #ifndef  ARM_MATH_BIG_ENDIAN
149
150       *__SIMD32(pDst)++ = __PKHBT((in1 >> -shiftBits),
151                                   (in2 >> -shiftBits), 16);
152
153 #else
154
155       *__SIMD32(pDst)++ = __PKHBT((in2 >> -shiftBits),
156                                   (in1 >> -shiftBits), 16);
157
158 #endif /* #ifndef  ARM_MATH_BIG_ENDIAN    */
159
160       in1 = *pSrc++;
161       in2 = *pSrc++;
162
163 #ifndef  ARM_MATH_BIG_ENDIAN
164
165       *__SIMD32(pDst)++ = __PKHBT((in1 >> -shiftBits),
166                                   (in2 >> -shiftBits), 16);
167
168 #else
169
170       *__SIMD32(pDst)++ = __PKHBT((in2 >> -shiftBits),
171                                   (in1 >> -shiftBits), 16);
172
173 #endif /* #ifndef  ARM_MATH_BIG_ENDIAN    */
174
175       /* Decrement the loop counter */
176       blkCnt--;
177     }
178
179     /* If the blockSize is not a multiple of 4, compute any remaining output samples here.   
180      ** No loop unrolling is used. */
181     blkCnt = blockSize % 0x4u;
182
183     while(blkCnt > 0u)
184     {
185       /* C = A >> shiftBits */
186       /* Shift the inputs and then store the results in the destination buffer. */
187       *pDst++ = (*pSrc++ >> -shiftBits);
188
189       /* Decrement the loop counter */
190       blkCnt--;
191     }
192   }
193
194 #else
195
196   /* Run the below code for Cortex-M0 */
197
198   /* Getting the sign of shiftBits */
199   sign = (shiftBits & 0x80);
200
201   /* If the shift value is positive then do right shift else left shift */
202   if(sign == 0u)
203   {
204     /* Initialize blkCnt with number of samples */
205     blkCnt = blockSize;
206
207     while(blkCnt > 0u)
208     {
209       /* C = A << shiftBits */
210       /* Shift and then store the results in the destination buffer. */
211       *pDst++ = __SSAT(((q31_t) * pSrc++ << shiftBits), 16);
212
213       /* Decrement the loop counter */
214       blkCnt--;
215     }
216   }
217   else
218   {
219     /* Initialize blkCnt with number of samples */
220     blkCnt = blockSize;
221
222     while(blkCnt > 0u)
223     {
224       /* C = A >> shiftBits */
225       /* Shift the inputs and then store the results in the destination buffer. */
226       *pDst++ = (*pSrc++ >> -shiftBits);
227
228       /* Decrement the loop counter */
229       blkCnt--;
230     }
231   }
232
233 #endif /* #ifndef ARM_MATH_CM0 */
234
235 }
236
237 /**   
238  * @} end of shift group   
239  */