11use crate :: { Cmov , CmovEq , Condition } ;
22use core:: arch:: asm;
33
4+ /// Conditional select
45macro_rules! csel {
5- ( $csel: expr, $dst: expr, $src: expr, $condition: expr) => {
6+ ( $cmp : expr , $ csel: expr, $dst: expr, $src: expr, $condition: expr) => {
67 unsafe {
78 asm! {
89 "cmp {0:w}, 0" ,
@@ -17,13 +18,14 @@ macro_rules! csel {
1718 } ;
1819}
1920
20- macro_rules! csel_eq {
21- ( $instruction: expr, $lhs: expr, $rhs: expr, $condition: expr, $dst: expr) => {
21+ /// Conditional select-based equality test
22+ macro_rules! cseleq {
23+ ( $eor: expr, $cmp: expr, $instruction: expr, $lhs: expr, $rhs: expr, $condition: expr, $dst: expr) => {
2224 let mut tmp = * $dst as u16 ;
2325 unsafe {
2426 asm! {
25- " eor {0:w}, {1:w}, {2:w}" ,
26- " cmp {0:w}, 0" ,
27+ $ eor,
28+ $ cmp,
2729 $instruction,
2830 out( reg) _,
2931 in( reg) * $lhs,
@@ -39,74 +41,118 @@ macro_rules! csel_eq {
3941 } ;
4042}
4143
44+ /// Conditional select using 32-bit `:w` registers
45+ macro_rules! csel32 {
46+ ( $csel: expr, $dst: expr, $src: expr, $condition: expr) => {
47+ csel!( "cmp {0:w}, 0" , $csel, $dst, $src, $condition)
48+ } ;
49+ }
50+
51+ /// Conditional select using 64-bit `:x` registers
52+ macro_rules! csel64 {
53+ ( $csel: expr, $dst: expr, $src: expr, $condition: expr) => {
54+ csel!( "cmp {0:x}, 0" , $csel, $dst, $src, $condition)
55+ } ;
56+ }
57+
58+ /// Conditional select equality test using 32-bit `:w` registers
59+ macro_rules! cseleq32 {
60+ ( $instruction: expr, $lhs: expr, $rhs: expr, $condition: expr, $dst: expr) => {
61+ cseleq!(
62+ "eor {0:w}, {1:w}, {2:w}" ,
63+ "cmp {0:w}, 0" ,
64+ $instruction,
65+ $lhs,
66+ $rhs,
67+ $condition,
68+ $dst
69+ )
70+ } ;
71+ }
72+
73+ /// Conditional select equality test using 64-bit `:w` registers
74+ macro_rules! cseleq64 {
75+ ( $instruction: expr, $lhs: expr, $rhs: expr, $condition: expr, $dst: expr) => {
76+ cseleq!(
77+ "eor {0:x}, {1:x}, {2:x}" ,
78+ "cmp {0:x}, 0" ,
79+ $instruction,
80+ $lhs,
81+ $rhs,
82+ $condition,
83+ $dst
84+ )
85+ } ;
86+ }
87+
4288impl Cmov for u16 {
4389 #[ inline]
4490 fn cmovnz ( & mut self , value : & Self , condition : Condition ) {
45- csel ! ( "csel {1:w}, {2:w}, {3:w}, NE" , self , value, condition) ;
91+ csel32 ! ( "csel {1:w}, {2:w}, {3:w}, NE" , self , value, condition) ;
4692 }
4793
4894 #[ inline]
4995 fn cmovz ( & mut self , value : & Self , condition : Condition ) {
50- csel ! ( "csel {1:w}, {2:w}, {3:w}, EQ" , self , value, condition) ;
96+ csel32 ! ( "csel {1:w}, {2:w}, {3:w}, EQ" , self , value, condition) ;
5197 }
5298}
5399
54100impl CmovEq for u16 {
55101 #[ inline]
56102 fn cmovne ( & self , rhs : & Self , input : Condition , output : & mut Condition ) {
57- csel_eq ! ( "csel {3:w}, {4:w}, {5:w}, NE" , self , rhs, input, output) ;
103+ cseleq32 ! ( "csel {3:w}, {4:w}, {5:w}, NE" , self , rhs, input, output) ;
58104 }
59105
60106 #[ inline]
61107 fn cmoveq ( & self , rhs : & Self , input : Condition , output : & mut Condition ) {
62- csel_eq ! ( "csel {3:w}, {4:w}, {5:w}, EQ" , self , rhs, input, output) ;
108+ cseleq32 ! ( "csel {3:w}, {4:w}, {5:w}, EQ" , self , rhs, input, output) ;
63109 }
64110}
65111
66112impl Cmov for u32 {
67113 #[ inline]
68114 fn cmovnz ( & mut self , value : & Self , condition : Condition ) {
69- csel ! ( "csel {1:w}, {2:w}, {3:w}, NE" , self , value, condition) ;
115+ csel32 ! ( "csel {1:w}, {2:w}, {3:w}, NE" , self , value, condition) ;
70116 }
71117
72118 #[ inline]
73119 fn cmovz ( & mut self , value : & Self , condition : Condition ) {
74- csel ! ( "csel {1:w}, {2:w}, {3:w}, EQ" , self , value, condition) ;
120+ csel32 ! ( "csel {1:w}, {2:w}, {3:w}, EQ" , self , value, condition) ;
75121 }
76122}
77123
78124impl CmovEq for u32 {
79125 #[ inline]
80126 fn cmovne ( & self , rhs : & Self , input : Condition , output : & mut Condition ) {
81- csel_eq ! ( "csel {3:w}, {4:w}, {5:w}, NE" , self , rhs, input, output) ;
127+ cseleq32 ! ( "csel {3:w}, {4:w}, {5:w}, NE" , self , rhs, input, output) ;
82128 }
83129
84130 #[ inline]
85131 fn cmoveq ( & self , rhs : & Self , input : Condition , output : & mut Condition ) {
86- csel_eq ! ( "csel {3:w}, {4:w}, {5:w}, EQ" , self , rhs, input, output) ;
132+ cseleq32 ! ( "csel {3:w}, {4:w}, {5:w}, EQ" , self , rhs, input, output) ;
87133 }
88134}
89135
90136impl Cmov for u64 {
91137 #[ inline]
92138 fn cmovnz ( & mut self , value : & Self , condition : Condition ) {
93- csel ! ( "csel {1:x}, {2:x}, {3:x}, NE" , self , value, condition) ;
139+ csel64 ! ( "csel {1:x}, {2:x}, {3:x}, NE" , self , value, condition) ;
94140 }
95141
96142 #[ inline]
97143 fn cmovz ( & mut self , value : & Self , condition : Condition ) {
98- csel ! ( "csel {1:x}, {2:x}, {3:x}, EQ" , self , value, condition) ;
144+ csel64 ! ( "csel {1:x}, {2:x}, {3:x}, EQ" , self , value, condition) ;
99145 }
100146}
101147
102148impl CmovEq for u64 {
103149 #[ inline]
104150 fn cmovne ( & self , rhs : & Self , input : Condition , output : & mut Condition ) {
105- csel_eq ! ( "csel {3:w }, {4:w }, {5:w }, NE" , self , rhs, input, output) ;
151+ cseleq64 ! ( "csel {3:x }, {4:x }, {5:x }, NE" , self , rhs, input, output) ;
106152 }
107153
108154 #[ inline]
109155 fn cmoveq ( & self , rhs : & Self , input : Condition , output : & mut Condition ) {
110- csel_eq ! ( "csel {3:w }, {4:w }, {5:w }, EQ" , self , rhs, input, output) ;
156+ cseleq64 ! ( "csel {3:x }, {4:x }, {5:x }, EQ" , self , rhs, input, output) ;
111157 }
112158}
0 commit comments