sys/architecture: add HAS_ALIGNMENT_OF() helper

This commit is contained in:
Marian Buschsieweke 2021-11-10 14:19:47 +01:00
parent 673299b1cf
commit 7b06e665ee
No known key found for this signature in database
GPG Key ID: CB8E3238CE715A94
2 changed files with 44 additions and 17 deletions

View File

@ -90,6 +90,26 @@ typedef int32_t sword_t;
*/ */
#define WORD_ALIGNED __attribute__((aligned(ARCHITECTURE_WORD_BYTES))) #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 * @brief Smallest number an uword_t can hold
*/ */

View File

@ -48,23 +48,30 @@ int main(void)
* with the non-C11 fallback implementation of static_assert, so we just * with the non-C11 fallback implementation of static_assert, so we just
* use a single use statement. * use a single use statement.
*/ */
static_assert( static_assert((ARCHITECTURE_WORD_BITS == CORRECT_WORD_BITS)
(ARCHITECTURE_WORD_BITS == CORRECT_WORD_BITS) && && (ARCHITECTURE_WORD_BYTES == CORRECT_WORD_BITS / 8)
(ARCHITECTURE_WORD_BYTES == CORRECT_WORD_BITS / 8) && && (sizeof(uword_t) == ARCHITECTURE_WORD_BYTES)
(sizeof(uword_t) == ARCHITECTURE_WORD_BYTES) && && (sizeof(sword_t) == ARCHITECTURE_WORD_BYTES)
(sizeof(sword_t) == ARCHITECTURE_WORD_BYTES) && && (UWORD_MIN == 0)
(UWORD_MIN == 0) && && ((ARCHITECTURE_WORD_BITS != 8) || (UWORD_MAX == 255))
((ARCHITECTURE_WORD_BITS != 8) || (UWORD_MAX == 255)) && && ((ARCHITECTURE_WORD_BITS != 8) || (SWORD_MIN == -128))
((ARCHITECTURE_WORD_BITS != 8) || (SWORD_MIN == -128)) && && ((ARCHITECTURE_WORD_BITS != 8) || (SWORD_MAX == 127))
((ARCHITECTURE_WORD_BITS != 8) || (SWORD_MAX == 127)) && && ((ARCHITECTURE_WORD_BITS != 16) || (UWORD_MAX == 65535))
((ARCHITECTURE_WORD_BITS != 16) || (UWORD_MAX == 65535)) && && ((ARCHITECTURE_WORD_BITS != 16) || (SWORD_MIN == -32768))
((ARCHITECTURE_WORD_BITS != 16) || (SWORD_MIN == -32768)) && && ((ARCHITECTURE_WORD_BITS != 16) || (SWORD_MAX == 32767))
((ARCHITECTURE_WORD_BITS != 16) || (SWORD_MAX == 32767)) && && ((ARCHITECTURE_WORD_BITS != 32) || (UWORD_MAX == 4294967295))
((ARCHITECTURE_WORD_BITS != 32) || (UWORD_MAX == 4294967295)) && && ((ARCHITECTURE_WORD_BITS != 32) || (SWORD_MIN == -2147483648))
((ARCHITECTURE_WORD_BITS != 32) || (SWORD_MIN == -2147483648)) && && ((ARCHITECTURE_WORD_BITS != 32) || (SWORD_MAX == 2147483647)),
((ARCHITECTURE_WORD_BITS != 32) || (SWORD_MAX == 2147483647)), "word size details are incorrect");
"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", printf("One word is %u bits or %u bytes in size\n",
ARCHITECTURE_WORD_BITS, ARCHITECTURE_WORD_BYTES); ARCHITECTURE_WORD_BITS, ARCHITECTURE_WORD_BYTES);