1#[derive(Clone, Copy, PartialEq, Eq)]
10pub struct Op {
11 bits: u32,
12}
13
14impl Op {
15 #[inline]
17 pub fn assign(arg: u32) -> Self {
18 Self::new(0, arg)
19 }
20
21 #[inline]
23 pub fn add(arg: u32) -> Self {
24 Self::new(1, arg)
25 }
26
27 #[inline]
29 pub fn or(arg: u32) -> Self {
30 Self::new(2, arg)
31 }
32
33 #[inline]
35 pub fn and_not(arg: u32) -> Self {
36 Self::new(3, arg)
37 }
38
39 #[inline]
41 pub fn xor(arg: u32) -> Self {
42 Self::new(4, arg)
43 }
44
45 #[inline]
47 pub fn assign_bit(bit: u32) -> Self {
48 Self::new(8, bit)
49 }
50
51 #[inline]
53 pub fn add_bit(bit: u32) -> Self {
54 Self::new(9, bit)
55 }
56
57 #[inline]
59 pub fn set_bit(bit: u32) -> Self {
60 Self::new(10, bit)
61 }
62
63 #[inline]
65 pub fn clear_bit(bit: u32) -> Self {
66 Self::new(11, bit)
67 }
68
69 #[inline]
71 pub fn toggle_bit(bit: u32) -> Self {
72 Self::new(12, bit)
73 }
74
75 #[inline]
76 fn new(op: u32, value: u32) -> Self {
77 if value >= 1 << 12 {
78 panic!("Value too large: {}", value);
79 }
80 Self {
81 bits: value << 12 | op << 28,
82 }
83 }
84}
85
86impl std::fmt::Debug for Op {
87 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
88 let op = match self.bits >> 28 {
89 0 => "assign",
90 1 => "add",
91 2 => "or",
92 3 => "and_not",
93 4 => "xor",
94 8 => "assign_bit",
95 9 => "add_bit",
96 10 => "set_bit",
97 11 => "clear_bit",
98 12 => "toggle_bit",
99 _ => "invalid",
100 };
101 write!(f, "Op::{}({})", op, self.bits >> 12 & 0xFFF)
102 }
103}
104
105#[derive(Clone, Copy, PartialEq, Eq)]
112pub struct Cmp {
113 bits: u32,
114}
115
116impl Cmp {
117 #[inline]
119 pub fn eq(value: u32) -> Self {
120 Self::new(0, value)
121 }
122
123 #[inline]
125 pub fn ne(value: u32) -> Self {
126 Self::new(1, value)
127 }
128
129 #[inline]
131 pub fn lt(value: u32) -> Self {
132 Self::new(2, value)
133 }
134
135 #[inline]
137 pub fn le(value: u32) -> Self {
138 Self::new(3, value)
139 }
140
141 #[inline]
143 pub fn gt(value: u32) -> Self {
144 Self::new(4, value)
145 }
146
147 #[inline]
149 pub fn ge(value: u32) -> Self {
150 Self::new(5, value)
151 }
152
153 #[inline]
154 fn new(op: u32, value: u32) -> Self {
155 if value >= 1 << 12 {
156 panic!("Value too large: {}", value);
157 }
158 Self {
159 bits: value | op << 24,
160 }
161 }
162}
163
164impl std::fmt::Debug for Cmp {
165 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
166 let op = match self.bits >> 24 & 0xF {
167 0 => "eq",
168 1 => "ne",
169 2 => "lt",
170 3 => "le",
171 4 => "gt",
172 5 => "ge",
173 _ => "invalid",
174 };
175 write!(f, "Cmp::{}({})", op, self.bits & 0xFFF)
176 }
177}
178
179#[derive(Clone, Copy, PartialEq, Eq)]
186pub struct OpAndCmp {
187 bits: u32,
188}
189
190impl OpAndCmp {
191 #[inline]
192 pub const fn from_raw_bits(bits: u32) -> Self {
193 Self { bits }
194 }
195
196 #[inline]
197 pub const fn raw_bits(self) -> u32 {
198 self.bits
199 }
200}
201
202impl std::ops::Add<Cmp> for Op {
203 type Output = OpAndCmp;
204 #[inline]
205 fn add(self, cmp: Cmp) -> OpAndCmp {
206 OpAndCmp {
207 bits: self.bits | cmp.bits,
208 }
209 }
210}
211
212impl std::fmt::Debug for OpAndCmp {
213 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
214 write!(
215 f,
216 "{:?} + {:?}",
217 Op { bits: self.bits },
218 Cmp { bits: self.bits }
219 )
220 }
221}