diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 68ece92fbc9c0..e8970ea57e822 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -692,7 +692,14 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ }, &[], ), - ("m", Stable, &[]), + // According to the RISC-V spec, the M ISA extension (integer multiplication/division) is supported only when the M bit + // of the misa register is 1, while Zmmul means integer multiplication is always supported. + // + // The Rust/LLVM "m" target feature means something slightly different: with "m" enabled, it is assumed that integer + // multiplication and division will always be available (M bit will be 1 in misa), so "m" implies "zmmul". + // + // See discussion in the PR adding Zmmul: https://github.com/rust-lang/rust/pull/162552 + ("m", Stable, &["zmmul"]), ("relax", Unstable(sym::riscv_target_feature), &[]), ( "rva23u64", @@ -793,6 +800,7 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zksed", Stable, &[]), ("zksh", Stable, &[]), ("zkt", Stable, &[]), + ("zmmul", Unstable(sym::riscv_target_feature), &[]), ("ztso", Stable, &[]), ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]), // Zvbb ⊃ Zvkb ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]), diff --git a/library/std_detect/src/detect/arch/riscv.rs b/library/std_detect/src/detect/arch/riscv.rs index 0e6bab512ac15..9e8648823e7a3 100644 --- a/library/std_detect/src/detect/arch/riscv.rs +++ b/library/std_detect/src/detect/arch/riscv.rs @@ -104,6 +104,7 @@ features! { /// | `"zksed"` | Zksed | 6.8 | /// | `"zksh"` | Zksh | 6.8 | /// | `"zkt"` | Zkt | 6.8 | + /// | `"zmmul"` | Zmmul | No [^ima] [^dep] | /// | `"ztso"` | Ztso | 6.8 | /// | `"zvbb"` | Zvbb | 6.8 | /// | `"zvbc"` | Zvbc | 6.8 | @@ -220,6 +221,8 @@ features! { @FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] m: "m"; /// "M" Extension for Integer Multiplication and Division + @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zmmul: "zmmul"; + /// "Zmmul" Extension for Integer Multiplication @FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] a: "a"; /// "A" Extension for Atomic Instructions diff --git a/library/std_detect/src/detect/os/riscv.rs b/library/std_detect/src/detect/os/riscv.rs index 9b9e0cba09d1c..d4315f5cc1d87 100644 --- a/library/std_detect/src/detect/os/riscv.rs +++ b/library/std_detect/src/detect/os/riscv.rs @@ -147,6 +147,8 @@ pub(crate) fn imply_features(mut value: cache::Initializer) -> cache::Initialize imply!(zicntr | zihpm | f | zfinx | zve32x => zicsr); + imply!(m => zmmul); + // Loop until the feature flags converge. if prev == value { return value; diff --git a/library/std_detect/tests/cpu-detection.rs b/library/std_detect/tests/cpu-detection.rs index f0b276072108d..a381d84cfbbc3 100644 --- a/library/std_detect/tests/cpu-detection.rs +++ b/library/std_detect/tests/cpu-detection.rs @@ -243,6 +243,7 @@ fn riscv_linux() { println!("zicboz: {}", is_riscv_feature_detected!("zicboz")); println!("zicond: {}", is_riscv_feature_detected!("zicond")); println!("m: {}", is_riscv_feature_detected!("m")); + println!("zmmul: {}", is_riscv_feature_detected!("zmmul")); println!("a: {}", is_riscv_feature_detected!("a")); println!("zalrsc: {}", is_riscv_feature_detected!("zalrsc")); println!("zaamo: {}", is_riscv_feature_detected!("zaamo")); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs index 29a933f922630..7664d87cdee3e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs @@ -204,6 +204,7 @@ const TARGET_FEATURE_IMPLICATIONS_RAW: &[(&str, &[&str])] = &[ // RISC-V ("a", &["zaamo", "zalrsc"]), ("d", &["f"]), + ("m", &["zmmul"]), ("zabha", &["zaamo"]), ("zdinx", &["zfinx"]), ("zfh", &["zfhmin"]), diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index 0d9aad0e4a193..13c49fe00ef1f 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -479,6 +479,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `zksed` `zksh` `zkt` +`zmmul` `zreg` `ztso` `zvbb`