From 7162c62d269b80cf8eff0a2c28555e8964bfa78e Mon Sep 17 00:00:00 2001 From: Kfir Itzhak Date: Sat, 25 Mar 2017 21:49:15 +0300 Subject: [PATCH] Implemented a fix to get the Neon code to compile successfully with GCC < 6.0 --- CMakeLists.txt | 18 ++++++++++++++++++ src/zm_image.cpp | 18 +++++++++--------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index baba4218d..dc50358ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,24 @@ set(CMAKE_CXX_FLAGS_DEBUG "-Wall -D__STDC_CONSTANT_MACROS -g") set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") +# GCC below 6.0 doesn't support __target__("fpu=neon") attribute, required for compiling ARM Neon code, otherwise compilation fails. +# Must use -mfpu=neon compiler flag instead, but only do that for processors that support neon, otherwise strip the neon code alltogether, +# because passing -fmpu=neon is unsafe to processors that don't support neon +IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" AND CMAKE_SYSTEM_NAME MATCHES "Linux") + IF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + EXEC_PROGRAM(grep ARGS " neon " "/proc/cpuinfo" OUTPUT_VARIABLE neonoutput RETURN_VALUE neonresult) + IF(neonresult EQUAL 0) + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mfpu=neon") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mfpu=neon") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mfpu=neon") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -mfpu=neon") + ELSE(neonresult EQUAL 0) + add_definitions(-DZM_STRIP_NEON=1) + message(STATUS "ARM Neon is not available on this processor. Neon functions will be absent") + ENDIF(neonresult EQUAL 0) + ENDIF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) +ENDIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" AND CMAKE_SYSTEM_NAME MATCHES "Linux") + # Modules that we need: include (GNUInstallDirs) include (CheckIncludeFile) diff --git a/src/zm_image.cpp b/src/zm_image.cpp index b65363ae2..63ee58310 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -3291,11 +3291,11 @@ __attribute__((noinline)) void std_fastblend(const uint8_t* col1, const uint8_t* } /* FastBlend Neon for AArch32 */ -#if defined(__arm__) +#if (defined(__arm__) && !defined(ZM_STRIP_NEON)) __attribute__((noinline,__target__("fpu=neon"))) #endif void neon32_armv7_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) { -#if defined(__arm__) +#if (defined(__arm__) && !defined(ZM_STRIP_NEON)) static int8_t divider = 0; static double current_blendpercent = 0.0; @@ -3348,7 +3348,7 @@ void neon32_armv7_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* r : "%r12", "%q0", "%q1", "%q2", "%q3", "cc", "memory" ); #else - Panic("Neon function called on a non ARM platform"); + Panic("Neon function called on a non-ARM platform or Neon code is absent"); #endif } @@ -3575,11 +3575,11 @@ __attribute__((noinline)) void std_delta8_abgr(const uint8_t* col1, const uint8_ } /* Grayscale Neon for AArch32 */ -#if defined(__arm__) +#if (defined(__arm__) && !defined(ZM_STRIP_NEON)) __attribute__((noinline,__target__("fpu=neon"))) #endif void neon32_armv7_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { -#if defined(__arm__) +#if (defined(__arm__) && !defined(ZM_STRIP_NEON)) /* Q0(D0,D1) = col1 */ /* Q1(D2,D3) = col2 */ @@ -3597,16 +3597,16 @@ void neon32_armv7_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t : "%q0", "%q1", "cc", "memory" ); #else - Panic("Neon function called on a non ARM platform"); + Panic("Neon function called on a non-ARM platform or Neon code is absent"); #endif } /* RGB32 Neon for AArch32 */ -#if defined(__arm__) +#if (defined(__arm__) && !defined(ZM_STRIP_NEON)) __attribute__((noinline,__target__("fpu=neon"))) #endif void neon32_armv7_delta8_rgb32(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, uint32_t multiplier) { -#if defined(__arm__) +#if (defined(__arm__) && !defined(ZM_STRIP_NEON)) /* Q0(D0,D1) = col1 */ /* Q1(D2,D3) = col2 */ @@ -3632,7 +3632,7 @@ void neon32_armv7_delta8_rgb32(const uint8_t* col1, const uint8_t* col2, uint8_t : "%r12", "%q0", "%q1", "%q2", "cc", "memory" ); #else - Panic("Neon function called on a non ARM platform"); + Panic("Neon function called on a non-ARM platform or Neon code is absent"); #endif }