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