/* Copyright (C) 2021,2022 fef . All rights reserved. */ #pragma once #ifndef __clang__ #error "Unsupported compiler, please use clang" #endif #include #ifdef __cplusplus #if defined(_KERNEL) && !defined(_CXX_KERNEL) #error "C++ cannot be used in kernel code. Define _CXX_KERNEL if you know what you're doing." #endif /** @brief Use `__restrict` in header files, and just `restrict` in C code */ #define __restrict #define __BEGIN_DELCS extern "C" { #define __END_DECLS } #else /* not __cplusplus */ #define __BEGIN_DECLS #define __END_DECLS #endif /* __cplusplus */ /** @brief Annotated symbol is an alias for another symbol. */ #define __alias(name) __attribute__(( alias(#name) )) /** @brief Force a type to be aligned to a certain number of bytes. */ #define __aligned(bytes) __attribute__(( aligned(bytes) )) /* * gcc might try to be all cute and already predefine this for us. * I know gcc is not supported, but i'm still putting it inside an ifdef * just in case the clang people decide to do that as well at some point. */ #ifndef __always_inline /** @brief Always try to inline a function, even with optimizations disabled. */ #define __always_inline inline __attribute__(( always_inline )) #endif /** * @brief Annotated function behaves like an allocator, so the branch * prediction optimizer will assume it's unlikely to return `NULL`. */ #define __malloc_like __attribute__(( malloc )) /** * @brief Hint that the returned pointer will be able to hold at least as much * bytes as specified by argument number `argn` (counting from 1). */ #define __alloc_size(argn) __attribute__(( alloc_size(argn) )) #define __naked __attribute(( naked )) #define __noreturn __attribute__(( noreturn )) /** * @brief Hint that the returned pointer will be able to hold at least as much * bytes as the product of the arguments `argn1` and `argn2` (counting from 1). */ #define __alloc_size2(argn1, argn2) __attribute__(( alloc_size(argn1, argn2) )) /** * @brief Tightly pack all members of a structure without any padding at the * cost of performance. Should only be used for hardware registers and such. */ #define __packed __attribute__(( packed )) #define __printflike(fmt_argn, firstva_argn) \ __attribute__(( format(printf, fmt_argn, firstva_argn) )) /** * @brief Function does not have any side effects or internal state. * Subsequent calls with the same parameters always return the same result. */ #define __pure __attribute__(( pure )) /** * @brief Like `__pure`, and the function additionally does not access or * manipulate any volatile memory except its own stack. */ #define __pure2 __attribute__(( const )) /** @brief Put the annotated symbol in a specific section. */ #define __section(name) __attribute__(( section(name) )) /** @brief Mark the symbol as used, even if it really isn't. */ #define __used __attribute__(( used )) /** @brief Symbol may be silently redefined. */ #define __weak __attribute__(( weak )) #ifdef __cplusplus /** * @brief If for whatever reason we ever get into the unfortunate situation of * having to use C++, this annotation disables the funny name mangling feature * so we actually have a chance of accessing the symbol from assembly. It also * forcefully marks it as `__used` because a certain IDE doesn't have full * assembly support even after it being in the issue tracker for 4 years and * would therefore spit out annoying warnings about the symbol bring unused. */ #define __asmlink __used extern "C" #else /** * @brief In non-C++ code, this isn't really required because C doesn't do name * mangling, but we declare it `__used` because a certain IDE (*cough* CLion) * doesn't have full assembly support and shows annoying unused warnings */ #define __asmlink __used #endif #ifndef offsetof #define offsetof(type, member) __builtin_offsetof(type, member) #endif #ifndef typeof #define typeof(expr) __typeof(expr) #endif /* * These are hints for clang's branch optimizer which will try to arrange the * code to yield the best performance when a condition is true or false. * * Use it sparingly and only in performance critical places because the overhead * from rearranging and aligning the individual instructions can quickly make * the kernel image too big. * Also, only use it if you actually know *for sure* that a particular branch * is *very* unlikely to be hit. Most modern CPUs have become pretty good at * speculative execution (~~and intel even managed to make it buggy~~) and * probably do a better job optimizing themselves at runtime than you can here. * Finally, you don't need this when doing resource allocation failure checks, * because those functions are annotated with __malloc_like anyway. */ #define __predict_true(x) __builtin_expect(x, 1) #define __predict_false(x) __builtin_expect(x, 0)