@@ -24,8 +24,22 @@ macro_rules! __unless_target_features {
2424#[ doc( hidden) ]
2525macro_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! {
79107pub 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
0 commit comments