cranelift: Native feature detection for RISC-V (#5044)

* cranelift: Native feature detection for RISC-V

* cranelift: Typo fix

Thanks @cfallin
This commit is contained in:
Afonso Bordado
2022-10-11 20:29:03 +01:00
committed by GitHub
parent d68ca3711b
commit 86331b9b37
3 changed files with 54 additions and 27 deletions

View File

@@ -47,30 +47,6 @@ fn build_host_isa(
builder.finish(flags).unwrap()
}
fn is_riscv64_compatible(
host: target_lexicon::Riscv64Architecture,
req: target_lexicon::Riscv64Architecture,
) -> bool {
match host {
// Riscv64gc is short for RV64IMAFDCZicsr_Zifencei.
// So can run them all.
target_lexicon::Riscv64Architecture::Riscv64gc => true,
// Riscv64imac can run when req is not Riscv64gc.
target_lexicon::Riscv64Architecture::Riscv64imac
if req != target_lexicon::Riscv64Architecture::Riscv64gc =>
{
true
}
// Riscv64 is just basic extension.
target_lexicon::Riscv64Architecture::Riscv64
if req == target_lexicon::Riscv64Architecture::Riscv64 =>
{
true
}
_ => false,
}
}
/// Checks if the host's ISA is compatible with the one requested by the test.
fn is_isa_compatible(
file_path: &str,
@@ -85,8 +61,7 @@ fn is_isa_compatible(
match (host_arch, requested_arch) {
(host, requested) if host == requested => {}
(Architecture::Riscv64(host), Architecture::Riscv64(req))
if is_riscv64_compatible(host, req) => {}
(Architecture::Riscv64(_), Architecture::Riscv64(_)) => {}
_ => {
return Err(format!(
"skipped {}: host can't run {:?} programs",

View File

@@ -14,7 +14,7 @@ edition.workspace = true
cranelift-codegen = { workspace = true, default-features = false }
target-lexicon = { workspace = true }
[target.'cfg(target_arch = "s390x")'.dependencies]
[target.'cfg(any(target_arch = "s390x", target_arch = "riscv64"))'.dependencies]
libc = "0.2.95"
[features]

View File

@@ -165,6 +165,58 @@ pub fn builder_with_options(infer_native_flags: bool) -> Result<isa::Builder, &'
}
}
// `is_riscv_feature_detected` is nightly only for now, use
// getauxval from the libc crate directly as a temporary measure.
#[cfg(all(target_arch = "riscv64", target_os = "linux"))]
{
use cranelift_codegen::settings::Configurable;
if !infer_native_flags {
return Ok(isa_builder);
}
let v = unsafe { libc::getauxval(libc::AT_HWCAP) };
const HWCAP_RISCV_EXT_A: libc::c_ulong = 1 << (b'a' - b'a');
const HWCAP_RISCV_EXT_C: libc::c_ulong = 1 << (b'c' - b'a');
const HWCAP_RISCV_EXT_D: libc::c_ulong = 1 << (b'd' - b'a');
const HWCAP_RISCV_EXT_F: libc::c_ulong = 1 << (b'f' - b'a');
const HWCAP_RISCV_EXT_M: libc::c_ulong = 1 << (b'm' - b'a');
const HWCAP_RISCV_EXT_V: libc::c_ulong = 1 << (b'v' - b'a');
if (v & HWCAP_RISCV_EXT_A) != 0 {
isa_builder.enable("has_a").unwrap();
}
if (v & HWCAP_RISCV_EXT_C) != 0 {
isa_builder.enable("has_c").unwrap();
}
if (v & HWCAP_RISCV_EXT_D) != 0 {
isa_builder.enable("has_d").unwrap();
}
if (v & HWCAP_RISCV_EXT_F) != 0 {
isa_builder.enable("has_f").unwrap();
// TODO: There doesn't seem to be a bit associated with this extension
// rust enables it with the `f` extension:
// https://github.com/rust-lang/stdarch/blob/790411f93c4b5eada3c23abb4c9a063fb0b24d99/crates/std_detect/src/detect/os/linux/riscv.rs#L43
isa_builder.enable("has_zicsr").unwrap();
}
if (v & HWCAP_RISCV_EXT_M) != 0 {
isa_builder.enable("has_m").unwrap();
}
if (v & HWCAP_RISCV_EXT_V) != 0 {
isa_builder.enable("has_v").unwrap();
}
// TODO: ZiFencei does not have a bit associated with it
// TODO: Zbkb does not have a bit associated with it
}
// squelch warnings about unused mut/variables on some platforms.
drop(&mut isa_builder);
drop(infer_native_flags);