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