[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:
Dan Robertson
2017-10-05 12:26:40 -04:00
committed by Alex Crichton
parent 186b8fe093
commit b421e9210c
2 changed files with 188 additions and 24 deletions
+18 -22
View File
@@ -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
+170 -2
View File
@@ -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))]