diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4f760200f..b4215a8af 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,6 @@ include_directories( ${ENGINE_COMMON_INCLUDES} ${ENGINE_BLOCKCACHE_INCLUDE} ${ENGINE_PRIMPROC_INCLUDE} ) cmake_policy(SET CMP0054 NEW) +SET(CMAKE_CXX_STANDARD 20) if (WITH_UNITTESTS) set(EXTERNAL_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/external) diff --git a/tests/simd_processors.cpp b/tests/simd_processors.cpp index 403593710..eb5327a66 100644 --- a/tests/simd_processors.cpp +++ b/tests/simd_processors.cpp @@ -16,22 +16,40 @@ MA 02110-1301, USA. */ +#include #include +#include #include #include "datatypes/mcs_datatype.h" #include "datatypes/mcs_int128.h" #if defined(__x86_64__) -#include "simd_sse.h" + #include "simd_sse.h" + #define TESTS_USING_SSE 1 + using float64_t = double; + using float32_t = float; +#endif +#ifdef __aarch64__ + #include "simd_arm.h" + #define TESTS_USING_ARM 1 +#endif using namespace std; template class SimdProcessorTypedTest : public testing::Test { +public: using IntegralType = T; - public: - - + #if TESTS_USING_SSE + using SimdType = std::conditional_t::value, + simd::vi128f_wr, + std::conditional_t::value, + simd::vi128d_wr, + simd::vi128_wr>>; + using Proc = typename simd::SimdFilterProcessor; + #else + using Proc = typename simd::SimdFilterProcessor::WrapperType, TypeParam>; + #endif void SetUp() override { } @@ -42,53 +60,7 @@ TYPED_TEST_SUITE(SimdProcessorTypedTest, SimdProcessor128TypedTestTypes); TYPED_TEST(SimdProcessorTypedTest, SimdFilterProcessor_simd128) { - using Proc = typename simd::SimdFilterProcessor; - using SimdType = typename Proc::SimdType; - constexpr static simd::MT allTrue = 0xFFFF; - constexpr static simd::MT allFalse = 0x0; - Proc proc; - SimdType lhs = proc.loadValue((TypeParam)-2); - SimdType rhs = proc.loadValue((TypeParam)-3); - EXPECT_GT((uint64_t)-2LL, (uint64_t)-3LL); - EXPECT_EQ(proc.cmpGe(lhs, rhs), allTrue); - EXPECT_EQ(proc.cmpGt(lhs, rhs), allTrue); - EXPECT_EQ(proc.cmpGe(rhs, lhs), allFalse); - EXPECT_EQ(proc.cmpGt(rhs, lhs), allFalse); - EXPECT_EQ(proc.cmpLe(rhs, lhs), allTrue); - EXPECT_EQ(proc.cmpLt(rhs, lhs), allTrue); - EXPECT_EQ(proc.cmpLe(lhs, rhs), allFalse); - EXPECT_EQ(proc.cmpLt(lhs, rhs), allFalse); - EXPECT_EQ(proc.cmpEq(rhs, lhs), allFalse); - EXPECT_EQ(proc.cmpNe(rhs, lhs), allTrue); - lhs = proc.loadValue((TypeParam)-3); - EXPECT_EQ(proc.cmpEq(lhs, rhs), allTrue); - EXPECT_EQ(proc.cmpNe(rhs, lhs), allFalse); -} -#endif -#ifdef __aarch64__ -#include "simd_arm.h" - - -using namespace std; - -template -class SimdProcessorTypedTest : public testing::Test -{ - using IntegralType = T; - - public: - void SetUp() override - { - } -}; - -using SimdProcessor128TypedTestTypes = - ::testing::Types; -TYPED_TEST_SUITE(SimdProcessorTypedTest, SimdProcessor128TypedTestTypes); - -TYPED_TEST(SimdProcessorTypedTest, SimdFilterProcessor_simdarm128) -{ - using Proc = typename simd::SimdFilterProcessor::WrapperType, TypeParam>; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; constexpr static simd::MT allTrue = 0xFFFF; constexpr static simd::MT allFalse = 0x0; @@ -122,21 +94,32 @@ TYPED_TEST(SimdProcessorTypedTest, SimdFilterProcessor_simdarm128) EXPECT_EQ(proc.cmpEq(rhs, lhs), allTrue); EXPECT_EQ(proc.cmpNe(rhs, lhs), allFalse); } -TEST(SimdProcessorTest,Int8) + + +TEST(SimdProcessorTest, Int8) { - using Proc = typename simd::SimdFilterProcessor::WrapperType, int8_t>; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; Proc proc; + constexpr static simd::MT allTrue = 0xFFFF; simd::MT expect = 0x0; int8_t l[16]{0, 1, 2, 5, 4, 3, 8, 5, 6, 10, 58, 2, 32, 41, 2, 5}; int8_t r[16]{0, 1, 8, 35, 24, 13, 8, 25, 16, 10, 58, 2, 32, 41, 2, 5}; + int8_t minlr[16]{0, 1, 2, 5, 4, 3, 8, 5, 6, 10, 58, 2, 32, 41, 2, 5}; + int8_t maxlr[16]{0, 1, 8, 35, 24, 13, 8, 25, 16, 10, 58, 2, 32, 41, 2, 5}; SimdType lhs = proc.loadFrom(reinterpret_cast(l)); SimdType rhs = proc.loadFrom(reinterpret_cast(r)); + SimdType min = proc.loadFrom(reinterpret_cast(minlr)); + SimdType max = proc.loadFrom(reinterpret_cast(maxlr)); for (int i = 0; i < 16; i++) if (l[i] > r[i]) expect |= 1 << i; EXPECT_EQ(proc.cmpGt(lhs, rhs), expect); EXPECT_EQ(proc.cmpLe(lhs, rhs),(simd::MT) ~expect); + SimdType testmax = proc.max(lhs, rhs); + SimdType testmin = proc.min(lhs, rhs); + EXPECT_EQ(proc.cmpEq(testmax, max), allTrue); + EXPECT_EQ(proc.cmpEq(testmin, min), allTrue); expect = 0x0; for (int i = 0; i < 16; i++) @@ -154,20 +137,28 @@ TEST(SimdProcessorTest,Int8) } TEST(SimdProcessorTest, Uint8) { - using Proc = - typename simd::SimdFilterProcessor::WrapperType, uint8_t>; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; Proc proc; + constexpr static simd::MT allTrue = 0xFFFF; simd::MT expect = 0x0; uint8_t l[16]{0, 1, 2, 5, 4, 3, 8, 5, 6, 10, 5, 2, 32, 41, 2, 5}; uint8_t r[16]{0, 1, 8, 35, 24, 13, 8, 25, 16, 10, 58, 2, 32, 41, 2, 5}; + uint8_t minlr[16]{0, 1, 2, 5, 4, 3, 8, 5, 6, 10, 5, 2, 32, 41, 2, 5}; + uint8_t maxlr[16]{0, 1, 8, 35, 24, 13, 8, 25, 16, 10, 58, 2, 32, 41, 2, 5}; SimdType lhs = proc.loadFrom(reinterpret_cast(l)); SimdType rhs = proc.loadFrom(reinterpret_cast(r)); + SimdType min = proc.loadFrom(reinterpret_cast(minlr)); + SimdType max = proc.loadFrom(reinterpret_cast(maxlr)); for (int i = 0; i < 16; i++) if (l[i] > r[i]) expect |= 1 << i; EXPECT_EQ(proc.cmpGt(lhs, rhs), expect); EXPECT_EQ(proc.cmpLe(lhs, rhs),(simd::MT) ~expect); + SimdType testmax = proc.max(lhs, rhs); + SimdType testmin = proc.min(lhs, rhs); + EXPECT_EQ(proc.cmpEq(testmax, max), allTrue); + EXPECT_EQ(proc.cmpEq(testmin, min), allTrue); expect = 0x0; for (int i = 0; i < 16; i++) @@ -183,22 +174,31 @@ TEST(SimdProcessorTest, Uint8) EXPECT_EQ(proc.cmpLt(lhs, rhs), expect); EXPECT_EQ(proc.cmpGe(lhs, rhs),(simd::MT) ~expect); } + TEST(SimdProcessorTest, Int16) { - using Proc = - typename simd::SimdFilterProcessor::WrapperType, int16_t>; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; Proc proc; + constexpr static simd::MT allTrue = 0xFFFF; simd::MT expect = 0x0; int16_t l[8]{0, 1, 2, -5, 4, 3, -8, 200}; - int16_t r[8]{0, 105, -8, 35, 24, 13, 8}; + int16_t r[8]{0, 105, -8, 35, 24, 13, 8, 100}; + int16_t minlr[8]{0, 1, -8, -5, 4, 3, -8, 100}; + int16_t maxlr[8]{0, 105, 2, 35, 24, 13, 8, 200}; SimdType lhs = proc.loadFrom(reinterpret_cast(l)); SimdType rhs = proc.loadFrom(reinterpret_cast(r)); + SimdType min = proc.loadFrom(reinterpret_cast(minlr)); + SimdType max = proc.loadFrom(reinterpret_cast(maxlr)); for (int i = 0; i < 8; i++) if (l[i] > r[i]) expect |= 3 << i * 2; EXPECT_EQ(proc.cmpGt(lhs, rhs), expect); EXPECT_EQ(proc.cmpLe(lhs, rhs), (simd::MT)~expect); + SimdType testmax = proc.max(lhs, rhs); + SimdType testmin = proc.min(lhs, rhs); + EXPECT_EQ(proc.cmpEq(testmax, max), allTrue); + EXPECT_EQ(proc.cmpEq(testmin, min), allTrue); expect = 0x0; for (int i = 0; i < 8; i++) @@ -216,20 +216,28 @@ TEST(SimdProcessorTest, Int16) } TEST(SimdProcessorTest, Uint16) { - using Proc = typename simd::SimdFilterProcessor::WrapperType, - uint16_t>; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; Proc proc; + constexpr static simd::MT allTrue = 0xFFFF; simd::MT expect = 0x0; uint16_t l[8]{0, 1, 2, 5, 4, 3, 8, 5}; - uint16_t r[8]{0, 1, 8, 35, 24, 13, 8}; + uint16_t r[8]{0, 1, 8, 35, 24, 13, 8, 17}; + uint16_t minlr[8]{0, 1, 2, 5, 4, 3, 8, 5}; + uint16_t maxlr[8]{0, 1, 8, 35, 24, 13, 8, 17}; SimdType lhs = proc.loadFrom(reinterpret_cast(l)); SimdType rhs = proc.loadFrom(reinterpret_cast(r)); + SimdType min = proc.loadFrom(reinterpret_cast(minlr)); + SimdType max = proc.loadFrom(reinterpret_cast(maxlr)); for (int i = 0; i < 8; i++) if (l[i] > r[i]) expect |= 3 << i*2; EXPECT_EQ(proc.cmpGt(lhs, rhs), expect); EXPECT_EQ(proc.cmpLe(lhs, rhs), (simd::MT)~expect); + SimdType testmax = proc.max(lhs, rhs); + SimdType testmin = proc.min(lhs, rhs); + EXPECT_EQ(proc.cmpEq(testmax, max), allTrue); + EXPECT_EQ(proc.cmpEq(testmin, min), allTrue); expect = 0x0; for (int i = 0; i < 8; i++) @@ -248,20 +256,28 @@ TEST(SimdProcessorTest, Uint16) TEST(SimdProcessorTest, Int32) { - using Proc = - typename simd::SimdFilterProcessor::WrapperType, int32_t>; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; Proc proc; + constexpr static simd::MT allTrue = 0xFFFF; simd::MT expect = 0x0; int32_t l[8]{0, 1, 2, -5}; int32_t r[8]{0, 105, -8,54333}; + int32_t minlr[8]{0, 1, -8, -5}; + int32_t maxlr[8]{0, 105, 2, 54333}; SimdType lhs = proc.loadFrom(reinterpret_cast(l)); SimdType rhs = proc.loadFrom(reinterpret_cast(r)); + SimdType min = proc.loadFrom(reinterpret_cast(minlr)); + SimdType max = proc.loadFrom(reinterpret_cast(maxlr)); for (int i = 0; i < 4; i++) if (l[i] > r[i]) expect |= 15 << i * 4; EXPECT_EQ(proc.cmpGt(lhs, rhs), expect); EXPECT_EQ(proc.cmpLe(lhs, rhs), (simd::MT)~expect); + SimdType testmax = proc.max(lhs, rhs); + SimdType testmin = proc.min(lhs, rhs); + EXPECT_EQ(proc.cmpEq(testmax, max), allTrue); + EXPECT_EQ(proc.cmpEq(testmin, min), allTrue); expect = 0x0; for (int i = 0; i < 4; i++) @@ -279,20 +295,28 @@ TEST(SimdProcessorTest, Int32) } TEST(SimdProcessorTest, Uint32) { - using Proc = typename simd::SimdFilterProcessor::WrapperType, - uint32_t>; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; Proc proc; + constexpr static simd::MT allTrue = 0xFFFF; simd::MT expect = 0x0; uint32_t l[4]{0, 1002, 2, 514}; uint32_t r[4]{2, 1, 80555, 35}; + uint32_t minlr[8]{0, 1, 2, 35}; + uint32_t maxlr[8]{2, 1002, 80555, 514}; SimdType lhs = proc.loadFrom(reinterpret_cast(l)); SimdType rhs = proc.loadFrom(reinterpret_cast(r)); + SimdType min = proc.loadFrom(reinterpret_cast(minlr)); + SimdType max = proc.loadFrom(reinterpret_cast(maxlr)); for (int i = 0; i < 4; i++) if (l[i] > r[i]) expect |= 15 << i * 4; EXPECT_EQ(proc.cmpGt(lhs, rhs), expect); EXPECT_EQ(proc.cmpLe(lhs, rhs), (simd::MT)~expect); + SimdType testmax = proc.max(lhs, rhs); + SimdType testmin = proc.min(lhs, rhs); + EXPECT_EQ(proc.cmpEq(testmax, max), allTrue); + EXPECT_EQ(proc.cmpEq(testmin, min), allTrue); expect = 0x0; for (int i = 0; i < 4; i++) @@ -310,20 +334,28 @@ TEST(SimdProcessorTest, Uint32) } TEST(SimdProcessorTest, Int64) { - using Proc = - typename simd::SimdFilterProcessor::WrapperType, int64_t>; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; Proc proc; + constexpr static simd::MT allTrue = 0xFFFF; simd::MT expect = 0x0; int64_t l[2]{-5, 122020}; int64_t r[2]{0, 105}; + int64_t minlr[8]{-5, 105}; + int64_t maxlr[8]{0, 122020}; SimdType lhs = proc.loadFrom(reinterpret_cast(l)); SimdType rhs = proc.loadFrom(reinterpret_cast(r)); + SimdType min = proc.loadFrom(reinterpret_cast(minlr)); + SimdType max = proc.loadFrom(reinterpret_cast(maxlr)); for (int i = 0; i < 2; i++) if (l[i] > r[i]) expect |= 0xFF << i * 8; EXPECT_EQ(proc.cmpGt(lhs, rhs), expect); EXPECT_EQ(proc.cmpLe(lhs, rhs), (simd::MT)~expect); + SimdType testmax = proc.max(lhs, rhs); + SimdType testmin = proc.min(lhs, rhs); + EXPECT_EQ(proc.cmpEq(testmax, max), allTrue); + EXPECT_EQ(proc.cmpEq(testmin, min), allTrue); expect = 0x0; for (int i = 0; i < 2; i++) @@ -341,20 +373,28 @@ TEST(SimdProcessorTest, Int64) } TEST(SimdProcessorTest, Uint64) { - using Proc = typename simd::SimdFilterProcessor::WrapperType, - uint64_t>; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; Proc proc; + constexpr static simd::MT allTrue = 0xFFFF; simd::MT expect = 0x0; uint64_t l[2]{822, 1002}; uint64_t r[2]{2, 1}; + uint64_t minlr[8]{2, 1}; + uint64_t maxlr[8]{822, 1002}; SimdType lhs = proc.loadFrom(reinterpret_cast(l)); SimdType rhs = proc.loadFrom(reinterpret_cast(r)); + SimdType min = proc.loadFrom(reinterpret_cast(minlr)); + SimdType max = proc.loadFrom(reinterpret_cast(maxlr)); for (int i = 0; i < 2; i++) if (l[i] > r[i]) expect |= 0xFF << i * 8; EXPECT_EQ(proc.cmpGt(lhs, rhs), expect); EXPECT_EQ(proc.cmpLe(lhs, rhs), (simd::MT)~expect); + SimdType testmax = proc.max(lhs, rhs); + SimdType testmin = proc.min(lhs, rhs); + EXPECT_EQ(proc.cmpEq(testmax, max), allTrue); + EXPECT_EQ(proc.cmpEq(testmin, min), allTrue); expect = 0x0; for (int i = 0; i < 2; i++) @@ -372,19 +412,28 @@ TEST(SimdProcessorTest, Uint64) } TEST(SimdProcessorTest, Float64) { - using Proc = typename simd::SimdFilterProcessor; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; Proc proc; + constexpr static simd::MT allTrue = 0xFFFF; simd::MT expect = 0x0; float64_t l[2]{-5.0, 12.5620}; float64_t r[2]{2.9, 1}; + float64_t minlr[8]{-5.0, 1}; + float64_t maxlr[8]{2.9, 12.5620}; SimdType lhs = proc.loadFrom(reinterpret_cast(l)); SimdType rhs = proc.loadFrom(reinterpret_cast(r)); + SimdType min = proc.loadFrom(reinterpret_cast(minlr)); + SimdType max = proc.loadFrom(reinterpret_cast(maxlr)); for (int i = 0; i < 2; i++) if (l[i] > r[i]) expect |= 0xFF << i * 8; EXPECT_EQ(proc.cmpGt(lhs, rhs), expect); EXPECT_EQ(proc.cmpLe(lhs, rhs), (simd::MT)~expect); + SimdType testmax = proc.max(lhs, rhs); + SimdType testmin = proc.min(lhs, rhs); + EXPECT_EQ(proc.cmpEq(testmax, max), allTrue); + EXPECT_EQ(proc.cmpEq(testmin, min), allTrue); expect = 0x0; for (int i = 0; i < 2; i++) @@ -402,19 +451,28 @@ TEST(SimdProcessorTest, Float64) } TEST(SimdProcessorTest, Float32) { - using Proc = typename simd::SimdFilterProcessor; + using Proc = typename SimdProcessorTypedTest::Proc; using SimdType = typename Proc::SimdType; Proc proc; + constexpr static simd::MT allTrue = 0xFFFF; simd::MT expect = 0x0; float32_t l[4]{82, 102,-5.6,9.5}; float32_t r[4]{2.0, 1,-5.7,6}; + float32_t minlr[8]{2.0, 1, -5.7, 6}; + float32_t maxlr[8]{82, 102, -5.6, 9.5}; SimdType lhs = proc.loadFrom(reinterpret_cast(l)); SimdType rhs = proc.loadFrom(reinterpret_cast(r)); + SimdType min = proc.loadFrom(reinterpret_cast(minlr)); + SimdType max = proc.loadFrom(reinterpret_cast(maxlr)); for (int i = 0; i < 4; i++) if (l[i] > r[i]) expect |= 15 << i * 4; EXPECT_EQ(proc.cmpGt(lhs, rhs), expect); EXPECT_EQ(proc.cmpLe(lhs, rhs), (simd::MT)~expect); + SimdType testmax = proc.max(lhs, rhs); + SimdType testmin = proc.min(lhs, rhs); + EXPECT_EQ(proc.cmpEq(testmax, max), allTrue); + EXPECT_EQ(proc.cmpEq(testmin, min), allTrue); expect = 0x0; for (int i = 0; i < 4; i++) @@ -430,4 +488,3 @@ TEST(SimdProcessorTest, Float32) EXPECT_EQ(proc.cmpLt(lhs, rhs), expect); EXPECT_EQ(proc.cmpGe(lhs, rhs), (simd::MT)~expect); } -#endif diff --git a/utils/common/simd_arm.h b/utils/common/simd_arm.h index d7d555383..304849125 100644 --- a/utils/common/simd_arm.h +++ b/utils/common/simd_arm.h @@ -165,13 +165,13 @@ template struct TypeToVecWrapperType; template -struct TypeToVecWrapperType::value>::type> +struct TypeToVecWrapperType::value>::type> : WidthToVecWrapperType { }; template -struct TypeToVecWrapperType::value>::type> +struct TypeToVecWrapperType::value>::type> : WidthToSVecWrapperType { }; @@ -419,6 +419,16 @@ class SimdFilterProcessor< { vst1q_s32(reinterpret_cast(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return reinterpret_cast(std::min(reinterpret_cast(x), reinterpret_cast(y))); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return reinterpret_cast(std::max(reinterpret_cast(x), reinterpret_cast(y))); + } }; template @@ -532,6 +542,16 @@ class SimdFilterProcessor< { vst1q_f64(reinterpret_cast(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return vminq_f64(x, y); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return vmaxq_f64(x, y); + } }; template @@ -645,6 +665,16 @@ class SimdFilterProcessor< { vst1q_f32(reinterpret_cast(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return vminq_f32(x, y); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return vmaxq_f32(x, y); + } }; template @@ -752,6 +782,16 @@ class SimdFilterProcessor< { vst1q_s64(reinterpret_cast(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return vbslq_s64(vcgtq_s64(x,y), x, y); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return vbslq_s64(vcgtq_s64(y,x), x, y); + } }; template @@ -859,6 +899,16 @@ class SimdFilterProcessor< { vst1q_u64(reinterpret_cast(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return vbslq_u64(vcgtq_u64(x,y), x, y); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return vbslq_u64(vcgtq_u64(y,x), x, y); + } }; template class SimdFilterProcessor< @@ -965,6 +1015,16 @@ class SimdFilterProcessor< { vst1q_s32(reinterpret_cast(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return vminq_s32(x, y); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return vmaxq_s32(x, y); + } }; template @@ -1072,6 +1132,16 @@ class SimdFilterProcessor< { vst1q_u32(reinterpret_cast(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return vminq_u32(x, y); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return vmaxq_u32(x, y); + } }; template @@ -1178,6 +1248,16 @@ class SimdFilterProcessor< { vst1q_s16(reinterpret_cast(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return vminq_s16(x, y); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return vmaxq_s16(x, y); + } }; template @@ -1284,6 +1364,16 @@ class SimdFilterProcessor(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return vminq_u16(x, y); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return vmaxq_u16(x, y); + } }; template @@ -1389,6 +1479,16 @@ class SimdFilterProcessor< { vst1q_s8(reinterpret_cast(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return vminq_s8(x, y); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return vmaxq_s8(x, y); + } }; template @@ -1496,6 +1596,16 @@ class SimdFilterProcessor< { vst1q_u8(reinterpret_cast(dst), x); } + + MCS_FORCE_INLINE SimdType min(SimdType& x, SimdType& y) + { + return vminq_u8(x, y); + } + + MCS_FORCE_INLINE SimdType max(SimdType& x, SimdType& y) + { + return vmaxq_u8(x, y); + } }; }; // namespace simd