]> begriffs open source - cmsis/blob - CMSIS/Core_A/Include/cmsis_armcc.h
Fixup documentation links that let link checker crash.
[cmsis] / CMSIS / Core_A / Include / cmsis_armcc.h
1 /**************************************************************************//**
2  * @file     cmsis_armcc.h
3  * @brief    CMSIS compiler ARMCC (Arm Compiler 5) header file
4  * @version  V1.0.6
5  * @date     13. November 2022
6  ******************************************************************************/
7 /*
8  * Copyright (c) 2009-2021 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_ARMCC_H
26 #define __CMSIS_ARMCC_H
27
28
29 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
30   #error "Please use Arm Compiler Toolchain V4.0.677 or later!"
31 #endif
32
33 /* CMSIS compiler control architecture macros */
34 #if (defined (__TARGET_ARCH_7_A ) && (__TARGET_ARCH_7_A  == 1))
35   #define __ARM_ARCH_7A__           1
36 #endif
37
38 /* CMSIS compiler specific defines */
39 #ifndef   __ASM
40   #define __ASM                                  __asm
41 #endif
42 #ifndef   __INLINE
43   #define __INLINE                               __inline
44 #endif
45 #ifndef   __FORCEINLINE
46   #define __FORCEINLINE                          __forceinline
47 #endif
48 #ifndef   __STATIC_INLINE
49   #define __STATIC_INLINE                        static __inline
50 #endif
51 #ifndef   __STATIC_FORCEINLINE
52   #define __STATIC_FORCEINLINE                   static __forceinline
53 #endif
54 #ifndef   __NO_RETURN
55   #define __NO_RETURN                            __declspec(noreturn)
56 #endif
57 #ifndef   CMSIS_DEPRECATED
58   #define CMSIS_DEPRECATED                       __attribute__((deprecated))
59 #endif
60 #ifndef   __USED
61   #define __USED                                 __attribute__((used))
62 #endif
63 #ifndef   __WEAK
64   #define __WEAK                                 __attribute__((weak))
65 #endif
66 #ifndef   __PACKED
67   #define __PACKED                               __attribute__((packed))
68 #endif
69 #ifndef   __PACKED_STRUCT
70   #define __PACKED_STRUCT                        __packed struct
71 #endif
72 #ifndef   __PACKED_UNION
73   #define __PACKED_UNION                         __packed union
74 #endif
75 #ifndef   __UNALIGNED_UINT32        /* deprecated */
76   #define __UNALIGNED_UINT32(x)                  (*((__packed uint32_t *)(x)))
77 #endif
78 #ifndef   __UNALIGNED_UINT16_WRITE
79   #define __UNALIGNED_UINT16_WRITE(addr, val)    ((*((__packed uint16_t *)(addr))) = (val))
80 #endif
81 #ifndef   __UNALIGNED_UINT16_READ
82   #define __UNALIGNED_UINT16_READ(addr)          (*((const __packed uint16_t *)(addr)))
83 #endif
84 #ifndef   __UNALIGNED_UINT32_WRITE
85   #define __UNALIGNED_UINT32_WRITE(addr, val)    ((*((__packed uint32_t *)(addr))) = (val))
86 #endif
87 #ifndef   __UNALIGNED_UINT32_READ
88   #define __UNALIGNED_UINT32_READ(addr)          (*((const __packed uint32_t *)(addr)))
89 #endif
90 #ifndef   __ALIGNED
91   #define __ALIGNED(x)                           __attribute__((aligned(x)))
92 #endif
93 #ifndef   __RESTRICT
94   #define __RESTRICT                             __restrict
95 #endif
96 #ifndef   __COMPILER_BARRIER
97   #define __COMPILER_BARRIER()                   __memory_changed()
98 #endif
99
100 /* ##########################  Core Instruction Access  ######################### */
101 /**
102   \brief   No Operation
103   \details No Operation does nothing. This instruction can be used for code alignment purposes.
104  */
105 #define __NOP                             __nop
106
107
108 /**
109   \brief   Wait For Interrupt
110   \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
111  */
112 #define __WFI                             __wfi
113
114
115 /**
116   \brief   Wait For Event
117   \details Wait For Event is a hint instruction that permits the processor to enter
118            a low-power state until one of a number of events occurs.
119  */
120 #define __WFE                             __wfe
121
122
123 /**
124   \brief   Send Event
125   \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
126  */
127 #define __SEV                             __sev
128
129
130 /**
131   \brief   Instruction Synchronization Barrier
132   \details Instruction Synchronization Barrier flushes the pipeline in the processor,
133            so that all instructions following the ISB are fetched from cache or memory,
134            after the instruction has been completed.
135  */
136 #define __ISB()                           __isb(0xF)
137
138 /**
139   \brief   Data Synchronization Barrier
140   \details Acts as a special kind of Data Memory Barrier.
141            It completes when all explicit memory accesses before this instruction complete.
142  */
143 #define __DSB()                           __dsb(0xF)
144
145 /**
146   \brief   Data Memory Barrier
147   \details Ensures the apparent order of the explicit memory operations before
148            and after the instruction, without ensuring their completion.
149  */
150 #define __DMB()                           __dmb(0xF)
151
152
153 /**
154   \brief   Reverse byte order (32 bit)
155   \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
156   \param [in]    value  Value to reverse
157   \return               Reversed value
158  */
159 #define __REV                             __rev
160
161
162 /**
163   \brief   Reverse byte order (16 bit)
164   \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
165   \param [in]    value  Value to reverse
166   \return               Reversed value
167  */
168 #ifndef __NO_EMBEDDED_ASM
169 __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
170 {
171   rev16 r0, r0
172   bx lr
173 }
174 #endif
175
176
177 /**
178   \brief   Reverse byte order (16 bit)
179   \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
180   \param [in]    value  Value to reverse
181   \return               Reversed value
182  */
183 #ifndef __NO_EMBEDDED_ASM
184 __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
185 {
186   revsh r0, r0
187   bx lr
188 }
189 #endif
190
191
192 /**
193   \brief   Rotate Right in unsigned value (32 bit)
194   \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
195   \param [in]    op1  Value to rotate
196   \param [in]    op2  Number of Bits to rotate
197   \return               Rotated value
198  */
199 #define __ROR                             __ror
200
201
202 /**
203   \brief   Breakpoint
204   \details Causes the processor to enter Debug state.
205            Debug tools can use this to investigate system state when the instruction at a particular address is reached.
206   \param [in]    value  is ignored by the processor.
207                  If required, a debugger can use it to store additional information about the breakpoint.
208  */
209 #define __BKPT(value)                     __breakpoint(value)
210
211
212 /**
213   \brief   Reverse bit order of value
214   \details Reverses the bit order of the given value.
215   \param [in]    value  Value to reverse
216   \return               Reversed value
217  */
218 #define __RBIT                            __rbit
219
220 /**
221   \brief   Count leading zeros
222   \details Counts the number of leading zeros of a data value.
223   \param [in]  value  Value to count the leading zeros
224   \return             number of leading zeros in value
225  */
226 #define __CLZ                             __clz
227
228 /**
229   \brief   LDR Exclusive (8 bit)
230   \details Executes a exclusive LDR instruction for 8 bit value.
231   \param [in]    ptr  Pointer to data
232   \return             value of type uint8_t at (*ptr)
233  */
234 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
235   #define __LDREXB(ptr)                                                        ((uint8_t ) __ldrex(ptr))
236 #else
237   #define __LDREXB(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr))  _Pragma("pop")
238 #endif
239
240
241 /**
242   \brief   LDR Exclusive (16 bit)
243   \details Executes a exclusive LDR instruction for 16 bit values.
244   \param [in]    ptr  Pointer to data
245   \return        value of type uint16_t at (*ptr)
246  */
247 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
248   #define __LDREXH(ptr)                                                        ((uint16_t) __ldrex(ptr))
249 #else
250   #define __LDREXH(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr))  _Pragma("pop")
251 #endif
252
253
254 /**
255   \brief   LDR Exclusive (32 bit)
256   \details Executes a exclusive LDR instruction for 32 bit values.
257   \param [in]    ptr  Pointer to data
258   \return        value of type uint32_t at (*ptr)
259  */
260 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
261   #define __LDREXW(ptr)                                                        ((uint32_t ) __ldrex(ptr))
262 #else
263   #define __LDREXW(ptr)          _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr))  _Pragma("pop")
264 #endif
265
266
267 /**
268   \brief   STR Exclusive (8 bit)
269   \details Executes a exclusive STR instruction for 8 bit values.
270   \param [in]  value  Value to store
271   \param [in]    ptr  Pointer to location
272   \return          0  Function succeeded
273   \return          1  Function failed
274  */
275 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
276   #define __STREXB(value, ptr)                                                 __strex(value, ptr)
277 #else
278   #define __STREXB(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
279 #endif
280
281
282 /**
283   \brief   STR Exclusive (16 bit)
284   \details Executes a exclusive STR instruction for 16 bit values.
285   \param [in]  value  Value to store
286   \param [in]    ptr  Pointer to location
287   \return          0  Function succeeded
288   \return          1  Function failed
289  */
290 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
291   #define __STREXH(value, ptr)                                                 __strex(value, ptr)
292 #else
293   #define __STREXH(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
294 #endif
295
296
297 /**
298   \brief   STR Exclusive (32 bit)
299   \details Executes a exclusive STR instruction for 32 bit values.
300   \param [in]  value  Value to store
301   \param [in]    ptr  Pointer to location
302   \return          0  Function succeeded
303   \return          1  Function failed
304  */
305 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
306   #define __STREXW(value, ptr)                                                 __strex(value, ptr)
307 #else
308   #define __STREXW(value, ptr)   _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr)        _Pragma("pop")
309 #endif
310
311
312 /**
313   \brief   Remove the exclusive lock
314   \details Removes the exclusive lock which is created by LDREX.
315  */
316 #define __CLREX                           __clrex
317
318
319 /**
320   \brief   Signed Saturate
321   \details Saturates a signed value.
322   \param [in]  value  Value to be saturated
323   \param [in]    sat  Bit position to saturate to (1..32)
324   \return             Saturated value
325  */
326 #define __SSAT                            __ssat
327
328
329 /**
330   \brief   Unsigned Saturate
331   \details Saturates an unsigned value.
332   \param [in]  value  Value to be saturated
333   \param [in]    sat  Bit position to saturate to (0..31)
334   \return             Saturated value
335  */
336 #define __USAT                            __usat
337
338 /* ###########################  Core Function Access  ########################### */
339
340 /**
341   \brief   Enable IRQ Interrupts
342   \details Enables IRQ interrupts by clearing special-purpose register PRIMASK.
343            Can only be executed in Privileged modes.
344  */
345 /* intrinsic void __enable_irq(); */
346
347
348 /**
349   \brief   Disable IRQ Interrupts
350   \details Disables IRQ interrupts by setting special-purpose register PRIMASK.
351   Can only be executed in Privileged modes.
352  */
353 /* intrinsic void __disable_irq(void); */
354
355 /**
356   \brief   Enable FIQ
357   \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
358            Can only be executed in Privileged modes.
359  */
360 #define __enable_fault_irq                __enable_fiq
361
362 /**
363   \brief   Disable FIQ
364   \details Disables FIQ interrupts by setting the F-bit in the CPSR.
365            Can only be executed in Privileged modes.
366  */
367 #define __disable_fault_irq               __disable_fiq
368
369 /**
370   \brief   Get FPSCR (Floating Point Status/Control)
371   \return               Floating Point Status/Control register value
372  */
373 __STATIC_INLINE uint32_t __get_FPSCR(void)
374 {
375 #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
376      (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     )
377   register uint32_t __regfpscr         __ASM("fpscr");
378   return(__regfpscr);
379 #else
380    return(0U);
381 #endif
382 }
383
384 /**
385   \brief   Set FPSCR (Floating Point Status/Control)
386   \param [in]    fpscr  Floating Point Status/Control value to set
387  */
388 __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
389 {
390 #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
391      (defined (__FPU_USED   ) && (__FPU_USED    == 1U))     )
392   register uint32_t __regfpscr         __ASM("fpscr");
393   __regfpscr = (fpscr);
394 #else
395   (void)fpscr;
396 #endif
397 }
398
399 /** \brief  Get CPSR (Current Program Status Register)
400     \return               CPSR Register value
401  */
402 __STATIC_INLINE uint32_t __get_CPSR(void)
403 {
404   register uint32_t __regCPSR          __ASM("cpsr");
405   return(__regCPSR);
406 }
407
408
409 /** \brief  Set CPSR (Current Program Status Register)
410     \param [in]    cpsr  CPSR value to set
411  */
412 __STATIC_INLINE void __set_CPSR(uint32_t cpsr)
413 {
414   register uint32_t __regCPSR          __ASM("cpsr");
415   __regCPSR = cpsr;
416 }
417
418 /** \brief  Get Mode
419     \return                Processor Mode
420  */
421 __STATIC_INLINE uint32_t __get_mode(void)
422 {
423   return (__get_CPSR() & 0x1FU);
424 }
425
426 /** \brief  Set Mode
427     \param [in]    mode  Mode value to set
428  */
429 __STATIC_INLINE __ASM void __set_mode(uint32_t mode)
430 {
431   MOV  r1, lr
432   MSR  CPSR_C, r0
433   BX   r1
434 }
435
436 /** \brief  Get Stack Pointer
437     \return Stack Pointer
438  */
439 __STATIC_INLINE __ASM uint32_t __get_SP(void)
440 {
441   MOV  r0, sp
442   BX   lr
443 }
444
445 /** \brief  Set Stack Pointer
446     \param [in]    stack  Stack Pointer value to set
447  */
448 __STATIC_INLINE __ASM void __set_SP(uint32_t stack)
449 {
450   MOV  sp, r0
451   BX   lr
452 }
453
454
455 /** \brief  Get USR/SYS Stack Pointer
456     \return USR/SYSStack Pointer
457  */
458 __STATIC_INLINE __ASM uint32_t __get_SP_usr(void)
459 {
460   ARM
461   PRESERVE8
462
463   MRS     R1, CPSR
464   CPS     #0x1F       ;no effect in USR mode
465   MOV     R0, SP
466   MSR     CPSR_c, R1  ;no effect in USR mode
467   ISB
468   BX      LR
469 }
470
471 /** \brief  Set USR/SYS Stack Pointer
472     \param [in]    topOfProcStack  USR/SYS Stack Pointer value to set
473  */
474 __STATIC_INLINE __ASM void __set_SP_usr(uint32_t topOfProcStack)
475 {
476   ARM
477   PRESERVE8
478
479   MRS     R1, CPSR
480   CPS     #0x1F       ;no effect in USR mode
481   MOV     SP, R0
482   MSR     CPSR_c, R1  ;no effect in USR mode
483   ISB
484   BX      LR
485 }
486
487 /** \brief  Get FPEXC (Floating Point Exception Control Register)
488     \return               Floating Point Exception Control Register value
489  */
490 __STATIC_INLINE uint32_t __get_FPEXC(void)
491 {
492 #if (__FPU_PRESENT == 1)
493   register uint32_t __regfpexc         __ASM("fpexc");
494   return(__regfpexc);
495 #else
496   return(0);
497 #endif
498 }
499
500 /** \brief  Set FPEXC (Floating Point Exception Control Register)
501     \param [in]    fpexc  Floating Point Exception Control value to set
502  */
503 __STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
504 {
505 #if (__FPU_PRESENT == 1)
506   register uint32_t __regfpexc         __ASM("fpexc");
507   __regfpexc = (fpexc);
508 #endif
509 }
510
511 /*
512  * Include common core functions to access Coprocessor 15 registers
513  */
514
515 #define __get_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); (Rt) = tmp; } while(0)
516 #define __set_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); tmp = (Rt); } while(0)
517 #define __get_CP64(cp, op1, Rt, CRm) \
518   do { \
519     uint32_t ltmp, htmp; \
520     __ASM volatile("MRRC p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \
521     (Rt) = ((((uint64_t)htmp) << 32U) | ((uint64_t)ltmp)); \
522   } while(0)
523
524 #define __set_CP64(cp, op1, Rt, CRm) \
525   do { \
526     const uint64_t tmp = (Rt); \
527     const uint32_t ltmp = (uint32_t)(tmp); \
528     const uint32_t htmp = (uint32_t)(tmp >> 32U); \
529     __ASM volatile("MCRR p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \
530   } while(0)
531
532 #include "cmsis_cp15.h"
533
534 /** \brief  Enable Floating Point Unit
535
536   Critical section, called from undef handler, so systick is disabled
537  */
538 __STATIC_INLINE __ASM void __FPU_Enable(void)
539 {
540         ARM
541
542         //Permit access to VFP/NEON, registers by modifying CPACR
543         MRC     p15,0,R1,c1,c0,2
544         ORR     R1,R1,#0x00F00000
545         MCR     p15,0,R1,c1,c0,2
546
547         //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
548         ISB
549
550         //Enable VFP/NEON
551         VMRS    R1,FPEXC
552         ORR     R1,R1,#0x40000000
553         VMSR    FPEXC,R1
554
555         //Initialise VFP/NEON registers to 0
556         MOV     R2,#0
557
558         //Initialise D16 registers to 0
559         VMOV    D0, R2,R2
560         VMOV    D1, R2,R2
561         VMOV    D2, R2,R2
562         VMOV    D3, R2,R2
563         VMOV    D4, R2,R2
564         VMOV    D5, R2,R2
565         VMOV    D6, R2,R2
566         VMOV    D7, R2,R2
567         VMOV    D8, R2,R2
568         VMOV    D9, R2,R2
569         VMOV    D10,R2,R2
570         VMOV    D11,R2,R2
571         VMOV    D12,R2,R2
572         VMOV    D13,R2,R2
573         VMOV    D14,R2,R2
574         VMOV    D15,R2,R2
575
576   IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
577         //Initialise D32 registers to 0
578         VMOV    D16,R2,R2
579         VMOV    D17,R2,R2
580         VMOV    D18,R2,R2
581         VMOV    D19,R2,R2
582         VMOV    D20,R2,R2
583         VMOV    D21,R2,R2
584         VMOV    D22,R2,R2
585         VMOV    D23,R2,R2
586         VMOV    D24,R2,R2
587         VMOV    D25,R2,R2
588         VMOV    D26,R2,R2
589         VMOV    D27,R2,R2
590         VMOV    D28,R2,R2
591         VMOV    D29,R2,R2
592         VMOV    D30,R2,R2
593         VMOV    D31,R2,R2
594   ENDIF
595
596         //Initialise FPSCR to a known state
597         VMRS    R1,FPSCR
598         LDR     R2,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
599         AND     R1,R1,R2
600         VMSR    FPSCR,R1
601
602         BX      LR
603 }
604
605 #endif /* __CMSIS_ARMCC_H */