You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
4.7 KiB
C
138 lines
4.7 KiB
C
/* Copyright (C) 2021,2022 fef <owo@fef.moe>. All rights reserved. */
|
|
|
|
#pragma once
|
|
|
|
#ifndef __clang__
|
|
#error "Unsupported compiler, please use clang"
|
|
#endif
|
|
|
|
#include <gay/_null.h>
|
|
|
|
#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)
|