1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use crate::{Assign, ConstId, Phi};
use std::fmt;
/// A single abstract machine instruction.
#[derive(Debug, Clone)]
pub enum Value {
/// A numerated input.
Input(usize),
/// An instruction to load a constant as a value.
Const(ConstId),
/// A phony use node, indicating what assignments flow into this.
Phi(Phi),
/// Compute `!arg`.
Not(Assign),
/// Compute `lhs + rhs`.
Add(Assign, Assign),
/// Compute `lhs - rhs`.
Sub(Assign, Assign),
/// Compute `lhs / rhs`.
Div(Assign, Assign),
/// Compute `lhs * rhs`.
Mul(Assign, Assign),
/// Compare if `lhs < rhs`.
CmpLt(Assign, Assign),
/// Compare if `lhs <= rhs`.
CmpLte(Assign, Assign),
/// Compare if `lhs == rhs`.
CmpEq(Assign, Assign),
/// Compare if `lhs > rhs`.
CmpGt(Assign, Assign),
/// Compare if `lhs >= rhs`.
CmpGte(Assign, Assign),
}
impl Value {
/// Dump diagnostical information on an instruction.
pub fn dump(&self) -> InstDump<'_> {
InstDump(self)
}
}
pub struct InstDump<'a>(&'a Value);
impl fmt::Display for InstDump<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {
Value::Input(n) => {
write!(f, "input {}", n)?;
}
Value::Const(id) => {
write!(f, "{}", id)?;
}
Value::Phi(phi) => {
write!(f, "{}", phi)?;
}
Value::Not(var) => {
write!(f, "not {}", var)?;
}
Value::Add(lhs, rhs) => {
write!(f, "add {}, {}", lhs, rhs)?;
}
Value::Sub(lhs, rhs) => {
write!(f, "sub {}, {}", lhs, rhs)?;
}
Value::Div(lhs, rhs) => {
write!(f, "div {}, {}", lhs, rhs)?;
}
Value::Mul(lhs, rhs) => {
write!(f, "mul {}, {}", lhs, rhs)?;
}
Value::CmpLt(lhs, rhs) => {
write!(f, "lt {}, {}", lhs, rhs)?;
}
Value::CmpLte(lhs, rhs) => {
write!(f, "lte {}, {}", lhs, rhs)?;
}
Value::CmpEq(lhs, rhs) => {
write!(f, "eq {}, {}", lhs, rhs)?;
}
Value::CmpGt(lhs, rhs) => {
write!(f, "gt {}, {}", lhs, rhs)?;
}
Value::CmpGte(lhs, rhs) => {
write!(f, "gte {}, {}", lhs, rhs)?;
}
}
Ok(())
}
}