@@ -17,8 +17,22 @@ macro_rules! __can_detect {
1717#[ doc( hidden) ]
1818macro_rules! __detect {
1919 ( $( $tf: tt) ,+) => { {
20- let hwcaps = $crate:: loongarch64_linux:: getauxval_hwcap( ) ;
21- $( $crate:: check!( hwcaps, $tf) & ) + true
20+ let cpucfg1: usize ;
21+ let cpucfg2: usize ;
22+ let cpucfg3: usize ;
23+ unsafe {
24+ std:: arch:: asm!(
25+ "cpucfg {}, {}" ,
26+ "cpucfg {}, {}" ,
27+ "cpucfg {}, {}" ,
28+ out( reg) cpucfg1, in( reg) 1 ,
29+ out( reg) cpucfg2, in( reg) 2 ,
30+ out( reg) cpucfg3, in( reg) 3 ,
31+ options( pure, nomem, preserves_flags, nostack)
32+ ) ;
33+ }
34+ let hwcaps = $crate:: loongarch64:: getauxval_hwcap( ) ;
35+ $( $crate:: check!( cpucfg1, cpucfg2, cpucfg3, hwcaps, $tf) & ) + true
2236 } } ;
2337}
2438
@@ -27,37 +41,53 @@ pub fn getauxval_hwcap() -> u64 {
2741 unsafe { libc:: getauxval ( libc:: AT_HWCAP ) }
2842}
2943
30- // Linux `expand_check_macro`
31- macro_rules! __expand_check_macro {
32- ( $( ( $name: tt, $hwcap: ident) ) ,* $( , ) ?) => {
33- #[ macro_export]
34- #[ doc( hidden) ]
35- macro_rules! check {
36- $(
37- ( $hwcaps: expr, $name) => {
38- ( ( $hwcaps & $crate:: loongarch64_linux:: hwcaps:: $hwcap) != 0 )
39- } ;
40- ) *
41- }
44+ #[ macro_export]
45+ #[ doc( hidden) ]
46+ macro_rules! check {
47+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "32s" ) => {
48+ ( ( $cpucfg1 & 1 ) != 0 || ( $cpucfg1 & 2 ) != 0 )
49+ } ;
50+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "f" ) => {
51+ ( ( $cpucfg2 & 2 ) != 0 && ( $hwcaps & $crate:: loongarch64:: hwcaps:: FPU ) != 0 )
52+ } ;
53+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "d" ) => {
54+ ( ( $cpucfg2 & 4 ) != 0 && ( $hwcaps & $crate:: loongarch64:: hwcaps:: FPU ) != 0 )
55+ } ;
56+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "frecipe" ) => {
57+ ( ( $cpucfg2 & ( 1 << 25 ) ) != 0 )
58+ } ;
59+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "div32" ) => {
60+ ( ( $cpucfg2 & ( 1 << 26 ) ) != 0 )
61+ } ;
62+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "lsx" ) => {
63+ ( ( $hwcaps & $crate:: loongarch64:: hwcaps:: LSX ) != 0 )
64+ } ;
65+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "lasx" ) => {
66+ ( ( $hwcaps & $crate:: loongarch64:: hwcaps:: LASX ) != 0 )
67+ } ;
68+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "lam-bh" ) => {
69+ ( ( $cpucfg2 & ( 1 << 27 ) ) != 0 )
70+ } ;
71+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "lamcas" ) => {
72+ ( ( $cpucfg2 & ( 1 << 28 ) ) != 0 )
73+ } ;
74+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "ld-seq-sa" ) => {
75+ ( ( $cpucfg3 & ( 1 << 23 ) ) != 0 )
76+ } ;
77+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "scq" ) => {
78+ ( ( $cpucfg2 & ( 1 << 30 ) ) != 0 )
79+ } ;
80+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "lbt" ) => {
81+ ( ( $hwcaps & $crate:: loongarch64:: hwcaps:: LBT_X86 ) != 0
82+ && ( $hwcaps & $crate:: loongarch64:: hwcaps:: LBT_ARM ) != 0
83+ && ( $hwcaps & $crate:: loongarch64:: hwcaps:: LBT_MIPS ) != 0 )
84+ } ;
85+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "lvz" ) => {
86+ ( ( $hwcaps & $crate:: loongarch64:: hwcaps:: LVZ ) != 0 )
87+ } ;
88+ ( $cpucfg1: expr, $cpucfg2: expr, $cpucfg3: expr, $hwcaps: expr, "ual" ) => {
89+ ( ( $hwcaps & $crate:: loongarch64:: hwcaps:: UAL ) != 0 )
4290 } ;
43- }
44-
45- // Linux `expand_check_macro`
46- __expand_check_macro ! {
47- ( "cpucfg" , CPUCFG ) , // Enable CPUCFG support.
48- ( "lam" , LAM ) , // Enable LAM support.
49- ( "ual" , UAL ) , // Enable UAL support.
50- ( "fpu" , FPU ) , // Enable FPU support.
51- ( "lsx" , LSX ) , // Enable LSX support.
52- ( "lasx" , LASX ) , // Enable LASX support.
53- ( "crc32" , CRC32 ) , // Enable CRC32 support.
54- ( "complex" , COMPLEX ) , // Enable COMPLEX support.
55- ( "crypto" , CRYPTO ) , // Enable CRYPTO support.
56- ( "lvz" , LVZ ) , // Enable LVZ support.
57- ( "lbt.x86" , LBT_X86 ) , // Enable LBT_X86 support.
58- ( "lbt.arm" , LBT_ARM ) , // Enable LBT_ARM support.
59- ( "lbt.mips" , LBT_MIPS ) , // Enable LBT_MIPS support.
60- ( "ptw" , PTW ) , // Enable PTW support.
6191}
6292
6393/// Linux hardware capabilities mapped to target features.
@@ -68,18 +98,12 @@ __expand_check_macro! {
6898pub mod hwcaps {
6999 use libc:: c_ulong;
70100
71- pub const CPUCFG : c_ulong = libc:: HWCAP_LOONGARCH_CPUCFG ;
72- pub const LAM : c_ulong = libc:: HWCAP_LOONGARCH_LAM ;
73101 pub const UAL : c_ulong = libc:: HWCAP_LOONGARCH_UAL ;
74102 pub const FPU : c_ulong = libc:: HWCAP_LOONGARCH_FPU ;
75103 pub const LSX : c_ulong = libc:: HWCAP_LOONGARCH_LSX ;
76104 pub const LASX : c_ulong = libc:: HWCAP_LOONGARCH_LASX ;
77- pub const CRC32 : c_ulong = libc:: HWCAP_LOONGARCH_CRC32 ;
78- pub const COMPLEX : c_ulong = libc:: HWCAP_LOONGARCH_COMPLEX ;
79- pub const CRYPTO : c_ulong = libc:: HWCAP_LOONGARCH_CRYPTO ;
80105 pub const LVZ : c_ulong = libc:: HWCAP_LOONGARCH_LVZ ;
81106 pub const LBT_X86 : c_ulong = libc:: HWCAP_LOONGARCH_LBT_X86 ;
82107 pub const LBT_ARM : c_ulong = libc:: HWCAP_LOONGARCH_LBT_ARM ;
83108 pub const LBT_MIPS : c_ulong = libc:: HWCAP_LOONGARCH_LBT_MIPS ;
84- pub const PTW : c_ulong = libc:: HWCAP_LOONGARCH_PTW ;
85109}
0 commit comments