1 /**************************************************************************//**
2 * @file cmsis_armclang.h
3 * @brief CMSIS compiler armclang (Arm Compiler 6) header file
6 ******************************************************************************/
8 * Copyright (c) 2009-2023 Arm Limited. All rights reserved.
10 * SPDX-License-Identifier: Apache-2.0
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
16 * www.apache.org/licenses/LICENSE-2.0
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.
25 #ifndef __CMSIS_ARMCLANG_H
26 #define __CMSIS_ARMCLANG_H
28 #pragma clang system_header /* treat file as system include file */
30 #if (__ARM_ACLE >= 200)
33 #error Compiler must support ACLE V2.0
34 #endif /* (__ARM_ACLE >= 200) */
36 /* CMSIS compiler specific defines */
41 #define __INLINE inline
43 #ifndef __STATIC_INLINE
44 #define __STATIC_INLINE static inline
46 #ifndef __STATIC_FORCEINLINE
47 #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
50 #define __NO_RETURN __attribute__((__noreturn__))
52 #ifndef CMSIS_DEPRECATED
53 #define CMSIS_DEPRECATED __attribute__((deprecated))
56 #define __USED __attribute__((used))
59 #define __WEAK __attribute__((weak))
62 #define __PACKED __attribute__((packed, aligned(1)))
64 #ifndef __PACKED_STRUCT
65 #define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
67 #ifndef __PACKED_UNION
68 #define __PACKED_UNION union __attribute__((packed, aligned(1)))
70 #ifndef __UNALIGNED_UINT16_WRITE
71 #pragma clang diagnostic push
72 #pragma clang diagnostic ignored "-Wpacked"
73 __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
74 #pragma clang diagnostic pop
75 #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
77 #ifndef __UNALIGNED_UINT16_READ
78 #pragma clang diagnostic push
79 #pragma clang diagnostic ignored "-Wpacked"
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)
84 #ifndef __UNALIGNED_UINT32_WRITE
85 #pragma clang diagnostic push
86 #pragma clang diagnostic ignored "-Wpacked"
87 __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
88 #pragma clang diagnostic pop
89 #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
91 #ifndef __UNALIGNED_UINT32_READ
92 #pragma clang diagnostic push
93 #pragma clang diagnostic ignored "-Wpacked"
94 __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
95 #pragma clang diagnostic pop
96 #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
99 #define __ALIGNED(x) __attribute__((aligned(x)))
102 #define __RESTRICT __restrict
104 #ifndef __COMPILER_BARRIER
105 #define __COMPILER_BARRIER() __ASM volatile("":::"memory")
108 #define __NO_INIT __attribute__ ((section (".bss.noinit")))
111 #define __ALIAS(x) __attribute__ ((alias(x)))
114 /* ########################## Core Instruction Access ######################### */
115 /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
116 Access to dedicated instructions
120 /* Define macros for porting to both thumb1 and thumb2.
121 * For thumb1, use low register (r0-r7), specified by constraint "l"
122 * Otherwise, use general registers, specified by constraint "r" */
123 #if defined (__thumb__) && !defined (__thumb2__)
124 #define __CMSIS_GCC_OUT_REG(r) "=l" (r)
125 #define __CMSIS_GCC_RW_REG(r) "+l" (r)
126 #define __CMSIS_GCC_USE_REG(r) "l" (r)
128 #define __CMSIS_GCC_OUT_REG(r) "=r" (r)
129 #define __CMSIS_GCC_RW_REG(r) "+r" (r)
130 #define __CMSIS_GCC_USE_REG(r) "r" (r)
135 \details No Operation does nothing. This instruction can be used for code alignment purposes.
137 #define __NOP() __nop()
141 \brief Wait For Interrupt
142 \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
144 #define __WFI() __wfi()
148 \brief Wait For Event
149 \details Wait For Event is a hint instruction that permits the processor to enter
150 a low-power state until one of a number of events occurs.
152 #define __WFE() __wfe()
157 \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
159 #define __SEV() __sev()
163 \brief Instruction Synchronization Barrier
164 \details Instruction Synchronization Barrier flushes the pipeline in the processor,
165 so that all instructions following the ISB are fetched from cache or memory,
166 after the instruction has been completed.
168 #define __ISB() __isb(0xF)
172 \brief Data Synchronization Barrier
173 \details Acts as a special kind of Data Memory Barrier.
174 It completes when all explicit memory accesses before this instruction complete.
176 #define __DSB() __dsb(0xF)
180 \brief Data Memory Barrier
181 \details Ensures the apparent order of the explicit memory operations before
182 and after the instruction, without ensuring their completion.
184 #define __DMB() __dmb(0xF)
188 \brief Reverse byte order (32 bit)
189 \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
190 \param [in] value Value to reverse
191 \return Reversed value
193 #define __REV(value) __rev(value)
197 \brief Reverse byte order (16 bit)
198 \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
199 \param [in] value Value to reverse
200 \return Reversed value
202 #define __REV16(value) __rev16(value)
206 \brief Reverse byte order (16 bit)
207 \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
208 \param [in] value Value to reverse
209 \return Reversed value
211 #define __REVSH(value) __revsh(value)
215 \brief Rotate Right in unsigned value (32 bit)
216 \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
217 \param [in] op1 Value to rotate
218 \param [in] op2 Number of Bits to rotate
219 \return Rotated value
221 #define __ROR(op1, op2) __ror(op1, op2)
226 \details Causes the processor to enter Debug state.
227 Debug tools can use this to investigate system state when the instruction at a particular address is reached.
228 \param [in] value is ignored by the processor.
229 If required, a debugger can use it to store additional information about the breakpoint.
231 #define __BKPT(value) __ASM volatile ("bkpt "#value)
235 \brief Reverse bit order of value
236 \details Reverses the bit order of the given value.
237 \param [in] value Value to reverse
238 \return Reversed value
240 #define __RBIT(value) __rbit(value)
244 \brief Count leading zeros
245 \details Counts the number of leading zeros of a data value.
246 \param [in] value Value to count the leading zeros
247 \return number of leading zeros in value
249 #define __CLZ(value) __clz(value)
252 #if ((__ARM_FEATURE_SAT >= 1) && \
253 (__ARM_ARCH_ISA_THUMB >= 2) )
254 /* __ARM_FEATURE_SAT is wrong for Armv8-M Baseline devices */
256 \brief Signed Saturate
257 \details Saturates a signed value.
258 \param [in] value Value to be saturated
259 \param [in] sat Bit position to saturate to (1..32)
260 \return Saturated value
262 #define __SSAT(value, sat) __ssat(value, sat)
266 \brief Unsigned Saturate
267 \details Saturates an unsigned value.
268 \param [in] value Value to be saturated
269 \param [in] sat Bit position to saturate to (0..31)
270 \return Saturated value
272 #define __USAT(value, sat) __usat(value, sat)
274 #else /* (__ARM_FEATURE_SAT >= 1) */
276 \brief Signed Saturate
277 \details Saturates a signed value.
278 \param [in] value Value to be saturated
279 \param [in] sat Bit position to saturate to (1..32)
280 \return Saturated value
282 __STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat)
284 if ((sat >= 1U) && (sat <= 32U))
286 const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
287 const int32_t min = -1 - max ;
302 \brief Unsigned Saturate
303 \details Saturates an unsigned value.
304 \param [in] value Value to be saturated
305 \param [in] sat Bit position to saturate to (0..31)
306 \return Saturated value
308 __STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat)
312 const uint32_t max = ((1U << sat) - 1U);
313 if (val > (int32_t)max)
322 return ((uint32_t)val);
324 #endif /* (__ARM_FEATURE_SAT >= 1) */
327 #if (__ARM_FEATURE_LDREX >= 1)
329 \brief Remove the exclusive lock
330 \details Removes the exclusive lock which is created by LDREX.
332 #define __CLREX __builtin_arm_clrex
336 \brief LDR Exclusive (8 bit)
337 \details Executes a exclusive LDR instruction for 8 bit value.
338 \param [in] ptr Pointer to data
339 \return value of type uint8_t at (*ptr)
341 #define __LDREXB (uint8_t)__builtin_arm_ldrex
345 \brief STR Exclusive (8 bit)
346 \details Executes a exclusive STR instruction for 8 bit values.
347 \param [in] value Value to store
348 \param [in] ptr Pointer to location
349 \return 0 Function succeeded
350 \return 1 Function failed
352 #define __STREXB (uint32_t)__builtin_arm_strex
353 #endif /* (__ARM_FEATURE_LDREX >= 1) */
356 #if (__ARM_FEATURE_LDREX >= 2)
358 \brief LDR Exclusive (16 bit)
359 \details Executes a exclusive LDR instruction for 16 bit values.
360 \param [in] ptr Pointer to data
361 \return value of type uint16_t at (*ptr)
363 #define __LDREXH (uint16_t)__builtin_arm_ldrex
367 \brief STR Exclusive (16 bit)
368 \details Executes a exclusive STR instruction for 16 bit values.
369 \param [in] value Value to store
370 \param [in] ptr Pointer to location
371 \return 0 Function succeeded
372 \return 1 Function failed
374 #define __STREXH (uint32_t)__builtin_arm_strex
375 #endif /* (__ARM_FEATURE_LDREX >= 2) */
378 #if (__ARM_FEATURE_LDREX >= 4)
380 \brief LDR Exclusive (32 bit)
381 \details Executes a exclusive LDR instruction for 32 bit values.
382 \param [in] ptr Pointer to data
383 \return value of type uint32_t at (*ptr)
385 #define __LDREXW (uint32_t)__builtin_arm_ldrex
389 \brief STR Exclusive (32 bit)
390 \details Executes a exclusive STR instruction for 32 bit values.
391 \param [in] value Value to store
392 \param [in] ptr Pointer to location
393 \return 0 Function succeeded
394 \return 1 Function failed
396 #define __STREXW (uint32_t)__builtin_arm_strex
397 #endif /* (__ARM_FEATURE_LDREX >= 4) */
400 #if (__ARM_ARCH_ISA_THUMB >= 2)
402 \brief Rotate Right with Extend (32 bit)
403 \details Moves each bit of a bitstring right by one bit.
404 The carry input is shifted in at the left end of the bitstring.
405 \param [in] value Value to rotate
406 \return Rotated value
408 __STATIC_FORCEINLINE uint32_t __RRX(uint32_t value)
412 __ASM volatile ("rrx %0, %1" : "=r" (result) : "r" (value));
418 \brief LDRT Unprivileged (8 bit)
419 \details Executes a Unprivileged LDRT instruction for 8 bit value.
420 \param [in] ptr Pointer to data
421 \return value of type uint8_t at (*ptr)
423 __STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr)
427 __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );
428 return ((uint8_t)result); /* Add explicit type cast here */
433 \brief LDRT Unprivileged (16 bit)
434 \details Executes a Unprivileged LDRT instruction for 16 bit values.
435 \param [in] ptr Pointer to data
436 \return value of type uint16_t at (*ptr)
438 __STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr)
442 __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );
443 return ((uint16_t)result); /* Add explicit type cast here */
448 \brief LDRT Unprivileged (32 bit)
449 \details Executes a Unprivileged LDRT instruction for 32 bit values.
450 \param [in] ptr Pointer to data
451 \return value of type uint32_t at (*ptr)
453 __STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr)
457 __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );
460 #endif /* (__ARM_ARCH_ISA_THUMB >= 2) */
463 #if (__ARM_ARCH >= 8)
465 \brief Load-Acquire (8 bit)
466 \details Executes a LDAB instruction for 8 bit value.
467 \param [in] ptr Pointer to data
468 \return value of type uint8_t at (*ptr)
470 __STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr)
474 __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
475 return ((uint8_t)result); /* Add explicit type cast here */
480 \brief Load-Acquire (16 bit)
481 \details Executes a LDAH instruction for 16 bit values.
482 \param [in] ptr Pointer to data
483 \return value of type uint16_t at (*ptr)
485 __STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr)
489 __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
490 return ((uint16_t)result); /* Add explicit type cast here */
495 \brief Load-Acquire (32 bit)
496 \details Executes a LDA instruction for 32 bit values.
497 \param [in] ptr Pointer to data
498 \return value of type uint32_t at (*ptr)
500 __STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr)
504 __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
510 \brief Store-Release (8 bit)
511 \details Executes a STLB instruction for 8 bit values.
512 \param [in] value Value to store
513 \param [in] ptr Pointer to location
515 __STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
517 __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
522 \brief Store-Release (16 bit)
523 \details Executes a STLH instruction for 16 bit values.
524 \param [in] value Value to store
525 \param [in] ptr Pointer to location
527 __STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
529 __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
534 \brief Store-Release (32 bit)
535 \details Executes a STL instruction for 32 bit values.
536 \param [in] value Value to store
537 \param [in] ptr Pointer to location
539 __STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr)
541 __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
546 \brief Load-Acquire Exclusive (8 bit)
547 \details Executes a LDAB exclusive instruction for 8 bit value.
548 \param [in] ptr Pointer to data
549 \return value of type uint8_t at (*ptr)
551 #define __LDAEXB (uint8_t)__builtin_arm_ldaex
555 \brief Load-Acquire Exclusive (16 bit)
556 \details Executes a LDAH exclusive instruction for 16 bit values.
557 \param [in] ptr Pointer to data
558 \return value of type uint16_t at (*ptr)
560 #define __LDAEXH (uint16_t)__builtin_arm_ldaex
564 \brief Load-Acquire Exclusive (32 bit)
565 \details Executes a LDA exclusive instruction for 32 bit values.
566 \param [in] ptr Pointer to data
567 \return value of type uint32_t at (*ptr)
569 #define __LDAEX (uint32_t)__builtin_arm_ldaex
573 \brief Store-Release Exclusive (8 bit)
574 \details Executes a STLB exclusive instruction for 8 bit values.
575 \param [in] value Value to store
576 \param [in] ptr Pointer to location
577 \return 0 Function succeeded
578 \return 1 Function failed
580 #define __STLEXB (uint32_t)__builtin_arm_stlex
584 \brief Store-Release Exclusive (16 bit)
585 \details Executes a STLH exclusive instruction for 16 bit values.
586 \param [in] value Value to store
587 \param [in] ptr Pointer to location
588 \return 0 Function succeeded
589 \return 1 Function failed
591 #define __STLEXH (uint32_t)__builtin_arm_stlex
595 \brief Store-Release Exclusive (32 bit)
596 \details Executes a STL exclusive instruction for 32 bit values.
597 \param [in] value Value to store
598 \param [in] ptr Pointer to location
599 \return 0 Function succeeded
600 \return 1 Function failed
602 #define __STLEX (uint32_t)__builtin_arm_stlex
604 #endif /* (__ARM_ARCH >= 8) */
606 /** @}*/ /* end of group CMSIS_Core_InstructionInterface */
609 /* ########################### Core Function Access ########################### */
610 /** \ingroup CMSIS_Core_FunctionInterface
611 \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
616 \brief Enable IRQ Interrupts
617 \details Enables IRQ interrupts by clearing special-purpose register PRIMASK.
618 Can only be executed in Privileged modes.
620 #ifndef __ARM_COMPAT_H
621 __STATIC_FORCEINLINE void __enable_irq(void)
623 __ASM volatile ("cpsie i" : : : "memory");
629 \brief Disable IRQ Interrupts
630 \details Disables IRQ interrupts by setting special-purpose register PRIMASK.
631 Can only be executed in Privileged modes.
633 #ifndef __ARM_COMPAT_H
634 __STATIC_FORCEINLINE void __disable_irq(void)
636 __ASM volatile ("cpsid i" : : : "memory");
640 #if (__ARM_ARCH_ISA_THUMB >= 2)
643 \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK.
644 Can only be executed in Privileged modes.
646 __STATIC_FORCEINLINE void __enable_fault_irq(void)
648 __ASM volatile ("cpsie f" : : : "memory");
654 \details Disables FIQ interrupts by setting special-purpose register FAULTMASK.
655 Can only be executed in Privileged modes.
657 __STATIC_FORCEINLINE void __disable_fault_irq(void)
659 __ASM volatile ("cpsid f" : : : "memory");
667 \details Returns the current value of the Floating Point Status/Control register.
668 \return Floating Point Status/Control register value
670 __STATIC_FORCEINLINE uint32_t __get_FPSCR(void)
672 #if (defined(__ARM_FP) && (__ARM_FP >= 1))
673 return (__builtin_arm_get_fpscr());
682 \details Assigns the given value to the Floating Point Status/Control register.
683 \param [in] fpscr Floating Point Status/Control value to set
685 __STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr)
687 #if (defined(__ARM_FP) && (__ARM_FP >= 1))
688 __builtin_arm_set_fpscr(fpscr);
694 /** @} end of CMSIS_Core_RegAccFunctions */
696 // Include the profile specific settings:
697 #if __ARM_ARCH_PROFILE == 'A'
698 #include "./a-profile/cmsis_armclang_a.h"
699 #elif __ARM_ARCH_PROFILE == 'R'
700 #include "./r-profile/cmsis_armclang_r.h"
701 #elif __ARM_ARCH_PROFILE == 'M'
702 #include "./m-profile/cmsis_armclang_m.h"
704 #error "Unknown Arm architecture profile"
707 #endif /* __CMSIS_ARMCLANG_H */