rustc_target: RISC-V: Add two supervisor extensions for intrinsics by a4lg · Pull Request #147439 · rust-lang/rust (original) (raw)
This commit adds two ratified privileged RISC-V extensions corresponding to 35 existing intrinsics in core::arch::riscv{32,64}.
Because they semantically require the H and/or Svinval privileged extensions, we'd better to have those new target features to use them as a part of the #[target_feature(enable = ...)] attribute.
It also adds a note about a conflict between e and h (no code changes for now but should be rejected in the future).
Background
In stdarch, there are 35 unique intrinsics corresponding ratified instructions in core::arch::riscv{32,64} (35 in riscv64, 32 in riscv32) that require an ISA extension to work (note: the supervisor/machine architectures are not extensions so privileged intrinsics like wfi are excluded from the list).
In general, we require #[target_feature(enable = ...)] attribute to denote what target features are truly required but those 35 intrinsics didn't have that (there is one intentional exception: the pause HINT that behaves as a pause operation when the Zihintpause extension is implemented but otherwise executed as a no-op).
As you can see below, there are two missing extensions: H (hypervisor) and Svinval (efficient address-translation cache invalidation).
Required: Svinval
sinval_vmasinval_vma_vaddrsinval_vma_asidsinval_vma_allsfence_w_invalsfence_inval_ir
Required: H
hfence_vvmahfence_vvma_vaddrhfence_vvma_asidhfence_vvma_allhfence_gvmahfence_gvma_gaddrhfence_gvma_vmidhfence_gvma_allhlv_bhlv_hhlv_whlv_d(riscv64only)hlv_buhlv_huhlv_wu(riscv64only)hlvx_huhlvx_wuhsv_bhsv_hhsv_whsv_d(riscv64only)
Required: H + Svinval
Note that LLVM only requires the Svinval extension but the RISC-V documentation states that corresponding instructions are implemented only when the hypervisor extension (H) is enabled.
hinval_vvmahinval_vvma_vaddrhinval_vvma_asidhinval_vvma_allhinval_gvmahinval_gvma_gaddrhinval_gvma_vmidhinval_gvma_all
About this PR
There are multiple ways to make all implemented intrinsics more consistent:
- Remove those unstable intrinsics without
#[target_feature(enable = ...)]to focus on the user mode (note that there are only three architectures with privileged-only intrinsics:riscv{32,64}andarm).
To be honest, I personally don't like implement a new feature only because we can thing like those intrinsics but removing them seems to be... too extreme. - Add appropriate
#[target_feature(enable = ...)]to intrinsics above.
That requires adding two RISC-V target features:handsvinval(which I didn't want to do that but at least it makes intrinsics more consistent and safer).
This is a preparation for the option 2 (on the Rust compiler side) and adds two extensions as two target features: h (which implies zicsr) and svinval.
There is an additional change: describe why ILP32E and LP64E ABIs are not declared incompatible with the H extension (h target feature in this PR) due to this extension's special dependency: a base integer ISA with 32 general purpose registers.
That means, target features e (a virtual extension denoting a base integer ISA with 16 general purpose registers, not 32) and h are truly incompatible (and should be rejected later) but for ABIs, there's no reason to declare incompatibility (as e is not required by those ABIs).
Related
- RISC-V: Use symbolic instructions on inline assembly (part 1) stdarch#1927 (discussion behind submission of this PR)
- RISC-V: Use symbolic instructions on inline assembly (part 2) stdarch#1936 (the main body of option 2: draft PR for
stdarchto be applied once this PR is merged)
Cc: @folkertdev
r? @Amanieu
@rustbot label +O-riscv +A-target-feature