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