CPU Features and Defines
The following page is our field notes for compiler versions supporting CPU features. They are used extensively in config.h
to define macros like CRYPTOPP_SSE42_AVAILABLE
and CRYPTOPP_NEON_AVAILABLE
.
SSE2, SSE3 and SSSE3 are usually always available due to Wei's inline assembly. The inline ASM is still important today because x86 IoT devices use low power Atoms that only incorporate the early ISAs (sometimes they include SSE4.1, too). Moving forward, we are concentrating on intrinsics because (1) they are available for ARM and IA32, and (2) every major compiler consumes them, including Microsoft, LLVM, Intel, GNU and Sun.
The emerging pain points are (1) new compiler on old OS; and (2) new compiler with old linker. An example of (1) is building Clang from sources on CentOS 5. An example of (2) is modern OpenBSD 6 with its ancient LD linker from the GPL-2 days. They are why a defines like CRYPTOPP_NO_SSE4
are sometimes set.
Some of the Apple Clang versions may be incorrect. That's because we don't always have a copy of Apple Xcode to test. In this case, we test LLVM Clang, and then lookup what version of LLVM Clang corresponds (by date) to the Xcode release of Apple's Clang. The lookup is available on Yamaya's GitHub at Xcode clang version record.
Intel X86
In the table below, the define prefix of CRYPTOPP_
is omitted for brevity and table formatting. However SSE41_AVAILABLE
should be used as CRYPTOPP_SSE41_AVAILABLE
. MSVC is the version of cl.exe
, not the Visual Studio version the compiler was released under.
For MSVC version 15.00.30729 (Visual Studio 2008 Update1), _MSC_FULL_VER >= 150030729
is used. _MSC_FULL_VER
macros can be found on a website in Asia at Visual Studioのバージョンと判別マクロ. Mysteriously, MSDN does not provide them.
Feature | Define | MSVC | GCC | ICC | LLVM Clang |
Apple Clang |
SunCC |
---|---|---|---|---|---|---|---|
Intel SSE4.1 | SSE41_AVAILABLE | 14.00 | 4.3 | 10.0 | 2.3 | 4.0 | 0x5110 |
Intel SSE4.2 | SSE42_AVAILABLE | 15.00 | 4.3 | 10.0 | 2.3 | 4.0 | 0x5110 |
Intel CRC | SSE42_AVAILABLE | 15.00 | 4.3 | 10.0 | 2.3 | 4.0 | 0x5110 |
Intel AES | AESNI_AVAILABLE | 15.00.30729 | 4.3 | 11.00 | 3.2 | 5.0 | 0x5120 |
Intel CLMUL | CLMUL_AVAILABLE | 15.00.30729 | 4.3 | 11.00 | 3.2 | 5.0 | 0x5120 |
Intel AVX | AVX_AVAILABLE | 16.00 | 4.6 | 11.10 | 3.3 | 5.0 | 0x5130 |
Intel AVX2 | AVX2_AVAILABLE | 18.00 | 4.7 | 12.00 | 3.3 | 5.0 | 0x5130 |
Intel SHA | SHANI_AVAILABLE | 19.00 | 4.9 | 13.00 | 3.4 | 5.1 | 0x5140 |
ARM, NEON and ARMv8
In the table below, the define prefix of CRYPTOPP_
is omitted for brevity and table formatting. However ARM_NEON_AVAILABLE
should be used as CRYPTOPP_ARM_NEON_AVAILABLE
. MSVC is the version of cl.exe
, not the Visual Studio version the compiler was released under.
Feature | Define | MSVC | GCC | ICC | LLVM Clang |
Apple Clang |
SunCC |
---|---|---|---|---|---|---|---|
ARM NEON | ARM_NEON_AVAILABLE | 17.00 | 4.3 | - | 2.3 | 4.3 | - |
ARM CRC | ARM_CRC32_AVAILABLE | 20.00 | 4.8 | - | 3.5 | 6.0 | - |
ARM AES | ARM_AES_AVAILABLE | 20.00 | 4.8 | - | 3.5 | 6.0 | - |
ARM CLMUL | ARM_PMULL_AVAILABLE | 20.00 | 4.8 | - | 3.5 | 6.0 | - |
ARM SHA | ARM_SHA_AVAILABLE | 20.00 | 4.8 | - | 3.5 | 6.0 | - |
Sample Defines
A typical X86 define would look like below, and can be found in config.h
.
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_SHA) && \ (defined(__SHA__) || (CRYPTOPP_MSC_VERSION >= 1900) || \ (CRYPTOPP_GCC_VERSION >= 40900) || (__INTEL_COMPILER >= 1300) || \ (CRYPTOPP_LLVM_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50100)) # define CRYPTOPP_SHANI_AVAILABLE 1 #endif
A typical ARM NEON define looks like below, and can be found in config.h
.
#if !defined(CRYPTOPP_ARM_NEON_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM) # if defined(__ARM_NEON__) || defined(__ARM_FEATURE_NEON) || (CRYPTOPP_MSC_VERSION >= 1700) || \ (CRYPTOPP_GCC_VERSION >= 40800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30500) # define CRYPTOPP_ARM_NEON_AVAILABLE 1 # endif #endif
A typical ARMv8 define looks like below, and can be found in config.h
.
#if !defined(CRYPTOPP_ARM_CRC32_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM) # if defined(__ARM_FEATURE_CRC32) || (CRYPTOPP_MSC_VERSION >= 2000) || \ defined(__aarch32__) || defined(__aarch64__) # define CRYPTOPP_ARM_CRC32_AVAILABLE 1 # endif #endif