• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2019 Nuclei Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #ifndef __NMSIS_GCC_H__
20 #define __NMSIS_GCC_H__
21 /*!
22  * @file     nmsis_gcc.h
23  * @brief    NMSIS compiler GCC header file
24  */
25 #include <stdint.h>
26 #include "riscv_encoding.h"
27 
28 #ifdef __cplusplus
29  extern "C" {
30 #endif
31 
32 /* #########################  Startup and Lowlevel Init  ######################## */
33 /**
34  * \defgroup NMSIS_Core_CompilerControl    Compiler Control
35  * \ingroup  NMSIS_Core
36  * \brief    Compiler agnostic \#define symbols for generic c/c++ source code
37  * \details
38  *
39  * The NMSIS-Core provides the header file <b>nmsis_compiler.h</b> with consistent \#define symbols for generate C or C++ source files that should be compiler agnostic.
40  * Each NMSIS compliant compiler should support the functionality described in this section.
41  *
42  * The header file <b>nmsis_compiler.h</b> is also included by each Device Header File <device.h> so that these definitions are available.
43  *   @{
44  */
45 /* ignore some GCC warnings */
46 #pragma GCC diagnostic push
47 #pragma GCC diagnostic ignored "-Wsign-conversion"
48 #pragma GCC diagnostic ignored "-Wconversion"
49 #pragma GCC diagnostic ignored "-Wunused-parameter"
50 
51 /* Fallback for __has_builtin */
52 #ifndef __has_builtin
53   #define __has_builtin(x) (0)
54 #endif
55 
56 /* NMSIS compiler specific defines */
57 /** \brief Pass information from the compiler to the assembler. */
58 #ifndef   __ASM
59   #define __ASM                                  __asm
60 #endif
61 
62 /** \brief Recommend that function should be inlined by the compiler. */
63 #ifndef   __INLINE
64   #define __INLINE                               inline
65 #endif
66 
67 /** \brief Define a static function that may be inlined by the compiler. */
68 #ifndef   __STATIC_INLINE
69   #define __STATIC_INLINE                        static inline
70 #endif
71 
72 /** \brief Define a static function that should be always inlined by the compiler. */
73 #ifndef   __STATIC_FORCEINLINE
74   #define __STATIC_FORCEINLINE                   __attribute__((always_inline)) static inline
75 #endif
76 
77 /** \brief Inform the compiler that a function does not return. */
78 #ifndef   __NO_RETURN
79   #define __NO_RETURN                            __attribute__((__noreturn__))
80 #endif
81 
82 /** \brief Inform that a variable shall be retained in executable image. */
83 #ifndef   __USED
84   #define __USED                                 __attribute__((used))
85 #endif
86 
87 /** \brief restrict pointer qualifier to enable additional optimizations. */
88 #ifndef   __WEAK
89   #define __WEAK                                 __attribute__((weak))
90 #endif
91 
92 /** \brief specified the vector size of the variable, measured in bytes */
93 #ifndef   __VECTOR_SIZE
94   #define __VECTOR_SIZE(x)                       __attribute__((vector_size(x)))
95 #endif
96 
97 /** \brief Request smallest possible alignment. */
98 #ifndef   __PACKED
99   #define __PACKED                               __attribute__((packed, aligned(1)))
100 #endif
101 
102 /** \brief Request smallest possible alignment for a structure. */
103 #ifndef   __PACKED_STRUCT
104   #define __PACKED_STRUCT                        struct __attribute__((packed, aligned(1)))
105 #endif
106 
107 /** \brief Request smallest possible alignment for a union. */
108 #ifndef   __PACKED_UNION
109   #define __PACKED_UNION                         union __attribute__((packed, aligned(1)))
110 #endif
111 
112 #ifndef   __UNALIGNED_UINT16_WRITE
113   #pragma GCC diagnostic push
114   #pragma GCC diagnostic ignored "-Wpacked"
115   #pragma GCC diagnostic ignored "-Wattributes"
116   /** \brief Packed struct for unaligned uint16_t write access */
117   __PACKED_STRUCT T_UINT16_WRITE {
118       uint16_t v;
119   };
120   #pragma GCC diagnostic pop
121   /** \brief Pointer for unaligned write of a uint16_t variable. */
122   #define __UNALIGNED_UINT16_WRITE(addr, val)    (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
123 #endif
124 
125 #ifndef   __UNALIGNED_UINT16_READ
126   #pragma GCC diagnostic push
127   #pragma GCC diagnostic ignored "-Wpacked"
128   #pragma GCC diagnostic ignored "-Wattributes"
129   /** \brief Packed struct for unaligned uint16_t read access */
130   __PACKED_STRUCT T_UINT16_READ {
131       uint16_t v;
132   };
133   #pragma GCC diagnostic pop
134   /** \brief Pointer for unaligned read of a uint16_t variable. */
135   #define __UNALIGNED_UINT16_READ(addr)          (((const struct T_UINT16_READ *)(const void *)(addr))->v)
136 #endif
137 
138 #ifndef   __UNALIGNED_UINT32_WRITE
139   #pragma GCC diagnostic push
140   #pragma GCC diagnostic ignored "-Wpacked"
141   #pragma GCC diagnostic ignored "-Wattributes"
142   /** \brief Packed struct for unaligned uint32_t write access */
143   __PACKED_STRUCT T_UINT32_WRITE {
144       uint32_t v;
145   };
146   #pragma GCC diagnostic pop
147   /** \brief Pointer for unaligned write of a uint32_t variable. */
148   #define __UNALIGNED_UINT32_WRITE(addr, val)    (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
149 #endif
150 
151 #ifndef   __UNALIGNED_UINT32_READ
152   #pragma GCC diagnostic push
153   #pragma GCC diagnostic ignored "-Wpacked"
154   #pragma GCC diagnostic ignored "-Wattributes"
155   /** \brief Packed struct for unaligned uint32_t read access */
156   __PACKED_STRUCT T_UINT32_READ {
157       uint32_t v;
158   };
159   #pragma GCC diagnostic pop
160   /** \brief Pointer for unaligned read of a uint32_t variable. */
161   #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v)
162 #endif
163 
164 /** \brief Minimum `x` bytes alignment for a variable. */
165 #ifndef   __ALIGNED
166   #define __ALIGNED(x)                           __attribute__((aligned(x)))
167 #endif
168 
169 /** \brief restrict pointer qualifier to enable additional optimizations. */
170 #ifndef   __RESTRICT
171   #define __RESTRICT                             __restrict
172 #endif
173 
174 /** \brief Barrier to prevent compiler from reordering instructions. */
175 #ifndef   __COMPILER_BARRIER
176   #define __COMPILER_BARRIER()                   __ASM volatile("":::"memory")
177 #endif
178 
179 /** \brief provide the compiler with branch prediction information, the branch is usually true */
180 #ifndef   __USUALLY
181   #define __USUALLY(exp)                         __builtin_expect((exp), 1)
182 #endif
183 
184 /** \brief provide the compiler with branch prediction information, the branch is rarely true */
185 #ifndef   __RARELY
186   #define __RARELY(exp)                          __builtin_expect((exp), 0)
187 #endif
188 
189 /** \brief Use this attribute to indicate that the specified function is an interrupt handler. */
190 #ifndef   __INTERRUPT
191   #define __INTERRUPT                            __attribute__((interrupt))
192 #endif
193 
194 /** @} */ /* End of Doxygen Group NMSIS_Core_CompilerControl */
195 
196 /* IO definitions (access restrictions to peripheral registers) */
197 /**
198  * \defgroup NMSIS_Core_PeriphAccess     Peripheral Access
199  * \brief  Naming conventions and optional features for accessing peripherals.
200  *
201  * The section below describes the naming conventions, requirements, and optional features
202  * for accessing device specific peripherals.
203  * Most of the rules also apply to the core peripherals.
204  *
205  * The **Device Header File <device.h>** contains typically these definition
206  * and also includes the core specific header files.
207  *
208  * @{
209  */
210 /** \brief Defines 'read only' permissions */
211 #ifdef __cplusplus
212   #define   __I     volatile
213 #else
214   #define   __I     volatile const
215 #endif
216 /** \brief Defines 'write only' permissions */
217 #define     __O     volatile
218 /** \brief Defines 'read / write' permissions */
219 #define     __IO    volatile
220 
221 /* following defines should be used for structure members */
222 /** \brief Defines 'read only' structure member permissions */
223 #define     __IM     volatile const
224 /** \brief Defines 'write only' structure member permissions */
225 #define     __OM     volatile
226 /** \brief Defines 'read/write' structure member permissions */
227 #define     __IOM    volatile
228 
229 /**
230  * \brief   Mask and shift a bit field value for use in a register bit range.
231  * \details The macro \ref _VAL2FLD uses the #define's _Pos and _Msk of the related bit
232  * field to shift bit-field values for assigning to a register.
233  *
234  * **Example**:
235  * \code
236  * ECLIC->CFG = _VAL2FLD(CLIC_CLICCFG_NLBIT, 3);
237  * \endcode
238  * \param[in] field  Name of the register bit field.
239  * \param[in] value  Value of the bit field. This parameter is interpreted as an uint32_t type.
240  * \return           Masked and shifted value.
241  */
242 #define _VAL2FLD(field, value)    (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
243 
244 /**
245  * \brief   Mask and shift a register value to extract a bit filed value.
246  * \details The macro \ref _FLD2VAL uses the #define's _Pos and _Msk of the related bit
247  * field to extract the value of a bit field from a register.
248  *
249  * **Example**:
250  * \code
251  * nlbits = _FLD2VAL(CLIC_CLICCFG_NLBIT, ECLIC->CFG);
252  * \endcode
253  * \param[in] field  Name of the register bit field.
254  * \param[in] value  Value of register. This parameter is interpreted as an uint32_t type.
255  * \return           Masked and shifted bit field value.
256  */
257 #define _FLD2VAL(field, value)    (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
258 
259 /** @} */ /* end of group NMSIS_Core_PeriphAccess */
260 
261 
262 #ifdef __cplusplus
263 }
264 #endif
265 #endif /* __NMSIS_GCC_H__ */
266