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