nmsis_gcc.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. #ifndef __NMSIS_GCC_H__
  19. #define __NMSIS_GCC_H__
  20. /*!
  21. * @file nmsis_gcc.h
  22. * @brief NMSIS compiler GCC header file
  23. */
  24. #include <stdint.h>
  25. #ifdef __cplusplus
  26. extern "C" {
  27. #endif
  28. #include "riscv_encoding.h"
  29. /* ######################### Startup and Lowlevel Init ######################## */
  30. /**
  31. * \defgroup NMSIS_Core_CompilerControl Compiler Control
  32. * \ingroup NMSIS_Core
  33. * \brief Compiler agnostic \#define symbols for generic c/c++ source code
  34. * \details
  35. *
  36. * 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.
  37. * Each NMSIS compliant compiler should support the functionality described in this section.
  38. *
  39. * The header file <b>nmsis_compiler.h</b> is also included by each Device Header File <device.h> so that these definitions are available.
  40. * @{
  41. */
  42. /* Fallback for __has_builtin */
  43. #ifndef __has_builtin
  44. #define __has_builtin(x) (0)
  45. #endif
  46. /* NMSIS compiler specific defines */
  47. /** \brief Pass information from the compiler to the assembler. */
  48. #ifndef __ASM
  49. #define __ASM __asm
  50. #endif
  51. /** \brief Recommend that function should be inlined by the compiler. */
  52. #ifndef __INLINE
  53. #define __INLINE inline
  54. #endif
  55. /** \brief Define a static function that may be inlined by the compiler. */
  56. #ifndef __STATIC_INLINE
  57. #define __STATIC_INLINE static inline
  58. #endif
  59. /** \brief Define a static function that should be always inlined by the compiler. */
  60. #ifndef __STATIC_FORCEINLINE
  61. #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
  62. #endif
  63. /** \brief Inform the compiler that a function does not return. */
  64. #ifndef __NO_RETURN
  65. #define __NO_RETURN __attribute__((__noreturn__))
  66. #endif
  67. /** \brief Inform that a variable shall be retained in executable image. */
  68. #ifndef __USED
  69. #define __USED __attribute__((used))
  70. #endif
  71. /** \brief restrict pointer qualifier to enable additional optimizations. */
  72. #ifndef __WEAK
  73. #define __WEAK __attribute__((weak))
  74. #endif
  75. /** \brief specified the vector size of the variable, measured in bytes */
  76. #ifndef __VECTOR_SIZE
  77. #define __VECTOR_SIZE(x) __attribute__((vector_size(x)))
  78. #endif
  79. /** \brief Request smallest possible alignment. */
  80. #ifndef __PACKED
  81. #define __PACKED __attribute__((packed, aligned(1)))
  82. #endif
  83. /** \brief Request smallest possible alignment for a structure. */
  84. #ifndef __PACKED_STRUCT
  85. #define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
  86. #endif
  87. /** \brief Request smallest possible alignment for a union. */
  88. #ifndef __PACKED_UNION
  89. #define __PACKED_UNION union __attribute__((packed, aligned(1)))
  90. #endif
  91. #ifndef __UNALIGNED_UINT16_WRITE
  92. #pragma GCC diagnostic push
  93. #pragma GCC diagnostic ignored "-Wpacked"
  94. #pragma GCC diagnostic ignored "-Wattributes"
  95. /** \brief Packed struct for unaligned uint16_t write access */
  96. __PACKED_STRUCT T_UINT16_WRITE {
  97. uint16_t v;
  98. };
  99. #pragma GCC diagnostic pop
  100. /** \brief Pointer for unaligned write of a uint16_t variable. */
  101. #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
  102. #endif
  103. #ifndef __UNALIGNED_UINT16_READ
  104. #pragma GCC diagnostic push
  105. #pragma GCC diagnostic ignored "-Wpacked"
  106. #pragma GCC diagnostic ignored "-Wattributes"
  107. /** \brief Packed struct for unaligned uint16_t read access */
  108. __PACKED_STRUCT T_UINT16_READ {
  109. uint16_t v;
  110. };
  111. #pragma GCC diagnostic pop
  112. /** \brief Pointer for unaligned read of a uint16_t variable. */
  113. #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
  114. #endif
  115. #ifndef __UNALIGNED_UINT32_WRITE
  116. #pragma GCC diagnostic push
  117. #pragma GCC diagnostic ignored "-Wpacked"
  118. #pragma GCC diagnostic ignored "-Wattributes"
  119. /** \brief Packed struct for unaligned uint32_t write access */
  120. __PACKED_STRUCT T_UINT32_WRITE {
  121. uint32_t v;
  122. };
  123. #pragma GCC diagnostic pop
  124. /** \brief Pointer for unaligned write of a uint32_t variable. */
  125. #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
  126. #endif
  127. #ifndef __UNALIGNED_UINT32_READ
  128. #pragma GCC diagnostic push
  129. #pragma GCC diagnostic ignored "-Wpacked"
  130. #pragma GCC diagnostic ignored "-Wattributes"
  131. /** \brief Packed struct for unaligned uint32_t read access */
  132. __PACKED_STRUCT T_UINT32_READ {
  133. uint32_t v;
  134. };
  135. #pragma GCC diagnostic pop
  136. /** \brief Pointer for unaligned read of a uint32_t variable. */
  137. #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
  138. #endif
  139. /** \brief Minimum `x` bytes alignment for a variable. */
  140. #ifndef __ALIGNED
  141. #define __ALIGNED(x) __attribute__((aligned(x)))
  142. #endif
  143. /** \brief restrict pointer qualifier to enable additional optimizations. */
  144. #ifndef __RESTRICT
  145. #define __RESTRICT __restrict
  146. #endif
  147. /** \brief Barrier to prevent compiler from reordering instructions. */
  148. #ifndef __COMPILER_BARRIER
  149. #define __COMPILER_BARRIER() __ASM volatile("":::"memory")
  150. #endif
  151. /** \brief provide the compiler with branch prediction information, the branch is usually true */
  152. #ifndef __USUALLY
  153. #define __USUALLY(exp) __builtin_expect((exp), 1)
  154. #endif
  155. /** \brief provide the compiler with branch prediction information, the branch is rarely true */
  156. #ifndef __RARELY
  157. #define __RARELY(exp) __builtin_expect((exp), 0)
  158. #endif
  159. /** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */
  160. #ifndef __INTERRUPT
  161. #define __INTERRUPT __attribute__((interrupt))
  162. #endif
  163. /** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */
  164. #ifndef __MACHINE_INTERRUPT
  165. #define __MACHINE_INTERRUPT __attribute__ ((interrupt ("machine")))
  166. #endif
  167. /** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Supervisor Mode. */
  168. #ifndef __SUPERVISOR_INTERRUPT
  169. #define __SUPERVISOR_INTERRUPT __attribute__ ((interrupt ("supervisor")))
  170. #endif
  171. /** \brief Use this attribute to indicate that the specified function is an interrupt handler run in User Mode. */
  172. #ifndef __USER_INTERRUPT
  173. #define __USER_INTERRUPT __attribute__ ((interrupt ("user")))
  174. #endif
  175. /** @} */ /* End of Doxygen Group NMSIS_Core_CompilerControl */
  176. #ifdef __cplusplus
  177. }
  178. #endif
  179. #endif /* __NMSIS_GCC_H__ */