[Docs] Improve documentation (#87)
- Add "How to write and example" section to CONTRIBUTING.md - Add a basic example using `target_feature` to the main page - Improve documentation of SSE 4.2 - Improve documentation of constants - Improve documentation of _mm_cmpistri
This commit is contained in:
parent
3202558c98
commit
c1da3bad76
3 changed files with 169 additions and 14 deletions
|
|
@ -24,13 +24,57 @@ particularly use some help. You may be most interested in [#40][vendor],
|
|||
implementing all vendor intrinsics on x86. That issue's got some good pointers
|
||||
about where to get started!
|
||||
|
||||
If you've got general questions feel free to [join us on gitter][gitter] and ask
|
||||
around! Feel free to ping either @BurntSushi or @alexcrichton with questions.
|
||||
|
||||
[gitter]: https://gitter.im/rust-impl-period/WG-libs-simd
|
||||
|
||||
# How to write examples for stdsimd intrinsics
|
||||
|
||||
There are a few features that must be enabled for the given intrinsic to work
|
||||
properly and the example must only be run by `cargo test --doc` when the feature
|
||||
is supported by the CPU. As a result, the default `fn main` that is generated by
|
||||
`rustdoc` will not work (in most cases). Consider using the following as a guide
|
||||
to ensure your example works as expected.
|
||||
|
||||
```rust
|
||||
/// # // We need cfg_target_feature to ensure the example is only
|
||||
/// # // run by `cargo test --doc` when the CPU supports the feature
|
||||
/// # #![feature(cfg_target_feature)]
|
||||
/// # // We need target_feature for the intrinsic to work
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # // rustdoc by default uses `extern crate stdsimd`, but we need the
|
||||
/// # // `#[macro_use]`
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// #
|
||||
/// # // The real main function
|
||||
/// # fn main() {
|
||||
/// # // Only run this if `<target feature>` is supported
|
||||
/// # if cfg_feature_enabled!("<target feature>") {
|
||||
/// # // Create a `worker` function that will only be run if the target feature
|
||||
/// # // is supported and ensure that `target_feature` is enabled for your worker
|
||||
/// # // function
|
||||
/// # #[target_feature = "+<target feature>"]
|
||||
/// # fn worker() {
|
||||
///
|
||||
/// // Write your example here. Feature specific intrinsics will work here! Go wild!
|
||||
///
|
||||
/// # }
|
||||
/// # worker();
|
||||
/// # }
|
||||
/// # }
|
||||
```
|
||||
|
||||
If some of the above syntax does not look familiar, the [Documentation as tests] section
|
||||
of the [Rust Book] describes the `rustdoc` syntax quite well. As always, feel free
|
||||
to [join us on gitter][gitter] and ask us if you hit any snags, and thank you for helping
|
||||
to improve the documentation of `stdsimd`!
|
||||
|
||||
[new]: https://github.com/rust-lang-nursery/stdsimd/issues/new
|
||||
[issues]: https://github.com/rust-lang-nursery/stdsimd/issues
|
||||
[help]: https://github.com/rust-lang-nursery/stdsimd/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22
|
||||
[impl]: https://github.com/rust-lang-nursery/stdsimd/issues?q=is%3Aissue+is%3Aopen+label%3Aimpl-period
|
||||
[vendor]: https://github.com/rust-lang-nursery/stdsimd/issues/40
|
||||
|
||||
If you've got general questions feel free to [join us on gitter][gitter] and ask
|
||||
around! Feel free to ping either @BurntSushi or @alexcrichton with questions.
|
||||
|
||||
[gitter]: https://gitter.im/rust-impl-period/WG-libs-simd
|
||||
[Documentation as tests]: https://doc.rust-lang.org/book/first-edition/documentation.html#documentation-as-tests
|
||||
[Rust Book]: https://doc.rust-lang.org/book/first-edition
|
||||
|
|
|
|||
|
|
@ -63,6 +63,38 @@
|
|||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! After verifying that a specified feature is available, use `target_feature`
|
||||
//! to enable a given feature and use the desired intrinsic.
|
||||
//!
|
||||
//! ```
|
||||
//! #![feature(cfg_target_feature)]
|
||||
//! #![feature(target_feature)]
|
||||
//!
|
||||
//! #[macro_use]
|
||||
//! extern crate stdsimd;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! if cfg_feature_enabled!("avx2") {
|
||||
//!
|
||||
//! // 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");
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! # Status
|
||||
//!
|
||||
//! This crate is intended for eventual inclusion into the standard library, but
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use stdsimd_test::assert_instr;
|
|||
use v128::*;
|
||||
use x86::__m128i;
|
||||
|
||||
/// String contains unsigned 8-bit characters
|
||||
/// String contains unsigned 8-bit characters *(Default)*
|
||||
pub const _SIDD_UBYTE_OPS: i8 = 0b00000000;
|
||||
/// String contains unsigned 16-bit characters
|
||||
pub const _SIDD_UWORD_OPS: i8 = 0b00000001;
|
||||
|
|
@ -13,16 +13,16 @@ pub const _SIDD_SBYTE_OPS: i8 = 0b00000010;
|
|||
/// String contains unsigned 16-bit characters
|
||||
pub const _SIDD_SWORD_OPS: i8 = 0b00000011;
|
||||
|
||||
/// For each character in `a`, find if it is in `b`
|
||||
/// For each character in `a`, find if it is in `b` *(Default)*
|
||||
pub const _SIDD_CMP_EQUAL_ANY: i8 = 0b00000000;
|
||||
/// For each character in `a`, determine if `b[0] <= c <= b[1] or b[1] <= c <= b[2]...`
|
||||
pub const _SIDD_CMP_RANGES: i8 = 0b00000100;
|
||||
/// String equality
|
||||
/// The strings defined by `a` and `b` are equal
|
||||
pub const _SIDD_CMP_EQUAL_EACH: i8 = 0b00001000;
|
||||
/// Substring search
|
||||
/// Search for the defined substring in the target
|
||||
pub const _SIDD_CMP_EQUAL_ORDERED: i8 = 0b00001100;
|
||||
|
||||
/// Do not negate results
|
||||
/// Do not negate results *(Default)*
|
||||
pub const _SIDD_POSITIVE_POLARITY: i8 = 0b00000000;
|
||||
/// Negate results
|
||||
pub const _SIDD_NEGATIVE_POLARITY: i8 = 0b00010000;
|
||||
|
|
@ -31,14 +31,14 @@ pub const _SIDD_MASKED_POSITIVE_POLARITY: i8 = 0b00100000;
|
|||
/// Negate results only before the end of the string
|
||||
pub const _SIDD_MASKED_NEGATIVE_POLARITY: i8 = 0b00110000;
|
||||
|
||||
/// Index only: return the least significant bit
|
||||
/// **Index only**: return the least significant bit *(Default)*
|
||||
pub const _SIDD_LEAST_SIGNIFICANT: i8 = 0b00000000;
|
||||
/// Index only: return the most significant bit
|
||||
/// **Index only**: return the most significant bit
|
||||
pub const _SIDD_MOST_SIGNIFICANT: i8 = 0b01000000;
|
||||
|
||||
/// Mask only: return the bit mask
|
||||
/// **Mask only**: return the bit mask
|
||||
pub const _SIDD_BIT_MASK: i8 = 0b00000000;
|
||||
/// Mask only: return the byte mask
|
||||
/// **Mask only**: return the byte mask
|
||||
pub const _SIDD_UNIT_MASK: i8 = 0b01000000;
|
||||
|
||||
/// Compare packed strings with implicit lengths in `a` and `b` using the
|
||||
|
|
@ -59,6 +59,85 @@ pub unsafe fn _mm_cmpistrm(
|
|||
|
||||
/// Compare packed strings with implicit lengths in `a` and `b` using the
|
||||
/// control in `imm8`, and return the generated index.
|
||||
///
|
||||
/// # 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_cmpistri, _SIDD_CMP_EQUAL_ORDERED};
|
||||
///
|
||||
/// let haystack = b"This is a long string of text data\r\n\tthat extends multiple lines";
|
||||
/// let needle = b"\r\n\t\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
///
|
||||
/// let a = __m128i::from(u8x16::load(needle, 0));
|
||||
/// let hop = 16;
|
||||
/// let mut indexes = Vec::new();
|
||||
///
|
||||
/// // Chunk the haystack into 16 byte chunks and find
|
||||
/// // the first "\r\n\t" in the chunk.
|
||||
/// for (i, chunk) in haystack.chunks(hop).enumerate() {
|
||||
/// let b = __m128i::from(u8x16::load(chunk, 0));
|
||||
/// let idx = unsafe {
|
||||
/// _mm_cmpistri(a, b, _SIDD_CMP_EQUAL_ORDERED)
|
||||
/// };
|
||||
/// if idx != 16 {
|
||||
/// indexes.push((idx as usize) + (i * hop));
|
||||
/// }
|
||||
/// }
|
||||
/// assert_eq!(indexes, vec![34]);
|
||||
/// # }
|
||||
/// # 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
|
||||
#[inline(always)]
|
||||
#[target_feature = "+sse4.2"]
|
||||
#[cfg_attr(test, assert_instr(pcmpistri, imm8 = 0))]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue