]> begriffs open source - cmsis/blob - CMSIS/Core/Include/cmsis_compiler.h
Issue #164: Added workaround for missing __CLZ intrinsic on ARMv6 in IAR compilers...
[cmsis] / CMSIS / Core / Include / cmsis_compiler.h
1 /**************************************************************************//**
2  * @file     cmsis_compiler.h
3  * @brief    CMSIS compiler generic header file
4  * @version  V5.0.2
5  * @date     13. February 2017
6  ******************************************************************************/
7 /*
8  * Copyright (c) 2009-2017 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_COMPILER_H
26 #define __CMSIS_COMPILER_H
27
28 #include <stdint.h>
29
30 /*
31  * ARM Compiler 4/5
32  */
33 #if   defined ( __CC_ARM )
34   #include "cmsis_armcc.h"
35
36
37 /*
38  * ARM Compiler 6 (armclang)
39  */
40 #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
41   #include "cmsis_armclang.h"
42
43
44 /*
45  * GNU Compiler
46  */
47 #elif defined ( __GNUC__ )
48   #include "cmsis_gcc.h"
49
50
51 /*
52  * IAR Compiler
53  */
54 #elif defined ( __ICCARM__ )
55
56   #ifndef   __ASM
57     #define __ASM                                  __asm
58   #endif
59   #ifndef   __INLINE
60     #define __INLINE                               inline
61   #endif
62   #ifndef   __STATIC_INLINE
63     #define __STATIC_INLINE                        static inline
64   #endif
65
66   #include <cmsis_iar.h>
67
68   #ifndef   __NO_RETURN
69     #define __NO_RETURN                            __noreturn
70   #endif
71   #ifndef   __USED
72     #define __USED                                 __root
73   #endif
74   #ifndef   __WEAK
75     #define __WEAK                                 __weak
76   #endif
77   #ifndef   __PACKED
78     #define __PACKED                               __packed
79   #endif
80   #ifndef   __PACKED_STRUCT
81     #define __PACKED_STRUCT                        __packed struct
82   #endif
83   #ifndef   __UNALIGNED_UINT32        /* deprecated */
84     __packed struct T_UINT32 { uint32_t v; };
85     #define __UNALIGNED_UINT32(x)                  (((struct T_UINT32 *)(x))->v)
86   #endif
87   #ifndef   __UNALIGNED_UINT16_WRITE
88     __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
89     #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
90   #endif
91   #ifndef   __UNALIGNED_UINT16_READ
92     __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
93     #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v)
94   #endif
95   #ifndef   __UNALIGNED_UINT32_WRITE
96     __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
97     #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
98   #endif
99   #ifndef   __UNALIGNED_UINT32_READ
100     __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
101     #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v)
102   #endif
103   #ifndef   __ALIGNED
104     #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
105     #define __ALIGNED(x)
106   #endif
107
108   // Workaround for missing __CLZ intrinsic in
109   // IAR compilers prior 8.0
110   #if (__CORE__ == __ARM6M__) && (__VER__ < 8000000)
111     __STATIC_INLINE uint32_t __CLZ(uint32_t data)
112     {
113       if (data == 0u) { return 32u; }
114       
115       uint32_t count = 0;
116       uint32_t mask = 0x80000000;
117       
118       while ((data & mask) == 0)
119       {
120         count += 1u;
121         mask = mask >> 1u;
122       }
123       
124       return (count);
125     }
126   #endif
127
128
129 /*
130  * TI ARM Compiler
131  */
132 #elif defined ( __TI_ARM__ )
133   #include <cmsis_ccs.h>
134
135   #ifndef   __ASM
136     #define __ASM                                  __asm
137   #endif
138   #ifndef   __INLINE
139     #define __INLINE                               inline
140   #endif
141   #ifndef   __STATIC_INLINE
142     #define __STATIC_INLINE                        static inline
143   #endif
144   #ifndef   __NO_RETURN
145     #define __NO_RETURN                            __attribute__((noreturn))
146   #endif
147   #ifndef   __USED
148     #define __USED                                 __attribute__((used))
149   #endif
150   #ifndef   __WEAK
151     #define __WEAK                                 __attribute__((weak))
152   #endif
153   #ifndef   __PACKED
154     #define __PACKED                               __attribute__((packed))
155   #endif
156   #ifndef   __PACKED_STRUCT
157     #define __PACKED_STRUCT                        struct __attribute__((packed))
158   #endif
159   #ifndef   __UNALIGNED_UINT32        /* deprecated */
160     struct __attribute__((packed)) T_UINT32 { uint32_t v; };
161     #define __UNALIGNED_UINT32(x)                  (((struct T_UINT32 *)(x))->v)
162   #endif
163   #ifndef   __UNALIGNED_UINT16_WRITE
164     __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
165     #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
166   #endif
167   #ifndef   __UNALIGNED_UINT16_READ
168     __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
169     #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v)
170   #endif
171   #ifndef   __UNALIGNED_UINT32_WRITE
172     __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
173     #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
174   #endif
175   #ifndef   __UNALIGNED_UINT32_READ
176     __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
177     #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v)
178   #endif
179   #ifndef   __ALIGNED
180     #define __ALIGNED(x)                           __attribute__((aligned(x)))
181   #endif
182
183
184 /*
185  * TASKING Compiler
186  */
187 #elif defined ( __TASKING__ )
188   /*
189    * The CMSIS functions have been implemented as intrinsics in the compiler.
190    * Please use "carm -?i" to get an up to date list of all intrinsics,
191    * Including the CMSIS ones.
192    */
193
194   #ifndef   __ASM
195     #define __ASM                                  __asm
196   #endif
197   #ifndef   __INLINE
198     #define __INLINE                               inline
199   #endif
200   #ifndef   __STATIC_INLINE
201     #define __STATIC_INLINE                        static inline
202   #endif
203   #ifndef   __NO_RETURN
204     #define __NO_RETURN                            __attribute__((noreturn))
205   #endif
206   #ifndef   __USED
207     #define __USED                                 __attribute__((used))
208   #endif
209   #ifndef   __WEAK
210     #define __WEAK                                 __attribute__((weak))
211   #endif
212   #ifndef   __PACKED
213     #define __PACKED                               __packed__
214   #endif
215   #ifndef   __PACKED_STRUCT
216     #define __PACKED_STRUCT                        struct __packed__
217   #endif
218   #ifndef   __UNALIGNED_UINT32        /* deprecated */
219     struct __packed__ T_UINT32 { uint32_t v; };
220     #define __UNALIGNED_UINT32(x)                  (((struct T_UINT32 *)(x))->v)
221   #endif
222   #ifndef   __UNALIGNED_UINT16_WRITE
223     __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
224     #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
225   #endif
226   #ifndef   __UNALIGNED_UINT16_READ
227     __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
228     #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v)
229   #endif
230   #ifndef   __UNALIGNED_UINT32_WRITE
231     __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
232     #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
233   #endif
234   #ifndef   __UNALIGNED_UINT32_READ
235     __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
236     #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v)
237   #endif
238   #ifndef   __ALIGNED
239     #define __ALIGNED(x)              __align(x)
240   #endif
241
242
243 /*
244  * COSMIC Compiler
245  */
246 #elif defined ( __CSMC__ )
247    #include <cmsis_csm.h>
248
249  #ifndef   __ASM
250     #define __ASM                                  _asm
251   #endif
252   #ifndef   __INLINE
253     #define __INLINE                               inline
254   #endif
255   #ifndef   __STATIC_INLINE
256     #define __STATIC_INLINE                        static inline
257   #endif
258   #ifndef   __NO_RETURN
259     // NO RETURN is automatically detected hence no warning here
260     #define __NO_RETURN
261   #endif
262   #ifndef   __USED
263     #warning No compiler specific solution for __USED. __USED is ignored.
264     #define __USED
265   #endif
266   #ifndef   __WEAK
267     #define __WEAK                                 __weak
268   #endif
269   #ifndef   __PACKED
270     #define __PACKED                               @packed
271   #endif
272   #ifndef   __PACKED_STRUCT
273     #define __PACKED_STRUCT                        @packed struct
274   #endif
275   #ifndef   __UNALIGNED_UINT32        /* deprecated */
276     @packed struct T_UINT32 { uint32_t v; };
277     #define __UNALIGNED_UINT32(x)                  (((struct T_UINT32 *)(x))->v)
278   #endif
279   #ifndef   __UNALIGNED_UINT16_WRITE
280     __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
281     #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
282   #endif
283   #ifndef   __UNALIGNED_UINT16_READ
284     __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
285     #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v)
286   #endif
287   #ifndef   __UNALIGNED_UINT32_WRITE
288     __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
289     #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
290   #endif
291   #ifndef   __UNALIGNED_UINT32_READ
292     __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
293     #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v)
294   #endif
295   #ifndef   __ALIGNED
296     #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
297     #define __ALIGNED(x)
298   #endif
299
300
301 #else
302   #error Unknown compiler.
303 #endif
304
305
306 #endif /* __CMSIS_COMPILER_H */
307