SIMD.h (4339B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_SIMD_h 8 #define mozilla_SIMD_h 9 10 #include "mozilla/Types.h" 11 #include <cstdint> 12 13 namespace mozilla { 14 // A collection of SIMD-implemented algorithms. Some of these exist in the CRT. 15 // However, the quality of the C runtime implementation varies wildly across 16 // platforms, so these should at least ensure consistency. 17 // 18 // NOTE: these are currently only implemented with hand-written SIMD for x86 19 // and AMD64 platforms, and fallback to the the C runtime or naive loops on 20 // other architectures. Please consider this before switching an already 21 // optimized loop to these helpers. 22 class SIMD { 23 public: 24 // NOTE: for memchr we have a goofy void* signature just to be an easy drop 25 // in replacement for the CRT version. We also give memchr8 which is just a 26 // typed version of memchr. 27 static const void* memchr(const void* ptr, int value, size_t num) { 28 return memchr8(reinterpret_cast<const char*>(ptr), static_cast<char>(value), 29 num); 30 } 31 32 // Search through `ptr[0..length]` for the first occurrence of `value` and 33 // return the pointer to it, or nullptr if it cannot be found. 34 static MFBT_API const char* memchr8(const char* ptr, char value, 35 size_t length); 36 37 // This function just restricts our execution to the SSE2 path 38 static MFBT_API const char* memchr8SSE2(const char* ptr, char value, 39 size_t length); 40 41 // This function just restricts our execution to the AVX2 path 42 static MFBT_API const char* memchr8AVX2(const char* ptr, char value, 43 size_t length); 44 45 // Search through `ptr[0..length]` for the first occurrence of `value` and 46 // return the pointer to it, or nullptr if it cannot be found. 47 static MFBT_API const char16_t* memchr16(const char16_t* ptr, char16_t value, 48 size_t length); 49 50 // This function just restricts our execution to the SSE2 path 51 static MFBT_API const char16_t* memchr16SSE2(const char16_t* ptr, 52 char16_t value, size_t length); 53 54 // This function just restricts our execution to the AVX2 path 55 static MFBT_API const char16_t* memchr16AVX2(const char16_t* ptr, 56 char16_t value, size_t length); 57 58 // Search through `ptr[0..length]` for the first occurrence of `value` and 59 // return the pointer to it, or nullptr if it cannot be found. 60 static MFBT_API const uint32_t* memchr32(const uint32_t* ptr, uint32_t value, 61 size_t length); 62 63 // This function just restricts our execution to the AVX2 path 64 static MFBT_API const uint32_t* memchr32AVX2(const uint32_t* ptr, 65 uint32_t value, size_t length); 66 67 // Search through `ptr[0..length]` for the first occurrence of `value` and 68 // return the pointer to it, or nullptr if it cannot be found. 69 static MFBT_API const uint64_t* memchr64(const uint64_t* ptr, uint64_t value, 70 size_t length); 71 72 // This function just restricts our execution to the AVX2 path 73 static MFBT_API const uint64_t* memchr64AVX2(const uint64_t* ptr, 74 uint64_t value, size_t length); 75 76 // Search through `ptr[0..length]` for the first occurrence of `v1` which is 77 // immediately followed by `v2` and return the pointer to the occurrence of 78 // `v1`. 79 static MFBT_API const char* memchr2x8(const char* ptr, char v1, char v2, 80 size_t length); 81 82 // Search through `ptr[0..length]` for the first occurrence of `v1` which is 83 // immediately followed by `v2` and return the pointer to the occurrence of 84 // `v1`. 85 static MFBT_API const char16_t* memchr2x16(const char16_t* ptr, char16_t v1, 86 char16_t v2, size_t length); 87 }; 88 89 } // namespace mozilla 90 91 #endif // mozilla_SIMD_h