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