2
|
1 /**************************************************************************//**
|
|
2 * @file cmsis_armcc_V6.h
|
|
3 * @brief CMSIS Cortex-M Core Function/Instruction Header File
|
|
4 * @version V4.30
|
|
5 * @date 20. October 2015
|
|
6 ******************************************************************************/
|
|
7 /* Copyright (c) 2009 - 2015 ARM LIMITED
|
|
8
|
|
9 All rights reserved.
|
|
10 Redistribution and use in source and binary forms, with or without
|
|
11 modification, are permitted provided that the following conditions are met:
|
|
12 - Redistributions of source code must retain the above copyright
|
|
13 notice, this list of conditions and the following disclaimer.
|
|
14 - Redistributions in binary form must reproduce the above copyright
|
|
15 notice, this list of conditions and the following disclaimer in the
|
|
16 documentation and/or other materials provided with the distribution.
|
|
17 - Neither the name of ARM nor the names of its contributors may be used
|
|
18 to endorse or promote products derived from this software without
|
|
19 specific prior written permission.
|
|
20 *
|
|
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
24 ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
|
25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
27 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
29 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
30 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
31 POSSIBILITY OF SUCH DAMAGE.
|
|
32 ---------------------------------------------------------------------------*/
|
|
33
|
|
34
|
|
35 #ifndef __CMSIS_ARMCC_V6_H
|
|
36 #define __CMSIS_ARMCC_V6_H
|
|
37
|
|
38
|
|
39 /* ########################### Core Function Access ########################### */
|
|
40 /** \ingroup CMSIS_Core_FunctionInterface
|
|
41 \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
|
42 @{
|
|
43 */
|
|
44
|
|
45 /**
|
|
46 \brief Enable IRQ Interrupts
|
|
47 \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
|
|
48 Can only be executed in Privileged modes.
|
|
49 */
|
|
50 __attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void)
|
|
51 {
|
|
52 __ASM volatile ("cpsie i" : : : "memory");
|
|
53 }
|
|
54
|
|
55
|
|
56 /**
|
|
57 \brief Disable IRQ Interrupts
|
|
58 \details Disables IRQ interrupts by setting the I-bit in the CPSR.
|
|
59 Can only be executed in Privileged modes.
|
|
60 */
|
|
61 __attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void)
|
|
62 {
|
|
63 __ASM volatile ("cpsid i" : : : "memory");
|
|
64 }
|
|
65
|
|
66
|
|
67 /**
|
|
68 \brief Get Control Register
|
|
69 \details Returns the content of the Control Register.
|
|
70 \return Control Register value
|
|
71 */
|
|
72 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void)
|
|
73 {
|
|
74 uint32_t result;
|
|
75
|
|
76 __ASM volatile ("MRS %0, control" : "=r" (result) );
|
|
77 return(result);
|
|
78 }
|
|
79
|
|
80
|
|
81 #if (__ARM_FEATURE_CMSE == 3U)
|
|
82 /**
|
|
83 \brief Get Control Register (non-secure)
|
|
84 \details Returns the content of the non-secure Control Register when in secure mode.
|
|
85 \return non-secure Control Register value
|
|
86 */
|
|
87 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void)
|
|
88 {
|
|
89 uint32_t result;
|
|
90
|
|
91 __ASM volatile ("MRS %0, control_ns" : "=r" (result) );
|
|
92 return(result);
|
|
93 }
|
|
94 #endif
|
|
95
|
|
96
|
|
97 /**
|
|
98 \brief Set Control Register
|
|
99 \details Writes the given value to the Control Register.
|
|
100 \param [in] control Control Register value to set
|
|
101 */
|
|
102 __attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control)
|
|
103 {
|
|
104 __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
|
|
105 }
|
|
106
|
|
107
|
|
108 #if (__ARM_FEATURE_CMSE == 3U)
|
|
109 /**
|
|
110 \brief Set Control Register (non-secure)
|
|
111 \details Writes the given value to the non-secure Control Register when in secure state.
|
|
112 \param [in] control Control Register value to set
|
|
113 */
|
|
114 __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control)
|
|
115 {
|
|
116 __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory");
|
|
117 }
|
|
118 #endif
|
|
119
|
|
120
|
|
121 /**
|
|
122 \brief Get IPSR Register
|
|
123 \details Returns the content of the IPSR Register.
|
|
124 \return IPSR Register value
|
|
125 */
|
|
126 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void)
|
|
127 {
|
|
128 uint32_t result;
|
|
129
|
|
130 __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
|
|
131 return(result);
|
|
132 }
|
|
133
|
|
134
|
|
135 #if (__ARM_FEATURE_CMSE == 3U)
|
|
136 /**
|
|
137 \brief Get IPSR Register (non-secure)
|
|
138 \details Returns the content of the non-secure IPSR Register when in secure state.
|
|
139 \return IPSR Register value
|
|
140 */
|
|
141 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_IPSR_NS(void)
|
|
142 {
|
|
143 uint32_t result;
|
|
144
|
|
145 __ASM volatile ("MRS %0, ipsr_ns" : "=r" (result) );
|
|
146 return(result);
|
|
147 }
|
|
148 #endif
|
|
149
|
|
150
|
|
151 /**
|
|
152 \brief Get APSR Register
|
|
153 \details Returns the content of the APSR Register.
|
|
154 \return APSR Register value
|
|
155 */
|
|
156 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void)
|
|
157 {
|
|
158 uint32_t result;
|
|
159
|
|
160 __ASM volatile ("MRS %0, apsr" : "=r" (result) );
|
|
161 return(result);
|
|
162 }
|
|
163
|
|
164
|
|
165 #if (__ARM_FEATURE_CMSE == 3U)
|
|
166 /**
|
|
167 \brief Get APSR Register (non-secure)
|
|
168 \details Returns the content of the non-secure APSR Register when in secure state.
|
|
169 \return APSR Register value
|
|
170 */
|
|
171 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_APSR_NS(void)
|
|
172 {
|
|
173 uint32_t result;
|
|
174
|
|
175 __ASM volatile ("MRS %0, apsr_ns" : "=r" (result) );
|
|
176 return(result);
|
|
177 }
|
|
178 #endif
|
|
179
|
|
180
|
|
181 /**
|
|
182 \brief Get xPSR Register
|
|
183 \details Returns the content of the xPSR Register.
|
|
184 \return xPSR Register value
|
|
185 */
|
|
186 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void)
|
|
187 {
|
|
188 uint32_t result;
|
|
189
|
|
190 __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
|
|
191 return(result);
|
|
192 }
|
|
193
|
|
194
|
|
195 #if (__ARM_FEATURE_CMSE == 3U)
|
|
196 /**
|
|
197 \brief Get xPSR Register (non-secure)
|
|
198 \details Returns the content of the non-secure xPSR Register when in secure state.
|
|
199 \return xPSR Register value
|
|
200 */
|
|
201 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_xPSR_NS(void)
|
|
202 {
|
|
203 uint32_t result;
|
|
204
|
|
205 __ASM volatile ("MRS %0, xpsr_ns" : "=r" (result) );
|
|
206 return(result);
|
|
207 }
|
|
208 #endif
|
|
209
|
|
210
|
|
211 /**
|
|
212 \brief Get Process Stack Pointer
|
|
213 \details Returns the current value of the Process Stack Pointer (PSP).
|
|
214 \return PSP Register value
|
|
215 */
|
|
216 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void)
|
|
217 {
|
|
218 register uint32_t result;
|
|
219
|
|
220 __ASM volatile ("MRS %0, psp" : "=r" (result) );
|
|
221 return(result);
|
|
222 }
|
|
223
|
|
224
|
|
225 #if (__ARM_FEATURE_CMSE == 3U)
|
|
226 /**
|
|
227 \brief Get Process Stack Pointer (non-secure)
|
|
228 \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
|
|
229 \return PSP Register value
|
|
230 */
|
|
231 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void)
|
|
232 {
|
|
233 register uint32_t result;
|
|
234
|
|
235 __ASM volatile ("MRS %0, psp_ns" : "=r" (result) );
|
|
236 return(result);
|
|
237 }
|
|
238 #endif
|
|
239
|
|
240
|
|
241 /**
|
|
242 \brief Set Process Stack Pointer
|
|
243 \details Assigns the given value to the Process Stack Pointer (PSP).
|
|
244 \param [in] topOfProcStack Process Stack Pointer value to set
|
|
245 */
|
|
246 __attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
|
247 {
|
|
248 __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : "sp");
|
|
249 }
|
|
250
|
|
251
|
|
252 #if (__ARM_FEATURE_CMSE == 3U)
|
|
253 /**
|
|
254 \brief Set Process Stack Pointer (non-secure)
|
|
255 \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
|
|
256 \param [in] topOfProcStack Process Stack Pointer value to set
|
|
257 */
|
|
258 __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
|
|
259 {
|
|
260 __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : "sp");
|
|
261 }
|
|
262 #endif
|
|
263
|
|
264
|
|
265 /**
|
|
266 \brief Get Main Stack Pointer
|
|
267 \details Returns the current value of the Main Stack Pointer (MSP).
|
|
268 \return MSP Register value
|
|
269 */
|
|
270 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void)
|
|
271 {
|
|
272 register uint32_t result;
|
|
273
|
|
274 __ASM volatile ("MRS %0, msp" : "=r" (result) );
|
|
275 return(result);
|
|
276 }
|
|
277
|
|
278
|
|
279 #if (__ARM_FEATURE_CMSE == 3U)
|
|
280 /**
|
|
281 \brief Get Main Stack Pointer (non-secure)
|
|
282 \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
|
|
283 \return MSP Register value
|
|
284 */
|
|
285 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void)
|
|
286 {
|
|
287 register uint32_t result;
|
|
288
|
|
289 __ASM volatile ("MRS %0, msp_ns" : "=r" (result) );
|
|
290 return(result);
|
|
291 }
|
|
292 #endif
|
|
293
|
|
294
|
|
295 /**
|
|
296 \brief Set Main Stack Pointer
|
|
297 \details Assigns the given value to the Main Stack Pointer (MSP).
|
|
298 \param [in] topOfMainStack Main Stack Pointer value to set
|
|
299 */
|
|
300 __attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
|
301 {
|
|
302 __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : "sp");
|
|
303 }
|
|
304
|
|
305
|
|
306 #if (__ARM_FEATURE_CMSE == 3U)
|
|
307 /**
|
|
308 \brief Set Main Stack Pointer (non-secure)
|
|
309 \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
|
|
310 \param [in] topOfMainStack Main Stack Pointer value to set
|
|
311 */
|
|
312 __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
|
|
313 {
|
|
314 __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : "sp");
|
|
315 }
|
|
316 #endif
|
|
317
|
|
318
|
|
319 /**
|
|
320 \brief Get Priority Mask
|
|
321 \details Returns the current state of the priority mask bit from the Priority Mask Register.
|
|
322 \return Priority Mask value
|
|
323 */
|
|
324 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void)
|
|
325 {
|
|
326 uint32_t result;
|
|
327
|
|
328 __ASM volatile ("MRS %0, primask" : "=r" (result) );
|
|
329 return(result);
|
|
330 }
|
|
331
|
|
332
|
|
333 #if (__ARM_FEATURE_CMSE == 3U)
|
|
334 /**
|
|
335 \brief Get Priority Mask (non-secure)
|
|
336 \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
|
|
337 \return Priority Mask value
|
|
338 */
|
|
339 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void)
|
|
340 {
|
|
341 uint32_t result;
|
|
342
|
|
343 __ASM volatile ("MRS %0, primask_ns" : "=r" (result) );
|
|
344 return(result);
|
|
345 }
|
|
346 #endif
|
|
347
|
|
348
|
|
349 /**
|
|
350 \brief Set Priority Mask
|
|
351 \details Assigns the given value to the Priority Mask Register.
|
|
352 \param [in] priMask Priority Mask
|
|
353 */
|
|
354 __attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
|
355 {
|
|
356 __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
|
|
357 }
|
|
358
|
|
359
|
|
360 #if (__ARM_FEATURE_CMSE == 3U)
|
|
361 /**
|
|
362 \brief Set Priority Mask (non-secure)
|
|
363 \details Assigns the given value to the non-secure Priority Mask Register when in secure state.
|
|
364 \param [in] priMask Priority Mask
|
|
365 */
|
|
366 __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
|
|
367 {
|
|
368 __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory");
|
|
369 }
|
|
370 #endif
|
|
371
|
|
372
|
|
373 #if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */
|
|
374
|
|
375 /**
|
|
376 \brief Enable FIQ
|
|
377 \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
|
|
378 Can only be executed in Privileged modes.
|
|
379 */
|
|
380 __attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void)
|
|
381 {
|
|
382 __ASM volatile ("cpsie f" : : : "memory");
|
|
383 }
|
|
384
|
|
385
|
|
386 /**
|
|
387 \brief Disable FIQ
|
|
388 \details Disables FIQ interrupts by setting the F-bit in the CPSR.
|
|
389 Can only be executed in Privileged modes.
|
|
390 */
|
|
391 __attribute__((always_inline)) __STATIC_INLINE void __disable_fault_irq(void)
|
|
392 {
|
|
393 __ASM volatile ("cpsid f" : : : "memory");
|
|
394 }
|
|
395
|
|
396
|
|
397 /**
|
|
398 \brief Get Base Priority
|
|
399 \details Returns the current value of the Base Priority register.
|
|
400 \return Base Priority register value
|
|
401 */
|
|
402 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void)
|
|
403 {
|
|
404 uint32_t result;
|
|
405
|
|
406 __ASM volatile ("MRS %0, basepri" : "=r" (result) );
|
|
407 return(result);
|
|
408 }
|
|
409
|
|
410
|
|
411 #if (__ARM_FEATURE_CMSE == 3U)
|
|
412 /**
|
|
413 \brief Get Base Priority (non-secure)
|
|
414 \details Returns the current value of the non-secure Base Priority register when in secure state.
|
|
415 \return Base Priority register value
|
|
416 */
|
|
417 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void)
|
|
418 {
|
|
419 uint32_t result;
|
|
420
|
|
421 __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) );
|
|
422 return(result);
|
|
423 }
|
|
424 #endif
|
|
425
|
|
426
|
|
427 /**
|
|
428 \brief Set Base Priority
|
|
429 \details Assigns the given value to the Base Priority register.
|
|
430 \param [in] basePri Base Priority value to set
|
|
431 */
|
|
432 __attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
|
|
433 {
|
|
434 __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
|
|
435 }
|
|
436
|
|
437
|
|
438 #if (__ARM_FEATURE_CMSE == 3U)
|
|
439 /**
|
|
440 \brief Set Base Priority (non-secure)
|
|
441 \details Assigns the given value to the non-secure Base Priority register when in secure state.
|
|
442 \param [in] basePri Base Priority value to set
|
|
443 */
|
|
444 __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t value)
|
|
445 {
|
|
446 __ASM volatile ("MSR basepri_ns, %0" : : "r" (value) : "memory");
|
|
447 }
|
|
448 #endif
|
|
449
|
|
450
|
|
451 /**
|
|
452 \brief Set Base Priority with condition
|
|
453 \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
|
454 or the new value increases the BASEPRI priority level.
|
|
455 \param [in] basePri Base Priority value to set
|
|
456 */
|
|
457 __attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
|
|
458 {
|
|
459 __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
|
|
460 }
|
|
461
|
|
462
|
|
463 #if (__ARM_FEATURE_CMSE == 3U)
|
|
464 /**
|
|
465 \brief Set Base Priority with condition (non_secure)
|
|
466 \details Assigns the given value to the non-secure Base Priority register when in secure state only if BASEPRI masking is disabled,
|
|
467 or the new value increases the BASEPRI priority level.
|
|
468 \param [in] basePri Base Priority value to set
|
|
469 */
|
|
470 __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_MAX_NS(uint32_t value)
|
|
471 {
|
|
472 __ASM volatile ("MSR basepri_max_ns, %0" : : "r" (value) : "memory");
|
|
473 }
|
|
474 #endif
|
|
475
|
|
476
|
|
477 /**
|
|
478 \brief Get Fault Mask
|
|
479 \details Returns the current value of the Fault Mask register.
|
|
480 \return Fault Mask register value
|
|
481 */
|
|
482 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
|
483 {
|
|
484 uint32_t result;
|
|
485
|
|
486 __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
|
487 return(result);
|
|
488 }
|
|
489
|
|
490
|
|
491 #if (__ARM_FEATURE_CMSE == 3U)
|
|
492 /**
|
|
493 \brief Get Fault Mask (non-secure)
|
|
494 \details Returns the current value of the non-secure Fault Mask register when in secure state.
|
|
495 \return Fault Mask register value
|
|
496 */
|
|
497 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void)
|
|
498 {
|
|
499 uint32_t result;
|
|
500
|
|
501 __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) );
|
|
502 return(result);
|
|
503 }
|
|
504 #endif
|
|
505
|
|
506
|
|
507 /**
|
|
508 \brief Set Fault Mask
|
|
509 \details Assigns the given value to the Fault Mask register.
|
|
510 \param [in] faultMask Fault Mask value to set
|
|
511 */
|
|
512 __attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
|
513 {
|
|
514 __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
|
|
515 }
|
|
516
|
|
517
|
|
518 #if (__ARM_FEATURE_CMSE == 3U)
|
|
519 /**
|
|
520 \brief Set Fault Mask (non-secure)
|
|
521 \details Assigns the given value to the non-secure Fault Mask register when in secure state.
|
|
522 \param [in] faultMask Fault Mask value to set
|
|
523 */
|
|
524 __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
|
|
525 {
|
|
526 __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory");
|
|
527 }
|
|
528 #endif
|
|
529
|
|
530
|
|
531 #endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
|
|
532
|
|
533
|
|
534 #if (__ARM_ARCH_8M__ == 1U)
|
|
535
|
|
536 /**
|
|
537 \brief Get Process Stack Pointer Limit
|
|
538 \details Returns the current value of the Process Stack Pointer Limit (PSPLIM).
|
|
539 \return PSPLIM Register value
|
|
540 */
|
|
541 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void)
|
|
542 {
|
|
543 register uint32_t result;
|
|
544
|
|
545 __ASM volatile ("MRS %0, psplim" : "=r" (result) );
|
|
546 return(result);
|
|
547 }
|
|
548
|
|
549
|
|
550 #if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
|
|
551 /**
|
|
552 \brief Get Process Stack Pointer Limit (non-secure)
|
|
553 \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
|
|
554 \return PSPLIM Register value
|
|
555 */
|
|
556 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void)
|
|
557 {
|
|
558 register uint32_t result;
|
|
559
|
|
560 __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) );
|
|
561 return(result);
|
|
562 }
|
|
563 #endif
|
|
564
|
|
565
|
|
566 /**
|
|
567 \brief Set Process Stack Pointer Limit
|
|
568 \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
|
|
569 \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
|
|
570 */
|
|
571 __attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
|
|
572 {
|
|
573 __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit));
|
|
574 }
|
|
575
|
|
576
|
|
577 #if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
|
|
578 /**
|
|
579 \brief Set Process Stack Pointer (non-secure)
|
|
580 \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
|
|
581 \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
|
|
582 */
|
|
583 __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
|
|
584 {
|
|
585 __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit));
|
|
586 }
|
|
587 #endif
|
|
588
|
|
589
|
|
590 /**
|
|
591 \brief Get Main Stack Pointer Limit
|
|
592 \details Returns the current value of the Main Stack Pointer Limit (MSPLIM).
|
|
593 \return MSPLIM Register value
|
|
594 */
|
|
595 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void)
|
|
596 {
|
|
597 register uint32_t result;
|
|
598
|
|
599 __ASM volatile ("MRS %0, msplim" : "=r" (result) );
|
|
600
|
|
601 return(result);
|
|
602 }
|
|
603
|
|
604
|
|
605 #if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
|
|
606 /**
|
|
607 \brief Get Main Stack Pointer Limit (non-secure)
|
|
608 \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
|
|
609 \return MSPLIM Register value
|
|
610 */
|
|
611 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void)
|
|
612 {
|
|
613 register uint32_t result;
|
|
614
|
|
615 __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) );
|
|
616 return(result);
|
|
617 }
|
|
618 #endif
|
|
619
|
|
620
|
|
621 /**
|
|
622 \brief Set Main Stack Pointer Limit
|
|
623 \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
|
|
624 \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set
|
|
625 */
|
|
626 __attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
|
|
627 {
|
|
628 __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit));
|
|
629 }
|
|
630
|
|
631
|
|
632 #if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
|
|
633 /**
|
|
634 \brief Set Main Stack Pointer Limit (non-secure)
|
|
635 \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
|
|
636 \param [in] MainStackPtrLimit Main Stack Pointer value to set
|
|
637 */
|
|
638 __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
|
|
639 {
|
|
640 __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit));
|
|
641 }
|
|
642 #endif
|
|
643
|
|
644 #endif /* (__ARM_ARCH_8M__ == 1U) */
|
|
645
|
|
646
|
|
647 #if ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=4 */
|
|
648
|
|
649 /**
|
|
650 \brief Get FPSCR
|
|
651 \details eturns the current value of the Floating Point Status/Control register.
|
|
652 \return Floating Point Status/Control register value
|
|
653 */
|
|
654 #define __get_FPSCR __builtin_arm_get_fpscr
|
|
655 #if 0
|
|
656 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void)
|
|
657 {
|
|
658 #if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
|
|
659 uint32_t result;
|
|
660
|
|
661 __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
|
|
662 __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
|
663 __ASM volatile ("");
|
|
664 return(result);
|
|
665 #else
|
|
666 return(0);
|
|
667 #endif
|
|
668 }
|
|
669 #endif
|
|
670
|
|
671 #if (__ARM_FEATURE_CMSE == 3U)
|
|
672 /**
|
|
673 \brief Get FPSCR (non-secure)
|
|
674 \details Returns the current value of the non-secure Floating Point Status/Control register when in secure state.
|
|
675 \return Floating Point Status/Control register value
|
|
676 */
|
|
677 __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FPSCR_NS(void)
|
|
678 {
|
|
679 #if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
|
|
680 uint32_t result;
|
|
681
|
|
682 __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
|
|
683 __ASM volatile ("VMRS %0, fpscr_ns" : "=r" (result) );
|
|
684 __ASM volatile ("");
|
|
685 return(result);
|
|
686 #else
|
|
687 return(0);
|
|
688 #endif
|
|
689 }
|
|
690 #endif
|
|
691
|
|
692
|
|
693 /**
|
|
694 \brief Set FPSCR
|
|
695 \details Assigns the given value to the Floating Point Status/Control register.
|
|
696 \param [in] fpscr Floating Point Status/Control value to set
|
|
697 */
|
|
698 #define __set_FPSCR __builtin_arm_set_fpscr
|
|
699 #if 0
|
|
700 __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
|
701 {
|
|
702 #if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
|
|
703 __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
|
|
704 __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
|
|
705 __ASM volatile ("");
|
|
706 #endif
|
|
707 }
|
|
708 #endif
|
|
709
|
|
710 #if (__ARM_FEATURE_CMSE == 3U)
|
|
711 /**
|
|
712 \brief Set FPSCR (non-secure)
|
|
713 \details Assigns the given value to the non-secure Floating Point Status/Control register when in secure state.
|
|
714 \param [in] fpscr Floating Point Status/Control value to set
|
|
715 */
|
|
716 __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FPSCR_NS(uint32_t fpscr)
|
|
717 {
|
|
718 #if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
|
|
719 __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
|
|
720 __ASM volatile ("VMSR fpscr_ns, %0" : : "r" (fpscr) : "vfpcc");
|
|
721 __ASM volatile ("");
|
|
722 #endif
|
|
723 }
|
|
724 #endif
|
|
725
|
|
726 #endif /* ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
|
|
727
|
|
728
|
|
729
|
|
730 /*@} end of CMSIS_Core_RegAccFunctions */
|
|
731
|
|
732
|
|
733 /* ########################## Core Instruction Access ######################### */
|
|
734 /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
|
735 Access to dedicated instructions
|
|
736 @{
|
|
737 */
|
|
738
|
|
739 /* Define macros for porting to both thumb1 and thumb2.
|
|
740 * For thumb1, use low register (r0-r7), specified by constraint "l"
|
|
741 * Otherwise, use general registers, specified by constraint "r" */
|
|
742 #if defined (__thumb__) && !defined (__thumb2__)
|
|
743 #define __CMSIS_GCC_OUT_REG(r) "=l" (r)
|
|
744 #define __CMSIS_GCC_USE_REG(r) "l" (r)
|
|
745 #else
|
|
746 #define __CMSIS_GCC_OUT_REG(r) "=r" (r)
|
|
747 #define __CMSIS_GCC_USE_REG(r) "r" (r)
|
|
748 #endif
|
|
749
|
|
750 /**
|
|
751 \brief No Operation
|
|
752 \details No Operation does nothing. This instruction can be used for code alignment purposes.
|
|
753 */
|
|
754 #define __NOP __builtin_arm_nop
|
|
755
|
|
756 /**
|
|
757 \brief Wait For Interrupt
|
|
758 \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
|
|
759 */
|
|
760 #define __WFI __builtin_arm_wfi
|
|
761
|
|
762
|
|
763 /**
|
|
764 \brief Wait For Event
|
|
765 \details Wait For Event is a hint instruction that permits the processor to enter
|
|
766 a low-power state until one of a number of events occurs.
|
|
767 */
|
|
768 #define __WFE __builtin_arm_wfe
|
|
769
|
|
770
|
|
771 /**
|
|
772 \brief Send Event
|
|
773 \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
|
774 */
|
|
775 #define __SEV __builtin_arm_sev
|
|
776
|
|
777
|
|
778 /**
|
|
779 \brief Instruction Synchronization Barrier
|
|
780 \details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
|
781 so that all instructions following the ISB are fetched from cache or memory,
|
|
782 after the instruction has been completed.
|
|
783 */
|
|
784 #define __ISB() __builtin_arm_isb(0xF);
|
|
785
|
|
786 /**
|
|
787 \brief Data Synchronization Barrier
|
|
788 \details Acts as a special kind of Data Memory Barrier.
|
|
789 It completes when all explicit memory accesses before this instruction complete.
|
|
790 */
|
|
791 #define __DSB() __builtin_arm_dsb(0xF);
|
|
792
|
|
793
|
|
794 /**
|
|
795 \brief Data Memory Barrier
|
|
796 \details Ensures the apparent order of the explicit memory operations before
|
|
797 and after the instruction, without ensuring their completion.
|
|
798 */
|
|
799 #define __DMB() __builtin_arm_dmb(0xF);
|
|
800
|
|
801
|
|
802 /**
|
|
803 \brief Reverse byte order (32 bit)
|
|
804 \details Reverses the byte order in integer value.
|
|
805 \param [in] value Value to reverse
|
|
806 \return Reversed value
|
|
807 */
|
|
808 #define __REV __builtin_bswap32
|
|
809
|
|
810
|
|
811 /**
|
|
812 \brief Reverse byte order (16 bit)
|
|
813 \details Reverses the byte order in two unsigned short values.
|
|
814 \param [in] value Value to reverse
|
|
815 \return Reversed value
|
|
816 */
|
|
817 #define __REV16 __builtin_bswap16 /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */
|
|
818 #if 0
|
|
819 __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
|
820 {
|
|
821 uint32_t result;
|
|
822
|
|
823 __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
|
824 return(result);
|
|
825 }
|
|
826 #endif
|
|
827
|
|
828
|
|
829 /**
|
|
830 \brief Reverse byte order in signed short value
|
|
831 \details Reverses the byte order in a signed short value with sign extension to integer.
|
|
832 \param [in] value Value to reverse
|
|
833 \return Reversed value
|
|
834 */
|
|
835 /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */
|
|
836 __attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
|
837 {
|
|
838 int32_t result;
|
|
839
|
|
840 __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
|
841 return(result);
|
|
842 }
|
|
843
|
|
844
|
|
845 /**
|
|
846 \brief Rotate Right in unsigned value (32 bit)
|
|
847 \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
|
848 \param [in] op1 Value to rotate
|
|
849 \param [in] op2 Number of Bits to rotate
|
|
850 \return Rotated value
|
|
851 */
|
|
852 __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
|
853 {
|
|
854 return (op1 >> op2) | (op1 << (32U - op2));
|
|
855 }
|
|
856
|
|
857
|
|
858 /**
|
|
859 \brief Breakpoint
|
|
860 \details Causes the processor to enter Debug state.
|
|
861 Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
|
862 \param [in] value is ignored by the processor.
|
|
863 If required, a debugger can use it to store additional information about the breakpoint.
|
|
864 */
|
|
865 #define __BKPT(value) __ASM volatile ("bkpt "#value)
|
|
866
|
|
867
|
|
868 /**
|
|
869 \brief Reverse bit order of value
|
|
870 \details Reverses the bit order of the given value.
|
|
871 \param [in] value Value to reverse
|
|
872 \return Reversed value
|
|
873 */
|
|
874 /* ToDo: ARMCC_V6: check if __builtin_arm_rbit is supported */
|
|
875 __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
|
876 {
|
|
877 uint32_t result;
|
|
878
|
|
879 #if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */
|
|
880 __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
|
881 #else
|
|
882 int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
|
|
883
|
|
884 result = value; /* r will be reversed bits of v; first get LSB of v */
|
|
885 for (value >>= 1U; value; value >>= 1U)
|
|
886 {
|
|
887 result <<= 1U;
|
|
888 result |= value & 1U;
|
|
889 s--;
|
|
890 }
|
|
891 result <<= s; /* shift when v's highest bits are zero */
|
|
892 #endif
|
|
893 return(result);
|
|
894 }
|
|
895
|
|
896
|
|
897 /**
|
|
898 \brief Count leading zeros
|
|
899 \details Counts the number of leading zeros of a data value.
|
|
900 \param [in] value Value to count the leading zeros
|
|
901 \return number of leading zeros in value
|
|
902 */
|
|
903 #define __CLZ __builtin_clz
|
|
904
|
|
905
|
|
906 #if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */
|
|
907
|
|
908 /**
|
|
909 \brief LDR Exclusive (8 bit)
|
|
910 \details Executes a exclusive LDR instruction for 8 bit value.
|
|
911 \param [in] ptr Pointer to data
|
|
912 \return value of type uint8_t at (*ptr)
|
|
913 */
|
|
914 #define __LDREXB (uint8_t)__builtin_arm_ldrex
|
|
915
|
|
916
|
|
917 /**
|
|
918 \brief LDR Exclusive (16 bit)
|
|
919 \details Executes a exclusive LDR instruction for 16 bit values.
|
|
920 \param [in] ptr Pointer to data
|
|
921 \return value of type uint16_t at (*ptr)
|
|
922 */
|
|
923 #define __LDREXH (uint16_t)__builtin_arm_ldrex
|
|
924
|
|
925
|
|
926 /**
|
|
927 \brief LDR Exclusive (32 bit)
|
|
928 \details Executes a exclusive LDR instruction for 32 bit values.
|
|
929 \param [in] ptr Pointer to data
|
|
930 \return value of type uint32_t at (*ptr)
|
|
931 */
|
|
932 #define __LDREXW (uint32_t)__builtin_arm_ldrex
|
|
933
|
|
934
|
|
935 /**
|
|
936 \brief STR Exclusive (8 bit)
|
|
937 \details Executes a exclusive STR instruction for 8 bit values.
|
|
938 \param [in] value Value to store
|
|
939 \param [in] ptr Pointer to location
|
|
940 \return 0 Function succeeded
|
|
941 \return 1 Function failed
|
|
942 */
|
|
943 #define __STREXB (uint32_t)__builtin_arm_strex
|
|
944
|
|
945
|
|
946 /**
|
|
947 \brief STR Exclusive (16 bit)
|
|
948 \details Executes a exclusive STR instruction for 16 bit values.
|
|
949 \param [in] value Value to store
|
|
950 \param [in] ptr Pointer to location
|
|
951 \return 0 Function succeeded
|
|
952 \return 1 Function failed
|
|
953 */
|
|
954 #define __STREXH (uint32_t)__builtin_arm_strex
|
|
955
|
|
956
|
|
957 /**
|
|
958 \brief STR Exclusive (32 bit)
|
|
959 \details Executes a exclusive STR instruction for 32 bit values.
|
|
960 \param [in] value Value to store
|
|
961 \param [in] ptr Pointer to location
|
|
962 \return 0 Function succeeded
|
|
963 \return 1 Function failed
|
|
964 */
|
|
965 #define __STREXW (uint32_t)__builtin_arm_strex
|
|
966
|
|
967
|
|
968 /**
|
|
969 \brief Remove the exclusive lock
|
|
970 \details Removes the exclusive lock which is created by LDREX.
|
|
971 */
|
|
972 #define __CLREX __builtin_arm_clrex
|
|
973
|
|
974
|
|
975 /**
|
|
976 \brief Signed Saturate
|
|
977 \details Saturates a signed value.
|
|
978 \param [in] value Value to be saturated
|
|
979 \param [in] sat Bit position to saturate to (1..32)
|
|
980 \return Saturated value
|
|
981 */
|
|
982 /*#define __SSAT __builtin_arm_ssat*/
|
|
983 #define __SSAT(ARG1,ARG2) \
|
|
984 ({ \
|
|
985 int32_t __RES, __ARG1 = (ARG1); \
|
|
986 __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
|
987 __RES; \
|
|
988 })
|
|
989
|
|
990
|
|
991 /**
|
|
992 \brief Unsigned Saturate
|
|
993 \details Saturates an unsigned value.
|
|
994 \param [in] value Value to be saturated
|
|
995 \param [in] sat Bit position to saturate to (0..31)
|
|
996 \return Saturated value
|
|
997 */
|
|
998 #define __USAT __builtin_arm_usat
|
|
999 #if 0
|
|
1000 #define __USAT(ARG1,ARG2) \
|
|
1001 ({ \
|
|
1002 uint32_t __RES, __ARG1 = (ARG1); \
|
|
1003 __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
|
1004 __RES; \
|
|
1005 })
|
|
1006 #endif
|
|
1007
|
|
1008
|
|
1009 /**
|
|
1010 \brief Rotate Right with Extend (32 bit)
|
|
1011 \details Moves each bit of a bitstring right by one bit.
|
|
1012 The carry input is shifted in at the left end of the bitstring.
|
|
1013 \param [in] value Value to rotate
|
|
1014 \return Rotated value
|
|
1015 */
|
|
1016 __attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
|
|
1017 {
|
|
1018 uint32_t result;
|
|
1019
|
|
1020 __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
|
1021 return(result);
|
|
1022 }
|
|
1023
|
|
1024
|
|
1025 /**
|
|
1026 \brief LDRT Unprivileged (8 bit)
|
|
1027 \details Executes a Unprivileged LDRT instruction for 8 bit value.
|
|
1028 \param [in] ptr Pointer to data
|
|
1029 \return value of type uint8_t at (*ptr)
|
|
1030 */
|
|
1031 __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr)
|
|
1032 {
|
|
1033 uint32_t result;
|
|
1034
|
|
1035 __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );
|
|
1036 return ((uint8_t) result); /* Add explicit type cast here */
|
|
1037 }
|
|
1038
|
|
1039
|
|
1040 /**
|
|
1041 \brief LDRT Unprivileged (16 bit)
|
|
1042 \details Executes a Unprivileged LDRT instruction for 16 bit values.
|
|
1043 \param [in] ptr Pointer to data
|
|
1044 \return value of type uint16_t at (*ptr)
|
|
1045 */
|
|
1046 __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr)
|
|
1047 {
|
|
1048 uint32_t result;
|
|
1049
|
|
1050 __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );
|
|
1051 return ((uint16_t) result); /* Add explicit type cast here */
|
|
1052 }
|
|
1053
|
|
1054
|
|
1055 /**
|
|
1056 \brief LDRT Unprivileged (32 bit)
|
|
1057 \details Executes a Unprivileged LDRT instruction for 32 bit values.
|
|
1058 \param [in] ptr Pointer to data
|
|
1059 \return value of type uint32_t at (*ptr)
|
|
1060 */
|
|
1061 __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr)
|
|
1062 {
|
|
1063 uint32_t result;
|
|
1064
|
|
1065 __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );
|
|
1066 return(result);
|
|
1067 }
|
|
1068
|
|
1069
|
|
1070 /**
|
|
1071 \brief STRT Unprivileged (8 bit)
|
|
1072 \details Executes a Unprivileged STRT instruction for 8 bit values.
|
|
1073 \param [in] value Value to store
|
|
1074 \param [in] ptr Pointer to location
|
|
1075 */
|
|
1076 __attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr)
|
|
1077 {
|
|
1078 __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
|
1079 }
|
|
1080
|
|
1081
|
|
1082 /**
|
|
1083 \brief STRT Unprivileged (16 bit)
|
|
1084 \details Executes a Unprivileged STRT instruction for 16 bit values.
|
|
1085 \param [in] value Value to store
|
|
1086 \param [in] ptr Pointer to location
|
|
1087 */
|
|
1088 __attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr)
|
|
1089 {
|
|
1090 __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
|
1091 }
|
|
1092
|
|
1093
|
|
1094 /**
|
|
1095 \brief STRT Unprivileged (32 bit)
|
|
1096 \details Executes a Unprivileged STRT instruction for 32 bit values.
|
|
1097 \param [in] value Value to store
|
|
1098 \param [in] ptr Pointer to location
|
|
1099 */
|
|
1100 __attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr)
|
|
1101 {
|
|
1102 __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
|
|
1103 }
|
|
1104
|
|
1105 #endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
|
|
1106
|
|
1107
|
|
1108 #if (__ARM_ARCH_8M__ == 1U)
|
|
1109
|
|
1110 /**
|
|
1111 \brief Load-Acquire (8 bit)
|
|
1112 \details Executes a LDAB instruction for 8 bit value.
|
|
1113 \param [in] ptr Pointer to data
|
|
1114 \return value of type uint8_t at (*ptr)
|
|
1115 */
|
|
1116 __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t *ptr)
|
|
1117 {
|
|
1118 uint32_t result;
|
|
1119
|
|
1120 __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) );
|
|
1121 return ((uint8_t) result);
|
|
1122 }
|
|
1123
|
|
1124
|
|
1125 /**
|
|
1126 \brief Load-Acquire (16 bit)
|
|
1127 \details Executes a LDAH instruction for 16 bit values.
|
|
1128 \param [in] ptr Pointer to data
|
|
1129 \return value of type uint16_t at (*ptr)
|
|
1130 */
|
|
1131 __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t *ptr)
|
|
1132 {
|
|
1133 uint32_t result;
|
|
1134
|
|
1135 __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) );
|
|
1136 return ((uint16_t) result);
|
|
1137 }
|
|
1138
|
|
1139
|
|
1140 /**
|
|
1141 \brief Load-Acquire (32 bit)
|
|
1142 \details Executes a LDA instruction for 32 bit values.
|
|
1143 \param [in] ptr Pointer to data
|
|
1144 \return value of type uint32_t at (*ptr)
|
|
1145 */
|
|
1146 __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t *ptr)
|
|
1147 {
|
|
1148 uint32_t result;
|
|
1149
|
|
1150 __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) );
|
|
1151 return(result);
|
|
1152 }
|
|
1153
|
|
1154
|
|
1155 /**
|
|
1156 \brief Store-Release (8 bit)
|
|
1157 \details Executes a STLB instruction for 8 bit values.
|
|
1158 \param [in] value Value to store
|
|
1159 \param [in] ptr Pointer to location
|
|
1160 */
|
|
1161 __attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
|
|
1162 {
|
|
1163 __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
|
1164 }
|
|
1165
|
|
1166
|
|
1167 /**
|
|
1168 \brief Store-Release (16 bit)
|
|
1169 \details Executes a STLH instruction for 16 bit values.
|
|
1170 \param [in] value Value to store
|
|
1171 \param [in] ptr Pointer to location
|
|
1172 */
|
|
1173 __attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
|
|
1174 {
|
|
1175 __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
|
1176 }
|
|
1177
|
|
1178
|
|
1179 /**
|
|
1180 \brief Store-Release (32 bit)
|
|
1181 \details Executes a STL instruction for 32 bit values.
|
|
1182 \param [in] value Value to store
|
|
1183 \param [in] ptr Pointer to location
|
|
1184 */
|
|
1185 __attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr)
|
|
1186 {
|
|
1187 __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
|
1188 }
|
|
1189
|
|
1190
|
|
1191 /**
|
|
1192 \brief Load-Acquire Exclusive (8 bit)
|
|
1193 \details Executes a LDAB exclusive instruction for 8 bit value.
|
|
1194 \param [in] ptr Pointer to data
|
|
1195 \return value of type uint8_t at (*ptr)
|
|
1196 */
|
|
1197 #define __LDAEXB (uint8_t)__builtin_arm_ldaex
|
|
1198
|
|
1199
|
|
1200 /**
|
|
1201 \brief Load-Acquire Exclusive (16 bit)
|
|
1202 \details Executes a LDAH exclusive instruction for 16 bit values.
|
|
1203 \param [in] ptr Pointer to data
|
|
1204 \return value of type uint16_t at (*ptr)
|
|
1205 */
|
|
1206 #define __LDAEXH (uint16_t)__builtin_arm_ldaex
|
|
1207
|
|
1208
|
|
1209 /**
|
|
1210 \brief Load-Acquire Exclusive (32 bit)
|
|
1211 \details Executes a LDA exclusive instruction for 32 bit values.
|
|
1212 \param [in] ptr Pointer to data
|
|
1213 \return value of type uint32_t at (*ptr)
|
|
1214 */
|
|
1215 #define __LDAEX (uint32_t)__builtin_arm_ldaex
|
|
1216
|
|
1217
|
|
1218 /**
|
|
1219 \brief Store-Release Exclusive (8 bit)
|
|
1220 \details Executes a STLB exclusive instruction for 8 bit values.
|
|
1221 \param [in] value Value to store
|
|
1222 \param [in] ptr Pointer to location
|
|
1223 \return 0 Function succeeded
|
|
1224 \return 1 Function failed
|
|
1225 */
|
|
1226 #define __STLEXB (uint32_t)__builtin_arm_stlex
|
|
1227
|
|
1228
|
|
1229 /**
|
|
1230 \brief Store-Release Exclusive (16 bit)
|
|
1231 \details Executes a STLH exclusive instruction for 16 bit values.
|
|
1232 \param [in] value Value to store
|
|
1233 \param [in] ptr Pointer to location
|
|
1234 \return 0 Function succeeded
|
|
1235 \return 1 Function failed
|
|
1236 */
|
|
1237 #define __STLEXH (uint32_t)__builtin_arm_stlex
|
|
1238
|
|
1239
|
|
1240 /**
|
|
1241 \brief Store-Release Exclusive (32 bit)
|
|
1242 \details Executes a STL exclusive instruction for 32 bit values.
|
|
1243 \param [in] value Value to store
|
|
1244 \param [in] ptr Pointer to location
|
|
1245 \return 0 Function succeeded
|
|
1246 \return 1 Function failed
|
|
1247 */
|
|
1248 #define __STLEX (uint32_t)__builtin_arm_stlex
|
|
1249
|
|
1250 #endif /* (__ARM_ARCH_8M__ == 1U) */
|
|
1251
|
|
1252 /*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
|
1253
|
|
1254
|
|
1255 /* ################### Compiler specific Intrinsics ########################### */
|
|
1256 /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
|
1257 Access to dedicated SIMD instructions
|
|
1258 @{
|
|
1259 */
|
|
1260
|
|
1261 #if (__ARM_FEATURE_DSP == 1U) /* ToDo: ARMCC_V6: This should be ARCH >= ARMv7-M + SIMD */
|
|
1262
|
|
1263 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
|
|
1264 {
|
|
1265 uint32_t result;
|
|
1266
|
|
1267 __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1268 return(result);
|
|
1269 }
|
|
1270
|
|
1271 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
|
|
1272 {
|
|
1273 uint32_t result;
|
|
1274
|
|
1275 __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1276 return(result);
|
|
1277 }
|
|
1278
|
|
1279 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
|
|
1280 {
|
|
1281 uint32_t result;
|
|
1282
|
|
1283 __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1284 return(result);
|
|
1285 }
|
|
1286
|
|
1287 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
|
|
1288 {
|
|
1289 uint32_t result;
|
|
1290
|
|
1291 __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1292 return(result);
|
|
1293 }
|
|
1294
|
|
1295 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
|
|
1296 {
|
|
1297 uint32_t result;
|
|
1298
|
|
1299 __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1300 return(result);
|
|
1301 }
|
|
1302
|
|
1303 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
|
|
1304 {
|
|
1305 uint32_t result;
|
|
1306
|
|
1307 __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1308 return(result);
|
|
1309 }
|
|
1310
|
|
1311
|
|
1312 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
|
|
1313 {
|
|
1314 uint32_t result;
|
|
1315
|
|
1316 __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1317 return(result);
|
|
1318 }
|
|
1319
|
|
1320 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
|
|
1321 {
|
|
1322 uint32_t result;
|
|
1323
|
|
1324 __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1325 return(result);
|
|
1326 }
|
|
1327
|
|
1328 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
|
|
1329 {
|
|
1330 uint32_t result;
|
|
1331
|
|
1332 __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1333 return(result);
|
|
1334 }
|
|
1335
|
|
1336 __attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
|
|
1337 {
|
|
1338 uint32_t result;
|
|
1339
|
|
1340 __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1341 return(result);
|
|
1342 }
|
|
1343
|
|
1344 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
|
|
1345 {
|
|
1346 uint32_t result;
|
|
1347
|
|
1348 __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1349 return(result);
|
|
1350 }
|
|
1351
|
|
1352 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
|
|
1353 {
|
|
1354 uint32_t result;
|
|
1355
|
|
1356 __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1357 return(result);
|
|
1358 }
|
|
1359
|
|
1360
|
|
1361 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
|
|
1362 {
|
|
1363 uint32_t result;
|
|
1364
|
|
1365 __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1366 return(result);
|
|
1367 }
|
|
1368
|
|
1369 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
|
|
1370 {
|
|
1371 uint32_t result;
|
|
1372
|
|
1373 __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1374 return(result);
|
|
1375 }
|
|
1376
|
|
1377 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
|
|
1378 {
|
|
1379 uint32_t result;
|
|
1380
|
|
1381 __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1382 return(result);
|
|
1383 }
|
|
1384
|
|
1385 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
|
|
1386 {
|
|
1387 uint32_t result;
|
|
1388
|
|
1389 __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1390 return(result);
|
|
1391 }
|
|
1392
|
|
1393 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
|
|
1394 {
|
|
1395 uint32_t result;
|
|
1396
|
|
1397 __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1398 return(result);
|
|
1399 }
|
|
1400
|
|
1401 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
|
|
1402 {
|
|
1403 uint32_t result;
|
|
1404
|
|
1405 __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1406 return(result);
|
|
1407 }
|
|
1408
|
|
1409 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
|
|
1410 {
|
|
1411 uint32_t result;
|
|
1412
|
|
1413 __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1414 return(result);
|
|
1415 }
|
|
1416
|
|
1417 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
|
|
1418 {
|
|
1419 uint32_t result;
|
|
1420
|
|
1421 __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1422 return(result);
|
|
1423 }
|
|
1424
|
|
1425 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
|
|
1426 {
|
|
1427 uint32_t result;
|
|
1428
|
|
1429 __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1430 return(result);
|
|
1431 }
|
|
1432
|
|
1433 __attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
|
|
1434 {
|
|
1435 uint32_t result;
|
|
1436
|
|
1437 __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1438 return(result);
|
|
1439 }
|
|
1440
|
|
1441 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
|
|
1442 {
|
|
1443 uint32_t result;
|
|
1444
|
|
1445 __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1446 return(result);
|
|
1447 }
|
|
1448
|
|
1449 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
|
|
1450 {
|
|
1451 uint32_t result;
|
|
1452
|
|
1453 __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1454 return(result);
|
|
1455 }
|
|
1456
|
|
1457 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
|
|
1458 {
|
|
1459 uint32_t result;
|
|
1460
|
|
1461 __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1462 return(result);
|
|
1463 }
|
|
1464
|
|
1465 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
|
|
1466 {
|
|
1467 uint32_t result;
|
|
1468
|
|
1469 __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1470 return(result);
|
|
1471 }
|
|
1472
|
|
1473 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
|
|
1474 {
|
|
1475 uint32_t result;
|
|
1476
|
|
1477 __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1478 return(result);
|
|
1479 }
|
|
1480
|
|
1481 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
|
|
1482 {
|
|
1483 uint32_t result;
|
|
1484
|
|
1485 __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1486 return(result);
|
|
1487 }
|
|
1488
|
|
1489 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
|
|
1490 {
|
|
1491 uint32_t result;
|
|
1492
|
|
1493 __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1494 return(result);
|
|
1495 }
|
|
1496
|
|
1497 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
|
|
1498 {
|
|
1499 uint32_t result;
|
|
1500
|
|
1501 __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1502 return(result);
|
|
1503 }
|
|
1504
|
|
1505 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
|
|
1506 {
|
|
1507 uint32_t result;
|
|
1508
|
|
1509 __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1510 return(result);
|
|
1511 }
|
|
1512
|
|
1513 __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
|
|
1514 {
|
|
1515 uint32_t result;
|
|
1516
|
|
1517 __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1518 return(result);
|
|
1519 }
|
|
1520
|
|
1521 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
|
|
1522 {
|
|
1523 uint32_t result;
|
|
1524
|
|
1525 __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1526 return(result);
|
|
1527 }
|
|
1528
|
|
1529 __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
|
|
1530 {
|
|
1531 uint32_t result;
|
|
1532
|
|
1533 __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1534 return(result);
|
|
1535 }
|
|
1536
|
|
1537 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
|
|
1538 {
|
|
1539 uint32_t result;
|
|
1540
|
|
1541 __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1542 return(result);
|
|
1543 }
|
|
1544
|
|
1545 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
|
|
1546 {
|
|
1547 uint32_t result;
|
|
1548
|
|
1549 __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1550 return(result);
|
|
1551 }
|
|
1552
|
|
1553 __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
|
|
1554 {
|
|
1555 uint32_t result;
|
|
1556
|
|
1557 __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1558 return(result);
|
|
1559 }
|
|
1560
|
|
1561 __attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
|
|
1562 {
|
|
1563 uint32_t result;
|
|
1564
|
|
1565 __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
|
1566 return(result);
|
|
1567 }
|
|
1568
|
|
1569 #define __SSAT16(ARG1,ARG2) \
|
|
1570 ({ \
|
|
1571 uint32_t __RES, __ARG1 = (ARG1); \
|
|
1572 __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
|
1573 __RES; \
|
|
1574 })
|
|
1575
|
|
1576 #define __USAT16(ARG1,ARG2) \
|
|
1577 ({ \
|
|
1578 uint32_t __RES, __ARG1 = (ARG1); \
|
|
1579 __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
|
1580 __RES; \
|
|
1581 })
|
|
1582
|
|
1583 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
|
|
1584 {
|
|
1585 uint32_t result;
|
|
1586
|
|
1587 __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
|
1588 return(result);
|
|
1589 }
|
|
1590
|
|
1591 __attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
|
|
1592 {
|
|
1593 uint32_t result;
|
|
1594
|
|
1595 __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1596 return(result);
|
|
1597 }
|
|
1598
|
|
1599 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
|
|
1600 {
|
|
1601 uint32_t result;
|
|
1602
|
|
1603 __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
|
1604 return(result);
|
|
1605 }
|
|
1606
|
|
1607 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
|
|
1608 {
|
|
1609 uint32_t result;
|
|
1610
|
|
1611 __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1612 return(result);
|
|
1613 }
|
|
1614
|
|
1615 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
|
|
1616 {
|
|
1617 uint32_t result;
|
|
1618
|
|
1619 __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1620 return(result);
|
|
1621 }
|
|
1622
|
|
1623 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
|
|
1624 {
|
|
1625 uint32_t result;
|
|
1626
|
|
1627 __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1628 return(result);
|
|
1629 }
|
|
1630
|
|
1631 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
|
|
1632 {
|
|
1633 uint32_t result;
|
|
1634
|
|
1635 __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
|
1636 return(result);
|
|
1637 }
|
|
1638
|
|
1639 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
|
|
1640 {
|
|
1641 uint32_t result;
|
|
1642
|
|
1643 __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
|
1644 return(result);
|
|
1645 }
|
|
1646
|
|
1647 __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
|
|
1648 {
|
|
1649 union llreg_u{
|
|
1650 uint32_t w32[2];
|
|
1651 uint64_t w64;
|
|
1652 } llr;
|
|
1653 llr.w64 = acc;
|
|
1654
|
|
1655 #ifndef __ARMEB__ /* Little endian */
|
|
1656 __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
|
1657 #else /* Big endian */
|
|
1658 __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
|
1659 #endif
|
|
1660
|
|
1661 return(llr.w64);
|
|
1662 }
|
|
1663
|
|
1664 __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
|
|
1665 {
|
|
1666 union llreg_u{
|
|
1667 uint32_t w32[2];
|
|
1668 uint64_t w64;
|
|
1669 } llr;
|
|
1670 llr.w64 = acc;
|
|
1671
|
|
1672 #ifndef __ARMEB__ /* Little endian */
|
|
1673 __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
|
1674 #else /* Big endian */
|
|
1675 __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
|
1676 #endif
|
|
1677
|
|
1678 return(llr.w64);
|
|
1679 }
|
|
1680
|
|
1681 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
|
|
1682 {
|
|
1683 uint32_t result;
|
|
1684
|
|
1685 __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1686 return(result);
|
|
1687 }
|
|
1688
|
|
1689 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
|
|
1690 {
|
|
1691 uint32_t result;
|
|
1692
|
|
1693 __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1694 return(result);
|
|
1695 }
|
|
1696
|
|
1697 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
|
|
1698 {
|
|
1699 uint32_t result;
|
|
1700
|
|
1701 __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
|
1702 return(result);
|
|
1703 }
|
|
1704
|
|
1705 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
|
|
1706 {
|
|
1707 uint32_t result;
|
|
1708
|
|
1709 __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
|
1710 return(result);
|
|
1711 }
|
|
1712
|
|
1713 __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
|
|
1714 {
|
|
1715 union llreg_u{
|
|
1716 uint32_t w32[2];
|
|
1717 uint64_t w64;
|
|
1718 } llr;
|
|
1719 llr.w64 = acc;
|
|
1720
|
|
1721 #ifndef __ARMEB__ /* Little endian */
|
|
1722 __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
|
1723 #else /* Big endian */
|
|
1724 __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
|
1725 #endif
|
|
1726
|
|
1727 return(llr.w64);
|
|
1728 }
|
|
1729
|
|
1730 __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
|
|
1731 {
|
|
1732 union llreg_u{
|
|
1733 uint32_t w32[2];
|
|
1734 uint64_t w64;
|
|
1735 } llr;
|
|
1736 llr.w64 = acc;
|
|
1737
|
|
1738 #ifndef __ARMEB__ /* Little endian */
|
|
1739 __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
|
1740 #else /* Big endian */
|
|
1741 __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
|
1742 #endif
|
|
1743
|
|
1744 return(llr.w64);
|
|
1745 }
|
|
1746
|
|
1747 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
|
|
1748 {
|
|
1749 uint32_t result;
|
|
1750
|
|
1751 __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1752 return(result);
|
|
1753 }
|
|
1754
|
|
1755 __attribute__((always_inline)) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2)
|
|
1756 {
|
|
1757 int32_t result;
|
|
1758
|
|
1759 __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1760 return(result);
|
|
1761 }
|
|
1762
|
|
1763 __attribute__((always_inline)) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2)
|
|
1764 {
|
|
1765 int32_t result;
|
|
1766
|
|
1767 __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
|
1768 return(result);
|
|
1769 }
|
|
1770
|
|
1771 #define __PKHBT(ARG1,ARG2,ARG3) \
|
|
1772 ({ \
|
|
1773 uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
|
1774 __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
|
1775 __RES; \
|
|
1776 })
|
|
1777
|
|
1778 #define __PKHTB(ARG1,ARG2,ARG3) \
|
|
1779 ({ \
|
|
1780 uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
|
1781 if (ARG3 == 0) \
|
|
1782 __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
|
|
1783 else \
|
|
1784 __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
|
1785 __RES; \
|
|
1786 })
|
|
1787
|
|
1788 __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
|
|
1789 {
|
|
1790 int32_t result;
|
|
1791
|
|
1792 __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
|
|
1793 return(result);
|
|
1794 }
|
|
1795
|
|
1796 #endif /* (__ARM_FEATURE_DSP == 1U) */
|
|
1797 /*@} end of group CMSIS_SIMD_intrinsics */
|
|
1798
|
|
1799
|
|
1800 #endif /* __CMSIS_ARMCC_V6_H */
|