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()
|
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.
|
/// Checks if the host's ISA is compatible with the one requested by the test.
|
||||||
fn is_isa_compatible(
|
fn is_isa_compatible(
|
||||||
file_path: &str,
|
file_path: &str,
|
||||||
@@ -85,8 +61,7 @@ fn is_isa_compatible(
|
|||||||
|
|
||||||
match (host_arch, requested_arch) {
|
match (host_arch, requested_arch) {
|
||||||
(host, requested) if host == requested => {}
|
(host, requested) if host == requested => {}
|
||||||
(Architecture::Riscv64(host), Architecture::Riscv64(req))
|
(Architecture::Riscv64(_), Architecture::Riscv64(_)) => {}
|
||||||
if is_riscv64_compatible(host, req) => {}
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"skipped {}: host can't run {:?} programs",
|
"skipped {}: host can't run {:?} programs",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ edition.workspace = true
|
|||||||
cranelift-codegen = { workspace = true, default-features = false }
|
cranelift-codegen = { workspace = true, default-features = false }
|
||||||
target-lexicon = { workspace = true }
|
target-lexicon = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "s390x")'.dependencies]
|
[target.'cfg(any(target_arch = "s390x", target_arch = "riscv64"))'.dependencies]
|
||||||
libc = "0.2.95"
|
libc = "0.2.95"
|
||||||
|
|
||||||
[features]
|
[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.
|
// squelch warnings about unused mut/variables on some platforms.
|
||||||
drop(&mut isa_builder);
|
drop(&mut isa_builder);
|
||||||
drop(infer_native_flags);
|
drop(infer_native_flags);
|
||||||
|
|||||||
Reference in New Issue
Block a user