Skip to content

Commit 3f4220b

Browse files
authored
cpufeatures: Align LoongArch features with libstd (#1206)
1 parent 87b916e commit 3f4220b

File tree

3 files changed

+87
-51
lines changed

3 files changed

+87
-51
lines changed

cpufeatures/README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,20 @@ Linux only (LoongArch64 does not support OS-independent feature detection)
7777

7878
Target features:
7979

80-
- `lam`*
81-
- `ual`*
82-
- `fpu`*
80+
- `32s`*
81+
- `f`*
82+
- `d`*
83+
- `frecipe`*
84+
- `div32`*
8385
- `lsx`*
8486
- `lasx`*
85-
- `crc32`*
86-
- `complex`*
87-
- `crypto`*
87+
- `lam-bh`*
88+
- `lamcas`*
89+
- `ld-seq-sa`*
90+
- `scq`*
91+
- `lbt`*
8892
- `lvz`*
89-
- `lbt.x86`*
90-
- `lbt.arm`*
91-
- `lbt.mips`*
92-
- `ptw`*
93+
- `ual`*
9394

9495
### `x86`/`x86_64`
9596

cpufeatures/src/loongarch64.rs

Lines changed: 61 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,22 @@ macro_rules! __unless_target_features {
2424
#[doc(hidden)]
2525
macro_rules! __detect_target_features {
2626
($($tf:tt),+) => {{
27+
let cpucfg1: usize;
28+
let cpucfg2: usize;
29+
let cpucfg3: usize;
30+
unsafe {
31+
std::arch::asm!(
32+
"cpucfg {}, {}",
33+
"cpucfg {}, {}",
34+
"cpucfg {}, {}",
35+
out(reg) cpucfg1, in(reg) 1,
36+
out(reg) cpucfg2, in(reg) 2,
37+
out(reg) cpucfg3, in(reg) 3,
38+
options(pure, nomem, preserves_flags, nostack)
39+
);
40+
}
2741
let hwcaps = $crate::loongarch64::getauxval_hwcap();
28-
$($crate::check!(hwcaps, $tf) & )+ true
42+
$($crate::check!(cpucfg1, cpucfg2, cpucfg3, hwcaps, $tf) & )+ true
2943
}};
3044
}
3145

@@ -35,39 +49,53 @@ pub fn getauxval_hwcap() -> u64 {
3549
unsafe { libc::getauxval(libc::AT_HWCAP) }
3650
}
3751

38-
// Linux `expand_check_macro`
39-
#[cfg(target_os = "linux")]
40-
macro_rules! __expand_check_macro {
41-
($(($name:tt, $hwcap:ident)),* $(,)?) => {
42-
#[macro_export]
43-
#[doc(hidden)]
44-
macro_rules! check {
45-
$(
46-
($hwcaps:expr, $name) => {
47-
(($hwcaps & $crate::loongarch64::hwcaps::$hwcap) != 0)
48-
};
49-
)*
50-
}
52+
#[macro_export]
53+
#[doc(hidden)]
54+
macro_rules! check {
55+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "32s") => {
56+
(($cpucfg1 & 1) != 0 || ($cpucfg1 & 2) != 0)
57+
};
58+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "f") => {
59+
(($cpucfg2 & 2) != 0 && ($hwcaps & $crate::loongarch64::hwcaps::FPU) != 0)
60+
};
61+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "d") => {
62+
(($cpucfg2 & 4) != 0 && ($hwcaps & $crate::loongarch64::hwcaps::FPU) != 0)
63+
};
64+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "frecipe") => {
65+
(($cpucfg2 & (1 << 25)) != 0)
66+
};
67+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "div32") => {
68+
(($cpucfg2 & (1 << 26)) != 0)
69+
};
70+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "lsx") => {
71+
(($hwcaps & $crate::loongarch64::hwcaps::LSX) != 0)
72+
};
73+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "lasx") => {
74+
(($hwcaps & $crate::loongarch64::hwcaps::LASX) != 0)
75+
};
76+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "lam-bh") => {
77+
(($cpucfg2 & (1 << 27)) != 0)
78+
};
79+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "lamcas") => {
80+
(($cpucfg2 & (1 << 28)) != 0)
81+
};
82+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "ld-seq-sa") => {
83+
(($cpucfg3 & (1 << 23)) != 0)
84+
};
85+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "scq") => {
86+
(($cpucfg2 & (1 << 30)) != 0)
87+
};
88+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "lbt") => {
89+
(($hwcaps & $crate::loongarch64::hwcaps::LBT_X86) != 0
90+
&& ($hwcaps & $crate::loongarch64::hwcaps::LBT_ARM) != 0
91+
&& ($hwcaps & $crate::loongarch64::hwcaps::LBT_MIPS) != 0)
92+
};
93+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "lvz") => {
94+
(($hwcaps & $crate::loongarch64::hwcaps::LVZ) != 0)
95+
};
96+
($cpucfg1:expr, $cpucfg2:expr, $cpucfg3:expr, $hwcaps:expr, "ual") => {
97+
(($hwcaps & $crate::loongarch64::hwcaps::UAL) != 0)
5198
};
52-
}
53-
54-
// Linux `expand_check_macro`
55-
#[cfg(target_os = "linux")]
56-
__expand_check_macro! {
57-
("cpucfg", CPUCFG), // Enable CPUCFG support.
58-
("lam", LAM), // Enable LAM support.
59-
("ual", UAL), // Enable UAL support.
60-
("fpu", FPU), // Enable FPU support.
61-
("lsx", LSX), // Enable LSX support.
62-
("lasx", LASX), // Enable LASX support.
63-
("crc32", CRC32), // Enable CRC32 support.
64-
("complex", COMPLEX), // Enable COMPLEX support.
65-
("crypto", CRYPTO), // Enable CRYPTO support.
66-
("lvz", LVZ), // Enable LVZ support.
67-
("lbt.x86", LBT_X86), // Enable LBT_X86 support.
68-
("lbt.arm", LBT_ARM), // Enable LBT_ARM support.
69-
("lbt.mips", LBT_MIPS), // Enable LBT_MIPS support.
70-
("ptw", PTW), // Enable PTW support.
7199
}
72100

