]> begriffs open source - cmsis/blob - CMSIS/Core_A/Include/cmsis_armclang.h
Core(A): Fixed file and component versions.
[cmsis] / CMSIS / Core_A / Include / cmsis_armclang.h
1 /**************************************************************************//**
2  * @file     cmsis_armclang.h
3  * @brief    CMSIS compiler specific macros, functions, instructions
4  * @version  V1.2.0
5  * @date     05. August 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_ARMCLANG_H
26 #define __CMSIS_ARMCLANG_H
27
28 #pragma clang system_header   /* treat file as system include file */
29
30 #ifndef __ARM_COMPAT_H
31 #include <arm_compat.h>    /* Compatibility header for Arm Compiler 5 intrinsics */
32 #endif
33
34 /* CMSIS compiler specific defines */
35 #ifndef   __ASM
36   #define __ASM                                  __asm
37 #endif
38 #ifndef   __INLINE
39   #define __INLINE                               __inline
40 #endif
41 #ifndef   __FORCEINLINE
42   #define __FORCEINLINE                          __attribute__((always_inline))
43 #endif
44 #ifndef   __STATIC_INLINE
45   #define __STATIC_INLINE                        static __inline
46 #endif
47 #ifndef   __STATIC_FORCEINLINE
48   #define __STATIC_FORCEINLINE                   __attribute__((always_inline)) static __inline
49 #endif
50 #ifndef   __NO_RETURN
51   #define __NO_RETURN                            __attribute__((__noreturn__))
52 #endif
53 #ifndef   CMSIS_DEPRECATED
54   #define CMSIS_DEPRECATED                       __attribute__((deprecated))
55 #endif
56 #ifndef   __USED
57   #define __USED                                 __attribute__((used))
58 #endif
59 #ifndef   __WEAK
60   #define __WEAK                                 __attribute__((weak))
61 #endif
62 #ifndef   __PACKED
63   #define __PACKED                               __attribute__((packed, aligned(1)))
64 #endif
65 #ifndef   __PACKED_STRUCT
66   #define __PACKED_STRUCT                        struct __attribute__((packed, aligned(1)))
67 #endif
68 #ifndef   __UNALIGNED_UINT16_WRITE
69   #pragma clang diagnostic push
70   #pragma clang diagnostic ignored "-Wpacked"
71 /*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */
72   __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
73   #pragma clang diagnostic pop
74   #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
75 #endif
76 #ifndef   __UNALIGNED_UINT16_READ
77   #pragma clang diagnostic push
78   #pragma clang diagnostic ignored "-Wpacked"
79 /*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */
80   __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
81   #pragma clang diagnostic pop
82   #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v)
83 #endif
84 #ifndef   __UNALIGNED_UINT32_WRITE
85   #pragma clang diagnostic push
86   #pragma clang diagnostic ignored "-Wpacked"
87 /*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
88   __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
89   #pragma clang diagnostic pop
90   #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
91 #endif
92 #ifndef   __UNALIGNED_UINT32_READ
93   #pragma clang diagnostic push
94   #pragma clang diagnostic ignored "-Wpacked"
95   __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
96   #pragma clang diagnostic pop
97   #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v)
98 #endif
99 #ifndef   __ALIGNED
100   #define __ALIGNED(x)                           __attribute__((aligned(x)))
101 #endif
102 #ifndef   __PACKED
103   #define __PACKED                               __attribute__((packed))
104 #endif
105 #ifndef   __COMPILER_BARRIER
106   #define __COMPILER_BARRIER()                   __ASM volatile("":::"memory")
107 #endif
108
109 /* ##########################  Core Instruction Access  ######################### */
110 /**
111   \brief   No Operation
112  */
113 #define __NOP                             __builtin_arm_nop
114
115 /**
116   \brief   Wait For Interrupt
117  */
118 #define __WFI                             __builtin_arm_wfi
119
120 /**
121   \brief   Wait For Event
122  */
123 #define __WFE                             __builtin_arm_wfe
124
125 /**
126   \brief   Send Event
127  */
128 #define __SEV                             __builtin_arm_sev
129
130 /**
131   \brief   Instruction Synchronization Barrier
132  */
133 #define __ISB()                           __builtin_arm_isb(0xF)
134
135 /**
136   \brief   Data Synchronization Barrier
137  */
138 #define __DSB()                           __builtin_arm_dsb(0xF)
139
140 /**
141   \brief   Data Memory Barrier
142  */
143 #define __DMB()                           __builtin_arm_dmb(0xF)
144
145 /**
146   \brief   Reverse byte order (32 bit)
147   \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
148   \param [in]    value  Value to reverse
149   \return               Reversed value
150  */
151 #define __REV(value)   __builtin_bswap32(value)
152
153 /**
154   \brief   Reverse byte order (16 bit)
155   \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
156   \param [in]    value  Value to reverse
157   \return               Reversed value
158  */
159 #define __REV16(value) __ROR(__REV(value), 16)
160
161
162 /**
163   \brief   Reverse byte order (16 bit)
164   \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
165   \param [in]    value  Value to reverse
166   \return               Reversed value
167  */
168 #define __REVSH(value) (int16_t)__builtin_bswap16(value)
169
170
171 /**
172   \brief   Rotate Right in unsigned value (32 bit)
173   \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
174   \param [in]    op1  Value to rotate
175   \param [in]    op2  Number of Bits to rotate
176   \return               Rotated value
177  */
178 __STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
179 {
180   op2 %= 32U;
181   if (op2 == 0U)
182   {
183     return op1;
184   }
185   return (op1 >> op2) | (op1 << (32U - op2));
186 }
187
188
189 /**
190   \brief   Breakpoint
191   \param [in]    value  is ignored by the processor.
192                  If required, a debugger can use it to store additional information about the breakpoint.
193  */
194 #define __BKPT(value)   __ASM volatile ("bkpt "#value)
195
196 /**
197   \brief   Reverse bit order of value
198   \param [in]    value  Value to reverse
199   \return               Reversed value
200  */
201 #define __RBIT          __builtin_arm_rbit
202
203 /**
204   \brief   Count leading zeros
205   \param [in]  value  Value to count the leading zeros
206   \return             number of leading zeros in value
207  */
208 __STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value)
209 {
210   /* Even though __builtin_clz produces a CLZ instruction on ARM, formally
211      __builtin_clz(0) is undefined behaviour, so handle this case specially.
212      This guarantees ARM-compatible results if happening to compile on a non-ARM
213      target, and ensures the compiler doesn't decide to activate any
214      optimisations using the logic "value was passed to __builtin_clz, so it
215      is non-zero".
216      ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a
217      single CLZ instruction.
218    */
219   if (value == 0U)
220   {
221     return 32U;
222   }
223   return __builtin_clz(value);
224 }
225
226 /**
227   \brief   LDR Exclusive (8 bit)
228   \details Executes a exclusive LDR instruction for 8 bit value.
229   \param [in]    ptr  Pointer to data
230   \return             value of type uint8_t at (*ptr)
231  */
232 #define __LDREXB        (uint8_t)__builtin_arm_ldrex
233
234
235 /**
236   \brief   LDR Exclusive (16 bit)
237   \details Executes a exclusive LDR instruction for 16 bit values.
238   \param [in]    ptr  Pointer to data
239   \return        value of type uint16_t at (*ptr)
240  */
241 #define __LDREXH        (uint16_t)__builtin_arm_ldrex
242
243 /**
244   \brief   LDR Exclusive (32 bit)
245   \details Executes a exclusive LDR instruction for 32 bit values.
246   \param [in]    ptr  Pointer to data
247   \return        value of type uint32_t at (*ptr)
248  */
249 #define __LDREXW        (uint32_t)__builtin_arm_ldrex
250
251 /**
252   \brief   STR Exclusive (8 bit)
253   \details Executes a exclusive STR instruction for 8 bit values.
254   \param [in]  value  Value to store
255   \param [in]    ptr  Pointer to location
256   \return          0  Function succeeded
257   \return          1  Function failed
258  */
259 #define __STREXB        (uint32_t)__builtin_arm_strex
260
261 /**
262   \brief   STR Exclusive (16 bit)
263   \details Executes a exclusive STR instruction for 16 bit values.
264   \param [in]  value  Value to store
265   \param [in]    ptr  Pointer to location
266   \return          0  Function succeeded
267   \return          1  Function failed
268  */
269 #define __STREXH        (uint32_t)__builtin_arm_strex
270
271 /**
272   \brief   STR Exclusive (32 bit)
273   \details Executes a exclusive STR instruction for 32 bit values.
274   \param [in]  value  Value to store
275   \param [in]    ptr  Pointer to location
276   \return          0  Function succeeded
277   \return          1  Function failed
278  */
279 #define __STREXW        (uint32_t)__builtin_arm_strex
280
281 /**
282   \brief   Remove the exclusive lock
283   \details Removes the exclusive lock which is created by LDREX.
284  */
285 #define __CLREX             __builtin_arm_clrex
286
287 /**
288   \brief   Signed Saturate
289   \details Saturates a signed value.
290   \param [in]  value  Value to be saturated
291   \param [in]    sat  Bit position to saturate to (1..32)
292   \return             Saturated value
293  */
294 #define __SSAT             __builtin_arm_ssat
295
296 /**
297   \brief   Unsigned Saturate
298   \details Saturates an unsigned value.
299   \param [in]  value  Value to be saturated
300   \param [in]    sat  Bit position to saturate to (0..31)
301   \return             Saturated value
302  */
303 #define __USAT             __builtin_arm_usat
304
305 /* ###################  Compiler specific Intrinsics  ########################### */
306 /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
307   Access to dedicated SIMD instructions
308   @{
309 */
310
311 #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1))
312
313 #define     __SADD8                 __builtin_arm_sadd8
314 #define     __SADD16                __builtin_arm_sadd16
315 #define     __QADD8                 __builtin_arm_qadd8
316 #define     __QSUB8                 __builtin_arm_qsub8
317 #define     __QADD16                __builtin_arm_qadd16
318 #define     __SHADD16               __builtin_arm_shadd16
319 #define     __QSUB16                __builtin_arm_qsub16
320 #define     __SHSUB16               __builtin_arm_shsub16
321 #define     __QASX                  __builtin_arm_qasx
322 #define     __SHASX                 __builtin_arm_shasx
323 #define     __QSAX                  __builtin_arm_qsax
324 #define     __SHSAX                 __builtin_arm_shsax
325 #define     __SXTB16                __builtin_arm_sxtb16
326 #define     __SMUAD                 __builtin_arm_smuad
327 #define     __SMUADX                __builtin_arm_smuadx
328 #define     __SMLAD                 __builtin_arm_smlad
329 #define     __SMLADX                __builtin_arm_smladx
330 #define     __SMLALD                __builtin_arm_smlald
331 #define     __SMLALDX               __builtin_arm_smlaldx
332 #define     __SMUSD                 __builtin_arm_smusd
333 #define     __SMUSDX                __builtin_arm_smusdx
334 #define     __SMLSDX                __builtin_arm_smlsdx
335 #define     __USAT16                __builtin_arm_usat16
336 #define     __SSUB8                 __builtin_arm_ssub8
337 #define     __SXTB16                __builtin_arm_sxtb16
338 #define     __SXTAB16               __builtin_arm_sxtab16
339
340
341 __STATIC_FORCEINLINE  int32_t __QADD( int32_t op1,  int32_t op2)
342 {
343   int32_t result;
344
345   __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
346   return(result);
347 }
348
349 __STATIC_FORCEINLINE  int32_t __QSUB( int32_t op1,  int32_t op2)
350 {
351   int32_t result;
352
353   __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
354   return(result);
355 }
356
357 #define __PKHBT(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0x0000FFFFUL) |  \
358                                            ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)  )
359
360 #define __PKHTB(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0xFFFF0000UL) |  \
361                                            ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)  )
362
363 __STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
364 {
365   int32_t result;
366
367   __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r"  (op1), "r" (op2), "r" (op3) );
368   return(result);
369 }
370
371 #endif /* (__ARM_FEATURE_DSP == 1) */
372
373 /* ###########################  Core Function Access  ########################### */
374
375 /**
376   \brief   Get FPSCR
377   \details Returns the current value of the Floating Point Status/Control register.
378   \return               Floating Point Status/Control register value
379  */
380 #define __get_FPSCR      __builtin_arm_get_fpscr
381
382 /**
383   \brief   Set FPSCR
384   \details Assigns the given value to the Floating Point Status/Control register.
385   \param [in]    fpscr  Floating Point Status/Control value to set
386  */
387 #define __set_FPSCR      __builtin_arm_set_fpscr
388
389 /** \brief  Get CPSR Register
390     \return               CPSR Register value
391  */
392 __STATIC_FORCEINLINE uint32_t __get_CPSR(void)
393 {
394   uint32_t result;
395   __ASM volatile("MRS %0, cpsr" : "=r" (result) );
396   return(result);
397 }
398
399 /** \brief  Set CPSR Register
400     \param [in]    cpsr  CPSR value to set
401  */
402 __STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr)
403 {
404 __ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "cc", "memory");
405 }
406
407 /** \brief  Get Mode
408     \return                Processor Mode
409  */
410 __STATIC_FORCEINLINE uint32_t __get_mode(void)
411 {
412         return (__get_CPSR() & 0x1FU);
413 }
414
415 /** \brief  Set Mode
416     \param [in]    mode  Mode value to set
417  */
418 __STATIC_FORCEINLINE void __set_mode(uint32_t mode)
419 {
420   __ASM volatile("MSR  cpsr_c, %0" : : "r" (mode) : "memory");
421 }
422
423 /** \brief  Get Stack Pointer
424     \return Stack Pointer value
425  */
426 __STATIC_FORCEINLINE uint32_t __get_SP()
427 {
428   uint32_t result;
429   __ASM volatile("MOV  %0, sp" : "=r" (result) : : "memory");
430   return result;
431 }
432
433 /** \brief  Set Stack Pointer
434     \param [in]    stack  Stack Pointer value to set
435  */
436 __STATIC_FORCEINLINE void __set_SP(uint32_t stack)
437 {
438   __ASM volatile("MOV  sp, %0" : : "r" (stack) : "memory");
439 }
440
441 /** \brief  Get USR/SYS Stack Pointer
442     \return USR/SYS Stack Pointer value
443  */
444 __STATIC_FORCEINLINE uint32_t __get_SP_usr()
445 {
446   uint32_t cpsr;
447   uint32_t result;
448   __ASM volatile(
449     "MRS     %0, cpsr   \n"
450     "CPS     #0x1F      \n" // no effect in USR mode
451     "MOV     %1, sp     \n"
452     "MSR     cpsr_c, %0 \n" // no effect in USR mode
453     "ISB" :  "=r"(cpsr), "=r"(result) : : "memory"
454    );
455   return result;
456 }
457
458 /** \brief  Set USR/SYS Stack Pointer
459     \param [in]    topOfProcStack  USR/SYS Stack Pointer value to set
460  */
461 __STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack)
462 {
463   uint32_t cpsr;
464   __ASM volatile(
465     "MRS     %0, cpsr   \n"
466     "CPS     #0x1F      \n" // no effect in USR mode
467     "MOV     sp, %1     \n"
468     "MSR     cpsr_c, %0 \n" // no effect in USR mode
469     "ISB" : "=r"(cpsr) : "r" (topOfProcStack) : "memory"
470    );
471 }
472
473 /** \brief  Get FPEXC
474     \return               Floating Point Exception Control register value
475  */
476 __STATIC_FORCEINLINE uint32_t __get_FPEXC(void)
477 {
478 #if (__FPU_PRESENT == 1)
479   uint32_t result;
480   __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory");
481   return(result);
482 #else
483   return(0);
484 #endif
485 }
486
487 /** \brief  Set FPEXC
488     \param [in]    fpexc  Floating Point Exception Control value to set
489  */
490 __STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc)
491 {
492 #if (__FPU_PRESENT == 1)
493   __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory");
494 #endif
495 }
496
497 /*
498  * Include common core functions to access Coprocessor 15 registers
499  */
500
501 #define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
502 #define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
503 #define __get_CP64(cp, op1, Rt, CRm)         __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : "=r" (Rt) : : "memory" )
504 #define __set_CP64(cp, op1, Rt, CRm)         __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : : "r" (Rt) : "memory" )
505
506 #include "cmsis_cp15.h"
507
508 /** \brief  Enable Floating Point Unit
509
510   Critical section, called from undef handler, so systick is disabled
511  */
512 __STATIC_INLINE void __FPU_Enable(void)
513 {
514   __ASM volatile(
515     //Permit access to VFP/NEON, registers by modifying CPACR
516     "        MRC     p15,0,R1,c1,c0,2  \n"
517     "        ORR     R1,R1,#0x00F00000 \n"
518     "        MCR     p15,0,R1,c1,c0,2  \n"
519
520     //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
521     "        ISB                       \n"
522
523     //Enable VFP/NEON
524     "        VMRS    R1,FPEXC          \n"
525     "        ORR     R1,R1,#0x40000000 \n"
526     "        VMSR    FPEXC,R1          \n"
527
528     //Initialise VFP/NEON registers to 0
529     "        MOV     R2,#0             \n"
530
531     //Initialise D16 registers to 0
532     "        VMOV    D0, R2,R2         \n"
533     "        VMOV    D1, R2,R2         \n"
534     "        VMOV    D2, R2,R2         \n"
535     "        VMOV    D3, R2,R2         \n"
536     "        VMOV    D4, R2,R2         \n"
537     "        VMOV    D5, R2,R2         \n"
538     "        VMOV    D6, R2,R2         \n"
539     "        VMOV    D7, R2,R2         \n"
540     "        VMOV    D8, R2,R2         \n"
541     "        VMOV    D9, R2,R2         \n"
542     "        VMOV    D10,R2,R2         \n"
543     "        VMOV    D11,R2,R2         \n"
544     "        VMOV    D12,R2,R2         \n"
545     "        VMOV    D13,R2,R2         \n"
546     "        VMOV    D14,R2,R2         \n"
547     "        VMOV    D15,R2,R2         \n"
548
549 #if __ARM_NEON == 1
550     //Initialise D32 registers to 0
551     "        VMOV    D16,R2,R2         \n"
552     "        VMOV    D17,R2,R2         \n"
553     "        VMOV    D18,R2,R2         \n"
554     "        VMOV    D19,R2,R2         \n"
555     "        VMOV    D20,R2,R2         \n"
556     "        VMOV    D21,R2,R2         \n"
557     "        VMOV    D22,R2,R2         \n"
558     "        VMOV    D23,R2,R2         \n"
559     "        VMOV    D24,R2,R2         \n"
560     "        VMOV    D25,R2,R2         \n"
561     "        VMOV    D26,R2,R2         \n"
562     "        VMOV    D27,R2,R2         \n"
563     "        VMOV    D28,R2,R2         \n"
564     "        VMOV    D29,R2,R2         \n"
565     "        VMOV    D30,R2,R2         \n"
566     "        VMOV    D31,R2,R2         \n"
567 #endif
568
569     //Initialise FPSCR to a known state
570     "        VMRS    R1,FPSCR          \n"
571     "        LDR     R2,=0x00086060    \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
572     "        AND     R1,R1,R2          \n"
573     "        VMSR    FPSCR,R1            "
574     : : : "cc", "r1", "r2"
575   );
576 }
577
578 #endif /* __CMSIS_ARMCLANG_H */