66) ] 
77#![ warn( missing_docs,  rust_2018_idioms,  unused_qualifications) ]  
88
9- #[ cfg( any( target_arch = "x86" ,  target_arch = "x86_64" ) ) ]  
9+ #[ cfg( any( target_arch = "x86" ,  target_arch = "x86_64" ,  target_arch =  "aarch64" ) ) ]  
1010use  core:: arch:: asm; 
1111
1212/// Move if zero. 
@@ -28,6 +28,46 @@ pub fn cmovz(condition: usize, src: usize, dst: &mut usize) {
2828    } 
2929} 
3030
31+ /// Move if zero. 
32+ /// 
33+ /// Uses a `cmp` instruction to check if the given `condition` value is 
34+ /// equal to zero, then calls `csel` to conditionally move 
35+ /// `src` to `dst` when `condition` is equal to zero. 
36+ #[ cfg( any( target_arch = "aarch64" ) ) ]  
37+ #[ inline( always) ]  
38+ pub  fn  cmovz ( condition :  usize ,  src :  usize ,  dst :  & mut  usize )  { 
39+     unsafe  { 
40+         asm !  { 
41+             "cmp {0}, 0" , 
42+             "csel {1}, {2}, {3}, EQ" , 
43+             in( reg)  condition, 
44+             inlateout( reg)  * dst, 
45+             in( reg)  src, 
46+             in( reg)  * dst, 
47+         } ; 
48+     } 
49+ } 
50+ 
51+ /// Move if not zero. 
52+ /// 
53+ /// Uses a `cmp` instruction to check if the given `condition` value is not 
54+ /// equal to zero, then calls `csel` to conditionally move 
55+ /// `src` to `dst` when `condition` is nonzero. 
56+ #[ cfg( any( target_arch = "aarch64" ) ) ]  
57+ #[ inline( always) ]  
58+ pub  fn  cmovnz ( condition :  usize ,  src :  usize ,  dst :  & mut  usize )  { 
59+     unsafe  { 
60+         asm !  { 
61+             "cmp {0}, 0" , 
62+             "csel {1}, {2}, {3}, NE" , 
63+             in( reg)  condition, 
64+             inlateout( reg)  * dst, 
65+             in( reg)  src, 
66+             in( reg)  * dst, 
67+         } ; 
68+     } 
69+ } 
70+ 
3171/// Move if not zero. 
3272/// 
3373/// Uses a `test` instruction to check if the given `condition` value is not 
@@ -52,7 +92,7 @@ pub fn cmovnz(condition: usize, src: usize, dst: &mut usize) {
5292/// This implementation is based on portable bitwise arithmetic but cannot 
5393/// guarantee that the resulting generated assembly is free of branch 
5494/// instructions. 
55- #[ cfg( not( any( target_arch = "x86" ,  target_arch = "x86_64" ) ) ) ]  
95+ #[ cfg( not( any( target_arch = "x86" ,  target_arch = "x86_64" ,  target_arch =  "aarch64" ) ) ) ]  
5696#[ inline( never) ]  
5797pub  fn  cmovz ( condition :  usize ,  src :  usize ,  dst :  & mut  usize )  { 
5898    let  mask = ( 1  ^ is_non_zero ( condition) ) . wrapping_sub ( 1 ) ; 
@@ -64,7 +104,7 @@ pub fn cmovz(condition: usize, src: usize, dst: &mut usize) {
64104/// This implementation is based on portable bitwise arithmetic but cannot 
65105/// guarantee that the resulting generated assembly is free of branch 
66106/// instructions. 
67- #[ cfg( not( any( target_arch = "x86" ,  target_arch = "x86_64" ) ) ) ]  
107+ #[ cfg( not( any( target_arch = "x86" ,  target_arch = "x86_64" ,  target_arch =  "aarch64" ) ) ) ]  
68108#[ inline( never) ]  
69109pub  fn  cmovnz ( condition :  usize ,  src :  usize ,  dst :  & mut  usize )  { 
70110    let  mask = is_non_zero ( condition) . wrapping_sub ( 1 ) ; 
@@ -76,7 +116,7 @@ pub fn cmovnz(condition: usize, src: usize, dst: &mut usize) {
76116/// # Returns 
77117/// - `condition` is zero: `0` 
78118/// - `condition` is non-zero: `1` 
79- #[ cfg( not( any( target_arch = "x86" ,  target_arch = "x86_64" ) ) ) ]  
119+ #[ cfg( not( any( target_arch = "x86" ,  target_arch = "x86_64" ,  target_arch =  "aarch64" ) ) ) ]  
80120#[ inline( always) ]  
81121fn  is_non_zero ( condition :  usize )  -> usize  { 
82122    const  SHIFT_BITS :  usize  = core:: mem:: size_of :: < usize > ( )  - 1 ; 
0 commit comments