73101
/// Linux hardware capabilities mapped to target features.
@@ -79,20 +107,14 @@ __expand_check_macro! {
79107
pub mod hwcaps {
80108
use libc::c_ulong;
81109

82-
pub const CPUCFG: c_ulong = libc::HWCAP_LOONGARCH_CPUCFG;
83-
pub const LAM: c_ulong = libc::HWCAP_LOONGARCH_LAM;
84110
pub const UAL: c_ulong = libc::HWCAP_LOONGARCH_UAL;
85111
pub const FPU: c_ulong = libc::HWCAP_LOONGARCH_FPU;
86112
pub const LSX: c_ulong = libc::HWCAP_LOONGARCH_LSX;
87113
pub const LASX: c_ulong = libc::HWCAP_LOONGARCH_LASX;
88-
pub const CRC32: c_ulong = libc::HWCAP_LOONGARCH_CRC32;
89-
pub const COMPLEX: c_ulong = libc::HWCAP_LOONGARCH_COMPLEX;
90-
pub const CRYPTO: c_ulong = libc::HWCAP_LOONGARCH_CRYPTO;
91114
pub const LVZ: c_ulong = libc::HWCAP_LOONGARCH_LVZ;
92115
pub const LBT_X86: c_ulong = libc::HWCAP_LOONGARCH_LBT_X86;
93116
pub const LBT_ARM: c_ulong = libc::HWCAP_LOONGARCH_LBT_ARM;
94117
pub const LBT_MIPS: c_ulong = libc::HWCAP_LOONGARCH_LBT_MIPS;
95-
pub const PTW: c_ulong = libc::HWCAP_LOONGARCH_PTW;
96118
}
97119

98120
// On other targets, runtime CPU feature detection is unavailable

cpufeatures/tests/loongarch64.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,21 @@
33
#![cfg(target_arch = "loongarch64")]
44

55
cpufeatures::new!(
6-
lacaps, "cpucfg", "lam", "ual", "fpu", "lsx", "lasx", "crc32", "complex", "crypto", "lvz",
7-
"lbt.x86", "lbt.arm", "lbt.mips", "ptw"
6+
lacaps,
7+
"32s",
8+
"f",
9+
"d",
10+
"frecipe",
11+
"div32",
12+
"lsx",
13+
"lasx",
14+
"lam-bh",
15+
"lamcas",
16+
"ld-seq-sa",
17+
"scq",
18+
"lbt",
19+
"lvz",
20+
"ual"
821
);
922

1023
#[test]

0 commit comments

Comments
 (0)