summaryrefslogtreecommitdiffstats
path: root/mozglue/misc/SIMD.h
diff options
context:
space:
mode:
Diffstat (limited to 'mozglue/misc/SIMD.h')
-rw-r--r--mozglue/misc/SIMD.h81
1 files changed, 81 insertions, 0 deletions
diff --git a/mozglue/misc/SIMD.h b/mozglue/misc/SIMD.h
new file mode 100644
index 0000000000..3d17185656
--- /dev/null
+++ b/mozglue/misc/SIMD.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_SIMD_h
+#define mozilla_SIMD_h
+
+#include "mozilla/Types.h"
+
+namespace mozilla {
+// A collection of SIMD-implemented algorithms. Some of these exist in the CRT.
+// However, the quality of the C runtime implementation varies wildly across
+// platforms, so these should at least ensure consistency.
+//
+// NOTE: these are currently only implemented with hand-written SIMD for x86
+// and AMD64 platforms, and fallback to the the C runtime or naive loops on
+// other architectures. Please consider this before switching an already
+// optimized loop to these helpers.
+class SIMD {
+ public:
+ // NOTE: for memchr we have a goofy void* signature just to be an easy drop
+ // in replacement for the CRT version. We also give memchr8 which is just a
+ // typed version of memchr.
+ static const void* memchr(const void* ptr, int value, size_t num) {
+ return memchr8(reinterpret_cast<const char*>(ptr), static_cast<char>(value),
+ num);
+ }
+
+ // Search through `ptr[0..length]` for the first occurrence of `value` and
+ // return the pointer to it, or nullptr if it cannot be found.
+ static MFBT_API const char* memchr8(const char* ptr, char value,
+ size_t length);
+
+ // This function just restricts our execution to the SSE2 path
+ static MFBT_API const char* memchr8SSE2(const char* ptr, char value,
+ size_t length);
+
+ // This function just restricts our execution to the AVX2 path
+ static MFBT_API const char* memchr8AVX2(const char* ptr, char value,
+ size_t length);
+
+ // Search through `ptr[0..length]` for the first occurrence of `value` and
+ // return the pointer to it, or nullptr if it cannot be found.
+ static MFBT_API const char16_t* memchr16(const char16_t* ptr, char16_t value,
+ size_t length);
+
+ // This function just restricts our execution to the SSE2 path
+ static MFBT_API const char16_t* memchr16SSE2(const char16_t* ptr,
+ char16_t value, size_t length);
+
+ // This function just restricts our execution to the AVX2 path
+ static MFBT_API const char16_t* memchr16AVX2(const char16_t* ptr,
+ char16_t value, size_t length);
+
+ // Search through `ptr[0..length]` for the first occurrence of `value` and
+ // return the pointer to it, or nullptr if it cannot be found.
+ static MFBT_API const uint64_t* memchr64(const uint64_t* ptr, uint64_t value,
+ size_t length);
+
+ // This function just restricts our execution to the AVX2 path
+ static MFBT_API const uint64_t* memchr64AVX2(const uint64_t* ptr,
+ uint64_t value, size_t length);
+
+ // Search through `ptr[0..length]` for the first occurrence of `v1` which is
+ // immediately followed by `v2` and return the pointer to the occurrence of
+ // `v1`.
+ static MFBT_API const char* memchr2x8(const char* ptr, char v1, char v2,
+ size_t length);
+
+ // Search through `ptr[0..length]` for the first occurrence of `v1` which is
+ // immediately followed by `v2` and return the pointer to the occurrence of
+ // `v1`.
+ static MFBT_API const char16_t* memchr2x16(const char16_t* ptr, char16_t v1,
+ char16_t v2, size_t length);
+};
+
+} // namespace mozilla
+
+#endif // mozilla_SIMD_h