From 7b06e665ee686eb68834ed53835c351a6df66c9d Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 10 Nov 2021 14:19:47 +0100 Subject: [PATCH] sys/architecture: add HAS_ALIGNMENT_OF() helper --- sys/include/architecture.h | 20 +++++++++++++++++ tests/sys_architecture/main.c | 41 ++++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/sys/include/architecture.h b/sys/include/architecture.h index 15ed358c8e..906b192eff 100644 --- a/sys/include/architecture.h +++ b/sys/include/architecture.h @@ -90,6 +90,26 @@ typedef int32_t sword_t; */ #define WORD_ALIGNED __attribute__((aligned(ARCHITECTURE_WORD_BYTES))) +/** + * @brief Check if @p addr is alignment to @p alignment + * @param[in] addr Address to check for being aligned + * @param[in] alignment Alignment to check for + * @pre @p alignment is a power of two. (But this is naturally + * fulfilled, as all possible alignment requirements in C + * are powers of two.) + * @retval 1 @p addr is aligned to @p alignment + * @retval 0 @p addr is unaligned + */ +#define HAS_ALIGNMENT_OF(addr, alignment) (((uintptr_t)(addr) & ((alignment) - 1)) == 0) + +/** + * @brief Check if @p addr is word-aligned + * @param[in] addr Address to check for word alignment + * @retval 1 @p addr is word-aligned + * @retval 0 @p addr is unaligned + */ +#define IS_WORD_ALIGNED(addr) HAS_ALIGNMENT_OF(addr, ARCHITECTURE_WORD_BYTES) + /** * @brief Smallest number an uword_t can hold */ diff --git a/tests/sys_architecture/main.c b/tests/sys_architecture/main.c index 19ac350ba4..a51ce84c47 100644 --- a/tests/sys_architecture/main.c +++ b/tests/sys_architecture/main.c @@ -48,23 +48,30 @@ int main(void) * with the non-C11 fallback implementation of static_assert, so we just * use a single use statement. */ - static_assert( - (ARCHITECTURE_WORD_BITS == CORRECT_WORD_BITS) && - (ARCHITECTURE_WORD_BYTES == CORRECT_WORD_BITS / 8) && - (sizeof(uword_t) == ARCHITECTURE_WORD_BYTES) && - (sizeof(sword_t) == ARCHITECTURE_WORD_BYTES) && - (UWORD_MIN == 0) && - ((ARCHITECTURE_WORD_BITS != 8) || (UWORD_MAX == 255)) && - ((ARCHITECTURE_WORD_BITS != 8) || (SWORD_MIN == -128)) && - ((ARCHITECTURE_WORD_BITS != 8) || (SWORD_MAX == 127)) && - ((ARCHITECTURE_WORD_BITS != 16) || (UWORD_MAX == 65535)) && - ((ARCHITECTURE_WORD_BITS != 16) || (SWORD_MIN == -32768)) && - ((ARCHITECTURE_WORD_BITS != 16) || (SWORD_MAX == 32767)) && - ((ARCHITECTURE_WORD_BITS != 32) || (UWORD_MAX == 4294967295)) && - ((ARCHITECTURE_WORD_BITS != 32) || (SWORD_MIN == -2147483648)) && - ((ARCHITECTURE_WORD_BITS != 32) || (SWORD_MAX == 2147483647)), - "word size details are incorrect" - ); + static_assert((ARCHITECTURE_WORD_BITS == CORRECT_WORD_BITS) + && (ARCHITECTURE_WORD_BYTES == CORRECT_WORD_BITS / 8) + && (sizeof(uword_t) == ARCHITECTURE_WORD_BYTES) + && (sizeof(sword_t) == ARCHITECTURE_WORD_BYTES) + && (UWORD_MIN == 0) + && ((ARCHITECTURE_WORD_BITS != 8) || (UWORD_MAX == 255)) + && ((ARCHITECTURE_WORD_BITS != 8) || (SWORD_MIN == -128)) + && ((ARCHITECTURE_WORD_BITS != 8) || (SWORD_MAX == 127)) + && ((ARCHITECTURE_WORD_BITS != 16) || (UWORD_MAX == 65535)) + && ((ARCHITECTURE_WORD_BITS != 16) || (SWORD_MIN == -32768)) + && ((ARCHITECTURE_WORD_BITS != 16) || (SWORD_MAX == 32767)) + && ((ARCHITECTURE_WORD_BITS != 32) || (UWORD_MAX == 4294967295)) + && ((ARCHITECTURE_WORD_BITS != 32) || (SWORD_MIN == -2147483648)) + && ((ARCHITECTURE_WORD_BITS != 32) || (SWORD_MAX == 2147483647)), + "word size details are incorrect"); + + DECLARE_CONSTANT(_workaround, HAS_ALIGNMENT_OF((void *)3, 1) + && HAS_ALIGNMENT_OF((void *)8, 2) + && HAS_ALIGNMENT_OF((void *)8, 4) + && HAS_ALIGNMENT_OF((void *)8, 8) + && !HAS_ALIGNMENT_OF((void *)7, 2) + && !HAS_ALIGNMENT_OF((void *)7, 4) + && !HAS_ALIGNMENT_OF((void *)7, 8)) + static_assert(_workaround, "HAS_ALIGNMENT_OF() is not working"); printf("One word is %u bits or %u bytes in size\n", ARCHITECTURE_WORD_BITS, ARCHITECTURE_WORD_BYTES);