1 /*
2  * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 /* ----------------------------------------------------------------------
20  * Project:      CMSIS NN Library
21  * Title:        arm_nn_add_q7.c
22  * Description:  Non saturating addition of elements of a q7 vector.
23  *
24  * $Date:        09. October 2020
25  * $Revision:    V.1.0.1
26  *
27  * Target Processor:  Cortex-M cores
28  *
29  * -------------------------------------------------------------------- */
30 
31 #include "arm_nn_tables.h"
32 #include "arm_nnsupportfunctions.h"
33 
34 /**
35  * @ingroup groupSupport
36  */
37 
38 /**
39  * @addtogroup NNBasicMath
40  * @{
41  */
42 
arm_nn_add_q7(const q7_t * input,q31_t * output,uint32_t block_size)43 void arm_nn_add_q7(const q7_t *input, q31_t *output, uint32_t block_size)
44 {
45     uint32_t block_count;
46     q31_t result = 0;
47 #if defined(ARM_MATH_DSP)
48     /* Loop unrolling: Compute 4 outputs at a time */
49     block_count = block_size >> 2U;
50 
51     while (block_count > 0U)
52     {
53         const int32_t mult_q15x2 = (1UL << 16) | 1UL;
54         q31_t in_q7x4 = arm_nn_read_q7x4_ia(&input);
55         q31_t temp_q15x2 = __SXTAB16(__SXTB16(in_q7x4), __ROR((uint32_t)in_q7x4, 8));
56 
57         result = __SMLAD(temp_q15x2, mult_q15x2, result);
58 
59         /* Decrement loop counter */
60         block_count--;
61     }
62 
63     /* Loop unrolling: Compute remaining outputs */
64     block_count = block_size & 0x3;
65 #else
66     block_count = block_size;
67 #endif
68     while (block_count > 0U)
69     {
70         /* Add and store result in destination buffer. */
71         result += *input++;
72 
73         /* Decrement loop counter */
74         block_count--;
75     }
76 
77     *output = result;
78 }
79 
80 /**
81  * @} end of NNBasicMath group
82  */