1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        arm_q15_to_float.c
4  * Description:  Converts the elements of the Q15 vector to floating-point vector
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/support_functions_f16.h"
30 
31 #if defined(ARM_FLOAT16_SUPPORTED)
32 
33 
34 /**
35   @ingroup groupSupport
36  */
37 
38 /**
39  * @defgroup q15_to_x  Convert 16-bit Integer value
40  */
41 
42 /**
43   @addtogroup q15_to_x
44   @{
45  */
46 
47 /**
48   @brief         Converts the elements of the Q15 vector to f16 vector.
49   @param[in]     pSrc       points to the Q15 input vector
50   @param[out]    pDst       points to the f16 output vector
51   @param[in]     blockSize  number of samples in each vector
52   @return        none
53 
54   @par           Details
55                    The equation used for the conversion process is:
56   <pre>
57       pDst[n] = (float16_t) pSrc[n] / 32768;   0 <= n < blockSize.
58   </pre>
59  */
60 
61 #if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
62 
arm_q15_to_f16(const q15_t * pSrc,float16_t * pDst,uint32_t blockSize)63 void arm_q15_to_f16(
64   const q15_t * pSrc,
65   float16_t * pDst,
66   uint32_t blockSize)
67 {
68     int32_t  blkCnt;           /* loop counters */
69     q15x8_t vecDst;
70     q15_t const *pSrcVec;
71 
72     pSrcVec = (q15_t const *) pSrc;
73     blkCnt = blockSize >> 3;
74     while (blkCnt > 0)
75     {
76         /* C = (float16_t) A / 32768 */
77         /* convert from q15 to float and then store the results in the destination buffer */
78         vecDst = vld1q(pSrcVec);   pSrcVec += 8;
79         vstrhq(pDst, vcvtq_n_f16_s16(vecDst, 15));  pDst += 8;
80         /*
81          * Decrement the blockSize loop counter
82          */
83         blkCnt--;
84     }
85     /*
86      * tail
87      * (will be merged thru tail predication)
88      */
89     blkCnt = blockSize & 7;
90     if (blkCnt > 0)
91     {
92         mve_pred16_t p0 = vctp16q(blkCnt);
93         vecDst = vld1q(pSrcVec);   pSrcVec += 8;
94         vstrhq_p(pDst, vcvtq_n_f16_s16(vecDst, 15), p0);
95     }
96 }
97 #else
98 
arm_q15_to_f16(const q15_t * pSrc,float16_t * pDst,uint32_t blockSize)99 void arm_q15_to_f16(
100   const q15_t * pSrc,
101         float16_t * pDst,
102         uint32_t blockSize)
103 {
104         uint32_t blkCnt;                               /* Loop counter */
105   const q15_t *pIn = pSrc;                             /* Source pointer */
106 
107 #if defined (ARM_MATH_LOOPUNROLL)
108 
109   /* Loop unrolling: Compute 4 outputs at a time */
110   blkCnt = blockSize >> 2U;
111 
112   while (blkCnt > 0U)
113   {
114     /* C = (float16_t) A / 32768 */
115 
116     /* Convert from q15 to float and store result in destination buffer */
117     *pDst++ = ((float16_t) * pIn++ / 32768.0f);
118     *pDst++ = ((float16_t) * pIn++ / 32768.0f);
119     *pDst++ = ((float16_t) * pIn++ / 32768.0f);
120     *pDst++ = ((float16_t) * pIn++ / 32768.0f);
121 
122     /* Decrement loop counter */
123     blkCnt--;
124   }
125 
126   /* Loop unrolling: Compute remaining outputs */
127   blkCnt = blockSize % 0x4U;
128 
129 #else
130 
131   /* Initialize blkCnt with number of samples */
132   blkCnt = blockSize;
133 
134 #endif /* #if defined (ARM_MATH_LOOPUNROLL) */
135 
136   while (blkCnt > 0U)
137   {
138     /* C = (float16_t) A / 32768 */
139 
140     /* Convert from q15 to float and store result in destination buffer */
141     *pDst++ = ((float16_t) *pIn++ / 32768.0f);
142 
143     /* Decrement loop counter */
144     blkCnt--;
145   }
146 
147 }
148 #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
149 
150 /**
151   @} end of q15_to_x group
152  */
153 
154 #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
155 
156