diff options
Diffstat (limited to 'prism/compiler')
| -rw-r--r-- | prism/compiler/accel.h | 19 | ||||
| -rw-r--r-- | prism/compiler/align.h | 36 | ||||
| -rw-r--r-- | prism/compiler/exported.h | 24 | ||||
| -rw-r--r-- | prism/compiler/fallthrough.h | 22 | ||||
| -rw-r--r-- | prism/compiler/filesystem.h | 32 | ||||
| -rw-r--r-- | prism/compiler/flex_array.h | 19 | ||||
| -rw-r--r-- | prism/compiler/force_inline.h | 21 | ||||
| -rw-r--r-- | prism/compiler/format.h | 25 | ||||
| -rw-r--r-- | prism/compiler/inline.h | 17 | ||||
| -rw-r--r-- | prism/compiler/nodiscard.h | 22 | ||||
| -rw-r--r-- | prism/compiler/nonnull.h | 18 | ||||
| -rw-r--r-- | prism/compiler/unused.h | 18 |
12 files changed, 273 insertions, 0 deletions
diff --git a/prism/compiler/accel.h b/prism/compiler/accel.h new file mode 100644 index 0000000000..be23236d1d --- /dev/null +++ b/prism/compiler/accel.h @@ -0,0 +1,19 @@ +/** + * @file compiler/accel.h + */ +#ifndef PRISM_COMPILER_ACCEL_H +#define PRISM_COMPILER_ACCEL_H + +/** + * Platform detection for SIMD/fast-path implementations. At most one of these + * macros is defined, selecting the best available vectorization strategy. + */ +#if (defined(__aarch64__) && defined(__ARM_NEON)) || (defined(_MSC_VER) && defined(_M_ARM64)) +# define PRISM_HAS_NEON +#elif (defined(__x86_64__) && defined(__SSSE3__)) || (defined(_MSC_VER) && defined(_M_X64)) +# define PRISM_HAS_SSSE3 +#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define PRISM_HAS_SWAR +#endif + +#endif diff --git a/prism/compiler/align.h b/prism/compiler/align.h new file mode 100644 index 0000000000..22cb49a48c --- /dev/null +++ b/prism/compiler/align.h @@ -0,0 +1,36 @@ +/** + * @file compiler/align.h + */ +#ifndef PRISM_COMPILER_ALIGN_H +#define PRISM_COMPILER_ALIGN_H + +/** + * Compiler-agnostic macros for specifying alignment of types and variables. + */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L /* C11 or later */ + /** Specify alignment for a type or variable. */ + #define PRISM_ALIGNAS _Alignas + + /** Get the alignment requirement of a type. */ + #define PRISM_ALIGNOF _Alignof +#elif defined(__GNUC__) || defined(__clang__) + /** Specify alignment for a type or variable. */ + #define PRISM_ALIGNAS(size) __attribute__((aligned(size))) + + /** Get the alignment requirement of a type. */ + #define PRISM_ALIGNOF(type) __alignof__(type) +#elif defined(_MSC_VER) + /** Specify alignment for a type or variable. */ + #define PRISM_ALIGNAS(size) __declspec(align(size)) + + /** Get the alignment requirement of a type. */ + #define PRISM_ALIGNOF(type) __alignof(type) +#else + /** Void because this platform does not support specifying alignment. */ + #define PRISM_ALIGNAS(size) + + /** Fallback to sizeof as alignment requirement of a type. */ + #define PRISM_ALIGNOF(type) sizeof(type) +#endif + +#endif diff --git a/prism/compiler/exported.h b/prism/compiler/exported.h new file mode 100644 index 0000000000..823773ecbb --- /dev/null +++ b/prism/compiler/exported.h @@ -0,0 +1,24 @@ +/** + * @file compiler/exported.h + */ +#ifndef PRISM_COMPILER_EXPORTED_H +#define PRISM_COMPILER_EXPORTED_H + +/** + * By default, we compile with -fvisibility=hidden. When this is enabled, we + * need to mark certain functions as being publically-visible. This macro does + * that in a compiler-agnostic way. + */ +#ifndef PRISM_EXPORTED_FUNCTION +# ifdef PRISM_EXPORT_SYMBOLS +# ifdef _WIN32 +# define PRISM_EXPORTED_FUNCTION __declspec(dllexport) extern +# else +# define PRISM_EXPORTED_FUNCTION __attribute__((__visibility__("default"))) extern +# endif +# else +# define PRISM_EXPORTED_FUNCTION +# endif +#endif + +#endif diff --git a/prism/compiler/fallthrough.h b/prism/compiler/fallthrough.h new file mode 100644 index 0000000000..ce1b450e8a --- /dev/null +++ b/prism/compiler/fallthrough.h @@ -0,0 +1,22 @@ +/** + * @file compiler/fallthrough.h + */ +#ifndef PRISM_COMPILER_FALLTHROUGH_H +#define PRISM_COMPILER_FALLTHROUGH_H + +/** + * We use -Wimplicit-fallthrough to guard potentially unintended fall-through + * between cases of a switch. Use PRISM_FALLTHROUGH to explicitly annotate cases + * where the fallthrough is intentional. + */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L /* C23 or later */ + #define PRISM_FALLTHROUGH [[fallthrough]]; +#elif defined(__GNUC__) || defined(__clang__) + #define PRISM_FALLTHROUGH __attribute__((fallthrough)); +#elif defined(_MSC_VER) + #define PRISM_FALLTHROUGH __fallthrough; +#else + #define PRISM_FALLTHROUGH +#endif + +#endif diff --git a/prism/compiler/filesystem.h b/prism/compiler/filesystem.h new file mode 100644 index 0000000000..f988909db8 --- /dev/null +++ b/prism/compiler/filesystem.h @@ -0,0 +1,32 @@ +/** + * @file compiler/filesystem.h + * + * Platform detection for mmap and filesystem support. + */ +#ifndef PRISM_COMPILER_FILESYSTEM_H +#define PRISM_COMPILER_FILESYSTEM_H + +/** + * In general, libc for embedded systems does not support memory-mapped files. + * If the target platform is POSIX or Windows, we can map a file in memory and + * read it in a more efficient manner. + */ +#ifdef _WIN32 +# define PRISM_HAS_MMAP +#else +# include <unistd.h> +# ifdef _POSIX_MAPPED_FILES +# define PRISM_HAS_MMAP +# endif +#endif + +/** + * If PRISM_HAS_NO_FILESYSTEM is defined, then we want to exclude all filesystem + * related code from the library. All filesystem related code should be guarded + * by PRISM_HAS_FILESYSTEM. + */ +#ifndef PRISM_HAS_NO_FILESYSTEM +# define PRISM_HAS_FILESYSTEM +#endif + +#endif diff --git a/prism/compiler/flex_array.h b/prism/compiler/flex_array.h new file mode 100644 index 0000000000..7504b5fdd3 --- /dev/null +++ b/prism/compiler/flex_array.h @@ -0,0 +1,19 @@ +/** + * @file compiler/flex_array.h + */ +#ifndef PRISM_COMPILER_FLEX_ARRAY_H +#define PRISM_COMPILER_FLEX_ARRAY_H + +/** + * A macro for helper define a flexible array member. C99 supports `data[]`, GCC + * supports `data[0]` as an extension, and older compilers require `data[1]`. + */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + #define PM_FLEX_ARRAY_LENGTH /* data[] */ +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) + #define PM_FLEX_ARRAY_LENGTH 0 /* data[0] */ +#else + #define PM_FLEX_ARRAY_LENGTH 1 /* data[1] */ +#endif + +#endif diff --git a/prism/compiler/force_inline.h b/prism/compiler/force_inline.h new file mode 100644 index 0000000000..e189d592d6 --- /dev/null +++ b/prism/compiler/force_inline.h @@ -0,0 +1,21 @@ +/** + * @file compiler/force_inline.h + */ +#ifndef PRISM_COMPILER_FORCE_INLINE_H +#define PRISM_COMPILER_FORCE_INLINE_H + +#include "prism/compiler/inline.h" + +/** + * Force a function to be inlined at every call site. Use sparingly — only for + * small, hot functions where the compiler's heuristics fail to inline. + */ +#if defined(_MSC_VER) +# define PRISM_FORCE_INLINE __forceinline +#elif defined(__GNUC__) || defined(__clang__) +# define PRISM_FORCE_INLINE PRISM_INLINE __attribute__((always_inline)) +#else +# define PRISM_FORCE_INLINE PRISM_INLINE +#endif + +#endif diff --git a/prism/compiler/format.h b/prism/compiler/format.h new file mode 100644 index 0000000000..32f4c3c6d7 --- /dev/null +++ b/prism/compiler/format.h @@ -0,0 +1,25 @@ +/** + * @file compiler/format.h + */ +#ifndef PRISM_COMPILER_FORMAT_H +#define PRISM_COMPILER_FORMAT_H + +/** + * Certain compilers support specifying that a function accepts variadic + * parameters that look like printf format strings to provide a better developer + * experience when someone is using the function. This macro does that in a + * compiler-agnostic way. + */ +#if defined(__GNUC__) +# if defined(__MINGW_PRINTF_FORMAT) +# define PRISM_ATTRIBUTE_FORMAT(fmt_idx_, arg_idx_) __attribute__((format(__MINGW_PRINTF_FORMAT, fmt_idx_, arg_idx_))) +# else +# define PRISM_ATTRIBUTE_FORMAT(fmt_idx_, arg_idx_) __attribute__((format(printf, fmt_idx_, arg_idx_))) +# endif +#elif defined(__clang__) +# define PRISM_ATTRIBUTE_FORMAT(fmt_idx_, arg_idx_) __attribute__((__format__(__printf__, fmt_idx_, arg_idx_))) +#else +# define PRISM_ATTRIBUTE_FORMAT(fmt_idx_, arg_idx_) +#endif + +#endif diff --git a/prism/compiler/inline.h b/prism/compiler/inline.h new file mode 100644 index 0000000000..856a375691 --- /dev/null +++ b/prism/compiler/inline.h @@ -0,0 +1,17 @@ +/** + * @file compiler/inline.h + */ +#ifndef PRISM_COMPILER_INLINE_H +#define PRISM_COMPILER_INLINE_H + +/** + * Old Visual Studio versions do not support the inline keyword, so we need to + * define it to be __inline. + */ +#if defined(_MSC_VER) && !defined(inline) +# define PRISM_INLINE __inline +#else +# define PRISM_INLINE inline +#endif + +#endif diff --git a/prism/compiler/nodiscard.h b/prism/compiler/nodiscard.h new file mode 100644 index 0000000000..ccd6c00719 --- /dev/null +++ b/prism/compiler/nodiscard.h @@ -0,0 +1,22 @@ +/** + * @file compiler/nodiscard.h + */ +#ifndef PRISM_COMPILER_NODISCARD_H +#define PRISM_COMPILER_NODISCARD_H + +/** + * Mark the return value of a function as important so that the compiler warns + * if a caller ignores it. This is useful for functions that return error codes + * or allocated resources that must be freed. + */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L +# define PRISM_NODISCARD [[nodiscard]] +#elif defined(__GNUC__) || defined(__clang__) +# define PRISM_NODISCARD __attribute__((__warn_unused_result__)) +#elif defined(_MSC_VER) +# define PRISM_NODISCARD _Check_return_ +#else +# define PRISM_NODISCARD +#endif + +#endif diff --git a/prism/compiler/nonnull.h b/prism/compiler/nonnull.h new file mode 100644 index 0000000000..9d19355665 --- /dev/null +++ b/prism/compiler/nonnull.h @@ -0,0 +1,18 @@ +/** + * @file compiler/nonnull.h + */ +#ifndef PRISM_COMPILER_NONNULL_H +#define PRISM_COMPILER_NONNULL_H + +/** + * Mark the parameters of a function as non-null. This allows the compiler to + * warn if a caller passes NULL for a parameter that should never be NULL. The + * arguments are the 1-based indices of the parameters. + */ +#if defined(__GNUC__) || defined(__clang__) +# define PRISM_NONNULL(...) __attribute__((__nonnull__(__VA_ARGS__))) +#else +# define PRISM_NONNULL(...) +#endif + +#endif diff --git a/prism/compiler/unused.h b/prism/compiler/unused.h new file mode 100644 index 0000000000..6a9e125dde --- /dev/null +++ b/prism/compiler/unused.h @@ -0,0 +1,18 @@ +/** + * @file compiler/unused.h + */ +#ifndef PRISM_COMPILER_UNUSED_H +#define PRISM_COMPILER_UNUSED_H + +/** + * GCC will warn if you specify a function or parameter that is unused at + * runtime. This macro allows you to mark a function or parameter as unused in a + * compiler-agnostic way. + */ +#if defined(__GNUC__) +# define PRISM_UNUSED __attribute__((unused)) +#else +# define PRISM_UNUSED +#endif + +#endif |
