Software APIs
macros.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors.
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_
6 #define OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_
7 
8 #include <assert.h>
9 #include <stddef.h>
10 #include <stdint.h>
11 
12 /**
13  * @file
14  * @brief Generic preprocessor macros that don't really fit anywhere else.
15  */
16 
17 /**
18  * An annotation that a switch/case fallthrough is the intended behavior.
19  */
20 #define FALLTHROUGH_INTENDED __attribute__((fallthrough))
21 
22 /**
23  * A directive to force the compiler to inline a function.
24  */
25 #define ALWAYS_INLINE __attribute__((always_inline)) inline
26 
27 /**
28  * A variable-argument macro that expands to the number of arguments passed into
29  * it, between 0 and 31 arguments.
30  *
31  * This macro is based off of a well-known preprocessor trick. This
32  * StackOverflow post expains the trick in detail:
33  * https://stackoverflow.com/questions/2308243/macro-returning-the-number-of-arguments-it-is-given-in-c
34  * TODO #2026: a dummy token is required for this to work correctly.
35  *
36  * @param dummy a dummy token that is required to be passed for the calculation
37  * to work correctly.
38  * @param ... the variable args list.
39  */
40 
41 // Implementation details for `GET_NUM_VARIABLE_ARGS()`.
42 #define GET_NUM_VARIABLE_ARGS(dummy, ...) \
43  SHIFT_N_VARIABLE_ARGS_(dummy, ##__VA_ARGS__, 31, 30, 29, 28, 27, 26, 25, 24, \
44  23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
45  10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
46 #define SHIFT_N_VARIABLE_ARGS_(...) GET_NTH_VARIABLE_ARG_(__VA_ARGS__)
47 #define GET_NTH_VARIABLE_ARG_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, \
48  x11, x12, x13, x14, x15, x16, x17, x18, x19, \
49  x20, x21, x22, x23, x24, x25, x26, x27, x28, \
50  x29, x30, x31, n, ...) \
51  n
52 
53 /**
54  * A macro that expands to an assertion for the offset of a struct member.
55  *
56  * @param type A struct type.
57  * @param member A member of the struct.
58  * @param offset Expected offset of the member.
59  */
60 #define OT_ASSERT_MEMBER_OFFSET(type, member, offset) \
61  static_assert(offsetof(type, member) == UINT32_C(offset), \
62  "Unexpected offset for " #type "." #member)
63 
64 /**
65  * A macro that expands to an assertion for the size of a type.
66  *
67  * @param type A type.
68  * @param size Expected size of the type.
69  */
70 #define OT_ASSERT_SIZE(type, size) \
71  static_assert(sizeof(type) == UINT32_C(size), "Unexpected size for " #type)
72 
73 /**
74  * A macro representing the OpenTitan execution platform.
75  */
76 #if __riscv_xlen == 32
77 #define OT_PLATFORM_RV32 1
78 #endif
79 
80 /**
81  * Attribute for functions which return errors that must be acknowledged.
82  *
83  * This attribute must be used to mark all DIFs which return an error value of
84  * some kind, to ensure that callers do not accidentally drop the error on the
85  * ground.
86  *
87  * Normally, the standard way to drop such a value on the ground explicitly is
88  * with the syntax `(void)expr;`, in analogy with the behavior of C++'s
89  * `[[nodiscard]]` attribute.
90  * However, GCC does not implement this, so the idiom `if (expr) {}` should be
91  * used instead, for the time being.
92  * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509.
93  */
94 #define OT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
95 
96 /**
97  * Attribute for weak functions that can be overridden, e.g., ISRs.
98  */
99 #define OT_ATTR_WEAK __attribute__((weak))
100 
101 #endif // OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_