gecko-dev/mozglue/misc/SIMD.h

82 lines
3.7 KiB
C++

/* -*- 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