|
1 | | -use crate::{Cmov, Condition}; |
| 1 | +use crate::{Cmov, CmovEq, Condition}; |
2 | 2 | use core::arch::asm; |
3 | 3 |
|
4 | 4 | macro_rules! csel { |
5 | | - ($cmp:expr, $csel:expr, $dst:expr, $src:expr, $condition:expr) => { |
| 5 | + ($csel:expr, $dst:expr, $src:expr, $condition:expr) => { |
6 | 6 | unsafe { |
7 | 7 | asm! { |
8 | | - $cmp, |
| 8 | + "cmp {0:w}, 0", |
9 | 9 | $csel, |
10 | 10 | in(reg) $condition, |
11 | 11 | inlateout(reg) *$dst, |
12 | | - in(reg) $src, |
| 12 | + in(reg) *$src, |
13 | 13 | in(reg) *$dst, |
14 | 14 | options(pure, nomem, nostack), |
15 | 15 | }; |
16 | 16 | } |
17 | 17 | }; |
18 | 18 | } |
19 | 19 |
|
| 20 | +macro_rules! csel_eq { |
| 21 | + ($instruction:expr, $lhs:expr, $rhs:expr, $condition:expr, $dst:expr) => { |
| 22 | + let mut tmp = *$dst as u16; |
| 23 | + unsafe { |
| 24 | + asm! { |
| 25 | + "eor {0:w}, {1:w}, {2:w}", |
| 26 | + "cmp {0:w}, 0", |
| 27 | + $instruction, |
| 28 | + out(reg) _, |
| 29 | + in(reg) *$lhs, |
| 30 | + in(reg) *$rhs, |
| 31 | + inlateout(reg) tmp, |
| 32 | + in(reg) $condition as u16, |
| 33 | + in(reg) tmp, |
| 34 | + options(pure, nomem, nostack), |
| 35 | + }; |
| 36 | + }; |
| 37 | + |
| 38 | + *$dst = tmp as u8; |
| 39 | + }; |
| 40 | +} |
| 41 | + |
20 | 42 | impl Cmov for u16 { |
21 | 43 | #[inline(always)] |
22 | 44 | fn cmovnz(&mut self, value: &Self, condition: Condition) { |
23 | | - csel!( |
24 | | - "cmp {0:w}, 0", |
25 | | - "csel {1:w}, {2:w}, {3:w}, NE", |
26 | | - self, |
27 | | - *value, |
28 | | - condition |
29 | | - ); |
| 45 | + csel!("csel {1:w}, {2:w}, {3:w}, NE", self, value, condition); |
30 | 46 | } |
31 | 47 |
|
32 | 48 | #[inline(always)] |
33 | 49 | fn cmovz(&mut self, value: &Self, condition: Condition) { |
34 | | - csel!( |
35 | | - "cmp {0:w}, 0", |
36 | | - "csel {1:w}, {2:w}, {3:w}, EQ", |
37 | | - self, |
38 | | - *value, |
39 | | - condition |
40 | | - ); |
| 50 | + csel!("csel {1:w}, {2:w}, {3:w}, EQ", self, value, condition); |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +impl CmovEq for u16 { |
| 55 | + #[inline(always)] |
| 56 | + 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); |
| 58 | + } |
| 59 | + |
| 60 | + #[inline(always)] |
| 61 | + 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); |
41 | 63 | } |
42 | 64 | } |
43 | 65 |
|
44 | 66 | impl Cmov for u32 { |
45 | 67 | #[inline(always)] |
46 | 68 | fn cmovnz(&mut self, value: &Self, condition: Condition) { |
47 | | - csel!( |
48 | | - "cmp {0:w}, 0", |
49 | | - "csel {1:w}, {2:w}, {3:w}, NE", |
50 | | - self, |
51 | | - *value, |
52 | | - condition |
53 | | - ); |
| 69 | + csel!("csel {1:w}, {2:w}, {3:w}, NE", self, value, condition); |
54 | 70 | } |
55 | 71 |
|
56 | 72 | #[inline(always)] |
57 | 73 | fn cmovz(&mut self, value: &Self, condition: Condition) { |
58 | | - csel!( |
59 | | - "cmp {0:w}, 0", |
60 | | - "csel {1:w}, {2:w}, {3:w}, EQ", |
61 | | - self, |
62 | | - *value, |
63 | | - condition |
64 | | - ); |
| 74 | + csel!("csel {1:w}, {2:w}, {3:w}, EQ", self, value, condition); |
| 75 | + } |
| 76 | +} |
| 77 | + |
| 78 | +impl CmovEq for u32 { |
| 79 | + #[inline(always)] |
| 80 | + 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); |
| 82 | + } |
| 83 | + |
| 84 | + #[inline(always)] |
| 85 | + 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); |
65 | 87 | } |
66 | 88 | } |
67 | 89 |
|
68 | 90 | impl Cmov for u64 { |
69 | 91 | #[inline(always)] |
70 | 92 | fn cmovnz(&mut self, value: &Self, condition: Condition) { |
71 | | - csel!( |
72 | | - "cmp {0:x}, 0", |
73 | | - "csel {1:x}, {2:x}, {3:x}, NE", |
74 | | - self, |
75 | | - *value, |
76 | | - condition |
77 | | - ); |
| 93 | + csel!("csel {1:x}, {2:x}, {3:x}, NE", self, value, condition); |
78 | 94 | } |
79 | 95 |
|
80 | 96 | #[inline(always)] |
81 | 97 | fn cmovz(&mut self, value: &Self, condition: Condition) { |
82 | | - csel!( |
83 | | - "cmp {0:x}, 0", |
84 | | - "csel {1:x}, {2:x}, {3:x}, EQ", |
85 | | - self, |
86 | | - *value, |
87 | | - condition |
88 | | - ); |
| 98 | + csel!("csel {1:x}, {2:x}, {3:x}, EQ", self, value, condition); |
| 99 | + } |
| 100 | +} |
| 101 | + |
| 102 | +impl CmovEq for u64 { |
| 103 | + #[inline(always)] |
| 104 | + 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); |
| 106 | + } |
| 107 | + |
| 108 | + #[inline(always)] |
| 109 | + 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); |
89 | 111 | } |
90 | 112 | } |
0 commit comments