(isa_builder: &mut dyn Configurable)
| 3 | use std::io::{BufRead, BufReader}; |
| 4 | |
| 5 | pub fn hwcap_detect(isa_builder: &mut dyn Configurable) -> Result<(), &'static str> { |
| 6 | let v = unsafe { libc::getauxval(libc::AT_HWCAP) }; |
| 7 | |
| 8 | const HWCAP_RISCV_EXT_A: libc::c_ulong = 1 << (b'a' - b'a'); |
| 9 | const HWCAP_RISCV_EXT_C: libc::c_ulong = 1 << (b'c' - b'a'); |
| 10 | const HWCAP_RISCV_EXT_D: libc::c_ulong = 1 << (b'd' - b'a'); |
| 11 | const HWCAP_RISCV_EXT_F: libc::c_ulong = 1 << (b'f' - b'a'); |
| 12 | const HWCAP_RISCV_EXT_M: libc::c_ulong = 1 << (b'm' - b'a'); |
| 13 | const HWCAP_RISCV_EXT_V: libc::c_ulong = 1 << (b'v' - b'a'); |
| 14 | |
| 15 | if (v & HWCAP_RISCV_EXT_A) != 0 { |
| 16 | isa_builder.enable("has_a").unwrap(); |
| 17 | } |
| 18 | |
| 19 | if (v & HWCAP_RISCV_EXT_C) != 0 { |
| 20 | isa_builder.enable("has_c").unwrap(); |
| 21 | } |
| 22 | |
| 23 | if (v & HWCAP_RISCV_EXT_D) != 0 { |
| 24 | isa_builder.enable("has_d").unwrap(); |
| 25 | } |
| 26 | |
| 27 | if (v & HWCAP_RISCV_EXT_F) != 0 { |
| 28 | isa_builder.enable("has_f").unwrap(); |
| 29 | |
| 30 | // TODO: There doesn't seem to be a bit associated with this extension |
| 31 | // rust enables it with the `f` extension: |
| 32 | // https://github.com/rust-lang/stdarch/blob/790411f93c4b5eada3c23abb4c9a063fb0b24d99/crates/std_detect/src/detect/os/linux/riscv.rs#L43 |
| 33 | isa_builder.enable("has_zicsr").unwrap(); |
| 34 | } |
| 35 | |
| 36 | if (v & HWCAP_RISCV_EXT_M) != 0 { |
| 37 | isa_builder.enable("has_m").unwrap(); |
| 38 | } |
| 39 | |
| 40 | if (v & HWCAP_RISCV_EXT_V) != 0 { |
| 41 | isa_builder.enable("has_v").unwrap(); |
| 42 | } |
| 43 | |
| 44 | // In general extensions that are longer than one letter |
| 45 | // won't have a bit associated with them. The Linux kernel |
| 46 | // is currently working on a new way to query the extensions. |
| 47 | Ok(()) |
| 48 | } |
| 49 | |
| 50 | /// Read the /proc/cpuinfo file and detect the extensions. |
| 51 | /// |
no test coverage detected