diff options
-rw-r--r-- | include/tools/simdsupport.hxx | 21 | ||||
-rw-r--r-- | tools/CppunitTest_tools_test.mk | 12 | ||||
-rw-r--r-- | tools/qa/cppunit/test_cpu_runtime_detection_AVX2.cxx | 75 | ||||
-rw-r--r-- | tools/qa/cppunit/test_cpu_runtime_detection_SSE2.cxx | 58 | ||||
-rw-r--r-- | tools/qa/cppunit/test_cpu_runtime_detection_SSSE3.cxx | 58 |
5 files changed, 214 insertions, 10 deletions
diff --git a/include/tools/simdsupport.hxx b/include/tools/simdsupport.hxx index 4ef7a698089e..5d10d53d48ad 100644 --- a/include/tools/simdsupport.hxx +++ b/include/tools/simdsupport.hxx @@ -14,6 +14,8 @@ // code using intrinsics or not. So we have to (re)set them again // every time this file has been included. +// In other words... DO NOT ADD "#pragma once" here + #undef LO_SSE2_AVAILABLE #undef LO_SSSE3_AVAILABLE #undef LO_AVX_AVAILABLE @@ -24,49 +26,48 @@ // SSE2 is required for X64 #if (defined(_M_X64) || defined(_M_IX86_FP) && _M_IX86_FP >= 2) #define LO_SSE2_AVAILABLE +#include <intrin.h> #endif // end SSE2 // compiled with /arch:AVX #if defined(__AVX__) #ifndef LO_SSE2_AVAILABLE #define LO_SSE2_AVAILABLE +#include <intrin.h> #endif #define LO_SSSE3_AVAILABLE #define LO_AVX_AVAILABLE -#endif // defined(__AVX__) +#include <immintrin.h> +#endif // end defined(__AVX__) // compiled with /arch:AVX2 #if defined(__AVX2__) #define LO_AVX2_AVAILABLE +#include <immintrin.h> #endif // defined(__AVX2__) #else // compiler Clang and GCC #if defined(__SSE2__) || defined(__x86_64__) // SSE2 is required for X64 #define LO_SSE2_AVAILABLE +#include <emmintrin.h> #endif // defined(__SSE2__) #if defined(__SSSE3__) #define LO_SSSE3_AVAILABLE +#include <tmmintrin.h> #endif // defined(__SSSE3__) #if defined(__AVX__) #define LO_AVX_AVAILABLE +#include <immintrin.h> #endif // defined(__AVX__) #if defined(__AVX2__) #define LO_AVX2_AVAILABLE +#include <immintrin.h> #endif // defined(__AVX2__) #endif // end compiler Clang and GCC -// If we detect any SIMD intrinsics, include the headers automatically -#if defined(LO_SSE2_AVAILABLE) -#include <emmintrin.h> -#elif defined(LO_SSSE3_AVAILABLE) -#include <tmmintrin.h> -#elif defined(LO_AVX_AVAILABLE) || defined(LO_AVX2_AVAILABLE) -#include <immintrin.h> -#endif - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/CppunitTest_tools_test.mk b/tools/CppunitTest_tools_test.mk index 46a6cf5242cd..aa5ac4606d02 100644 --- a/tools/CppunitTest_tools_test.mk +++ b/tools/CppunitTest_tools_test.mk @@ -34,6 +34,18 @@ $(eval $(call gb_CppunitTest_add_exception_objects,tools_test, \ tools/qa/cppunit/test_cpuid \ )) +$(eval $(call gb_CppunitTest_add_exception_objects,tools_test,\ + tools/qa/cppunit/test_cpu_runtime_detection_AVX2, $(CXXFLAGS_INTRINSICS_AVX2) \ +)) + +$(eval $(call gb_CppunitTest_add_exception_objects,tools_test,\ + tools/qa/cppunit/test_cpu_runtime_detection_SSE2, $(CXXFLAGS_INTRINSICS_SSE2) \ +)) + +$(eval $(call gb_CppunitTest_add_exception_objects,tools_test,\ + tools/qa/cppunit/test_cpu_runtime_detection_SSSE3, $(CXXFLAGS_INTRINSICS_SSSE3) \ +)) + $(eval $(call gb_CppunitTest_use_sdk_api,tools_test)) $(eval $(call gb_CppunitTest_use_libraries,tools_test, \ diff --git a/tools/qa/cppunit/test_cpu_runtime_detection_AVX2.cxx b/tools/qa/cppunit/test_cpu_runtime_detection_AVX2.cxx new file mode 100644 index 000000000000..0c98f2fc8c98 --- /dev/null +++ b/tools/qa/cppunit/test_cpu_runtime_detection_AVX2.cxx @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <tools/simdsupport.hxx> + +#ifdef LO_AVX2_AVAILABLE + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> + +#include <tools/cpuid.hxx> + +namespace +{ +class CpuRuntimeDetection_AVX2 : public CppUnit::TestFixture +{ +public: + void checkAVX2(); + void testCpuRuntimeDetection(); + + CPPUNIT_TEST_SUITE(CpuRuntimeDetection_AVX2); + CPPUNIT_TEST(testCpuRuntimeDetection); + CPPUNIT_TEST_SUITE_END(); +}; + +void CpuRuntimeDetection_AVX2::testCpuRuntimeDetection() +{ + // can only run if this function if CPU supports AVX2 + if (cpuid::isCpuInstructionSetSupported(cpuid::InstructionSetFlags::AVX2)) + checkAVX2(); +} + +void CpuRuntimeDetection_AVX2::checkAVX2() +{ + __m256i a = _mm256_set_epi64x(1, 4, 8, 3); + __m256i b = _mm256_set_epi64x(2, 1, 1, 5); + __m256i c = _mm256_xor_si256(a, b); + + sal_Int64 values[4]; + _mm256_storeu_si256(reinterpret_cast<__m256i*>(&values), c); + + CPPUNIT_ASSERT_EQUAL(sal_Int64(6), values[0]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(9), values[1]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(5), values[2]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(3), values[3]); + + __m256i d = _mm256_set_epi64x(3, 5, 1, 0); + + __m256i result = _mm256_cmpeq_epi64(d, c); + + // Compare equals + sal_Int64 compare[4]; + _mm256_storeu_si256(reinterpret_cast<__m256i*>(&compare), result); + + CPPUNIT_ASSERT_EQUAL(sal_Int64(0), compare[0]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(0), compare[1]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(-1), compare[2]); + CPPUNIT_ASSERT_EQUAL(sal_Int64(-1), compare[3]); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(CpuRuntimeDetection_AVX2); + +} // end anonymous namespace + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_cpu_runtime_detection_SSE2.cxx b/tools/qa/cppunit/test_cpu_runtime_detection_SSE2.cxx new file mode 100644 index 000000000000..13dd48d2176e --- /dev/null +++ b/tools/qa/cppunit/test_cpu_runtime_detection_SSE2.cxx @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <tools/simdsupport.hxx> + +#ifdef LO_SSE2_AVAILABLE + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> + +#include <tools/cpuid.hxx> + +namespace +{ +class CpuRuntimeDetection_SSE2 : public CppUnit::TestFixture +{ +public: + void checkSSE2(); + void testCpuRuntimeDetection(); + + CPPUNIT_TEST_SUITE(CpuRuntimeDetection_SSE2); + CPPUNIT_TEST(testCpuRuntimeDetection); + CPPUNIT_TEST_SUITE_END(); +}; + +void CpuRuntimeDetection_SSE2::testCpuRuntimeDetection() +{ + // can only run if this function if CPU supports SSE2 + if (cpuid::isCpuInstructionSetSupported(cpuid::InstructionSetFlags::SSE2)) + checkSSE2(); +} + +void CpuRuntimeDetection_SSE2::checkSSE2() +{ + // Try some SSE2 intrinsics calcualtion + __m128i a = _mm_set1_epi32(15); + __m128i b = _mm_set1_epi32(15); + __m128i c = _mm_xor_si128(a, b); + + // Check zero + CPPUNIT_ASSERT_EQUAL(0xFFFF, _mm_movemask_epi8(_mm_cmpeq_epi32(c, _mm_setzero_si128()))); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(CpuRuntimeDetection_SSE2); + +} // end anonymous namespace + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/qa/cppunit/test_cpu_runtime_detection_SSSE3.cxx b/tools/qa/cppunit/test_cpu_runtime_detection_SSSE3.cxx new file mode 100644 index 000000000000..1d730d99e985 --- /dev/null +++ b/tools/qa/cppunit/test_cpu_runtime_detection_SSSE3.cxx @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <tools/simdsupport.hxx> + +#ifdef LO_SSSE3_AVAILABLE + +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> + +#include <tools/cpuid.hxx> + +namespace +{ +class CpuRuntimeDetection_SSSE3 : public CppUnit::TestFixture +{ +public: + void checkSSSE3(); + void testCpuRuntimeDetection(); + + CPPUNIT_TEST_SUITE(CpuRuntimeDetection_SSSE3); + CPPUNIT_TEST(testCpuRuntimeDetection); + CPPUNIT_TEST_SUITE_END(); +}; + +void CpuRuntimeDetection_SSSE3::testCpuRuntimeDetection() +{ + // can only run if this function if CPU supports SSSE3 + if (cpuid::isCpuInstructionSetSupported(cpuid::InstructionSetFlags::SSSE3)) + checkSSSE3(); +} + +void CpuRuntimeDetection_SSSE3::checkSSSE3() +{ + // Try some SSSE3 intrinsics calcualtion + __m128i a = _mm_set1_epi32(3); + __m128i b = _mm_set1_epi32(3); + __m128i c = _mm_maddubs_epi16(a, b); + + // Check result is 9 + CPPUNIT_ASSERT_EQUAL(0xFFFF, _mm_movemask_epi8(_mm_cmpeq_epi32(c, _mm_set1_epi32(9)))); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(CpuRuntimeDetection_SSSE3); + +} // end anonymous namespace + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |