Skip to content

Commit e811963

Browse files
dlrobertsonalexcrichton
authored andcommitted
[Docs] Improve documentation (rust-lang#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
1 parent 3a8bf80 commit e811963

File tree

3 files changed

+169
-14
lines changed

3 files changed

+169
-14
lines changed

CONTRIBUTING.md

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,57 @@ particularly use some help. You may be most interested in [#40][vendor],
2424
implementing all vendor intrinsics on x86. That issue's got some good pointers
2525
about where to get started!
2626

27+
If you've got general questions feel free to [join us on gitter][gitter] and ask
28+
around! Feel free to ping either @BurntSushi or @alexcrichton with questions.
29+
30+
[gitter]: https://gitter.im/rust-impl-period/WG-libs-simd
31+
32+
# How to write examples for stdsimd intrinsics
33+
34+
There are a few features that must be enabled for the given intrinsic to work
35+
properly and the example must only be run by `cargo test --doc` when the feature
36+
is supported by the CPU. As a result, the default `fn main` that is generated by
37+
`rustdoc` will not work (in most cases). Consider using the following as a guide
38+
to ensure your example works as expected.
39+
40+
```rust
41+
/// # // We need cfg_target_feature to ensure the example is only
42+
/// # // run by `cargo test --doc` when the CPU supports the feature
43+
/// # #![feature(cfg_target_feature)]
44+
/// # // We need target_feature for the intrinsic to work
45+
/// # #![feature(target_feature)]
46+
/// #
47+
/// # // rustdoc by default uses `extern crate stdsimd`, but we need the
48+
/// # // `#[macro_use]`
49+
/// # #[macro_use] extern crate stdsimd;
50+
/// #
51+
/// # // The real main function
52+
/// # fn main() {
53+
/// # // Only run this if `<target feature>` is supported
54+
/// # if cfg_feature_enabled!("<target feature>") {
55+
/// # // Create a `worker` function that will only be run if the target feature
56+
/// # // is supported and ensure that `target_feature` is enabled for your worker
57+
/// # // function
58+
/// # #[target_feature = "+<target feature>"]
59+
/// # fn worker() {
60+
///
61+
/// // Write your example here. Feature specific intrinsics will work here! Go wild!
62+
///
63+
/// # }
64+
/// # worker();
65+
/// # }
66+
/// # }
67+
```
68+
69+
If some of the above syntax does not look familiar, the [Documentation as tests] section
70+
of the [Rust Book] describes the `rustdoc` syntax quite well. As always, feel free
71+
to [join us on gitter][gitter] and ask us if you hit any snags, and thank you for helping
72+
to improve the documentation of `stdsimd`!
73+
2774
[new]: https://github.com/rust-lang-nursery/stdsimd/issues/new
2875
[issues]: https://github.com/rust-lang-nursery/stdsimd/issues
2976
[help]: https://github.com/rust-lang-nursery/stdsimd/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22
3077
[impl]: https://github.com/rust-lang-nursery/stdsimd/issues?q=is%3Aissue+is%3Aopen+label%3Aimpl-period
3178
[vendor]: https://github.com/rust-lang-nursery/stdsimd/issues/40
32-
33-
If you've got general questions feel free to [join us on gitter][gitter] and ask
34-
around! Feel free to ping either @BurntSushi or @alexcrichton with questions.
35-
36-
[gitter]: https://gitter.im/rust-impl-period/WG-libs-simd
79+
[Documentation as tests]: https://doc.rust-lang.org/book/first-edition/documentation.html#documentation-as-tests
80+
[Rust Book]: https://doc.rust-lang.org/book/first-edition

src/lib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,38 @@
6363
//! }
6464
//! ```
6565
//!
66+
//! After verifying that a specified feature is available, use `target_feature`
67+
//! to enable a given feature and use the desired intrinsic.
68+
//!
69+
//! ```
70+
//! #![feature(cfg_target_feature)]
71+
//! #![feature(target_feature)]
72+
//!
73+
//! #[macro_use]
74+
//! extern crate stdsimd;
75+
//!
76+
//! fn main() {
77+
//! if cfg_feature_enabled!("avx2") {
78+
//!
79+
//! // avx2 will work. It is safe to use avx2 specific code here.
80+
//! #[target_feature = "+avx2"]
81+
//! fn and_256() {
82+
//! // avx2 feature specific intrinsics will work here!
83+
//! use stdsimd::vendor::{__m256i, _mm256_and_si256};
84+
//!
85+
//! let a = __m256i::splat(5);
86+
//! let b = __m256i::splat(3);
87+
//! let got = unsafe { _mm256_and_si256(a, b) };
88+
//! assert_eq!(got, __m256i::splat(1));
89+
//! }
90+
//!
91+
//! and_256();
92+
//! } else {
93+
//! println!("avx2 intrinsics will not work, they may generate SIGILL");
94+
//! }
95+
//! }
96+
//! ```
97+
//!
6698
//! # Status
6799
//!
68100
//! This crate is intended for eventual inclusion into the standard library, but

src/x86/sse42.rs

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use stdsimd_test::assert_instr;
44
use v128::*;
55
use x86::__m128i;
66

7-
/// String contains unsigned 8-bit characters
7+
/// String contains unsigned 8-bit characters *(Default)*
88
pub const _SIDD_UBYTE_OPS: i8 = 0b00000000;
99
/// String contains unsigned 16-bit characters
1010
pub const _SIDD_UWORD_OPS: i8 = 0b00000001;
@@ -13,16 +13,16 @@ pub const _SIDD_SBYTE_OPS: i8 = 0b00000010;
1313
/// String contains unsigned 16-bit characters
1414
pub const _SIDD_SWORD_OPS: i8 = 0b00000011;
1515

16-
/// For each character in `a`, find if it is in `b`
16+
/// For each character in `a`, find if it is in `b` *(Default)*
1717
pub const _SIDD_CMP_EQUAL_ANY: i8 = 0b00000000;
1818
/// For each character in `a`, determine if `b[0] <= c <= b[1] or b[1] <= c <= b[2]...`
1919
pub const _SIDD_CMP_RANGES: i8 = 0b00000100;
20-
/// String equality
20+
/// The strings defined by `a` and `b` are equal
2121
pub const _SIDD_CMP_EQUAL_EACH: i8 = 0b00001000;
22-
/// Substring search
22+
/// Search for the defined substring in the target
2323
pub const _SIDD_CMP_EQUAL_ORDERED: i8 = 0b00001100;
2424

25-
/// Do not negate results
25+
/// Do not negate results *(Default)*
2626
pub const _SIDD_POSITIVE_POLARITY: i8 = 0b00000000;
2727
/// Negate results
2828
pub const _SIDD_NEGATIVE_POLARITY: i8 = 0b00010000;
@@ -31,14 +31,14 @@ pub const _SIDD_MASKED_POSITIVE_POLARITY: i8 = 0b00100000;
3131
/// Negate results only before the end of the string
3232
pub const _SIDD_MASKED_NEGATIVE_POLARITY: i8 = 0b00110000;
3333

34-
/// Index only: return the least significant bit
34+
/// **Index only**: return the least significant bit *(Default)*
3535
pub const _SIDD_LEAST_SIGNIFICANT: i8 = 0b00000000;
36-
/// Index only: return the most significant bit
36+
/// **Index only**: return the most significant bit
3737
pub const _SIDD_MOST_SIGNIFICANT: i8 = 0b01000000;
3838

39-
/// Mask only: return the bit mask
39+
/// **Mask only**: return the bit mask
4040
pub const _SIDD_BIT_MASK: i8 = 0b00000000;
41-
/// Mask only: return the byte mask
41+
/// **Mask only**: return the byte mask
4242
pub const _SIDD_UNIT_MASK: i8 = 0b01000000;
4343

4444
/// Compare packed strings with implicit lengths in `a` and `b` using the
@@ -59,6 +59,85 @@ pub unsafe fn _mm_cmpistrm(
5959

6060
/// Compare packed strings with implicit lengths in `a` and `b` using the
6161
/// control in `imm8`, and return the generated index.
62+
///
63+
/// # Control modes
64+
///
65+
/// The control specified by `imm8` may be one or more of the following.
66+
///
67+
/// ## Data size and signedness
68+
///
69+
/// - [`_SIDD_UBYTE_OPS`] - Default
70+
/// - [`_SIDD_UWORD_OPS`]
71+
/// - [`_SIDD_SBYTE_OPS`]
72+
/// - [`_SIDD_SWORD_OPS`]
73+
///
74+
/// ## Comparison options
75+
/// - [`_SIDD_CMP_EQUAL_ANY`] - Default
76+
/// - [`_SIDD_CMP_RANGES`]
77+
/// - [`_SIDD_CMP_EQUAL_EACH`]
78+
/// - [`_SIDD_CMP_EQUAL_ORDERED`]
79+
///
80+
/// ## Result polarity
81+
/// - [`_SIDD_POSITIVE_POLARITY`] - Default
82+
/// - [`_SIDD_NEGATIVE_POLARITY`]
83+
///
84+
/// ## Bit returned
85+
/// - [`_SIDD_LEAST_SIGNIFICANT`] - Default
86+
/// - [`_SIDD_MOST_SIGNIFICANT`]
87+
///
88+
/// # Examples
89+
///
90+
/// ```
91+
/// # #![feature(cfg_target_feature)]
92+
/// # #![feature(target_feature)]
93+
/// #
94+
/// # #[macro_use] extern crate stdsimd;
95+
/// #
96+
/// # fn main() {
97+
/// # if cfg_feature_enabled!("sse4.2") {
98+
/// # #[target_feature = "+sse4.2"]
99+
/// # fn worker() {
100+
///
101+
/// use stdsimd::simd::u8x16;
102+
/// use stdsimd::vendor::{__m128i, _mm_cmpistri, _SIDD_CMP_EQUAL_ORDERED};
103+
///
104+
/// let haystack = b"This is a long string of text data\r\n\tthat extends multiple lines";
105+
/// let needle = b"\r\n\t\0\0\0\0\0\0\0\0\0\0\0\0\0";
106+
///
107+
/// let a = __m128i::from(u8x16::load(needle, 0));
108+
/// let hop = 16;
109+
/// let mut indexes = Vec::new();
110+
///
111+
/// // Chunk the haystack into 16 byte chunks and find
112+
/// // the first "\r\n\t" in the chunk.
113+
/// for (i, chunk) in haystack.chunks(hop).enumerate() {
114+
/// let b = __m128i::from(u8x16::load(chunk, 0));
115+
/// let idx = unsafe {
116+
/// _mm_cmpistri(a, b, _SIDD_CMP_EQUAL_ORDERED)
117+
/// };
118+
/// if idx != 16 {
119+
/// indexes.push((idx as usize) + (i * hop));
120+
/// }
121+
/// }
122+
/// assert_eq!(indexes, vec![34]);
123+
/// # }
124+
/// # worker();
125+
/// # }
126+
/// # }
127+
/// ```
128+
///
129+
/// [`_SIDD_UBYTE_OPS`]: constant._SIDD_UBYTE_OPS.html
130+
/// [`_SIDD_UWORD_OPS`]: constant._SIDD_UWORD_OPS.html
131+
/// [`_SIDD_SBYTE_OPS`]: constant._SIDD_SBYTE_OPS.html
132+
/// [`_SIDD_SWORD_OPS`]: constant._SIDD_SWORD_OPS.html
133+
/// [`_SIDD_CMP_EQUAL_ANY`]: constant._SIDD_CMP_EQUAL_ANY.html
134+
/// [`_SIDD_CMP_RANGES`]: constant._SIDD_CMP_RANGES.html
135+
/// [`_SIDD_CMP_EQUAL_EACH`]: constant._SIDD_CMP_EQUAL_EACH.html
136+
/// [`_SIDD_CMP_EQUAL_ORDERED`]: constant._SIDD_CMP_EQUAL_ORDERED.html
137+
/// [`_SIDD_POSITIVE_POLARITY`]: constant._SIDD_POSITIVE_POLARITY.html
138+
/// [`_SIDD_NEGATIVE_POLARITY`]: constant._SIDD_NEGATIVE_POLARITY.html
139+
/// [`_SIDD_LEAST_SIGNIFICANT`]: constant._SIDD_LEAST_SIGNIFICANT.html
140+
/// [`_SIDD_MOST_SIGNIFICANT`]: constant._SIDD_MOST_SIGNIFICANT.html
62141
#[inline(always)]
63142
#[target_feature = "+sse4.2"]
64143
#[cfg_attr(test, assert_instr(pcmpistri, imm8 = 0))]

0 commit comments

Comments
 (0)