5#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_
6#define OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_
10#if !defined(__ASSEMBLER__) && !defined(NOSTDINC)
30#if defined(__CHERI_PURE_CAPABILITY__)
35typedef ptrdiff_t ot_sword_t;
59#define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
64#define OT_FALLTHROUGH_INTENDED __attribute__((fallthrough))
69#define OT_ALWAYS_INLINE __attribute__((always_inline)) inline
77#define OT_RESTRICT __restrict__
82#define OT_STRINGIFY(a) OT_STRINGIFY_(a)
83#define OT_STRINGIFY_(a) #a
98#define OT_VA_ARGS_COUNT(dummy, ...) \
99 OT_SHIFT_N_VARIABLE_ARGS_(dummy, ##__VA_ARGS__, 31, 30, 29, 28, 27, 26, 25, \
100 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
101 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
104#define OT_SHIFT_N_VARIABLE_ARGS_(...) OT_GET_NTH_VARIABLE_ARG_(__VA_ARGS__)
105#define OT_GET_NTH_VARIABLE_ARG_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, \
106 x11, x12, x13, x14, x15, x16, x17, x18, x19, \
107 x20, x21, x22, x23, x24, x25, x26, x27, x28, \
108 x29, x30, x31, n, ...) \
117#define OT_CAT(a, ...) OT_PRIMITIVE_CAT(a, __VA_ARGS__)
118#define OT_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
123#define OT_GET_ARG(n, ...) OT_CAT(OT_CAT(OT_GET_ARG_, n), _)(__VA_ARGS__)
132#define OT_GET_LAST_ARG(...) \
133 OT_GET_ARG(OT_VA_ARGS_COUNT(__VA_ARGS__), ##__VA_ARGS__)
139#define OT_GET_ARG_0_(x0, ...) x0
140#define OT_GET_ARG_1_(x1, x0, ...) x0
141#define OT_GET_ARG_2_(x2, x1, x0, ...) x0
142#define OT_GET_ARG_3_(x3, x2, x1, x0, ...) x0
143#define OT_GET_ARG_4_(x4, x3, x2, x1, x0, ...) x0
144#define OT_GET_ARG_5_(x5, x4, x3, x2, x1, x0, ...) x0
145#define OT_GET_ARG_6_(x6, x5, x4, x3, x2, x1, x0, ...) x0
146#define OT_GET_ARG_7_(x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
147#define OT_GET_ARG_8_(x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
148#define OT_GET_ARG_9_(x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
149#define OT_GET_ARG_10_(x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
150#define OT_GET_ARG_11_(x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
151#define OT_GET_ARG_12_(x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, \
154#define OT_GET_ARG_13_(x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, \
157#define OT_GET_ARG_14_(x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, \
160#define OT_GET_ARG_15_(x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, \
161 x3, x2, x1, x0, ...) \
163#define OT_GET_ARG_16_(x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, \
164 x4, x3, x2, x1, x0, ...) \
166#define OT_GET_ARG_17_(x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, \
167 x5, x4, x3, x2, x1, x0, ...) \
169#define OT_GET_ARG_18_(x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, \
170 x7, x6, x5, x4, x3, x2, x1, x0, ...) \
172#define OT_GET_ARG_19_(x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, \
173 x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
175#define OT_GET_ARG_20_(x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, \
176 x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
178#define OT_GET_ARG_21_(x21, x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, \
179 x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
181#define OT_GET_ARG_22_(x22, x21, x20, x19, x18, x17, x16, x15, x14, x13, x12, \
182 x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
184#define OT_GET_ARG_23_(x23, x22, x21, x20, x19, x18, x17, x16, x15, x14, x13, \
185 x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, \
188#define OT_GET_ARG_24_(x24, x23, x22, x21, x20, x19, x18, x17, x16, x15, x14, \
189 x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, \
192#define OT_GET_ARG_25_(x25, x24, x23, x22, x21, x20, x19, x18, x17, x16, x15, \
193 x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, \
196#define OT_GET_ARG_26_(x26, x25, x24, x23, x22, x21, x20, x19, x18, x17, x16, \
197 x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, \
198 x3, x2, x1, x0, ...) \
200#define OT_GET_ARG_27_(x27, x26, x25, x24, x23, x22, x21, x20, x19, x18, x17, \
201 x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, \
202 x4, x3, x2, x1, x0, ...) \
204#define OT_GET_ARG_28_(x28, x27, x26, x25, x24, x23, x22, x21, x20, x19, x18, \
205 x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, \
206 x5, x4, x3, x2, x1, x0, ...) \
208#define OT_GET_ARG_29_(x29, x28, x27, x26, x25, x24, x23, x22, x21, x20, x19, \
209 x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, \
210 x7, x6, x5, x4, x3, x2, x1, x0, ...) \
212#define OT_GET_ARG_30_(x30, x29, x28, x27, x26, x25, x24, x23, x22, x21, x20, \
213 x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, \
214 x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
216#define OT_GET_ARG_31_(x31, x30, x29, x28, x27, x26, x25, x24, x23, x22, x21, \
217 x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, \
218 x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
228#define OT_ASSERT_MEMBER_OFFSET(type, member, offset) \
229 static_assert(offsetof(type, member) == UINT32_C(offset), \
230 "Unexpected offset for " #type "." #member)
239#define OT_ASSERT_MEMBER_OFFSET_AS_ENUM(type, member, enum_offset) \
240 static_assert(offsetof(type, member) == enum_offset, \
241 "Unexpected offset for " #type "." #member)
250#define OT_ASSERT_MEMBER_SIZE(type, member, size) \
251 static_assert(sizeof(((type){0}).member) == UINT32_C(size), \
252 "Unexpected size for " #type)
264#define OT_ASSERT_MEMBER_SIZE_AS_ENUM(type, member, enum_size) \
265 static_assert(sizeof(((type){0}).member) == enum_size, \
266 "Unexpected size for " #type)
274#define OT_ASSERT_SIZE(type, size) \
275 static_assert(sizeof(type) == UINT32_C(size), "Unexpected size for " #type)
283#define OT_ASSERT_ENUM_VALUE(var, expected_value) \
284 static_assert(var == expected_value, "Unexpected value for " #var)
301#define OT_VA_FOR_EACH(action, ...) \
303 OT_CAT(OT_CAT(OT_VA_FOR_EACH_, OT_VA_ARGS_COUNT(0, ##__VA_ARGS__)), _) \
304 (action, ##__VA_ARGS__) \
311#define OT_VA_FOR_EACH_0_(action)
312#define OT_VA_FOR_EACH_1_(action, item, ...) \
314 OT_VA_FOR_EACH_0_(action, ##__VA_ARGS__)
315#define OT_VA_FOR_EACH_2_(action, item, ...) \
317 OT_VA_FOR_EACH_1_(action, ##__VA_ARGS__)
318#define OT_VA_FOR_EACH_3_(action, item, ...) \
320 OT_VA_FOR_EACH_2_(action, ##__VA_ARGS__)
321#define OT_VA_FOR_EACH_4_(action, item, ...) \
323 OT_VA_FOR_EACH_3_(action, ##__VA_ARGS__)
324#define OT_VA_FOR_EACH_5_(action, item, ...) \
326 OT_VA_FOR_EACH_4_(action, ##__VA_ARGS__)
327#define OT_VA_FOR_EACH_6_(action, item, ...) \
329 OT_VA_FOR_EACH_5_(action, ##__VA_ARGS__)
330#define OT_VA_FOR_EACH_7_(action, item, ...) \
332 OT_VA_FOR_EACH_6_(action, ##__VA_ARGS__)
333#define OT_VA_FOR_EACH_8_(action, item, ...) \
335 OT_VA_FOR_EACH_7_(action, ##__VA_ARGS__)
336#define OT_VA_FOR_EACH_9_(action, item, ...) \
338 OT_VA_FOR_EACH_8_(action, ##__VA_ARGS__)
339#define OT_VA_FOR_EACH_10_(action, item, ...) \
341 OT_VA_FOR_EACH_9_(action, ##__VA_ARGS__)
342#define OT_VA_FOR_EACH_11_(action, item, ...) \
344 OT_VA_FOR_EACH_10_(action, ##__VA_ARGS__)
345#define OT_VA_FOR_EACH_12_(action, item, ...) \
347 OT_VA_FOR_EACH_11_(action, ##__VA_ARGS__)
348#define OT_VA_FOR_EACH_13_(action, item, ...) \
350 OT_VA_FOR_EACH_12_(action, ##__VA_ARGS__)
351#define OT_VA_FOR_EACH_14_(action, item, ...) \
353 OT_VA_FOR_EACH_13_(action, ##__VA_ARGS__)
354#define OT_VA_FOR_EACH_15_(action, item, ...) \
356 OT_VA_FOR_EACH_14_(action, ##__VA_ARGS__)
357#define OT_VA_FOR_EACH_16_(action, item, ...) \
359 OT_VA_FOR_EACH_15_(action, ##__VA_ARGS__)
360#define OT_VA_FOR_EACH_17_(action, item, ...) \
362 OT_VA_FOR_EACH_16_(action, ##__VA_ARGS__)
363#define OT_VA_FOR_EACH_18_(action, item, ...) \
365 OT_VA_FOR_EACH_17_(action, ##__VA_ARGS__)
366#define OT_VA_FOR_EACH_19_(action, item, ...) \
368 OT_VA_FOR_EACH_18_(action, ##__VA_ARGS__)
369#define OT_VA_FOR_EACH_20_(action, item, ...) \
371 OT_VA_FOR_EACH_19_(action, ##__VA_ARGS__)
372#define OT_VA_FOR_EACH_21_(action, item, ...) \
374 OT_VA_FOR_EACH_20_(action, ##__VA_ARGS__)
375#define OT_VA_FOR_EACH_22_(action, item, ...) \
377 OT_VA_FOR_EACH_21_(action, ##__VA_ARGS__)
378#define OT_VA_FOR_EACH_23_(action, item, ...) \
380 OT_VA_FOR_EACH_22_(action, ##__VA_ARGS__)
381#define OT_VA_FOR_EACH_24_(action, item, ...) \
383 OT_VA_FOR_EACH_23_(action, ##__VA_ARGS__)
384#define OT_VA_FOR_EACH_25_(action, item, ...) \
386 OT_VA_FOR_EACH_24_(action, ##__VA_ARGS__)
387#define OT_VA_FOR_EACH_26_(action, item, ...) \
389 OT_VA_FOR_EACH_25_(action, ##__VA_ARGS__)
390#define OT_VA_FOR_EACH_27_(action, item, ...) \
392 OT_VA_FOR_EACH_26_(action, ##__VA_ARGS__)
393#define OT_VA_FOR_EACH_28_(action, item, ...) \
395 OT_VA_FOR_EACH_27_(action, ##__VA_ARGS__)
396#define OT_VA_FOR_EACH_29_(action, item, ...) \
398 OT_VA_FOR_EACH_28_(action, ##__VA_ARGS__)
399#define OT_VA_FOR_EACH_30_(action, item, ...) \
401 OT_VA_FOR_EACH_29_(action, ##__VA_ARGS__)
402#define OT_VA_FOR_EACH_31_(action, item, ...) \
404 OT_VA_FOR_EACH_30_(action, ##__VA_ARGS__)
413#define OT_CHECK_NOT_INT64(arg) \
414 _Generic((arg), int64_t: false, uint64_t: false, default: true)
425#define OT_FAIL_IF_64_BIT(arg, func_name) \
427 static_assert(OT_CHECK_NOT_INT64(arg), \
428 "Argument '" #arg "' passed to the " #func_name \
429 " function must be no wider than 32 bits. " \
430 "Hint: maybe cast with '(uint32_t) " #arg "'?"); \
436#if __riscv_xlen == 32
437#define OT_PLATFORM_RV32 1
444#ifdef OT_IS_ENGLISH_BREAKFAST_REDUCED_SUPPORT_FOR_INTERNAL_USE_ONLY_
445#define OT_IS_ENGLISH_BREAKFAST 1
462#define OT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
467#define OT_WEAK __attribute__((weak))
477#define OT_NAKED __attribute__((naked))
485#define OT_SECTION(name) __attribute__((section(name)))
501#define OT_SET_BSS_SECTION(name, ...) \
502 OT_SET_BSS_SECTION_(clang section bss = name) \
504 _Pragma("clang section bss = \"\"")
505#define OT_SET_BSS_SECTION_(section) _Pragma(#section)
512#define OT_NOINLINE __attribute__((noinline))
519#define OT_FRAME_ADDR() __builtin_frame_address(0)
531#define OT_UNREACHABLE() __builtin_unreachable()
537#define OT_ALIAS(name) __attribute__((alias(name)))
618#define OT_ADDRESSABLE_LABEL(kName_) \
619 extern const char kName_[]; \
620 asm volatile(".local " #kName_ "; " #kName_ ":;"); \
631#define OT_DISCARD(expr_) \
639#define OT_USED __attribute__((used))
645#if defined(__clang__) && __clang_major__ >= 21
646#define OT_NONSTRING __attribute__((nonstring))
647#elif defined(__GNUC__) && !defined(__clang__)
648#define OT_NONSTRING __attribute__((nonstring))
658#ifdef __clang_analyzer__
659#define OT_BUILD_FOR_STATIC_ANALYZER 1
661#define OT_BUILD_FOR_STATIC_ANALYZER 0
667#define OT_ALIGN_MEM(x) (uint32_t)(4 + (((uintptr_t)(x) - 1) & ~3u))
669#if !defined(__ASSEMBLER__) && !defined(NOSTDINC) && \
670 !defined(RUST_PREPROCESSOR_EMIT)
679#define OT_SIGNED(value) \
681 uint8_t: (int8_t)(value), \
682 uint16_t: (int16_t)(value), \
683 uint32_t: (int32_t)(value), \
684 uint64_t: (int64_t)(value), \
685 default: (struct OtSignConversionUnsupportedType){.err = 1})
690#define OT_UNSIGNED(value) \
692 int8_t: (uint8_t)(value), \
693 int16_t: (uint16_t)(value), \
694 int32_t: (uint32_t)(value), \
695 int64_t: (uint64_t)(value), \
696 default: (struct OtSignConversionUnsupportedType){.err = 1})
707 using SignedT =
typename std::make_signed<T>::type;
708 using UnsignedT =
typename std::make_unsigned<T>::type;
709 static constexpr SignedT as_signed(T value) {
710 return static_cast<SignedT
>(value);
712 static constexpr UnsignedT as_unsigned(T value) {
713 return static_cast<UnsignedT
>(value);
718#define OT_SIGNED(value) (SignConverter<__typeof__(value)>::as_signed((value)))
719#define OT_UNSIGNED(value) \
720 (SignConverter<__typeof__(value)>::as_unsigned((value)))
728#define ATOMIC_WAIT_FOR_INTERRUPT(_volatile_condition) \
730 irq_global_ctrl(false); \
731 if ((_volatile_condition)) { \
734 wait_for_interrupt(); \
735 irq_global_ctrl(true); \
737 irq_global_ctrl(true)
742#define OT_WORD_SIZE 4
743#define OT_HALF_WORD_SIZE (OT_WORD_SIZE / 2)
746#define OT_CONTEXT_SIZE (OT_WORD_SIZE * 30)
757 typeof(a) _a = (a); \
758 typeof(b) _b = (b); \
773 typeof(a) _a = (a); \
774 typeof(b) _b = (b); \