Subversion Repositories DashDisplay

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/* ----------------------------------------------------------------------    
2
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.    
3
*    
4
* $Date:        19. March 2015
5
* $Revision:    V.1.4.5
6
*    
7
* Project:          CMSIS DSP Library    
8
* Title:            arm_mat_add_q31.c    
9
*    
10
* Description:  Q31 matrix addition    
11
*    
12
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
13
*  
14
* Redistribution and use in source and binary forms, with or without
15
* modification, are permitted provided that the following conditions
16
* are met:
17
*   - Redistributions of source code must retain the above copyright
18
*     notice, this list of conditions and the following disclaimer.
19
*   - Redistributions in binary form must reproduce the above copyright
20
*     notice, this list of conditions and the following disclaimer in
21
*     the documentation and/or other materials provided with the
22
*     distribution.
23
*   - Neither the name of ARM LIMITED nor the names of its contributors
24
*     may be used to endorse or promote products derived from this
25
*     software without specific prior written permission.
26
*
27
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
* POSSIBILITY OF SUCH DAMAGE.    
39
* -------------------------------------------------------------------- */
40
 
41
#include "arm_math.h"
42
 
43
/**      
44
 * @ingroup groupMatrix      
45
 */
46
 
47
/**      
48
 * @addtogroup MatrixAdd      
49
 * @{      
50
 */
51
 
52
/**      
53
 * @brief Q31 matrix addition.      
54
 * @param[in]       *pSrcA points to the first input matrix structure      
55
 * @param[in]       *pSrcB points to the second input matrix structure      
56
 * @param[out]      *pDst points to output matrix structure      
57
 * @return              The function returns either      
58
 * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.      
59
 *      
60
 * <b>Scaling and Overflow Behavior:</b>      
61
 * \par      
62
 * The function uses saturating arithmetic.      
63
 * Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.      
64
 */
65
 
66
arm_status arm_mat_add_q31(
67
  const arm_matrix_instance_q31 * pSrcA,
68
  const arm_matrix_instance_q31 * pSrcB,
69
  arm_matrix_instance_q31 * pDst)
70
{
71
  q31_t *pIn1 = pSrcA->pData;                    /* input data matrix pointer A */
72
  q31_t *pIn2 = pSrcB->pData;                    /* input data matrix pointer B */
73
  q31_t *pOut = pDst->pData;                     /* output data matrix pointer */
74
  q31_t inA1, inB1;                              /* temporary variables */
75
 
76
#ifndef ARM_MATH_CM0_FAMILY
77
 
78
  q31_t inA2, inB2;                              /* temporary variables */
79
  q31_t out1, out2;                              /* temporary variables */
80
 
81
#endif //      #ifndef ARM_MATH_CM0_FAMILY
82
 
83
  uint32_t numSamples;                           /* total number of elements in the matrix  */
84
  uint32_t blkCnt;                               /* loop counters */
85
  arm_status status;                             /* status of matrix addition */
86
 
87
#ifdef ARM_MATH_MATRIX_CHECK
88
  /* Check for matrix mismatch condition */
89
  if((pSrcA->numRows != pSrcB->numRows) ||
90
     (pSrcA->numCols != pSrcB->numCols) ||
91
     (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
92
  {
93
    /* Set status as ARM_MATH_SIZE_MISMATCH */
94
    status = ARM_MATH_SIZE_MISMATCH;
95
  }
96
  else
97
#endif
98
  {
99
    /* Total number of samples in the input matrix */
100
    numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
101
 
102
#ifndef ARM_MATH_CM0_FAMILY
103
 
104
    /* Run the below code for Cortex-M4 and Cortex-M3 */
105
 
106
    /* Loop Unrolling */
107
    blkCnt = numSamples >> 2u;
108
 
109
 
110
    /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.    
111
     ** a second loop below computes the remaining 1 to 3 samples. */
112
    while(blkCnt > 0u)
113
    {
114
      /* C(m,n) = A(m,n) + B(m,n) */
115
      /* Add, saturate and then store the results in the destination buffer. */
116
      /* Read values from source A */
117
      inA1 = pIn1[0];
118
 
119
      /* Read values from source B */
120
      inB1 = pIn2[0];
121
 
122
      /* Read values from source A */
123
      inA2 = pIn1[1];
124
 
125
      /* Add and saturate */
126
      out1 = __QADD(inA1, inB1);
127
 
128
      /* Read values from source B */
129
      inB2 = pIn2[1];
130
 
131
      /* Read values from source A */
132
      inA1 = pIn1[2];
133
 
134
      /* Add and saturate */
135
      out2 = __QADD(inA2, inB2);
136
 
137
      /* Read values from source B */
138
      inB1 = pIn2[2];
139
 
140
      /* Store result in destination */
141
      pOut[0] = out1;
142
      pOut[1] = out2;
143
 
144
      /* Read values from source A */
145
      inA2 = pIn1[3];
146
 
147
      /* Read values from source B */
148
      inB2 = pIn2[3];
149
 
150
      /* Add and saturate */
151
      out1 = __QADD(inA1, inB1);
152
      out2 = __QADD(inA2, inB2);
153
 
154
      /* Store result in destination */
155
      pOut[2] = out1;
156
      pOut[3] = out2;
157
 
158
      /* update pointers to process next sampels */
159
      pIn1 += 4u;
160
      pIn2 += 4u;
161
      pOut += 4u;
162
 
163
      /* Decrement the loop counter */
164
      blkCnt--;
165
    }
166
 
167
    /* If the numSamples is not a multiple of 4, compute any remaining output samples here.      
168
     ** No loop unrolling is used. */
169
    blkCnt = numSamples % 0x4u;
170
 
171
#else
172
 
173
    /* Run the below code for Cortex-M0 */
174
 
175
    /* Initialize blkCnt with number of samples */
176
    blkCnt = numSamples;
177
 
178
 
179
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
180
 
181
    while(blkCnt > 0u)
182
    {
183
      /* C(m,n) = A(m,n) + B(m,n) */
184
      /* Add, saturate and then store the results in the destination buffer. */
185
      inA1 = *pIn1++;
186
      inB1 = *pIn2++;
187
 
188
      inA1 = __QADD(inA1, inB1);
189
 
190
      /* Decrement the loop counter */
191
      blkCnt--;
192
 
193
      *pOut++ = inA1;
194
 
195
    }
196
 
197
    /* set status as ARM_MATH_SUCCESS */
198
    status = ARM_MATH_SUCCESS;
199
  }
200
 
201
  /* Return to application */
202
  return (status);
203
}
204
 
205
/**      
206
 * @} end of MatrixAdd group      
207
 */