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