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