ckb_vm/instructions/
ast.rs

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            // By default immediates are unsigned
118            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            // By default immediates are unsigned
130            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    // For now we only support JIT on 64 bit RISC-V machine
138    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        // Signed shl and unsigned shl are the same thing
348        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            // By default immediates are unsigned
354            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}