5 #ifndef OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_
6 #define OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_
10 #if !defined(__ASSEMBLER__) && !defined(NOSTDINC)
19 #include <type_traits>
45 #define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
50 #define OT_FALLTHROUGH_INTENDED __attribute__((fallthrough))
55 #define OT_ALWAYS_INLINE __attribute__((always_inline)) inline
63 #define OT_RESTRICT __restrict__
68 #define OT_STRINGIFY(a) OT_STRINGIFY_(a)
69 #define OT_STRINGIFY_(a) #a
84 #define OT_VA_ARGS_COUNT(dummy, ...) \
85 OT_SHIFT_N_VARIABLE_ARGS_(dummy, ##__VA_ARGS__, 31, 30, 29, 28, 27, 26, 25, \
86 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
87 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
90 #define OT_SHIFT_N_VARIABLE_ARGS_(...) OT_GET_NTH_VARIABLE_ARG_(__VA_ARGS__)
91 #define OT_GET_NTH_VARIABLE_ARG_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, \
92 x11, x12, x13, x14, x15, x16, x17, x18, x19, \
93 x20, x21, x22, x23, x24, x25, x26, x27, x28, \
94 x29, x30, x31, n, ...) \
103 #define OT_CAT(a, ...) OT_PRIMITIVE_CAT(a, __VA_ARGS__)
104 #define OT_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
109 #define OT_GET_ARG(n, ...) OT_CAT(OT_CAT(OT_GET_ARG_, n), _)(__VA_ARGS__)
118 #define OT_GET_LAST_ARG(...) \
119 OT_GET_ARG(OT_VA_ARGS_COUNT(__VA_ARGS__), ##__VA_ARGS__)
125 #define OT_GET_ARG_0_(x0, ...) x0
126 #define OT_GET_ARG_1_(x1, x0, ...) x0
127 #define OT_GET_ARG_2_(x2, x1, x0, ...) x0
128 #define OT_GET_ARG_3_(x3, x2, x1, x0, ...) x0
129 #define OT_GET_ARG_4_(x4, x3, x2, x1, x0, ...) x0
130 #define OT_GET_ARG_5_(x5, x4, x3, x2, x1, x0, ...) x0
131 #define OT_GET_ARG_6_(x6, x5, x4, x3, x2, x1, x0, ...) x0
132 #define OT_GET_ARG_7_(x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
133 #define OT_GET_ARG_8_(x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
134 #define OT_GET_ARG_9_(x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
135 #define OT_GET_ARG_10_(x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
136 #define OT_GET_ARG_11_(x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
137 #define OT_GET_ARG_12_(x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, \
140 #define OT_GET_ARG_13_(x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, \
143 #define OT_GET_ARG_14_(x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, \
146 #define OT_GET_ARG_15_(x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, \
147 x3, x2, x1, x0, ...) \
149 #define OT_GET_ARG_16_(x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, \
150 x4, x3, x2, x1, x0, ...) \
152 #define OT_GET_ARG_17_(x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, \
153 x5, x4, x3, x2, x1, x0, ...) \
155 #define OT_GET_ARG_18_(x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, \
156 x7, x6, x5, x4, x3, x2, x1, x0, ...) \
158 #define OT_GET_ARG_19_(x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, \
159 x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
161 #define OT_GET_ARG_20_(x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, \
162 x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
164 #define OT_GET_ARG_21_(x21, x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, \
165 x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
167 #define OT_GET_ARG_22_(x22, x21, x20, x19, x18, x17, x16, x15, x14, x13, x12, \
168 x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
170 #define OT_GET_ARG_23_(x23, x22, x21, x20, x19, x18, x17, x16, x15, x14, x13, \
171 x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, \
174 #define OT_GET_ARG_24_(x24, x23, x22, x21, x20, x19, x18, x17, x16, x15, x14, \
175 x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, \
178 #define OT_GET_ARG_25_(x25, x24, x23, x22, x21, x20, x19, x18, x17, x16, x15, \
179 x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, \
182 #define OT_GET_ARG_26_(x26, x25, x24, x23, x22, x21, x20, x19, x18, x17, x16, \
183 x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, \
184 x3, x2, x1, x0, ...) \
186 #define OT_GET_ARG_27_(x27, x26, x25, x24, x23, x22, x21, x20, x19, x18, x17, \
187 x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, \
188 x4, x3, x2, x1, x0, ...) \
190 #define OT_GET_ARG_28_(x28, x27, x26, x25, x24, x23, x22, x21, x20, x19, x18, \
191 x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, \
192 x5, x4, x3, x2, x1, x0, ...) \
194 #define OT_GET_ARG_29_(x29, x28, x27, x26, x25, x24, x23, x22, x21, x20, x19, \
195 x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, \
196 x7, x6, x5, x4, x3, x2, x1, x0, ...) \
198 #define OT_GET_ARG_30_(x30, x29, x28, x27, x26, x25, x24, x23, x22, x21, x20, \
199 x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, \
200 x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
202 #define OT_GET_ARG_31_(x31, x30, x29, x28, x27, x26, x25, x24, x23, x22, x21, \
203 x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, \
204 x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
214 #define OT_ASSERT_MEMBER_OFFSET(type, member, offset) \
215 static_assert(offsetof(type, member) == UINT32_C(offset), \
216 "Unexpected offset for " #type "." #member)
225 #define OT_ASSERT_MEMBER_SIZE(type, member, size) \
226 static_assert(sizeof(((type){0}).member) == UINT32_C(size), \
227 "Unexpected size for " #type)
235 #define OT_ASSERT_SIZE(type, size) \
236 static_assert(sizeof(type) == UINT32_C(size), "Unexpected size for " #type)
244 #define OT_ASSERT_ENUM_VALUE(var, expected_value) \
245 static_assert(var == expected_value, "Unexpected value for " #var)
250 #if __riscv_xlen == 32
251 #define OT_PLATFORM_RV32 1
258 #ifdef OT_IS_ENGLISH_BREAKFAST_REDUCED_SUPPORT_FOR_INTERNAL_USE_ONLY_
259 #define OT_IS_ENGLISH_BREAKFAST 1
276 #define OT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
281 #define OT_WEAK __attribute__((weak))
291 #define OT_NAKED __attribute__((naked))
299 #define OT_SECTION(name) __attribute__((section(name)))
315 #define OT_SET_BSS_SECTION(name, ...) \
316 OT_SET_BSS_SECTION_(clang section bss = name) \
318 _Pragma("clang section bss = \"\"")
319 #define OT_SET_BSS_SECTION_(section) _Pragma(#section)
326 #define OT_NOINLINE __attribute__((noinline))
333 #define OT_FRAME_ADDR() __builtin_frame_address(0)
345 #define OT_UNREACHABLE() __builtin_unreachable()
351 #define OT_ALIAS(name) __attribute__((alias(name)))
432 #define OT_ADDRESSABLE_LABEL(kName_) \
433 extern const char kName_[]; \
434 asm volatile(".local " #kName_ "; " #kName_ ":;"); \
445 #define OT_DISCARD(expr_) \
453 #define OT_USED __attribute__((used))
460 #ifdef __clang_analyzer__
461 #define OT_BUILD_FOR_STATIC_ANALYZER 1
463 #define OT_BUILD_FOR_STATIC_ANALYZER 0
469 #define OT_ALIGN_MEM(x) (uint32_t)(4 + (((uintptr_t)(x)-1) & ~3u))
471 #if !defined(__ASSEMBLER__) && !defined(NOSTDINC) && \
472 !defined(RUST_PREPROCESSOR_EMIT)
481 #define OT_SIGNED(value) \
483 uint8_t: (int8_t)(value), \
484 uint16_t: (int16_t)(value), \
485 uint32_t: (int32_t)(value), \
486 uint64_t: (int64_t)(value), \
487 default: (struct OtSignConversionUnsupportedType){.err = 1})
492 #define OT_UNSIGNED(value) \
494 int8_t: (uint8_t)(value), \
495 int16_t: (uint16_t)(value), \
496 int32_t: (uint32_t)(value), \
497 int64_t: (uint64_t)(value), \
498 default: (struct OtSignConversionUnsupportedType){.err = 1})
506 template <
typename T>
507 class SignConverter {
509 using SignedT =
typename std::make_signed<T>::type;
510 using UnsignedT =
typename std::make_unsigned<T>::type;
511 static constexpr SignedT as_signed(T value) {
512 return static_cast<SignedT
>(value);
514 static constexpr UnsignedT as_unsigned(T value) {
515 return static_cast<UnsignedT
>(value);
520 #define OT_SIGNED(value) (SignConverter<typeof(value)>::as_signed((value)))
521 #define OT_UNSIGNED(value) (SignConverter<typeof(value)>::as_unsigned((value)))
522 #endif // __cplusplus
523 #endif // !defined(__ASSEMBLER__) && !defined(NOSTDINC) &&
529 #define ATOMIC_WAIT_FOR_INTERRUPT(_volatile_condition) \
531 irq_global_ctrl(false); \
532 if ((_volatile_condition)) { \
535 wait_for_interrupt(); \
536 irq_global_ctrl(true); \
538 irq_global_ctrl(true)
539 #endif // OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_