1use crate::Register;
2use std::fmt::{self, Display};
3use std::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
4use std::rc::Rc;
5
6#[derive(Debug, Clone, Copy)]
7pub enum ActionOp1 {
8 Not,
9 LogicalNot,
10 Clz,
11 Ctz,
12 Cpop,
13 Orcb,
14 Rev8,
15}
16
17#[derive(Debug, Clone, Copy)]
18pub enum ActionOp2 {
19 Add,
20 Sub,
21 Mul,
22 Mulhsu,
23 Bitand,
24 Bitor,
25 Bitxor,
26 Shl,
27 Eq,
28 Clmul,
29 Clmulh,
30 Clmulr,
31 Rol,
32 Ror,
33}
34
35#[derive(Debug, Clone, Copy)]
36pub enum SignActionOp2 {
37 Mulh,
38 Div,
39 Rem,
40 Shr,
41 Lt,
42 Extend,
43}
44
45#[derive(Debug, Clone)]
46pub enum Value {
47 Imm(u64),
48 Register(usize),
49 Op1(ActionOp1, Rc<Value>),
50 Op2(ActionOp2, Rc<Value>, Rc<Value>),
51 SignOp2(SignActionOp2, Rc<Value>, Rc<Value>, bool),
52 Cond(Rc<Value>, Rc<Value>, Rc<Value>),
53 Load(Rc<Value>, u8),
54}
55
56impl Default for Value {
57 fn default() -> Value {
58 Value::zero()
59 }
60}
61
62impl Display for Value {
63 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64 write!(f, "{:?}", self)
65 }
66}
67
68impl Not for Value {
69 type Output = Self;
70
71 fn not(self) -> Value {
72 if let Value::Imm(imm) = self {
73 return Value::Imm(!imm);
74 }
75 Value::Op1(ActionOp1::Not, Rc::new(self))
76 }
77}
78
79impl BitAnd for Value {
80 type Output = Self;
81
82 fn bitand(self, rhs: Self) -> Value {
83 if let (Value::Imm(imm1), Value::Imm(imm2)) = (&self, &rhs) {
84 return Value::Imm(imm1 & imm2);
85 }
86 Value::Op2(ActionOp2::Bitand, Rc::new(self), Rc::new(rhs))
87 }
88}
89
90impl BitOr for Value {
91 type Output = Self;
92
93 fn bitor(self, rhs: Self) -> Value {
94 if let (Value::Imm(imm1), Value::Imm(imm2)) = (&self, &rhs) {
95 return Value::Imm(imm1 | imm2);
96 }
97 Value::Op2(ActionOp2::Bitor, Rc::new(self), Rc::new(rhs))
98 }
99}
100
101impl BitXor for Value {
102 type Output = Self;
103
104 fn bitxor(self, rhs: Self) -> Value {
105 if let (Value::Imm(imm1), Value::Imm(imm2)) = (&self, &rhs) {
106 return Value::Imm(imm1 ^ imm2);
107 }
108 Value::Op2(ActionOp2::Bitxor, Rc::new(self), Rc::new(rhs))
109 }
110}
111
112impl Shl<Value> for Value {
113 type Output = Self;
114
115 fn shl(self, rhs: Self) -> Value {
116 if let (Value::Imm(imm1), Value::Imm(imm2)) = (&self, &rhs) {
117 return Value::Imm(imm1 << imm2);
119 }
120 Value::Op2(ActionOp2::Shl, Rc::new(self), Rc::new(rhs))
121 }
122}
123
124impl Shr<Value> for Value {
125 type Output = Self;
126
127 fn shr(self, rhs: Self) -> Value {
128 if let (Value::Imm(imm1), Value::Imm(imm2)) = (&self, &rhs) {
129 return Value::Imm(imm1 >> imm2);
131 }
132 Value::SignOp2(SignActionOp2::Shr, Rc::new(self), Rc::new(rhs), false)
133 }
134}
135
136impl Register for Value {
137 const BITS: u8 = 64;
139 const SHIFT_MASK: u8 = 0x3F;
140
141 fn zero() -> Value {
142 Value::Imm(0)
143 }
144
145 fn one() -> Value {
146 Value::Imm(1)
147 }
148
149 fn min_value() -> Value {
150 Value::Imm(u64::MIN)
151 }
152
153 fn max_value() -> Value {
154 Value::Imm(u64::MAX)
155 }
156
157 fn eq(&self, other: &Value) -> Value {
158 Value::Op2(ActionOp2::Eq, Rc::new(self.clone()), Rc::new(other.clone()))
159 }
160
161 fn lt(&self, other: &Value) -> Value {
162 Value::SignOp2(
163 SignActionOp2::Lt,
164 Rc::new(self.clone()),
165 Rc::new(other.clone()),
166 false,
167 )
168 }
169
170 fn lt_s(&self, other: &Value) -> Value {
171 Value::SignOp2(
172 SignActionOp2::Lt,
173 Rc::new(self.clone()),
174 Rc::new(other.clone()),
175 true,
176 )
177 }
178
179 fn logical_not(&self) -> Value {
180 Value::Op1(ActionOp1::LogicalNot, Rc::new(self.clone()))
181 }
182
183 fn cond(&self, true_value: &Value, false_value: &Value) -> Value {
184 Value::Cond(
185 Rc::new(self.clone()),
186 Rc::new(true_value.clone()),
187 Rc::new(false_value.clone()),
188 )
189 }
190
191 fn overflowing_add(&self, rhs: &Value) -> Value {
192 if let (Value::Imm(imm1), Value::Imm(imm2)) = (self, rhs) {
193 let imm = (*imm1).overflowing_add(*imm2).0;
194 return Value::Imm(imm);
195 }
196 Value::Op2(ActionOp2::Add, Rc::new(self.clone()), Rc::new(rhs.clone()))
197 }
198
199 fn overflowing_sub(&self, rhs: &Value) -> Value {
200 if let (Value::Imm(imm1), Value::Imm(imm2)) = (self, rhs) {
201 let imm = (*imm1).overflowing_sub(*imm2).0;
202 return Value::Imm(imm);
203 }
204 Value::Op2(ActionOp2::Sub, Rc::new(self.clone()), Rc::new(rhs.clone()))
205 }
206
207 fn overflowing_mul(&self, rhs: &Value) -> Value {
208 Value::Op2(ActionOp2::Mul, Rc::new(self.clone()), Rc::new(rhs.clone()))
209 }
210
211 fn overflowing_div(&self, rhs: &Value) -> Value {
212 Value::SignOp2(
213 SignActionOp2::Div,
214 Rc::new(self.clone()),
215 Rc::new(rhs.clone()),
216 false,
217 )
218 }
219
220 fn overflowing_rem(&self, rhs: &Value) -> Value {
221 Value::SignOp2(
222 SignActionOp2::Rem,
223 Rc::new(self.clone()),
224 Rc::new(rhs.clone()),
225 false,
226 )
227 }
228
229 fn overflowing_div_signed(&self, rhs: &Value) -> Value {
230 Value::SignOp2(
231 SignActionOp2::Div,
232 Rc::new(self.clone()),
233 Rc::new(rhs.clone()),
234 true,
235 )
236 }
237
238 fn overflowing_rem_signed(&self, rhs: &Value) -> Value {
239 Value::SignOp2(
240 SignActionOp2::Rem,
241 Rc::new(self.clone()),
242 Rc::new(rhs.clone()),
243 true,
244 )
245 }
246
247 fn overflowing_mul_high_signed(&self, rhs: &Value) -> Value {
248 Value::SignOp2(
249 SignActionOp2::Mulh,
250 Rc::new(self.clone()),
251 Rc::new(rhs.clone()),
252 true,
253 )
254 }
255
256 fn overflowing_mul_high_unsigned(&self, rhs: &Value) -> Value {
257 Value::SignOp2(
258 SignActionOp2::Mulh,
259 Rc::new(self.clone()),
260 Rc::new(rhs.clone()),
261 false,
262 )
263 }
264
265 fn overflowing_mul_high_signed_unsigned(&self, rhs: &Value) -> Value {
266 Value::Op2(
267 ActionOp2::Mulhsu,
268 Rc::new(self.clone()),
269 Rc::new(rhs.clone()),
270 )
271 }
272
273 fn clz(&self) -> Value {
274 Value::Op1(ActionOp1::Clz, Rc::new(self.clone()))
275 }
276
277 fn ctz(&self) -> Value {
278 Value::Op1(ActionOp1::Ctz, Rc::new(self.clone()))
279 }
280
281 fn cpop(&self) -> Value {
282 Value::Op1(ActionOp1::Cpop, Rc::new(self.clone()))
283 }
284
285 fn clmul(&self, rhs: &Value) -> Value {
286 if let (Value::Imm(imm1), Value::Imm(imm2)) = (self, rhs) {
287 return Value::Imm(imm1.clmul(imm2));
288 }
289 Value::Op2(
290 ActionOp2::Clmul,
291 Rc::new(self.clone()),
292 Rc::new(rhs.clone()),
293 )
294 }
295
296 fn clmulh(&self, rhs: &Value) -> Value {
297 if let (Value::Imm(imm1), Value::Imm(imm2)) = (self, rhs) {
298 return Value::Imm(imm1.clmulh(imm2));
299 }
300 Value::Op2(
301 ActionOp2::Clmulh,
302 Rc::new(self.clone()),
303 Rc::new(rhs.clone()),
304 )
305 }
306
307 fn clmulr(&self, rhs: &Value) -> Value {
308 if let (Value::Imm(imm1), Value::Imm(imm2)) = (self, rhs) {
309 return Value::Imm(imm1.clmulr(imm2));
310 }
311 Value::Op2(
312 ActionOp2::Clmulr,
313 Rc::new(self.clone()),
314 Rc::new(rhs.clone()),
315 )
316 }
317
318 fn orcb(&self) -> Self {
319 if let Value::Imm(imm1) = self {
320 return Value::Imm(imm1.orcb());
321 }
322 Value::Op1(ActionOp1::Orcb, Rc::new(self.clone()))
323 }
324
325 fn rev8(&self) -> Self {
326 if let Value::Imm(imm1) = self {
327 return Value::Imm(imm1.rev8());
328 }
329 Value::Op1(ActionOp1::Rev8, Rc::new(self.clone()))
330 }
331
332 fn rol(&self, rhs: &Value) -> Value {
333 if let (Value::Imm(imm1), Value::Imm(imm2)) = (self, rhs) {
334 return Value::Imm(imm1.rotate_left(*imm2 as u32));
335 }
336 Value::Op2(ActionOp2::Rol, Rc::new(self.clone()), Rc::new(rhs.clone()))
337 }
338
339 fn ror(&self, rhs: &Value) -> Value {
340 if let (Value::Imm(imm1), Value::Imm(imm2)) = (self, rhs) {
341 return Value::Imm(imm1.rotate_right(*imm2 as u32));
342 }
343 Value::Op2(ActionOp2::Ror, Rc::new(self.clone()), Rc::new(rhs.clone()))
344 }
345
346 fn signed_shl(&self, rhs: &Value) -> Value {
347 self.clone().shl(rhs.clone())
349 }
350
351 fn signed_shr(&self, rhs: &Value) -> Value {
352 if let (Value::Imm(imm1), Value::Imm(imm2)) = (self, rhs) {
353 return Value::Imm(((*imm1 as i64) >> imm2) as u64);
355 }
356 Value::SignOp2(
357 SignActionOp2::Shr,
358 Rc::new(self.clone()),
359 Rc::new(rhs.clone()),
360 true,
361 )
362 }
363
364 fn zero_extend(&self, start_bit: &Value) -> Value {
365 Value::SignOp2(
366 SignActionOp2::Extend,
367 Rc::new(self.clone()),
368 Rc::new(start_bit.clone()),
369 false,
370 )
371 }
372
373 fn sign_extend(&self, start_bit: &Value) -> Value {
374 Value::SignOp2(
375 SignActionOp2::Extend,
376 Rc::new(self.clone()),
377 Rc::new(start_bit.clone()),
378 true,
379 )
380 }
381
382 fn to_i8(&self) -> i8 {
383 0
384 }
385
386 fn to_i16(&self) -> i16 {
387 0
388 }
389
390 fn to_i32(&self) -> i32 {
391 0
392 }
393
394 fn to_i64(&self) -> i64 {
395 0
396 }
397
398 fn to_u8(&self) -> u8 {
399 0
400 }
401
402 fn to_u16(&self) -> u16 {
403 0
404 }
405
406 fn to_u32(&self) -> u32 {
407 0
408 }
409
410 fn to_u64(&self) -> u64 {
411 0
412 }
413
414 fn from_i8(v: i8) -> Value {
415 Value::Imm(i64::from(v) as u64)
416 }
417
418 fn from_i16(v: i16) -> Value {
419 Value::Imm(i64::from(v) as u64)
420 }
421
422 fn from_i32(v: i32) -> Value {
423 Value::Imm(i64::from(v) as u64)
424 }
425
426 fn from_i64(v: i64) -> Value {
427 Value::Imm(v as u64)
428 }
429
430 fn from_u8(v: u8) -> Value {
431 Value::Imm(u64::from(v))
432 }
433
434 fn from_u16(v: u16) -> Value {
435 Value::Imm(u64::from(v))
436 }
437
438 fn from_u32(v: u32) -> Value {
439 Value::Imm(u64::from(v))
440 }
441
442 fn from_u64(v: u64) -> Value {
443 Value::Imm(v)
444 }
445}