mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-28 20:16:58 +03:00
[Docs] Add more docs to the sse4.2 cmpstr fns (#94)
- Add more examples to _mm_cmpistri - Add basic docs to _mm_cmpestri - Cleanup lib docs
This commit is contained in:
committed by
Alex Crichton
parent
186b8fe093
commit
b421e9210c
+18
-22
@@ -67,32 +67,28 @@
|
||||
//! to enable a given feature and use the desired intrinsic.
|
||||
//!
|
||||
//! ```
|
||||
//! #![feature(cfg_target_feature)]
|
||||
//! #![feature(target_feature)]
|
||||
//! # #![feature(cfg_target_feature)]
|
||||
//! # #![feature(target_feature)]
|
||||
//! # #[macro_use]
|
||||
//! # extern crate stdsimd;
|
||||
//! # fn main() {
|
||||
//! # if cfg_feature_enabled!("avx2") {
|
||||
//! // avx2 specific code may be used in this function
|
||||
//! #[target_feature = "+avx2"]
|
||||
//! fn and_256() {
|
||||
//! // avx2 feature specific intrinsics will work here!
|
||||
//! use stdsimd::vendor::{__m256i, _mm256_and_si256};
|
||||
//!
|
||||
//! #[macro_use]
|
||||
//! extern crate stdsimd;
|
||||
//! let a = __m256i::splat(5);
|
||||
//! let b = __m256i::splat(3);
|
||||
//!
|
||||
//! fn main() {
|
||||
//! if cfg_feature_enabled!("avx2") {
|
||||
//! let got = unsafe { _mm256_and_si256(a, b) };
|
||||
//!
|
||||
//! // avx2 will work. It is safe to use avx2 specific code here.
|
||||
//! #[target_feature = "+avx2"]
|
||||
//! fn and_256() {
|
||||
//! // avx2 feature specific intrinsics will work here!
|
||||
//! use stdsimd::vendor::{__m256i, _mm256_and_si256};
|
||||
//!
|
||||
//! let a = __m256i::splat(5);
|
||||
//! let b = __m256i::splat(3);
|
||||
//! let got = unsafe { _mm256_and_si256(a, b) };
|
||||
//! assert_eq!(got, __m256i::splat(1));
|
||||
//! }
|
||||
//!
|
||||
//! and_256();
|
||||
//! } else {
|
||||
//! println!("avx2 intrinsics will not work, they may generate SIGILL");
|
||||
//! }
|
||||
//! assert_eq!(got, __m256i::splat(1));
|
||||
//! }
|
||||
//! # and_256();
|
||||
//! # }
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! # Status
|
||||
|
||||
@@ -58,7 +58,9 @@ macro_rules! call {
|
||||
}
|
||||
|
||||
/// Compare packed strings with implicit lengths in `a` and `b` using the
|
||||
/// control in `imm8`, and return the generated index.
|
||||
/// control in `imm8`, and return the generated index. Similar to [`_mm_cmpestri`]
|
||||
/// with the excception that [`_mm_cmpestri`] requires the lengths of `a` and
|
||||
/// `b` to be explicitly specified.
|
||||
///
|
||||
/// # Control modes
|
||||
///
|
||||
@@ -87,6 +89,8 @@ macro_rules! call {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Find a substring using [`_SIDD_CMP_EQUAL_ORDERED`]
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
@@ -126,6 +130,89 @@ macro_rules! call {
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// The `_mm_cmpistri` intrinsic may also be used to find the existance of
|
||||
/// one or more of a given set of characters in the haystack.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("sse4.2") {
|
||||
/// # #[target_feature = "+sse4.2"]
|
||||
/// # fn worker() {
|
||||
/// use stdsimd::simd::u8x16;
|
||||
/// use stdsimd::vendor::{__m128i, _mm_cmpistri, _SIDD_CMP_EQUAL_ANY};
|
||||
///
|
||||
/// // Ensure your input is 16 byte aligned
|
||||
/// let password = b"hunter2\0\0\0\0\0\0\0\0\0";
|
||||
/// let special_chars = b"!@#$%^&*()[]:;<>";
|
||||
///
|
||||
/// // Load the input
|
||||
/// let a = __m128i::from(u8x16::load(special_chars, 0));
|
||||
/// let b = __m128i::from(u8x16::load(password, 0));
|
||||
///
|
||||
/// // Use _SIDD_CMP_EQUAL_ANY to find the index of any bytes in b
|
||||
/// let idx = unsafe {
|
||||
/// _mm_cmpistri(a, b, _SIDD_CMP_EQUAL_ANY)
|
||||
/// };
|
||||
///
|
||||
/// if idx < 16 {
|
||||
/// println!("Congrats! Your password contains a special character");
|
||||
/// # panic!("{:?} does not contain a special character", password);
|
||||
/// } else {
|
||||
/// println!("Your password should contain a special character");
|
||||
/// }
|
||||
/// # }
|
||||
/// # worker();
|
||||
/// # }
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Working with 16-bit characters.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("sse4.2") {
|
||||
/// # #[target_feature = "+sse4.2"]
|
||||
/// # fn worker() {
|
||||
/// use stdsimd::simd::u16x8;
|
||||
/// use stdsimd::vendor::{__m128i, _mm_cmpistri};
|
||||
/// use stdsimd::vendor::{_SIDD_UWORD_OPS, _SIDD_CMP_EQUAL_EACH};
|
||||
///
|
||||
/// # let mut some_utf16_words = [0u16; 8];
|
||||
/// # let mut more_utf16_words = [0u16; 8];
|
||||
/// # '❤'.encode_utf16(&mut some_utf16_words);
|
||||
/// # '𝕊'.encode_utf16(&mut more_utf16_words);
|
||||
/// // Load the input
|
||||
/// let a = __m128i::from(u16x8::load(&some_utf16_words, 0));
|
||||
/// let b = __m128i::from(u16x8::load(&more_utf16_words, 0));
|
||||
///
|
||||
/// // Specify _SIDD_UWORD_OPS to compare words instead of bytes, and
|
||||
/// // use _SIDD_CMP_EQUAL_EACH to compare the two strings.
|
||||
/// let idx = unsafe {
|
||||
/// _mm_cmpistri(a, b, _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH)
|
||||
/// };
|
||||
///
|
||||
/// if idx == 0 {
|
||||
/// println!("16-bit unicode strings were equal!");
|
||||
/// # panic!("Strings should not be equal!")
|
||||
/// } else {
|
||||
/// println!("16-bit unicode strings were not equal!");
|
||||
/// }
|
||||
/// # }
|
||||
/// # worker();
|
||||
/// # }
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`_SIDD_UBYTE_OPS`]: constant._SIDD_UBYTE_OPS.html
|
||||
/// [`_SIDD_UWORD_OPS`]: constant._SIDD_UWORD_OPS.html
|
||||
/// [`_SIDD_SBYTE_OPS`]: constant._SIDD_SBYTE_OPS.html
|
||||
@@ -138,6 +225,7 @@ macro_rules! call {
|
||||
/// [`_SIDD_NEGATIVE_POLARITY`]: constant._SIDD_NEGATIVE_POLARITY.html
|
||||
/// [`_SIDD_LEAST_SIGNIFICANT`]: constant._SIDD_LEAST_SIGNIFICANT.html
|
||||
/// [`_SIDD_MOST_SIGNIFICANT`]: constant._SIDD_MOST_SIGNIFICANT.html
|
||||
/// [`_mm_cmpestri`]: fn._mm_cmpestri.html
|
||||
#[inline(always)]
|
||||
#[target_feature = "+sse4.2"]
|
||||
#[cfg_attr(test, assert_instr(pcmpistri, imm8 = 0))]
|
||||
@@ -255,7 +343,87 @@ macro_rules! call {
|
||||
}
|
||||
|
||||
/// Compare packed strings `a` and `b` with lengths `la` and `lb` using the
|
||||
/// control in `imm8`, and return the generated index.
|
||||
/// control in `imm8`, and return the generated index. Similar to [`_mm_cmpistri`]
|
||||
/// with the excception that [`_mm_cmpistri`] implicityly determines the length of
|
||||
/// `a` and `b`.
|
||||
///
|
||||
/// # Control modes
|
||||
///
|
||||
/// The control specified by `imm8` may be one or more of the following.
|
||||
///
|
||||
/// ## Data size and signedness
|
||||
///
|
||||
/// - [`_SIDD_UBYTE_OPS`] - Default
|
||||
/// - [`_SIDD_UWORD_OPS`]
|
||||
/// - [`_SIDD_SBYTE_OPS`]
|
||||
/// - [`_SIDD_SWORD_OPS`]
|
||||
///
|
||||
/// ## Comparison options
|
||||
/// - [`_SIDD_CMP_EQUAL_ANY`] - Default
|
||||
/// - [`_SIDD_CMP_RANGES`]
|
||||
/// - [`_SIDD_CMP_EQUAL_EACH`]
|
||||
/// - [`_SIDD_CMP_EQUAL_ORDERED`]
|
||||
///
|
||||
/// ## Result polarity
|
||||
/// - [`_SIDD_POSITIVE_POLARITY`] - Default
|
||||
/// - [`_SIDD_NEGATIVE_POLARITY`]
|
||||
///
|
||||
/// ## Bit returned
|
||||
/// - [`_SIDD_LEAST_SIGNIFICANT`] - Default
|
||||
/// - [`_SIDD_MOST_SIGNIFICANT`]
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("sse4.2") {
|
||||
/// # #[target_feature = "+sse4.2"]
|
||||
/// # fn worker() {
|
||||
///
|
||||
/// use stdsimd::simd::u8x16;
|
||||
/// use stdsimd::vendor::{__m128i, _mm_cmpestri, _SIDD_CMP_EQUAL_ORDERED};
|
||||
///
|
||||
/// // The string we want to find a substring in
|
||||
/// let haystack = b"Split \r\n\t line ";
|
||||
///
|
||||
/// // The string we want to search for with some
|
||||
/// // extra bytes we do not want to search for.
|
||||
/// let needle = b"\r\n\t ignore this ";
|
||||
///
|
||||
/// let a = __m128i::from(u8x16::load(needle, 0));
|
||||
/// let b = __m128i::from(u8x16::load(haystack, 0));
|
||||
///
|
||||
/// // Note: We explicitly specify we only want to search `b` for the
|
||||
/// // first 3 characters of a.
|
||||
/// let idx = unsafe {
|
||||
/// _mm_cmpestri(a, 3, b, 15, _SIDD_CMP_EQUAL_ORDERED)
|
||||
/// };
|
||||
///
|
||||
/// assert_eq!(idx, 6);
|
||||
/// # }
|
||||
/// # worker();
|
||||
/// # }
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`_SIDD_UBYTE_OPS`]: constant._SIDD_UBYTE_OPS.html
|
||||
/// [`_SIDD_UWORD_OPS`]: constant._SIDD_UWORD_OPS.html
|
||||
/// [`_SIDD_SBYTE_OPS`]: constant._SIDD_SBYTE_OPS.html
|
||||
/// [`_SIDD_SWORD_OPS`]: constant._SIDD_SWORD_OPS.html
|
||||
/// [`_SIDD_CMP_EQUAL_ANY`]: constant._SIDD_CMP_EQUAL_ANY.html
|
||||
/// [`_SIDD_CMP_RANGES`]: constant._SIDD_CMP_RANGES.html
|
||||
/// [`_SIDD_CMP_EQUAL_EACH`]: constant._SIDD_CMP_EQUAL_EACH.html
|
||||
/// [`_SIDD_CMP_EQUAL_ORDERED`]: constant._SIDD_CMP_EQUAL_ORDERED.html
|
||||
/// [`_SIDD_POSITIVE_POLARITY`]: constant._SIDD_POSITIVE_POLARITY.html
|
||||
/// [`_SIDD_NEGATIVE_POLARITY`]: constant._SIDD_NEGATIVE_POLARITY.html
|
||||
/// [`_SIDD_LEAST_SIGNIFICANT`]: constant._SIDD_LEAST_SIGNIFICANT.html
|
||||
/// [`_SIDD_MOST_SIGNIFICANT`]: constant._SIDD_MOST_SIGNIFICANT.html
|
||||
/// [`_mm_cmpistri`]: fn._mm_cmpistri.html
|
||||
#[inline(always)]
|
||||
#[target_feature = "+sse4.2"]
|
||||
#[cfg_attr(test, assert_instr(pcmpestri, imm8 = 0))]
|
||||
|
||||
Reference in New Issue
Block a user