CPU Features and Defines

From Crypto++ Wiki
Jump to navigation Jump to search

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