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:
@@ -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",
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user