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