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