commit 76f1eb10e31908adba4d6b840390a4e7aa132469
parent bd13ee2f4b6535d280906dd4b5f12de7e5a4b2e1
Author: vaplv <vaplv@free.fr>
Date: Mon, 1 Feb 2021 15:40:29 +0100
Add conditionnal support of FMA instruction sets
Diffstat:
3 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -27,7 +27,7 @@ set(RSIMD_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
set(Sleef_DIR ${PROJECT_SOURCE_DIR}/../)
find_package(RCMake REQUIRED)
-find_package(RSys 0.7 REQUIRED)
+find_package(RSys 0.12 REQUIRED)
find_package(PkgConfig REQUIRED)
find_package(Sleef REQUIRED)
@@ -42,7 +42,8 @@ if(CMAKE_COMPILER_IS_GNUCC)
include(CheckCCompilerFlag)
CHECK_C_COMPILER_FLAG("-msse4.1" SSE4_1)
CHECK_C_COMPILER_FLAG("-mavx" AVX)
-endif(CMAKE_COMPILER_IS_GNUCC)
+ CHECK_C_COMPILER_FLAG("-mfma" FMA)
+endif()
################################################################################
# Configure and define targets
@@ -119,12 +120,12 @@ if(NOT NO_TEST)
add_test(${_name} ${_name})
if(NOT "${ARGN}" STREQUAL "")
set_target_properties(${_name} PROPERTIES COMPILE_FLAGS ${ARGN})
- endif(NOT "${ARGN}" STREQUAL "")
- endfunction(new_test_named)
+ endif()
+ endfunction()
function(new_test _name)
new_test_named(${_name} ${_name} ${ARGN})
- endfunction(new_test)
+ endfunction()
new_test(test_v4f)
new_test(test_v4i)
@@ -139,7 +140,14 @@ if(NOT NO_TEST)
if(SSE4_1 AND CMAKE_COMPILER_IS_GNUCC)
new_test_named(test_v4f_sse4_1 test_v4f "-msse4.1")
new_test_named(test_v4i_sse4_1 test_v4i "-msse4.1")
- endif(SSE4_1 AND CMAKE_COMPILER_IS_GNUCC)
+ endif()
+
+ if(FMA AND CMAKE_COMPILER_IS_GNUCC)
+ new_test_named(test_v4f_fma test_v4f "-mfma")
+ new_test_named(test_soa8f2_fma test_soa8f2 "-mfma")
+ new_test_named(test_soa8f3_fma test_soa8f3 "-mfma")
+ new_test_named(test_soa8f4_fma test_soa8f4 "-mfma")
+ endif()
if(AVX AND CMAKE_COMPILER_IS_GNUCC)
new_test(test_v8f "-mavx")
diff --git a/cmake/RSIMDConfig.cmake b/cmake/RSIMDConfig.cmake
@@ -14,8 +14,32 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 3.1)
+
+# Check dependenc
find_package(Sleef REQUIRED)
+# Check compiler features
+if(CMAKE_COMPILER_IS_GNUCC)
+ include(CheckCCompilerFlag)
+ CHECK_C_COMPILER_FLAG("-msse2" SSE2)
+ CHECK_C_COMPILER_FLAG("-msse4.1" SSE4_1)
+ CHECK_C_COMPILER_FLAG("-mavx" AVX)
+ CHECK_C_COMPILER_FLAG("-mfma" FMA)
+
+ if(SSE2)
+ list(APPEND _compile_flags -msse2)
+ endif()
+ if(SSE4_1)
+ list(APPEND _compile_flags -msse4.1)
+ endif()
+ if(AVX)
+ list(APPEND _compile_flags -mavx)
+ endif()
+ if(FMA)
+ list(APPEND _compile_flags -mfma)
+ endif()
+endif()
+
# Try to find the RSIMD devel. Once done this will define:
# - RSIMD_FOUND: system has RSIMD
# - RSIMD_INCLUDE_DIR: the include directory
@@ -86,7 +110,8 @@ set_target_properties(RSIMD PROPERTIES
${_import_prop}_RELWITHDEBINFO ${RSIMD_LIBRARY_RELWITHDEBINFO}
${_import_prop}_MINSIZEREL ${RSIMD_LIBRARY_MINSIZEREL}
INTERFACE_INCLUDE_DIRECTORIES ${RSIMD_INCLUDE_DIR}
- INTERFACE_LINK_LIBRARIES Sleef)
+ INTERFACE_LINK_LIBRARIES Sleef
+ INTERFACE_COMPILE_OPTIONS "${_compile_flags}")
# Check the package
include(FindPackageHandleStandardArgs)
diff --git a/src/sse/ssef.h b/src/sse/ssef.h
@@ -28,6 +28,9 @@
#ifdef SIMD_SSE4_1
#include <smmintrin.h>
#endif
+#ifdef FMADD
+ #include <immintrin.h>
+#endif
typedef __m128 v4f_T;
#define V4F_AT__(Vec, Id) __builtin_ia32_vec_ext_v4sf(Vec, Id)
@@ -315,7 +318,11 @@ v4f_div(const v4f_T v0, const v4f_T v1)
static FINLINE v4f_T
v4f_madd(const v4f_T v0, const v4f_T v1, const v4f_T v2)
{
+#ifdef FMADD
+ return _mm_fmadd_ps(v0, v1, v2);
+#else
return _mm_add_ps(_mm_mul_ps(v0, v1), v2);
+#endif
}
static FINLINE v4f_T