160 lines
6.0 KiB
Diff
160 lines
6.0 KiB
Diff
|
# HG changeset patch
|
||
|
# User Mike Hommey <mh@glandium.org>
|
||
|
# Date 1578673372 -3600
|
||
|
# Fri Jan 10 17:22:52 2020 +0100
|
||
|
# Node ID 9c359d019d333282476ffeec3dab819cfdcf127e
|
||
|
# Parent 4921046404f197526969a6b79f19c136469e69f8
|
||
|
Bug 1608327 - Fix freebl arm NEON code use on tier3 platforms.
|
||
|
|
||
|
Summary:
|
||
|
Despite the code having runtime detection of NEON and crypto extensions,
|
||
|
the optimized code using those instructions is disabled at build time on
|
||
|
platforms where the compiler doesn't enable NEON by default of with the
|
||
|
flags it's given for the caller code.
|
||
|
|
||
|
In the case of gcm, this goes as far as causing a build error.
|
||
|
|
||
|
What is needed is for the optimized code to be enabled in every case,
|
||
|
letting the caller code choose whether to use that code based on the
|
||
|
existing runtime checks.
|
||
|
|
||
|
But this can't be simply done either, because those optimized parts of
|
||
|
the code need to be built with NEON enabled, unconditionally, but that
|
||
|
is not compatible with platforms using the softfloat ABI. For those,
|
||
|
we need to use the softfp ABI, which is compatible. However, the softfp
|
||
|
ABI is not compatible with the hardfp ABI, so we also can't
|
||
|
unconditionally use the softfp ABI, so we do so only when the compiler
|
||
|
targets the softfloat ABI, which confusingly enough is advertized via
|
||
|
the `__SOFTFP__` define.
|
||
|
|
||
|
Reviewers: jcj!
|
||
|
|
||
|
Bug #: 1608327
|
||
|
|
||
|
Differential Revision: https://phabricator.services.mozilla.com/D59451
|
||
|
|
||
|
diff --git a/lib/freebl/Makefile b/lib/freebl/Makefile
|
||
|
--- a/lib/freebl/Makefile
|
||
|
+++ b/lib/freebl/Makefile
|
||
|
@@ -781,8 +781,12 @@ ifdef INTEL_GCM_CLANG_CL
|
||
|
endif
|
||
|
|
||
|
ifeq ($(CPU_ARCH),arm)
|
||
|
-$(OBJDIR)/$(PROG_PREFIX)aes-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a -mfpu=crypto-neon-fp-armv8
|
||
|
-$(OBJDIR)/$(PROG_PREFIX)gcm-arm32-neon$(OBJ_SUFFIX): CFLAGS += -mfpu=neon
|
||
|
+# When the compiler uses the softfloat ABI, we want to use the compatible softfp ABI when
|
||
|
+# enabling NEON for these objects.
|
||
|
+# Confusingly, __SOFTFP__ is the name of the define for the softfloat ABI, not for the softfp ABI.
|
||
|
+USES_SOFTFLOAT_ABI := $(shell $(CC) -o - -E -dM - $(CFLAGS) < /dev/null | grep __SOFTFP__ > /dev/null && echo 1)
|
||
|
+$(OBJDIR)/$(PROG_PREFIX)aes-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a -mfpu=crypto-neon-fp-armv8$(if $(USES_SOFTFLOAT_ABI), -mfloat-abi=softfp)
|
||
|
+$(OBJDIR)/$(PROG_PREFIX)gcm-arm32-neon$(OBJ_SUFFIX): CFLAGS += -mfpu=neon$(if $(USES_SOFTFLOAT_ABI), -mfloat-abi=softfp)
|
||
|
endif
|
||
|
ifeq ($(CPU_ARCH),aarch64)
|
||
|
$(OBJDIR)/$(PROG_PREFIX)aes-armv8$(OBJ_SUFFIX): CFLAGS += -march=armv8-a+crypto
|
||
|
diff --git a/lib/freebl/aes-armv8.c b/lib/freebl/aes-armv8.c
|
||
|
--- a/lib/freebl/aes-armv8.c
|
||
|
+++ b/lib/freebl/aes-armv8.c
|
||
|
@@ -8,7 +8,7 @@
|
||
|
#if ((defined(__clang__) || \
|
||
|
(defined(__GNUC__) && defined(__GNUC_MINOR__) && \
|
||
|
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 8)))) && \
|
||
|
- (defined(__ARM_NEON) || defined(__ARM_NEON__)))
|
||
|
+ defined(IS_LITTLE_ENDIAN))
|
||
|
|
||
|
#ifndef __ARM_FEATURE_CRYPTO
|
||
|
#error "Compiler option is invalid"
|
||
|
diff --git a/lib/freebl/freebl.gyp b/lib/freebl/freebl.gyp
|
||
|
--- a/lib/freebl/freebl.gyp
|
||
|
+++ b/lib/freebl/freebl.gyp
|
||
|
@@ -126,10 +126,12 @@
|
||
|
'<(DEPTH)/exports.gyp:nss_exports'
|
||
|
],
|
||
|
'cflags': [
|
||
|
- '-mfpu=neon'
|
||
|
+ '-mfpu=neon',
|
||
|
+ '<@(softfp_cflags)',
|
||
|
],
|
||
|
'cflags_mozilla': [
|
||
|
- '-mfpu=neon'
|
||
|
+ '-mfpu=neon',
|
||
|
+ '<@(softfp_cflags)',
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
@@ -179,11 +181,13 @@
|
||
|
[ 'target_arch=="arm"', {
|
||
|
'cflags': [
|
||
|
'-march=armv8-a',
|
||
|
- '-mfpu=crypto-neon-fp-armv8'
|
||
|
+ '-mfpu=crypto-neon-fp-armv8',
|
||
|
+ '<@(softfp_cflags)',
|
||
|
],
|
||
|
'cflags_mozilla': [
|
||
|
'-march=armv8-a',
|
||
|
- '-mfpu=crypto-neon-fp-armv8'
|
||
|
+ '-mfpu=crypto-neon-fp-armv8',
|
||
|
+ '<@(softfp_cflags)',
|
||
|
],
|
||
|
}, 'target_arch=="arm64" or target_arch=="aarch64"', {
|
||
|
'cflags': [
|
||
|
@@ -533,6 +537,11 @@
|
||
|
}, {
|
||
|
'have_int128_support%': 0,
|
||
|
}],
|
||
|
+ [ 'target_arch=="arm"', {
|
||
|
+ # When the compiler uses the softfloat ABI, we want to use the compatible softfp ABI when enabling NEON for these objects.
|
||
|
+ # Confusingly, __SOFTFP__ is the name of the define for the softfloat ABI, not for the softfp ABI.
|
||
|
+ 'softfp_cflags': '<!(${CC:-cc} -o - -E -dM - ${CFLAGS} < /dev/null | grep __SOFTFP__ > /dev/null && echo -mfloat-abi=softfp || true)',
|
||
|
+ }],
|
||
|
],
|
||
|
}
|
||
|
}
|
||
|
diff --git a/lib/freebl/gcm-arm32-neon.c b/lib/freebl/gcm-arm32-neon.c
|
||
|
--- a/lib/freebl/gcm-arm32-neon.c
|
||
|
+++ b/lib/freebl/gcm-arm32-neon.c
|
||
|
@@ -11,7 +11,7 @@
|
||
|
#include "secerr.h"
|
||
|
#include "prtypes.h"
|
||
|
|
||
|
-#if defined(__ARM_NEON__) || defined(__ARM_NEON)
|
||
|
+#if defined(IS_LITTLE_ENDIAN)
|
||
|
|
||
|
#include <arm_neon.h>
|
||
|
|
||
|
@@ -199,4 +199,4 @@ gcm_HashZeroX_hw(gcmHashContext *ghash)
|
||
|
return SECSuccess;
|
||
|
}
|
||
|
|
||
|
-#endif /* __ARM_NEON__ || __ARM_NEON */
|
||
|
+#endif /* IS_LITTLE_ENDIAN */
|
||
|
diff --git a/lib/freebl/gcm.c b/lib/freebl/gcm.c
|
||
|
--- a/lib/freebl/gcm.c
|
||
|
+++ b/lib/freebl/gcm.c
|
||
|
@@ -21,11 +21,8 @@
|
||
|
#if defined(__aarch64__) && defined(IS_LITTLE_ENDIAN) && \
|
||
|
(defined(__clang__) || defined(__GNUC__) && __GNUC__ > 6)
|
||
|
#define USE_ARM_GCM
|
||
|
-#elif defined(__arm__) && defined(IS_LITTLE_ENDIAN) && \
|
||
|
- (defined(__ARM_NEON__) || defined(__ARM_NEON))
|
||
|
-/* We don't test on big endian platform, so disable this on big endian.
|
||
|
- * Also, we don't check whether compiler support NEON well, so this uses
|
||
|
- * that compiler uses -mfpu=neon only. */
|
||
|
+#elif defined(__arm__) && defined(IS_LITTLE_ENDIAN)
|
||
|
+/* We don't test on big endian platform, so disable this on big endian. */
|
||
|
#define USE_ARM_GCM
|
||
|
#endif
|
||
|
|
||
|
diff --git a/lib/freebl/rijndael.c b/lib/freebl/rijndael.c
|
||
|
--- a/lib/freebl/rijndael.c
|
||
|
+++ b/lib/freebl/rijndael.c
|
||
|
@@ -20,8 +20,7 @@
|
||
|
#include "gcm.h"
|
||
|
#include "mpi.h"
|
||
|
|
||
|
-#if (!defined(IS_LITTLE_ENDIAN) && !defined(NSS_X86_OR_X64)) || \
|
||
|
- (defined(__arm__) && !defined(__ARM_NEON) && !defined(__ARM_NEON__))
|
||
|
+#if !defined(IS_LITTLE_ENDIAN) && !defined(NSS_X86_OR_X64)
|
||
|
// not test yet on big endian platform of arm
|
||
|
#undef USE_HW_AES
|
||
|
#endif
|