diff --git a/CMakeLists.txt b/CMakeLists.txt index a4973c02..0e118dd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -521,6 +521,7 @@ set (hs_exec_SRCS src/util/shuffle_ssse3.h src/util/simd_utils.h src/util/simd_utils_ssse3.h + src/util/simd_utils_ssse3.c src/util/state_compress.h src/util/state_compress.c src/util/unaligned.h diff --git a/src/util/simd_utils.h b/src/util/simd_utils.h index e115aa7a..99ad7ce5 100644 --- a/src/util/simd_utils.h +++ b/src/util/simd_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Intel Corporation + * Copyright (c) 2015-2016, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -199,6 +199,7 @@ static really_inline m128 shiftLeft8Bits(m128 a) { } #define byteShiftRight128(a, count_immed) _mm_srli_si128(a, count_immed) +#define byteShiftLeft128(a, count_immed) _mm_slli_si128(a, count_immed) #if !defined(__AVX2__) // TODO: this entire file needs restructuring - this carveout is awful diff --git a/src/util/simd_utils_ssse3.c b/src/util/simd_utils_ssse3.c new file mode 100644 index 00000000..50cbe007 --- /dev/null +++ b/src/util/simd_utils_ssse3.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "simd_utils_ssse3.h" + +const char vbs_mask_data[] ALIGN_CL_DIRECTIVE = { + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, +}; diff --git a/src/util/simd_utils_ssse3.h b/src/util/simd_utils_ssse3.h index 23c77d22..268bf422 100644 --- a/src/util/simd_utils_ssse3.h +++ b/src/util/simd_utils_ssse3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Intel Corporation + * Copyright (c) 2015-2016, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -77,6 +77,15 @@ m128 pshufb(m128 a, m128 b) { return result; } +extern const char vbs_mask_data[]; + +static really_inline +m128 variable_byte_shift_m128(m128 in, s32 amount) { + assert(amount >= -16 && amount <= 16); + m128 shift_mask = loadu128(vbs_mask_data + 16 - amount); + return pshufb(in, shift_mask); +} + #if defined(__AVX2__) static really_inline diff --git a/unit/internal/simd_utils.cpp b/unit/internal/simd_utils.cpp index c0b2b2a0..de0f1eea 100644 --- a/unit/internal/simd_utils.cpp +++ b/unit/internal/simd_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Intel Corporation + * Copyright (c) 2015-2016, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -32,7 +32,7 @@ #include "util/alloc.h" #include "util/make_unique.h" #include "util/simd_utils.h" - +#include "util/simd_utils_ssse3.h" using namespace std; using namespace ue2; @@ -640,4 +640,58 @@ TEST(SimdUtilsTest, set2x128) { } #endif +TEST(SimdUtilsTest, variableByteShift128) { + char base[] = "0123456789ABCDEF"; + m128 in = loadu128(base); + + EXPECT_TRUE(!diff128(byteShiftRight128(in, 0), + variable_byte_shift_m128(in, 0))); + EXPECT_TRUE(!diff128(byteShiftRight128(in, 1), + variable_byte_shift_m128(in, -1))); + EXPECT_TRUE(!diff128(byteShiftRight128(in, 2), + variable_byte_shift_m128(in, -2))); + EXPECT_TRUE(!diff128(byteShiftRight128(in, 3), + variable_byte_shift_m128(in, -3))); + EXPECT_TRUE(!diff128(byteShiftRight128(in, 4), + variable_byte_shift_m128(in, -4))); + EXPECT_TRUE(!diff128(byteShiftRight128(in, 5), + variable_byte_shift_m128(in, -5))); + EXPECT_TRUE(!diff128(byteShiftRight128(in, 6), + variable_byte_shift_m128(in, -6))); + EXPECT_TRUE(!diff128(byteShiftRight128(in, 7), + variable_byte_shift_m128(in, -7))); + EXPECT_TRUE(!diff128(byteShiftRight128(in, 8), + variable_byte_shift_m128(in, -8))); + EXPECT_TRUE(!diff128(byteShiftRight128(in, 9), + variable_byte_shift_m128(in, -9))); + EXPECT_TRUE(!diff128(byteShiftRight128(in, 10), + variable_byte_shift_m128(in, -10))); + + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 0), + variable_byte_shift_m128(in, 0))); + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 1), + variable_byte_shift_m128(in, 1))); + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 2), + variable_byte_shift_m128(in, 2))); + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 3), + variable_byte_shift_m128(in, 3))); + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 4), + variable_byte_shift_m128(in, 4))); + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 5), + variable_byte_shift_m128(in, 5))); + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 6), + variable_byte_shift_m128(in, 6))); + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 7), + variable_byte_shift_m128(in, 7))); + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 8), + variable_byte_shift_m128(in, 8))); + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 9), + variable_byte_shift_m128(in, 9))); + EXPECT_TRUE(!diff128(byteShiftLeft128(in, 10), + variable_byte_shift_m128(in, 10))); + + EXPECT_TRUE(!diff128(zeroes128(), variable_byte_shift_m128(in, 16))); + EXPECT_TRUE(!diff128(zeroes128(), variable_byte_shift_m128(in, -16))); +} + } // namespace