@@ -53,14 +53,14 @@ impl Cmov for u32 {
5353impl CmovEq for u32 {
5454 #[ inline]
5555 fn cmovne ( & self , rhs : & Self , input : Condition , output : & mut Condition ) {
56- let ne = testnz32 ( self ^ rhs) as u8 ;
56+ let ne = testne32 ( * self , * rhs) ;
5757 output. cmovnz ( & input, ne) ;
5858 }
5959
6060 #[ inline]
6161 fn cmoveq ( & self , rhs : & Self , input : Condition , output : & mut Condition ) {
62- let ne = testnz32 ( self ^ rhs) as u8 ;
63- output. cmovnz ( & input, ne ^ 1 ) ;
62+ let eq = testeq32 ( * self , * rhs) ;
63+ output. cmovnz ( & input, eq ) ;
6464 }
6565}
6666
@@ -81,41 +81,105 @@ impl Cmov for u64 {
8181impl CmovEq for u64 {
8282 #[ inline]
8383 fn cmovne ( & self , rhs : & Self , input : Condition , output : & mut Condition ) {
84- let ne = testnz64 ( self ^ rhs) as u8 ;
84+ let ne = testne64 ( * self , * rhs) ;
8585 output. cmovnz ( & input, ne) ;
8686 }
8787
8888 #[ inline]
8989 fn cmoveq ( & self , rhs : & Self , input : Condition , output : & mut Condition ) {
90- let ne = testnz64 ( self ^ rhs) as u8 ;
91- output. cmovnz ( & input, ne ^ 1 ) ;
90+ let eq = testeq64 ( * self , * rhs) ;
91+ output. cmovnz ( & input, eq ) ;
9292 }
9393}
9494
95+ /// Returns `1` if `x` is equal to `y`, otherwise returns `0` (32-bit version)
96+ fn testeq32 ( x : u32 , y : u32 ) -> Condition {
97+ testne32 ( x, y) ^ 1
98+ }
99+
100+ /// Returns `1` if `x` is equal to `y`, otherwise returns `0` (64-bit version)
101+ fn testeq64 ( x : u64 , y : u64 ) -> Condition {
102+ testne64 ( x, y) ^ 1
103+ }
104+
105+ /// Returns `0` if `x` is equal to `y`, otherwise returns `1` (32-bit version)
106+ fn testne32 ( x : u32 , y : u32 ) -> Condition {
107+ testnz32 ( x ^ y) as Condition
108+ }
109+
110+ /// Returns `0` if `x` is equal to `y`, otherwise returns `1` (64-bit version)
111+ fn testne64 ( x : u64 , y : u64 ) -> Condition {
112+ testnz64 ( x ^ y) as Condition
113+ }
114+
95115/// Returns `0` if `x` is `0`, otherwise returns `1` (32-bit version)
96- pub fn testnz32 ( mut x : u32 ) -> u32 {
97- x |= x. wrapping_neg ( ) ;
98- core:: hint:: black_box ( x >> ( u32:: BITS - 1 ) )
116+ fn testnz32 ( mut x : u32 ) -> u32 {
117+ x |= x. wrapping_neg ( ) ; // MSB now set if non-zero
118+ core:: hint:: black_box ( x >> ( u32:: BITS - 1 ) ) // Extract MSB
99119}
100120
101121/// Returns `0` if `x` is `0`, otherwise returns `1` (64-bit version)
102- pub fn testnz64 ( mut x : u64 ) -> u64 {
103- x |= x. wrapping_neg ( ) ;
104- core:: hint:: black_box ( x >> ( u64:: BITS - 1 ) )
122+ fn testnz64 ( mut x : u64 ) -> u64 {
123+ x |= x. wrapping_neg ( ) ; // MSB now set if non-zero
124+ core:: hint:: black_box ( x >> ( u64:: BITS - 1 ) ) // Extract MSB
105125}
106126
107127/// Return a [`u32::MAX`] mask if `condition` is non-zero, otherwise return zero for a zero input.
108- pub fn masknz32 ( condition : Condition ) -> u32 {
128+ fn masknz32 ( condition : Condition ) -> u32 {
109129 testnz32 ( condition as u32 ) . wrapping_neg ( )
110130}
111131
112132/// Return a [`u64::MAX`] mask if `condition` is non-zero, otherwise return zero for a zero input.
113- pub fn masknz64 ( condition : Condition ) -> u64 {
133+ fn masknz64 ( condition : Condition ) -> u64 {
114134 testnz64 ( condition as u64 ) . wrapping_neg ( )
115135}
116136
117137#[ cfg( test) ]
118138mod tests {
139+ #[ test]
140+ fn testeq32 ( ) {
141+ assert_eq ! ( super :: testeq32( 0 , 0 ) , 1 ) ;
142+ assert_eq ! ( super :: testeq32( 1 , 0 ) , 0 ) ;
143+ assert_eq ! ( super :: testeq32( 0 , 1 ) , 0 ) ;
144+ assert_eq ! ( super :: testeq32( 1 , 1 ) , 1 ) ;
145+ assert_eq ! ( super :: testeq32( u32 :: MAX , 1 ) , 0 ) ;
146+ assert_eq ! ( super :: testeq32( 1 , u32 :: MAX ) , 0 ) ;
147+ assert_eq ! ( super :: testeq32( u32 :: MAX , u32 :: MAX ) , 1 ) ;
148+ }
149+
150+ #[ test]
151+ fn testeq64 ( ) {
152+ assert_eq ! ( super :: testeq64( 0 , 0 ) , 1 ) ;
153+ assert_eq ! ( super :: testeq64( 1 , 0 ) , 0 ) ;
154+ assert_eq ! ( super :: testeq64( 0 , 1 ) , 0 ) ;
155+ assert_eq ! ( super :: testeq64( 1 , 1 ) , 1 ) ;
156+ assert_eq ! ( super :: testeq64( u64 :: MAX , 1 ) , 0 ) ;
157+ assert_eq ! ( super :: testeq64( 1 , u64 :: MAX ) , 0 ) ;
158+ assert_eq ! ( super :: testeq64( u64 :: MAX , u64 :: MAX ) , 1 ) ;
159+ }
160+
161+ #[ test]
162+ fn testne32 ( ) {
163+ assert_eq ! ( super :: testne32( 0 , 0 ) , 0 ) ;
164+ assert_eq ! ( super :: testne32( 1 , 0 ) , 1 ) ;
165+ assert_eq ! ( super :: testne32( 0 , 1 ) , 1 ) ;
166+ assert_eq ! ( super :: testne32( 1 , 1 ) , 0 ) ;
167+ assert_eq ! ( super :: testne32( u32 :: MAX , 1 ) , 1 ) ;
168+ assert_eq ! ( super :: testne32( 1 , u32 :: MAX ) , 1 ) ;
169+ assert_eq ! ( super :: testne32( u32 :: MAX , u32 :: MAX ) , 0 ) ;
170+ }
171+
172+ #[ test]
173+ fn testne64 ( ) {
174+ assert_eq ! ( super :: testne64( 0 , 0 ) , 0 ) ;
175+ assert_eq ! ( super :: testne64( 1 , 0 ) , 1 ) ;
176+ assert_eq ! ( super :: testne64( 0 , 1 ) , 1 ) ;
177+ assert_eq ! ( super :: testne64( 1 , 1 ) , 0 ) ;
178+ assert_eq ! ( super :: testne64( u64 :: MAX , 1 ) , 1 ) ;
179+ assert_eq ! ( super :: testne64( 1 , u64 :: MAX ) , 1 ) ;
180+ assert_eq ! ( super :: testne64( u64 :: MAX , u64 :: MAX ) , 0 ) ;
181+ }
182+
119183 #[ test]
120184 fn testnz32 ( ) {
121185 assert_eq ! ( super :: testnz32( 0 ) , 0 ) ;
0 commit comments