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