Implemented a fix to get the Neon code to compile successfully with GCC < 6.0

This commit is contained in:
Kfir Itzhak 2017-03-25 21:49:15 +03:00
parent ca99d84995
commit 7162c62d26
2 changed files with 27 additions and 9 deletions

View File

@ -66,6 +66,24 @@ set(CMAKE_CXX_FLAGS_DEBUG "-Wall -D__STDC_CONSTANT_MACROS -g")
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") 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: # Modules that we need:
include (GNUInstallDirs) include (GNUInstallDirs)
include (CheckIncludeFile) include (CheckIncludeFile)

View File

@ -3291,11 +3291,11 @@ __attribute__((noinline)) void std_fastblend(const uint8_t* col1, const uint8_t*
} }
/* FastBlend Neon for AArch32 */ /* FastBlend Neon for AArch32 */
#if defined(__arm__) #if (defined(__arm__) && !defined(ZM_STRIP_NEON))
__attribute__((noinline,__target__("fpu=neon"))) __attribute__((noinline,__target__("fpu=neon")))
#endif #endif
void neon32_armv7_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) { 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 int8_t divider = 0;
static double current_blendpercent = 0.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" : "%r12", "%q0", "%q1", "%q2", "%q3", "cc", "memory"
); );
#else #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 #endif
} }
@ -3575,11 +3575,11 @@ __attribute__((noinline)) void std_delta8_abgr(const uint8_t* col1, const uint8_
} }
/* Grayscale Neon for AArch32 */ /* Grayscale Neon for AArch32 */
#if defined(__arm__) #if (defined(__arm__) && !defined(ZM_STRIP_NEON))
__attribute__((noinline,__target__("fpu=neon"))) __attribute__((noinline,__target__("fpu=neon")))
#endif #endif
void neon32_armv7_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { 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 */ /* Q0(D0,D1) = col1 */
/* Q1(D2,D3) = col2 */ /* 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" : "%q0", "%q1", "cc", "memory"
); );
#else #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 #endif
} }
/* RGB32 Neon for AArch32 */ /* RGB32 Neon for AArch32 */
#if defined(__arm__) #if (defined(__arm__) && !defined(ZM_STRIP_NEON))
__attribute__((noinline,__target__("fpu=neon"))) __attribute__((noinline,__target__("fpu=neon")))
#endif #endif
void neon32_armv7_delta8_rgb32(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, uint32_t multiplier) { 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 */ /* Q0(D0,D1) = col1 */
/* Q1(D2,D3) = col2 */ /* 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" : "%r12", "%q0", "%q1", "%q2", "cc", "memory"
); );
#else #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 #endif
} }