diff --git a/readme.md b/readme.md index 523e3532e..7b86c12c6 100644 --- a/readme.md +++ b/readme.md @@ -91,6 +91,14 @@ there are correctness bugs open in the issue tracker. [**] it is currently not easily possible to run these platforms on CI. +# Machine code verification + +The +[`verify/`](https://github.com/rust-lang-nursery/packed_simd/tree/master/verify) +crate tests disassembles the portable packed vector APIs at run-time and +compares the generated machine code against the desired one to make sure that +this crate remains efficient. + # License This project is licensed under either of diff --git a/verify/readme.md b/verify/readme.md new file mode 100644 index 000000000..b3e6f5ed5 --- /dev/null +++ b/verify/readme.md @@ -0,0 +1,36 @@ +# Machine code verification + +This crates verifies the machine code generated for some of the portable packed +vector APIs by disassembling the API at run-time and comparing the machine code +generated against the desired one for a particular target and target features. + +This is done by using the +[`stdsimd-test`](https://github.com/rust-lang-nursery/stdsimd/tree/master/crates/stdsimd-test) +crate, which exposes the `assert_instr` procedural macro. It is used like this: + +```rust +// The verification functions must be #[inline]: +#[inline] +// Enable the target features required for the desired code generation +// on the different targets: +#[cfg_attr( + any(target_arch = "x86", target_arch = "x86_64"), + target_feature(enable = "avx512f,avx512vl") +)] +// Check that the disassembly contains a particular instruction: +#[cfg_attr( + any(target_arch = "x86", target_arch = "x86_64"), + assert_instr(vpro) +)] +unsafe fn rotate_right_variable(x: u64x8, v: u64x8) -> u64x8 { + x.rotate_right(v) +} +``` + +The `assert_instr` procedural macro creates a test that contains a +`#[inline(never)]` function that calls the API. It then gets a function pointer +to this function, and calls `stdsimd_test::assert` with it, the function name, +and the expected assembly instruction. `stdsimd_test` uses `objdump` or similar +to disassemble itself, it then looks for the function address and name in the +disassembly, and verifies that the machine code for the function contains the +instruction.