From d80f17d5c94b21c4fb2e82ee527bfe001b3553f2 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Wed, 29 Dec 2021 15:34:37 -0500 Subject: [PATCH] Simplify __ARM_ARCH__ definition. OpenSSL's assembly files have a few places where we condition code on __ARM_ARCH__, the minimum target ARM revision. It currently only controls some pre-ARMv7 code. This symbol has, from what I can tell, the same semantics as __ARM_ARCH, defined in Arm C Language Extensions, and added in GCC 4.8 and Clang 3.2: https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=9e94a7fc5ab770928b9e6a2b74e292d35b4c94da;hp=25bab91e017eb1d6d93117f3da96fa9b43703190 https://github.com/llvm/llvm-project/commit/e98c4dbd1ef783b04f0d8276847076fb79a804e8 Those are over nine years old, so drop all the fallback code. Also fix arm_arch.h to be includable on non-ARM platforms. Some tools expect all public headers to be cleanly includable and arm_arch.h being "public" was getting in the way (see cl/416881417). Interestingly, arm_arch.h previously only computed __ARM_ARCH__ for __GNUC__ and Clang doesn't define __GNUC__ on Windows. That means we actually weren't defining __ARM_ARCH__ for Windows. But none of the aarch64 assembly has __ARM_ARCH__-gated code, so it works out. If it ever does, that CL smooths that over. I've gated the __ARM_(MAX_)_ARCH__ bits on __ASSEMBLER__ to avoid breaking no-asm Windows/aarch64 builds on MSVC. There aren't any uses in C. Update-Note: ARM assembly now requires the compiler define __ARM_ARCH. This is not expected to break Clang or GCC from the last 8 or 9 years. Change-Id: Id45e95406edeecf8dda11dce9e82418516e9de1f Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50849 Reviewed-by: Adam Langley --- include/openssl/arm_arch.h | 68 ++++++++++++++------------------------ 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/include/openssl/arm_arch.h b/include/openssl/arm_arch.h index 3a34829e7..7215f62eb 100644 --- a/include/openssl/arm_arch.h +++ b/include/openssl/arm_arch.h @@ -53,49 +53,12 @@ #ifndef OPENSSL_HEADER_ARM_ARCH_H #define OPENSSL_HEADER_ARM_ARCH_H -#if !defined(__ARM_ARCH__) -# if defined(__CC_ARM) -# define __ARM_ARCH__ __TARGET_ARCH_ARM -# if defined(__BIG_ENDIAN) -# define __ARMEB__ -# else -# define __ARMEL__ -# endif -# elif defined(__GNUC__) -# if defined(__aarch64__) -# define __ARM_ARCH__ 8 - // Why doesn't gcc define __ARM_ARCH__? Instead it defines - // bunch of below macros. See all_architectires[] table in - // gcc/config/arm/arm.c. On a side note it defines - // __ARMEL__/__ARMEB__ for little-/big-endian. -# elif defined(__ARM_ARCH) -# define __ARM_ARCH__ __ARM_ARCH -# elif defined(__ARM_ARCH_8A__) -# define __ARM_ARCH__ 8 -# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ - defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \ - defined(__ARM_ARCH_7EM__) -# define __ARM_ARCH__ 7 -# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ - defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \ - defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \ - defined(__ARM_ARCH_6T2__) -# define __ARM_ARCH__ 6 -# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \ - defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \ - defined(__ARM_ARCH_5TEJ__) -# define __ARM_ARCH__ 5 -# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) -# define __ARM_ARCH__ 4 -# else -# error "unsupported ARM architecture" -# endif -# endif -#endif +// arm_arch.h contains symbols used by ARM assembly, and the C code that calls +// it. It is included as a public header to simplify the build, but is not +// intended for external use. -// Even when building for 32-bit ARM, support for aarch64 crypto instructions -// will be included. -#define __ARM_MAX_ARCH__ 8 +#if defined(__ARMEL__) || defined(_M_ARM) || defined(__AARCH64EL__) || \ + defined(_M_ARM64) // ARMV7_NEON is true when a NEON unit is present in the current CPU. #define ARMV7_NEON (1 << 0) @@ -117,6 +80,23 @@ #if defined(__ASSEMBLER__) +// We require the ARM assembler provide |__ARM_ARCH| from Arm C Language +// Extensions (ACLE). This is supported in GCC 4.8+ and Clang 3.2+. MSVC does +// not implement ACLE, but we require Clang's assembler on Windows. +#if !defined(__ARM_ARCH) +#error "ARM assembler must define __ARM_ARCH" +#endif + +// __ARM_ARCH__ is used by OpenSSL assembly to determine the minimum target ARM +// version. +// +// TODO(davidben): Switch the assembly to use |__ARM_ARCH| directly. +#define __ARM_ARCH__ __ARM_ARCH + +// Even when building for 32-bit ARM, support for aarch64 crypto instructions +// will be included. +#define __ARM_MAX_ARCH__ 8 + // Support macros for // - Armv8.3-A Pointer Authentication and // - Armv8.5-A Branch Target Identification @@ -233,6 +213,8 @@ .popsection; #endif -#endif /* defined __ASSEMBLER__ */ +#endif // __ASSEMBLER__ + +#endif // __ARMEL__ || _M_ARM || __AARCH64EL__ || _M_ARM64 #endif // OPENSSL_HEADER_ARM_ARCH_H