diff --git a/configure.ac b/configure.ac index cfe9e841e17..d042d3d2821 100644 --- a/configure.ac +++ b/configure.ac @@ -106,6 +106,9 @@ AC_DEFUN([AC_CHECK_CC_FLAG], AC_CHECK_CC_FLAG([-Wtype-limits], [WARN_TYPE_LIMITS]) AC_CHECK_CC_FLAG([-Wignored-qualifiers], [WARN_IGNORED_QUALIFIERS]) +# Checks for architecture stuff +AM_CONDITIONAL([ENABLE_FPU_NEON], [case $target_cpu in arm*) true;; *) false;; esac]) + # Checks for libraries. ACX_PTHREAD AC_CHECK_LIB([uuid], [uuid_parse], [true], AC_MSG_FAILURE([libuuid not found])) diff --git a/src/Makefile.am b/src/Makefile.am index 3bdec278c6f..7d87c7b5f60 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -775,6 +775,10 @@ unittest_addrs_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} unittest_addrs_LDADD = $(LIBGLOBAL_LDA) ${UNITTEST_LDADD} check_PROGRAMS += unittest_addrs +unittest_arch_SOURCES = test/test_arch.c arch/intel.c arch/neon.c arch/probe.cc +unittest_arch_CXXFLAGS = ${AM_CFLAGS} +check_PROGRAMS += unittest_arch + unittest_sharedptr_registry_SOURCES = test/common/test_sharedptr_registry.cc unittest_sharedptr_registry_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} unittest_sharedptr_registry_LDADD = libcommon.la ${LIBGLOBAL_LDA} ${UNITTEST_LDADD} @@ -1340,6 +1344,11 @@ AM_CXXFLAGS = \ -Wnon-virtual-dtor \ -Wno-invalid-offsetof +if ENABLE_FPU_NEON +AM_CFLAGS += -mfpu=neon +AM_CXXFLAGS += -mfpu=neon +endif + if !CLANG AM_CXXFLAGS += -Wstrict-null-sentinel endif @@ -1521,6 +1530,7 @@ libcommon_files = \ ./ceph_ver.c \ arch/probe.cc \ arch/intel.c \ + arch/neon.c \ auth/AuthAuthorizeHandler.cc \ auth/AuthClientHandler.cc \ auth/AuthSessionHandler.cc \ @@ -1772,6 +1782,7 @@ noinst_HEADERS = \ rados_sync.h \ arch/probe.h \ arch/intel.h \ + arch/neon.h \ auth/cephx/CephxAuthorizeHandler.h\ auth/cephx/CephxKeyServer.h\ auth/cephx/CephxProtocol.h\ diff --git a/src/arch/neon.c b/src/arch/neon.c new file mode 100644 index 00000000000..32c1f621ef7 --- /dev/null +++ b/src/arch/neon.c @@ -0,0 +1,51 @@ +#include "arch/probe.h" + +/* flags we export */ +int ceph_arch_neon = 0; + +#include + +#if __linux__ + +#include +#include // ElfW macro + +#if __arm__ +#include +#endif // __arm__ + +static unsigned long get_auxval(unsigned long type) +{ + unsigned long result = 0; + FILE *f = fopen("/proc/self/auxv", "r"); + if (f) { + ElfW(auxv_t) entry; + while (fread(&entry, sizeof(entry), 1, f)) { + if (entry.a_type == type) { + result = entry.a_un.a_val; + break; + } + } + fclose(f); + } + return result; +} + +static unsigned long get_hwcap(void) +{ + return get_auxval(AT_HWCAP); +} + +#endif // __linux__ + +int ceph_arch_neon_probe(void) +{ +#if __arm__ && __linux__ + ceph_arch_neon = (get_hwcap() & HWCAP_NEON) == HWCAP_NEON; +#else + if (0) + get_hwcap(); // make compiler shut up +#endif + return 0; +} + diff --git a/src/arch/neon.h b/src/arch/neon.h new file mode 100644 index 00000000000..0c8aacf5e87 --- /dev/null +++ b/src/arch/neon.h @@ -0,0 +1,16 @@ +#ifndef CEPH_ARCH_NEON_H +#define CEPH_ARCH_NEON_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ceph_arch_neon; /* true if we have ARM NEON abilities */ + +extern int ceph_arch_neon_probe(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/arch/probe.cc b/src/arch/probe.cc index 9f8bc9d2d0f..8648e54d945 100644 --- a/src/arch/probe.cc +++ b/src/arch/probe.cc @@ -4,6 +4,7 @@ #include "arch/probe.h" #include "arch/intel.h" +#include "arch/neon.h" int ceph_arch_probe(void) { @@ -11,6 +12,7 @@ int ceph_arch_probe(void) return 1; ceph_arch_intel_probe(); + ceph_arch_neon_probe(); ceph_arch_probed = 1; return 1; diff --git a/src/test/test_arch.c b/src/test/test_arch.c new file mode 100644 index 00000000000..549221e60f9 --- /dev/null +++ b/src/test/test_arch.c @@ -0,0 +1,19 @@ + +#include +#include +#include + +#include "arch/probe.h" +#include "arch/intel.h" +#include "arch/neon.h" + +int main(int argc, char **argv) +{ + ceph_arch_probe(); + assert(ceph_arch_probed); + + printf("ceph_arch_intel_sse42 = %d\n", ceph_arch_intel_sse42); + printf("ceph_arch_neon = %d\n", ceph_arch_neon); + + return 0; +}