Smart Remote 3 nRF52 v1.2
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
macros_armv5e.h
1 /***********************************************************************
2 Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3 Copyright (c) 2013 Parrot
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 - Redistributions of source code must retain the above copyright notice,
8 this list of conditions and the following disclaimer.
9 - Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 - Neither the name of Internet Society, IETF or IETF Trust, nor the
13 names of specific contributors, may be used to endorse or promote
14 products derived from this software without specific prior written
15 permission.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 POSSIBILITY OF SUCH DAMAGE.
27 ***********************************************************************/
28 
29 #ifndef SILK_MACROS_ARMv5E_H
30 #define SILK_MACROS_ARMv5E_H
31 
32 /* This macro only avoids the undefined behaviour from a left shift of
33  a negative value. It should only be used in macros that can't include
34  SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */
35 #define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b)))
36 
37 /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
38 #undef silk_SMULWB
39 static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b)
40 {
41  int res;
42 
43 #if defined( __CC_ARM )
44  __asm{ SMULWB res, a, b }
45 #elif defined( __ICCARM__ )
46  __asm(
47  "smulwb %0, %1, %2\n\t"
48  : "=r"(res)
49  : "r"(a), "r"(b)
50  );
51 #else
52  __asm__(
53  "#silk_SMULWB\n\t"
54  "smulwb %0, %1, %2\n\t"
55  : "=r"(res)
56  : "r"(a), "r"(b)
57  );
58 #endif
59 
60  return res;
61 }
62 #define silk_SMULWB(a, b) (silk_SMULWB_armv5e(a, b))
63 
64 /* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */
65 #undef silk_SMLAWB
66 static OPUS_INLINE opus_int32 silk_SMLAWB_armv5e(opus_int32 a, opus_int32 b,
67  opus_int16 c)
68 {
69  int res;
70 
71 #if defined( __CC_ARM )
72  __asm{ SMLAWB res, b, c, a }
73 #elif defined( __ICCARM__ )
74  __asm(
75  "smlawb %0, %1, %2, %3\n\t"
76  : "=r"(res)
77  : "r"(b), "r"(c), "r"(a)
78  );
79 #else
80  __asm__(
81  "#silk_SMLAWB\n\t"
82  "smlawb %0, %1, %2, %3\n\t"
83  : "=r"(res)
84  : "r"(b), "r"(c), "r"(a)
85  );
86 #endif
87 
88  return res;
89 }
90 #define silk_SMLAWB(a, b, c) (silk_SMLAWB_armv5e(a, b, c))
91 
92 /* (a32 * (b32 >> 16)) >> 16 */
93 #undef silk_SMULWT
94 static OPUS_INLINE opus_int32 silk_SMULWT_armv5e(opus_int32 a, opus_int32 b)
95 {
96  int res;
97 
98 #if defined( __CC_ARM )
99  __asm{ SMULWT res, a, b }
100 #elif defined( __ICCARM__ )
101  __asm(
102  "smulwt %0, %1, %2\n\t"
103  : "=r"(res)
104  : "r"(a), "r"(b)
105  );
106 #else
107  __asm__(
108  "#silk_SMULWT\n\t"
109  "smulwt %0, %1, %2\n\t"
110  : "=r"(res)
111  : "r"(a), "r"(b)
112  );
113 #endif
114 
115  return res;
116 }
117 #define silk_SMULWT(a, b) (silk_SMULWT_armv5e(a, b))
118 
119 /* a32 + (b32 * (c32 >> 16)) >> 16 */
120 #undef silk_SMLAWT
121 static OPUS_INLINE opus_int32 silk_SMLAWT_armv5e(opus_int32 a, opus_int32 b,
122  opus_int32 c)
123 {
124  int res;
125 
126 #if defined( __CC_ARM )
127  __asm{ SMLAWT res, b, c, a }
128 #elif defined( __ICCARM__ )
129  __asm(
130  "smlawt %0, %1, %2, %3\n\t"
131  : "=r"(res)
132  : "r"(b), "r"(c), "r"(a)
133  );
134 #else
135  __asm__(
136  "#silk_SMLAWT\n\t"
137  "smlawt %0, %1, %2, %3\n\t"
138  : "=r"(res)
139  : "r"(b), "r"(c), "r"(a)
140  );
141 #endif
142 
143  return res;
144 }
145 #define silk_SMLAWT(a, b, c) (silk_SMLAWT_armv5e(a, b, c))
146 
147 /* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */
148 #undef silk_SMULBB
149 static OPUS_INLINE opus_int32 silk_SMULBB_armv5e(opus_int32 a, opus_int32 b)
150 {
151  int res;
152 
153 #if defined( __CC_ARM )
154  __asm{ SMULBB res, a, b }
155 #elif defined( __ICCARM__ )
156  __asm(
157  "smulbb %0, %1, %2\n\t"
158  : "=r"(res)
159  : "r"(a), "r"(b)
160  );
161 #else
162  __asm__(
163  "#silk_SMULBB\n\t"
164  "smulbb %0, %1, %2\n\t"
165  : "=r"(res)
166  : "%r"(a), "r"(b)
167  );
168 #endif
169 
170  return res;
171 }
172 #define silk_SMULBB(a, b) (silk_SMULBB_armv5e(a, b))
173 
174 /* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */
175 #undef silk_SMLABB
176 static OPUS_INLINE opus_int32 silk_SMLABB_armv5e(opus_int32 a, opus_int32 b,
177  opus_int32 c)
178 {
179  int res;
180 
181 #if defined( __CC_ARM )
182  __asm{ SMLABB res, b, c, a }
183 #elif defined( __ICCARM__ )
184  __asm(
185  "smlabb %0, %1, %2, %3\n\t"
186  : "=r"(res)
187  : "r"(b), "r"(c), "r"(a)
188  );
189 #else
190  __asm__(
191  "#silk_SMLABB\n\t"
192  "smlabb %0, %1, %2, %3\n\t"
193  : "=r"(res)
194  : "%r"(b), "r"(c), "r"(a)
195  );
196 #endif
197 
198  return res;
199 }
200 #define silk_SMLABB(a, b, c) (silk_SMLABB_armv5e(a, b, c))
201 
202 /* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */
203 #undef silk_SMULBT
204 static OPUS_INLINE opus_int32 silk_SMULBT_armv5e(opus_int32 a, opus_int32 b)
205 {
206  int res;
207 #if defined( __CC_ARM )
208  __asm{ SMULBT res, a, b }
209 #elif defined( __ICCARM__ )
210  __asm(
211  "smulbt %0, %1, %2\n\t"
212  : "=r"(res)
213  : "r"(a), "r"(b)
214  );
215 #else
216  __asm__(
217  "#silk_SMULBT\n\t"
218  "smulbt %0, %1, %2\n\t"
219  : "=r"(res)
220  : "r"(a), "r"(b)
221  );
222 #endif
223  return res;
224 }
225 #define silk_SMULBT(a, b) (silk_SMULBT_armv5e(a, b))
226 
227 /* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */
228 #undef silk_SMLABT
229 static OPUS_INLINE opus_int32 silk_SMLABT_armv5e(opus_int32 a, opus_int32 b,
230  opus_int32 c)
231 {
232  int res;
233 #if defined( __CC_ARM )
234  __asm{ SMLABT res, b, c, a }
235 #elif defined( __ICCARM__ )
236  __asm(
237  "smlabt %0, %1, %2, %3\n\t"
238  : "=r"(res)
239  : "r"(b), "r"(c), "r"(a)
240  );
241 #else
242  __asm__(
243  "#silk_SMLABT\n\t"
244  "smlabt %0, %1, %2, %3\n\t"
245  : "=r"(res)
246  : "r"(b), "r"(c), "r"(a)
247  );
248 #endif
249 
250  return res;
251 }
252 #define silk_SMLABT(a, b, c) (silk_SMLABT_armv5e(a, b, c))
253 
254 /* add/subtract with output saturated */
255 #undef silk_ADD_SAT32
256 static OPUS_INLINE opus_int32 silk_ADD_SAT32_armv5e(opus_int32 a, opus_int32 b)
257 {
258  int res;
259 
260 #if defined( __CC_ARM )
261  __asm{ QADD res, a, b }
262 #elif defined( __ICCARM__ )
263  __asm(
264  "qadd %0, %1, %2\n\t"
265  : "=r"(res)
266  : "r"(a), "r"(b)
267  );
268 #else
269  __asm__(
270  "#silk_ADD_SAT32\n\t"
271  "qadd %0, %1, %2\n\t"
272  : "=r"(res)
273  : "%r"(a), "r"(b)
274  );
275 #endif
276 
277  return res;
278 }
279 #define silk_ADD_SAT32(a, b) (silk_ADD_SAT32_armv5e(a, b))
280 
281 #undef silk_SUB_SAT32
282 static OPUS_INLINE opus_int32 silk_SUB_SAT32_armv5e(opus_int32 a, opus_int32 b)
283 {
284  int res;
285 
286 #if defined( __CC_ARM )
287  __asm{ QSUB res, a, b }
288 #elif defined( __ICCARM__ )
289  __asm(
290  "qsub %0, %1, %2\n\t"
291  : "=r"(res)
292  : "r"(a), "r"(b)
293  );
294 #else
295  __asm__(
296  "#silk_SUB_SAT32\n\t"
297  "qsub %0, %1, %2\n\t"
298  : "=r"(res)
299  : "r"(a), "r"(b)
300  );
301 #endif
302 
303  return res;
304 }
305 #define silk_SUB_SAT32(a, b) (silk_SUB_SAT32_armv5e(a, b))
306 
307 #undef silk_CLZ16
308 static OPUS_INLINE opus_int32 silk_CLZ16_armv5(opus_int16 in16)
309 {
310  int res;
311 
312 #if defined( __CC_ARM )
313  __asm{ CLZ res, (SAFE_SHL(in16,16)|0x8000) }
314 #elif defined( __ICCARM__ )
315  __asm(
316  "clz %0, %1;\n"
317  : "=r"(res)
318  : "r"(SAFE_SHL(in16,16)|0x8000)
319  );
320 #else
321  __asm__(
322  "#silk_CLZ16\n\t"
323  "clz %0, %1;\n"
324  : "=r"(res)
325  : "r"(SAFE_SHL(in16,16)|0x8000)
326  );
327 #endif
328 
329  return res;
330 }
331 #define silk_CLZ16(in16) (silk_CLZ16_armv5(in16))
332 
333 #undef silk_CLZ32
334 static OPUS_INLINE opus_int32 silk_CLZ32_armv5(opus_int32 in32)
335 {
336  int res;
337 #if defined( __CC_ARM )
338  __asm{ CLZ res, in32 }
339 #elif defined( __ICCARM__ )
340  __asm(
341  "clz %0, %1\n\t"
342  : "=r"(res)
343  : "r"(in32)
344  );
345 #else
346  __asm__(
347  "#silk_CLZ32\n\t"
348  "clz %0, %1\n\t"
349  : "=r"(res)
350  : "r"(in32)
351  );
352 #endif
353 
354  return res;
355 }
356 #define silk_CLZ32(in32) (silk_CLZ32_armv5(in32))
357 
358 #undef SAFE_SHL
359 
360 #endif /* SILK_MACROS_ARMv5E_H */