| 66b4bf32 | 06-Aug-2025 |
Andrew Brown <[email protected]> |
x64: handle ISA features more completely (#11272)
* asm: generate boolean terms of CPU features
As discussed [here], we will soon need the ability to express more complex combinations of CPU featur
x64: handle ISA features more completely (#11272)
* asm: generate boolean terms of CPU features
As discussed [here], we will soon need the ability to express more complex combinations of CPU features. These are best expressed as boolean terms: e.g., `(32-bit OR 64-bit) AND ...`, `(32-bit OR 64-bit) AND ((AVX512VL AND AVX512F) OR AVX10.1)`. This change modifies the generated code to have a `Inst::is_available` method which contains a Rust-ified version of the instruction's boolean term. To do this, we now pass in a `Features` trait, which the instruction can query to see if its desired feature set is available.
[here]: https://bytecodealliance.zulipchat.com/#narrow/channel/217117-cranelift/topic/boolean.20terms.20for.20x64.20features
* x64: wire up `Inst::is_available` in Cranelift
This change makes us of the assembler's new generated `Inst::is_available` methods to check an instruction's feature set in a more succinct (and likely quicker) way. Unfortunately, this does not allow us to print the missing ISA requirements on failure--something to address later.
* Rename `Features` to `AvailableFeatures`
* Remove unused `InstructionSet`
* asm: fix all feature definitions
This is a mechanical transformation converting all instruction definitions. Now, instructions should have a correct boolean term describe the features required: e.g., `(_64b | compat) & avx`.
* x64: replace `use_*` with `has_*` when checking ISA features
In Cranelift, the `has_*` flags of `isa::x64::settings::Flags` indicate that the CPU _has_ some capability; the `use_*` flags indicate that Cranelift _should emit_ instructions using those capabilities. Further, the `use_*` flags may turned on by the presence of more than one `has_*` flags; e.g., when `has_avx` and `has_avx2` are available, `use_avx2` is enabled.
Now that Cranelift's new x64 assembler understands boolean terms, we no longer need the `use_*` flags for checking if an instruction can be emitted: instead, we should use the `has_*` flags and rely on the logic encoded in `Inst::is_available`.
* asm: materialize `Features` via `Inst::features`
For better error messages (and just for general use of CPU features, see discussion [here]), this change adds `Inst::features`--a way to explicitly examine the boolean term for an instruction. This function returns a `&'static Features` that contains the `AND` and `OR` branches defining when an instruction is available. This is all generated into something that looks like:
```rust pub fn features(&self) -> &'static Features { const F1: &'static Features = &Features::Feature(Feature::_64b); const F2: &'static Features = &Features::Feature(Feature::compat); const F0: &'static Features = &Features::Or(F1, F2); F0 } ```
This change makes use of `for_each_feature` more: we build up the `AvailableFeatures` trait and the `Feature` enum from it. This should be a bit more direct than searching through the generated code (?).
[here]: https://github.com/bytecodealliance/wasmtime/pull/11272#discussion_r2214465871
show more ...
|