embed_compiler_directives.h¶
Source: include/embed_compiler_directives.h
Compiler feature checks, attribute wrappers, diagnostic pragmas, an argument count, and target flags.
Note: This header has no
extern "C"guard of its own, because it defines that guard asEMBED_BEGIN_DECLS. Each name here is a macro, and a macro has no linkage to mangle.Note: If your library uses this one, make aliases of these macros under your own prefix. Do not copy them into your own tree. A copy drifts when this header changes.
Macros¶
EMBED_GNU_ATTRIBUTES¶
#if defined(__GNUC__) || defined(__clang__)
#define EMBED_GNU_ATTRIBUTES 1
#else
#define EMBED_GNU_ATTRIBUTES 0
#endif
Set to 1 where the compiler defines __GNUC__ or __clang__, 0 otherwise.
Note:
EMBED_HAS_ATTRIBUTEfalls back to this value where the compiler has no__has_attribute. A compiler too old for__has_attributeusually still accepts the GNU attributes, and a 0 here would turn all of them off.Note: This macro always has a value, 0 or 1. Test it with
#if.#ifdefis true either way.
EMBED_HAS_ATTRIBUTE¶
#if defined(__has_attribute)
#define EMBED_HAS_ATTRIBUTE(attribute_) __has_attribute(attribute_)
#else
#define EMBED_HAS_ATTRIBUTE(attribute_) EMBED_GNU_ATTRIBUTES
#endif
Expands to __has_attribute(attribute_) where the compiler has __has_attribute.
[in]:attribute_Attribute name, as__has_attributetakes it.
**Returns:** The value that __has_attribute gives for attribute_.
Note: Each attribute macro below goes through this one. A question to the compiler about an attribute is more reliable than a test of which compiler it is.
Warning: Expands to
EMBED_GNU_ATTRIBUTESwhere the compiler has no__has_attribute, and discardsattribute_. Then each attribute gets the same answer. A compiler without__has_attributegets all of them or none.
EMBED_HAS_BUILTIN¶
#if defined(__has_builtin)
#define EMBED_HAS_BUILTIN(builtin_) __has_builtin(builtin_)
#else
#define EMBED_HAS_BUILTIN(builtin_) 0
#endif
Expands to __has_builtin(builtin_) where the compiler has __has_builtin.
[in]:builtin_Builtin name, as__has_builtintakes it.
**Returns:** The value that __has_builtin gives for builtin_.
Note: This macro is the builtin form of
EMBED_HAS_ATTRIBUTE. Use it to gate a builtin as you gate an attribute.Warning: Without
__has_builtinthis expands to 0 and discardsbuiltin_. The fallback is 0, because a builtin that the compiler does not have fails to compile.EMBED_HAS_ATTRIBUTEfalls back to a guess instead, because the compiler ignores an attribute that it does not have.
EMBED_STATIC_ASSERT¶
#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L)
#elif defined(__cplusplus) || __STDC_VERSION__ >= 202311L
#define EMBED_STATIC_ASSERT(cond_, msg_) static_assert(cond_, msg_)
#else
#define EMBED_STATIC_ASSERT(cond_, msg_) _Static_assert(cond_, msg_)
#endif
Expands to a static assertion of two operands.
[in]:cond_Constant expression, passed through with no change.[in]:msg_Message operand, passed through with no change.
Note: This macro gives one name for the assertion across C11, C23, and C++. Each file here that claims a width or a layout uses it.
Note: C++ and C23 get
static_assert, which is a keyword in both. All other revisions get_Static_assert, the C11 keyword.Note: The
__cplusplusarm is necessary. No C++ compiler defines__STDC_VERSION__, and without that arm the#errorbelow fires on each C++ build.Note: Neither arm includes
<assert.h>. Both names are keywords in the revision that takes them.Note: The expansion has no semicolon at its end. Write one at the call site.
Warning:
#errorbelow C11, where neither keyword exists. Without it, the name would parse as a function declaration that returns implicit int. Then each assertion in the build would compile and check nothing.
EMBED_BEGIN_DECLS¶
#ifdef __cplusplus
#define EMBED_BEGIN_DECLS \
extern "C" \
{
#else
#define EMBED_BEGIN_DECLS
#endif
Expands to extern "C" { where the compiler defines __cplusplus.
Note: This library is C. A C++ translation unit that includes these headers needs the guard to reach the symbols by their names without the C++ mangle.
Warning: The expansion leaves a
{open.EMBED_END_DECLScloses it.Note: Expands to nothing where the compiler does not define
__cplusplus.
Expands to nothing where the compiler does not define __cplusplus. This arm opens no brace.
EMBED_END_DECLS¶
Expands to } where the compiler defines __cplusplus, and closes EMBED_BEGIN_DECLS.
Expands to nothing where the compiler does not define __cplusplus.
EMBED_INLINE¶
#ifndef EMBED_INLINE
#if EMBED_HAS_ATTRIBUTE(always_inline)
#define EMBED_INLINE static inline __attribute__((always_inline))
#else
#define EMBED_INLINE static inline
#endif
#endif
Expands to static inline followed by __attribute__((always_inline)).
Note: GCC and clang put the body in line, also where their size heuristic would keep it out of line. A plain
static inlinegives that decision to the compiler.Note: Expands to
static inlinewhereEMBED_HAS_ATTRIBUTE(always_inline)is 0. The code stays correct. It can run slower.Warning: This header defines nothing where the build defines
EMBED_INLINEfirst. Define it ahead of this header to set your own policy for the inline expansion.
EMBED_FLATTEN¶
#if EMBED_HAS_ATTRIBUTE(flatten)
#define EMBED_FLATTEN __attribute__((flatten))
#else
#define EMBED_FLATTEN
#endif
Expands to __attribute__((flatten)) where EMBED_HAS_ATTRIBUTE(flatten) is not zero.
Note: Put this on a function, and GCC or clang puts each call of that function in line. This includes the bodies that their size heuristic would skip.
EMBED_INLINEgoes on the callee. This macro goes on the caller.Note: Each call site of the marked function holds the code put in line. Put it on one hot function.
Warning: The bodies of the calls must be visible. Without link-time optimization this does nothing across translation units.
Warning: Expands to nothing where
EMBED_HAS_ATTRIBUTE(flatten)is 0. The code stays correct. It can run slower.
EMBED_ENUM_BYTE¶
#if defined(__clang__) && defined(_MSC_VER)
#define EMBED_ENUM_BYTE(name_, ...) \
typedef enum : unsigned char \
{ \
__VA_ARGS__ \
} name_
#elif EMBED_HAS_ATTRIBUTE(packed)
#define EMBED_ENUM_BYTE(name_, ...) \
typedef enum __attribute__((packed)) \
{ \
__VA_ARGS__ \
} name_
#elif defined(__cplusplus)
#define EMBED_ENUM_BYTE(name_, ...) \
typedef enum : unsigned char \
{ \
__VA_ARGS__ \
} name_
#else
#define EMBED_ENUM_BYTE(name_, ...) \
enum \
{ \
__VA_ARGS__ \
}; \
typedef unsigned char name_
#endif
Declares name_ as a one-byte enumeration of the enumerators given, on each compiler.
[in]:name_The name of the type.[in]: ... The enumerators, as the braces of an enum hold them.
Note: Where the compiler can pin an enum to one byte,
name_is that enum. Then the compiler still checks a switch on it, or a value of another enum.Note: Clang on the MSVC ABI and C++ take the fixed type
: unsigned char. C++11 made that form standard, and clang takes it in C as the C23 form.Note: Clang on the MSVC ABI also accepts the packed attribute, but it keeps the enum as wide as an int, as MSVC does. So that arm takes the fixed type before it looks for the attribute. Each other compiler with the packed attribute takes the attribute.
Note: Where the compiler cannot pin an enum, MSVC's C among them, the enumerators become constants and
name_is an unsigned char. The width is one byte either way. A struct that holdsname_has the same layout on each compiler.Warning: An enumerator above 255 or below 0 fails the build on the arms of the fixed type. It widens the enum on the attribute arm. On the unsigned char arm, a store cuts it to a byte.
embed_types.h declares a probe and asserts its size. That assertion also finds a compiler that accepts the attribute and ignores it.
EMBED_ALIGN¶
#if EMBED_HAS_ATTRIBUTE(aligned)
#define EMBED_ALIGN(bytes_) __attribute__((aligned(bytes_)))
#elif defined(_MSC_VER)
#if defined(__cplusplus)
#define EMBED_ALIGN(bytes_) alignas(bytes_)
#else
#define EMBED_ALIGN(bytes_) _Alignas(bytes_)
#endif
#else
#define EMBED_ALIGN(bytes_)
#endif
Expands to __attribute__((aligned(bytes_))) where EMBED_HAS_ATTRIBUTE(aligned) is not zero.
[in]:bytes_The alignment that the attribute takes.
Note: This macro works both ways. It can raise the alignment of an object above its natural alignment, or lower it to 1.
EMBED_RAWuses the form that lowers it to 1.Warning: Expands to nothing where
EMBED_HAS_ATTRIBUTE(aligned)is 0, and discardsbytes_. Then an object that you mean to align more keeps its natural alignment. A type that you mean to drop to alignment 1 also keeps its natural alignment, and the code still reads it from any address.
EMBED_ALIAS¶
#if EMBED_HAS_ATTRIBUTE(may_alias)
#define EMBED_ALIAS __attribute__((may_alias))
#else
#define EMBED_ALIAS
#endif
Expands to __attribute__((may_alias)) where EMBED_HAS_ATTRIBUTE(may_alias) is not zero.
Note: C lets a character type alias any object. A read of an eight-bit array through a word lvalue goes the other way, and C leaves that read undefined. This attribute on the word type gives the read a defined result.
Warning: Expands to nothing where
EMBED_HAS_ATTRIBUTE(may_alias)is 0. Nothing diagnoses that. The code compiles, and the compiler can assume that the two accesses never touch the same memory.
EMBED_RAW¶
#if EMBED_HAS_ATTRIBUTE(aligned)
#define EMBED_RAW EMBED_ALIGN(1) EMBED_ALIAS
#else
#define EMBED_RAW EMBED_ALIAS
#endif
Expands to EMBED_ALIGN(1) followed by EMBED_ALIAS.
Note: A read of a word from an address that is not a multiple of its width needs both attributes.
EMBED_ALIGN(1)stops the compiler from an assumption about the alignment.EMBED_ALIASlets the read reach bytes that another type owns. Either one alone leaves the access undefined.Note: This macro holds both attributes. If each declaration writes out the pair, the two can drift apart at the first edit of one.
Warning: Both warnings above apply here. Nothing diagnoses either failure.
EMBED_HOST_DEVICE¶
#if defined(__CUDACC__)
#define EMBED_HOST_DEVICE __host__ __device__
#else
#define EMBED_HOST_DEVICE
#endif
Expands to __host__ __device__ under nvcc, and to nothing on other compilers.
Note: A function with this macro compiles into each of the two passes of nvcc from one definition. Other compilers have one pass, and the function compiles into it. Each entry of
embed_atomic.h andembed_lane.h has this macro, so one source runs on the host and on the device.Note: Both arms define this macro.
EMBED_HAS_VECTOR_SIZE¶
#if EMBED_HAS_ATTRIBUTE(vector_size)
#define EMBED_HAS_VECTOR_SIZE 1
#else
#define EMBED_HAS_VECTOR_SIZE 0
#endif
Set to 1 where EMBED_HAS_ATTRIBUTE(vector_size) is not zero, else 0.
Note: The
vector_sizeattribute on a scalar type makes a type that the compiler keeps in a vector register. The plain operators then run over each element at once. The lane header takes its vector arm where this macro is 1, and its portable arm where it is 0.Note: Both arms define this macro. Test it with
#if.
EMBED_VECTOR¶
#if EMBED_HAS_VECTOR_SIZE
#define EMBED_VECTOR(bytes_) __attribute__((vector_size(bytes_)))
#else
#define EMBED_VECTOR(bytes_)
#endif
Expands to __attribute__((vector_size(bytes_))) where EMBED_HAS_VECTOR_SIZE is 1.
[in]:bytes_The width of the vector in bytes, a power of two and a multiple of the size of the scalar.
Warning: Expands to nothing where
EMBED_HAS_VECTOR_SIZEis 0, and discardsbytes_: the type is the scalar alone. A declaration that needs the width testsEMBED_HAS_VECTOR_SIZEfirst. On the other arm it declares a struct of the elements, asembed_lane.h does.
EMBED_VECTOR_REGISTER_BITS¶
#if defined(__AVX512F__)
#define EMBED_VECTOR_REGISTER_BITS 512
#elif defined(__AVX2__)
#define EMBED_VECTOR_REGISTER_BITS 256
#elif defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64)
#define EMBED_VECTOR_REGISTER_BITS 128
#else
#define EMBED_VECTOR_REGISTER_BITS 0
#endif
The width in bits of the widest vector register that the target compiles for. It is 512 under AVX-512, 256 under AVX2, 128 under SSE2 or NEON, and 0 where the target has none.
Note: The compiler defines a macro for each instruction set that it emits, and this value comes from those macros. The build supplies no width of its own here. A flag that turns on an instruction set changes this value with it. The lane header derives the width of the lane from this value where the build does not define one.
Note: Both arms define this macro. Test it with
#if.
EMBED_HAS_BYTE_MASK_256¶
#if defined(__AVX2__) && EMBED_HAS_BUILTIN(__builtin_ia32_pmovmskb256)
#define EMBED_HAS_BYTE_MASK_256 1
#else
#define EMBED_HAS_BYTE_MASK_256 0
#endif
Set to 1 where the target runs AVX2 and the compiler has the builtin for the mask of 32 bytes, else 0. The builtin reads the sign bit of each byte into an integer.
Note: The builtin is the compiler's own name for the instruction, and it needs no vendor header. A byte compare of two vectors of 32 bytes sets each equal byte to all ones. This builtin then reads those bytes into one bit for each byte, in one instruction.
Note: Both arms define this macro. Test it with
#if.
EMBED_BYTE_MASK_256¶
#if EMBED_HAS_BYTE_MASK_256
#define EMBED_BYTE_MASK_256(chars_) __builtin_ia32_pmovmskb256(chars_)
#else
#define EMBED_BYTE_MASK_256(chars_) 0
#endif
The sign bits of 32 bytes as an int, bit 0 from the first byte, where EMBED_HAS_BYTE_MASK_256 is 1.
[in]:chars_A vector of 32 char.
Warning: Expands to 0 where
EMBED_HAS_BYTE_MASK_256is 0, and discardschars_. A use tests the flag first and takes another arm where it is 0, asembed_lane.h does.
EMBED_HAS_BYTE_MASK_128¶
#if defined(__SSE2__) && EMBED_HAS_BUILTIN(__builtin_ia32_pmovmskb128)
#define EMBED_HAS_BYTE_MASK_128 1
#else
#define EMBED_HAS_BYTE_MASK_128 0
#endif
Set to 1 where the target runs SSE2 and the compiler has the builtin for the mask of 16 bytes, else 0. The builtin reads the sign bit of each byte into an integer.
Note: Both arms define this macro. Test it with
#if.
EMBED_BYTE_MASK_128¶
#if EMBED_HAS_BYTE_MASK_128
#define EMBED_BYTE_MASK_128(chars_) __builtin_ia32_pmovmskb128(chars_)
#else
#define EMBED_BYTE_MASK_128(chars_) 0
#endif
The sign bits of 16 bytes as an int, bit 0 from the first byte, where EMBED_HAS_BYTE_MASK_128 is 1.
[in]:chars_A vector of 16 char.
Warning: Expands to 0 where
EMBED_HAS_BYTE_MASK_128is 0, and discardschars_. A use tests the flag first and takes another arm where it is 0, asembed_lane.h does.
EMBED_UNUSED¶
#if EMBED_HAS_ATTRIBUTE(unused)
#define EMBED_UNUSED __attribute__((unused))
#else
#define EMBED_UNUSED
#endif
Expands to __attribute__((unused)) where EMBED_HAS_ATTRIBUTE(unused) is not zero.
Note: Put this on a definition that the code can leave with no reference. A static definition in a header goes into each translation unit that includes it. A unit that never uses its copy gives a warning.
Warning: Expands to nothing where
EMBED_HAS_ATTRIBUTE(unused)is 0. Then the warning comes back. The code stays correct.
EMBED_WEAK¶
#if EMBED_HAS_ATTRIBUTE(weak)
#define EMBED_WEAK __attribute__((weak))
#else
#define EMBED_WEAK
#endif
Expands to __attribute__((weak)) where EMBED_HAS_ATTRIBUTE(weak) is not zero.
Note: The linker takes a strong definition of a name before a weak one. With no strong definition, the weak one links. So a default can ship here, and a port can replace it with no edit to this file.
Warning: Expands to nothing where
EMBED_HAS_ATTRIBUTE(weak)is 0. The default then has ordinary external linkage. A replacement becomes a duplicate symbol, and the link fails.
EMBED_WEAK_NAME¶
#if !EMBED_HAS_ATTRIBUTE(weak) && defined(_MSC_VER)
#define EMBED_WEAK_NAME(name_) name_##_default
#else
#define EMBED_WEAK_NAME(name_) name_
#endif
The name of the definition of a weak default. It is name_ itself where EMBED_HAS_ATTRIBUTE(weak) is not zero, and name_ with _default after it under MSVC without the attribute.
[in]:name_The name that callers reach and that a port defines.
**Returns:** The name of the definition of the default.
Note: The MSVC linker has no weak definition. Its /alternatename option gives a second name to a name that no unit defines. So the default stands under the second name. A port that defines
name_then wins, with no duplicate.EMBED_WEAK_DEFAULTemits that alternate name.Note: Write both at the default:
EMBED_WEAK_DEFAULT(name_)at file scope, then the definition withEMBED_WEAKandEMBED_WEAK_NAME(name_).Warning: Under MSVC, a call to the default by
name_in the unit that defines it goes through the linker, and never in line.
EMBED_WEAK_DEFAULT¶
#if !EMBED_HAS_ATTRIBUTE(weak) && defined(_MSC_VER) && defined(_M_IX86)
#define EMBED_WEAK_DEFAULT(name_) __pragma(comment(linker, "/alternatename:_" #name_ "=_" #name_ "_default"))
#elif !EMBED_HAS_ATTRIBUTE(weak) && defined(_MSC_VER)
#define EMBED_WEAK_DEFAULT(name_) __pragma(comment(linker, "/alternatename:" #name_ "=" #name_ "_default"))
#else
#define EMBED_WEAK_DEFAULT(name_)
#endif
Emits the alternate name of the linker for a weak default under MSVC without the weak attribute, and nothing on other compilers.
[in]:name_The name that callers reach and that a port defines.
Note: A C symbol on 32-bit x86 has an underscore at its start, and the linker reads the decorated names. So the x86 arm adds one underscore to each side.
EMBED_DIAGNOSTIC_STRING¶
Expands to #text_.
[in]:text_The tokens to make into a string.
**Returns:** text_ as a string literal.
Note:
EMBED_DIAGNOSTIC_IGNOREcalls this macro._Pragmatakes a string literal, and this macro makes the full pragma line into one.Note: This macro stands above the compiler arms below. A definition in each arm would put two copies in the file, and they would drift at the first edit of one.
EMBED_DIAGNOSTIC_PUSH¶
#if defined(__clang__)
#define EMBED_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
#elif defined(__GNUC__)
#define EMBED_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
#else
#define EMBED_DIAGNOSTIC_PUSH
#endif
Expands to _Pragma("clang diagnostic push") where the compiler defines __clang__.
Note: This macro saves the current diagnostic state. Without a save ahead of it, an
EMBED_DIAGNOSTIC_IGNOREstays in force to the end of the translation unit. Put eachEMBED_DIAGNOSTIC_IGNOREbetween this macro andEMBED_DIAGNOSTIC_POP.
Expands to _Pragma("GCC diagnostic push") where the compiler defines __GNUC__ and not __clang__.
Note: This macro is the GCC form of the clang push above. See that block for where to put
EMBED_DIAGNOSTIC_IGNORE.
Expands to nothing where the compiler defines neither __clang__ nor __GNUC__.
Note: A compiler with no diagnostic pragma has no state to save. The code that calls these macros keeps the same push, ignore, and pop shape on each compiler, and this arm costs nothing.
EMBED_DIAGNOSTIC_POP¶
#if defined(__clang__)
#define EMBED_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
#elif defined(__GNUC__)
#define EMBED_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#else
#define EMBED_DIAGNOSTIC_POP
#endif
Expands to _Pragma("clang diagnostic pop") where the compiler defines __clang__.
Note: This macro restores the state that
EMBED_DIAGNOSTIC_PUSHsaved, and that ends the suppression. Without it, the suppression runs to the end of the translation unit. Nothing reports that, because the suppressed warning is the warning that would report it.
Expands to _Pragma("GCC diagnostic pop") where the compiler defines __GNUC__ and not __clang__.
Note: This macro is the GCC form of the clang pop above. See that block for what occurs without it.
Expands to nothing where the compiler defines neither __clang__ nor __GNUC__.
Note: This macro pairs with
EMBED_DIAGNOSTIC_PUSH. That macro also expands to nothing on this arm.
EMBED_DIAGNOSTIC_IGNORE¶
#if defined(__clang__)
#define EMBED_DIAGNOSTIC_IGNORE(warning_) _Pragma(EMBED_DIAGNOSTIC_STRING(clang diagnostic ignored warning_))
#elif defined(__GNUC__)
#define EMBED_DIAGNOSTIC_IGNORE(warning_) _Pragma(EMBED_DIAGNOSTIC_STRING(GCC diagnostic ignored warning_))
#else
#define EMBED_DIAGNOSTIC_IGNORE(warning_)
#endif
Expands to a clang pragma that ignores the named warning.
[in]:warning_Warning name as a string literal, such as "-Wpadded".
Note: This macro turns off exactly one warning. See
EMBED_DIAGNOSTIC_PUSHfor where to put it.Note:
EMBED_DIAGNOSTIC_STRINGmakes the full pragma text into a string,warning_with it.
Expands to a GCC pragma that ignores the named warning.
[in]:warning_Warning name as a string literal, such as "-Wpadded".
Note: The compiler takes this arm where it defines
__GNUC__and not__clang__.Note: This macro turns off exactly one warning. See
EMBED_DIAGNOSTIC_PUSHfor where to put it.
Expands to nothing where the compiler defines neither __clang__ nor __GNUC__.
[in]:warning_Warning name as a string literal, which this arm discards.
Warning: This arm does not stop the warning. A compiler that raises it still reports it. A report is the safe direction.
EMBED_BIG_ENDIAN¶
#ifndef EMBED_BIG_ENDIAN
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define EMBED_BIG_ENDIAN 1
#else
#define EMBED_BIG_ENDIAN 0
#endif
#endif
Set to 1 where __BYTE_ORDER__ and __ORDER_BIG_ENDIAN__ both have a value and the two are equal, 0 otherwise.
Note: A consumer that reads or writes values of more than one byte, one byte at a time, branches on this macro. Nothing in this library reads it.
Warning: This header defines nothing where the build defines
EMBED_BIG_ENDIANfirst. A compiler that defines neither__BYTE_ORDER__nor__ORDER_BIG_ENDIAN__falls to 0 here. For a big-endian target with such a compiler, set the macro on the command line.
EMBED_FAST_UNALIGNED_LOAD¶
#ifndef EMBED_FAST_UNALIGNED_LOAD
#if defined(__ARM_FEATURE_UNALIGNED)
#define EMBED_FAST_UNALIGNED_LOAD 1
#else
#define EMBED_FAST_UNALIGNED_LOAD 0
#endif
#endif
Set to 1 where the target loads a word from any address in one instruction, 0 otherwise.
Note: An unaligned load compiles on any target through a type with
EMBED_RAW. This flag is 1 only where the target does that load in one instruction.Note: GCC and clang define
__ARM_FEATURE_UNALIGNEDon the targets that can do it. The option-mno-unaligned-accessturns it off.Note: This macro names no target. The flag falls to 0 wherever that macro is absent, and 0 is the safe answer. A consumer that sees 0 takes the path one byte at a time, which is correct on each target.
Warning: This header defines nothing where the build defines
EMBED_FAST_UNALIGNED_LOADfirst. Nothing in this library reads this flag.