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_OFFSET_AS_ENUM(type, member, enum_offset) \
226 static_assert(offsetof(type, member) == enum_offset, \
227 "Unexpected offset for " #type "." #member)
236 #define OT_ASSERT_MEMBER_SIZE(type, member, size) \
237 static_assert(sizeof(((type){0}).member) == UINT32_C(size), \
238 "Unexpected size for " #type)
250 #define OT_ASSERT_MEMBER_SIZE_AS_ENUM(type, member, enum_size) \
251 static_assert(sizeof(((type){0}).member) == enum_size, \
252 "Unexpected size for " #type)
260 #define OT_ASSERT_SIZE(type, size) \
261 static_assert(sizeof(type) == UINT32_C(size), "Unexpected size for " #type)
269 #define OT_ASSERT_ENUM_VALUE(var, expected_value) \
270 static_assert(var == expected_value, "Unexpected value for " #var)
287 #define OT_VA_FOR_EACH(action, ...) \
289 OT_CAT(OT_CAT(OT_VA_FOR_EACH_, OT_VA_ARGS_COUNT(0, ##__VA_ARGS__)), _) \
290 (action, ##__VA_ARGS__) \
297 #define OT_VA_FOR_EACH_0_(action)
298 #define OT_VA_FOR_EACH_1_(action, item, ...) \
300 OT_VA_FOR_EACH_0_(action, ##__VA_ARGS__)
301 #define OT_VA_FOR_EACH_2_(action, item, ...) \
303 OT_VA_FOR_EACH_1_(action, ##__VA_ARGS__)
304 #define OT_VA_FOR_EACH_3_(action, item, ...) \
306 OT_VA_FOR_EACH_2_(action, ##__VA_ARGS__)
307 #define OT_VA_FOR_EACH_4_(action, item, ...) \
309 OT_VA_FOR_EACH_3_(action, ##__VA_ARGS__)
310 #define OT_VA_FOR_EACH_5_(action, item, ...) \
312 OT_VA_FOR_EACH_4_(action, ##__VA_ARGS__)
313 #define OT_VA_FOR_EACH_6_(action, item, ...) \
315 OT_VA_FOR_EACH_5_(action, ##__VA_ARGS__)
316 #define OT_VA_FOR_EACH_7_(action, item, ...) \
318 OT_VA_FOR_EACH_6_(action, ##__VA_ARGS__)
319 #define OT_VA_FOR_EACH_8_(action, item, ...) \
321 OT_VA_FOR_EACH_7_(action, ##__VA_ARGS__)
322 #define OT_VA_FOR_EACH_9_(action, item, ...) \
324 OT_VA_FOR_EACH_8_(action, ##__VA_ARGS__)
325 #define OT_VA_FOR_EACH_10_(action, item, ...) \
327 OT_VA_FOR_EACH_9_(action, ##__VA_ARGS__)
328 #define OT_VA_FOR_EACH_11_(action, item, ...) \
330 OT_VA_FOR_EACH_10_(action, ##__VA_ARGS__)
331 #define OT_VA_FOR_EACH_12_(action, item, ...) \
333 OT_VA_FOR_EACH_11_(action, ##__VA_ARGS__)
334 #define OT_VA_FOR_EACH_13_(action, item, ...) \
336 OT_VA_FOR_EACH_12_(action, ##__VA_ARGS__)
337 #define OT_VA_FOR_EACH_14_(action, item, ...) \
339 OT_VA_FOR_EACH_13_(action, ##__VA_ARGS__)
340 #define OT_VA_FOR_EACH_15_(action, item, ...) \
342 OT_VA_FOR_EACH_14_(action, ##__VA_ARGS__)
343 #define OT_VA_FOR_EACH_16_(action, item, ...) \
345 OT_VA_FOR_EACH_15_(action, ##__VA_ARGS__)
346 #define OT_VA_FOR_EACH_17_(action, item, ...) \
348 OT_VA_FOR_EACH_16_(action, ##__VA_ARGS__)
349 #define OT_VA_FOR_EACH_18_(action, item, ...) \
351 OT_VA_FOR_EACH_17_(action, ##__VA_ARGS__)
352 #define OT_VA_FOR_EACH_19_(action, item, ...) \
354 OT_VA_FOR_EACH_18_(action, ##__VA_ARGS__)
355 #define OT_VA_FOR_EACH_20_(action, item, ...) \
357 OT_VA_FOR_EACH_19_(action, ##__VA_ARGS__)
358 #define OT_VA_FOR_EACH_21_(action, item, ...) \
360 OT_VA_FOR_EACH_20_(action, ##__VA_ARGS__)
361 #define OT_VA_FOR_EACH_22_(action, item, ...) \
363 OT_VA_FOR_EACH_21_(action, ##__VA_ARGS__)
364 #define OT_VA_FOR_EACH_23_(action, item, ...) \
366 OT_VA_FOR_EACH_22_(action, ##__VA_ARGS__)
367 #define OT_VA_FOR_EACH_24_(action, item, ...) \
369 OT_VA_FOR_EACH_23_(action, ##__VA_ARGS__)
370 #define OT_VA_FOR_EACH_25_(action, item, ...) \
372 OT_VA_FOR_EACH_24_(action, ##__VA_ARGS__)
373 #define OT_VA_FOR_EACH_26_(action, item, ...) \
375 OT_VA_FOR_EACH_25_(action, ##__VA_ARGS__)
376 #define OT_VA_FOR_EACH_27_(action, item, ...) \
378 OT_VA_FOR_EACH_26_(action, ##__VA_ARGS__)
379 #define OT_VA_FOR_EACH_28_(action, item, ...) \
381 OT_VA_FOR_EACH_27_(action, ##__VA_ARGS__)
382 #define OT_VA_FOR_EACH_29_(action, item, ...) \
384 OT_VA_FOR_EACH_28_(action, ##__VA_ARGS__)
385 #define OT_VA_FOR_EACH_30_(action, item, ...) \
387 OT_VA_FOR_EACH_29_(action, ##__VA_ARGS__)
388 #define OT_VA_FOR_EACH_31_(action, item, ...) \
390 OT_VA_FOR_EACH_30_(action, ##__VA_ARGS__)
399 #define OT_CHECK_NOT_INT64(arg) \
400 _Generic((arg), int64_t: false, uint64_t: false, default: true)
411 #define OT_FAIL_IF_64_BIT(arg, func_name) \
413 static_assert(OT_CHECK_NOT_INT64(arg), \
414 "Argument '" #arg "' passed to the " #func_name \
415 " function must be no wider than 32 bits. " \
416 "Hint: maybe cast with '(uint32_t) " #arg "'?"); \
422 #if __riscv_xlen == 32
423 #define OT_PLATFORM_RV32 1
430 #ifdef OT_IS_ENGLISH_BREAKFAST_REDUCED_SUPPORT_FOR_INTERNAL_USE_ONLY_
431 #define OT_IS_ENGLISH_BREAKFAST 1
448 #define OT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
453 #define OT_WEAK __attribute__((weak))
463 #define OT_NAKED __attribute__((naked))
471 #define OT_SECTION(name) __attribute__((section(name)))
487 #define OT_SET_BSS_SECTION(name, ...) \
488 OT_SET_BSS_SECTION_(clang section bss = name) \
490 _Pragma("clang section bss = \"\"")
491 #define OT_SET_BSS_SECTION_(section) _Pragma(#section)
498 #define OT_NOINLINE __attribute__((noinline))
505 #define OT_FRAME_ADDR() __builtin_frame_address(0)
517 #define OT_UNREACHABLE() __builtin_unreachable()
523 #define OT_ALIAS(name) __attribute__((alias(name)))
604 #define OT_ADDRESSABLE_LABEL(kName_) \
605 extern const char kName_[]; \
606 asm volatile(".local " #kName_ "; " #kName_ ":;"); \
617 #define OT_DISCARD(expr_) \
625 #define OT_USED __attribute__((used))
632 #ifdef __clang_analyzer__
633 #define OT_BUILD_FOR_STATIC_ANALYZER 1
635 #define OT_BUILD_FOR_STATIC_ANALYZER 0
641 #define OT_ALIGN_MEM(x) (uint32_t)(4 + (((uintptr_t)(x)-1) & ~3u))
643 #if !defined(__ASSEMBLER__) && !defined(NOSTDINC) && \
644 !defined(RUST_PREPROCESSOR_EMIT)
653 #define OT_SIGNED(value) \
655 uint8_t: (int8_t)(value), \
656 uint16_t: (int16_t)(value), \
657 uint32_t: (int32_t)(value), \
658 uint64_t: (int64_t)(value), \
659 default: (struct OtSignConversionUnsupportedType){.err = 1})
664 #define OT_UNSIGNED(value) \
666 int8_t: (uint8_t)(value), \
667 int16_t: (uint16_t)(value), \
668 int32_t: (uint32_t)(value), \
669 int64_t: (uint64_t)(value), \
670 default: (struct OtSignConversionUnsupportedType){.err = 1})
678 template <
typename T>
679 class SignConverter {
681 using SignedT =
typename std::make_signed<T>::type;
682 using UnsignedT =
typename std::make_unsigned<T>::type;
683 static constexpr SignedT as_signed(T value) {
684 return static_cast<SignedT
>(value);
686 static constexpr UnsignedT as_unsigned(T value) {
687 return static_cast<UnsignedT
>(value);
692 #define OT_SIGNED(value) (SignConverter<__typeof__(value)>::as_signed((value)))
693 #define OT_UNSIGNED(value) \
694 (SignConverter<__typeof__(value)>::as_unsigned((value)))
702 #define ATOMIC_WAIT_FOR_INTERRUPT(_volatile_condition) \
704 irq_global_ctrl(false); \
705 if ((_volatile_condition)) { \
708 wait_for_interrupt(); \
709 irq_global_ctrl(true); \
711 irq_global_ctrl(true)
716 #define OT_WORD_SIZE 4
717 #define OT_HALF_WORD_SIZE (OT_WORD_SIZE / 2)
720 #define OT_CONTEXT_SIZE (OT_WORD_SIZE * 30)