2

I'm having a hard time determining ARM-64 features across platforms (Linux, Apple, Windows Phone and Windows Store) and toolchains (ARMCC, GCC, Clang, MSVC). According to ARM's documentation at Compiler Toolchain for __ARM_FEATURE_CRYPTO:

Set to 1 if the target has crypto instructions.

Back tracking a bit further, and according to the ARM C Language Extensions 2.0 (ACLE):

6.5.7 Crypto Extension

__ARM_FEATURE_CRYPTO is defined to 1 if the Crypto instructions are supported and the intrinsics defined in 12.3.14 are available. These instructions include AES{E, D}, SHA1{C, P, M} etc. This is only available when __ARM_ARCH>= 8.

And:

2.3.14 Crypto Intrinsics

Crypto extension instructions are part of the Advanced SIMD instruction set. These intrinsics are available when __ARM_FEATURE_CRYPTO is defined ...

If you notice, section 6.5.7 defers to 2.3.14, and 2.3.14 circles back and defers to 6.5.7.

What are the instructions that will trigger the define? And when the instructions(s) are present, what intrinisics are available?


From a 64-bit ARMv8-a LeMaker HiKey (asimd is neon in disguise):

$ cat /proc/cpuinfo 
Processor   : AArch64 Processor rev 3 (aarch64)
processor   : 0
...
Features    : fp asimd evtstrm aes pmull sha1 sha2 crc32 

And from the same LeMaker HiKey dev board (-march=native is not available):

$ gcc -dM -E -march=armv8-a -mcpu=cortex-a53 - < /dev/null | egrep -i '(arm|aarch|neon|crc|crypto)'
#define __AARCH64_CMODEL_SMALL__ 1
#define __aarch64__ 1
#define __AARCH64EL__ 1
#define __ARM_NEON 1

And from an Apple toolchain with -arch arm64:

$ clang++ -arch arm64 -dM -E - < /dev/null | sort | egrep -i '(arm|aarch|neon|crc)'
#define __AARCH64EL__ 1
#define __AARCH64_SIMD__ 1
#define __ARM64_ARCH_8__ 1
#define __ARM_64BIT_STATE 1
#define __ARM_ACLE 200
#define __ARM_ALIGN_MAX_STACK_PWR 4
#define __ARM_ARCH 8
#define __ARM_ARCH_ISA_A64 1
#define __ARM_ARCH_PROFILE 'A'
#define __ARM_FEATURE_CLZ 1
#define __ARM_FEATURE_CRYPTO 1
#define __ARM_FEATURE_DIV 1
#define __ARM_FEATURE_FMA 1
#define __ARM_FEATURE_UNALIGNED 1
#define __ARM_FP 0xe
#define __ARM_FP16_FORMAT_IEEE 1
#define __ARM_FP_FENV_ROUNDING 1
#define __ARM_NEON 1
#define __ARM_NEON_FP 7
#define __ARM_NEON__ 1
#define __ARM_PCS_AAPCS64 1
#define __ARM_SIZEOF_MINIMAL_ENUM 4
#define __ARM_SIZEOF_WCHAR_T 4
#define __aarch64__ 1
#define __arm64 1
#define __arm64__ 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • For Apple see the SO answer for [iPhone support hardware-accelerated AES Encryption?](http://stackoverflow.com/a/5387310/451475) – zaph May 15 '16 at 11:41
  • @zaph That appears to be about utilising an external crypto accelerator peripheral, not the specific ARMv8 instructions for performing AES/SHA on the CPU itself. Notably, it dates from before the ARMv8 architecture was even announced... – Notlikethat May 15 '16 at 11:54

1 Answers1

4

Being an optional extension, it's generally down to you to tell the compiler if your target implements the crypto instructions. For GCC or regular Clang, that means adding the +crypto feature modifier to your -march or -mcpu setting.

It looks like Apple's version of Clang enables it unconditionally, but the target there is implicitly "Apples's CPUs", and I doubt they make non-crypto versions since they don't license their CPU designs at all, let alone for export. As for Windows Phone, whilst ARMv8 does add the crypto instructions to AArch32 as well, the VS2015 ARM compiler still only seems to support ARMv7, so I think it's entirely moot there.

Note that GCC doesn't do much with the crypto feature other than pass it through to the assembler, since it doesn't properly support ACLE. I tried Clang 4.8 as packaged by Arch Linux, and that does happily compile the standard AES intrinsics from arm_acle.h if -march=armv8-a+crypto is given.

Community
  • 1
  • 1
Notlikethat
  • 20,095
  • 3
  • 40
  • 77
  • If the application is intended to run in AArch32 state, how can I compile it using Clang, if it uses crypto extensions? – Vivekanand V Aug 20 '20 at 17:05